Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F585241
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/RELEASE-NOTES-1.44 b/RELEASE-NOTES-1.44
index bd448625996..55d612f9138 100644
--- a/RELEASE-NOTES-1.44
+++ b/RELEASE-NOTES-1.44
@@ -638,6 +638,8 @@ because of Phabricator reports.
* Maintenance::beginTransaction(), Maintenance::commitTransaction(),
Maintenance::rollbackTransaction(), and Maintenance::waitForReplication()
are now deprecated. Use Maintenance::*TransactionRound() instead.
+* Sanitizer::mergeAttributes() has been deprecated.
+* TextboxBuilder::mergeClassesIntoAttributes() has been deprecated.
* The ReverseArrayIterator class, unused since 1.32, has been deprecated.
* OutputPage::parserOptions() has been deprecated; use
ParserOptions::newFromContext( $outputPage->getContext() ) instead.
diff --git a/includes/Output/OutputPage.php b/includes/Output/OutputPage.php
index 9c1ef3d615f..e6533d6c9bd 100644
--- a/includes/Output/OutputPage.php
+++ b/includes/Output/OutputPage.php
@@ -3893,11 +3893,20 @@ class OutputPage extends ContextSource {
$services = MediaWikiServices::getInstance();
$sitedir = $services->getContentLanguage()->getDir();
+ $rlHtmlAtribs = $this->getRlClient()->getDocumentAttributes();
+ $skinHtmlAttribs = $sk->getHtmlElementAttributes();
+ // Combine the classes from different sources, and convert to a string, which is needed below
+ $htmlClass = Html::expandClassList( [
+ Html::expandClassList( $rlHtmlAtribs['class'] ?? [] ),
+ Html::expandClassList( $skinHtmlAttribs['class'] ?? [] ),
+ Html::expandClassList( $this->mAdditionalHtmlClasses )
+ ] );
+ if ( $htmlClass === '' ) {
+ $htmlClass = null;
+ }
+ $htmlAttribs = array_merge( $rlHtmlAtribs, $skinHtmlAttribs, [ 'class' => $htmlClass ] );
+
$pieces = [];
- $htmlAttribs = Sanitizer::mergeAttributes( Sanitizer::mergeAttributes(
- $this->getRlClient()->getDocumentAttributes(),
- $sk->getHtmlElementAttributes()
- ), [ 'class' => implode( ' ', $this->mAdditionalHtmlClasses ) ] );
$pieces[] = Html::htmlHeader( $htmlAttribs );
$pieces[] = Html::openElement( 'head' );
@@ -3918,7 +3927,7 @@ class OutputPage extends ContextSource {
}
$pieces[] = Html::element( 'title', [], $this->getHTMLTitle() );
- $pieces[] = $this->getRlClient()->getHeadHtml( $htmlAttribs['class'] ?? null );
+ $pieces[] = $this->getRlClient()->getHeadHtml( $htmlClass );
$pieces[] = $this->buildExemptModules();
$pieces = array_merge( $pieces, array_values( $this->getHeadLinksArray() ) );
$pieces = array_merge( $pieces, array_values( $this->mHeadItems ) );
diff --git a/includes/editpage/EditPage.php b/includes/editpage/EditPage.php
index a45de1be54d..2bf34e7e87b 100644
--- a/includes/editpage/EditPage.php
+++ b/includes/editpage/EditPage.php
@@ -3639,10 +3639,9 @@ class EditPage implements IEditObject {
$attribs = [
'aria-label' => $this->context->msg( 'edit-textarea-aria-label' )->text(),
- 'tabindex' => 1
+ 'tabindex' => 1,
+ 'class' => $classes,
];
-
- $attribs = $builder->mergeClassesIntoAttributes( $classes, $attribs );
}
$this->showTextbox(
diff --git a/includes/editpage/TextConflictHelper.php b/includes/editpage/TextConflictHelper.php
index a0e4aff3e24..d30eeaf7d83 100644
--- a/includes/editpage/TextConflictHelper.php
+++ b/includes/editpage/TextConflictHelper.php
@@ -269,8 +269,9 @@ class TextConflictHelper {
'tabindex' => 1,
];
$attribs += $customAttribs;
-
- $attribs = $builder->mergeClassesIntoAttributes( $classes, $attribs );
+ foreach ( $classes as $class ) {
+ Html::addClass( $attribs['class'], $class );
+ }
$attribs = $builder->buildTextboxAttribs(
'wpTextbox1',
diff --git a/includes/editpage/TextboxBuilder.php b/includes/editpage/TextboxBuilder.php
index b5a587e2c5f..550c42b4bf6 100644
--- a/includes/editpage/TextboxBuilder.php
+++ b/includes/editpage/TextboxBuilder.php
@@ -55,6 +55,7 @@ class TextboxBuilder {
* @param string[] $classes
* @param mixed[] $attribs
* @return mixed[]
+ * @deprecated since 1.44, use Html::addClass() instead
*/
public function mergeClassesIntoAttributes( array $classes, array $attribs ) {
if ( $classes === [] ) {
diff --git a/includes/gallery/TraditionalImageGallery.php b/includes/gallery/TraditionalImageGallery.php
index d2314e19cab..b45cf206381 100644
--- a/includes/gallery/TraditionalImageGallery.php
+++ b/includes/gallery/TraditionalImageGallery.php
@@ -9,7 +9,6 @@ use MediaWiki\Linker\LinkRenderer;
use MediaWiki\MainConfigNames;
use MediaWiki\MediaWikiServices;
use MediaWiki\Parser\Parser;
-use MediaWiki\Parser\Sanitizer;
use MediaWiki\Title\Title;
use Wikimedia\Assert\Assert;
@@ -61,18 +60,18 @@ class TraditionalImageGallery extends ImageGalleryBase {
$badFileLookup = $services->getBadFileLookup();
}
+ Html::addClass( $this->mAttribs['class'], 'gallery' );
+ Html::addClass( $this->mAttribs['class'], 'mw-gallery-' . $this->mMode );
+
if ( $this->mPerRow > 0 ) {
$maxwidth = $this->mPerRow * ( $this->mWidths + $this->getAllPadding() );
$oldStyle = $this->mAttribs['style'] ?? '';
$this->mAttribs['style'] = "max-width: {$maxwidth}px;" . $oldStyle;
}
- $attribs = Sanitizer::mergeAttributes(
- [ 'class' => 'gallery mw-gallery-' . $this->mMode ], $this->mAttribs );
-
$parserOutput->addModules( $this->getModules() );
$parserOutput->addModuleStyles( [ 'mediawiki.page.gallery.styles' ] );
- $output = Html::openElement( 'ul', $attribs );
+ $output = Html::openElement( 'ul', $this->mAttribs );
if ( $this->mCaption ) {
$output .= "\n\t" . Html::rawElement( 'li', [ 'class' => 'gallerycaption' ], $this->mCaption );
}
diff --git a/includes/linker/LinkRenderer.php b/includes/linker/LinkRenderer.php
index cf32b779b51..d2099153151 100644
--- a/includes/linker/LinkRenderer.php
+++ b/includes/linker/LinkRenderer.php
@@ -30,7 +30,6 @@ use MediaWiki\Linker\LinkTarget as MWLinkTarget;
use MediaWiki\Message\Message;
use MediaWiki\Page\PageReference;
use MediaWiki\Parser\Parser;
-use MediaWiki\Parser\Sanitizer;
use MediaWiki\SpecialPage\SpecialPageFactory;
use MediaWiki\Title\Title;
use MediaWiki\Title\TitleFormatter;
@@ -218,7 +217,7 @@ class LinkRenderer {
* @param-taint $target none
* @param string|HtmlArmor|null $text Text that the user can click on to visit the link.
* @param-taint $text escapes_html
- * @param string $classes CSS classes to add
+ * @param string|array $classes CSS classes to add
* @param-taint $classes none
* @param array $extraAttribs Attributes you would like to add to the <a> tag. For example, if
* you would like to add title="Text when hovering!", you would set this to [ 'title' => 'Text
@@ -231,7 +230,7 @@ class LinkRenderer {
* @return-taint escaped
*/
public function makePreloadedLink(
- $target, $text = null, $classes = '', array $extraAttribs = [], array $query = []
+ $target, $text = null, $classes = [], array $extraAttribs = [], array $query = []
) {
Assert::parameterType( [ LinkTarget::class, PageReference::class ], $target, '$target' );
@@ -242,15 +241,19 @@ class LinkRenderer {
}
$target = $this->normalizeTarget( $target );
$url = $this->getLinkURL( $target, $query );
- $attribs = [ 'class' => $classes ];
+ // Define empty attributes here for consistent order in the output
+ $attribs = [ 'href' => null, 'class' => [], 'title' => null ];
+
$prefixedText = $this->titleFormatter->getPrefixedText( $target );
if ( $prefixedText !== '' ) {
$attribs['title'] = $prefixedText;
}
- $attribs = [
- 'href' => $url,
- ] + $this->mergeAttribs( $attribs, $extraAttribs );
+ $attribs = array_merge( $attribs, $extraAttribs, [ 'href' => $url ] );
+
+ Html::addClass( $classes, Html::expandClassList( $extraAttribs['class'] ?? [] ) );
+ // Stringify attributes for hook compatibility
+ $attribs['class'] = Html::expandClassList( $classes );
$text ??= $this->getLinkText( $target );
@@ -302,7 +305,7 @@ class LinkRenderer {
return $this->makePreloadedLink(
$target,
$text,
- implode( ' ', $classes ),
+ $classes,
$extraAttribs,
$query
);
@@ -350,7 +353,9 @@ class LinkRenderer {
}
$url = $this->getLinkURL( $target, $query );
- $attribs = [ 'class' => 'new' ];
+ // Define empty attributes here for consistent order in the output
+ $attribs = [ 'href' => null, 'class' => [], 'title' => null ];
+
$prefixedText = $this->titleFormatter->getPrefixedText( $target );
if ( $prefixedText !== '' ) {
// This ends up in parser cache!
@@ -359,9 +364,11 @@ class LinkRenderer {
->text();
}
- $attribs = [
- 'href' => $url,
- ] + $this->mergeAttribs( $attribs, $extraAttribs );
+ $attribs = array_merge( $attribs, $extraAttribs, [ 'href' => $url ] );
+
+ Html::addClass( $attribs['class'], 'new' );
+ // Stringify attributes for hook compatibility
+ $attribs['class'] = Html::expandClassList( $attribs['class'] ?? [] );
$text ??= $this->getLinkText( $target );
@@ -566,31 +573,6 @@ class LinkRenderer {
return $target;
}
- /**
- * Merges two sets of attributes
- *
- * @param array $defaults
- * @param array $attribs
- *
- * @return array
- */
- private function mergeAttribs( $defaults, $attribs ) {
- if ( !$attribs ) {
- return $defaults;
- }
- # Merge the custom attribs with the default ones, and iterate
- # over that, deleting all "false" attributes.
- $ret = [];
- $merged = Sanitizer::mergeAttributes( $defaults, $attribs );
- foreach ( $merged as $key => $val ) {
- # A false value suppresses the attribute
- if ( $val !== false ) {
- $ret[$key] = $val;
- }
- }
- return $ret;
- }
-
/**
* Returns CSS classes to add to a known link.
*
diff --git a/includes/linker/UserLinkRenderer.php b/includes/linker/UserLinkRenderer.php
index 9f302e5eb80..13664239be6 100644
--- a/includes/linker/UserLinkRenderer.php
+++ b/includes/linker/UserLinkRenderer.php
@@ -157,7 +157,7 @@ class UserLinkRenderer {
$classes[] = $attributes['class'];
}
- $attributes['class'] = implode( ' ', $classes );
+ $attributes['class'] = $classes;
if ( $page !== null ) {
return $this->linkRenderer->makeLink( $page, new HtmlArmor( $linkText ), $attributes );
diff --git a/includes/parser/Sanitizer.php b/includes/parser/Sanitizer.php
index a2c71938a82..61301b75b6e 100644
--- a/includes/parser/Sanitizer.php
+++ b/includes/parser/Sanitizer.php
@@ -613,6 +613,8 @@ class Sanitizer {
* will be combined (if they're both strings).
*
* @todo implement merging for other attributes such as style
+ * @deprecated since 1.44, use array_merge() for attribute arrays and
+ * Html::addClass() / Html::expandClassList() for class lists
*/
public static function mergeAttributes( array $a, array $b ): array {
$out = array_merge( $a, $b );
diff --git a/tests/parser/legacyMedia.txt b/tests/parser/legacyMedia.txt
index b1ae938cd6a..16b28514a83 100644
--- a/tests/parser/legacyMedia.txt
+++ b/tests/parser/legacyMedia.txt
@@ -2366,18 +2366,18 @@ Gallery with valid attributes
!! config
wgParserEnableLegacyMediaDOM=true
!! wikitext
-<gallery type="123" summary="345">
+<gallery type="123" summary="345" class="foo">
File:File:Foobar.jpg
</gallery>
!! html/php
-<ul class="gallery mw-gallery-traditional" type="123">
+<ul type="123" class="foo gallery mw-gallery-traditional">
<li class="gallerybox" style="width: 155px"><div style="width: 155px">
<div class="thumb" style="height: 150px;">File:Foobar.jpg</div>
<div class="gallerytext"></div>
</div></li>
</ul>
!! html/parsoid
-<ul class="gallery mw-gallery-traditional" type="123" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"type":"123","summary":"345"},"body":{}}'>
+<ul class="foo gallery mw-gallery-traditional" type="123" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"type":"123","summary":"345"},"body":{}}'>
<li class="gallerybox" style="width: 155px;"><div class="thumb" style="height: 150px;"><span typeof="mw:Error mw:File" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/File:Foobar.jpg"><span class="mw-file-element mw-broken-media" resource="./File:File:Foobar.jpg" data-width="120" data-height="120">File:File:Foobar.jpg</span></a></span></div><div class="gallerytext"></div></li>
</ul>
!! end
@@ -2921,7 +2921,7 @@ wgParserEnableLegacyMediaDOM=true
File:Foobar.jpg
</gallery>
!! html/php
-<ul class="gallery mw-gallery-traditional center" style="text-align: center;">
+<ul class="center gallery mw-gallery-traditional" style="text-align: center;">
<li class="gallerybox" style="width: 155px"><div style="width: 155px">
<div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" decoding="async" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
<div class="gallerytext"></div>
@@ -2965,7 +2965,7 @@ wgParserEnableLegacyMediaDOM=true
File:Foobar.jpg
</gallery>
!! html/php
-<ul class="gallery mw-gallery-slideshow" data-showthumbnails="1">
+<ul data-showthumbnails="1" class="gallery mw-gallery-slideshow">
<li class="gallerybox" style="width: 155px"><div style="width: 155px">
<div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" decoding="async" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
<div class="gallerytext"></div>
diff --git a/tests/parser/media.txt b/tests/parser/media.txt
index 7b128b8f107..2f88b0e6ceb 100644
--- a/tests/parser/media.txt
+++ b/tests/parser/media.txt
@@ -2483,18 +2483,18 @@ Gallery with valid attributes
!! config
wgParserEnableLegacyMediaDOM=false
!! wikitext
-<gallery type="123" summary="345">
+<gallery type="123" summary="345" class="foo">
File:File:Foobar.jpg
</gallery>
!! html/php
-<ul class="gallery mw-gallery-traditional" type="123">
+<ul type="123" class="foo gallery mw-gallery-traditional">
<li class="gallerybox" style="width: 155px">
<div class="thumb" style="height: 150px;"><span typeof="mw:Error mw:File"><a href="/index.php?title=Special:Upload&wpDestFile=File:Foobar.jpg" class="new" title="File:File:Foobar.jpg"><span class="mw-file-element mw-broken-media" data-width="120" data-height="120">File:File:Foobar.jpg</span></a></span></div>
<div class="gallerytext"></div>
</li>
</ul>
!! html/parsoid
-<ul class="gallery mw-gallery-traditional" type="123" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"type":"123","summary":"345"},"body":{}}'>
+<ul class="foo gallery mw-gallery-traditional" type="123" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"type":"123","summary":"345"},"body":{}}'>
<li class="gallerybox" style="width: 155px;"><div class="thumb" style="height: 150px;"><span typeof="mw:Error mw:File" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/File:Foobar.jpg"><span class="mw-file-element mw-broken-media" resource="./File:File:Foobar.jpg" data-width="120" data-height="120">File:File:Foobar.jpg</span></a></span></div><div class="gallerytext"></div></li>
</ul>
!! end
@@ -3055,7 +3055,7 @@ wgParserEnableLegacyMediaDOM=false
File:Foobar.jpg
</gallery>
!! html/php
-<ul class="gallery mw-gallery-traditional center" style="text-align: center;">
+<ul class="center gallery mw-gallery-traditional" style="text-align: center;">
<li class="gallerybox" style="width: 155px">
<div class="thumb" style="width: 150px; height: 150px;"><span typeof="mw:File"><a href="/wiki/File:Foobar.jpg" class="mw-file-description"><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" decoding="async" width="120" height="14" class="mw-file-element" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></span></div>
<div class="gallerytext"></div>
@@ -3099,7 +3099,7 @@ wgParserEnableLegacyMediaDOM=false
File:Foobar.jpg
</gallery>
!! html/php
-<ul class="gallery mw-gallery-slideshow" data-showthumbnails="1">
+<ul data-showthumbnails="1" class="gallery mw-gallery-slideshow">
<li class="gallerybox" style="width: 155px">
<div class="thumb" style="width: 150px;"><span typeof="mw:File"><a href="/wiki/File:Foobar.jpg" class="mw-file-description"><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" decoding="async" width="120" height="14" class="mw-file-element" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></span></div>
<div class="gallerytext"></div>
@@ -4442,7 +4442,7 @@ File:Foobar.jpg|One
File:Foobar.jpg|Two
</gallery>
!! html/php
-<ul class="gallery mw-gallery-traditional" style="max-width: 163px;color: red">
+<ul style="max-width: 163px;color: red" class="gallery mw-gallery-traditional">
<li class="gallerybox" style="width: 155px">
<div class="thumb" style="width: 150px; height: 150px;"><span typeof="mw:File"><a href="/wiki/File:Foobar.jpg" class="mw-file-description" title="One"><img alt="One" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" decoding="async" width="120" height="14" class="mw-file-element" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></span></div>
<div class="gallerytext">One</div>
diff --git a/tests/phpunit/includes/linker/LinkRendererTest.php b/tests/phpunit/includes/linker/LinkRendererTest.php
index ab1ca814c34..51eaddc036e 100644
--- a/tests/phpunit/includes/linker/LinkRendererTest.php
+++ b/tests/phpunit/includes/linker/LinkRendererTest.php
@@ -55,7 +55,7 @@ class LinkRendererTest extends MediaWikiLangTestCase {
'bar' => 'baz'
] );
$this->assertEquals(
- '<a href="/wiki/Special:BlankPage" class="new foobar" '
+ '<a href="/wiki/Special:BlankPage" class="foobar new" '
. 'title="Special:BlankPage (page does not exist)" bar="baz">'
. 'Special:BlankPage</a>',
$link
diff --git a/tests/phpunit/includes/recentchanges/RCCacheEntryFactoryTest.php b/tests/phpunit/includes/recentchanges/RCCacheEntryFactoryTest.php
index c004901c3f0..34fa11d4645 100644
--- a/tests/phpunit/includes/recentchanges/RCCacheEntryFactoryTest.php
+++ b/tests/phpunit/includes/recentchanges/RCCacheEntryFactoryTest.php
@@ -161,7 +161,7 @@ class RCCacheEntryFactoryTest extends MediaWikiLangTestCase {
private function assertUserLinks( $user, $cacheEntry ) {
$this->assertValidHTML( $cacheEntry->userlink );
$this->assertMatchesRegularExpression(
- '#^<a .*class="new mw-userlink".*><bdi>' . $user . '</bdi></a>#',
+ '#^<a .*class="mw-userlink new".*><bdi>' . $user . '</bdi></a>#',
$cacheEntry->userlink,
'verify user link'
);
diff --git a/tests/phpunit/integration/includes/linker/UserLinkRendererTest.php b/tests/phpunit/integration/includes/linker/UserLinkRendererTest.php
index 8b8122417e9..2e228dd9cb8 100644
--- a/tests/phpunit/integration/includes/linker/UserLinkRendererTest.php
+++ b/tests/phpunit/integration/includes/linker/UserLinkRendererTest.php
@@ -228,7 +228,7 @@ class UserLinkRendererTest extends MediaWikiLangTestCase {
'Named user with nonexistent user page' => [
'<a href="/index.php?title=User:UserLinkRendererTestUserNoPage&action=edit&redlink=1" '
- . 'class="new mw-userlink" '
+ . 'class="mw-userlink new" '
. 'title="User:UserLinkRendererTestUserNoPage (page does not exist)">'
. '<bdi>UserLinkRendererTestUserNoPage</bdi></a>',
new UserIdentityValue( 4, 'UserLinkRendererTestUserNoPage' )
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Jul 5, 5:32 AM (1 d, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
227652
Default Alt Text
(19 KB)
Attached To
Mode
rMW mediawiki
Attached
Detach File
Event Timeline
Log In to Comment