mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Cite
synced 2024-11-23 14:36:51 +00:00
Move Reference Previews user preference into the Cite extension
This seems to play well with Popups with and without Ie8fa1672b9fd . However, it's not clear to me why this still works and even gives priority to the Popups implementation when present, regardless of the order the extensions are loaded in. Happily, this is the desired behavior. Bug: T363162 Change-Id: Ic479c0a381ee16d1abcecfdd5ee48f0afccc1d3f
This commit is contained in:
parent
8e4c83bfc6
commit
c7b60735fe
|
@ -26,6 +26,7 @@
|
|||
"Hooks": {
|
||||
"APIQuerySiteInfoGeneralInfo": "main",
|
||||
"ContentHandlerDefaultModelFor": "main",
|
||||
"GetPreferences": "main",
|
||||
"ParserAfterParse": "parser",
|
||||
"ParserClearState": "parser",
|
||||
"ParserCloned": "parser",
|
||||
|
@ -33,13 +34,15 @@
|
|||
"EditPage::showEditForm:initial": "main",
|
||||
"MakeGlobalVariablesScript": "main",
|
||||
"ResourceLoaderGetConfigVars": "main",
|
||||
"ResourceLoaderRegisterModules": "main"
|
||||
"ResourceLoaderRegisterModules": "main",
|
||||
"UserGetDefaultOptions": "main"
|
||||
},
|
||||
"HookHandlers": {
|
||||
"main": {
|
||||
"class": "Cite\\Hooks\\CiteHooks",
|
||||
"services": [
|
||||
"Cite.ReferencePreviewsContext",
|
||||
"Cite.GadgetsIntegration",
|
||||
"UserOptionsLookup"
|
||||
]
|
||||
},
|
||||
|
|
|
@ -79,5 +79,9 @@
|
|||
"cite-wikieditor-help-content-reference-example-ref-reuse": "<ref name=\"$1\" />",
|
||||
"cite-wikieditor-help-content-reference-example-ref-extends": "<ref extends=\"$1\">$2</ref>",
|
||||
"cite-wikieditor-help-content-reference-example-ref-result": "[$1]",
|
||||
"cite-wikieditor-help-content-reference-example-reflist": "<references />"
|
||||
"cite-wikieditor-help-content-reference-example-reflist": "<references />",
|
||||
"popups-prefs-navpopups-gadget-conflict-info": "You have the [[$1|Navigation popups]] gadget enabled, so you won't see previews provided by this feature. Depending on your wiki, the gadget may have a slightly different name. If you continue to experience issues, please review your gadgets and user scripts, including global ones.",
|
||||
"popups-prefs-reftooltips-and-navpopups-gadget-conflict-info": "You have the [[$1|Navigation popups]] and [[$1|Reference Tooltips]] gadgets enabled, so you won't see previews provided by this feature. Depending on your wiki, the gadgets may have slightly different names. If you continue to experience issues, please review your gadgets and user scripts, including global ones.",
|
||||
"popups-prefs-reftooltips-gadget-conflict-info": "You have the [[$1|Reference Tooltips]] gadget enabled, so you won't see reference previews but will still see page previews. Depending on your wiki, the gadget may have a slightly different name. If you continue to experience issues, please review your gadgets and user scripts, including global ones.",
|
||||
"popups-refpreview-user-preference-label": "Enable reference previews (get quick previews of a reference while reading a page)"
|
||||
}
|
||||
|
|
|
@ -84,5 +84,9 @@
|
|||
"cite-wikieditor-help-content-reference-example-ref-reuse": "{{ignored}}",
|
||||
"cite-wikieditor-help-content-reference-example-ref-extends": "{{ignored}}",
|
||||
"cite-wikieditor-help-content-reference-example-ref-result": "{{ignored}}",
|
||||
"cite-wikieditor-help-content-reference-example-reflist": "{{ignored}}"
|
||||
"cite-wikieditor-help-content-reference-example-reflist": "{{ignored}}",
|
||||
"popups-prefs-navpopups-gadget-conflict-info": "Help message telling to disable the \"Navigation popups\" gadget in order to allow page and reference previews. The word \"Gadgets\" should be based on {{msg-mw|prefs-gadgets}}.\n\nParameters:\n* $1 – Link to the Gadgets tab in the user's preferences",
|
||||
"popups-prefs-reftooltips-gadget-conflict-info": "Help message telling to disable the \"Reference Tooltips\" gadget in order to allow reference previews. The word \"Gadgets\" should be based on {{msg-mw|prefs-gadgets}}.\n\nParameters:\n* $1 – Link to the Gadgets tab in the user's preferences",
|
||||
"popups-prefs-reftooltips-and-navpopups-gadget-conflict-info": "Help message telling to disable the \"Navigation popups\" and \"Reference Tooltips\" gadgets in order to allow page and reference previews. The word \"Gadgets\" should be based on {{msg-mw|prefs-gadgets}}.\n\nParameters:\n* $1 – Link to the Gadgets tab in the user's preferences",
|
||||
"popups-refpreview-user-preference-label": "Label for the user option to enable or disable reference preview popups"
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace Cite\Hooks;
|
|||
|
||||
use ApiQuerySiteinfo;
|
||||
use Cite\ReferencePreviews\ReferencePreviewsContext;
|
||||
use Cite\ReferencePreviews\ReferencePreviewsGadgetsIntegration;
|
||||
use ExtensionRegistry;
|
||||
use MediaWiki\Api\Hook\APIQuerySiteInfoGeneralInfoHook;
|
||||
use MediaWiki\Config\Config;
|
||||
|
@ -21,6 +22,7 @@ use MediaWiki\ResourceLoader\ResourceLoader;
|
|||
use MediaWiki\Revision\Hook\ContentHandlerDefaultModelForHook;
|
||||
use MediaWiki\Title\Title;
|
||||
use MediaWiki\User\Options\UserOptionsLookup;
|
||||
use MediaWiki\User\User;
|
||||
|
||||
/**
|
||||
* @license GPL-2.0-or-later
|
||||
|
@ -36,13 +38,16 @@ class CiteHooks implements
|
|||
{
|
||||
|
||||
private ReferencePreviewsContext $referencePreviewsContext;
|
||||
private ReferencePreviewsGadgetsIntegration $gadgetsIntegration;
|
||||
private UserOptionsLookup $userOptionsLookup;
|
||||
|
||||
public function __construct(
|
||||
ReferencePreviewsContext $referencePreviewsContext,
|
||||
ReferencePreviewsGadgetsIntegration $gadgetsIntegration,
|
||||
UserOptionsLookup $userOptionsLookup
|
||||
) {
|
||||
$this->referencePreviewsContext = $referencePreviewsContext;
|
||||
$this->gadgetsIntegration = $gadgetsIntegration;
|
||||
$this->userOptionsLookup = $userOptionsLookup;
|
||||
}
|
||||
|
||||
|
@ -172,4 +177,52 @@ class CiteHooks implements
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add options to user Preferences page
|
||||
*
|
||||
* @param User $user User whose preferences are being modified
|
||||
* @param array[] &$prefs Preferences description array, to be fed to a HTMLForm object
|
||||
*/
|
||||
public function onGetPreferences( $user, &$prefs ) {
|
||||
$option = [
|
||||
'type' => 'toggle',
|
||||
'label-message' => 'popups-refpreview-user-preference-label',
|
||||
// FIXME: This message is unnecessary and unactionable since we already
|
||||
// detect specific gadget conflicts.
|
||||
'help-message' => 'popups-prefs-conflicting-gadgets-info',
|
||||
// FIXME: copied from Popups
|
||||
'section' => 'rendering/reading',
|
||||
];
|
||||
$isNavPopupsGadgetEnabled = $this->gadgetsIntegration->isNavPopupsGadgetEnabled( $user );
|
||||
$isRefTooltipsGadgetEnabled = $this->gadgetsIntegration->isRefTooltipsGadgetEnabled( $user );
|
||||
if ( $isNavPopupsGadgetEnabled && $isRefTooltipsGadgetEnabled ) {
|
||||
$option[ 'disabled' ] = true;
|
||||
$option[ 'help-message' ] = [ 'popups-prefs-reftooltips-and-navpopups-gadget-conflict-info',
|
||||
'Special:Preferences#mw-prefsection-gadgets' ];
|
||||
} elseif ( $isNavPopupsGadgetEnabled ) {
|
||||
$option[ 'disabled' ] = true;
|
||||
$option[ 'help-message' ] = [ 'popups-prefs-navpopups-gadget-conflict-info',
|
||||
'Special:Preferences#mw-prefsection-gadgets' ];
|
||||
} elseif ( $isRefTooltipsGadgetEnabled ) {
|
||||
$option[ 'disabled' ] = true;
|
||||
$option[ 'help-message' ] = [ 'popups-prefs-reftooltips-gadget-conflict-info',
|
||||
'Special:Preferences#mw-prefsection-gadgets' ];
|
||||
}
|
||||
|
||||
$prefs += [
|
||||
ReferencePreviewsContext::REFERENCE_PREVIEWS_PREFERENCE_NAME => $option
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://www.mediawiki.org/wiki/Manual:Hooks/UserGetDefaultOptions
|
||||
* @param array &$defaultOptions Array of preference keys and their default values.
|
||||
*/
|
||||
public static function onUserGetDefaultOptions( &$defaultOptions ) {
|
||||
// FIXME: Move to extension.json once migration is complete. See T363162
|
||||
if ( !isset( $defaultOptions[ ReferencePreviewsContext::REFERENCE_PREVIEWS_PREFERENCE_NAME ] ) ) {
|
||||
$defaultOptions[ ReferencePreviewsContext::REFERENCE_PREVIEWS_PREFERENCE_NAME ] = '1';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@ class ReferencePreviewsContext {
|
|||
|
||||
public function __construct(
|
||||
Config $config,
|
||||
ReferencePreviewsGadgetsIntegration $gadgetsIntegration,
|
||||
UserOptionsLookup $userOptionsLookup
|
||||
) {
|
||||
$this->gadgetsIntegration = new ReferencePreviewsGadgetsIntegration( $config );
|
||||
$this->userOptionsLookup = $userOptionsLookup;
|
||||
|
||||
$this->config = $config;
|
||||
$this->gadgetsIntegration = $gadgetsIntegration;
|
||||
$this->userOptionsLookup = $userOptionsLookup;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,10 +5,8 @@ namespace Cite\ReferencePreviews;
|
|||
use InvalidArgumentException;
|
||||
use MediaWiki\Config\Config;
|
||||
use MediaWiki\Extension\Gadgets\GadgetRepo;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\User\User;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
use Wikimedia\Services\NoSuchServiceException;
|
||||
|
||||
/**
|
||||
* Gadgets integration
|
||||
|
@ -25,17 +23,13 @@ class ReferencePreviewsGadgetsIntegration {
|
|||
private string $navPopupsGadgetName;
|
||||
private string $refTooltipsGadgetName;
|
||||
|
||||
public function __construct( Config $config ) {
|
||||
public function __construct( Config $config, ?GadgetRepo $gadgetRepo ) {
|
||||
$this->navPopupsGadgetName = $this->sanitizeGadgetName(
|
||||
$config->get( self::CONFIG_NAVIGATION_POPUPS_NAME ) );
|
||||
$this->refTooltipsGadgetName = $this->sanitizeGadgetName(
|
||||
$config->get( self::CONFIG_REFERENCE_TOOLTIPS_NAME ) );
|
||||
|
||||
try {
|
||||
$this->gadgetRepo = MediaWikiServices::getInstance()->getService( 'GadgetsRepo' );
|
||||
} catch ( NoSuchServiceException $e ) {
|
||||
$this->gadgetRepo = null;
|
||||
}
|
||||
$this->gadgetRepo = $gadgetRepo;
|
||||
}
|
||||
|
||||
private function sanitizeGadgetName( string $gadgetName ): string {
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
<?php
|
||||
|
||||
use Cite\ReferencePreviews\ReferencePreviewsContext;
|
||||
use Cite\ReferencePreviews\ReferencePreviewsGadgetsIntegration;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Registration\ExtensionRegistry;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
return [
|
||||
'Cite.GadgetsIntegration' => static function ( MediaWikiServices $services ): ReferencePreviewsGadgetsIntegration {
|
||||
return new ReferencePreviewsGadgetsIntegration(
|
||||
$services->getMainConfig(),
|
||||
ExtensionRegistry::getInstance()->isLoaded( 'Gadgets' ) ?
|
||||
$services->getService( 'GadgetsRepo' ) :
|
||||
null
|
||||
);
|
||||
},
|
||||
'Cite.ReferencePreviewsContext' => static function ( MediaWikiServices $services ): ReferencePreviewsContext {
|
||||
return new ReferencePreviewsContext(
|
||||
$services->getMainConfig(),
|
||||
$services->getService( 'Cite.GadgetsIntegration' ),
|
||||
$services->getUserOptionsLookup()
|
||||
);
|
||||
},
|
||||
|
|
|
@ -4,9 +4,11 @@ namespace Cite\Tests;
|
|||
|
||||
use ApiQuerySiteinfo;
|
||||
use Cite\Hooks\CiteHooks;
|
||||
use Cite\ReferencePreviews\ReferencePreviewsGadgetsIntegration;
|
||||
use MediaWiki\Config\HashConfig;
|
||||
use MediaWiki\ResourceLoader\ResourceLoader;
|
||||
use MediaWiki\User\Options\StaticUserOptionsLookup;
|
||||
use MediaWiki\User\User;
|
||||
|
||||
/**
|
||||
* @covers \Cite\Hooks\CiteHooks
|
||||
|
@ -28,6 +30,7 @@ class CiteHooksTest extends \MediaWikiIntegrationTestCase {
|
|||
|
||||
( new CiteHooks(
|
||||
$this->getServiceContainer()->getService( 'Cite.ReferencePreviewsContext' ),
|
||||
$this->getServiceContainer()->getService( 'Cite.GadgetsIntegration' ),
|
||||
new StaticUserOptionsLookup( [] )
|
||||
) )
|
||||
->onResourceLoaderGetConfigVars( $vars, 'vector', $config );
|
||||
|
@ -53,6 +56,7 @@ class CiteHooksTest extends \MediaWikiIntegrationTestCase {
|
|||
|
||||
( new CiteHooks(
|
||||
$this->getServiceContainer()->getService( 'Cite.ReferencePreviewsContext' ),
|
||||
$this->getServiceContainer()->getService( 'Cite.GadgetsIntegration' ),
|
||||
new StaticUserOptionsLookup( [] )
|
||||
) )
|
||||
->onResourceLoaderRegisterModules( $resourceLoader );
|
||||
|
@ -71,6 +75,7 @@ class CiteHooksTest extends \MediaWikiIntegrationTestCase {
|
|||
|
||||
( new CiteHooks(
|
||||
$this->getServiceContainer()->getService( 'Cite.ReferencePreviewsContext' ),
|
||||
$this->getServiceContainer()->getService( 'Cite.GadgetsIntegration' ),
|
||||
new StaticUserOptionsLookup( [] )
|
||||
) )
|
||||
->onAPIQuerySiteInfoGeneralInfo( $api, $data );
|
||||
|
@ -83,4 +88,69 @@ class CiteHooksTest extends \MediaWikiIntegrationTestCase {
|
|||
yield [ false ];
|
||||
}
|
||||
|
||||
public function testOnGetPreferences_noConflicts() {
|
||||
$expected = [
|
||||
'popups-reference-previews' => [
|
||||
'type' => 'toggle',
|
||||
'label-message' => 'popups-refpreview-user-preference-label',
|
||||
'help-message' => 'popups-prefs-conflicting-gadgets-info',
|
||||
'section' => 'rendering/reading'
|
||||
]
|
||||
];
|
||||
$gadgetsIntegrationMock = $this->createMock( ReferencePreviewsGadgetsIntegration::class );
|
||||
$prefs = [];
|
||||
( new CiteHooks(
|
||||
$this->getServiceContainer()->getService( 'Cite.ReferencePreviewsContext' ),
|
||||
$gadgetsIntegrationMock,
|
||||
new StaticUserOptionsLookup( [] )
|
||||
) )
|
||||
->onGetPreferences( $this->createMock( User::class ), $prefs );
|
||||
$this->assertEquals( $expected, $prefs );
|
||||
}
|
||||
|
||||
public function testOnGetPreferences_conflictingGadget() {
|
||||
$expected = [
|
||||
'popups-reference-previews' => [
|
||||
'type' => 'toggle',
|
||||
'label-message' => 'popups-refpreview-user-preference-label',
|
||||
// 'help-message' => 'popups-prefs-conflicting-gadgets-info',
|
||||
'help-message' => [
|
||||
'popups-prefs-navpopups-gadget-conflict-info',
|
||||
'Special:Preferences#mw-prefsection-gadgets',
|
||||
],
|
||||
'section' => 'rendering/reading',
|
||||
'disabled' => true
|
||||
]
|
||||
];
|
||||
$gadgetsIntegrationMock = $this->createMock( ReferencePreviewsGadgetsIntegration::class );
|
||||
$gadgetsIntegrationMock->expects( $this->once() )
|
||||
->method( 'isNavPopupsGadgetEnabled' )
|
||||
->willReturn( true );
|
||||
$prefs = [];
|
||||
( new CiteHooks(
|
||||
$this->getServiceContainer()->getService( 'Cite.ReferencePreviewsContext' ),
|
||||
$gadgetsIntegrationMock,
|
||||
new StaticUserOptionsLookup( [] )
|
||||
) )
|
||||
->onGetPreferences( $this->createMock( User::class ), $prefs );
|
||||
$this->assertEquals( $expected, $prefs );
|
||||
}
|
||||
|
||||
public function testOnGetPreferences_redundantPreference() {
|
||||
$prefs = [
|
||||
'popups-reference-previews' => [
|
||||
'type' => 'toggle',
|
||||
'label-message' => 'from-another-extension',
|
||||
]
|
||||
];
|
||||
$expected = $prefs;
|
||||
( new CiteHooks(
|
||||
$this->getServiceContainer()->getService( 'Cite.ReferencePreviewsContext' ),
|
||||
$this->getServiceContainer()->getService( 'Cite.GadgetsIntegration' ),
|
||||
new StaticUserOptionsLookup( [] )
|
||||
) )
|
||||
->onGetPreferences( $this->createMock( User::class ), $prefs );
|
||||
$this->assertEquals( $expected, $prefs );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ class ReferencePreviewsContextTest extends MediaWikiIntegrationTestCase {
|
|||
$this->assertSame( $expected,
|
||||
( new ReferencePreviewsContext(
|
||||
$config,
|
||||
$this->getServiceContainer()->getService( 'Cite.GadgetsIntegration' ),
|
||||
$userOptLookup
|
||||
) )
|
||||
->isReferencePreviewsEnabled( $user, $skin ),
|
||||
|
@ -80,6 +81,7 @@ class ReferencePreviewsContextTest extends MediaWikiIntegrationTestCase {
|
|||
$this->assertSame( $expected,
|
||||
( new ReferencePreviewsContext(
|
||||
$config,
|
||||
$this->getServiceContainer()->getService( 'Cite.GadgetsIntegration' ),
|
||||
$userOptLookup
|
||||
) )
|
||||
->isReferencePreviewsEnabled( $user, $skin ),
|
||||
|
|
|
@ -39,9 +39,12 @@ class ReferencePreviewsGadgetsIntegrationTest extends MediaWikiIntegrationTestCa
|
|||
}
|
||||
|
||||
public function testConflictsWithNavPopupsGadgetIfGadgetsExtensionIsNotLoaded() {
|
||||
$integration = new ReferencePreviewsGadgetsIntegration( $this->getConfig() );
|
||||
$this->assertFalse(
|
||||
$integration->isNavPopupsGadgetEnabled( $this->createNoOpMock( User::class ) ),
|
||||
( new ReferencePreviewsGadgetsIntegration(
|
||||
$this->getConfig(),
|
||||
null
|
||||
) )
|
||||
->isNavPopupsGadgetEnabled( $this->createNoOpMock( User::class ) ),
|
||||
'No conflict is identified.'
|
||||
);
|
||||
}
|
||||
|
@ -153,12 +156,13 @@ class ReferencePreviewsGadgetsIntegrationTest extends MediaWikiIntegrationTestCa
|
|||
GadgetRepo $repoMock,
|
||||
bool $expected
|
||||
): void {
|
||||
$this->setService( 'GadgetsRepo', $repoMock );
|
||||
|
||||
$integration = new ReferencePreviewsGadgetsIntegration( $config );
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$integration->isNavPopupsGadgetEnabled( $user ),
|
||||
( new ReferencePreviewsGadgetsIntegration(
|
||||
$config,
|
||||
$repoMock
|
||||
) )
|
||||
->isNavPopupsGadgetEnabled( $user ),
|
||||
( $expected ? 'A' : 'No' ) . ' conflict is identified.'
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Cite\Tests\Unit;
|
|||
|
||||
use Cite\Hooks\CiteHooks;
|
||||
use Cite\ReferencePreviews\ReferencePreviewsContext;
|
||||
use Cite\ReferencePreviews\ReferencePreviewsGadgetsIntegration;
|
||||
use MediaWiki\Title\Title;
|
||||
use MediaWiki\User\Options\StaticUserOptionsLookup;
|
||||
|
||||
|
@ -22,6 +23,7 @@ class CiteHooksUnitTest extends \MediaWikiUnitTestCase {
|
|||
|
||||
( new CiteHooks(
|
||||
$this->createMock( ReferencePreviewsContext::class ),
|
||||
$this->createMock( ReferencePreviewsGadgetsIntegration::class ),
|
||||
new StaticUserOptionsLookup( [] )
|
||||
) )
|
||||
->onContentHandlerDefaultModelFor( $title, $model );
|
||||
|
|
Loading…
Reference in a new issue