mediawiki-extensions-Discus.../includes/Hooks/ParserHooks.php

131 lines
4.5 KiB
PHP
Raw Normal View History

<?php
/**
* DiscussionTools parser hooks
*
* @file
* @ingroup Extensions
* @license MIT
*/
namespace MediaWiki\Extension\DiscussionTools\Hooks;
use MediaWiki\Config\Config;
use MediaWiki\Config\ConfigFactory;
use MediaWiki\Extension\DiscussionTools\CommentFormatter;
use MediaWiki\Hook\GetDoubleUnderscoreIDsHook;
use MediaWiki\Hook\ParserAfterTidyHook;
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
use MediaWiki\Hook\ParserOutputPostCacheTransformHook;
use MediaWiki\Parser\Parsoid\PageBundleParserOutputConverter;
use MediaWiki\Parser\Parsoid\ParsoidParser;
use MediaWiki\Title\Title;
use Parser;
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
use ParserOutput;
class ParserHooks implements
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
ParserOutputPostCacheTransformHook,
GetDoubleUnderscoreIDsHook,
ParserAfterTidyHook
{
private Config $config;
public function __construct(
ConfigFactory $configFactory
) {
$this->config = $configFactory->makeConfig( 'discussiontools' );
}
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
private function transformHtml(
ParserOutput $pout, string &$html, Title $title, bool $isPreview
): void {
// This condition must be unreliant on current enablement config or user preference.
// In other words, include parser output of talk pages with DT disabled.
//
// This is similar to HookUtils::isAvailableForTitle, but instead of querying the
// database for the latest metadata of a page that exists, we check metadata of
// the given ParserOutput object only (this runs before the edit is saved).
if ( $title->isTalkPage() || $pout->getNewSection() ) {
$talkExpiry = $this->config->get( 'DiscussionToolsTalkPageParserCacheExpiry' );
// Override parser cache expiry of talk pages (T280605).
// Note, this can only shorten it. MediaWiki ignores values higher than the default.
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
// NOTE: this currently has no effect for Parsoid read
// views, since parsoid executes this method as a
// post-cache transform. *However* future work may allow
// caching of intermediate results of the "post cache"
// transformation pipeline, in which case this code will
// again be effective. (More: T350626)
if ( $talkExpiry > 0 ) {
$pout->updateCacheExpiry( $talkExpiry );
}
}
// Always apply the DOM transform if DiscussionTools are available for this page,
// to allow linking to individual comments from Echo 'mention' and 'edit-user-talk'
// notifications (T253082, T281590), and to reduce parser cache fragmentation (T279864).
// The extra buttons are hidden in CSS (ext.discussionTools.init.styles module) when
// the user doesn't have DiscussionTools features enabled.
if ( HookUtils::isAvailableForTitle( $title ) ) {
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
// This modifies $html
CommentFormatter::addDiscussionTools( $html, $pout, $title );
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
if ( $isPreview ) {
$html = CommentFormatter::removeInteractiveTools( $html );
// Suppress the empty state
$pout->setExtensionData( 'DiscussionTools-isEmptyTalkPage', null );
}
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
$pout->addModuleStyles( [ 'ext.discussionTools.init.styles' ] );
}
}
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
/**
* For now, this hook only runs on Parsoid HTML. Eventually, this is likely
* to be run for legacy HTML but that requires ParserCache storage to be allocated
* for DiscussionTools HTML which will be purused separately.
*
* @inheritDoc
*/
public function onParserOutputPostCacheTransform( $parserOutput, &$text, &$options ): void {
// NOTE: This is a temporary proxy for 'isPreview' flag in ParserOptions.
// It is not clear whether 'editsectionEditLinks' is disabled only for previews.
$isPreview = empty( $options['enableSectionEditLinks'] );
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
// We want to run this hook only on Parsoid HTML for now.
// (and leave the onParserAfterTidy handler for legacy HTML).
if ( PageBundleParserOutputConverter::hasPageBundle( $parserOutput ) ) {
$titleDbKey = $parserOutput->getExtensionData( ParsoidParser::PARSOID_TITLE_KEY );
$title = Title::newFromDBkey( $titleDbKey );
'@phan-var Title $title';
$this->transformHtml( $parserOutput, $text, $title, $isPreview );
Add ParserOutputPostCacheTransformHook handler for Parsoid HTML * This patch enables DT to work with Parsoid HTML without changing the functionality for legacy HTML. * The code comments document some of the decisions being made here. Some of these decisions are temporary and need better solutions but this patch will let us run visual diff tests and expose any other latent bugs. TODO ---- * We need to add new tests to verify CommentFormatter expectations for Parsoid HTML. I'll tackle this in a followup patch. Known issues: ------------- * Performance: Since the getText() transformed output in ParserOutput is not cached, if DiscussionTools is to switch over to Parsoid HTML, we have to add some form of caching of the transformed output because transformHtml can take a couple seconds in the p99 case which is too long to render uncached! * Longer-term: Since this hook is called when getText() is called, all calls to getText() will now invoke this handler (which will return but still has to do a bunch of checks to determine this won't apply). Presumably, transformHtml() is idempotent because when some other code (other extensions, for ex) calls getText(), we will run the transfromHtml() on previously transformed content. My understanding is that getText() is going the way of the dodo and that getText() callers will have to explicit call the output transform pipeline code (and presumably this issue of repeatedly calling the same transforms on previously transformed content will be addressed there). * Some CSS doesn't apply to Parsoid HTML because intervening <section> tags interfere with existing query selectors -- will be addressed separately. Bug: T341010 Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
2023-10-27 21:37:22 +00:00
}
}
/**
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ParserAfterTidy
*
* @param Parser $parser
* @param string &$text
*/
public function onParserAfterTidy( $parser, &$text ) {
$pOpts = $parser->getOptions();
if ( $pOpts->getInterfaceMessage() ) {
return;
}
$this->transformHtml(
$parser->getOutput(), $text, $parser->getTitle(), $pOpts->getIsPreview()
);
}
/**
* @see https://www.mediawiki.org/wiki/Manual:Hooks/GetDoubleUnderscoreIDs
*
* @param string[] &$doubleUnderscoreIDs
* @return bool|void
*/
public function onGetDoubleUnderscoreIDs( &$doubleUnderscoreIDs ) {
$doubleUnderscoreIDs[] = 'archivedtalk';
$doubleUnderscoreIDs[] = 'notalk';
}
}