Merge "Deprecate Linker::generateTOC() and related methods"

This commit is contained in:
jenkins-bot 2024-03-08 14:13:47 +00:00 committed by Gerrit Code Review
commit 121ce8b620
6 changed files with 172 additions and 9 deletions

View file

@ -616,6 +616,8 @@ because of Phabricator reports.
Vuex 4 will remain accessible for the foreseeable future. Pinia should be used
for new projects.
* Linker::makeHeadline() has been deprecated.
* Linker::generateTOC(), Linker::tocIndent(), Linker::tocUnindent(),
Linker::tocLine(), Linker::tocLineEnd(), Linker::tocList() are deprecated.
* Title::getBrokenLinksFrom() has been deprecated.
* ReplicatedBagOStuff has been deprecated since 1.42.
* The third argument to ContentRenderer::getParserOutput() now accepts a

View file

@ -4,13 +4,16 @@ namespace MediaWiki\OutputTransform\Stages;
use Language;
use MediaWiki\Context\RequestContext;
use MediaWiki\Linker\Linker;
use MediaWiki\Html\Html;
use MediaWiki\MainConfigNames;
use MediaWiki\MediaWikiServices;
use MediaWiki\OutputTransform\ContentTextTransformStage;
use MediaWiki\Parser\Parser;
use MediaWiki\Parser\ParserOutput;
use MediaWiki\Parser\Sanitizer;
use MediaWiki\Tidy\TidyDriverBase;
use ParserOptions;
use Wikimedia\Parsoid\Core\TOCData;
/**
* Inject table of contents (or empty string if there's no sections)
@ -45,9 +48,9 @@ class HandleTOCMarkers extends ContentTextTransformStage {
if ( $numSections === 0 ) {
$toc = '';
} else {
$toc = Linker::generateTOC( $tocData, $lang );
$toc =
$this->tidy->tidy( $toc, [ Sanitizer::class, 'armorFrenchSpaces' ] );
$toc = self::generateTOC( $tocData, $lang );
// TODO: This may no longer be needed since Ic0a805f29c928d0c2edf266ea045b0d29bb45a28
$toc = $this->tidy->tidy( $toc, [ Sanitizer::class, 'armorFrenchSpaces' ] );
}
return Parser::replaceTableOfContentsMarker( $text, $toc );
@ -72,4 +75,147 @@ class HandleTOCMarkers extends ContentTextTransformStage {
}
return $userLang;
}
/**
* Add another level to the Table of Contents
*
* @return string
*/
private static function tocIndent() {
return "\n<ul>\n";
}
/**
* Finish one or more sublevels on the Table of Contents
*
* @param int $level
* @return string
*/
private static function tocUnindent( $level ) {
return "</li>\n" . str_repeat( "</ul>\n</li>\n", $level > 0 ? $level : 0 );
}
/**
* parameter level defines if we are on an indentation level
*
* @param string $linkAnchor Identifier
* @param string $tocline Properly escaped HTML
* @param string $tocnumber Unescaped text
* @param int $level
* @param string|false $sectionIndex
* @return string
*/
private static function tocLine( $linkAnchor, $tocline, $tocnumber, $level, $sectionIndex = false ) {
$classes = "toclevel-$level";
// Parser.php used to suppress tocLine by setting $sectionindex to false.
// In those circumstances, we can now encounter '' or a "T-" prefixed index
// for when the section comes from templates.
if ( $sectionIndex !== false && $sectionIndex !== '' && !str_starts_with( $sectionIndex, "T-" ) ) {
$classes .= " tocsection-$sectionIndex";
}
// <li class="$classes"><a href="#$linkAnchor"><span class="tocnumber">
// $tocnumber</span> <span class="toctext">$tocline</span></a>
return Html::openElement( 'li', [ 'class' => $classes ] )
. Html::rawElement( 'a',
[ 'href' => "#$linkAnchor" ],
Html::element( 'span', [ 'class' => 'tocnumber' ], $tocnumber )
. ' '
. Html::rawElement( 'span', [ 'class' => 'toctext' ], $tocline )
);
}
/**
* End a Table Of Contents line.
* tocUnindent() will be used instead if we're ending a line below
* the new level.
* @return string
*/
private static function tocLineEnd() {
return "</li>\n";
}
/**
* Wraps the TOC in a div with ARIA navigation role and provides the hide/collapse JavaScript.
*
* @param string $toc Html of the Table Of Contents
* @param Language|null $lang Language for the toc title, defaults to user language
* @return string Full html of the TOC
*/
private static function tocList( $toc, Language $lang = null ) {
$lang ??= RequestContext::getMain()->getLanguage();
$title = wfMessage( 'toc' )->inLanguage( $lang )->escaped();
return '<div id="toc" class="toc" role="navigation" aria-labelledby="mw-toc-heading">'
. Html::element( 'input', [
'type' => 'checkbox',
'role' => 'button',
'id' => 'toctogglecheckbox',
'class' => 'toctogglecheckbox',
'style' => 'display:none',
] )
. Html::openElement( 'div', [
'class' => 'toctitle',
'lang' => $lang->getHtmlCode(),
'dir' => $lang->getDir(),
] )
. '<h2 id="mw-toc-heading">' . $title . '</h2>'
. '<span class="toctogglespan">'
. Html::label( '', 'toctogglecheckbox', [
'class' => 'toctogglelabel',
] )
. '</span>'
. '</div>'
. $toc
. "</ul>\n</div>\n";
}
/**
* Generate a table of contents from a section tree.
*
* @param ?TOCData $tocData Return value of ParserOutput::getSections()
* @param Language|null $lang Language for the toc title, defaults to user language
* @param array $options
* - 'maxtoclevel' Max TOC level to generate
* @return string HTML fragment
*/
private static function generateTOC( ?TOCData $tocData, Language $lang = null, array $options = [] ): string {
$toc = '';
$lastLevel = 0;
$maxTocLevel = $options['maxtoclevel'] ?? null;
if ( $maxTocLevel === null ) {
// Use wiki-configured default
$services = MediaWikiServices::getInstance();
$config = $services->getMainConfig();
$maxTocLevel = $config->get( MainConfigNames::MaxTocLevel );
}
foreach ( ( $tocData ? $tocData->getSections() : [] ) as $section ) {
$tocLevel = $section->tocLevel;
if ( $tocLevel < $maxTocLevel ) {
if ( $tocLevel > $lastLevel ) {
$toc .= self::tocIndent();
} elseif ( $tocLevel < $lastLevel ) {
if ( $lastLevel < $maxTocLevel ) {
$toc .= self::tocUnindent(
$lastLevel - $tocLevel );
} else {
$toc .= self::tocLineEnd();
}
} else {
$toc .= self::tocLineEnd();
}
$toc .= self::tocLine( $section->linkAnchor,
$section->line, $section->number,
$tocLevel, $section->index );
$lastLevel = $tocLevel;
}
}
if ( $lastLevel < $maxTocLevel && $lastLevel > 0 ) {
$toc .= self::tocUnindent( $lastLevel - 1 );
}
return self::tocList( $toc, $lang );
}
}

View file

@ -2194,7 +2194,7 @@ abstract class ApiBase extends ContextSource {
* @param string[] &$help Array of help data
* @param array $options Options passed to ApiHelp::getHelp
* @param array &$tocData If a TOC is being generated, this array has keys
* as anchors in the page and values as for Linker::generateTOC().
* as anchors in the page and values as for SectionMetadata::fromLegacy().
*/
public function modifyHelp( array &$help, array $options, array &$tocData ) {
}

View file

@ -24,10 +24,11 @@ use MediaWiki\Context\DerivativeContext;
use MediaWiki\Context\IContextSource;
use MediaWiki\Html\Html;
use MediaWiki\Html\HtmlHelper;
use MediaWiki\Linker\Linker;
use MediaWiki\MainConfigNames;
use MediaWiki\MediaWikiServices;
use MediaWiki\Output\OutputPage;
use MediaWiki\Parser\ParserOutput;
use MediaWiki\Parser\ParserOutputFlags;
use MediaWiki\SpecialPage\SpecialPage;
use MediaWiki\Specials\SpecialVersion;
use MediaWiki\Title\Title;
@ -190,8 +191,11 @@ class ApiHelp extends ApiBase {
$haveModules = [];
$html = self::getHelpInternal( $context, $modules, $options, $haveModules );
if ( !empty( $options['toc'] ) && $haveModules ) {
$tocData = TOCData::fromLegacy( array_values( $haveModules ) );
$out->addHTML( Linker::generateTOC( $tocData, $context->getLanguage() ) );
$pout = new ParserOutput;
$pout->setTOCData( TOCData::fromLegacy( array_values( $haveModules ) ) );
$pout->setOutputFlag( ParserOutputFlags::SHOW_TOC );
$pout->setText( Parser::TOC_PLACEHOLDER );
$out->addParserOutput( $pout );
}
$out->addHTML( $html );

View file

@ -21,7 +21,7 @@ interface APIHelpModifyOutputHook {
* @param string[] &$help Array of HTML strings to be joined for the output
* @param array $options Array of formatting options passed to ApiHelp::getHelp
* @param array &$tocData If a TOC is being generated, this array has keys as anchors in
* the page and values as for Linker::generateTOC().
* the page and values as for SectionMetadata::fromLegacy().
* @return bool|void True or no return value to continue or false to abort
*/
public function onAPIHelpModifyOutput( $module, &$help, $options, &$tocData );

View file

@ -1777,27 +1777,32 @@ class Linker {
/**
* Add another level to the Table of Contents
*
* @deprecated since 1.42
* @since 1.16.3
* @return string
*/
public static function tocIndent() {
wfDeprecated( __METHOD__, '1.42' );
return "\n<ul>\n";
}
/**
* Finish one or more sublevels on the Table of Contents
*
* @deprecated since 1.42
* @since 1.16.3
* @param int $level
* @return string
*/
public static function tocUnindent( $level ) {
wfDeprecated( __METHOD__, '1.42' );
return "</li>\n" . str_repeat( "</ul>\n</li>\n", $level > 0 ? $level : 0 );
}
/**
* parameter level defines if we are on an indentation level
*
* @deprecated since 1.42
* @since 1.16.3
* @param string $linkAnchor Identifier
* @param string $tocline Properly escaped HTML
@ -1807,6 +1812,7 @@ class Linker {
* @return string
*/
public static function tocLine( $linkAnchor, $tocline, $tocnumber, $level, $sectionIndex = false ) {
wfDeprecated( __METHOD__, '1.42' );
$classes = "toclevel-$level";
// Parser.php used to suppress tocLine by setting $sectionindex to false.
@ -1831,22 +1837,26 @@ class Linker {
* End a Table Of Contents line.
* tocUnindent() will be used instead if we're ending a line below
* the new level.
* @deprecated since 1.42
* @since 1.16.3
* @return string
*/
public static function tocLineEnd() {
wfDeprecated( __METHOD__, '1.42' );
return "</li>\n";
}
/**
* Wraps the TOC in a div with ARIA navigation role and provides the hide/collapse JavaScript.
*
* @deprecated since 1.42
* @since 1.16.3
* @param string $toc Html of the Table Of Contents
* @param Language|null $lang Language for the toc title, defaults to user language
* @return string Full html of the TOC
*/
public static function tocList( $toc, Language $lang = null ) {
wfDeprecated( __METHOD__, '1.42' );
$lang ??= RequestContext::getMain()->getLanguage();
$title = wfMessage( 'toc' )->inLanguage( $lang )->escaped();
@ -1879,6 +1889,7 @@ class Linker {
* @internal For use by ParserOutput and API modules
* Generate a table of contents from a section tree.
*
* @deprecated since 1.42
* @since 1.16.3. $lang added in 1.17. Parameters changed in 1.40.
* @param ?TOCData $tocData Return value of ParserOutput::getSections()
* @param Language|null $lang Language for the toc title, defaults to user language