initial page text for file uploads.
* (T181651) The info page for File pages now displays the file's base-16 SHA1
hash value in the table of basic information.
+* Style tags with a 'data-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 ===
*
* @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
return self::rawElement( 'style', [
'media' => $media,
- ], $contents );
+ ] + $attribs, $contents );
}
/**
'allowTOC' => !$params['disabletoc'],
'enableSectionEditLinks' => !$params['disableeditsection'],
'unwrap' => $params['wrapoutputclass'] === '',
+ 'deduplicateStyles' => !$params['disablestylededuplication'],
] );
$result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
}
'disablelimitreport' => false,
'disableeditsection' => false,
'disabletidy' => false,
+ 'disablestylededuplication' => false,
'generatexml' => [
ApiBase::PARAM_DFLT => false,
ApiBase::PARAM_HELP_MSG => [
"apihelp-parse-param-disablepp": "Use <var>$1disablelimitreport</var> instead.",
"apihelp-parse-param-disableeditsection": "Omit edit section links from the parser output.",
"apihelp-parse-param-disabletidy": "Do not run HTML cleanup (e.g. tidy) on the parser output.",
+ "apihelp-parse-param-disablestylededuplication": "Do not deduplicate inline stylesheets in the parser output.",
"apihelp-parse-param-generatexml": "Generate XML parse tree (requires content model <code>$1</code>; replaced by <kbd>$2prop=parsetree</kbd>).",
"apihelp-parse-param-preview": "Parse in preview mode.",
"apihelp-parse-param-sectionpreview": "Parse in section preview mode (enables preview mode too).",
"apihelp-parse-param-disablepp": "{{doc-apihelp-param|parse|disablepp}}",
"apihelp-parse-param-disableeditsection": "{{doc-apihelp-param|parse|disableeditsection}}",
"apihelp-parse-param-disabletidy": "{{doc-apihelp-param|parse|disabletidy}}",
+ "apihelp-parse-param-disablestylededuplication": "{{doc-apihelp-param|parse|disablestylededuplication}}",
"apihelp-parse-param-generatexml": "{{doc-apihelp-param|parse|generatexml|params=* $1 - Value of the constant CONTENT_MODEL_WIKITEXT|paramstart=2}}",
"apihelp-parse-param-preview": "{{doc-apihelp-param|parse|preview}}",
"apihelp-parse-param-sectionpreview": "{{doc-apihelp-param|parse|sectionpreview}}",
* @file
* @ingroup Parser
*/
+
class ParserOutput extends CacheTime {
/**
* Feature flags to indicate to extensions that MediaWiki core supports and
* section edit link tokens are present in the HTML. Default is true,
* but might be statefully overridden.
* - unwrap: (bool) Remove a wrapping mw-parser-output div. Default is false.
+ * - deduplicateStyles: (bool) When true, which is the default, `<style>`
+ * tags with the `data-mw-deduplicate` attribute set are deduplicated by
+ * value of the attribute: all but the first will be replaced by `<link
+ * rel="mw-deduplicated-inline-style" href="mw-data:..."/>` tags, where
+ * the scheme-specific-part of the href is the (percent-encoded) value
+ * of the `data-mw-deduplicate` attribute.
* @return string HTML
*/
public function getText( $options = [] ) {
'allowTOC' => !empty( $this->mTOCEnabled ),
'enableSectionEditLinks' => $this->mEditSectionTokens,
'unwrap' => false,
+ 'deduplicateStyles' => true,
];
$text = $this->mText;
);
}
+ if ( $options['deduplicateStyles'] ) {
+ $seen = [];
+ $text = preg_replace_callback(
+ '#<style\s+([^>]*data-mw-deduplicate\s*=[^>]*)>.*?</style>#s',
+ function ( $m ) use ( &$seen ) {
+ $attr = Sanitizer::decodeTagAttributes( $m[1] );
+ if ( !isset( $attr['data-mw-deduplicate'] ) ) {
+ return $m[0];
+ }
+
+ $key = $attr['data-mw-deduplicate'];
+ if ( !isset( $seen[$key] ) ) {
+ $seen[$key] = true;
+ return $m[0];
+ }
+
+ // We were going to use an empty <style> here, but there
+ // was concern that would be too much overhead for browsers.
+ // So let's hope a <link> with a non-standard rel and href isn't
+ // going to be misinterpreted or mangled by any subsequent processing.
+ return Html::element( 'link', [
+ 'rel' => 'mw-deduplicated-inline-style',
+ 'href' => "mw-data:" . wfUrlencode( $key ),
+ ] );
+ },
+ $text
+ );
+ }
+
return $text;
}
<h2><span class="mw-headline" id="Section_3">Section 3</span><mw:editsection page="Test Page" section="4">Section 3</mw:editsection></h2>
<p>Three
</p></div>
+EOF;
+
+ $dedupText = <<<EOF
+<p>This is a test document.</p>
+<style data-mw-deduplicate="duplicate1">.Duplicate1 {}</style>
+<style data-mw-deduplicate="duplicate1">.Duplicate1 {}</style>
+<style data-mw-deduplicate="duplicate2">.Duplicate2 {}</style>
+<style data-mw-deduplicate="duplicate1">.Duplicate1 {}</style>
+<style data-mw-deduplicate="duplicate2">.Duplicate2 {}</style>
+<style data-mw-not-deduplicate="duplicate1">.Duplicate1 {}</style>
+<style data-mw-deduplicate="duplicate1">.Same-attribute-different-content {}</style>
+<style data-mw-deduplicate="duplicate3">.Duplicate1 {}</style>
+<style>.Duplicate1 {}</style>
EOF;
return [
<!-- Saved in parser cache... -->', '<p>Test document.</p>
<!-- Saved in parser cache... -->'
],
+ 'Style deduplication' => [
+ [], [], $dedupText, <<<EOF
+<p>This is a test document.</p>
+<style data-mw-deduplicate="duplicate1">.Duplicate1 {}</style>
+<link rel="mw-deduplicated-inline-style" href="mw-data:duplicate1"/>
+<style data-mw-deduplicate="duplicate2">.Duplicate2 {}</style>
+<link rel="mw-deduplicated-inline-style" href="mw-data:duplicate1"/>
+<link rel="mw-deduplicated-inline-style" href="mw-data:duplicate2"/>
+<style data-mw-not-deduplicate="duplicate1">.Duplicate1 {}</style>
+<link rel="mw-deduplicated-inline-style" href="mw-data:duplicate1"/>
+<style data-mw-deduplicate="duplicate3">.Duplicate1 {}</style>
+<style>.Duplicate1 {}</style>
+EOF
+ ],
+ 'Style deduplication disabled' => [
+ [ 'deduplicateStyles' => false ], [], $dedupText, $dedupText
+ ],
];
// phpcs:enable
}