jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/393260 )
Change subject: ParserOutput: Add stateless transforms to getText()
......................................................................
ParserOutput: Add stateless transforms to getText()
The stateful transforms are deprecated.
Inspired by Krinkle's If2fb32fc.
Bug: T171797
Change-Id: Ied5fe1a6159c2d4fa48170042b44d735ce7b6f9b
---
M RELEASE-NOTES-1.31
M docs/hooks.txt
M includes/parser/ParserOptions.php
M includes/parser/ParserOutput.php
M tests/phpunit/includes/parser/ParserOutputTest.php
5 files changed, 298 insertions(+), 4 deletions(-)
Approvals:
Legoktm: Looks good to me, approved
jenkins-bot: Verified
diff --git a/RELEASE-NOTES-1.31 b/RELEASE-NOTES-1.31
index b32e3e7..139773b 100644
--- a/RELEASE-NOTES-1.31
+++ b/RELEASE-NOTES-1.31
@@ -31,6 +31,8 @@
[[iw:User:Example|iw>Example]].
* (T111605) The 'ImportHandleUnknownUser' hook allows extensions to auto-create
users during an import.
+* Added a hook, ParserOutputPostCacheTransform, to allow extensions to affect
+ the ParserOutput::getText() post-cache transformations.
=== External library changes in 1.31 ===
@@ -119,6 +121,18 @@
* The Block class will no longer accept usable-but-missing usernames for
'byText' or ->setBlocker(). Callers should either ensure the blocker exists
locally or use a new interwiki-format username like "iw>Example".
+* The following methods that get and set ParserOutput state are deprecated.
+ Callers should use the new stateless $options parameter to
+ ParserOutput::getText() instead.
+ * ParserOptions::getEditSection()
+ * ParserOptions::setEditSection()
+ * ParserOutput::getEditSectionTokens()
+ * ParserOutput::setEditSectionTokens()
+ * ParserOutput::getTOCEnabled()
+ * ParserOutput::setTOCEnabled()
+ * OutputPage::enableSectionEditLinks()
+ * OutputPage::sectionEditLinksEnabled()
+ * The public ParserOutput state fields $mTOCEnabled and $mEditSectionTokens
are also deprecated.
== Compatibility ==
MediaWiki 1.31 requires PHP 5.5.9 or later. There is experimental support for
diff --git a/docs/hooks.txt b/docs/hooks.txt
index 685a182..29883b2 100644
--- a/docs/hooks.txt
+++ b/docs/hooks.txt
@@ -2594,6 +2594,12 @@
callable here. The callable is passed the ParserOptions object and the option
name.
+'ParserOutputPostCacheTransform': Called from ParserOutput::getText() to do
+post-cache transforms.
+$parserOutput: The ParserOutput object.
+&$text: The text being transformed, before core transformations are done.
+&$options: The options array being used for the transformation.
+
'ParserSectionCreate': Called each time the parser creates a document section
from wikitext. Use this to apply per-section modifications to HTML (like
wrapping the section in a DIV). Caveat: DIVs are valid wikitext, and a DIV
diff --git a/includes/parser/ParserOptions.php
b/includes/parser/ParserOptions.php
index 5e2845f..f99089b 100644
--- a/includes/parser/ParserOptions.php
+++ b/includes/parser/ParserOptions.php
@@ -869,6 +869,7 @@
/**
* Create "edit section" links?
+ * @deprecated since 1.31, use ParserOutput::getText() options instead.
* @return bool
*/
public function getEditSection() {
@@ -877,6 +878,7 @@
/**
* Create "edit section" links?
+ * @deprecated since 1.31, use ParserOutput::getText() options instead.
* @param bool|null $x New value (null is no change)
* @return bool Old value
*/
diff --git a/includes/parser/ParserOutput.php b/includes/parser/ParserOutput.php
index 3480a51..59c27e5 100644
--- a/includes/parser/ParserOutput.php
+++ b/includes/parser/ParserOutput.php
@@ -144,6 +144,7 @@
public $mSections = [];
/**
+ * @deprecated since 1.31 Use getText() options.
* @var bool $mEditSectionTokens prefix/suffix markers if edit sections
were output as tokens.
*/
public $mEditSectionTokens = false;
@@ -164,6 +165,7 @@
public $mTimestamp;
/**
+ * @deprecated since 1.31 Use getText() options.
* @var bool $mTOCEnabled Whether TOC should be shown, can't override
__NOTOC__.
*/
public $mTOCEnabled = true;
@@ -250,9 +252,38 @@
return $this->mText;
}
- public function getText() {
+ /**
+ * Get the output HTML
+ *
+ * @param array $options (since 1.31) Transformations to apply to the
HTML
+ * - allowTOC: (bool) Show the TOC, assuming there were enough headings
+ * to generate one and `__NOTOC__` wasn't used. Default is true,
+ * but might be statefully overridden.
+ * - enableSectionEditLinks: (bool) Include section edit links,
assuming
+ * section edit link tokens are present in the HTML. Default is true,
+ * but might be statefully overridden.
+ * @return string HTML
+ */
+ public function getText( $options = [] ) {
+ // @todo Warn if !array_key_exists( 'allowTOC', $options ) &&
empty( $this->mTOCEnabled )
+
+ // @todo Warn if !array_key_exists( 'enableSectionEditLinks',
$options )
+ // && !$this->mEditSectionTokens
+ // Note that while $this->mEditSectionTokens defaults to false,
+ // ParserOptions->getEditSection() defaults to true and Parser
copies
+ // that to us so true makes more sense as the stateless
default.
+
+ $options += [
+ // empty() here because old cached versions might lack
the field somehow.
+ // In that situation, the historical behavior (possibly
buggy) is to remove the TOC.
+ 'allowTOC' => !empty( $this->mTOCEnabled ),
+ 'enableSectionEditLinks' => $this->mEditSectionTokens,
+ ];
$text = $this->mText;
- if ( $this->mEditSectionTokens ) {
+
+ Hooks::runWithoutAbort( 'ParserOutputPostCacheTransform', [
$this, &$text, &$options ] );
+
+ if ( $options['enableSectionEditLinks'] ) {
$text = preg_replace_callback(
self::EDITSECTION_REGEX,
function ( $m ) {
@@ -278,8 +309,7 @@
$text = preg_replace( self::EDITSECTION_REGEX, '',
$text );
}
- // If you have an old cached version of this class - sorry, you
can't disable the TOC
- if ( isset( $this->mTOCEnabled ) && $this->mTOCEnabled ) {
+ if ( $options['allowTOC'] ) {
$text = str_replace( [ Parser::TOC_START,
Parser::TOC_END ], '', $text );
} else {
$text = preg_replace(
@@ -288,6 +318,7 @@
$text
);
}
+
return $text;
}
@@ -339,6 +370,9 @@
return $this->mSections;
}
+ /**
+ * @deprecated since 1.31 Use getText() options.
+ */
public function getEditSectionTokens() {
return $this->mEditSectionTokens;
}
@@ -426,6 +460,9 @@
return $this->mLimitReportJSData;
}
+ /**
+ * @deprecated since 1.31 Use getText() options.
+ */
public function getTOCEnabled() {
return $this->mTOCEnabled;
}
@@ -454,6 +491,9 @@
return wfSetVar( $this->mSections, $toc );
}
+ /**
+ * @deprecated since 1.31 Use getText() options.
+ */
public function setEditSectionTokens( $t ) {
return wfSetVar( $this->mEditSectionTokens, $t );
}
@@ -470,6 +510,9 @@
return wfSetVar( $this->mTimestamp, $timestamp );
}
+ /**
+ * @deprecated since 1.31 Use getText() options.
+ */
public function setTOCEnabled( $flag ) {
return wfSetVar( $this->mTOCEnabled, $flag );
}
diff --git a/tests/phpunit/includes/parser/ParserOutputTest.php
b/tests/phpunit/includes/parser/ParserOutputTest.php
index ec8f0d0..441d60d 100644
--- a/tests/phpunit/includes/parser/ParserOutputTest.php
+++ b/tests/phpunit/includes/parser/ParserOutputTest.php
@@ -1,5 +1,7 @@
<?php
+use Wikimedia\TestingAccessWrapper;
+
/**
* @group Database
* ^--- trigger DB shadowing because we are using Title magic
@@ -89,4 +91,231 @@
$this->assertArrayNotHasKey( 'foo', $properties );
}
+ /**
+ * @covers ParserOutput::getText
+ * @dataProvider provideGetText
+ * @param array $options Options to getText()
+ * @param array $poState ParserOptions state fields to set
+ * @param string $text Parser text
+ * @param string $expect Expected output
+ */
+ public function testGetText( $options, $poState, $text, $expect ) {
+ $this->setMwGlobals( [
+ 'wgArticlePath' => '/wiki/$1',
+ 'wgScriptPath' => '/w',
+ 'wgScript' => '/w/index.php',
+ ] );
+
+ $po = new ParserOutput( $text );
+
+ // Emulate Parser
+ $po->setEditSectionTokens( true );
+
+ if ( $poState ) {
+ $wrap = TestingAccessWrapper::newFromObject( $po );
+ foreach ( $poState as $key => $value ) {
+ $wrap->$key = $value;
+ }
+ }
+
+ $actual = $po->getText( $options );
+ $this->assertSame( $expect, $actual );
+ }
+
+ public static function provideGetText() {
+ // @codingStandardsIgnoreStart Generic.Files.LineLength
+ $text = <<<EOF
+<p>Test document.
+</p>
+<mw:toc><div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#Section_1"><span
class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
+<li class="toclevel-1 tocsection-2"><a href="#Section_2"><span
class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
+<ul>
+<li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span
class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
+</ul>
+</li>
+<li class="toclevel-1 tocsection-4"><a href="#Section_3"><span
class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
+</ul>
+</div>
+</mw:toc>
+<h2><span class="mw-headline" id="Section_1">Section 1</span><mw:editsection
page="Test Page" section="1">Section 1</mw:editsection></h2>
+<p>One
+</p>
+<h2><span class="mw-headline" id="Section_2">Section 2</span><mw:editsection
page="Test Page" section="2">Section 2</mw:editsection></h2>
+<p>Two
+</p>
+<h3><span class="mw-headline" id="Section_2.1">Section
2.1</span><mw:editsection page="Test Page" section="3">Section
2.1</mw:editsection></h3>
+<p>Two point one
+</p>
+<h2><span class="mw-headline" id="Section_3">Section 3</span><mw:editsection
page="Test Page" section="4">Section 3</mw:editsection></h2>
+<p>Three
+</p>
+EOF;
+
+ return [
+ 'No stateless options, default state' => [
+ [], [], $text, <<<EOF
+<p>Test document.
+</p>
+<div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#Section_1"><span
class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
+<li class="toclevel-1 tocsection-2"><a href="#Section_2"><span
class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
+<ul>
+<li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span
class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
+</ul>
+</li>
+<li class="toclevel-1 tocsection-4"><a href="#Section_3"><span
class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
+</ul>
+</div>
+
+<h2><span class="mw-headline" id="Section_1">Section 1</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=1" title="Edit
section: Section 1">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>One
+</p>
+<h2><span class="mw-headline" id="Section_2">Section 2</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=2" title="Edit
section: Section 2">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>Two
+</p>
+<h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=3" title="Edit
section: Section 2.1">edit</a><span
class="mw-editsection-bracket">]</span></span></h3>
+<p>Two point one
+</p>
+<h2><span class="mw-headline" id="Section_3">Section 3</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=4" title="Edit
section: Section 3">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>Three
+</p>
+EOF
+ ],
+ 'No stateless options, TOC statefully disabled' => [
+ [], [ 'mTOCEnabled' => false ], $text, <<<EOF
+<p>Test document.
+</p>
+
+<h2><span class="mw-headline" id="Section_1">Section 1</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=1" title="Edit
section: Section 1">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>One
+</p>
+<h2><span class="mw-headline" id="Section_2">Section 2</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=2" title="Edit
section: Section 2">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>Two
+</p>
+<h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=3" title="Edit
section: Section 2.1">edit</a><span
class="mw-editsection-bracket">]</span></span></h3>
+<p>Two point one
+</p>
+<h2><span class="mw-headline" id="Section_3">Section 3</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=4" title="Edit
section: Section 3">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>Three
+</p>
+EOF
+ ],
+ 'No stateless options, section edits statefully
disabled' => [
+ [], [ 'mEditSectionTokens' => false ], $text,
<<<EOF
+<p>Test document.
+</p>
+<div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#Section_1"><span
class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
+<li class="toclevel-1 tocsection-2"><a href="#Section_2"><span
class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
+<ul>
+<li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span
class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
+</ul>
+</li>
+<li class="toclevel-1 tocsection-4"><a href="#Section_3"><span
class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
+</ul>
+</div>
+
+<h2><span class="mw-headline" id="Section_1">Section 1</span></h2>
+<p>One
+</p>
+<h2><span class="mw-headline" id="Section_2">Section 2</span></h2>
+<p>Two
+</p>
+<h3><span class="mw-headline" id="Section_2.1">Section 2.1</span></h3>
+<p>Two point one
+</p>
+<h2><span class="mw-headline" id="Section_3">Section 3</span></h2>
+<p>Three
+</p>
+EOF
+ ],
+ 'Stateless options override stateful settings' => [
+ [ 'allowTOC' => true, 'enableSectionEditLinks'
=> true ],
+ [ 'mTOCEnabled' => false, 'mEditSectionTokens'
=> false ],
+ $text, <<<EOF
+<p>Test document.
+</p>
+<div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#Section_1"><span
class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
+<li class="toclevel-1 tocsection-2"><a href="#Section_2"><span
class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
+<ul>
+<li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span
class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
+</ul>
+</li>
+<li class="toclevel-1 tocsection-4"><a href="#Section_3"><span
class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
+</ul>
+</div>
+
+<h2><span class="mw-headline" id="Section_1">Section 1</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=1" title="Edit
section: Section 1">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>One
+</p>
+<h2><span class="mw-headline" id="Section_2">Section 2</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=2" title="Edit
section: Section 2">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>Two
+</p>
+<h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=3" title="Edit
section: Section 2.1">edit</a><span
class="mw-editsection-bracket">]</span></span></h3>
+<p>Two point one
+</p>
+<h2><span class="mw-headline" id="Section_3">Section 3</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=4" title="Edit
section: Section 3">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>Three
+</p>
+EOF
+ ],
+ 'Statelessly disable section edit links' => [
+ [ 'enableSectionEditLinks' => false ], [],
$text, <<<EOF
+<p>Test document.
+</p>
+<div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#Section_1"><span
class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
+<li class="toclevel-1 tocsection-2"><a href="#Section_2"><span
class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
+<ul>
+<li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span
class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
+</ul>
+</li>
+<li class="toclevel-1 tocsection-4"><a href="#Section_3"><span
class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
+</ul>
+</div>
+
+<h2><span class="mw-headline" id="Section_1">Section 1</span></h2>
+<p>One
+</p>
+<h2><span class="mw-headline" id="Section_2">Section 2</span></h2>
+<p>Two
+</p>
+<h3><span class="mw-headline" id="Section_2.1">Section 2.1</span></h3>
+<p>Two point one
+</p>
+<h2><span class="mw-headline" id="Section_3">Section 3</span></h2>
+<p>Three
+</p>
+EOF
+ ],
+ 'Statelessly disable TOC' => [
+ [ 'allowTOC' => false ], [], $text, <<<EOF
+<p>Test document.
+</p>
+
+<h2><span class="mw-headline" id="Section_1">Section 1</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=1" title="Edit
section: Section 1">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>One
+</p>
+<h2><span class="mw-headline" id="Section_2">Section 2</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=2" title="Edit
section: Section 2">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>Two
+</p>
+<h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=3" title="Edit
section: Section 2.1">edit</a><span
class="mw-editsection-bracket">]</span></span></h3>
+<p>Two point one
+</p>
+<h2><span class="mw-headline" id="Section_3">Section 3</span><span
class="mw-editsection"><span class="mw-editsection-bracket">[</span><a
href="/w/index.php?title=Test_Page&action=edit&section=4" title="Edit
section: Section 3">edit</a><span
class="mw-editsection-bracket">]</span></span></h2>
+<p>Three
+</p>
+EOF
+ ],
+ ];
+ // @codingStandardsIgnoreEnd
+ }
+
}
--
To view, visit https://gerrit.wikimedia.org/r/393260
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ied5fe1a6159c2d4fa48170042b44d735ce7b6f9b
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Anomie <[email protected]>
Gerrit-Reviewer: Anomie <[email protected]>
Gerrit-Reviewer: C. Scott Ananian <[email protected]>
Gerrit-Reviewer: Jackmcbarn <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits