Anomie has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/393284 )
Change subject: ParserOutput: Add 'deduplicateStyles' post-cache transformation
......................................................................
ParserOutput: Add 'deduplicateStyles' post-cache transformation
This transformation will find <style> tag with a "mw-deduplicate"
attribute. For each value of the attribute, the first instance will be
kept as-is, while any subsequent tags with the same value will have all
contents removed and will have "mw-deduplicate" replaced with
"mw-deduplicated".
This also adds an $attribs parameter to Html::inlineStyle() so the
mw-deduplicate attribute can be added.
Note this doesn't actually depend on Ib931e25c, but action=mobileview
will break if it starts being used without that patch.
Bug: T160563
Change-Id: I055abdf4d73ec65771eaa4fe0999ec907c831568
Depends-On: Ib931e25ce85072000e62c486bbe5907f03372494
---
M RELEASE-NOTES-1.31
M includes/Html.php
M includes/parser/ParserOutput.php
M tests/phpunit/includes/parser/ParserOutputTest.php
4 files changed, 72 insertions(+), 2 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/84/393284/1
diff --git a/RELEASE-NOTES-1.31 b/RELEASE-NOTES-1.31
index 4fd3f20..e997dfb 100644
--- a/RELEASE-NOTES-1.31
+++ b/RELEASE-NOTES-1.31
@@ -24,6 +24,9 @@
warningBox generation.
* Added a hook, ParserOutputPostCacheTransform, to allow extensions to affect
the ParserOutput::getText() post-cache transformations.
+* Style tags with an 'mw-deduplicate' attribute will be deduplicated as a
+ ParserOutput::getText() post-cache transformation. This may be disabled by
+ passing 'deduplicateStyles' => false to that method.
=== External library changes in 1.31 ===
diff --git a/includes/Html.php b/includes/Html.php
index dfd80a8..3bcf131 100644
--- a/includes/Html.php
+++ b/includes/Html.php
@@ -589,9 +589,12 @@
*
* @param string $contents CSS
* @param string $media A media type string, like 'screen'
+ * @param array $attribs (since 1.31) Associative array of attributes,
e.g., [
+ * 'href' => 'https://www.mediawiki.org/' ]. See expandAttributes()
for
+ * further documentation.
* @return string Raw HTML
*/
- public static function inlineStyle( $contents, $media = 'all' ) {
+ public static function inlineStyle( $contents, $media = 'all', $attribs
= [] ) {
// Don't escape '>' since that is used
// as direct child selector.
// Remember, in css, there is no "x" for hexadecimal escapes,
and
@@ -609,7 +612,7 @@
return self::rawElement( 'style', [
'media' => $media,
- ], $contents );
+ ] + $attribs, $contents );
}
/**
diff --git a/includes/parser/ParserOutput.php b/includes/parser/ParserOutput.php
index fb4a169..d1b6203 100644
--- a/includes/parser/ParserOutput.php
+++ b/includes/parser/ParserOutput.php
@@ -21,6 +21,9 @@
* @file
* @ingroup Parser
*/
+
+use HtmlFormatter\HtmlFormatter;
+
class ParserOutput extends CacheTime {
/**
* Feature flag to indicate to extensions that MediaWiki core supports
and
@@ -268,6 +271,11 @@
* - enableSectionEditLinks: (bool) Include section edit links,
assuming
* section edit link tokens are present in the HTML. Default is true,
* but might be statefully overridden.
+ * - deduplicateStyles: (bool) When true, which is the default, <style>
+ * tags with the `mw-deduplicate` attribute set are deduplicated by
+ * value of the attribute: all but the first will have the attribute
+ * replaced with a `mw-deduplicated` attribute and will have all
child
+ * nodes removed.
* @return string HTML
*/
public function getText( $options = [] ) {
@@ -282,6 +290,7 @@
$options += [
'allowTOC' => !empty( $this->mTOCEnabled ),
'enableSectionEditLinks' => $this->mEditSectionTokens,
+ 'deduplicateStyles' => true,
];
$text = $this->mText;
@@ -323,6 +332,31 @@
);
}
+ if ( $options['deduplicateStyles'] ) {
+ // Hide newlines from HtmlFormatter, it sometimes
strips them
+ $text = str_replace( "\n<", ' <', $text );
+
+ $formatter = new HtmlFormatter( $text );
+ $doc = $formatter->getDoc();
+ $xpath = new DOMXPath( $doc );
+
+ $seen = [];
+ $nodes = $xpath->query( '//style[@mw-deduplicate]' );
+ foreach ( $nodes as $node ) {
+ $key = $node->getAttribute( 'mw-deduplicate' );
+ if ( isset( $seen[$key] ) ) {
+ $node->removeAttribute(
'mw-deduplicate' );
+ $node->setAttribute( 'mw-deduplicated',
$key );
+ while ( $node->firstChild !== null ) {
+ $node->removeChild(
$node->firstChild );
+ }
+ }
+ $seen[$key] = true;
+ }
+
+ $text = $formatter->getText();
+ }
+
return $text;
}
diff --git a/tests/phpunit/includes/parser/ParserOutputTest.php
b/tests/phpunit/includes/parser/ParserOutputTest.php
index ef35363b..ddb79cd 100644
--- a/tests/phpunit/includes/parser/ParserOutputTest.php
+++ b/tests/phpunit/includes/parser/ParserOutputTest.php
@@ -147,6 +147,19 @@
</p>
EOF;
+ $dedupText = <<<EOF
+<p>This is a test document.</p>
+<style mw-deduplicate="duplicate1">.Duplicate1 {}</style>
+<style mw-deduplicate="duplicate1">.Duplicate1 {}</style>
+<style mw-deduplicate="duplicate2">.Duplicate2 {}</style>
+<style mw-deduplicate="duplicate1">.Duplicate1 {}</style>
+<style mw-deduplicate="duplicate2">.Duplicate2 {}</style>
+<style mw-not-deduplicate="duplicate1">.Duplicate1 {}</style>
+<style mw-deduplicate="duplicate1">.Same-attribute-different-content {}</style>
+<style mw-deduplicate="duplicate3">.Duplicate1 {}</style>
+<style>.Duplicate1 {}</style>
+EOF;
+
return [
'No stateless options, default state' => [
[], [], $text, <<<EOF
@@ -308,6 +321,23 @@
</p>
EOF
],
+ 'Style deduplication' => [
+ [], [], $dedupText, <<<EOF
+<p>This is a test document.</p>
+<style mw-deduplicate="duplicate1">.Duplicate1 {}</style>
+<style mw-deduplicated="duplicate1"></style>
+<style mw-deduplicate="duplicate2">.Duplicate2 {}</style>
+<style mw-deduplicated="duplicate1"></style>
+<style mw-deduplicated="duplicate2"></style>
+<style mw-not-deduplicate="duplicate1">.Duplicate1 {}</style>
+<style mw-deduplicated="duplicate1"></style>
+<style mw-deduplicate="duplicate3">.Duplicate1 {}</style>
+<style>.Duplicate1 {}</style>
+EOF
+ ],
+ 'Style deduplication disabled' => [
+ [ 'deduplicateStyles' => false ], [],
$dedupText, $dedupText
+ ],
];
// @codingStandardsIgnoreEnd
}
--
To view, visit https://gerrit.wikimedia.org/r/393284
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I055abdf4d73ec65771eaa4fe0999ec907c831568
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Anomie <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits