aboutsummaryrefslogtreecommitdiffstats
path: root/includes/resourceloader/ResourceLoaderUserDefaultsModule.php
Commit message (Collapse)AuthorAgeFilesLines
* resourceloader: Bundle `user.defaults` as part of `mediawiki.base`Timo Tijhof2021-11-181-52/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | == Background == The `user.options` module is private, and thus has to be embedded in the page HTML. This data is quite large. For example, on enwiki the finalized mw.user.options object is about 3KB serialized/compressed (7KB uncompressed). The `user.defaults` module is an implementation detail of `user.options`, and was created to accomplish mainly two things: * Save significant data transfers by allowing it to be cached client-side without being part of the article. * Ensure consistency between articles and allow faster deployment of changes, by not being part of the cacheable article HTML. All our pageviews already load `user.defaults`, as a dependency of the popular `mediawiki.api` and `mediawiki.user` modules. These are used by `mediawiki.page.ready` (queued on all pages), and on Wikipedia these are also loaded on all pages by ULS, VisualEditor, EventLogging, and more. As such, in practice, bundling "user.defaults" with "mediawiki.base" will not cause the data to be loaded more often than before. == What == * Add virtual "user.json" package file with the same data that was previously exported by ResourceLoaderUserDefaultsModule, and pass it to mw.user.options.set() from base module's entry point. An alternative way would be to use a "user.js" file, which would return a generated "mw.user.options.set()" expression. I went for exporting it as JSON for improved maintainability (reducing the amount of JS code written in PHP), and because it performs slightly better. The JS file would implicitly come with a file closure (tiny bit more bytes), and would then be lazy executed (tiny bit more time). The chosen approach allows the browser to compile the JSON off-the-main-thread ahead of time while the module response downloads. Then when the module executes, we can reference the JSON object and use it directly. * Update internal dependency from `user.options`. * Remove `user.defaults` module without deprecation. It is an internal module with no direct use anywhere in Git (Codeseach), and no use anywhere on-wiki (Global Search). Change-Id: Id3916f94f75078808951863dea2b3a9c71b0e30c
* resourceloader: Avoid User::getDefaultOptions in UserDefaultsModuleDannyS7122021-01-301-1/+6
| | | | | | Method is deprecated. Change-Id: I26f938939d5f374a6d0c6777d6faf6b3cb3dcfee
* resourceloader: Add some typehints and misc clean upTimo Tijhof2020-07-021-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Add a void return hint to methods that are not meant to return anything. This helps catch accidental return statements in the future, lets Phan better understand how methods are meant to be used, and might also allow PHP to better optimise the compiled code form (speculation). I did not, however, add it to publicly extended methods as that might mess with strict mode. * Remove the internal getResourceLoader() method from MessageBlobStore. This has been redundant since 3edaa0b37c1e2684. The method was protected, and not considered stable to subclass for extensions. Hence not a breaking change. * Add Throwable typehint to formatException() and friends. This is the narrowest one I could add given that the methods called from here already enforce the same typehint. Update the doc to match for now. There isn't a reason right now to limit this only to Exception, and given this is the method and not the catch statement itself, does not change behaviour. * Remove unused ResourceLoader->getHookContainer(). Added within 1.35 cycle, safe to remove. * Remove unexpected `@since` for `@internal` getHookRunner(). * Remove redundant `@internal` from ResourceLoaderMwUrlModule methods, which itself is already `@internal`. Change-Id: I68d33ff6feca7ef95282a7ff03eb9332adfde31c
* Merge "resourceloader: Add $context to static functions in ResourceLoader"jenkins-bot2019-09-271-1/+1
|\
| * resourceloader: Add $context to static functions in ResourceLoaderFomafix2019-09-271-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This change allows to use the context in the functions. The following internal static functions from ResourceLoader get now a reference to the ResourceLoaderContext object: * makeLoaderImplementScript * makeLoaderStateScript * makeLoaderRegisterScript * makeLoaderSourcesScript ResouceLoader::encodeJsonForScript is duplicated to ResourceLoaderContext::encodeJson loading the debug mode from context. ResourceLoader::encodeJsonForScript is kept for other usages without context. The debug mode is loaded from $context->getDebug() instead of from ResourceLoader::inDebugMode(). This does not support to enable the debug mode by setting the cookie 'resourceLoaderDebug' or the configuration variable wgResourceLoaderDebug. Only the URL parameter debug=true enables the debug mode. This should be sufficient for the subsequent ResourceLoader requests. The tests don't need the global variable wgResourceLoaderDebug anymore. The initial ResourceLoader context in OutputPage still uses ResourceLoader::inDebugMode() with cookie and global configuration variable. This change adds the parameter $context with a ResourceLoaderContext object to ResourceLoaderModule::getDeprecationInformation and deprecates omitting the parameter. Ifa1a3bb56b731b83864022a358916c6aca5d7c10 updates this in extension ExtJSBase. Bug: T229311 Change-Id: I5341f18625209446a6d006f60244990f65530319
* | resourceloader: Add Doxygen group and improve overall docsTimo Tijhof2019-09-141-2/+3
|/ | | | | | | | | | | | | | | | | | | * Add license header where missing. * Add missing `@since` (1.17 for most classes), except ResourceLoaderLessVarFileModule since 1.32 (1bc62c548c). * Remove duplicate file-level description for class-only files, merge with the class description instead. * Remove my own `@author` annotation from one file. * Mark core's own FileModule subclasses as `@internal`, except for the following which we support use of in extensions: ResourceLoaderLessVarFileModule, ResourceLoaderOOUIIconPackModule, and ResourceLoaderWikiModule. Change-Id: I336af2e4ccdbe2512594e8861b72628d24194e41
* resourceloader: Replace Xml::encodeJsCall by encodeJsonForScriptFomafix2019-09-101-5/+3
| | | | | | | | Also document that encodeJsonForScript can return false on invalid UTF-8 characters. Bug: T32956 Change-Id: I9c2fd33fb2130ada67fa70ff176e5488f1a014bf
* Document return string as JavaScript code for getScriptFomafix2017-04-031-1/+1
| | | | Change-Id: I01055c2b6a11dbe6284d1aff2352ba428ed9bee2
* Convert all array() syntax to []Kunal Mehta2016-02-171-2/+2
| | | | | | | | | | Per wikitech-l consensus: https://lists.wikimedia.org/pipermail/wikitech-l/2016-February/084821.html Notes: * Disabled CallTimePassByReference due to false positives (T127163) Change-Id: I2c8ce713ce6600a0bb7bf67537c87044c7a45c4b
* resourceloader: Consistently refer to the framework as ResourceLoaderTimo Tijhof2015-10-281-1/+1
| | | | Change-Id: Ia59e4eac9662723e80d62f7cfcb9e4292e3ee4de
* resourceloader: Enable module content version for data modulesTimo Tijhof2015-06-181-8/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* resourceloader: Remove redundant getModifiedTime implementationsTimo Tijhof2015-06-031-8/+0
| | | | | | | | | | | | | | | | | | | Follows-up f37cee996e which replaced the getHashMtime() and getDefinitionMtime() methods with dummies that always return 1. These getModifiedTime() implementations were only tracking the definition summary or custom hash, which is already tracked by getVersionHash(). Notes: * SpecialCharacterDataModule: This one was odd as it was tracking both the mtime *and* the file contents. * UserCSSPrefsModule/UserOptionsModule: Remove redundant caching. Already taken care of by getVersionHash() as of f37cee996e. Bug: T94074 Change-Id: I6e37c3c2f85ef4599a8643b0efabc18de2f51ec4
* Use more pretty output in ResourceLoader debug mode for arraysumherirrender2014-12-191-1/+5
| | | | | | | | | | | Effected: - mw.language.data - mw.language.names - mw.config.set - mw.user.options.set for defaults - mw.toolbar Change-Id: I8a9e718ab15f0b3f80e12b817295c6843a570d46
* resourceloader: Make timestamp handling more consistentTimo Tijhof2014-12-051-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Use time() instead of: - wfTimestamp() - wfTimestamp( TS_UNIX ) - wfTimestamp( TS_UNIX, 0 ) - wfTimestamp( TS_UNIX, time() ) - intval( wfTimestamp( TS_UNIX, time() ) ) * Consistently use 1 as default instead of 0. Previously the unwritten convention was that anything "final" max()'ed with 1, and any internal method would use 0, but this wasn't applied consistently made it fragile. There doesn't seem to be any value in returning 0 only to have it maxed up to 1 (because if the 0 would ever make it out alive, we'd be in trouble). * wfTimestamp returns a string for TS_UNIX. In PHP this doesn't matter much. In fact, max() takes number-like integers so transparently, it even preserves it: > max( 1, 3, '2' ); < 3 > max( 1, '3', 2 ); < "3" Just cast it in one place at the very end (StartupModule) instead of doing intval( wfTimestamp() ). * Fix weird documentation claiming getModifiedTime can return an array, or mixed. * Remove 'version > 1 ? version : 1' logic in ResourceLoader::makeLoaderRegisterScript. The client doesn't have "0 means now" behaviour so this isn't needed. And the method was only doing it for variadic argument calls. Removal of quotes around timestamps reduced the size of the startup module from 26.8KB to 25.9KB before gzip. After gzip the size was and still is 5.7KB, though. (From 5456 bytes to 5415 bytes.) Change-Id: If92ca3e7511e78fa779f2f2701e2ab24db78c8a8
* Optimize how user options are delivered to the clientOri Livneh2014-12-051-0/+58
We currently embed the full set of user options in a <script> tag in the HTML output of every page. This is grossly inefficient, because the full set of options is usually largely made up of site defaults which the user hasn't customized. So instead of doing that, let's emit the default options using one ResourceLoader module and then apply the user's customizations on top. This has the effect of slightly increasing the total bytes of JavaScript code (because options that the user has customized will be emitted twice: once with their default value in the user.defaults module, and then again with the customized value in user.options). But this is more than offset by the fact that the bulk of user options code (~4 kB uncompressed on enwiki) becomes cacheable across requests. Bonus round: * Varnish gets to cache 4 kB fewer per page. * Changes to the default options don't take 30 days to propagate. Change-Id: I5a7e258d2d69159381bf5cc363227088b8fd6019