diff options
author | C. Scott Ananian <cscott@cscott.net> | 2022-05-27 12:20:35 -0400 |
---|---|---|
committer | C. Scott Ananian <cscott@cscott.net> | 2022-07-21 15:29:11 -0400 |
commit | cc798985225a58b1ea46d69ee9a2f5d7c7a8a4db (patch) | |
tree | 63fe2daa389f9e6ffb53aa8e03c05d0a6a776aed | |
parent | dff8a1571e2d404df9cafcd3c8667d7b02734ecd (diff) | |
download | mediawikicore-cc798985225a58b1ea46d69ee9a2f5d7c7a8a4db.tar.gz mediawikicore-cc798985225a58b1ea46d69ee9a2f5d7c7a8a4db.zip |
ParserOption/ParserOutput flag to suppress or hide the table of contents
There are two related issues here: first, when parsing non-wikitext
pages for side effects (categories, etc) we want to ensure that any
spurious `===` or `<h2>` on the page don't create nonsense "sections".
We introduce a ParserOption to suppress the ToC in this case; a
follow-up patch will set this parser option from the correct path in
CodeContentHandler and its subclasses. [T307691]
Second, modern skins can generate the ToC on-the-fly outside the
content area, and need to be able to regenerate the ToC from API
output when the page is edited. A ParserOutput flag is added to
mirror the $enoughToc variable from the parser to indicate whether
or not the ToC should be generated and/or updated after edit.
(See I6cf76c870124c162dc1bcbc2f7e9ca0c5fdcd10e for parallel code
to echo this value in ApiParse.)
Bug: T294950
Bug: T307691
Change-Id: I35e199cca40c0e4359ac493e5806dcf4ae49321c
-rw-r--r-- | includes/parser/Parser.php | 21 | ||||
-rw-r--r-- | includes/parser/ParserOptions.php | 26 | ||||
-rw-r--r-- | includes/parser/ParserOutputFlags.php | 16 | ||||
-rw-r--r-- | tests/parser/parserTests.txt | 216 |
4 files changed, 257 insertions, 22 deletions
diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index a3dd74340534..c0116d011313 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -4499,8 +4499,9 @@ class Parser { $this->setOutputType( $oldType ); - # Never ever show TOC if no headers - if ( $numVisible < 1 ) { + # Never ever show TOC if no headers (or suppressed) + $suppressToc = $this->mOptions->getSuppressTOC(); + if ( $numVisible < 1 || $suppressToc ) { $enoughToc = false; } @@ -4510,9 +4511,19 @@ class Parser { } $toc = Linker::tocList( $toc, $this->mOptions->getUserLangObj() ); $this->mOutput->setTOCHTML( $toc ); - } - - if ( $isMain ) { + } else { + // Record the fact that the TOC should not be shown. T294950 + $this->mOutput->setOutputFlag( ParserOutputFlags::HIDE_TOC ); + } + + if ( $isMain && !$suppressToc ) { + // We generally output the section information via the API + // even if there isn't "enough" of a ToC to merit showing + // it -- but the "suppress TOC" parser option is set when + // any sections that might be found aren't "really there" + // (ie, JavaScript content that might have spurious === or + // <h2>: T307691) so we will *not* set section information + // in that case. $this->mOutput->setSections( $tocraw ); } diff --git a/includes/parser/ParserOptions.php b/includes/parser/ParserOptions.php index b1000a750159..bc0427a2b38d 100644 --- a/includes/parser/ParserOptions.php +++ b/includes/parser/ParserOptions.php @@ -759,6 +759,31 @@ class ParserOptions { } /** + * Should the table of contents be suppressed? + * Used when parsing "code" pages (like JavaScript) as wikitext + * for backlink support and categories, but where we don't want + * other metadata generated (like the table of contents). + * @see T307691 + * @since 1.39 + * @return bool + */ + public function getSuppressTOC() { + return $this->getOption( 'suppressTOC' ); + } + + /** + * Suppress generation of the table of contents. + * Used when parsing "code" pages (like JavaScript) as wikitext + * for backlink support and categories, but where we don't want + * other metadata generated (like the table of contents). + * @see T307691 + * @since 1.39 + */ + public function setSuppressTOC() { + $this->setOption( 'suppressTOC', true ); + } + + /** * If the wiki is configured to allow raw html ($wgRawHtml = true) * is it allowed in the specific case of parsing this page. * @@ -1129,6 +1154,7 @@ class ParserOptions { 'interfaceMessage' => false, 'targetLanguage' => null, 'removeComments' => true, + 'suppressTOC' => false, 'enableLimitReport' => false, 'preSaveTransform' => true, 'isPreview' => false, diff --git a/includes/parser/ParserOutputFlags.php b/includes/parser/ParserOutputFlags.php index 70e206e79ad0..007083d589fb 100644 --- a/includes/parser/ParserOutputFlags.php +++ b/includes/parser/ParserOutputFlags.php @@ -50,11 +50,6 @@ class ParserOutputFlags { public const NO_GALLERY = 'mw-NoGallery'; /** - * @var string Used to suppress language conversion in ToC contents. - */ - public const NO_TOC_CONVERSION = 'no-toc-conversion'; - - /** * @var string Whether OOUI should be enabled. * @see \ParserOutput::getEnableOOUI() * @see \ParserOutput::setEnableOOUI() @@ -99,6 +94,16 @@ class ParserOutputFlags { // These flags are stored in the ParserOutput::$mFlags array /** + * @var string Hide the table of contents in the skin? + */ + public const HIDE_TOC = 'hide-toc'; + + /** + * @var string Used to suppress language conversion in ToC contents. + */ + public const NO_TOC_CONVERSION = 'no-toc-conversion'; + + /** * @var string */ public const VARY_REVISION = 'vary-revision'; @@ -161,6 +166,7 @@ class ParserOutputFlags { self::NO_INDEX_POLICY, self::NEW_SECTION, self::HIDE_NEW_SECTION, + self::HIDE_TOC, self::PREVENT_CLICKJACKING, self::VARY_REVISION, self::VARY_REVISION_ID, diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt index aff1ea258777..0a009bcc4f2a 100644 --- a/tests/parser/parserTests.txt +++ b/tests/parser/parserTests.txt @@ -11475,7 +11475,7 @@ showflags !! html/* <p>1337 </p> -flags=vary-revision-id +flags=hide-toc, vary-revision-id !! end !! test @@ -11488,7 +11488,7 @@ showflags !! html/* <p>1337 </p> -flags=vary-revision-id +flags=hide-toc, vary-revision-id !! end !! test @@ -11502,7 +11502,7 @@ showflags !! html/* <p>19700101000203 </p> -flags= +flags=hide-toc !! end !! test @@ -11515,7 +11515,7 @@ showflags !! html/* <p>123 </p> -flags=vary-revision-timestamp +flags=hide-toc, vary-revision-timestamp !! end !! test @@ -11529,7 +11529,7 @@ showflags !! html/* <p>127.0.0.1 </p> -flags=vary-user +flags=hide-toc, vary-user !! end !! test @@ -11543,7 +11543,7 @@ showflags !! html/* <p>1337 </p> -flags=vary-revision-id +flags=hide-toc, vary-revision-id !! end !! test @@ -11555,7 +11555,7 @@ showflags {{REVISIONID:{{PAGENAME}}}} !! html/* -flags=vary-revision-id +flags=hide-toc, vary-revision-id !! end !! test @@ -11569,7 +11569,7 @@ showflags !! html/* <p>19700101000203 </p> -flags=vary-revision-timestamp +flags=hide-toc, vary-revision-timestamp !! end !! test @@ -11583,7 +11583,7 @@ showflags !! html/* <p>1 </p> -flags=vary-revision-timestamp +flags=hide-toc, vary-revision-timestamp !! end !! test @@ -11597,7 +11597,7 @@ showflags !! html/* <p>01 </p> -flags=vary-revision-timestamp +flags=hide-toc, vary-revision-timestamp !! end !! test @@ -11611,7 +11611,7 @@ showflags !! html/* <p>1970 </p> -flags=vary-revision-timestamp +flags=hide-toc, vary-revision-timestamp !! end !! test @@ -11625,7 +11625,7 @@ showflags !! html/* <p>25 </p> -flags=vary-revision-sha1 +flags=hide-toc, vary-revision-sha1 !! end !! test @@ -16791,6 +16791,8 @@ Template:sections !! test Template with sections, __NOTOC__ +!! options +showflags !! wikitext __NOTOC__ ==Section 0== @@ -16801,6 +16803,193 @@ __NOTOC__ <h3><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Sections&action=edit&section=T-1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> <h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Sections&action=edit&section=T-2" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <h2><span class="mw-headline" id="Section_4">Section 4</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 4">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +flags=hide-toc +!! end + +!! test +T307691: hide-toc flag: no sections +!! options +showflags +!! wikitext +!! html + +flags=hide-toc +!! end + +# You can't force a TOC if there aren't any sections +!! test +T307691: hide-toc flag: no sections, but __FORCETOC__ +!! options +showflags +!! wikitext +__FORCETOC__ +!! html + +flags=hide-toc +!! end + +# Placing a manual __TOC__ doesn't do anything if there aren't any sections +!! test +T307691: hide-toc flag: no sections, but __TOC__ +!! options +showflags +!! wikitext +__TOC__ +!! html + +flags=hide-toc +!! end + +!! test +T307691: hide-toc flag: no sections, and __NOTOC__ +!! options +showflags +!! wikitext +__NOTOC__ +!! html + +flags=hide-toc +!! end + +!! test +T307691: hide-toc flag: not "enough" sections +!! options +showflags +!! wikitext +== One == +!! html +<h2><span class="mw-headline" id="One">One</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: One">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +flags=hide-toc +!! end + +!! test +T307691: hide-toc flag: not "enough" sections, but __FORCETOC__ +!! options +showflags +!! wikitext +__FORCETOC__ +== One == +!! html +<div id="toc" class="toc" role="navigation" aria-labelledby="mw-toc-heading"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2 id="mw-toc-heading">Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div> +<ul> +<li class="toclevel-1 tocsection-1"><a href="#One"><span class="tocnumber">1</span> <span class="toctext">One</span></a></li> +</ul> +</div> + +<h2><span class="mw-headline" id="One">One</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: One">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +flags= +!! end + +!! test +T307691: hide-toc flag: not "enough" sections, but __TOC__ +!! options +showflags +!! wikitext +== One == +__TOC__ +!! html +<h2><span class="mw-headline" id="One">One</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: One">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<div id="toc" class="toc" role="navigation" aria-labelledby="mw-toc-heading"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2 id="mw-toc-heading">Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div> +<ul> +<li class="toclevel-1 tocsection-1"><a href="#One"><span class="tocnumber">1</span> <span class="toctext">One</span></a></li> +</ul> +</div> +flags= +!! end + +!! test +T307691: hide-toc flag: not "enough" sections, and __NOTOC__ +!! options +showflags +!! wikitext +__NOTOC__ +== One == +!! html +<h2><span class="mw-headline" id="One">One</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: One">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +flags=hide-toc +!! end + +!! test +T307691: hide-toc flag: "enough" sections +!! options +showflags +!! wikitext +== One == +=== Two === +== Three == +=== Four === +!! html +<div id="toc" class="toc" role="navigation" aria-labelledby="mw-toc-heading"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2 id="mw-toc-heading">Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div> +<ul> +<li class="toclevel-1 tocsection-1"><a href="#One"><span class="tocnumber">1</span> <span class="toctext">One</span></a> +<ul> +<li class="toclevel-2 tocsection-2"><a href="#Two"><span class="tocnumber">1.1</span> <span class="toctext">Two</span></a></li> +</ul> +</li> +<li class="toclevel-1 tocsection-3"><a href="#Three"><span class="tocnumber">2</span> <span class="toctext">Three</span></a> +<ul> +<li class="toclevel-2 tocsection-4"><a href="#Four"><span class="tocnumber">2.1</span> <span class="toctext">Four</span></a></li> +</ul> +</li> +</ul> +</div> + +<h2><span class="mw-headline" id="One">One</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: One">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Two">Two</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Two">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="Three">Three</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Three">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Four">Four</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Four">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +flags= +!! end + +!! test +T307691: hide-toc flag: "enough" sections and __FORCETOC__ +!! options +showflags +!! wikitext +__FORCETOC__ +== One == +=== Two === +== Three == +=== Four === +!! html +<div id="toc" class="toc" role="navigation" aria-labelledby="mw-toc-heading"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2 id="mw-toc-heading">Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div> +<ul> +<li class="toclevel-1 tocsection-1"><a href="#One"><span class="tocnumber">1</span> <span class="toctext">One</span></a> +<ul> +<li class="toclevel-2 tocsection-2"><a href="#Two"><span class="tocnumber">1.1</span> <span class="toctext">Two</span></a></li> +</ul> +</li> +<li class="toclevel-1 tocsection-3"><a href="#Three"><span class="tocnumber">2</span> <span class="toctext">Three</span></a> +<ul> +<li class="toclevel-2 tocsection-4"><a href="#Four"><span class="tocnumber">2.1</span> <span class="toctext">Four</span></a></li> +</ul> +</li> +</ul> +</div> + +<h2><span class="mw-headline" id="One">One</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: One">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Two">Two</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Two">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="Three">Three</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Three">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Four">Four</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Four">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +flags= +!! end + +!! test +T307691: hide-toc flag: "enough" sections and __NOTOC__ +!! options +showflags +!! wikitext +__NOTOC__ +== One == +=== Two === +== Three == +=== Four === +!! html +<h2><span class="mw-headline" id="One">One</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: One">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Two">Two</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Two">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="Three">Three</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Three">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Four">Four</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Four">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +flags=hide-toc !! end !! test @@ -20423,12 +20612,15 @@ parsoid={ "modes": ["wt2html","html2html"], "normalizePhp": true } !! test __FORCETOC__ override +!! options +showflags !! wikitext __NEWSECTIONLINK__ __FORCETOC__ !! html/php <p><br /> </p> +flags=hide-toc !! end !! test |