2021-01-29 17:09:52 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* DiscussionTools page hooks
|
|
|
|
*
|
|
|
|
* @file
|
|
|
|
* @ingroup Extensions
|
|
|
|
* @license MIT
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace MediaWiki\Extension\DiscussionTools\Hooks;
|
|
|
|
|
2021-01-29 18:31:27 +00:00
|
|
|
use MediaWiki\Extension\DiscussionTools\CommentFormatter;
|
2021-02-17 22:34:02 +00:00
|
|
|
use MediaWiki\Extension\DiscussionTools\SubscriptionStore;
|
2021-01-29 17:09:52 +00:00
|
|
|
use MediaWiki\Hook\BeforePageDisplayHook;
|
|
|
|
use MediaWiki\Hook\OutputPageBeforeHTMLHook;
|
|
|
|
use MediaWiki\MediaWikiServices;
|
|
|
|
use OutputPage;
|
|
|
|
use Skin;
|
|
|
|
use VisualEditorHooks;
|
|
|
|
|
|
|
|
class PageHooks implements
|
|
|
|
BeforePageDisplayHook,
|
|
|
|
OutputPageBeforeHTMLHook
|
|
|
|
{
|
2021-02-17 22:34:02 +00:00
|
|
|
/** @var SubscriptionStore */
|
|
|
|
protected $subscriptionStore;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param SubscriptionStore $subscriptionStore
|
|
|
|
*/
|
|
|
|
public function __construct( SubscriptionStore $subscriptionStore ) {
|
|
|
|
$this->subscriptionStore = $subscriptionStore;
|
|
|
|
}
|
|
|
|
|
2021-01-29 17:09:52 +00:00
|
|
|
/**
|
|
|
|
* Adds DiscussionTools JS to the output.
|
|
|
|
*
|
|
|
|
* This is attached to the MediaWiki 'BeforePageDisplay' hook.
|
|
|
|
*
|
|
|
|
* @param OutputPage $output
|
|
|
|
* @param Skin $skin
|
|
|
|
* @return void This hook must not abort, it must return no value
|
|
|
|
*/
|
2021-07-22 07:25:13 +00:00
|
|
|
public function onBeforePageDisplay( $output, $skin ): void {
|
2021-01-29 17:09:52 +00:00
|
|
|
$user = $output->getUser();
|
2021-03-06 12:08:50 +00:00
|
|
|
// Load style modules if the tools can be available for the title
|
|
|
|
// as this means the DOM may have been modified in the parser cache.
|
|
|
|
if ( HookUtils::isAvailableForTitle( $output->getTitle() ) ) {
|
2021-01-29 17:09:52 +00:00
|
|
|
$output->addModuleStyles( [
|
2021-02-17 22:34:02 +00:00
|
|
|
'ext.discussionTools.init.styles',
|
2021-01-29 17:09:52 +00:00
|
|
|
] );
|
2021-03-06 12:08:50 +00:00
|
|
|
}
|
|
|
|
// Load modules if any DT feature is enabled for this user
|
|
|
|
if ( HookUtils::isFeatureEnabledForOutput( $output ) ) {
|
2021-01-29 17:09:52 +00:00
|
|
|
$output->addModules( [
|
|
|
|
'ext.discussionTools.init'
|
|
|
|
] );
|
|
|
|
|
2021-02-17 17:16:17 +00:00
|
|
|
$enabledVars = [];
|
|
|
|
foreach ( HookUtils::FEATURES as $feature ) {
|
|
|
|
$enabledVars[$feature] = HookUtils::isFeatureEnabledForOutput( $output, $feature );
|
|
|
|
}
|
|
|
|
$output->addJsConfigVars( 'wgDiscussionToolsFeaturesEnabled', $enabledVars );
|
2021-01-29 17:09:52 +00:00
|
|
|
|
|
|
|
$services = MediaWikiServices::getInstance();
|
|
|
|
$optionsLookup = $services->getUserOptionsLookup();
|
|
|
|
$req = $output->getRequest();
|
|
|
|
$editor = $optionsLookup->getOption( $user, 'discussiontools-editmode' );
|
|
|
|
// User has no preferred editor yet
|
|
|
|
// If the user has a preferred editor, this will be evaluated in the client
|
|
|
|
if ( !$editor ) {
|
|
|
|
// Check which editor we would use for articles
|
|
|
|
// VE pref is 'visualeditor'/'wikitext'. Here we describe the mode,
|
|
|
|
// not the editor, so 'visual'/'source'
|
|
|
|
$editor = VisualEditorHooks::getPreferredEditor( $user, $req ) === 'visualeditor' ?
|
|
|
|
'visual' : 'source';
|
|
|
|
$output->addJsConfigVars(
|
|
|
|
'wgDiscussionToolsFallbackEditMode',
|
|
|
|
$editor
|
|
|
|
);
|
|
|
|
}
|
|
|
|
$dtConfig = $services->getConfigFactory()->makeConfig( 'discussiontools' );
|
|
|
|
$abstate = $dtConfig->get( 'DiscussionToolsABTest' ) ?
|
|
|
|
$optionsLookup->getOption( $user, 'discussiontools-abtest' ) :
|
|
|
|
false;
|
|
|
|
if ( $abstate ) {
|
|
|
|
$output->addJsConfigVars(
|
|
|
|
'wgDiscussionToolsABTestBucket',
|
|
|
|
$abstate
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* OutputPageBeforeHTML hook handler
|
|
|
|
* @see https://www.mediawiki.org/wiki/Manual:Hooks/OutputPageBeforeHTML
|
|
|
|
*
|
|
|
|
* @param OutputPage $output OutputPage object that corresponds to the page
|
|
|
|
* @param string &$text Text that will be displayed, in HTML
|
|
|
|
* @return bool|void This hook must not abort, it must return true or null.
|
|
|
|
*/
|
|
|
|
public function onOutputPageBeforeHTML( $output, &$text ) {
|
2021-01-28 17:14:20 +00:00
|
|
|
$lang = $output->getLanguage();
|
2021-04-19 18:34:55 +00:00
|
|
|
// Check after the parser cache if tools need to be added for
|
2021-01-29 17:09:52 +00:00
|
|
|
// non-cacheable reasons i.e. query string or cookie
|
2021-04-19 18:34:55 +00:00
|
|
|
// The addDiscussionTools method is responsible for ensuring that
|
|
|
|
// tools aren't added twice.
|
2021-02-17 17:16:17 +00:00
|
|
|
foreach ( CommentFormatter::USE_WITH_FEATURES as $feature ) {
|
|
|
|
if ( HookUtils::isFeatureEnabledForOutput( $output, $feature ) ) {
|
2021-04-15 21:09:55 +00:00
|
|
|
CommentFormatter::addDiscussionTools( $text );
|
2021-02-17 17:16:17 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-01-28 17:14:20 +00:00
|
|
|
|
2021-02-17 17:16:17 +00:00
|
|
|
foreach ( HookUtils::FEATURES as $feature ) {
|
|
|
|
// Add a CSS class for each enabled feature
|
|
|
|
if ( HookUtils::isFeatureEnabledForOutput( $output, $feature ) ) {
|
2021-03-13 14:39:39 +00:00
|
|
|
$output->addBodyClasses( "ext-discussiontools-$feature-enabled" );
|
2021-02-17 17:16:17 +00:00
|
|
|
}
|
2021-01-29 17:09:52 +00:00
|
|
|
}
|
2021-02-17 17:16:17 +00:00
|
|
|
|
2021-04-08 12:30:28 +00:00
|
|
|
if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::TOPICSUBSCRIPTION ) ) {
|
2021-04-19 19:14:07 +00:00
|
|
|
$text = CommentFormatter::postprocessTopicSubscription(
|
|
|
|
$text, $lang, $this->subscriptionStore, $output->getUser()
|
2021-02-17 22:34:02 +00:00
|
|
|
);
|
|
|
|
}
|
2021-04-15 21:09:55 +00:00
|
|
|
if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::REPLYTOOL ) ) {
|
|
|
|
$text = CommentFormatter::postprocessReplyTool(
|
|
|
|
$text, $lang
|
|
|
|
);
|
|
|
|
}
|
2021-02-17 22:34:02 +00:00
|
|
|
|
2021-01-29 17:09:52 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|