wiki.techinc.nl/includes/resourceloader/ResourceLoaderUserOptionsModule.php

81 lines
1.9 KiB
PHP
Raw Normal View History

<?php
/**
* ResourceLoader module for user preference customizations.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @author Trevor Parscal
* @author Roan Kattouw
*/
/**
* Module for user preference customizations
*/
class ResourceLoaderUserOptionsModule extends ResourceLoaderModule {
protected $origin = self::ORIGIN_CORE_INDIVIDUAL;
protected $targets = [ 'desktop', 'mobile' ];
/**
resourceloader: Add context param to ResourceLoaderModule::getDependencies By providing context as a parameter in getDependencies, we allow modules to dyanamically determine dependencies based on context. Note: To ease rollout, the parameter is optional in this patch. It is expected that it will be made non-optional in the near future. The use case is for CentralNotice campaigns to be able to add special modules ahead of deciding which banner to show a user. The dynamically chosen RL modules would replace ad-hoc JS currently sent with some banners. A list of possible campaigns and banners is already sent as a PHP- implemented RL module; that's the module that will dynamically choose other modules as dependencies when appropriate. This approach will save a round trip as compared to dynamically loading the modules client-side. For compatibility, extensions that override ResourceLoaderModule::getDependencies() should be updated with the new method signature. Here are changes for extensions currently deployed on Wikimedia wikis: * CentralNotice: I816bffa3815e2eab7e88cb04d1b345070e6aa15f * Gadgets: I0a10fb0cbf17d095ece493e744296caf13dcee02 * EventLogging: I67e957f74d6ca48cfb9a41fb5144bcc78f885e50 * PageTriage: Ica3ba32aa2fc76d11a44f391b6edfc871e7fbe0d * UniversalLanguageSelector: Ic63e617f51702c27104e123d4bed91983a726b7f * VisualEditor: I0ac775ca286e64825e31a9213b94648e41a5bc30 For more on the CentralNotice use case, please see I9f80edcbcacca2. Bug: T98924 Change-Id: Iee61e5b527321d01287baa03ad9b4d4f526ff3ef
2015-04-08 21:34:08 +00:00
* @param ResourceLoaderContext $context
* @return array List of module names as strings
*/
resourceloader: Add context param to ResourceLoaderModule::getDependencies By providing context as a parameter in getDependencies, we allow modules to dyanamically determine dependencies based on context. Note: To ease rollout, the parameter is optional in this patch. It is expected that it will be made non-optional in the near future. The use case is for CentralNotice campaigns to be able to add special modules ahead of deciding which banner to show a user. The dynamically chosen RL modules would replace ad-hoc JS currently sent with some banners. A list of possible campaigns and banners is already sent as a PHP- implemented RL module; that's the module that will dynamically choose other modules as dependencies when appropriate. This approach will save a round trip as compared to dynamically loading the modules client-side. For compatibility, extensions that override ResourceLoaderModule::getDependencies() should be updated with the new method signature. Here are changes for extensions currently deployed on Wikimedia wikis: * CentralNotice: I816bffa3815e2eab7e88cb04d1b345070e6aa15f * Gadgets: I0a10fb0cbf17d095ece493e744296caf13dcee02 * EventLogging: I67e957f74d6ca48cfb9a41fb5144bcc78f885e50 * PageTriage: Ica3ba32aa2fc76d11a44f391b6edfc871e7fbe0d * UniversalLanguageSelector: Ic63e617f51702c27104e123d4bed91983a726b7f * VisualEditor: I0ac775ca286e64825e31a9213b94648e41a5bc30 For more on the CentralNotice use case, please see I9f80edcbcacca2. Bug: T98924 Change-Id: Iee61e5b527321d01287baa03ad9b4d4f526ff3ef
2015-04-08 21:34:08 +00:00
public function getDependencies( ResourceLoaderContext $context = null ) {
return [ 'user.defaults' ];
}
/**
resourceloader: Enable module content version for data modules This greatly simplifies logic required to compute module versions. It also makes it significantly less error-prone. Since f37cee996e, we support hashes as versions (instead of timestamps). This means we can build a hash of the content directly, instead of compiling a large array with all values that may influence the module content somehow. Benefits: * Remove all methods and logic related to querying database and disk for timestamps, revision numbers, definition summaries, cache epochs, and more. * No longer needlessly invalidate cache as a result of no-op changes to implementation datails. Due to inclusion of absolute file paths in the definition summary, cache was always invalidated when moving wikis to newer MediaWiki branches; even if the module observed no actual changes. * When changes are reverted within a certain period of time, old caches can now be re-used. The module would produce the same version hash as before. Previously when a change was deployed and then reverted, all web clients (even those that never saw the bad version) would have re-fetch modules because the version increased. Updated unit tests to account for the change in version. New default version of empty test modules is: "mvgTPvXh". For the record, this comes from the base64 encoding of the SHA1 digest of the JSON serialised form of the module content: > $str = '{"scripts":"","styles":{"css":[]},"messagesBlob":"{}"}'; > echo base64_encode(sha1($str, true)); > FEb3+VuiUm/fOMfod1bjw/te+AQ= Enabled content versioning for the data modules in MediaWiki core: * EditToolbarModule * JqueryMsgModule * LanguageDataModule * LanguageNamesModule * SpecialCharacterDataModule * UserCSSPrefsModule * UserDefaultsModule * UserOptionsModule The FileModule and base class explicitly disable it for now and keep their current behaviour of using the definition summary. We may remove it later, but that requires more performance testing first. Explicitly disable it in the WikiModule class to avoid breakage when the default changes. Ref T98087. Change-Id: I782df43c50dfcfb7d7592f744e13a3a0430b0dc6
2015-06-02 17:27:23 +00:00
* @return bool
*/
resourceloader: Enable module content version for data modules This greatly simplifies logic required to compute module versions. It also makes it significantly less error-prone. Since f37cee996e, we support hashes as versions (instead of timestamps). This means we can build a hash of the content directly, instead of compiling a large array with all values that may influence the module content somehow. Benefits: * Remove all methods and logic related to querying database and disk for timestamps, revision numbers, definition summaries, cache epochs, and more. * No longer needlessly invalidate cache as a result of no-op changes to implementation datails. Due to inclusion of absolute file paths in the definition summary, cache was always invalidated when moving wikis to newer MediaWiki branches; even if the module observed no actual changes. * When changes are reverted within a certain period of time, old caches can now be re-used. The module would produce the same version hash as before. Previously when a change was deployed and then reverted, all web clients (even those that never saw the bad version) would have re-fetch modules because the version increased. Updated unit tests to account for the change in version. New default version of empty test modules is: "mvgTPvXh". For the record, this comes from the base64 encoding of the SHA1 digest of the JSON serialised form of the module content: > $str = '{"scripts":"","styles":{"css":[]},"messagesBlob":"{}"}'; > echo base64_encode(sha1($str, true)); > FEb3+VuiUm/fOMfod1bjw/te+AQ= Enabled content versioning for the data modules in MediaWiki core: * EditToolbarModule * JqueryMsgModule * LanguageDataModule * LanguageNamesModule * SpecialCharacterDataModule * UserCSSPrefsModule * UserDefaultsModule * UserOptionsModule The FileModule and base class explicitly disable it for now and keep their current behaviour of using the definition summary. We may remove it later, but that requires more performance testing first. Explicitly disable it in the WikiModule class to avoid breakage when the default changes. Ref T98087. Change-Id: I782df43c50dfcfb7d7592f744e13a3a0430b0dc6
2015-06-02 17:27:23 +00:00
public function enableModuleContentVersion() {
return true;
}
/**
* @param ResourceLoaderContext $context
* @return string
*/
public function getScript( ResourceLoaderContext $context ) {
return Xml::encodeJsCall( 'mw.user.options.set',
[ $context->getUserObj()->getOptions( User::GETOPTIONS_EXCLUDE_DEFAULTS ) ],
ResourceLoader::inDebugMode()
);
}
/**
* @return bool
*/
public function supportsURLLoading() {
return false;
}
resourceloader: Move queue formatting out of OutputPage HTML formatting of the queue was distributed over several OutputPage methods. Each method demanding a snippet of HTML by calling makeResourceLoaderLink() with a limited amount of information. As such, makeResourceLoaderLink() was unable to provide the client with the proper state information. Centralising it also allows it to better reduce duplication in HTML output and maintain a more accurate state. Problems fixed by centralising: 1. The 'user' module is special (due to per-user 'version' and 'user' params). It is manually requested via script-src. To avoid a separate (and wrong) request from something that requires it, we set state=loading directly. However, because the module is in the bottom, the old HTML formatter could only put state=loading in the bottom also. This sometimes caused a wrong request to be fired for modules=user if something in the top queue triggered a requirement for it. 2. Since a464d1d4 (T87871) we track states of page-style modules, with purpose of allowing dependencies on style modules without risking duplicate loading on pages where the styles are loaded already. This didn't work, because the state information about page-style modules is output near the stylesheet, which is after the script tag with mw.loader.load(). That runs first, and mw.loader would still make a duplicate request before it learns the state. Changes: * Document reasons for style/script tag order in getHeadHtml (per 09537e83). * Pass $type from getModuleStyles() to getAllowedModules(). This wasn't needed before since a duplicate check in makeResourceLoaderLink() verified the origin a second time. * Declare explicit position 'top' on 'user.options' and 'user.tokens' module. Previously, OutputPage hardcoded them in the top. The new formatter doesn't. * Remove getHeadScripts(). * Remove getInlineHeadScripts(). * Remove getExternalHeadScripts(). * Remove buildCssLinks(). * Remove getScriptsForBottomQueue(). * Change where Skin::setupSkinUserCss() is called. This methods lets the skin add modules to the queue. Previously it was called from buildCssLinks(), via headElement(), via prepareQuickTemplate(), via OutputPage::output(). It's now in OutputPage::output() directly (slightly earlier). This is needed because prepareQuickTemplate() calls bottomScripts() before headElement(). And bottomScript() would lazy-initialise the queue and lock it before setupSkinUserCss() is called from headElement(). This makes execution order more predictable instead of being dependent on the arbitrary order of data extraction in prepareQuickTemplate (which varies from one skin to another). * Compute isUserModulePreview() and isKnownEmpty() for the 'user' module early on so. This avoids wrongful loading and fixes problem 1. Effective changes in output: * mw.loader.state() is now before mw.loader.load(). This fixes problem 2. * mw.loader.state() now sets 'user.options' and 'user.tokens' to "loading". * mw.loader.state() now sets 'user' (as "loading" or "ready"). Fixes problem 1. * The <script async src> tag for 'startup' changed position (slightly). Previously it was after all inline scripts and stylesheets. It's still after all inline scripts and after most stylesheets, but before any user styles. Since the queue is now formatted outside OutputPage, it can't inject the meta-ResourceLoaderDynamicStyles tag and user-stylesheet hack in the middle of existing output. This shouldn't have any noticable impact. Bug: T87871 Change-Id: I605b8cd1e1fc009b4662a0edbc54d09dd65ee1df
2016-07-15 14:13:09 +00:00
/**
* @return string
*/
public function getPosition() {
return 'top';
}
/**
* @return string
*/
public function getGroup() {
return 'private';
}
}