Revert "Use setExtensionData() instead of marker comments where possible (2/3)"

This reverts commit 0ac420ecbc.

Reason for revert: this was supposed to be merged later; revert it now and reapply in a bit

Change-Id: I33fb07856152c2401b3a071c143f27f1e9753287
This commit is contained in:
DLynch 2023-02-12 02:57:31 +00:00
parent 0ac420ecbc
commit fb08abe062
2 changed files with 108 additions and 140 deletions

View file

@ -707,46 +707,52 @@ class CommentFormatter {
/** /**
* Post-process visual enhancements features for page subtitle * Post-process visual enhancements features for page subtitle
* *
* @param ParserOutput $pout * @param string &$text
* @param Language $lang * @param Language $lang
* @param UserIdentity $user * @param UserIdentity $user
* @return ?string * @return ?string
*/ */
public static function postprocessVisualEnhancementsSubtitle( public static function postprocessVisualEnhancementsSubtitle(
ParserOutput $pout, Language $lang, UserIdentity $user string &$text, Language $lang, UserIdentity $user
): ?string { ): ?string {
$itemData = $pout->getExtensionData( 'DiscussionTools-newestComment' ); preg_match( '/<!--__DTLATESTCOMMENTPAGE__(.*?)__-->/', $text, $matches );
if ( $itemData && $itemData['timestamp'] && $itemData['id'] ) { // The subtitle is inserted into the correct place by the caller, so cleanup the comment here
$relativeTime = static::getSignatureRelativeTime( $text = preg_replace( '/<!--__DTLATESTCOMMENTPAGE__(.*?)-->/', '', $text );
new MWTimestamp( $itemData['timestamp'] ), if ( count( $matches ) ) {
$lang, $itemData = json_decode( htmlspecialchars_decode( $matches[1] ), true );
$user
);
$commentLink = Html::element( 'a', [
'href' => '#' . Sanitizer::escapeIdForLink( $itemData['id'] )
], $relativeTime );
if ( isset( $itemData['heading'] ) ) { if ( $itemData && $itemData['timestamp'] && $itemData['id'] ) {
$headingLink = Html::element( 'a', [ $relativeTime = static::getSignatureRelativeTime(
'href' => '#' . Sanitizer::escapeIdForLink( $itemData['heading']['linkableTitle'] ) new MWTimestamp( $itemData['timestamp'] ),
], $itemData['heading']['text'] ); $lang,
$label = wfMessage( 'discussiontools-pageframe-latestcomment' ) $user
->rawParams( $commentLink ) );
->params( $itemData['author'] ) $commentLink = Html::element( 'a', [
->rawParams( $headingLink ) 'href' => '#' . Sanitizer::escapeIdForLink( $itemData['id'] )
->inLanguage( $lang )->escaped(); ], $relativeTime );
} else {
$label = wfMessage( 'discussiontools-pageframe-latestcomment-notopic' ) if ( isset( $itemData['heading'] ) ) {
->rawParams( $commentLink ) $headingLink = Html::element( 'a', [
->params( $itemData['author'] ) 'href' => '#' . Sanitizer::escapeIdForLink( $itemData['heading']['linkableTitle'] )
->inLanguage( $lang )->escaped(); ], $itemData['heading']['text'] );
$label = wfMessage( 'discussiontools-pageframe-latestcomment' )
->rawParams( $commentLink )
->params( $itemData['author'] )
->rawParams( $headingLink )
->inLanguage( $lang )->escaped();
} else {
$label = wfMessage( 'discussiontools-pageframe-latestcomment-notopic' )
->rawParams( $commentLink )
->params( $itemData['author'] )
->inLanguage( $lang )->escaped();
}
return Html::rawElement(
'div',
[ 'class' => 'ext-discussiontools-init-pageframe-latestcomment' ],
$label
);
} }
return Html::rawElement(
'div',
[ 'class' => 'ext-discussiontools-init-pageframe-latestcomment' ],
$label
);
} }
return null; return null;
} }
@ -790,43 +796,42 @@ class CommentFormatter {
/** /**
* Check if the talk page had no comments or headings. * Check if the talk page had no comments or headings.
* *
* @param ParserOutput $pout * @param string $text
* @return bool * @return bool
*/ */
public static function isEmptyTalkPage( ParserOutput $pout ): bool { public static function isEmptyTalkPage( string $text ): bool {
return $pout->getExtensionData( 'DiscussionTools-isEmptyTalkPage' ) === true; return strpos( $text, '<!--__DTEMPTYTALKPAGE__-->' ) !== false;
} }
/** /**
* Append content to an empty talk page * Append content to an empty talk page
* *
* @param ParserOutput $pout * @param string $text
* @param string $content * @param string $content
* @return string
*/ */
public static function appendToEmptyTalkPage( ParserOutput $pout, string $content ): void { public static function appendToEmptyTalkPage( string $text, string $content ): string {
$text = $pout->getRawText(); return str_replace( '<!--__DTEMPTYTALKPAGE__-->', $content, $text );
$text .= $content;
$pout->setText( $text );
} }
/** /**
* Check if the talk page has content above the first heading, in the lede section. * Check if the talk page has content above the first heading, in the lede section.
* *
* @param ParserOutput $pout * @param string $text
* @return bool * @return bool
*/ */
public static function hasLedeContent( ParserOutput $pout ): bool { public static function hasLedeContent( string $text ): bool {
return $pout->getExtensionData( 'DiscussionTools-hasLedeContent' ) === true; return strpos( $text, '<!--__DTHASLEDECONTENT__-->' ) !== false;
} }
/** /**
* Check if the talk page has comments above the first heading, in the lede section. * Check if the talk page has comments above the first heading, in the lede section.
* *
* @param ParserOutput $pout * @param string $text
* @return bool * @return bool
*/ */
public static function hasCommentsInLedeContent( ParserOutput $pout ): bool { public static function hasCommentsInLedeContent( string $text ): bool {
return $pout->getExtensionData( 'DiscussionTools-hasCommentsInLedeContent' ) === true; return strpos( $text, '<!--__DTHASCOMMENTSINLEDECONTENT__-->' ) !== false;
} }
public static function isLanguageRequiringReplyIcon( Language $lang ): bool { public static function isLanguageRequiringReplyIcon( Language $lang ): bool {

View file

@ -176,42 +176,6 @@ class PageHooks implements
if ( $output->getSkin()->getSkinName() === 'minerva' ) { if ( $output->getSkin()->getSkinName() === 'minerva' ) {
$title = $output->getTitle(); $title = $output->getTitle();
if (
$title->isTalkPage() &&
HookUtils::isFeatureEnabledForOutput( $output, HookUtils::REPLYTOOL ) && (
// 'DiscussionTools-ledeButton' property may be already set to true or false.
// Examine the other conditions only if it's unset.
$output->getProperty( 'DiscussionTools-ledeButton' ) ?? (
// Header shown on all talk pages, see Article::showNamespaceHeader
!$output->getContext()->msg( 'talkpageheader' )->isDisabled() &&
// Check if it isn't empty since it may use parser functions to only show itself on some pages
trim( $output->getContext()->msg( 'talkpageheader' )->text() ) !== ''
)
)
) {
$output->addBodyClasses( 'ext-discussiontools-init-lede-hidden' );
$output->enableOOUI();
$output->prependHTML(
Html::rawElement( 'div',
[ 'class' => 'ext-discussiontools-init-lede-button-container' ],
( new ButtonWidget( [
'label' => $output->getContext()->msg( 'discussiontools-ledesection-button' )->text(),
'classes' => [ 'ext-discussiontools-init-lede-button' ],
'framed' => false,
'icon' => 'info',
'infusable' => true,
] ) )
)
);
// Preload jquery.makeCollapsible for LedeSectionDialog.
// Using the same approach as in Skin::getDefaultModules in MediaWiki core.
if ( strpos( $output->getHTML(), 'mw-collapsible' ) !== false ) {
$output->addModules( 'jquery.makeCollapsible' );
$output->addModuleStyles( 'jquery.makeCollapsible.styles' );
}
}
if ( if (
HookUtils::isFeatureEnabledForOutput( $output, HookUtils::NEWTOPICTOOL ) && HookUtils::isFeatureEnabledForOutput( $output, HookUtils::NEWTOPICTOOL ) &&
// Only add the button if "New section" tab would be shown in a normal skin. // Only add the button if "New section" tab would be shown in a normal skin.
@ -240,6 +204,43 @@ class PageHooks implements
->setAttributes( [ 'data-event-name' => 'talkpage.add-topic' ] ) ->setAttributes( [ 'data-event-name' => 'talkpage.add-topic' ] )
) ); ) );
} }
if (
$title->isTalkPage() &&
HookUtils::isFeatureEnabledForOutput( $output, HookUtils::REPLYTOOL ) && (
CommentFormatter::hasLedeContent( $output->getHTML() ) || (
// Header shown on all talk pages, see Article::showNamespaceHeader
!$output->getContext()->msg( 'talkpageheader' )->isDisabled() &&
// Check if it isn't empty since it may use parser functions to only show itself on some pages
trim( $output->getContext()->msg( 'talkpageheader' )->text() ) !== ''
)
) &&
// If there are comments in the lede section, we can't really separate them from other lede
// content, so keep the whole section visible.
!CommentFormatter::hasCommentsInLedeContent( $output->getHTML() )
) {
$output->addBodyClasses( 'ext-discussiontools-init-lede-hidden' );
$output->enableOOUI();
$output->prependHTML(
Html::rawElement( 'div',
[ 'class' => 'ext-discussiontools-init-lede-button-container' ],
( new ButtonWidget( [
'label' => $output->getContext()->msg( 'discussiontools-ledesection-button' )->text(),
'classes' => [ 'ext-discussiontools-init-lede-button' ],
'framed' => false,
'icon' => 'info',
'infusable' => true,
] ) )
)
);
// Preload jquery.makeCollapsible for LedeSectionDialog.
// Using the same approach as in Skin::getDefaultModules in MediaWiki core.
if ( strpos( $output->getHTML(), 'mw-collapsible' ) !== false ) {
$output->addModules( 'jquery.makeCollapsible' );
$output->addModuleStyles( 'jquery.makeCollapsible.styles' );
}
}
} }
} }
@ -279,6 +280,17 @@ class PageHooks implements
); );
} }
if (
CommentFormatter::isEmptyTalkPage( $text ) &&
HookUtils::shouldDisplayEmptyState( $output->getContext() )
) {
$output->enableOOUI();
$text = CommentFormatter::appendToEmptyTalkPage(
$text, $this->getEmptyStateHtml( $output->getContext() )
);
$output->addBodyClasses( 'ext-discussiontools-emptystate-shown' );
}
if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::VISUALENHANCEMENTS ) ) { if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::VISUALENHANCEMENTS ) ) {
$output->enableOOUI(); $output->enableOOUI();
if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::TOPICSUBSCRIPTION ) ) { if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::TOPICSUBSCRIPTION ) ) {
@ -313,6 +325,14 @@ class PageHooks implements
$text = CommentFormatter::postprocessVisualEnhancements( $text = CommentFormatter::postprocessVisualEnhancements(
$text, $lang, $output->getUser(), $isMobile $text, $lang, $output->getUser(), $isMobile
); );
$subtitle = CommentFormatter::postprocessVisualEnhancementsSubtitle(
$text, $lang, $output->getUser()
);
if ( $subtitle ) {
$output->addSubtitle( $subtitle );
}
} }
return true; return true;
@ -327,64 +347,7 @@ class PageHooks implements
* @return void This hook must not abort, it must return no value * @return void This hook must not abort, it must return no value
*/ */
public function onOutputPageParserOutput( $output, $pout ): void { public function onOutputPageParserOutput( $output, $pout ): void {
// ParserOutputPostCacheTransform hook would be a better place to do this, CommentFormatter::postprocessTableOfContents( $pout, $output->getLanguage() );
// so that when the ParserOutput is used directly without using this hook,
// we don't leave half-baked interface elements in it (see e.g. T292345, T294168).
// But that hook doesn't provide parameters that we need to render correctly
// (including the page title, interface language, and current user).
// This hook can be executed more than once per page view if the page content is composed from
// multiple sources!
$isMobile = $this->isMobile();
$lang = $output->getLanguage();
CommentFormatter::postprocessTableOfContents( $pout, $lang );
if (
CommentFormatter::isEmptyTalkPage( $pout ) &&
HookUtils::shouldDisplayEmptyState( $output->getContext() )
) {
$output->enableOOUI();
CommentFormatter::appendToEmptyTalkPage(
$pout, $this->getEmptyStateHtml( $output->getContext() )
);
$output->addBodyClasses( 'ext-discussiontools-emptystate-shown' );
}
if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::VISUALENHANCEMENTS ) ) {
$subtitle = CommentFormatter::postprocessVisualEnhancementsSubtitle(
$pout, $lang, $output->getUser()
);
if ( $subtitle ) {
$output->addSubtitle( $subtitle );
}
}
if ( $output->getSkin()->getSkinName() === 'minerva' ) {
$title = $output->getTitle();
if (
$title->isTalkPage() &&
HookUtils::isFeatureEnabledForOutput( $output, HookUtils::REPLYTOOL )
) {
if (
CommentFormatter::hasCommentsInLedeContent( $pout )
) {
// If there are comments in the lede section, we can't really separate them from other lede
// content, so keep the whole section visible.
$output->setProperty( 'DiscussionTools-ledeButton', false );
} elseif (
CommentFormatter::hasLedeContent( $pout ) &&
$output->getProperty( 'DiscussionTools-ledeButton' ) === null
) {
// If there is lede content and the lede button hasn't been disabled above, enable it.
$output->setProperty( 'DiscussionTools-ledeButton', true );
}
}
}
} }
/** /**