# Constants needed for external link processing
# Everything except bracket, space, or control characters
- const EXT_LINK_URL_CLASS = '(?:[^\]\[<>"\\x00-\\x20\\x7F]|(?:\[\]))';
+ const EXT_LINK_URL_CLASS = '[^][<>"\\x00-\\x20\\x7F]';
const EXT_IMAGE_REGEX = '/^(http:\/\/|https:\/\/)([^][<>"\\x00-\\x20\\x7F]+)
\\/([A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF]+)\\.((?i)gif|png|jpg|jpeg)$/Sx';
var $mImageParamsMagicArray = array();
var $mMarkerIndex = 0;
var $mFirstCall = true;
- var $mVariables, $mSubstWords; # Initialised by initialiseVariables()
+
+ # Initialised by initialiseVariables()
+
+ /**
+ * @var MagicWordArray
+ */
+ var $mVariables;
+
+ /**
+ * @var MagicWordArray
+ */
+ var $mSubstWords;
var $mConf, $mPreprocessor, $mExtLinkBracketedRegex, $mUrlProtocols; # Initialised in constructor
# Cleared with clearState():
var $mStripState;
var $mIncludeCount, $mArgStack, $mLastSection, $mInPre;
- var $mLinkHolders, $mLinkID;
+ /**
+ * @var LinkHolderArray
+ */
+ var $mLinkHolders;
+
+ var $mLinkID;
var $mIncludeSizes, $mPPNodeCount, $mDefaultSort;
var $mTplExpandCache; # empty-frame expansion cache
var $mTplRedirCache, $mTplDomCache, $mHeadings, $mDoubleUnderscores;
var $mRevisionObject; # The revision object of the specified revision ID
var $mRevisionId; # ID to display in {{REVISIONID}} tags
var $mRevisionTimestamp; # The timestamp of the specified revision ID
- var $mRevisionUser; # Userto display in {{REVISIONUSER}} tag
+ var $mRevisionUser; # User to display in {{REVISIONUSER}} tag
var $mRevIdForTs; # The revision ID which was used to fetch the timestamp
+ /**
+ * @var string
+ */
+ var $mUniqPrefix;
+
/**
* Constructor
*/
$this->mConf = $conf;
$this->mUrlProtocols = wfUrlProtocols();
$this->mExtLinkBracketedRegex = '/\[(\b(' . wfUrlProtocols() . ')'.
- '(?:[^\]\[<>"\x00-\x20\x7F]|\[\])+) *([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]/S';
+ '[^][<>"\\x00-\\x20\\x7F]+) *([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]/S';
if ( isset( $conf['preprocessorClass'] ) ) {
$this->mPreprocessorClass = $conf['preprocessorClass'];
+ } elseif ( defined( 'MW_COMPILED' ) ) {
+ # Preprocessor_Hash is much faster than Preprocessor_DOM in compiled mode
+ $this->mPreprocessorClass = 'Preprocessor_Hash';
} elseif ( extension_loaded( 'domxml' ) ) {
# PECL extension that conflicts with the core DOM extension (bug 13770)
wfDebug( "Warning: you have the obsolete domxml extension for PHP. Please remove it!\n" );
} else {
$this->mPreprocessorClass = 'Preprocessor_Hash';
}
+ wfDebug( __CLASS__ . ": using preprocessor: {$this->mPreprocessorClass}\n" );
}
/**
*
* @param $text String: text extension wants to have parsed
* @param $frame PPFrame: The frame to use for expanding any template variables
+ *
+ * @return string
*/
function recursiveTagParse( $text, $frame=false ) {
wfProfileIn( __METHOD__ );
/**
* Get a random string
+ *
+ * @return string
*/
static public function getRandomString() {
return dechex( mt_rand( 0, 0x7fffffff ) ) . dechex( mt_rand( 0, 0x7fffffff ) );
/**
* Set the context title
+ *
+ * @param $t Title
*/
function setTitle( $t ) {
if ( !$t || $t instanceof FakeTitle ) {
return wfSetVar( $this->mOptions, $x );
}
+ /**
+ * @return int
+ */
function nextLinkID() {
return $this->mLinkID++;
}
+ /**
+ * @param $id int
+ */
function setLinkID( $id ) {
$this->mLinkID = $id;
}
if ( $target !== null ) {
return $target;
} else {
- return $this->mOptions->getInterfaceMessage() ? $wgLang : $wgContLang;
+ return $this->mOptions->getInterfaceMessage() ? $wgLang : $this->mTitle->getPageLanguage();
}
}
* array( 'param' => 'x' ),
* '<element param="x">tag content</element>' ) )
*
- * @param $elements list of element names. Comments are always extracted.
- * @param $text Source text string.
- * @param $matches Out parameter, Array: extracted tags
- * @param $uniq_prefix
+ * @param $elements array list of element names. Comments are always extracted.
+ * @param $text string Source text string.
+ * @param $matches array Out parameter, Array: extracted tags
+ * @param $uniq_prefix string
* @return String: stripped text
*/
public static function extractTagsAndParams( $elements, $text, &$matches, $uniq_prefix = '' ) {
/**
* Get a list of strippable XML-like elements
+ *
+ * @return array
*/
function getStripList() {
return $this->mStripList;
* Add an item to the strip state
* Returns the unique tag which must be inserted into the stripped text
* The tag will be replaced with the original text in unstrip()
- *
- * @private
*/
function insertStripItem( $text ) {
$rnd = "{$this->mUniqPrefix}-item-{$this->mMarkerIndex}-" . self::MARKER_SUFFIX;
# empty line, go to next line,
# but only append \n if outside of table
- if ( $line === '') {
+ if ( $line === '') {
$output .= $outLine . "\n";
continue;
}
if ( $attributes !== '' ) {
$table['attributes'] = $attributes;
}
- } else if ( !isset( $tables[0] ) ) {
+ } elseif ( !isset( $tables[0] ) ) {
// we're outside the table
$out .= $outLine . "\n";
- } else if ( $firstChars === '|}' ) {
+ } elseif ( $firstChars === '|}' ) {
// trim the |} code from the line
$line = substr ( $line , 2 );
$output .= $o;
- } else if ( $firstChars === '|-' ) {
+ } elseif ( $firstChars === '|-' ) {
// start a new row element
// but only when we haven't started one already
if ( count( $currentRow ) != 0 ) {
$currentRow['attributes'] = $attributes;
}
- } else if ( $firstChars === '|+' ) {
+ } elseif ( $firstChars === '|+' ) {
// a table caption, but only proceed if there isn't one already
if ( !isset ( $table['caption'] ) ) {
$line = substr ( $line , 2 );
-
+
$c = $this->getCellAttr( $line , 'caption' );
$table['caption'] = array();
$table['caption']['content'] = $c[0];
unset( $c );
$output =& $table['caption']['content'];
}
- } else if ( $firstChars === '|' || $firstChars === '!' || $firstChars === '!+' ) {
+ } elseif ( $firstChars === '|' || $firstChars === '!' || $firstChars === '!+' ) {
// Which kind of cells are we dealing with
$currentTag = 'td';
$line = substr ( $line , 1 );
// decide whether thead to tbody
if ( !array_key_exists( 'type', $currentRow ) ) {
$currentRow['type'] = ( $firstChars === '!' ) ? 'thead' : 'tbody' ;
- } else if ( $firstChars === '|' ) {
+ } elseif ( $firstChars === '|' ) {
$currentRow['type'] = 'tbody';
}
/**
* Helper function for doTableStuff() separating the contents of cells from
- * attributes. Particularly useful as there's a possible bug and this action
+ * attributes. Particularly useful as there's a possible bug and this action
* is repeated twice.
*
* @private
+ * @param $cell
+ * @param $tagName
+ * @return array
*/
function getCellAttr ( $cell, $tagName ) {
- $content = null;
$attributes = null;
$cell = trim ( $cell );
if ( strpos( $cellData[0], '[[' ) !== false ) {
$content = trim ( $cell );
}
- else if ( count ( $cellData ) == 1 ) {
+ elseif ( count ( $cellData ) == 1 ) {
$content = trim ( $cellData[0] );
- }
- else {
+ } else {
$attributes = $this->mStripState->unstripBoth( $cellData[0] );
$attributes = Sanitizer::fixTagAttributes( $attributes , $tagName );
*
* @private
*/
- function generateTableHTML ( &$table ) {
+ function generateTableHTML( &$table ) {
$return = "";
$return .= str_repeat( '<dl><dd>' , $table['indent'] );
$return .= '<table';
// If we only have tbodies, mark table as simple
for ( $i = 0; isset( $table[$i] ); $i++ ) {
if ( !count( $table[$i] ) ) continue;
- if ( !isset( $table[$i]['type'] ) ) $table[$i]['type'] = 'tbody';
+ if ( !isset( $table[$i]['type'] ) ) {
+ $table[$i]['type'] = 'tbody';
+ }
if ( !$lastSection ) {
$lastSection = $table[$i]['type'];
- } else if ( $lastSection != $table[$i]['type'] ) {
+ } elseif ( $lastSection != $table[$i]['type'] ) {
$simple = false;
- break;
}
}
$lastSection = '';
for ( $i = 0; isset( $table[$i] ); $i++ ) {
- // Check for empty tables
- if ( count( $table[$i] ) ) {
- $empty = false;
- } else {
- continue;
- }
+ if ( !count( $table[$i] ) ) continue;
+ $empty = false; // check for empty tables
+
if ( $table[$i]['type'] != $lastSection && !$simple ) {
$return .= "\n<" . $table[$i]['type'] . '>';
}
return $text;
}
+ /**
+ * @throws MWException
+ * @param $m array
+ * @return HTML|string
+ */
function magicLinkCallback( $m ) {
if ( isset( $m[1] ) && $m[1] !== '' ) {
# Skip anchor
$args = ( null == $piece['parts'] ) ? array() : $piece['parts'];
wfProfileOut( __METHOD__.'-setup' );
wfProfileIn( __METHOD__."-title-$originalTitle" );
-
+
# SUBST
wfProfileIn( __METHOD__.'-modifiers' );
if ( !$found ) {
# Register the file as a dependency...
$this->mOutput->addImage( $title->getDBkey(), $time, $sha1 );
if ( $file && !$title->equals( $file->getTitle() ) ) {
- # Update fetched file title
+ # Update fetched file title
$title = $file->getTitle();
}
return array( $file, $title );
/**
* Transclude an interwiki link.
*
+ * @param $title Title
+ * @param $action
+ *
* @return string
*/
function interwikiTransclude( $title, $action ) {
if ( $dot ) {
$numbering .= '.';
}
- $numbering .= $wgContLang->formatNum( $sublevelCount[$i] );
+ $numbering .= $this->getFunctionLang()->formatNum( $sublevelCount[$i] );
$dot = 1;
}
}
# If we're still here, make it a link to the user page
$userText = wfEscapeWikiText( $username );
$nickText = wfEscapeWikiText( $nickname );
- if ( $user->isAnon() ) {
- return wfMsgExt( 'signature-anon', array( 'content', 'parsemag' ), $userText, $nickText );
- } else {
- return wfMsgExt( 'signature', array( 'content', 'parsemag' ), $userText, $nickText );
- }
+ $msgName = $user->isAnon() ? 'signature-anon' : 'signature';
+
+ return wfMessage( $msgName, $userText, $nickText )->inContentLanguage()->title( $this->getTitle() )->text();
}
/**
/**
* Remove a specific tag hook. Should not be called on $wgParser.
+ * Does not change the strip list.
*
* @param string $tag
* @return void
function clearTagHook( $tag ) {
if ( isset( $this->mTagHooks[$tag] ) ) {
unset( $this->mTagHooks[$tag] );
- $key = array_search( $tag, $this->mStripList );
- if ( $key !== false ) {
- unset( $this->mStripList[$key] );
- }
}
}
# Bogus title. Ignore these so we don't bomb out later.
continue;
}
-
+
$label = '';
$alt = '';
if ( isset( $matches[3] ) ) {
// look for an |alt= definition while trying not to break existing
// captions with multiple pipes (|) in it, until a more sensible grammar
// is defined for images in galleries
-
+
$matches[3] = $this->recursiveTagParse( trim( $matches[3] ) );
$altmatches = StringUtils::explode('|', $matches[3]);
$magicWordAlt = MagicWord::get( 'img_alt' );
return $ret;
}
+ /**
+ * @param $caption
+ * @param $holders LinkHolderArray
+ * @return mixed|String
+ */
protected function stripAltText( $caption, $holders ) {
# Strip bad stuff out of the title (tooltip). We can't just use
# replaceLinkHoldersText() here, because if this function is called
$matches = array();
$elements = array_keys( $this->mTransparentTagHooks );
$text = self::extractTagsAndParams( $elements, $text, $matches, $this->mUniqPrefix );
+ $replacements = array();
foreach ( $matches as $marker => $data ) {
list( $element, $content, $params, $tag ) = $data;
} else {
$output = $tag;
}
- $this->mStripState->addGeneral( $marker, $output );
+ $replacements[$marker] = $output;
}
- return $text;
+ return strtr( $text, $replacements );
}
/**
* @param $newText String: replacement text for section data.
* @return String: for "get", the extracted section text.
* for "replace", the whole page with the section replaced.
+ * If the page is empty and section 0 is requested, $text (as '')
+ * is returned
*/
private function extractSections( $text, $section, $mode, $newText='' ) {
global $wgTitle; # not generally used but removes an ugly failure mode
*
* @return string
*/
- function testSrvus( $text, $title, ParserOptions $options, $outputType = self::OT_HTML ) {
- if ( !$title instanceof Title ) {
- $title = Title::newFromText( $title );
- }
+ function testSrvus( $text, Title $title, ParserOptions $options, $outputType = self::OT_HTML ) {
$this->startParse( $title, $options, $outputType, true );
$text = $this->replaceVariables( $text );
return $text;
}
- function testPst( $text, $title, $options ) {
- global $wgUser;
- if ( !$title instanceof Title ) {
- $title = Title::newFromText( $title );
- }
- return $this->preSaveTransform( $text, $title, $wgUser, $options );
+ function testPst( $text, Title $title, ParserOptions $options ) {
+ return $this->preSaveTransform( $text, $title, $options->getUser(), $options );
}
- function testPreprocess( $text, $title, $options ) {
- if ( !$title instanceof Title ) {
- $title = Title::newFromText( $title );
- }
+ function testPreprocess( $text, Title $title, ParserOptions $options ) {
return $this->testSrvus( $text, $title, $options, self::OT_PREPROCESS );
}