* @var string Deprecated accessor for the strip marker prefix.
* @deprecated since 1.26; use Parser::MARKER_PREFIX instead.
*/
- public $mUniqPrefix = Parser::MARKER_PREFIX;
+ public $mUniqPrefix = self::MARKER_PREFIX;
/**
* @var array Array with the language name of each language link (i.e. the
// Since we're not really outputting HTML, decode the entities and
// then re-encode the things that need hiding inside HTML comments.
$limitReport = htmlspecialchars_decode( $limitReport );
- Hooks::run( 'ParserLimitReport', [ $this, &$limitReport ] );
+ // Run deprecated hook
+ Hooks::run( 'ParserLimitReport', [ $this, &$limitReport ], '1.22' );
// Sanitize for comment. Note '‐' in the replacement is U+2010,
// which looks much like the problematic '-'.
return $text;
}
- /**
- * Get a random string
- *
- * @return string
- * @deprecated since 1.26; use wfRandomString() instead.
- */
- public static function getRandomString() {
- wfDeprecated( __METHOD__, '1.26' );
- return wfRandomString( 16 );
- }
-
/**
* Set the current user.
* Should only be used when doing pre-save transform.
$this->mUser = $user;
}
- /**
- * Accessor for mUniqPrefix.
- *
- * @return string
- * @deprecated since 1.26; use Parser::MARKER_PREFIX instead.
- */
- public function uniqPrefix() {
- wfDeprecated( __METHOD__, '1.26' );
- return self::MARKER_PREFIX;
- }
-
/**
* Set the context title
*
*
* @param array $elements List of element names. Comments are always extracted.
* @param string $text Source text string.
- * @param array $matches Out parameter, Array: extracted tags
- * @param string|null $uniq_prefix
+ * @param array &$matches Out parameter, Array: extracted tags
* @return string Stripped text
- * @since 1.26 The uniq_prefix argument is deprecated.
*/
- public static function extractTagsAndParams( $elements, $text, &$matches, $uniq_prefix = null ) {
- if ( $uniq_prefix !== null ) {
- wfDeprecated( __METHOD__ . ' called with $prefix argument', '1.26' );
- }
+ public static function extractTagsAndParams( $elements, $text, &$matches ) {
static $n = 1;
$stripped = '';
$matches = [];
* @return string
*/
public function doTableStuff( $text ) {
-
$lines = StringUtils::explode( "\n", $text );
$out = '';
$td_history = []; # Is currently a td tag open?
* @return string
*/
public function internalParse( $text, $isMain = true, $frame = false ) {
-
$origText = $text;
// Avoid PHP 7.1 warning from passing $this by reference
if ( !$frame->depth ) {
$flag = 0;
} else {
- $flag = Parser::PTD_FOR_INCLUSION;
+ $flag = self::PTD_FOR_INCLUSION;
}
$dom = $this->preprocessToDom( $text, $flag );
$text = $frame->expand( $dom );
* @return string
*/
public function replaceExternalLinks( $text ) {
-
$bits = preg_split( $this->mExtLinkBracketedRegex, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
if ( $bits === false ) {
throw new MWException( "PCRE needs to be compiled with "
/**
* Process [[ ]] wikilinks (RIL)
- * @param string $s
+ * @param string &$s
* @throws MWException
* @return LinkHolderArray
*
$link = $origLink;
}
- $noforce = ( substr( $origLink, 0, 1 ) !== ':' );
- if ( !$noforce ) {
- # Strip off leading ':'
- $link = substr( $link, 1 );
- }
-
$unstrip = $this->mStripState->unstripNoWiki( $link );
$nt = is_string( $unstrip ) ? Title::newFromText( $unstrip ) : null;
if ( $nt === null ) {
$ns = $nt->getNamespace();
$iw = $nt->getInterwiki();
+ $noforce = ( substr( $origLink, 0, 1 ) !== ':' );
+
if ( $might_be_img ) { # if this is actually an invalid link
if ( $ns == NS_FILE && $noforce ) { # but might be an image
$found = false;
$wasblank = ( $text == '' );
if ( $wasblank ) {
$text = $link;
+ if ( !$noforce ) {
+ # Strip off leading ':'
+ $text = substr( $text, 1 );
+ }
} else {
# T6598 madness. Handle the quotes only if they come from the alternate part
# [[Lista d''e paise d''o munno]] -> <a href="...">Lista d''e paise d''o munno</a>
}
$s = rtrim( $s . $prefix );
- $s .= trim( $trail, "\n" ) == '' ? '': $prefix . $trail;
+ $s .= trim( $trail, "\n" ) == '' ? '' : $prefix . $trail;
continue;
}
) ) );
break;
case 'talkpagename':
- if ( $this->mTitle->canTalk() ) {
+ if ( $this->mTitle->canHaveTalkPage() ) {
$talkPage = $this->mTitle->getTalkPage();
$value = wfEscapeWikiText( $talkPage->getPrefixedText() );
} else {
}
break;
case 'talkpagenamee':
- if ( $this->mTitle->canTalk() ) {
+ if ( $this->mTitle->canHaveTalkPage() ) {
$talkPage = $this->mTitle->getTalkPage();
$value = wfEscapeWikiText( $talkPage->getPrefixedURL() );
} else {
$value = $this->mTitle->getNamespace();
break;
case 'talkspace':
- $value = $this->mTitle->canTalk()
+ $value = $this->mTitle->canHaveTalkPage()
? str_replace( '_', ' ', $this->mTitle->getTalkNsText() )
: '';
break;
case 'talkspacee':
- $value = $this->mTitle->canTalk() ? wfUrlencode( $this->mTitle->getTalkNsText() ) : '';
+ $value = $this->mTitle->canHaveTalkPage() ? wfUrlencode( $this->mTitle->getTalkNsText() ) : '';
break;
case 'subjectspace':
$value = str_replace( '_', ' ', $this->mTitle->getSubjectNsText() );
* @return string The text of the template
*/
public function braceSubstitution( $piece, $frame ) {
-
// Flags
// $text has been filled
list( $callback, $flags ) = $this->mFunctionHooks[$function];
- # Workaround for PHP bug 35229 and similar
- if ( !is_callable( $callback ) ) {
- throw new MWException( "Tag hook for $function is not callable\n" );
- }
-
// Avoid PHP 7.1 warning from passing $this by reference
$parser = $this;
# string or an array containing the string and any flags. This mungs
# things around to match what this method should return.
if ( !is_array( $result ) ) {
- $result =[
+ $result = [
'found' => true,
'text' => $result,
];
* @return array
*/
public function argSubstitution( $piece, $frame ) {
-
$error = false;
$parts = $piece['parts'];
$nameWithSpaces = $frame->expand( $piece['title'] );
}
if ( isset( $this->mTagHooks[$name] ) ) {
- # Workaround for PHP bug 35229 and similar
- if ( !is_callable( $this->mTagHooks[$name] ) ) {
- throw new MWException( "Tag hook for $name is not callable\n" );
- }
$output = call_user_func_array( $this->mTagHooks[$name],
[ $content, $attributes, $this, $frame ] );
} elseif ( isset( $this->mFunctionTagHooks[$name] ) ) {
list( $callback, ) = $this->mFunctionTagHooks[$name];
- if ( !is_callable( $callback ) ) {
- throw new MWException( "Tag hook for $name is not callable\n" );
- }
// Avoid PHP 7.1 warning from passing $this by reference
$parser = $this;
* @return string
*/
public function doDoubleUnderscore( $text ) {
-
# The position of __TOC__ needs to be recorded
$mw = MagicWord::get( 'toc' );
if ( $mw->match( $text ) ) {
* @private
*/
public function formatHeadings( $text, $origText, $isMain = true ) {
- global $wgMaxTocLevel, $wgExperimentalHtmlIds;
+ global $wgMaxTocLevel;
# Inhibit editsection links if requested in the page
if ( isset( $this->mDoubleUnderscores['noeditsection'] ) ) {
# Save headline for section edit hint before it's escaped
$headlineHint = $safeHeadline;
- if ( $wgExperimentalHtmlIds ) {
- # For reverse compatibility, provide an id that's
- # HTML4-compatible, like we used to.
- # It may be worth noting, academically, that it's possible for
- # the legacy anchor to conflict with a non-legacy headline
- # anchor on the page. In this case likely the "correct" thing
- # would be to either drop the legacy anchors or make sure
- # they're numbered first. However, this would require people
- # to type in section names like "abc_.D7.93.D7.90.D7.A4"
- # manually, so let's not bother worrying about it.
- $legacyHeadline = Sanitizer::escapeId( $safeHeadline,
- [ 'noninitial', 'legacy' ] );
- $safeHeadline = Sanitizer::escapeId( $safeHeadline );
-
- if ( $legacyHeadline == $safeHeadline ) {
- # No reason to have both (in fact, we can't)
- $legacyHeadline = false;
- }
- } else {
- $legacyHeadline = false;
- $safeHeadline = Sanitizer::escapeId( $safeHeadline,
- 'noninitial' );
+ $fallbackHeadline = Sanitizer::escapeIdForAttribute( $safeHeadline, Sanitizer::ID_FALLBACK );
+ $linkAnchor = Sanitizer::escapeIdForLink( $safeHeadline );
+ $safeHeadline = Sanitizer::escapeIdForAttribute( $safeHeadline, Sanitizer::ID_PRIMARY );
+ if ( $fallbackHeadline === $safeHeadline ) {
+ # No reason to have both (in fact, we can't)
+ $fallbackHeadline = false;
}
- # HTML names must be case-insensitively unique (T12721).
- # This does not apply to Unicode characters per
- # https://www.w3.org/TR/html5/infrastructure.html#case-sensitivity-and-string-comparison
+ # HTML IDs must be case-insensitively unique for IE compatibility (T12721).
# @todo FIXME: We may be changing them depending on the current locale.
$arrayKey = strtolower( $safeHeadline );
- if ( $legacyHeadline === false ) {
- $legacyArrayKey = false;
+ if ( $fallbackHeadline === false ) {
+ $fallbackArrayKey = false;
} else {
- $legacyArrayKey = strtolower( $legacyHeadline );
+ $fallbackArrayKey = strtolower( $fallbackHeadline );
}
# Create the anchor for linking from the TOC to the section
$anchor = $safeHeadline;
- $legacyAnchor = $legacyHeadline;
+ $fallbackAnchor = $fallbackHeadline;
if ( isset( $refers[$arrayKey] ) ) {
// @codingStandardsIgnoreStart
for ( $i = 2; isset( $refers["${arrayKey}_$i"] ); ++$i );
// @codingStandardsIgnoreEnd
$anchor .= "_$i";
+ $linkAnchor .= "_$i";
$refers["${arrayKey}_$i"] = true;
} else {
$refers[$arrayKey] = true;
}
- if ( $legacyHeadline !== false && isset( $refers[$legacyArrayKey] ) ) {
+ if ( $fallbackHeadline !== false && isset( $refers[$fallbackArrayKey] ) ) {
// @codingStandardsIgnoreStart
- for ( $i = 2; isset( $refers["${legacyArrayKey}_$i"] ); ++$i );
+ for ( $i = 2; isset( $refers["${fallbackArrayKey}_$i"] ); ++$i );
// @codingStandardsIgnoreEnd
- $legacyAnchor .= "_$i";
- $refers["${legacyArrayKey}_$i"] = true;
+ $fallbackAnchor .= "_$i";
+ $refers["${fallbackArrayKey}_$i"] = true;
} else {
- $refers[$legacyArrayKey] = true;
+ $refers[$fallbackArrayKey] = true;
}
# Don't number the heading if it is the only one (looks silly)
}
if ( $enoughToc && ( !isset( $wgMaxTocLevel ) || $toclevel < $wgMaxTocLevel ) ) {
- $toc .= Linker::tocLine( $anchor, $tocline,
+ $toc .= Linker::tocLine( $linkAnchor, $tocline,
$numbering, $toclevel, ( $isTemplate ? false : $sectionIndex ) );
}
}
$head[$headlineCount] = Linker::makeHeadline( $level,
$matches['attrib'][$headlineCount], $anchor, $headline,
- $editlink, $legacyAnchor );
+ $editlink, $fallbackAnchor );
$headlineCount++;
}
# which may corrupt this parser instance via its wfMessage()->text() call-
# Signatures
- $sigText = $this->getUserSig( $user );
- $text = strtr( $text, [
- '~~~~~' => $d,
- '~~~~' => "$sigText $d",
- '~~~' => $sigText
- ] );
+ if ( strpos( $text, '~~~' ) !== false ) {
+ $sigText = $this->getUserSig( $user );
+ $text = strtr( $text, [
+ '~~~~~' => $d,
+ '~~~~' => "$sigText $d",
+ '~~~' => $sigText
+ ] );
+ # The main two signature forms used above are time-sensitive
+ $this->mOutput->setFlag( 'user-signature' );
+ }
# Context links ("pipe tricks"): [[|name]] and [[name (context)|]]
$tc = '[' . Title::legalChars() . ']';
* Do not reuse this parser instance after calling getUserSig(),
* as it may have changed if it's the $wgParser.
*
- * @param User $user
+ * @param User &$user
* @param string|bool $nickname Nickname to use or false to use user's default nickname
* @param bool|null $fancySig whether the nicknname is the complete signature
* or null to use default value
* @throws MWException
* @return callable|null The old value of the mTagHooks array associated with the hook
*/
- public function setHook( $tag, $callback ) {
+ public function setHook( $tag, callable $callback ) {
$tag = strtolower( $tag );
if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
throw new MWException( "Invalid character {$m[0]} in setHook('$tag', ...) call" );
* @throws MWException
* @return callable|null The old value of the mTagHooks array associated with the hook
*/
- public function setTransparentTagHook( $tag, $callback ) {
+ public function setTransparentTagHook( $tag, callable $callback ) {
$tag = strtolower( $tag );
if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
throw new MWException( "Invalid character {$m[0]} in setTransparentHook('$tag', ...) call" );
* @throws MWException
* @return string|callable The old callback function for this name, if any
*/
- public function setFunctionHook( $id, $callback, $flags = 0 ) {
+ public function setFunctionHook( $id, callable $callback, $flags = 0 ) {
global $wgContLang;
$oldVal = isset( $this->mFunctionHooks[$id] ) ? $this->mFunctionHooks[$id][0] : null;
* @throws MWException
* @return null
*/
- public function setFunctionTagHook( $tag, $callback, $flags ) {
+ public function setFunctionTagHook( $tag, callable $callback, $flags ) {
$tag = strtolower( $tag );
if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
throw new MWException( "Invalid character {$m[0]} in setFunctionTagHook('$tag', ...) call" );
* Replace "<!--LINK-->" link placeholders with actual links, in the buffer
* Placeholders created in Linker::link()
*
- * @param string $text
+ * @param string &$text
* @param int $options
*/
public function replaceLinkHolders( &$text, $options = 0 ) {
* @return string HTML
*/
public function renderImageGallery( $text, $params ) {
-
$mode = false;
if ( isset( $params['mode'] ) ) {
$mode = $params['mode'];
* Callback from the Sanitizer for expanding items found in HTML attribute
* values, so they can be safely tested and escaped.
*
- * @param string $text
+ * @param string &$text
* @param bool|PPFrame $frame
* @return string
*/
# Strip out wikitext links(they break the anchor)
$text = $this->stripSectionName( $text );
$text = Sanitizer::normalizeSectionNameWhitespace( $text );
- return '#' . Sanitizer::escapeId( $text, 'noninitial' );
+ return '#' . Sanitizer::escapeIdForLink( $text );
}
/**
* Same as guessSectionNameFromWikiText(), but produces legacy anchors
- * instead. For use in redirects, since IE6 interprets Redirect: headers
- * as something other than UTF-8 (apparently?), resulting in breakage.
+ * instead, if possible. For use in redirects, since various versions
+ * of Microsoft browsers interpret Location: headers as something other
+ * than UTF-8, resulting in breakage.
*
* @param string $text The section name
* @return string An anchor
*/
public function guessLegacySectionNameFromWikiText( $text ) {
+ global $wgFragmentMode;
+
# Strip out wikitext links(they break the anchor)
$text = $this->stripSectionName( $text );
$text = Sanitizer::normalizeSectionNameWhitespace( $text );
- return '#' . Sanitizer::escapeId( $text, [ 'noninitial', 'legacy' ] );
+
+ if ( isset( $wgFragmentMode[1] ) && $wgFragmentMode[1] === 'legacy' ) {
+ // ForAttribute() and ForLink() are the same for legacy encoding
+ $id = Sanitizer::escapeIdForAttribute( $text, Sanitizer::ID_FALLBACK );
+ } else {
+ $id = Sanitizer::escapeIdForLink( $text );
+ }
+
+ return "#$id";
}
/**
$e = new Exception;
$this->mInParse = $e->getTraceAsString();
- $recursiveCheck = new ScopedCallback( function() {
+ $recursiveCheck = new ScopedCallback( function () {
$this->mInParse = false;
} );