Add a simple class to `libs/` for memoizing functions by caching return values
in APC. I decided not to make this an external library just yet because I see
this as potentially a part of a larger functional programming library.
Doesn't use APCBagOStuff for two reasons: (1) avoid dependency on MediaWiki
code; (2) ability to pass third &$success parameter to apc_store, to
distinguish between cache misses and cached false values.
Use this in ResourceLoaderFileModule to cache CSSMin::remap.
Change-Id: I00a47983a2583655d4631ecc9c6ba17597e36b5f
As Timo noted in a review of I1ff6115, using '+=' to combine file dependencies
is incorrect here. I fixed it in one place but not the other, causing the file
dependencies to vary based on whether a .lesscache file was used.
Change-Id: Ie3f48048febc32c5c2d45acd87e10f946f6dfc94
Re-use the md_skin database field for now as to not need a
schema change, beause this table is going away soon (T113916).
Bug: T113868
Change-Id: I7c7546ec58fd9be0447604989b908dd2084b0fe3
Make paths stored in the module_deps table relative to $IP. This ensures that when
the MediaWiki install path changes and/or if the location of the extension or skins
directory changes, that ResourceLoader's internal model is still accurate.
Previously when these paths change, ResourceLoader would exhibit various bugs.
1. Unable to detect changes in the module (if the directory no longer exists).
2. Point #1 is usually preceeded by one last cache invalidation as the content hash
of the file path changes (from a valid hash to an empty string).
3. Unnecessary cache invalidation (if both old and new directories exist). This
happens when a file is both an entry point (in the 'scripts' or 'styles' array)
and also a file dependency. At first they are de-duplicated by array_unique.
But after the disk path changes, the next check will result in the old path
being fetched from module_deps, and the new path from the live configuration.
This causes two changes that result in needless cache invalidation:
- The hash list contains one more item (T111481).
- The hash list contains both the old and new version of a file.
(or even alternate versions, e.g. when a change is backported to the old
wmf branch; it also affects wikis on the new branch due to the stale
file path still in the database).
It seems unusual to move a MediaWiki install, and usually we recommend third
parties to run update.php if site administrators do move their wiki. However
Wikimedia's deployment system implicitly moves the MediaWiki install continously
from e.g. "/srv/mediawiki/php-1.26wmf5" to "/srv/mediawiki/php-1.26wmf6".
This caused virtually all ResourceLoader caching layers to get invalidated every
week when another wmf-branch is deployed, thus breaking these file paths, which
changes the version hash, which then invalidates the cache.
Bug: T111481
Change-Id: I173a9820b3067c4a6598a4c8d77e239797d2659c
* Remove ResourceLoaderFileModule::getLessCompiler(). There is no reason for a
module to need to get a compiler in a different manner than
ResourceLoader::getLessCompiler().
* Add ResourceLoaderModule::getLessVars(). This method provides a means for
subclasses to easily inject custom LESS variables. The default implementation
simply returns an empty array.
* Make the $context parameter for ResourceLoaderFileModule::readStyleFiles()
non-optional (via graceful deprecation). The only callers I found were either
already calling it with a ResourceLoader context, or had a perfectly usable
ResourceLoaderContext in local scope.
* Make ResourceLoaderFileModule::{readStyleFile,getLessCompiler} require a
context. These methods are protected, so I didn't bother with a deprecation.
* Call ksort() on the LESS variables array in the only place it matters -- when
hashing its serialized representation to construct a cache lookup key. This
relieves getLessVars() subclasses from having to remember to re-sort the
variables array if they modify it.
* These changes make it possible to substantially simplify
ResourceLoaderEditToolbarModule, because the only thing it needs to do now is
implement its own getLessVars() method.
* This also allows it to be versioned like any other ResourceLoaderFileModule,
rather than having to use enableModuleContentVersion().
Change-Id: Ic3eab71691e502bfe19bdf4eb6f82cc679a7782f
Most of it was already there (SELECT in preloadInfo, and in-class holder via
setFileDependencies) but the logic to write to the database was within
the file module class.
Moving it the other way around may make more sense in the future, but for
the moment ResourceLoader.php makes assumptions about all modules being
able to store setFileDependencies as read from the database. Whether or not
a class currently implements a way to write to that table.
Change-Id: I06b5da4144798197478c66e8b9ccd4cc62cf6fb6
Caching the output of a LESS compiler is tricky, because a LESS file may
include additional LESS files via @imports, in which case the cache needs
to vary as the contents of those files vary (and not just the contents of
the primary LESS file).
To solve this, we first introduce a utility class, FileContentsHasher. This
class is essentially a smart version of md5_file() -- given one or more file
names, it computes a hash digest of their contents. It tries to avoid
re-reading files by caching the hash digest in APC and re-using it as long as
the files' mtimes have not changed. This is the same approach I used in
I5ceb8537c.
Next, we use this class in ResourceLoaderFileModule in the following way:
whenever we compile a LESS file, we cache the result as an associative array
with the following keys:
* `files` : the list of files whose contents influenced the compiled CSS.
* `hash` : a hash digest of the combined contents of those files.
* `css` : the CSS output of the compiler itself.
Before using a cached value, we verify that it is still current by asking
FileContentHasher for a hash of the combined contents of all referenced files,
and we compare that against the value of the `hash` key of the cached entry.
Bug: T112035
Change-Id: I1ff61153ddb95ed17e543bd4af7dd13fa3352861
The way this is implemented is really dirty... but it found us
a few pre-existing bugs already (T111518, T111519, T111771).
I think it might be worth it.
* CSSMin: Add new method getAllLocalFileReferences() which skips the
file_exists() check.
* ResourceLoaderModule: Make use of it to track missing files too.
* ResourcesTest: Verify that the missing files are missing.
Change-Id: I5a3cdeb7d53485f161ccf8133e76850cdf5b4579
These properties don't affect the module response. They are either
only consumed by OutputPage, or provided by the startup module
directly, which detects its own changes.
Changes to these properties should not invalidate module cache for
these properties.
Follows-up 2f30ff7a86 which added a hook to getDependencies()
but still included the raw 'dependencies' in the definition summary.
But as it turns out, dependencies don't need to be included.
Change-Id: I468e6a6edc352d845dc7a5d06b0ae2a6d809700b
In Wikimedia production this tends to contain the branch name,
which causes the version to change for no reason after a MediaWiki
deployment. For example:
["remoteBasePath"]=>
string(43) "https://test.wikipedia.org/static/1.26wmf19"
Bug: T102578
Change-Id: I50b8afd72183cae875d4aaa0aaf0da4e7d664284
Enabling the module content versionining is not feasible for FileModule as that
would involve Lessc and CSSJanus just to compute the version hash.
Instead, we can keep the existing logic that exists for the timestamp-based
versioning (which already has a comprehensive grip on tracking all involved
factors that cause a module to change) and convert it to use hashing instead.
This way the version hashes will be deterministic. Currently module versions
tend to be invalidated too often (and sometimes not often enough) due to Git and
other transport mechanisms not preserving file timestamps.
== Research ==
* <https://phabricator.wikimedia.org/T98087#1412712>
It'd take upto 10 seconds to run startup if FileModule enables build versioning.
* <https://phabricator.wikimedia.org/T104950#1433142>
Checking all files in resources/** took only ~30m longer in total with
sha1_file compared to filemtime.
Bug: T104950
Change-Id: I732fa4db32258c634e32b507952f76eac7fc9395
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
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
Currently all styles modules added to the page using
addModuleStyles are put into the head, regardless
of their "position" value.
Bug: T97420
Change-Id: Ie4287e17d6f298cc63f42f257b1f67ee36961b77
Modules now track their version via getVersionHash() instead of getModifiedTime().
== Background ==
While some resources have observeable timestamps (e.g. files stored on disk),
many other resources do not. E.g. config variables, and module definitions.
For static file modules, one can e.g. revert one of more files in a module to a
previous version and not affect the max timestamp.
Wiki modules include pages only if they exist. The user module supports common.js
and skin.js. By default neither exists. If a user has both, and then the
less-recently modified one is deleted, the max-timestamp remains unchanged.
For client-side caching, batch requests use "Math.max" on the relevant timestamps.
Again, if a module changes but another module is more recent (e.g. out-of-order
deployment, or out-of-order discovery), the change would not result in a cache miss.
More scenarios can be found in the associated Phabricator tasks.
== Version hash ==
Previously we virtually mapped these variables to a timestamp by storing the current
time alongside a hash of the value in ObjectCache. Considering the number of
possible request contexts (wikis * modules * users * skins * languages) this doesn't
work well. It results in needless cache invalidation when the first time observation
is purged due to LRU algorithms. It also has other minor bugs leading to fewer
cache hits.
All modules automatically get the benefits of version hashing with this change.
The old getDefinitionMtime() and getHashMtime() have been replaced with dummies
that return 1. These functions are often called from getModifiedTime() in subclasses.
For backward-compatibility, their respective values (definition summary and hash)
are now included in getVersionHash directly.
As examples, the following modules have been updated to use getVersionHash directly.
Other modules still work fine and can be updated later.
* ResourceLoaderFileModule
* ResourceLoaderEditToolbarModule
* ResourceLoaderStartUpModule
* ResourceLoaderWikiModule
The presence of hashes in place of timestamps increases the startup module size on
a default MediaWiki install from 4.4k to 5.8k (after gzip and minification).
== ETag ==
Since timestamps are no longer tracked, we need a different way to implement caching
for cache proxies (e.g. Varnish) and web browsers. Previously we used the
Last-Modified header (in combination with Cache-Control and Expires).
Instead of Last-Modified (and If-Modified-Since), we use ETag (and If-None-Match).
Entity tags (new in HTTP/1.1) are much stricter than Last-Modified by default.
They instruct browsers to allow usage of partial Range requests. Since our responses
are dynamically generated, we need to use the Weak version of ETag.
While this sounds bad, it's no different than Last-Modified. As reassured by
RFC 2616 <http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.3> the
specified behaviour behind Last-Modified follows the same "Weak" caching logic as
Entity tags. It's just that entity tags are capable of a stricter mode (whereas
Last-Modified is inherently weak).
== File cache ==
If $wgUseFileCache is enabled, ResourceLoader uses ResourceFileCache to cache
load.php responses. While the blind TTL handling (during the allowed expiry period)
is still maxage/timestamp based, tryRespondNotModified() now requires the caller to
know the expected ETag.
For this to work, the FileCache handling had to be moved from the top of
ResoureLoader::respond() to after the expected ETag is computed.
This also allows us to remove the duplicate tryRespondNotModified() handling since
that's is already handled by ResourceLoader::respond() meanwhile.
== Misc ==
* Remove redundant modifiedTime cache in ResourceLoaderFileModule.
* Change bugzilla references to Phabricator.
* Centralised inclusion of wgCacheEpoch using getDefinitionSummary. Previously this
logic was duplicated in each place the modified timestamp was used.
* It's easy to forget calling the parent class in getDefinitionSummary().
Previously this method only tracked 'class' by default. As such, various
extensions hardcoded that one value instead of calling the parent and extending
the array. To better prevent this in the future, getVersionHash() now asserts
that the '_cacheEpoch' property made it through.
* tests: Don't use getDefinitionSummary() as an API.
Fix ResourceLoaderWikiModuleTest to call getPages properly.
* In tests, the default timestamp used to be 1388534400000 (which is the unix time
of 20140101000000; the unit tests' CacheEpoch). The new version hash of these
modules is "XyCC+PSK", which is the base64 encoded prefix of the SHA1 digest of:
'{"_class":"ResourceLoaderTestModule","_cacheEpoch":"20140101000000"}'
* Add sha1.js library for client-side hash generation.
Compared various different implementations for code size (after minfication/gzip),
and speed (when used for short hexidecimal strings).
https://jsperf.com/sha1-implementations
- CryptoJS <https://code.google.com/p/crypto-js/#SHA-1> (min+gzip: 2.5k)
http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js
Chrome: 45k, Firefox: 89k, Safari: 92k
- jsSHA <https://github.com/Caligatio/jsSHA>
https://github.com/Caligatio/jsSHA/blob/3c1d4f2e/src/sha1.js (min+gzip: 1.8k)
Chrome: 65k, Firefox: 53k, Safari: 69k
- phpjs-sha1 <https://github.com/kvz/phpjs> (RL min+gzip: 0.8k)
https://github.com/kvz/phpjs/blob/1eaab15d/functions/strings/sha1.js
Chrome: 200k, Firefox: 280k, Safari: 78k
Modern browsers implement the HTML5 Crypto API. However, this API is asynchronous,
only enabled when on HTTPS in Chromium, and is quite low-level. It requires boilerplate
code to actually use with TextEncoder, ArrayBuffer and Uint32Array. Due this being
needed in the module loader, we'd have to load the fallback regardless. Considering
this is not used in a critical path for performance, it's not worth shipping two
implementations for this optimisation.
May also resolve:
* T44094
* T90411
* T94810
Bug: T94074
Change-Id: Ibb292d2416839327d1807a66c78fd96dac0637d0
lessc::allParsedFiles() always includes the main file we already
know about. As such needlessly causing it to be queried multiple
times.
Change-Id: Icd2c11d93d6491664fcf58a18bfe6e2932689774
Right now ResourceLoaderModule::getDefinitionSummary just returns an array
with the class name, but may be extended in the future. Either way, it shouldn't
be repeated in the subclass.
Change-Id: Ic1d58f8d330fb2176daffc7ad39bc0751c196181
Xhprof generates this data now. Custom profiling of various
sub-function units are kept.
Calls to profiler represented about 3% of page execution
time on Special:BlankPage (1.5% in/out); after this change
it's down to about 0.98% of page execution time.
Change-Id: Id9a1dc9d8f80bbd52e42226b724a1e1213d07af7
- Changed spaces to tabs for indentation
- space after 'function'/'if'
- Added/Removed space after parenthesis/brackets/end of line
- Removed space after cast
Change-Id: I0e8e6a19b84b5e1308b632a0266cb78f688494ee
A base ResourceLoaderModule::getTemplates() exists for subclasses
to override. An implementation is provided for ResourceLoaderFileModule.
For file modules, templates can be specified in the following manner:
'example' => array(
'templates' => array(
'bar' => 'templates/foo.html',
),
'scripts' => 'example.js',
),
The delivery system is template language agnostic, and currently
only supports "compiling" plain HTML templates.
This also adds template support to the following modules as a POC:
* mediawiki.feedback
* mediawiki.action.view.postEdit
* mediawiki.special.upload
Works with $wgResourceLoaderStorageEnabled
Change-Id: Ia0c5c8ec960aa6dff12c9626cee41ae9a3286b76
Not ready for merging, and Roan says that the +2 was
most likely accidental and meant to be a -1.
This reverts commit d146934f94.
Change-Id: I3926c9ae9e3c8026fceb3aeedd3b1f1d9b91667b
Preparation work for templating in core.
RL should allow us to ship HTML / template markup from server to client.
Use in Special:Upload and mediawiki.feedback as a proof of concept.
Separation of concerns etc...
See Also:
Ia63d6b6868f23a773e4a41daa0036d4bf2cd6724
Change-Id: I6ff38c12897e3164969a1090449e626001926c3b
No need to set a variable to value of itself. Also consistent
with the way $remoteBasePath is set, already.
Change-Id: I9b71322592a5ca2d85927fcf6732096f758847e9
This reverts most of commit 2d842f1425,
leaving only the test added in it, and reimplements the same
functionality better.
Instead of stripping /*@noflip*/ annotations in CSSJanus, which is
incompatible with other implementations that preserve it, extend
CSSMin to allow other CSS comments to be present before the
rule-global @embed annotation. (This required making the regex logic
in it even worse than it was, but it's actually slightly less terrible
than I expected it would be. Good thing we have tests!)
Bug: 69698
Change-Id: I58603ef64f7d7cdc6461b34721a4d6b15f15ad79
Bonus: actually make $wgResourceBasePath default to $wgScriptPath, rather than
special-casing it in ResourceLoaderFileModule.
Change-Id: I608435cef00d3e77a5bbdb0a0122d3e7e1a4eb78
Also, try out a way to have per-module LESS variables defined in PHP.
This might come in handy in the future… Maybe for skin theme support?
(I recommend reviewing the file changes in the order below. :D)
includes/resourceloader/ResourceLoaderFileModule.php
* Pass the context (ResourceLoaderContext) deeper down via
readStyleFiles() and readStyleFile(). We need it to compile the
.less files for the right language.
* Extract LESS compiler creation to getLessCompiler().
* Allow passing a LESS compiler instance to compileLessFile(), rather
than getting one after the method is called.
All of the changes are backwards-compatible.
includes/resourceloader/ResourceLoaderEditToolbarModule.php
* New module to support getting the language data and passing it to
LESS variables.
It might be a good idea to factor out a reusable class for a LESS
module with additional variables, but that would require more
attention to design than I gave it.
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/mediawiki.action.edit.toolbar.less
* Glue code to use the language data defined by the module above and
put it in final CSS.
includes/EditPage.php
* Do not hardcode image URLs in output HTML, as they are provided in
CSS now. This gets rid of some usage of globals.
In fact, we should be able to finally move the inline JavaScript
calls out of getEditToolbar(), but I'm already introducing too many
changes for one patch. That can be done later.
languages/Language.php
* Add getImageFiles() to complement existing getImageFile() method.
Misleadingly named, it returns paths for images for the toolbar
only (and no other ones at all).
skins/common/ → resources/src/mediawiki.action/mediawiki.action.edit.toolbar/
* Moved all of the button images to new location.
Also, boring cleanup that was harder before because we treated the
paths as public API:
* Placed default ones in en/ subdirectory.
* Renamed cyrl/ to ru/.
* Renamed ksh/button_S_italic.png → ksh/button_italic.png.
languages/messages/
* Adjusting paths and filenames for the changes above.
resources/src/mediawiki.action/mediawiki.action.edit.css
resources/src/mediawiki.action/mediawiki.action.edit.js
* Added styles and updated the script to make it possible to have
non-<img> elements as toolbar buttons.
* Consolidated styles that were already required, but defined
somewhere else:
* `cursor: pointer;` (from shared.css)
* `vertical-align: middle;` (from commonElements.css)
Bug: 69277
Change-Id: I39d8ed4258c7da0fe4fe4c665cdb26c86420769c
We used to have a second level of caching for them – when a module's
cache was invalidated, individual .less files that comprise it would
only be recompiled (with all their @imports) if their mktime changed
(or if $wgResourceLoaderLESSVars changed).
Given that practice has shown that RL modules including .less files
usually just include one file that @imports tons of stuff, and given
that RL already is very careful about invalidating caches, I think
this is unnecessary at best and harmful at worst.
The behavior proved problematic when I tried to implement support for
per-module LESS variables, values of which were language-dependent –
files would not be recompiled for different languages, and
getLessCacheKey() is called several levels deep in code that doesn't
have access to the context in which the module is being compiled.
Change-Id: I667f063507583e4cd3a669e32398d440f1431f7e
To do it, just remove /*@noflip*/ annotations in CSSJanus after
we're done processing. They are not needed anymore and some obscure
interactions with CSSMin logic for preserving comments caused
`/*@noflip*/ /*@embed*/ background-image: url(…)` not to work
correctly (it would not be embedded).
This also requires us to always do CSSJanus processing, even when we
don't need flipping, to consistently handle the annotations.
I'm not entirely sure if this is worth it, but I still greatly prefer
doing it to documenting this stupid limitation. :)
Bug: 69698
Change-Id: I311b12b08b2dff9d45efb584db08cf4a11318f59
Follows-up 75c08916b0. Looking at the call chain of
validateScriptFile() up to JSTokenzier, the first parameter is the file
name, otherwise "[inline]" is used; so that variable should be $localPath.
Bug: 69214
Change-Id: If7f36449cb352f50ba795a6d306e5d949a3dbd29
The newly introduced $wgResourceModuleSkinStyles global enables skins to
provide additional stylesheets to existing ResourceLoader module.
This both makes it easier (or at all possible) to override default
styles and lowers the style footprint by making it possible not to
load styles unused on most pages.
----
Example:
Use the file 'foo-styles.css' for the 'mediawiki.foo' module when using
the MySkin skin:
$wgResourceModuleSkinStyles['myskin'] = array(
'mediawiki.foo' => 'foo-styles.css',
'remoteSkinPath' => 'MySkin',
'localBasePath' => __DIR__,
);
For detailed documentation, see the doc comment in DefaultSettings.php.
For a practical usage example, see Vector.php.
----
Implementation notes:
* The values defined in $wgResourceModuleSkinStyles are embedded into
the modules as late as possible (in ResourceLoader::register()).
* Only plain file modules are supported, setting module skin styles
for other module types has no effect.
* ResourceLoader and ResourceLoaderFileModule now support loading
files from arbitrary paths to make this possible, defined using
ResourceLoaderFilePath objects.
* This required some adjustments in seemingly unrelated places for
code which didn't handle the paths fully correctly before.
* ResourceLoader and ResourceLoaderFileModule are now a bit more
tightly coupled than before :(
* Included a tiny example change for the Vector skin, a lot more of
similar cleanup is possible and planned for the future.
* Many of the non-essential mediawiki.* modules defined in
Resources.php should be using `'skinStyles' => array( 'default' => … )`
instead of `'styles' => …` to allow more customizations, this is
also planned for the future after auditing which ones would actually
benefit from this.
Change-Id: Ica4ff9696b490e35f60288d7ce1295766c427e87
- Swap "$variable type" to "type $variable"
- Added missing types
- Fixed spacing inside docs
- Makes beginning of @param/@return/@var/@throws in capital
- Changed some types to match the more common spelling
Change-Id: I8ebfbcea0e2ae2670553822acedde49c1aa7e98d
* Add the ResourceLoaderFileModule#getAllSkinStyleFiles method,
which returns all of the skinStyles files for a given module
* The LessFileCompilationTest and checkLess.php script, which use
the #getAllStyleFile method, now validate all LESS style files
Bug: 63343
Change-Id: Ib2eb5761919c648aea4ae58f8d0531799fe7982b
remoteSkinPath works the same as remoteExtPath but is relative to skins/ instead of extensions/
This will allow skins to register modules using:
$wgResourceModules['skin.myskin'] = array(
// ...
'localBasePath' => __DIR__,
'remoteSkinPath' => 'myskin',
);
Instead of using:
'remoteBasePath' => $GLOBALS['wgStylePath'] . '/myskin', // or
'remoteBasePath' => &$GLOBALS['wgStylePath'],
Change-Id: I0e8c4a37a224e9528c9c5aa5417f0f56dbb89b97
A module can be registered with a skip function. Such function,
if provided, will be invoked by the client when a module is
queued for loading. If the function returns true, the client will
bypass any further loading action and mark the module as 'ready'.
This can be used to implement a feature test for a module
providing a shim or polyfill.
* Change visibility of method ResourceLoader::filter to public.
So that it can be invoked by ResourceLoaderStartupModule.
* Add option to suppress the cache key report in ResourceLoader::filter.
We usually only call the minifier once on an entire request
reponse (because it's all concatenated javascript or embedded
javascript in various different closures, still valid as one
large script) and only add a little bottom line for the cache
key. When embedding the skip function we have to run the minifier
on them separately as they're output as strings (not actual
functions). These strings are typically quite small and blowing
up the response with loads of cache keys is not desirable in
production.
* Add method to clear the static cache of ResourceLoader::inDebugMode.
Global static state is evil but, as long as we have it, we at
least need to clear it after switching contexts in the test suite.
Also:
* Remove obsolete setting of 'debug=true' in the FauxRequest in
ResourceLoaderTestCase. It already sets global wgResourceLoaderDebug
in the setUp() method.
Bug: 66390
Change-Id: I87a0ea888d791ad39f114380c42e2daeca470961
Also:
* Fix incorrect documentation comment of ResourceLoaderModule::getStyles(),
it doesn't return a string, it never has.
* Remove spurious space in count() call.
* Fix spelling of in "proper".
Change-Id: I000393636f7b9015ad1bacfbb3eb8a6ad8695d72
Swapped some "$var type" to "type $var" or added missing types
before the $var. Changed some other types to match the more common
spelling. Makes beginning of some text in captial.
Change-Id: Ifbb1da2a6278b0bde2a6f6ce2e7bd383ee3fb28a