Merge "commonPrint: Remove overqualified selectors & `!important` where applicable"
[lhc/web/wiklou.git] / includes / parser / Parser.php
index 38eb621..f0898ba 100644 (file)
@@ -251,7 +251,7 @@ class Parser {
        protected $mProfiler;
 
        /**
-        * @var \MediaWiki\Linker\LinkRenderer
+        * @var LinkRenderer
         */
        protected $mLinkRenderer;
 
@@ -395,7 +395,8 @@ class Parser {
         * @param int $revid Number to pass in {{REVISIONID}}
         * @return ParserOutput A ParserOutput
         */
-       public function parse( $text, Title $title, ParserOptions $options,
+       public function parse(
+               $text, Title $title, ParserOptions $options,
                $linestart = true, $clearState = true, $revid = null
        ) {
                /**
@@ -462,6 +463,10 @@ class Parser {
                        }
                }
 
+               # Done parsing! Compute runtime adaptive expiry if set
+               $this->mOutput->finalizeAdaptiveCacheExpiry();
+
+               # Warn if too many heavyweight parser functions were used
                if ( $this->mExpensiveFunctionCount > $this->mOptions->getExpensiveParserFunctionLimit() ) {
                        $this->limitationWarn( 'expensive-parserfunction',
                                $this->mExpensiveFunctionCount,
@@ -882,10 +887,10 @@ class Parser {
        }
 
        /**
-        * Get a \MediaWiki\Linker\LinkRenderer instance to make links with
+        * Get a LinkRenderer instance to make links with
         *
         * @since 1.28
-        * @return \MediaWiki\Linker\LinkRenderer
+        * @return LinkRenderer
         */
        public function getLinkRenderer() {
                if ( !$this->mLinkRenderer ) {
@@ -906,11 +911,11 @@ class Parser {
         * the form:
         *
         * @code
-        *   'UNIQ-xxxxx' => array(
+        *   'UNIQ-xxxxx' => [
         *     'element',
         *     'tag content',
-        *     array( 'param' => 'x' ),
-        *     '<element param="x">tag content</element>' ) )
+        *     [ 'param' => 'x' ],
+        *     '<element param="x">tag content</element>' ]
         * @endcode
         *
         * @param array $elements List of element names. Comments are always extracted.
@@ -1434,11 +1439,17 @@ class Parser {
                } elseif ( isset( $m[5] ) && $m[5] !== '' ) {
                        # RFC or PMID
                        if ( substr( $m[0], 0, 3 ) === 'RFC' ) {
+                               if ( !$this->mOptions->getMagicRFCLinks() ) {
+                                       return $m[0];
+                               }
                                $keyword = 'RFC';
                                $urlmsg = 'rfcurl';
                                $cssClass = 'mw-magiclink-rfc';
                                $id = $m[5];
                        } elseif ( substr( $m[0], 0, 4 ) === 'PMID' ) {
+                               if ( !$this->mOptions->getMagicPMIDLinks() ) {
+                                       return $m[0];
+                               }
                                $keyword = 'PMID';
                                $urlmsg = 'pubmedurl';
                                $cssClass = 'mw-magiclink-pmid';
@@ -1449,7 +1460,9 @@ class Parser {
                        }
                        $url = wfMessage( $urlmsg, $id )->inContentLanguage()->text();
                        return Linker::makeExternalLink( $url, "{$keyword} {$id}", true, $cssClass, [], $this->mTitle );
-               } elseif ( isset( $m[6] ) && $m[6] !== '' ) {
+               } elseif ( isset( $m[6] ) && $m[6] !== ''
+                       && $this->mOptions->getMagicISBNLinks()
+               ) {
                        # ISBN
                        $isbn = $m[6];
                        $space = self::SPACE_NOT_NL; #  non-newline space
@@ -1770,7 +1783,7 @@ class Parser {
         * Replace external links (REL)
         *
         * Note: this is all very hackish and the order of execution matters a lot.
-        * Make sure to run tests/parserTests.php if you change this code.
+        * Make sure to run tests/parser/parserTests.php if you change this code.
         *
         * @private
         *
@@ -3144,14 +3157,17 @@ class Parser {
                                                $context->setUser( User::newFromName( '127.0.0.1', false ) );
                                        }
                                        $context->setLanguage( $this->mOptions->getUserLangObj() );
-                                       $ret = SpecialPageFactory::capturePath( $title, $context, $this->getLinkRenderer() );
+                                       $ret = SpecialPageFactory::capturePath(
+                                               $title, $context, $this->getLinkRenderer() );
                                        if ( $ret ) {
                                                $text = $context->getOutput()->getHTML();
                                                $this->mOutput->addOutputPageMetadata( $context->getOutput() );
                                                $found = true;
                                                $isHTML = true;
                                                if ( $specialPage && $specialPage->maxIncludeCacheTime() !== false ) {
-                                                       $this->mOutput->updateCacheExpiry( $specialPage->maxIncludeCacheTime() );
+                                                       $this->mOutput->updateRuntimeAdaptiveExpiry(
+                                                               $specialPage->maxIncludeCacheTime()
+                                                       );
                                                }
                                        }
                                } elseif ( MWNamespace::isNonincludable( $title->getNamespace() ) ) {
@@ -3450,10 +3466,18 @@ class Parser {
         * @since 1.24
         * @param Title $title
         * @param Parser|bool $parser
-        * @return Revision
+        * @return Revision|bool False if missing
         */
-       public static function statelessFetchRevision( $title, $parser = false ) {
-               return Revision::newFromTitle( $title );
+       public static function statelessFetchRevision( Title $title, $parser = false ) {
+               $pageId = $title->getArticleID();
+               $revId = $title->getLatestRevID();
+
+               $rev = Revision::newKnownCurrent( wfGetDB( DB_REPLICA ), $pageId, $revId );
+               if ( $rev ) {
+                       $rev->setTitle( $title );
+               }
+
+               return $rev;
        }
 
        /**
@@ -3668,7 +3692,7 @@ class Parser {
         */
        public function fetchScaryTemplateMaybeFromCache( $url ) {
                global $wgTranscludeCacheExpiry;
-               $dbr = wfGetDB( DB_SLAVE );
+               $dbr = wfGetDB( DB_REPLICA );
                $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry );
                $obj = $dbr->selectRow( 'transcache', [ 'tc_time', 'tc_contents' ],
                                [ 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ] );
@@ -3760,9 +3784,28 @@ class Parser {
         * @return string
         */
        public function extensionSubstitution( $params, $frame ) {
+               static $errorStr = '<span class="error">';
+               static $errorLen = 20;
+
                $name = $frame->expand( $params['name'] );
+               if ( substr( $name, 0, $errorLen ) === $errorStr ) {
+                       // Probably expansion depth or node count exceeded. Just punt the
+                       // error up.
+                       return $name;
+               }
+
                $attrText = !isset( $params['attr'] ) ? null : $frame->expand( $params['attr'] );
+               if ( substr( $attrText, 0, $errorLen ) === $errorStr ) {
+                       // See above
+                       return $attrText;
+               }
+
                $content = !isset( $params['inner'] ) ? null : $frame->expand( $params['inner'] );
+               if ( substr( $content, 0, $errorLen ) === $errorStr ) {
+                       // See above
+                       return $content;
+               }
+
                $marker = self::MARKER_PREFIX . "-$name-"
                        . sprintf( '%08X', $this->mMarkerIndex++ ) . self::MARKER_SUFFIX;
 
@@ -3820,6 +3863,10 @@ class Parser {
                                $output = "<$name$attrText/>";
                        } else {
                                $close = is_null( $params['close'] ) ? '' : $frame->expand( $params['close'] );
+                               if ( substr( $close, 0, $errorLen ) === $errorStr ) {
+                                       // See above
+                                       return $close;
+                               }
                                $output = "<$name$attrText>$content$close";
                        }
                }
@@ -4114,12 +4161,13 @@ class Parser {
                        # * <b> (r105284)
                        # * <bdi> (bug 72884)
                        # * <span dir="rtl"> and <span dir="ltr"> (bug 35167)
+                       # * <s> and <strike> (T35715)
                        # We strip any parameter from accepted tags (second regex), except dir="rtl|ltr" from <span>,
                        # to allow setting directionality in toc items.
                        $tocline = preg_replace(
                                [
-                                       '#<(?!/?(span|sup|sub|bdi|i|b)(?: [^>]*)?>).*?>#',
-                                       '#<(/?(?:span(?: dir="(?:rtl|ltr)")?|sup|sub|bdi|i|b))(?: .*?)?>#'
+                                       '#<(?!/?(span|sup|sub|bdi|i|b|s|strike)(?: [^>]*)?>).*?>#',
+                                       '#<(/?(?:span(?: dir="(?:rtl|ltr)")?|sup|sub|bdi|i|b|s|strike))(?: .*?)?>#'
                                ],
                                [ '', '<$1>' ],
                                $safeHeadline
@@ -4364,7 +4412,11 @@ class Parser {
                $this->startParse( $title, $options, self::OT_WIKI, $clearState );
                $this->setUser( $user );
 
-               $text = str_replace( [ "\r\n", "\r" ], "\n", $text );
+               // We still normalize line endings for backwards-compatibility
+               // with other code that just calls PST, but this should already
+               // be handled in TextContent subclasses
+               $text = TextContent::normalizeLineEndings( $text );
+
                if ( $options->getPreSaveTransform() ) {
                        $text = $this->pstPass2( $text, $user );
                }
@@ -4442,9 +4494,6 @@ class Parser {
                        $text = preg_replace( $p2, '[[\\1]]', $text );
                }
 
-               # Trim trailing whitespace
-               $text = rtrim( $text );
-
                return $text;
        }