Merge "Add SPARQL client to core"
[lhc/web/wiklou.git] / includes / parser / ParserOutput.php
index 346a151..19375e0 100644 (file)
@@ -21,6 +21,7 @@
  * @file
  * @ingroup Parser
  */
+
 class ParserOutput extends CacheTime {
        /**
         * Feature flags to indicate to extensions that MediaWiki core supports and
@@ -270,6 +271,12 @@ class ParserOutput extends CacheTime {
         *     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 = [] ) {
@@ -290,6 +297,7 @@ class ParserOutput extends CacheTime {
                        'allowTOC' => !empty( $this->mTOCEnabled ),
                        'enableSectionEditLinks' => $this->mEditSectionTokens,
                        'unwrap' => false,
+                       'deduplicateStyles' => true,
                ];
                $text = $this->mText;
 
@@ -350,6 +358,35 @@ class ParserOutput extends CacheTime {
                        );
                }
 
+               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;
        }