From: Max Semenik Date: Thu, 22 Aug 2013 22:22:03 +0000 (+0400) Subject: Make TOC hideable X-Git-Tag: 1.31.0-rc.0~18404^2 X-Git-Url: http://git.cyclocoop.org/%7B%24www_url%7Dadmin/password.php?a=commitdiff_plain;h=21c1c7d025365540f17be4f7ae19184e1ccca4cc;p=lhc%2Fweb%2Fwiklou.git Make TOC hideable Currently, if an extension doesn't want a TOC, it has to remove it manually. This change wraps the TOC in markers that make it easy to remove it in ParserOutput on demand without fragmenting the parser cache with stuff like "use/not use TOC". Change-Id: I2889bcb9eb999c9049601e92440132118e1a8a41 --- diff --git a/includes/OutputPage.php b/includes/OutputPage.php index cc3f9b3689..ffaf77d266 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -255,6 +255,11 @@ class OutputPage extends ContextSource { */ private $mTarget = null; + /** + * @var bool: Whether output should contain table of contents + */ + private $mEnableTOC = true; + /** * Constructor for OutputPage. This should not be called directly. * Instead a new RequestContext should be created and it will implicitly create @@ -1606,6 +1611,7 @@ class OutputPage extends ContextSource { */ function addParserOutput( &$parserOutput ) { $this->addParserOutputNoText( $parserOutput ); + $parserOutput->setTOCEnabled( $this->mEnableTOC ); $text = $parserOutput->getText(); wfRunHooks( 'OutputPageBeforeHTML', array( &$this, &$text ) ); $this->addHTML( $text ); @@ -3648,4 +3654,20 @@ $templates return array(); } + /** + * Enables/disables TOC, doesn't override __NOTOC__ + * @param bool $flag + * @since 1.22 + */ + public function enableTOC( $flag = true ) { + $this->mEnableTOC = $flag; + } + + /** + * @return bool + * @since 1.22 + */ + public function isTOCEnabled() { + return $this->mEnableTOC; + } } diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 221a630f91..7dbb202a2e 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -115,6 +115,10 @@ class Parser { # Marker Suffix needs to be accessible staticly. const MARKER_SUFFIX = "-QINU\x7f"; + # Markers used for wrapping the table of contents + const TOC_START = ''; + const TOC_END = ''; + # Persistent: var $mTagHooks = array(); var $mTransparentTagHooks = array(); @@ -2466,7 +2470,7 @@ class Parser { $openmatch = preg_match( '/(?:mUniqPrefix . '-pre|<\\/li|<\\/ul|<\\/ol|<\\/dl|<\\/?center)/iS', $t ); + 'mUniqPrefix . '-pre|<\\/li|<\\/ul|<\\/ol|<\\/dl|<\\/?center)/iS', $t ); if ( $openmatch or $closematch ) { $paragraphStack = false; # TODO bug 5718: paragraph closed @@ -4520,6 +4524,7 @@ class Parser { } $toc = Linker::tocList( $toc, $this->mOptions->getUserLangObj() ); $this->mOutput->setTOCHTML( $toc ); + $toc = self::TOC_START . $toc . self::TOC_END; } if ( $isMain ) { diff --git a/includes/parser/ParserOutput.php b/includes/parser/ParserOutput.php index 9519de9aed..502f0fd186 100644 --- a/includes/parser/ParserOutput.php +++ b/includes/parser/ParserOutput.php @@ -47,7 +47,8 @@ class ParserOutput extends CacheTime { $mEditSectionTokens = false, # prefix/suffix markers if edit sections were output as tokens $mProperties = array(), # Name/value pairs to be cached in the DB $mTOCHTML = '', # HTML of the TOC - $mTimestamp; # Timestamp of the revision + $mTimestamp, # Timestamp of the revision + $mTOCEnabled = true; # Whether TOC should be shown, can't override __NOTOC__ private $mIndexPolicy = ''; # 'index' or 'noindex'? Any other value will result in no change. private $mAccessedOptions = array(); # List of ParserOptions (stored in the keys) private $mSecondaryDataUpdates = array(); # List of DataUpdate, used to save info from the page somewhere else. @@ -68,11 +69,27 @@ class ParserOutput extends CacheTime { } function getText() { + wfProfileIn( __METHOD__ ); + $text = $this->mText; if ( $this->mEditSectionTokens ) { - return preg_replace_callback( ParserOutput::EDITSECTION_REGEX, - array( &$this, 'replaceEditSectionLinksCallback' ), $this->mText ); + $text = preg_replace_callback( ParserOutput::EDITSECTION_REGEX, + array( &$this, 'replaceEditSectionLinksCallback' ), $text ); + } else { + $text = preg_replace( ParserOutput::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 ) { + $text = str_replace( array( Parser::TOC_START, Parser::TOC_END ), '', $text ); + } else { + $text = preg_replace( + '#'. preg_quote( Parser::TOC_START ) . '.*?' . preg_quote( Parser::TOC_END ) . '#s', + '', + $text + ); } - return preg_replace( ParserOutput::EDITSECTION_REGEX, '', $this->mText ); + wfProfileOut( __METHOD__ ); + return $text; } /** @@ -123,6 +140,7 @@ class ParserOutput extends CacheTime { function getTOCHTML() { return $this->mTOCHTML; } function getTimestamp() { return $this->mTimestamp; } function getLimitReportData() { return $this->mLimitReportData; } + function getTOCEnabled() { return $this->mTOCEnabled; } function setText( $text ) { return wfSetVar( $this->mText, $text ); } function setLanguageLinks( $ll ) { return wfSetVar( $this->mLanguageLinks, $ll ); } @@ -134,6 +152,7 @@ class ParserOutput extends CacheTime { function setIndexPolicy( $policy ) { return wfSetVar( $this->mIndexPolicy, $policy ); } function setTOCHTML( $tochtml ) { return wfSetVar( $this->mTOCHTML, $tochtml ); } function setTimestamp( $timestamp ) { return wfSetVar( $this->mTimestamp, $timestamp ); } + function setTOCEnabled( $flag ) { return wfSetVar( $this->mTOCEnabled, $flag ); } function addCategory( $c, $sort ) { $this->mCategories[$c] = $sort; } function addLanguageLink( $t ) { $this->mLanguageLinks[] = $t; } diff --git a/tests/parser/parserTest.inc b/tests/parser/parserTest.inc index 3f8d7f96af..1fac2f58d6 100644 --- a/tests/parser/parserTest.inc +++ b/tests/parser/parserTest.inc @@ -494,6 +494,9 @@ class ParserTest { /** * Get a Parser object + * + * @param string $preprocessor + * @return Parser */ function getParser( $preprocessor = null ) { global $wgParserConf; @@ -566,6 +569,7 @@ class ParserTest { $out = $parser->getPreloadText( $input, $title, $options ); } else { $output = $parser->parse( $input, $title, $options, true, true, 1337 ); + $output->setTOCEnabled( !isset( $opts['notoc'] ) ); $out = $output->getText(); if ( isset( $opts['showtitle'] ) ) { @@ -618,7 +622,7 @@ class ParserTest { /** * Use a regex to find out the value of an option * @param $key String: name of option val to retrieve - * @param $opts Options array to look in + * @param $opts array: Options array to look in * @param $default Mixed: default value returned if not found */ private static function getOptionValue( $key, $opts, $default ) { diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt index 3266b166ae..8c1ad6c841 100644 --- a/tests/parser/parserTests.txt +++ b/tests/parser/parserTests.txt @@ -26,6 +26,7 @@ # showtitle make the first line the title # comment run through Linker::formatComment() instead of main parser # local format section links in edit comment text as local links +# notoc disable table of contents # # You can also set the following parser properties via test options: # wgEnableUploads, wgAllowExternalImages, wgMaxTocLevel, @@ -10103,6 +10104,7 @@ Some text +

Headline 1[edit]

Subheadline 1[edit]

Skipping a level[edit]
@@ -10158,6 +10160,7 @@ Handling of sections up to level 6 and beyond +

Level 1 Heading[edit]

Level 2 Heading[edit]

Level 3 Heading[edit]

@@ -10200,6 +10203,7 @@ TOC regression (bug 9764) +

title 1[edit]

title 1.1[edit]

title 1.1.1[edit]

@@ -10236,6 +10240,7 @@ wgMaxTocLevel=3 +

title 1[edit]

title 1.1[edit]

title 1.1.1[edit]

@@ -10266,6 +10271,7 @@ wgMaxTocLevel=3
  • 2 Section 2
  • +

    Section 1[edit]

    Section 1.1[edit]

    Section 1.1.1[edit]

    @@ -10358,6 +10364,7 @@ __TOC__
  • 2 title 2
  • +

    title 1[edit]

    title 1.1[edit]

    title 2[edit]

    @@ -10421,6 +10428,7 @@ section 5
  • 5 text " text
  • +

    text > text[edit]

    section 1

    @@ -10455,6 +10463,7 @@ Headers with excess '=' characters
  • 4 =italic heading
  • +

    foo=[edit]

    =foo[edit]

    italic heading=[edit]

    @@ -10492,6 +10501,7 @@ __NOEDITSECTION__ +

    Header 1

    Header 1.1

    Header 1.2

    @@ -11866,6 +11876,7 @@ http://

    Contents

    + !! end !! test @@ -13749,6 +13760,7 @@ Out-of-order TOC heading levels +

    2[edit]

    6[edit]

    3[edit]

    @@ -15315,6 +15327,7 @@ __TOC__
  • 1 Lost episodes
  • +

    Lost episodes[edit]

    !! end @@ -15332,6 +15345,7 @@ __TOC__
  • 1 should be bold then normal text
  • +

    should be bold then normal text[edit]

    !! end @@ -15349,6 +15363,7 @@ __TOC__
  • 1 Image
  • +

    Image Foobar.jpg[edit]

    !! end @@ -15366,6 +15381,7 @@ __TOC__
  • 1 Quote
  • +

    Quote
    [edit]

    !! end @@ -15385,6 +15401,7 @@ QED
  • 1 Proof: 2 < 3
  • +

    Proof: 2 < 3[edit]

    Hanc marginis exiguitas non caperet. QED @@ -15405,6 +15422,7 @@ __TOC__

  • 2 Foo Bar
  • +

    Foo Bar[edit]

    Foo
    Bar
    [edit]

    @@ -15424,6 +15442,7 @@ __TOC__
  • 2 b">Evilbye
  • +

    Hello[edit]

    b">Evilbye[edit]

    @@ -15452,6 +15471,7 @@ __TOC__
  • 5 Attributes after dir on these span tags must be deleted from the TOC
  • +

    C++[edit]

    זבנג![edit]

    The attributes on these span tags must be deleted from the TOC[edit]

    @@ -15741,6 +15761,29 @@ HttP://MediaWiki.Org/

    !! end +!!test +Disable TOC +!! options +notoc +!! input +Lead +== Section 1 == +== Section 2 == +== Section 3 == +== Section 4 == +== Section 5 == +!! result +

    Lead +

    + +

    Section 1[edit]

    +

    Section 2[edit]

    +

    Section 3[edit]

    +

    Section 4[edit]

    +

    Section 5[edit]

    + +!! end + ### ### Parsoids-specific tests diff --git a/tests/phpunit/includes/parser/NewParserTest.php b/tests/phpunit/includes/parser/NewParserTest.php index ab8e77b172..dc1cb0dbd9 100644 --- a/tests/phpunit/includes/parser/NewParserTest.php +++ b/tests/phpunit/includes/parser/NewParserTest.php @@ -629,6 +629,7 @@ class NewParserTest extends MediaWikiTestCase { $out = $parser->getPreloadText( $input, $title, $options ); } else { $output = $parser->parse( $input, $title, $options, true, true, 1337 ); + $output->setTOCEnabled( !isset( $opts['notoc'] ) ); $out = $output->getText(); if ( isset( $opts['showtitle'] ) ) {