Commit graph

171 commits

Author SHA1 Message Date
Timo Tijhof
c554ee8e64 resourceloader: Remove support for raw modules
Being a raw module means that when it is requested from load.php with
"only=scripts" set, then the output is *not* wrapped in an
'mw.loader.implement' closure *and* there no 'mw.loader.state()' appendix.
Instead, it is served "raw".

Before 2018, the modules 'mediawiki' and 'jquery' were raw modules.
They were needed before the client could define 'mw.loader.implement', and
could never be valid dependencies. Module 'mediawiki' merged to 'startup',
and 'jquery' became a regular module (T192623). Based on the architecture
of modules being deliverable bundles, it doesn't make sense for there to
ever be raw modules again. Anything that 'startup' needs should be bundled
with it. Anything else is a regular module.

On top of that, we never actually needed this feature because specifying
the 'only=scripts' and 'raw=1' parameters does the same thing.

The only special bit about marking modules (not requests) as "raw" was that
it allowed the client to forget to specify "raw=1" and the server would
automatically omit the 'mw.loader.state()' appendix based on whether the
module is marked as raw. As of Ie4564ec8e26ad53f2, the two remaining use
cases for raw responses now specify the 'raw=1' request parameter, and we
can get rid of the "raw module" feature and all the complexity around it.

== Startup module

In the startup module there was an interesting use of isRaw() that has
little to do with the above. The "ATTENTION" warning there applies to the
startup module only, not raw modules in general. This is now fixed by
explicitly checking for StartupModule.

Above that warning, it talked about saving bytes, which was an optimisation
given that "raw" modules don't communicate with mw.loader, they also don't
need to be registered there because even if mw.loader would try to load
them, the server would never inform mw.loader about the module having
arrived. There are now no longer any such modules.

Bug: T201483
Change-Id: I8839036e7b2b76919b6cd3aa42ccfde4d1247899
2019-06-27 00:08:14 +00:00
Timo Tijhof
a72b082811 resourceloader: Document which FileModule methods use a DB
Also, for the unit test, disable the two methods we use there
that can get called. The unintended side-effects of these two
methods was the only reason it used `@group Database`.
Removing that makes the test a bit faster as well.

Enforce this via MediaWikiServices for this suite to avoid an
untracked dependency slipping back in in the future.

Bug: T225730
Change-Id: I6c54466e9517d9899bc39f8f9bb946369c0a526d
2019-06-19 23:44:39 +01:00
Fomafix
110a5877e9 Use [...] instead of array(...) in PHP comments and documentation
Change-Id: I0c83783051bf35fe785bc01644eeb2946902b6b2
2019-06-17 21:15:09 +02:00
Timo Tijhof
a80d071a2c resourceloader: Support 'versionCallback' for computed package files
The use cases we've seen for using computed (or virtual) package files,
involve expensive computations to expand and transform data for the client
that we don't want to evaluate in full just to compute the module's version
hash (e.g. in the StartupModule, where we need to do this for 1000s of
modules).

For such cases, the module can specify a 'versionCallback' of which the
return value will be used to seed the module's version hash. The default
remains the same as before, which is to use the full content to seed the
version hash (via getDefinitionSummary).

Bug: T223260
Change-Id: I76f573239e6bd429287e7adb33a92ffd5e260c20
2019-06-14 17:05:43 +00:00
Derick Alangi
2dca5bbbf5 Remove unnecessary semi-colons
Change-Id: I9eb65bdfbd3aa581effc14ead801b9e89b0359c3
2019-06-12 14:35:59 +01:00
Jack Phoenix
57bfd3d678 resourceloader: Fix variable spacings where need be
This fix is to make sure resource loader code conforms with convension
https://www.mediawiki.org/wiki/Manual:Coding_conventions/PHP#Spaces.

Change-Id: I34c0a0addbf7c373fc3a64b644a3098bb485a3f4
2019-04-06 13:09:05 +00:00
Aaron Schulz
bc80791f4d resourceloader: Reword and expand doc comment about FileModule "packageFiles"
Change-Id: Id9d68205504ecbddea6ca248e108f368fdcac2d2
2019-03-12 04:01:58 +00:00
Roan Kattouw
b444d3ff39 resourceloader: Remove back compat for old packageFiles format
Was introduced as a transitional measure in Ic566a1cd7efd075c3.

Depends-On: I717f03caf9ea8266e6a4d2b6daf4c543c0815931
Change-Id: I6ae615ea38572042f8ba705338067b393827153a
2019-02-22 19:07:31 +00:00
Roan Kattouw
9316f2e3c3 resourceloader: Change 'packageFiles' format to be JSON-compatible
The module definition format for 'packageFiles', as initially designed,
mixes sequential and associative arrays. This works in PHP, but not in
JSON. To make the format JSON compatible, use a 'name' key instead of
using the key in the main array.

Leave backwards compatibility in place so that extensions using the old
format can be migrated. This will be removed in the next commit.

Before:

'packageFiles' => [
	'script.js',
	'script2.js',
	'config.json' => [ 'config' => [ 'Foo', 'Bar' ] ],
	'data.json' => [ 'callback' => function () { ... } ],
],

After:

'packageFiles' => [
	'script.js',
	'script2.js',
	[ 'name' => 'config.json', 'config' => [ 'Foo', 'Bar' ] ],
	[ 'name' => 'data.json', 'callback' => function () { ... } ],
],

This can then be written in extension.json as:
"packageFiles": [
	"script.js",
	"script2.js",
	[ "name": "config.json", "config": [ "Foo", "Bar" ] ],
	[ "name": "data.json", "callback: [ "MyExtHooks", "getData" ] ]
]

Change-Id: Ic566a1cd7efd075c380bc50ba0cc2c329a2041d7
2019-02-22 19:06:39 +00:00
Timo Tijhof
92d6be8a38 resourceloader: Require $context parameter for FileModule::readStyleFiles()
Deprecated since MW 1.27.

Also update ResourcesTest to use TestingAccessWrapper instead of long-form
object reflection, and also apply it to its call for this method given
its meant to be private.

Change-Id: I9cc1af93730f632e4f8bf3a16d514a51ee73cb03
2019-02-18 19:05:24 +00:00
Roan Kattouw
fbbd65d2df ResourceLoader: Add support for packageFiles
Package files are files that are part of a module, but are not
immediately executed when the module executes. Instead, they are
lazy-excecuted when require() is called on them. Package files can be
scripts (JS) or data (JSON), and can be real files on the file system,
or virtual files generated by a callback.

Using virtual data files, server-side data and config variables can be
bundled with a module. Support for file-based require() allows us to
import npm modules into ResourceLoader more easily.

The require function passed to each script execution context, which was
previously a reference to the global mw.loader.require() function, is
changed to one that is scoped to the module and the file being executed.
This is needed to support relative paths: require( '../foo.js' ) can
mean a different file depending on the path of the calling file.

The results of require()ing each file (i.e. the value of module.exports
after executing it) are stored, and calling require() on the same file a
second time won't execute it again, but will return the stored value.

Miscellaneous changes:
- Add XmlJsCode::encodeObject(), which combines an associative array of
  XmlJsCode objects into one larger XmlJsCode object. This is needed for
  encoding the packageFiles parameter in mw.loader.implement() calls.

Bug: T133462
Change-Id: I78cc86e626de0720397718cd2bed8ed279579112
2019-02-05 22:05:02 +00:00
Timo Tijhof
3bd1910f95 resourceloader: Remove wgResourceLoaderValidateStaticJS setting
Not used since 2011 (MediaWiki 1.18).

In an early version of ResourceLoader, we ran JSMinPlus syntax
validation on-demand on all served JavaScript content. This
was identified as cause of slowdown and high memory use, and
generally not considered as useful in production.

The reason it was there originally was not for the purpose of
validating static files, but for user-generated content.

So in MediaWiki 1.18, the behaviour of wgResourceLoaderValidateJS
was changed to only apply to user-generated content, and the
rest was disabled behind wgResourceLoaderValidateStaticJS, which
we then never use. Not even in development, given that we now
have superior experience through ESLint, even within IDEs where
supported.

Follows-up 49d3d18033 (r91914).

Change-Id: Ie25109a4fb23ee93fed0db4af5db4b11fe9ffe7f
2018-08-20 20:25:01 +01:00
Timo Tijhof
ca510f742f resourceloader: Remove $wgResourceLoaderLESSVars support
The use of global variables was deprecated in favour of
ResourceLoaderModule::getLessVars() on a per-module basis.

Also moved testLessFileCompilation case to the appropiate file as it
covers ResourceLoaderFileModule.php, not ResourceLoader.php.

Bug: T140804
Depends-On: Ib1b2808df2384473bfac47f53a5d25d7c9bbca2b
Depends-On: I96047f69d01c4736306df2719267e6347daf556f
Change-Id: If708087c85c80355c7e78f1768529b5f2e16ed07
2018-08-14 18:57:45 +00:00
Umherirrender
130ec2523d Fix PhanTypeMismatchDeclaredParam
Auto fix MediaWiki.Commenting.FunctionComment.DefaultNullTypeParam sniff

Change-Id: I865323fd0295aabd06f3e3c75e0e5043fb31069e
2018-07-07 00:34:30 +00:00
Timo Tijhof
a0339862ac resourceloader: Add @covers for FileModuleTest
Add @covers for various helper methods used by public methods, where the helper
methods actually contain most of the logic being tested in FileModuleTest.

I've changed these methods from protected to private (confirmed no usage)
to further pin down that their contract doesn't matter beyond making the
public methods work.

Change-Id: I2aef0d322b38bc3595e7d2c2339112b16fc66b8d
2018-06-26 02:06:03 +00:00
Bartosz Dziewoński
485f66f174 Use PHP 7 '??' operator instead of '?:' with 'isset()' where convenient
Find: /isset\(\s*([^()]+?)\s*\)\s*\?\s*\1\s*:\s*/
Replace with: '\1 ?? '

(Everywhere except includes/PHPVersionCheck.php)
(Then, manually fix some line length and indentation issues)

Then manually reviewed the replacements for cases where confusing
operator precedence would result in incorrect results
(fixing those in I478db046a1cc162c6767003ce45c9b56270f3372).

Change-Id: I33b421c8cb11cdd4ce896488c9ff5313f03a38cf
2018-05-30 18:06:13 -07:00
Alexia E. Smith
8a1da0a43b resourceloader: Include global LESS variables in LESS cache key
This prevents cache churn when the wiki-global LESS variables vary
between wikis because the cache key is used as a "global" instead of
db-local. This is good for the common case, but should still explicitly
vary if the vars differ between wikis.

Bug: T191937
Change-Id: If12fd07a7062792205384150d6f5fd9a83f996cc
2018-05-25 18:13:10 +00:00
Thiemo Mättig
544122a6c2 Remove self-explaining "section heading" comments from classes
I can see that "parent::__construct" literally calls the parent
constructor. I can see that stuff preceeded by the keyword "protected"
is protected. I really (really) don't need comments explaining such.

Change-Id: I7458e714976a6acd3ba6a7c93fdc27d03903df83
2017-12-28 16:12:08 +01:00
Timo Tijhof
3f10aa34e6 resourceloader: Include lessVars in FileModule definition summary
This already worked as expected for any module that uses the new
enableModuleContentVersion model, but for the majority of file modules
this is not yet the case for performance reasons. As such, make
sure lessVars are included in our manual tracking.

Include it conditionally to avoid changing the array for other modules,
which would needlessly invalidate their cache.

Bug: T171809
Change-Id: Ib250068e0ecfc29a09ca33c23bef901ee0482bf2
2017-07-27 03:02:09 +00:00
Timo Tijhof
98b148d247 resourceloader: Minor documentation and coding style improvements
Based on current non-voting codesniffer warnings.

Change-Id: I34cbc31eda3eaa519a71fe2c04122859f2f15914
2017-06-30 17:31:56 -07:00
Timo Tijhof
189c906062 resourceloader: Remove unused getPosition() code
Unused as of bc374082fa (T109837).

Change-Id: I1d8f7109bbe49700f1824fdce0439e958e84f6fa
2016-11-18 19:02:12 +00:00
Brion Vibber
ff490cc42a Add 'noflip' option on RL modules to disable CSSJanus
Should be useful for cases where we pull in an external library
that already manages RTL flipping in its styles, and CSSJanus
does the wrong thing without extra markup.

Example:

  'ext.tmh.video-js' => $baseExtensionResource + [
      'scripts' => 'resources/videojs/video.js',
      'styles' => 'resources/videojs/video-js.css',
      'noflip' => true,
      ...
  ],

Bug: T148572
Bug: T148565
Change-Id: Icbad20d8a6e9a0d354ad159f5816f4fb67cc2775
2016-10-18 13:36:27 -07:00
Amir Sarabadani
d56829dca8 Clean up array() syntax from docs, part VI
Change-Id: Ib0eea494e2065c7ab356dc45fd174544a9c1c942
2016-09-12 14:36:37 +04:30
Amir Sarabadani
efa0d7af44 Clean up array() syntax in docs, part III
Also fixing some typos here and there

Change-Id: I29c29acf87f84ba9993ba75ebf2ad8091d981574
2016-08-13 05:40:40 +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
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
Derk-Jan Hartman
844199e67c resourceloader: Strip leading BOM when concatenating files
We read files and concatenate their contents. Files may start with a BOM character.
BOM characters are only allowed at the beginning of a file, not half way.
Stripping it should be safe, since we already assume that everything is UTF-8.

Change-Id: I14ad698a684e78976e873e9ae2c367475550a063
2016-05-31 19:47:19 +01:00
Timo Tijhof
98911418c2 CSSMin: Remove file-existance filter in getLocalFileReferences()
Follows-up 8f5cd11d82.

The old getLocalFileReferences() method is no longer used anywhere.
Remove it and rename getAllLocalFileReferences back to it.

Change-Id: I864258aad128ba9b54464c7bc854543f2937f977
2016-03-03 00:16:13 +00:00
Timo Tijhof
570cff1168 resourceloader: Don't cache CSSMin::remap() calls
The output of this function is not deterministic. This function
is what tranforms urls to include content hashes and also embeds
content as data URI. The calls to this function are expected to be
up to date and matching the version hash as constructed by the
current web request.

Previously, the content hash as constructed based on the collective
file hash of all references images was accurate but the generated
css associated with it could be stale.

Unless we abuse MemoizedCallable to take a separate cache buster
(with $localFileRefs?), it's best to remove this as it isn't
a deterministic function and shouldn't be memoized.

Bug: T128668
Change-Id: Icb87ddc585d7320ac48619446bb8b9cbe5f4780e
2016-03-03 00:10:14 +00:00
Timo Tijhof
792054a2a4 resourceloader: Add content hash to static debug urls
This way, they automatically bypass any stale client or server cache.

Remove an old wfExpandUrl() call that would interfere with
transformResourcePath()'s ability to recognise the path.

Expanding the url there wasn't needed anyway. Whether it's on a separate host
(eg. bits.wikimedia.org), or path-absolute, either way works as-is.

Bug: T90983
Change-Id: I64eb3291adcfc3733ef96690399c09c06e19b3aa
2016-02-20 22:40:44 +00: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
jdlrobson
4d0a36f333 resourceloader: Change getLessCompiler() to not be static
Cache Less variables in the instance instead of statically.

This allows tests to populate their own less variabless via ResourceLoaderLESSVars.

Make getLessCompiler() and getLessVars() regular public methods and
update callers.

Change-Id: I95506b8bb20a4b2b3f82014a7b0fcee5f28973e6
2016-01-14 18:44:32 -08:00
jenkins-bot
1d489846c1 Merge "Fix various mistakes in PHPDoc comments" 2015-12-09 18:13:19 +00:00
Thiemo Mättig
53c5a52970 Fix various mistakes in PHPDoc comments
Change-Id: I434207f61e0663f2d2c9a076296c2e0d04a3fafb
2015-12-09 18:20:41 +01: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
17c91ad610 Replace newAccelerator() with getLocalServerInstance()
The name is clearer and more consistent, with simpler arguments.

Change-Id: I7205a99ce033e8b086a52cd02c8a721e99c84b1e
2015-11-02 21:39:08 +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
da3443bfa2 Add MemoizedCallable for APC-backed function memoization
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
2015-10-06 23:35:03 +00:00
Ori Livneh
7ac0a3ac59 Fix LESS file dependency tracking in ResourceLoader
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
2015-09-30 14:04:18 -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
12afb3607d resourceloader: Improve caching for LESS file compilation
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
2015-09-24 00:34:17 +00:00
Ori Livneh
ea862efa75 Replace leafo/lessphp with oyejorge/less.php
Bug: T112035
Change-Id: I826adf981ac28c44f0915ceb059d699d6b23a254
2015-09-18 16:49:58 +00:00
Bartosz Dziewoński
8f5cd11d82 ResourcesTest: Detect missing files in url(...) expressions
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
2015-09-16 00:27:23 +00:00