const SUPPORTS_UNWRAP_TRANSFORM = 1;
/**
- * @var string $mText The output text
+ * @var string|null $mText The output text
*/
- public $mText;
+ public $mText = null;
/**
* @var array $mLanguageLinks List of the full text of language links,
const SLOW_AR_TTL = 3600; // adaptive TTL for "slow" pages
const MIN_AR_TTL = 15; // min adaptive TTL (for sanity, pool counter, and edit stashing)
+ /**
+ * @param string|null $text HTML. Use null to indicate that this ParserOutput contains only
+ * meta-data, and the HTML output is undetermined, as opposed to empty. Passing null
+ * here causes hasText() to return false.
+ * @param array $languageLinks
+ * @param array $categoryLinks
+ * @param bool $unused
+ * @param string $titletext
+ */
public function __construct( $text = '', $languageLinks = [], $categoryLinks = [],
$unused = false, $titletext = ''
) {
$this->mTitleText = $titletext;
}
+ /**
+ * Returns true if text was passed to the constructor, or set using setText(). Returns false
+ * if null was passed to the $text parameter of the constructor to indicate that this
+ * ParserOutput only contains meta-data, and the HTML output is undetermined.
+ *
+ * @since 1.32
+ *
+ * @return bool Whether this ParserOutput contains rendered text. If this returns false, the
+ * ParserOutput contains meta-data only.
+ */
+ public function hasText() {
+ return ( $this->mText !== null );
+ }
+
/**
* Get the cacheable text with <mw:editsection> markers still in it. The
* return value is suitable for writing back via setText() but is not valid
* @since 1.27
*/
public function getRawText() {
+ if ( $this->mText === null ) {
+ throw new LogicException( 'This ParserOutput contains no text!' );
+ }
+
return $this->mText;
}
* the scheme-specific-part of the href is the (percent-encoded) value
* of the `data-mw-deduplicate` attribute.
* @return string HTML
+ * @return-taint escaped
*/
public function getText( $options = [] ) {
$options += [
'deduplicateStyles' => true,
'wrapperDivClass' => $this->getWrapperDivClass(),
];
- $text = $this->mText;
+ $text = $this->getRawText();
Hooks::runWithoutAbort( 'ParserOutputPostCacheTransform', [ $this, &$text, &$options ] );
);
}
+ // TODO remove this method once old parser cache objects have expired, probably mid-October 2018
+ public function __wakeup() {
+ // T203716 remove wrapper that was added by logic in an older version of this class,
+ // where the wrapper was included in mText. This might sometimes remove a wrapper that's
+ // genuine content (manually added to a system message), but that will work out OK, see below.
+ $text = $this->getRawText();
+ $start = Html::openElement( 'div', [
+ 'class' => 'mw-parser-output'
+ ] );
+ $startLen = strlen( $start );
+ $end = Html::closeElement( 'div' );
+ $endPos = strrpos( $text, $end );
+ $endLen = strlen( $end );
+ if ( substr( $text, 0, $startLen ) === $start && $endPos !== false
+ // if the closing div is followed by real content, bail out of unwrapping
+ && preg_match( '/^(?>\s*<!--.*?-->)*\s*$/s', substr( $text, $endPos + $endLen ) )
+ ) {
+ $text = substr( $text, $startLen );
+ $text = substr( $text, 0, $endPos - $startLen ) .
+ substr( $text, $endPos - $startLen + $endLen );
+ $this->setText( $text );
+ // We found a wrapper to remove, so the ParserOutput was probably created by the
+ // code path that now contains an addWrapperDivClass( 'mw-parser-output' ) call,
+ // but it did not contain it when this object was cached, so we need to fix the
+ // wrapper class variable.
+ // If this was a message with a manually added wrapper, we are technically wrong about
+ // this but we were wrong about the unwrapping as well so it will work out just right,
+ // except when this is a normal page view of such a message page, in which case
+ // it will be single-wrapped instead of double-wrapped (harmless) or something wants
+ // render the message with unwrap=true (in which case the message won't be wrapped even
+ // though it should, but the few code paths using unwrap=true only do it for real pages).
+ $this->clearWrapperDivClass();
+ $this->addWrapperDivClass( 'mw-parser-output' );
+ }
+ }
+
/**
* Merges internal metadata such as flags, accessed options, and profiling info
* from $source into this ParserOutput. This should be used whenever the state of $source