Merge "Add part to update ctd_user_defined in populateChangeTagDef"
[lhc/web/wiklou.git] / includes / OutputPage.php
index c8e18e0..99a4c2b 100644 (file)
@@ -58,6 +58,15 @@ class OutputPage extends ContextSource {
         * @var string The contents of <h1> */
        private $mPageTitle = '';
 
+       /**
+        * @var string The displayed title of the page. Different from page title
+        * if overridden by display title magic word or hooks. Can contain safe
+        * HTML. Different from page title which may contain messages such as
+        * "Editing X" which is displayed in h1. This can be used for other places
+        * where the page name is referred on the page.
+        */
+       private $displayTitle;
+
        /**
         * @var string Contains all of the "<body>" content. Should be private we
         *   got set/get accessors and the append() method.
@@ -964,6 +973,48 @@ class OutputPage extends ContextSource {
                return $this->mPageTitle;
        }
 
+       /**
+        * Same as page title but only contains name of the page, not any other text.
+        *
+        * @since 1.32
+        * @param string $html Page title text.
+        * @see OutputPage::setPageTitle
+        */
+       public function setDisplayTitle( $html ) {
+               $this->displayTitle = $html;
+       }
+
+       /**
+        * Returns page display title.
+        *
+        * Performs some normalization, but this not as strict the magic word.
+        *
+        * @since 1.32
+        * @return string HTML
+        */
+       public function getDisplayTitle() {
+               $html = $this->displayTitle;
+               if ( $html === null ) {
+                       $html = $this->getTitle()->getPrefixedText();
+               }
+
+               return Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags( $html ) );
+       }
+
+       /**
+        * Returns page display title without namespace prefix if possible.
+        *
+        * @since 1.32
+        * @return string HTML
+        */
+       public function getUnprefixedDisplayTitle() {
+               $text = $this->getDisplayTitle();
+               $nsPrefix = $this->getTitle()->getNsText() . ':';
+               $prefix = preg_quote( $nsPrefix, '/' );
+
+               return preg_replace( "/^$prefix/i", '', $text );
+       }
+
        /**
         * Set the Title object to use
         *
@@ -2364,10 +2415,6 @@ class OutputPage extends ContextSource {
 
                if ( !$this->mArticleBodyOnly ) {
                        $sk = $this->getSkin();
-
-                       if ( $sk->shouldPreloadLogo() ) {
-                               $this->addLogoPreloadLinkHeaders();
-                       }
                }
 
                $linkHeader = $this->getLinkHeader();
@@ -2758,6 +2805,18 @@ class OutputPage extends ContextSource {
                                        foreach ( $this->contentOverrideCallbacks as $callback ) {
                                                $content = $callback( $title );
                                                if ( $content !== null ) {
+                                                       $text = ContentHandler::getContentText( $content );
+                                                       if ( strpos( $text, '</script>' ) !== false ) {
+                                                               // Proactively replace this so that we can display a message
+                                                               // to the user, instead of letting it go to Html::inlineScript(),
+                                                               // where it would be considered a server-side issue.
+                                                               $titleFormatted = $title->getPrefixedText();
+                                                               $content = new JavaScriptContent(
+                                                                       Xml::encodeJsCall( 'mw.log.error', [
+                                                                               "Cannot preview $titleFormatted due to script-closing tag."
+                                                                       ] )
+                                                               );
+                                                       }
                                                        return $content;
                                                }
                                        }
@@ -3915,80 +3974,6 @@ class OutputPage extends ContextSource {
                ] );
        }
 
-       /**
-        * Add Link headers for preloading the wiki's logo.
-        *
-        * @since 1.26
-        */
-       protected function addLogoPreloadLinkHeaders() {
-               $logo = ResourceLoaderSkinModule::getLogo( $this->getConfig() );
-
-               $tags = [];
-               $logosPerDppx = [];
-               $logos = [];
-
-               if ( !is_array( $logo ) ) {
-                       // No media queries required if we only have one variant
-                       $this->addLinkHeader( '<' . $logo . '>;rel=preload;as=image' );
-                       return;
-               }
-
-               if ( isset( $logo['svg'] ) ) {
-                       // No media queries required if we only have a 1x and svg variant
-                       // because all preload-capable browsers support SVGs
-                       $this->addLinkHeader( '<' . $logo['svg'] . '>;rel=preload;as=image' );
-                       return;
-               }
-
-               foreach ( $logo as $dppx => $src ) {
-                       // Keys are in this format: "1.5x"
-                       $dppx = substr( $dppx, 0, -1 );
-                       $logosPerDppx[$dppx] = $src;
-               }
-
-               // Because PHP can't have floats as array keys
-               uksort( $logosPerDppx, function ( $a , $b ) {
-                       $a = floatval( $a );
-                       $b = floatval( $b );
-                       // Sort from smallest to largest (e.g. 1x, 1.5x, 2x)
-                       return $a <=> $b;
-               } );
-
-               foreach ( $logosPerDppx as $dppx => $src ) {
-                       $logos[] = [ 'dppx' => $dppx, 'src' => $src ];
-               }
-
-               $logosCount = count( $logos );
-               // Logic must match ResourceLoaderSkinModule:
-               // - 1x applies to resolution < 1.5dppx
-               // - 1.5x applies to resolution >= 1.5dppx && < 2dppx
-               // - 2x applies to resolution >= 2dppx
-               // Note that min-resolution and max-resolution are both inclusive.
-               for ( $i = 0; $i < $logosCount; $i++ ) {
-                       if ( $i === 0 ) {
-                               // Smallest dppx
-                               // min-resolution is ">=" (larger than or equal to)
-                               // "not min-resolution" is essentially "<"
-                               $media_query = 'not all and (min-resolution: ' . $logos[ 1 ]['dppx'] . 'dppx)';
-                       } elseif ( $i !== $logosCount - 1 ) {
-                               // In between
-                               // Media query expressions can only apply "not" to the entire expression
-                               // (e.g. can't express ">= 1.5 and not >= 2).
-                               // Workaround: Use <= 1.9999 in place of < 2.
-                               $upper_bound = floatval( $logos[ $i + 1 ]['dppx'] ) - 0.000001;
-                               $media_query = '(min-resolution: ' . $logos[ $i ]['dppx'] .
-                                       'dppx) and (max-resolution: ' . $upper_bound . 'dppx)';
-                       } else {
-                               // Largest dppx
-                               $media_query = '(min-resolution: ' . $logos[ $i ]['dppx'] . 'dppx)';
-                       }
-
-                       $this->addLinkHeader(
-                               '<' . $logos[$i]['src'] . '>;rel=preload;as=image;media=' . $media_query
-                       );
-               }
-       }
-
        /**
         * Get (and set if not yet set) the CSP nonce.
         *