Commit graph

165 commits

Author SHA1 Message Date
Kunal Mehta
61adc1e146 Use namespaced ScopedCallback
The un-namespaced \ScopedCallback is deprecated.

Change-Id: Ie014d5a775ead66335a24acac9d339915884d1a4
2016-10-17 15:46:05 -07:00
Aaron Schulz
a2790b1b80 Remove wfGetCaller() dependency from DatabaseBase
Change-Id: I3e240b2eb5c1f6a21f1bc974c3d28f5755c7451a
2016-09-15 14:40:00 -07:00
Amir Sarabadani
d56829dca8 Clean up array() syntax from docs, part VI
Change-Id: Ib0eea494e2065c7ab356dc45fd174544a9c1c942
2016-09-12 14:36:37 +04:30
Aaron Schulz
fdd40afc42 Avoid "No transaction is active" saveFileDependencies() tests errors
Unit tests run in CLI mode without DBO_TRX

Change-Id: Icee9cf84cb9e057b329dd3960fcc9b238af478a3
2016-09-11 20:46:43 -07:00
Aaron Schulz
950cf6016c Rename DB_SLAVE constant to DB_REPLICA
This is more consistent with LoadBalancer, modern, and inclusive
of master/master mysql, NDB cluster, and MariaDB galera cluster.

The old constant is an alias now.

Change-Id: I0b37299ecb439cc446ffbe8c341365d1eef45849
2016-09-05 22:55:53 -07:00
Amir Sarabadani
6b221fa96a Clean up array() syntax in docs, part IV
Change-Id: If626409a93d31bf90c054c9bf7ba44a78ea9a621
2016-08-26 16:06:58 +04:30
jdlrobson
8af960e484 resourceloader: Implement 'deprecated' option for FileModule
ResourceLoader modules can now carry a 'deprecated' option which can
be a boolean or an object with message key. This message or a default
deprecation message will be show whenever that module is used in production.

Note: This will not work in debug mode for ResourceLoaderFile modules
and this is deemed acceptable for the time being. We can revisit later.

Bug: T137772
Change-Id: Ib9ebd2d39a59fd41d8537e06884699f77b03580c
2016-08-04 18:01:53 +00:00
Aaron Schulz
97da254d9c resourceloader: Release saveFileDependencies() lock on rollback
Change-Id: Iffa42c8214af4e17285c411795b46d1fe2708285
2016-07-19 19:35:03 +00:00
Timo Tijhof
a464d1d41d resourceloader: Track state of page-style modules
This allows dynamically loaded modules to depend on page-style modules
without it causing the page-style module to be loaded a second time.

* New method Module::getType() indicates whether a module is
  a page-style module or supposed to be dynamically loaded.

* Emit warning from addModuleStyles() when given a module that is
  not a page-style module (to be enforced later)

Bug: T92459
Bug: T87871
Change-Id: I8b6c6a10d965e73965f877c42e995d04202524f3
2016-07-14 20:28:40 +01:00
Timo Tijhof
2cda917e3f resourceloader: Remove unused Module::setOrigin() method
Follows-up da36f65433 which added this method with intent to use in
ResourceLoader::register(). However, the feature was redesigned to
not need this and the method was left behind.

Change-Id: I5ebc93805d0df6605bec94094bcd4eb2b70ff18d
2016-05-10 19:13:33 +01:00
Kunal Mehta
b9668d6d80 build: Update mediawiki-codesniffer to 0.6.0, add "composer fix"
* Fix errors spotted by new release
* Introduce "composer fix", which uses phpcbf to automatically fix some
errors spotted by phpcs.
* Drop $PHPCS_ARGS variable that didn't work on Windows, and add -s flag
* Remove rules from phpcs.xml that are now in MW-CS ruleset.

Change-Id: I13e2155695918c918b67497ac65b85a03897095e
2016-02-17 02:54:42 -08:00
Kunal Mehta
6e9b4f0e9c Convert all array() syntax to []
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
2016-02-17 01:33:00 -08:00
jenkins-bot
480ab87dbc Merge "resourceloader: Reduce module_deps write slams after deployments" 2016-02-09 22:50:26 +00:00
Aaron Schulz
1d15085bb3 resourceloader: Reduce module_deps write slams after deployments
Bug: T124649
Change-Id: I8d45e538f7d3d098a89950e5777e0984c90d7e51
2016-02-02 11:37:37 -08:00
Aaron Schulz
1a27995553 Cleanup setFileDependencies() docs
Change-Id: If7973bbfd2aaede1b2f5cc0df3f416bc9b8c77c6
2016-01-27 12:37:44 -08:00
Timo Tijhof
5d5b269e0e resourceloader: Migrate from msg_resource table to object cache
MessageBlobStore class:
* Make logger aware.
* Log an error if json encoding fails.
* Stop using the DB table. WANObjectCache supports everything we need:
  - Batch retrieval.
  - Invalidate keys with wildcard selects or cascading check keys.
* Update tests slightly since the actual update now happens on-demand as
  part of get() instead of within updateMessage().

ResourceLoader class:
* Remove all interaction with the msg_resource table. Remove db table later.
* Refactor code to use a hash of the blob instead of a timestamp.
  Timestamps are unreliable and roll over too frequently for message blob store
  because there is no authoritative source. The timestamps were inferred based on
  when a change is observed. Message overrides from the local wiki have an
  explicit update event when the page is edited. All other messages, such as
  from MediaWiki core and extensions using LocalisationCache, have a single
  timestamp for all messages which rolls over every time the cache is rebuilt.
  A hash is deterministic, and won't cause needless invalidation (T102578).
* Remove redundant pre-fetching in makeModuleResponse().
  This is already done by preloadModuleInfo() in respond().
* Don't bother storing and retreiving empty "{}" objects.
  Instead, detect whether a module's message list is empty at runtime.

ResourceLoaderModule class:
* Make logger aware.
* Log if a module's message blob was not preloaded.

cleanupRemovedModules:
* Now that blobs have a TTL, there's no need to prune old entries.

Bug: T113092
Bug: T92357
Change-Id: Id8c26f41a82597e34013f95294cdc3971a4f52ae
2015-12-08 14:02:38 +00:00
Aaron Schulz
4b6304e5c3 resourceloader: Use WAN cache for validateScriptFile cache
This keeps core callers more consistent.

Change-Id: I5e06a963a5e10204445a01c00109b46a6971bcfe
2015-11-04 01:09:11 +00:00
Timo Tijhof
afcfc3290c resourceloader: Consistently refer to the framework as ResourceLoader
Change-Id: Ia59e4eac9662723e80d62f7cfcb9e4292e3ee4de
2015-10-28 03:24:40 +00:00
Timo Tijhof
a0809dfa5a resourceloader: Remove 'loaderScripts' option from FileModule
Not used in any of our public repositories.

Bug: T65240
Change-Id: I1e9f741c3ef0f922129ecd10039228b58565bf62
2015-10-28 02:53:16 +00:00
Timo Tijhof
9435cd81b0 resoureloader: Consolidate styles-only queue at the top
This effectively reverts d6b4d3c537 and declines T97420.
This was previously attempted in b7c0e537eb.

Drop support for position "bottom" for addModuleStyles().
This feature was only recently introduced with the intent
to optimise page load performance, but had an adverse effect.

It increases chances of FOUC due to late discovery of these styles.
It also caused minor problems for some gadgets and extensions
that did not or were unable to set these flags. Some mobile
code was introduced around the same time as this feature and
was never given position=top.

Stylesheets that don't affect initial render or are only needed
on interaction should be loaded via addModules() instead; which
is handled by the asynchronous loader in JavaScript.

Change-Id: Ib9821b7b87cfc8a59062bb6ca358974fdb01ced1
2015-10-27 03:39:34 +00:00
Ori Livneh
e2547a73c9 Update ResourceLoader for Ib7fc2f939b
Use BagOStuff::makeKey() and BagOStuff::makeGlobalKey() instead of
wfMemcKey() and wfGlobalCacheKey().

Change-Id: Id4e58c0e616b74de220faf13ba7c9ea606fef8c1
2015-10-19 17:28:09 -07:00
Kevin Israel
b52502eec5 Change 1.26 to 1.27, mostly in doc comments
Using the following command line, I have found doc comments (and
a wfDeprecated() call) mentioning "1.26" when they should mention
"1.27" instead, which I have fixed manually:

git diff -M REL1_26 | grep --color=always -C 10 -iP \
'^\+.*\D1\.26(\D|$)' | aha > oldver.html

Follows-up these commits:
* 047b60b96d
* 169b7b98b5
* 25a44aa3e4
* 2fb2a3f14b
* 3f1e9fa268 [1]
* 8c84af70b6
* c0cb80beac
* d04a92a551
* d3b85592ea

[1] Release notes moved in I195dd1cf.

Because a release note stating that the UserRights hook is deprecated
was added in 37062a0c0d (before the branch cut), this commit does not
change the Hooks::run call that had been changed in 21206c8fbe.

Change-Id: I5a427f003e7e3b4559fe377bcdfdca466a570708
2015-10-07 01:41:41 -04:00
Ori Livneh
ca30efa30a resourceloader: cache minified user and site modules
* Add support for a '/* @nomin */' annotation in ResourceLoader. If present in
  JavaScript or CSS, the code will not be minified or cached. This allows
  modules like the ResourceLoaderUserTokensModule to declare themselves unfit
  for minification / caching without requiring a complicated refactor.
* Make ResourceLoader::filter() static, at the cost of not having minifier
  errors in the ResourceLoader log bucket. (They will continue to be logged as
  exceptions, however).

Change-Id: Ic1d802ee20565e61046bfbd8fd209bc56a4cbd6c
2015-10-03 20:29:48 +00:00
Ori Livneh
3c1e0ac9f0 Fix-up for I21bb3f08e7f: make ResourceLoaderModule::expandRelativePaths public
Change-Id: Iba76d7e788c3ca5457fe462b7fd9ecfaedba50f8
2015-10-01 18:05:53 -07:00
Timo Tijhof
280d29215a resourceloader: Vary module_deps on language (in addition to skin)
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
2015-09-30 00:40:56 +00:00
Timo Tijhof
047b60b96d resourceloader: Store relative instead of absolute paths in module_deps
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
2015-09-30 00:25:27 +00:00
Ori Livneh
3f1e9fa268 resourceloader: Tidy up RL to simplify ResourceLoaderEditToolbarModule
* 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
2015-09-28 12:18:12 -07:00
Timo Tijhof
d04a92a551 resourceloader: Keep module_deps handling inside module base class
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
2015-09-24 07:43:51 +00:00
Ori Livneh
2cbd25e9e4 resourceloader: Use FileContentsHasher in safeFileHash()
Replace the one-off code for APC-assisted file content hashing from I5ceb8537c
with a call to the FileContentsHasher class introduced in I1ff61153.

Change-Id: I8e4c3d5a5e7cdf6455a43769261d742b0255622c
2015-09-24 00:49:59 +00:00
Ori Livneh
7934bd9d72 ResourceLoaderModule: cache file content hash
Cache the content hash of module files in APC, if available. Include the
modification time in the cached value, so that touching the file invalidates
the cache.

Does this take us back to a world in which updates to a file's mtime cause a
module's version to change? No. The content hash cache will be invalidated,
and the content hash will be computed, but the actual value should remain
the same.

Change-Id: I5ceb8537c3cdb120beae19740635f085ee128272
2015-09-18 22:27:34 +00:00
Ori Livneh
935e24f9cd resourceloader: Use MD4 to compute file hash rather than SHA1
The hash value generated by ResourceLoaderModule::safeFileHash() is used for
versioning and cache invalidation, so a cryptographic hash function is not
necessary. We can get better performance by using MD4.

Wikimedia on-CPU time over 24 hours of safeFileHash() in load.php:
* 6.68% with safeFileHash using SHA1 (day 1)
* 7.07% with safeFileHash using SHA1 (day 2)
* 2.84% with safeFileHash using MD4 (day 3)

Change-Id: I6ff728f1240268517c0f03e0823129316bc901cb
2015-09-18 22:26:55 +00:00
Aaron Schulz
4f0b16b914 Fixed BufferingStatsdDataFactory::timing() callers to use ms
* The interface actually demands this

Change-Id: I1e334c2696a8a8eca73a6ae7f71428190cad3107
2015-08-19 01:01:49 +00:00
Timo Tijhof
e68ce73a89 resourceloader: Fix undefined $filename in safeFileHash()
Follows-up 28f6d7fbde.

This was causing versions to stay stuck at their current version.
It worked fine for the initial deployment since the rest of the
definition summary is still fine, but subsequent deploys that changed
only the file were ineffective due to these silently becoming
empty strings.

Thanks to suppressWarnings() we never saw these anywhere in the
tests or in production.

Change-Id: Ib4371255fe970442bcc0041219bce633a7f6f6dd
2015-08-05 22:51:06 -07:00
Timo Tijhof
28f6d7fbde resourceloader: Convert FileModule to use version hashing
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
2015-08-05 19:30:33 +00:00
Timo Tijhof
c318e3a265 Hygiene: Use strtr() instead of str_replace() for character swapping
strtr() is marginally faster as it runs through the string only
once. A better fit for one-for-one character translation.

The strtr() function also supports an associative array as second
parameter for entire string replacements. This, too, has the same
performance and predictable behaviour (starts with the longest key).
Whereas str_replace is for more aggressive needs where you want
multiple passes until there are no further matches.

The associative array form is arguably also easier to understand
and harder to mess up since the needle/replacement pairs are
explicitly connected instead of two separate arrays.

Also:
* Use getFormattedNsText instead of strtr( getNsText, .. ) which
  reduces duplication of this fact through a more semantic intent.

Change-Id: Ie23e4210a5b6908dd79eebc8a2b931d12fe31af6
2015-07-06 20:25:19 +00:00
Timo Tijhof
b88e88b67d resourceloader: Add timing metrics for key operations
* Minification of css and js.

* Total generation of module content.
  Includes:
  - Fetching/generating of content (files, wikipage, dynamic).
  - Pre/post processing (concat, less>css, cssjanus, ..)

Change-Id: Id60e665dfb6280aa254116f0867b909afc6f878a
2015-06-29 20:21:58 +00:00
Aaron Schulz
03c1d480a7 resourceloader: Small code cleanups to ResourceLoaderModule
* Changed Exception => LogicException
* Broke some 100 char+ lines

Change-Id: I37bc72065cb567fdd9596f707facc27c6841c434
2015-06-20 04:01:42 +01:00
Timo Tijhof
2581453fac 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-18 20:39:38 +00:00
Timo Tijhof
aac831f9fa resourceloader: Use content-neutral context when computing module versions
The startup module produces a manifest with versions representing the
entire module.

Typically, the request for the startup module itself has only=scripts.
However, that "only" must only apply to what resources of the startup module are
output in the request.

The context passed to getModifiedTime() and getVersionHash() must not suggest
any restriction of measuring only the scripts, or otherwise ignoring some
aspects of the module (such as stylesheets, or messages).

Most existing getModifiedTime() implementations compute timestamps of all
files, regardless of the context. So this bug didn't surface before.
However that will change for modules that compute the version hash based on
getModuleContent(), which does honour the getOnly() and shouldIncludeScripts()
methods of the request context.

Change-Id: Ib8f09c39d10724d146b53b6d53d82da18944a12b
2015-06-18 21:10:41 +01:00
umherirrender
d8821f2b0b Fixed spacing
- Removed space after casts
- Removed spaces in array index
- Added spaces around string concat
- Added space after words: switch, foreach
- else if -> elseif
- Removed parentheses around require_once, because it is not a function
- Added newline at end of file
- Removed double spaces
- Added spaces around operations
- Removed repeated newlines

Bug: T102609
Change-Id: Ib860222b24f8ad8e9062cd4dc42ec88dc63fb49e
2015-06-17 20:22:32 +00:00
Kunal Mehta
f6e5079a69 Use mediawiki/at-ease library for suppressing warnings
wfSuppressWarnings() and wfRestoreWarnings() were split out into a
separate library. All usages in core were replaced with the new
functions, and the wf* global functions are marked as deprecated.

Additionally, some uses of @ were replaced due to composer's autoloader
being loaded even earlier.

Ie1234f8c12693408de9b94bf6f84480a90bd4f8e adds the library to
mediawiki/vendor.

Bug: T100923
Change-Id: I5c35079a0a656180852be0ae6b1262d40f6534c4
2015-06-11 18:49:29 +00:00
jenkins-bot
f74244cd13 Merge "resourceloader: Move packaging to a new getModuleContent() method" 2015-06-09 09:13:49 +00:00
Andrew Green
7e0d3369c2 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-06-09 03:10:20 +01:00
Timo Tijhof
5ddd7f91c7 resourceloader: Move packaging to a new getModuleContent() method
Centralise the building of module packages into this method so
that it can be easily re-used.

This is in preparation for providing the option for modules to use
content-based hashing (instead of based on meta-data) in the version
string of modules. Having a getModuleContent method allows that to
be implemented in a way that is well-cached (as we'll be calling it
from multiple multiple code paths) and without duplicating this logic.

Bug: T98087
Change-Id: I376233caaabe44b6101565b70a50904abdf8ab4f
2015-06-09 02:04:58 +01:00
Timo Tijhof
cd0dff5c00 resourceloader: Use mw.log instead of 'throw' for scripts with syntax errors
For scripts loaded from load.php using mw.loader.implement(), an
exception is handled fine and results in the module state progressing
from 'loading' to 'errror'.

However, for wikis modules loaded with only=scripts from the HTML directly,
there is no wrapper. As such, the state() call appended to the script is
never reached and the module indefinitely stays "loading".

VisualEditor (and others) already explicitly ignore the error state
of the wiki modules (with inline mw.loader.using and casting the Promise to resolved).
However in this case the Promise never completed to neither success nor failure.

As such, this was causing users with syntax errors in their user script to
encounter a stuck VisualEditor loading bar that never goes beyond 70%.

Change-Id: I091a020bdd3392b965e0e25d03b216037fadc48f
2015-06-02 22:43:46 +00:00
Gilles Dubuc
d6b4d3c537 Add ability to load plain CSS files at the bottom
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
2015-05-25 21:10:14 +00:00
Timo Tijhof
f37cee996e resourceloader: Replace timestamp system with version hashing
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
2015-05-19 22:28:17 +00:00
Timo Tijhof
9b6ee1da59 resourceloader: Remove only=messages
This isn't needed.

* Deprecate 'modulemessages' API, return empty result and warning.
* Remove half-implemented only=templates.

Change-Id: Ia6c87d687c6670b3ebf24251572191732651e8f5
2015-05-13 20:17:35 +01:00
Timo Tijhof
f2fee57949 resourceloader: Add logging for T94810
Bug: T94810
Change-Id: Ibedc31659ed91262bca115101136fe60df6c5134
2015-04-24 20:02:46 +00:00
Timo Tijhof
885a1e0703 resourceloader: Simplify getHashMtime() to merely a timestamp
Similar to what getDefinitionMtime() does already. No need to
repeat the hash. No need for an array that needs serialising and
unserialising internally.

Change the hash key to avoid using old cache values.

Also moved the comment about hashes being included in the key to
this method. getDefinitionMtime() is a later method that performs
the same logic but doesn't need the entire story again.

Follows-up 044713c4, d3bdda32.

Change-Id: Idd83de5ac27138a2dbf2ec49d81ea9188bd6ad57
2015-03-31 20:57:07 +00:00
Aaron Schulz
3897868db1 resourceloader: Cut down on file stat time in safeFilemtime()
* If stat cache is not enabled, this used to do two queries.

Change-Id: Icfed675b27f952ec13b9d0af3e345b1486ea7c8f
2015-03-31 17:10:57 +00:00
Timo Tijhof
3e94967191 resourceloader: Simplify log message for getDefinitionMtime() cache miss
* Add quotes around context (which has pipe characters in it).
* Remove hash (not useful).

Change-Id: Iff80c914add0c5a2fe27fff6398bb3384102e3d2
2015-02-20 06:47:06 +00:00
Chad Horohoe
aa21e125a3 Remove obvious function-level profiling
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
2015-01-07 11:14:24 -08:00
Timo Tijhof
6a1ec17e79 resourceloader: Make timestamp handling more consistent
* 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
2014-12-05 21:29:57 +00:00
jdlrobson
ebeb297236 resourceloader: Add support for delivering templates
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
2014-10-29 19:31:16 +00:00
Legoktm
de24e3099e Revert "Add RL template module with HTML markup language"
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
2014-10-17 23:19:21 +00:00
jdlrobson
d146934f94 Add RL template module with HTML markup language
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
2014-10-17 09:23:04 -07:00
umherirrender
c2de24efcd Add missing @param to function docs
Change-Id: Ib7ac94d05a04490f25dfd40b46b27973cbab582c
2014-08-14 19:38:57 +00:00
Kunal Mehta
4b1a87c96e includes/resourceloader/: Use Config instead of globals
Change-Id: Iaa1f4ae9c397575c9bb86dacbc342456e6f5f532
2014-08-07 18:47:34 +01:00
umherirrender
dd8921c9d9 Cleanup some docs (includes/[m-r])
- 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
2014-07-24 19:43:25 +02:00
Kunal Mehta
126fb8d157 OutputPage: Support foreign module sources in makeResourceLoaderLink
To do so, created ResourceLoader::createLoaderURL(), which takes a
ResourceLoaderContext object. ResourceLoader::makeLoaderURL() was
deprecated.

While reviewing usage of the old function, many of the callers only
differed by one or two parameters from their respective
ResourceLoaderContext object. To simplify that use case, I created
DerivativeResourceLoaderContext, based of off DerivativeContext for
IContextSource.

Change-Id: I961c641ab953153057be3e3b8cf6c07435e9a0b0
2014-07-19 23:44:00 +00:00
Timo Tijhof
75c08916b0 resourceloader: Implement "skip function" feature
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
2014-06-12 03:48:26 +02:00
Siebrand Mazeland
0b2fcf3785 Pass phpcs-strict on includes/resourceloader/
Change-Id: I5c63e0612c2aae240abcdbf21da9cdadd80dee31
2014-05-10 10:39:37 +02:00
Bartosz Dziewoński
62e7156f76 ResourceLoaderModule: Add @since annotations to new methods
Change-Id: I91434fcdc87efdf6d49ec94348f26d20c840abad
2014-05-08 22:26:42 +02:00
umherirrender
dcf6955e5c Fixed some @params documentation (includes/*)
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
2014-04-20 23:33:05 +02:00
Timo Tijhof
044713c4dc resourceloader: Make sure hashmtime cache key is different by language
We were continuously invalidating the cache for the
ResourceLoaderLanguageDataModule every time a request for a langauge
other than the previous request came in as they all resulted in
the same cache key.

This could be resolved by adding $context->getLang() to the key
(which would be enough for langdata module, but not enough for
other uses of hashmtime), or by adding $context->getHash() (which
will fragment it for all possible context factor combinations,
slightly overkill for most cases, but would work).

Instead resolving it the same way we did in d3bdda3 for a similar
issue in #getDefinitionMtime: by adding the hash itself to the
key. That way it will solve the problem, including two nice things:
* Not fragment anymore than necessary (if it doesn't vary by
  skin, it won't vary by skin, and same for language etc.).
* Always separate keys when the value is different (if something
  can very based on other factors, e.g. LocalSettings globals or
  whatever untracked method may exist for influencing anything,
  it will all work as expected).
* Don't keep alternating and incrementing the timestamp while a
  multi-server infrastructure is syncing code (e.g. old code and
  new code for the same request context will not result in the
  same key and each old/new server alternatingly increasing the
  timestamp, instead the first new server will make the new key
  and the other servers will gradually start finding the new key
  with the timestamp of when it was first seen).

Change-Id: Ifa9088c11c388ca6c912e62efc43494e91702603
2013-12-04 00:56:13 +00:00
Ori Livneh
185d1bc255 Added wfProfileOut for early returns in ResourceLoaderModule::getDefinitionMtime
I added the profiling calls in PS13 of I00cf086c9 but forgot to add
wfProfileOuts for the early returns.

Change-Id: Ibcd22daba8da0e087376553bca271796e0d207e5
2013-12-02 22:10:44 -08:00
Timo Tijhof
d3bdda3221 resourceloader: Add definition hashing to improve cache invalidation
Currently we invalidate module caches based on timestamps from
various places (including message blob, file mtimes and more).

This meant that when a module changes such that the maximum
detectable timestamp is still the same, the cache would not
invalidate.

Module classes can now implement a method to build a summary.
In most cases this should be (a normalised version of) the
definition array originally given to ResourceLoader::register
(such as $wgResourceModules items).

The most common scenarios this addresses:

* File lists (scripts, styles) being re-ordered.
* Files being removed when more recently changed files remain
  part of the module (e.g. removing an older file).
* Files or messages being added to a module while other more
  recently changed things are already part of the module.
  E.g. you create a message and use it in a js file, but forget
  to add the message to the module. Then later you add the msg
  key. This last update would be ignored, because the mtime of
  the message is no newer than the total which already included
  the (same) mtime of the js file added in the previous update.
* Change the concatenation order of pages in a Gadget definition.

Bug: 37812
Change-Id: I00cf086c981a84235623bf58fb83c9c23aa2d619
2013-12-02 21:45:33 -08:00
Timo Tijhof
339ca89b18 resourceloader: Support hashes as cache invalidation trigger
For now ResourceLoader will still internally deal with timestamps,
especially because they are easier to max() on the client side
(on the server we could make a hash of different hashes, on the
client that's a bit annoying).

However ResourceLoaderModule#getHashMtime will abstract the logic
we already use in ResourceLoaderLanguageDataModule and have
encouraged others to use, which is to put the timestamp and
hash in Memcached, and use that to observer the hash change and
update the timestamp when it does.

Updated ResourceLoaderLanguageDataModule to make use of this.

Change-Id: Ib051ef41ba239084671c30fd275b8d94099d5d52
2013-10-07 23:00:38 +02:00
Max Semenik
5c51cb96ea Maintenance script to check LESS files for validity
A reworked version of script from I068686854ad79e2f63a08d81b1af02f373110613

Move leccs instantiation code to ResourceLoader because it doesn't depend on any
particular module's state.

Change-Id: I733b53171dca77f50a30e5bd0bd5f1b456e4c85d
2013-09-30 21:37:13 +04:00
Timo Tijhof
93cb656139 less: Use new addParsedFile method, replacing embeddedFiles hack
Follows-up b67b9e1, lessphp now has a public method to add to the
list of files for compilation cache.

Change-Id: I62a6c7cdeb34ea742fa7547e3ca10e24ee484b97
2013-09-29 05:16:00 +00:00
Timo Tijhof
e09c4d952d less: Add '@since 1.22' comments
Change-Id: I673705423cf7618e207c0ee47b01761d6c89ce5f
2013-09-28 06:23:01 +00:00
Ori Livneh
565b0fae81 Rename lessc->embeddedImages to lessc->embeddedFiles
'embeddedImages' is a custom property we set on lessc compiler instances to
track the set of files that were embedded in the generated source as data URIs.
This is so done so we know to regenerate the CSS if the source file for an
embedded asset changes. (If my pull request[1] is merged, we won't have to use
a custom property at all.)

I realized that the property name should be 'embeddedFiles' rather than
'embeddedImages', because it's not just images that can be usefully embedded in
CSS, but fonts as well.

  [1]: https://github.com/leafo/lessphp/pull/472

Change-Id: Ief3afaa23e4532f4a536e0dfef943d4fa20db80d
2013-09-23 14:46:41 -07:00
Ori Livneh
b67b9e1b48 Support LESS stylesheets in ResourceLoader
This patch adds support for the LESS stylesheet language to ResourceLoader.
LESS is a stylesheet language that compiles into CSS. The patch includes
lessphp, a LESS compiler implemented in PHP. The rationale for choosing LESS is
explained in a MediaWiki RFC which accompanies this patch, available at
<https://www.mediawiki.org/wiki/Requests_for_comment/LESS>.

LESS support is provided for ResourceLoader file modules. It is triggered by
the presence of the '.less' extension in stylesheet filenames. LESS files are
compiled by lessc, and the resultant CSS is subjected to the standard set of
transformations (CSSJanus & CSSMin). The immediate result of LESS compilation
is encoded as an array, which includes the list of LESS files that were
compiled and their mtimes. This array is cached. Cache invalidation is
performed by comparing the cached mtimes with the mtimes of the files on disk.
If the compiler itself throws an exception, ResourceLoader constructs a
compilation result which consists of the error message encoded as a CSS
comment. Failed compilation results are cached too, but with an expiration time
of five minutes. The expiration time is required because the full list of
referenced files is not known.

Three configuration variables configure the global environment for LESS
modules: $wgResourceLoaderLESSVars, $wgResourceLoaderLESSFunctions, and
$wgResourceLoaderLESSImportPaths. $wgResourceLoaderLESSVars maps variable names
to CSS values, specified as strings. Variables declared in this array are
available in all LESS files. $wgResourceLoaderLESSFunctions is similar, except
it maps custom function names to PHP callables. These functions can be called
from within LESS to transform values. Read more about custom functions at
<http://leafo.net/lessphp/docs/#custom_functions>. Finally,
$wgResourceLoaderLESSImportPaths specifies file system paths in addition to the
current module's path where the LESS compiler should look up files referenced
in @import statements.

The issue of handling of /* @embed */ and /* @noflip */ annotations is left
unresolved. Earlier versions of this patch included an @embed analog
implemented as a LESS custom function, but there was enough ambiguity about
whether the strategy it took was optimal to merit discussing it in a separate,
follow-up patch.

Bug: 40964
Change-Id: Id052a04dd2f76a1f4aef39fbd454bd67f5fd282f
2013-09-23 12:55:19 -07:00
Ori Livneh
71e7e64001 Consistently follow conventions for documenting parameters
Per MW:CC/PHP, the type goes before the variable name, and built-in types are
not uppercase.

Change-Id: Ibb753acd9529ace3579d57654adc47673fa49719
2013-09-12 21:50:45 -07:00
Matthew Flaschen
5b212601db Remove comment saying code should add RL dependencies directly
This does not reflect actual ResourceLoader best practices.

Bug: 51853
Change-Id: I62e875c472ecc54b310ce5ed14fdcabda02e19e5
2013-08-22 17:50:26 +00:00
Timo Tijhof
8dbe77db6c phpcs: Pass includes/resourceloader/
- A cast statement must not be followed by a space.
- The method parameter $context is never used.
- Avoid function calls in a FOR loop test part.
- Opening brace should be on the same line as closing parenthesis.

Change-Id: I0eba7fcc9ceab372003d1134857346690c525e87
2013-04-03 02:16:02 +02:00
Yuri Astrakhan
9506e3d812 Spellchecked /includes directory
* Ran spell-checker over code comments in /includes/
* A few spellchecking fixes for wfDebug() calls

Found one very strange (NOOP?) line in Linker.php - see "TODO: BUG?"

Change-Id: Ibb86b51073b980eda9ecce2cf0b8dd33f058adbf
2013-03-13 03:42:41 -04:00
Tyler Anthony Romeo
4dcc7961df Fixed @param tags to conform with Doxygen format.
Doxygen expects parameter types to come before the
parameter name in @param tags. Used a quick regex
to switch everything around where possible. This
only fixes cases where a primitve variable (or a
primitive followed by other types) is the variable
type. Other cases will need to be fixed manually.

Change-Id: Ic59fd20856eb0489d70f3469a56ebce0efb3db13
2013-03-11 13:15:01 -04:00
umherirrender
d63121016d fix some spacing
Added/removed spaces around logical/arithmetic operator
Reduced multiple empty lines to one empty line
Removed wrong tabs before comments at end of line
Removed too many spaces in assigments

Change-Id: I2bba4e72f9b5f88c53324d7b70e6042f1aad8f6b
2013-03-07 17:53:21 +01:00
Juliusz Gonera
c2d117b379 Add mobile target to modules needed for mw.msg()
This changes allows us to use mw.msg() in MobileFrontend.

Change-Id: I446656bcc17a31d23da054a6e1154f3e5823fbf5
2012-12-17 16:24:02 -08:00
Timo Tijhof
799db0b44b ResourceLoader: Move safeFilemtime() to ResourceLoaderModule.
This is a useful method not just for inside and sub classes of
ResourceLoaderFileModule (i.e. it could've been useful in
VisualEditor's ResourceLoaderModule class as well)

Also moved up getTargets() to be in the right section (looking at
the file as a whole).

Change-Id: If696ffbdc5aa7f0a51603bcf9d52adab38b9c686
2012-12-16 23:13:04 +01:00
Ori Livneh
56831e1f9e Fix typo (manuall -> manually)
Change-Id: Ia6101ea84faf9a4420afe9568b5e3904fffa61b1
2012-11-19 02:18:27 -08:00
Ori Livneh
6179de561b Fix typo (ResourceLodaer => ResourceLoader)
Change-Id: Ie349853f3fbcd7a9eb038d5988497f115684ebeb
2012-11-12 20:18:59 -08:00
umherirrender
9d19d7342a Remove a bunch of trailing spaces and unneeded newlines
Change-Id: I7db616db8c969567d420c0161fa207b366e292b6
2012-10-19 22:03:05 +02:00
Brion Vibber
4b3a426ae0 Work in progress on ResourceLoader mobilification
Goes along with MobileFrontend changes: https://gerrit.wikimedia.org/r/28434

Adds 'targets' option to module definitions, defaulting to 'desktop'.
Only a couple more modules are whitelisted into both desktop and mobile for now.

Startup module takes a 'target' parameter (defaults to 'desktop') to filter
the resource module registration list. Only modules matching the filter get
registered, and thus will be loadable from client-side RL.

Change-Id: Ifb772d4995b8e2ec4b63776fe0bb5b0214f82e04
2012-10-18 00:55:54 +00:00
Siebrand
766ed469cf Merge "Stylize" 2012-10-03 14:49:22 +00:00
Timo Tijhof
ff594d3b0a ResourceLoader: Refactor style loading
Fixes:
* bug 31676: Work around IE stylesheet limit.
* bug 35562: @import styles broken in modules that combine
  multiple stylesheets.
* bug 40498: Don't output empty "@media print { }" blocks.
* bug 40500: Don't ignore media-type for urls in debug mode.

Approach:
* Re-use the same <style> tag so that we stay under the 31
  stylesheet limit in IE. Unless the to-be-added css text from
  the being-loaded module contains @import, in which case we do
  create a new <style> tag and then re-use that one from that
  point on (bug 31676).

* Return stylesheets as arrays, instead of a concatenated string.
  This fixes bug 35562, because @import only works when at the
  top of a stylesheet. By not unconditionally concatenating files
  within a module on the server side already, @import will work
  in e.g. module 'site' that contains 2 wiki pages.

  This is normalized in ResourceLoader::makeCombinedStyles(),
  so far only ResourceLoaderWikiModule makes use of this.

Misc. clean up and bug fixes:
* Reducing usage of jQuery() and mw.html.element() where
  native DOM would be very simple and faster. Aside from
  simplicity and speed, this is also working towards a more
  stand-alone ResourceLoader.
* Trim server output a little bit more
  - Redundant new line after minify-css (it is now an array, so
    no need to keep space afterwards)
  - Redundant semi-colon after minify-js if it ends in a colon
* Allow space in styleTest.css.php
* Clean up and extend unit tests to cover for these features
  and bug fixes.
* Don't set styleEl.rel = 'stylesheet'; that has no business
  on a <style> tag.
* Fix bug in mw.loader's addStyleTag(). It turns out IE6
  has an odd security measure that does not allow manipulation
  of elements (at least style tags) that are created by a
  different script (even if that script was served from the same
  domain/origin etc.). We didn't ran into this before because
  we only created new style tags, never appended to them. Now
  that we do, this came up. Took a while to figure out because
  it was created by mediawiki.js but it calls jQuery which did
  the actual dom insertion. Odd thing is, we load jquery.js and
  mediawiki.js in the same request even...
  Without this all css-url related mw.loader tests would fail
  in IE6.
* mediawiki.js and mediawiki.test.js now pass jshint again.

Tested (and passing qunit/?module=mediawiki; 123 of 123):
* Chrome 14, 21
* Firefox 3.0, 3.6, 4, 7, 14, 15, 16beta
* IE 6, 7, 8, 9
* Safari 4.0, 5.0, 5.1
* Opera 10.0, 11.1, 11.5, 11.6, 12.0, 12.5beta
* iPhone 3GS / iOS 3.0 / Mobile Safari 4.0
  iPhone 4 / iOS 4.0.1 / Mobile Safari 4.0.5
  iPhone 4S / iOS 6.0 Beta / Mobile Safari 6.0

Change-Id: I3e8227ddb87fd9441071ca935439fc6467751dab
2012-10-03 00:23:16 +02:00
jeroendedauw
1ccaff3ee8 Stylize
Change-Id: Ia9532f06db8331da1ea5ff9c9398073d7d084484
2012-10-01 12:36:15 +02:00
jeroendedauw
e1101bbb6f Style fix
Change-Id: I6b900924b07b44152fa943d10400fe151b4046c8
2012-09-27 21:36:14 +02:00
Antoine Musso
aab43dd495 escape tags and entity in doxygen comments
When inserting XML elements inline <such as this one>, doxygen chokes
about it not being known. Simply enclosing the tag in double quotes
prevents doxygen from emitting a warning.

Also enclosed a few invalid functions calls such as \. and double quoted
the HTML entities such as &foobar;

Change-Id: I4019637145e683c2bec3d17b2fd98b0c50a932f1
2012-07-10 17:08:32 +02:00
Max Semenik
cd7923ac16 Introduced the concept of raw ResourceLoader modules
This is needed for mobile scripts that are supposed to work on dumb
devices and as such can't rely on client-side RL, but still can take
advantage of server-side minification and concatenation.

Patchset 2: Allow loading raw modules with &raw=true appended to URL.

Change-Id: I9410ffbf6633075e07bd06b10a98a4d12d9b6106
2012-05-16 01:03:12 +04:00
Alexandre Emsenhuber
7d9016943d Added missing GPLv2 headers in some places.
Also made file/class documentation more consistent.

Change-Id: I1815587ab2eeb24623ce4bf1c695088bd3f1c2ea
2012-04-30 09:16:10 +02:00
Roan Kattouw
beb7ab0f36 (bug 35036) Wikipage-based ResourceLoader modules were not automatically purged as they should be when one of their messages changed. In practice, this only affected WikiLove.
Also adding a documentation comment in ResourceLoaderModule to clarify that it is the subclass's responsibility to make sure message blob timestamps are taken into account
2012-03-07 19:33:37 +00:00
Sam Reed
f8a0e34ca1 Documentation
Trim trailing whitespace

Make returns return values where appropriate (ie other paths in the same method do)
2011-10-14 08:06:54 +00:00
Roan Kattouw
488d368b86 Followup r96978, clean up code duplication by factoring out the code building load.php requests into ResourceLoader::makeLoaderURL() and makeLoaderQuery() 2011-09-13 20:36:24 +00:00
Roan Kattouw
f4f3107209 Fix the fixme on r88053: dependency handling was broken in debug mode in certain cases. More specifically, if A is a file module that depends on B, B is a wiki module that depends on C and C is a file module, the loading order is CBA (correct) in production mode but was BCA (wrong) in debug mode. Fixed this by URL-ifying scripts and styles for those modules in debug mode, as I said to on CR. What this means is that the initial debug=true request for a module will now always return arrays of URLs, never the JS or CSS itself. This was already the case for file modules (which returned arrays of URLs to the raw files), but not for other modules (which returned the JS and CSS itself). So for non-file modules, load.php?modules=foo&debug=true now returns some JS that instructs the loader to fetch the module's JS from load.php?modules=foo&debug=true&only=scripts and the CSS from ...&only=styles .
* Removed the magic behavior where ResourceLoaderModule::getScripts() and getStyles() could return an array of URLs where the documentation said they should return a JS/CSS string. Because I didn't restructure the calling code too much, the old magical behavior should still work.
* Instead, move this behavior to getScriptURLsForDebug() and getStyleURLsForDebug(). The default implementation constructs a single URL for a load.php request for the module with debug=true&only=scripts (or styles). The URL building code duplicates some things from OutputPage::makeResourceLoaderLink(), I'll clean that up later. ResourceLoaderFileModule overrides this method to return URLs to the raw files, using code that I removed from getScripts()/getStyles()
* Add ResourceLoaderModule::supportsURLLoading(), which returns true by default but may return false to indicate that a module does not support loading via a URL. This is needed to respect $this->debugRaw in ResourceLoaderFileModule (set to true for jquery and mediawiki), and obviously for the startup module as well, because we get bootstrapping problems otherwise (can't call mw.loader.implement() when the code for mw.loader isn't loaded yet)
2011-09-13 17:13:53 +00:00
Krinkle
cc21627b4d [ResourceLoader 2]: Add support for multiple loadScript sources
Front-end:
* New mw.loader method: addSource(). Call with two arguments or an object as first argument for multiple registrations
* New property in module registry: "source". Optional for local modules (falls back to 'local'). When loading/using one or more modules, the worker will group the request by source and make separate requests to the sources as needed.
* Re-arranging object properties in mw.loader.register to match the same order all other code parts use.
* Adding documentation for 'source' and where missing updating it to include 'group' as well.
* Refactor of mw.loader.work() by Roan Kattouw and Timo Tijhof:'
-- Additional splitting layer by source (in addition to splitting by group), renamed 'groups' to 'splits'
-- Clean up of the loop, and removing a no longer needed loop after the for-in-loop 
-- Much more function documentation in mw.loader.work()
-- Moved caching of wgResourceLoaderMaxQueryLength out of the loop and renamed 'limit' to 'maxQueryLength

Back-end changed provided through patch by Roan Kattouw (to avoid broken code between commits):
* New method in ResourceLoader: addSource(). During construction of ResourceLoader this will be called by default for 'local' with loadScript property set to $wgLoadScript. Additional sources can be registered through $wgResourceLoaderSources (empty array by default)
* Calling mw.loader.addSource from the startup module
* Passing source to mw.loader.register from startup module
* Some new static helper methods

Use:
* By default nothing should change in core, all modules simply default to 'local'. This info originates from the getSource()-method of the ResourceLoaderModule class, which is inherited to all core ResourceLoaderModule-implementations (none override it)
* Third-party users and/or extensions can create new classes extending ResourceLoaderModule, re-implementing the getSource-method to return something else.

Basic example:
$wgResourceLoaderSources['mywiki'] = array( 'loadScript' => 'http://example.org/w/load.php' );
class MyCentralWikiModule extends ResourceLoaderModule {
	function getSource(){
		return 'mywiki';
	}
}
$wgResourceModules['cool.stuff'] => array( 'class' => 'MyCentralWikiModule' );

More complicated example
// imagine some stuff with a ForeignGadgetRepo class, putting stuff in $wgResourceLoaderSources in the __construct() method
class ForeignGadgetRepoGadget extends ResourceLoaderModule {
	function getSource(){
		return $this->source;
	}
}

Loading:
Loading is completely transparent, stuff like $wgOut->addModules() or mw.loader.loader/using both take it as any other module and load from the right source accordingly.


--
This commit is part of the ResourceLoader 2 project.
2011-07-26 21:10:34 +00:00
Brion Vibber
0f201b19f4 * (bug 28626) Validate JavaScript files and pages loaded via ResourceLoader before minification, protecting separate modules from interference
This is possibly not perfect but seems to serve for a start; follows up on r91591 that adds JSMin+ to use it in some unit tests. May want to adjust some related bits.

- $wgResourceLoaderValidateJs on by default (can be disabled)
- when loading a JS file through ResourceLoaderFileModule or ResourceLoaderWikiModule, parse it using JSMinPlus's JSParser class. If the parser throws an exception, the JS code of the offending file will be replaced by a JS exception throw listing the file or page name, line number (in original form), and description of the error from the parser.
- parsing results are cached based on md5 of content to avoid re-parsing identical text
- for JS pages loaded via direct load.php request, the parse error is thrown and visible in the JS console/error log

Issues:
- the primary use case for this is when a single load.php request implements multiple modules via mw.loader.implement() -- the loader catches the exception and skips on to the next module (good) but doesn't re-throw the exception for the JS console. It does log to console if present, but it'll only show up as a regular debug message, not an error. This can suppress visibility of errors in a module that's loaded together with other modules (such as a gadget).
- have not done performance testing on the JSParser
- have not done thorough unit testing with the JSParser
2011-07-06 21:48:09 +00:00
Sam Reed
16c194d0ae Fixup/add documentation
Remove trailing whitespace
2011-05-21 17:45:20 +00:00