From 7b8bad23f2eb4d9aa2f76e3f99c1c9ec4745da35 Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Tue, 14 Jul 2020 16:07:09 +0300 Subject: [PATCH] Vector manages search functionality and provides config flag Add onSkinPageReadyConfig hook that overrides module after page loaded The new module is currently empty pending further work in the feature branch. Depends-On: I0dc38e74052027f26a70d58b5f520e5830e0d55d Bug: T257706 Change-Id: Ib6c8f890fb3d6e751f5f01a6576614b9cc9b440c --- bundlesize.config.json | 2 +- includes/Hooks.php | 48 +++++++++++++++++++ jsdoc.json | 3 +- resources/MediaWikiPageReady.d.ts | 7 +++ .../VectorResourceLoaderVirtualConfig.d.ts | 7 +++ resources/skins.vector.js/skin.js | 12 +++++ .../skins.vector.legacy.js/skin-legacy.js | 4 ++ skin.json | 18 ++++++- 8 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 resources/MediaWikiPageReady.d.ts create mode 100644 resources/VectorResourceLoaderVirtualConfig.d.ts diff --git a/bundlesize.config.json b/bundlesize.config.json index bef7f6d..74b488a 100644 --- a/bundlesize.config.json +++ b/bundlesize.config.json @@ -17,6 +17,6 @@ }, { "resourceModule": "skins.vector.legacy.js", - "maxSize": "1.7 kB" + "maxSize": "1.8 kB" } ] diff --git a/includes/Hooks.php b/includes/Hooks.php index f1c282d..5736335 100644 --- a/includes/Hooks.php +++ b/includes/Hooks.php @@ -2,11 +2,13 @@ namespace Vector; +use Config; use ExtensionRegistry; use HTMLForm; use MediaWiki\MediaWikiServices; use OutputPage; use RequestContext; +use ResourceLoaderContext; use Skin; use SkinTemplate; use SkinVector; @@ -19,6 +21,21 @@ use User; * on() */ class Hooks { + /** + * Passes config variables to Vector (modern) ResourceLoader module. + * @param ResourceLoaderContext $context + * @param Config $config + * @return array + */ + public static function getVectorResourceLoaderConfig( + ResourceLoaderContext $context, + Config $config + ) { + return [ + 'wgVectorUseCoreSearch' => $config->get( 'VectorUseCoreSearch' ), + ]; + } + /** * BeforePageDisplayMobile hook handler * @@ -52,6 +69,37 @@ class Hooks { } } + /** + * SkinPageReadyConfig hook handler + * + * Replace searchModule provided by skin. + * + * @since 1.35 + * @param ResourceLoaderContext $context + * @param mixed[] &$config Associative array of configurable options + * @return void This hook must not abort, it must return no value + */ + public static function onSkinPageReadyConfig( + ResourceLoaderContext $context, + array &$config + ) { + // It's better to exit before any additional check + if ( $context->getSkin() !== 'vector' ) { + return; + } + + // Tell the `mediawiki.page.ready` module not to wire up search. + // This allows us to use $wgVectorUseCoreSearch to decide to load + // the historic jquery autocomplete search or the new Vue implementation. + // ResourceLoaderContext has no knowledge of legacy / modern Vector + // and from its point of view they are the same thing. + // Please see the modules `skins.vector.js` and `skins.vector.legacy.js` + // for the wire up of search. + // The related method self::getVectorResourceLoaderConfig handles which + // search to load. + $config['search'] = false; + } + /** * Add icon class to an existing navigation item inside a menu hook. * See self::onSkinTemplateNavigation. diff --git a/jsdoc.json b/jsdoc.json index e7f4ab4..c65ce84 100644 --- a/jsdoc.json +++ b/jsdoc.json @@ -25,8 +25,9 @@ "CheckboxHack": "https://doc.wikimedia.org/mediawiki-core/master/js", "MW": "https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw", + "MediaWikiPageReadyModule": "https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.plugin.page.ready", "JQueryStatic": "https://api.jquery.com", - + "VectorResourceLoaderVirtualConfig": "#", "void": "#" } } diff --git a/resources/MediaWikiPageReady.d.ts b/resources/MediaWikiPageReady.d.ts new file mode 100644 index 0000000..95fb117 --- /dev/null +++ b/resources/MediaWikiPageReady.d.ts @@ -0,0 +1,7 @@ +interface MediaWikiPageReadyModule { + /** + * Loads search module when search input is focused. + * @param {string} moduleName to load on input focus. + */ + loadSearchModule(moduleName: string): void +} diff --git a/resources/VectorResourceLoaderVirtualConfig.d.ts b/resources/VectorResourceLoaderVirtualConfig.d.ts new file mode 100644 index 0000000..a460c4d --- /dev/null +++ b/resources/VectorResourceLoaderVirtualConfig.d.ts @@ -0,0 +1,7 @@ +/** See Vector\Hooks::getVectorResourceLoaderConfig */ +interface VectorResourceLoaderVirtualConfig { + /** + * The name of the ResourceLoader module that contains search. + */ + wgVectorUseCoreSearch: boolean +} diff --git a/resources/skins.vector.js/skin.js b/resources/skins.vector.js/skin.js index f478385..471ff1c 100644 --- a/resources/skins.vector.js/skin.js +++ b/resources/skins.vector.js/skin.js @@ -1,5 +1,12 @@ +/** @interface VectorResourceLoaderVirtualConfig */ +/** @interface MediaWikiPageReadyModule */ + var collapsibleTabs = require( '../skins.vector.legacy.js/collapsibleTabs.js' ), vector = require( '../skins.vector.legacy.js/vector.js' ), + /** @type {VectorResourceLoaderVirtualConfig} */ + config = require( /** @type {string} */ ( './config.json' ) ), + /** @type {MediaWikiPageReadyModule} */ + pageReady = require( /** @type {string} */( 'mediawiki.page.ready' ) ), sidebar = require( './sidebar.js' ); /** @@ -43,6 +50,11 @@ function main( window ) { collapsibleTabs.init(); sidebar.init( window ); $( vector.init ); + pageReady.loadSearchModule( + // Decide between new Vue implementation or old. + config.wgVectorUseCoreSearch ? + 'mediawiki.searchSuggest' : 'skins.vector.search' + ); } main( window ); diff --git a/resources/skins.vector.legacy.js/skin-legacy.js b/resources/skins.vector.legacy.js/skin-legacy.js index 40eff8a..8907e02 100644 --- a/resources/skins.vector.legacy.js/skin-legacy.js +++ b/resources/skins.vector.legacy.js/skin-legacy.js @@ -1,10 +1,14 @@ +/** @interface MediaWikiPageReadyModule */ var collapsibleTabs = require( './collapsibleTabs.js' ), + /** @type {MediaWikiPageReadyModule} */ + pageReady = require( /** @type {string} */( 'mediawiki.page.ready' ) ), vector = require( './vector.js' ); function main() { collapsibleTabs.init(); $( vector.init ); + pageReady.loadSearchModule( 'mediawiki.searchSuggest' ); } main(); diff --git a/skin.json b/skin.json index ee18dba..e292653 100644 --- a/skin.json +++ b/skin.json @@ -49,6 +49,7 @@ }, "Hooks": { "BeforePageDisplay": "Vector\\Hooks::onBeforePageDisplay", + "SkinPageReadyConfig": "Vector\\Hooks::onSkinPageReadyConfig", "GetPreferences": "Vector\\Hooks::onGetPreferences", "PreferencesFormPreSave": "Vector\\Hooks::onPreferencesFormPreSave", "SkinTemplateNavigation": "Vector\\Hooks::onSkinTemplateNavigation", @@ -96,16 +97,25 @@ ], "styles": [ "resources/skins.vector.styles.responsive.less" ] }, + "skins.vector.search": { + "dependencies": [ + "vue" + ] + }, "skins.vector.js": { "packageFiles": [ "resources/skins.vector.js/skin.js", + { + "name": "resources/skins.vector.js/config.json", + "callback": "Vector\\Hooks::getVectorResourceLoaderConfig" + }, "resources/skins.vector.js/sidebar.js", "resources/skins.vector.legacy.js/collapsibleTabs.js", "resources/skins.vector.legacy.js/vector.js" ], "dependencies": [ - "mediawiki.util", - "mediawiki.page.ready" + "mediawiki.page.ready", + "mediawiki.util" ] }, "skins.vector.legacy.js": { @@ -115,6 +125,7 @@ "resources/skins.vector.legacy.js/vector.js" ], "dependencies": [ + "mediawiki.page.ready", "mediawiki.util" ] } @@ -172,6 +183,9 @@ "value": "1", "description": "@var string:['2'|'1'] The version ('2' for latest, '1' for legacy) of the Vector skin to **set** for newly created user accounts. **The value is persisted as a user preference.** This configuration is not used for preexisting accounts (see VectorDefaultSkinVersionForExistingAccounts) and only ever executed once at new account creation time." }, + "VectorUseCoreSearch": { + "value": true + }, "VectorDefaultSidebarVisibleForAuthorisedUser": { "value": true },