Commit graph

92 commits

Author SHA1 Message Date
Ori Livneh
471a3bfb3d ResourceLoader: make cacheReport option false by default
In the three years or so that I have been around, we at Wikimedia have not to
my knowledge used the cache keys to manage the cache of ResourceLoader modules.
Instead, if we want to force a module to rebuild, we simply touch one of its
files. (Though even that is not often required these days.)

Change-Id: Ib62a792e053572f268d4be19a10f99f84c07abc5
2015-08-11 09:38:43 -07:00
Timo Tijhof
7facd8b214 resourceloader: Fix RLQ script to support IE8 quirk
In IE8 there is a race condition. If the window.RLQ runs first (that is, the
startup module loads first) then 'var RLQ' does not get associated
properly to our custom window.RLQ object.

The other way around is fine, but never happens because <script async>
isn't supported in IE8.

Consistently use 'window.RLQ' (never 'var RLQ') to bypass this bug.

Also updating the startup.js file for consistency (though not strictly
needed since the implicit global reference without 'var' also works fine
in IE8.

Bug: T107954
Change-Id: I3f46fee7c4528abf806bb9c51fc767eceb795009
2015-08-04 16:25:11 -07:00
Timo Tijhof
d7905627fd resourceloader: Async all the way
Page startup:
* Due to the startup module and top queue being asynchronous now,
  move client-nojs/client-js class handling to OutputPage to ensure
  there is no flashes of wrongly styled or unstyled content.

  To preserve compatibility for unsupported browsers, undo the
  class swap at runtime after the isCompatible() check.

ResourceLoader startup module:
* Load the startup module with <script async>.
* Use DOM methods instead of 'document.write' to create base module request (jquery|mediawiki).

mw.loader:
* Drop 'async' parameter from mw.loader.load().
* Remove the now-unused code paths for synchronous requests.

OutputPage:

* Drop '$loadCall' parameter from makeResourceLoaderLink().
  Asynchronous is now the default and only way to load JavaScript.
  This means the 'user' module "conditional document-write scripts"
  are now a simple "mw.loader.load( url )" call.

* Fix incorrect @return of makeResourceLoaderLink(). This returns
  an array not a string.

* Improve documentation of makeResourceLoaderLink().

* Drop '$inHead' parameter from getScriptsForBottomQueue(). No longer used.
  Compatibility with the $wgResourceLoaderExperimentalAsyncLoading
  feature is maintained. It just no longer needs to change the
  way the queue works since it's always asynchronous. The feature
  flag now only controls whether the bottom queue starts at the bottom
  or starts at the top.

* Remove jQuery.ready() optimisation.
  This was mostly there to avoid the setTimeout() loop jQuery does to detect
  dom-ready in IE6/IE7 (which we no longer serve JavaScript at all).
  And for a bug in Firefox with document.write (which is no longer used as of
  this commit).

Bug: T107399
Change-Id: Icba6d7a87b239bf127a221bc6bc432cfa71a4a72
2015-08-04 10:20:10 -07:00
Timo Tijhof
96fc60533f resourceloader: Remove ESI support (previously disabled)
These were never enabled or used in production and are not
compatible with the upcoming async changes (T107399). To avoid
having to maintain compatibility with this, remove it for now.

The current on-going request to operations for ESI support is unrelated
to this code.

Considered making makeResourceLoaderLink() protected as it's not
used anywhere in @wikimedia Git outside mediawiki-core. And the unit
test actually treated it as protected already. However it's called
in SpecialJavaScriptTest so leaving that as-is for now.

In Icba6d7a87b239 the signature will change again with the removal
of the $loadCall parameter, which is obsolete in an async world
due to document.write being forbidden.

Change-Id: I9f557cc794638ffd15329934865e21e1027f7cfa
2015-08-01 18:05:23 +00:00
Timo Tijhof
ad77bb10f2 resourceloader: Use WrappedString library to merge RLQ inline scripts
Update unit test to account for the internal 'html' prop now
being an array instead of string. And update expected values to
no longer have a trailing line break.

Bug: T27202
Change-Id: I105b6ef2e64ab8b891562e16940edb88592bd415
2015-07-31 17:45:06 +00:00
Timo Tijhof
59f1a1efa8 resourceloader: Convert inline statements to queued functions
Instead of having inline statements be plain statements wrapped
in an if-conditional block, convert them to inline functions
pushed into a queue.

The queue is kept in-memory until the startup module is loaded
at which point it transforms into a function that is immediately
invoked.

This is a prerequisite to making the top queue asynchronous.
Until then these functions will just run immediately as they
occur in the HTML after the startup module.

This is based on the previously reverted commit e86e5f8460.

Bug: T107399
Change-Id: Ifb38efca219c10ab973ad4c4ebb21c6a4239b005
2015-07-30 18:22:46 +00:00
Vivek Ghaisas
9f5b6f5aeb Fix whitespace issues around parentheses
Fix issues found by MediaWiki.WhiteSpace.SpaceyParenthesis sniff.

Bug: T102617
Change-Id: Iec7f71e64081659fba373ec20d9d2006306a98f4
2015-06-16 22:14:02 +03:00
jenkins-bot
5d7a5925a4 Merge "resourceloader: Omit empty parameters from mw.loader.implement calls" 2015-04-06 06:22:45 +00:00
Timo Tijhof
3cf2f18bb8 resourceloader: Omit empty parameters from mw.loader.implement calls
Follows-up ebeb29723, 1f393b6da, 0e719ce23.

Also:
* Add tests for ResourceLoader::makeLoaderImplementScript().
* Apply ResourceLoader::trimArray to makeLoaderImplementScript (new in c0c221bf).

This commit changes the load.php response to omit empty parameters.

These parameters were required until recently. The client has been
updated (1f393b6da and 0e719ce23) to make these optional, thus supporting
both the old server format and the change this commit makes

Clients with a tab open from before 0e719ce23 are naturally not
compatible with load.php responses from after this commit. Ensure
this is deployed several days after 0e719ce23 to reduce race
conditions of this nature.

(This is a re-submitted version of 4ce0c0da4)

Bug: T88879
Change-Id: I9e998261ee9b0b745e3339bc3493755c0cb04b6a
2015-04-03 07:20:51 +01:00
Kunal Mehta
4fb5c877f6 Don't trigger MessageBlobStore during tests
The test for OutputPage::makeResourceLoaderLink was triggering database
queries through MessageBlobStore even though it doesn't use any
messages.

In bb03d1a8e0 I had made MessageBlobStore a singleton instead of static
functions, however there's no need for it to be one since the class is
stateless. Callers can just create a new MessageBlobStore instance and
call functions upon it. Using getInstance() is now deprecated.

ResourceLoader now has a setMessageBlobStore setter to allow overriding
which MessageBlobStore instance will be used. OutputPageTest uses this
to set a NullMessageBlobStore, which makes no database queries.

Change-Id: Ica7436fb6f1ea59bd445b02527829ab0742c0842
2015-03-28 21:25:25 -07:00
Ori.livneh
2b6eb60ce5 Revert "Optimize order of styles and scripts"
The patch did not improve performance. I'd like to think that the increased
control over when inline scripts are executed makes the patch worthwhile
regardless, but that is post hoc justification and possibly a bit of personal
ego. Krinkle agrees that we may use some of the ideas in this patch in the
future but he thinks we're better off not heading down this path before we
have a better sense of where we're going, and I trust his judgment.

This reverts commit e86e5f8460.

Change-Id: I151f74a41dd664b5a0aa5cfd99fcc95e2686a1e6
2015-03-25 04:40:46 +00:00
Timo Tijhof
dbd718dc55 resourceloader: Add @covers and minor clean up of test suites
* Move testMixedCssAnnotations to ResourceLoaderFileModuleTest.
* Re-order data providers before test methods.
* Add relevant @covers annotations in resourceloader/ tests.
* Make test helper function private.
* Add a few @covers for methods called from OutputPage::makeResourceLoaderLink
  (only one level deep, we should have separate unit tests for
  the more internal helpers).

Change-Id: I2cc1757126214ed28059d4566ca813a86bcd95a7
2015-03-23 04:16:08 +00:00
Ori Livneh
e86e5f8460 Optimize order of styles and scripts
The current ordering of scripts and stylesheets in <head> causes all major
browsers to serialize and defer requests that could be performed in parallel.

The problem is that external stylesheets are loaded before inline scripts. As
Steven Souders explains, "all major browsers preserve the order of CSS and
JavaScript. The stylesheet has to be fully downloaded, parsed, and applied
before the inline script is executed. And the inline script must be executed
before the remaining resources can be downloaded. Therefore, resources that
follow a stylesheet and inline script are blocked from downloading."[1]

In other words: the browser could start loading body images, but it refuses to
do that until it has executed inline scripts in head. And it refuses to execute
those scripts until the external CSS is downloaded, parsed and applied. You can
see the effect of this in this image, showing the request waterfall for
[[en:Gothic Alphabet]]: [2]. Notice how no images were requested before the
browser had finished processing the three load.php requests at the top.

To fix this, we want to move the inline scripts above the external CSS. This is
a little bit tricky, because the inline scripts depend on mw.loader, which is
loaded via an external script. If we move the external script so that it too is
above the external stylesheet, we force the browser to serialize requests,
because the browser will not retrieve the external CSS until it has retrieved
and executed the external JS code. So what we want is to move the inline
scripts above the external stylesheet, but keep the external script (which the
inline scripts depend on) below the external stylesheet.

We can do this by wrapping the inline script code in a closure (which binds
'mw') and enqueuing the closure in a global array which will be processed by
the startup module at just the right time.

Net result: external CSS and JS is retrieved in parallel, retrieval of images
(and other external assets) is unblocked, but the order in which code is
evaluated remains the same.

[1]: <http://www.stevesouders.com/blog/2009/05/06/positioning-inline-scripts/>
[2]: <http://people.wikimedia.org/~ori/enwiki-waterfall.png> (excerpted from
 <http://www.webpagetest.org/result/150316_0C_7MB/1/details/>.

Change-Id: I98d383a6299ffbd10210431544a505338ca8643f
2015-03-17 03:10:49 +01:00
Timo Tijhof
3ed7b27f7b OutputPage: Condition-wrap the <script> for 'user.groups'
Follows-up 9d390a09cd. It already wraps the only=script requests
for 'site' and 'user', but forgot about 'user.groups' which is
not 'scripts' but 'combined' (as regular module requests).

That request responds with mw.loader.implement whih will be absent
if the environment is unsupported.

With normal module requests, this is naturally covered by those
requests not being fired from mw.loader in the first place but
with hardcoded requests like these the condition wrap with
document.write is unfortunately required in the current reality.

Change-Id: Ib3a7378d0c44e601760fbbc5174da09bd7b7f492
2015-03-11 19:33:24 +00:00
Krinkle
6e46b4b380 Revert "resourceloader: Omit empty parameters from mw.loader.implement calls"
Works as intended, but didn't account for the first implement() parameter
being omitted client-side. Revert until that is accounted for, then re-try after
that fix is rolled out for > 1 week.

This reverts commit 4ce0c0da42.

Change-Id: I36c1619991663c0303636d1d3f037b0021ac79bf
2015-01-20 23:56:17 +00:00
Timo Tijhof
4ce0c0da42 resourceloader: Omit empty parameters from mw.loader.implement calls
Follows-up ebeb297236.

Also:
* Add tests for ResourceLoader::makeLoaderImplementScript().
* Apply ResourceLoader::trimArray to makeLoaderImplementScript (new in c0c221bf).

As always, the client (updated in Ie32e7d6a3c) is backward-compatible with old
(cached) load.php module responses. However, the old client is not compatible
new load.php responses after this commit.

That's generally not an issue, as we don't cache the client very long (~ 5 min).
However people with their browser open and mw.loader clients initialised can
still make new module requests (e.g. modules loaded on-demand, such as when
previewing edits, clicking buttons etc.). That can easily be several hours after
initial page load. As such, client/server bound changes should always be
back-compat and deployed a reasonable time apart to reduce chances of active
sessions making subsequent requests. Ideally we'd find some solution to this in
the long-term, but handling this at all is better than what we usually do...

For deployment: Ensure this is deployed several days after Ie32e7d6a3c09f.

Change-Id: Ic8d7efe49b5d45e3f95a2f04e3a26a014b10af16
2015-01-20 23:11:05 +00:00
Ricordisamoa
12dec5d85d Fix some stuttering in comments and documentation
Change-Id: I9c0088b9aab37335203cad45a1d6fa8ac3f43321
2014-12-17 19:44:10 +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
Timo Tijhof
9d390a09cd resourceloader: Condition-wrap the HTML tag instead of JS response
Follows-up 9272bc6c47, 03c503da22, 1e063f6078.

One can't wrap arbitrary JavaScript in an if-statement and have
its inner-body mean exactly the same.

Certain statements are only allowed in the top of a scope (such
as hoisted function declarations). These are not allowed inside
a block. They're fine in both global scope and local function
scope, but not inside an if-block of any scope.

The ECMAScript spec only describes what is an allowed token.
Any unexpected token should result in a SyntaxError.

Chrome's implementation (V8) allows function declarations in
blocks and hoists them to *outside* the condition. Firefox's
SpiderMonkey silently ignores the statement. Neither throw a
SyntaxError.

Rgular ResourceLoader responses only contain mw.loader.implement()
and mw.loader.state() call which could be wrapped without issues.
However such responses don't need wrapping as they're only made
by mediawiki.js (in which case mw is obviously loaded). The
wrapping is for legacy scripts that execute in the global scope.

For those, let's wrap the script tag itself (instead of the
response). That seems like the most water-tight and semantically
correct solution.

Had to bring in $isRaw from ResourceLoader.php, else the startup
module would have been wrapped as well (added regression test).

Bug: 69924
Change-Id: Iedda0464f734ba5f7a884726487f6c7e07d444f1
2014-09-09 15:54:16 +00:00
jenkins-bot
a04d94d4f2 Merge "Improve tests for OutputPage::makeResourceLoaderLink" 2014-09-05 19:25:26 +00:00
Timo Tijhof
5553be79b9 OutputPage: Restore ResourceLoader condition wrap for embedded modules
Follows-up 9272bc6c47, 03c503da22.

* In 9272bc6c47, the condition wrap was removed from
  OutputPage for no reason. This went unnnoticed as I had also
  accidentally made the cond wrap in makeModuleResponse apply
  to both only=scripts and regular (faux) responses, such as by
  OutputPage embedding private modules.

* In 03c503da22, the latter bug was fixed, thus exposing the former.

This wrapper belongs in OutputPage, not in ResourceLoader. It's
OutputPage making the loader request. And just like in other places,
it's the "client"'s responsibility to ensure the request is either not
made or wrapped appropriately.

The test for "private module (only=scripts)" could be removed but
I'll keep it so we can see how this changes in the future. It's
a case that can't ever happen, but if it would, it currently gets
a double condition wrapper, which is fine.

Change-Id: Id333e4958ed769831fabca02164c1e8505962d57
2014-09-02 11:05:13 +02:00
Kunal Mehta
f32a59fadc Improve tests for OutputPage::makeResourceLoaderLink
Change-Id: I0880c2b92bcf96ca1d25952d55464bbfb755ade0
2014-08-23 20:33:40 -07:00
Timo Tijhof
03c503da22 resourceloader: Only conditional-wrap script responses with only=scripts
Follows-up 9272bc6c47. The shouldIncludeScripts method returns
true for only=scripts, but also for other responses (except for
only=styles, naturally).

Regular load.php responses that load both scripts and styles don't
need the conditional wrap because those requests should only be
made from the mw.loader client which inherently means the
environment has been provided already.

It's merely unnecessary and shouldn't have caused any issues since
it simply evaluates to true always. It was already correctly being
excluded from raw modules that run before the environment is
provided (such as startup, jquery and mediawiki).

Change-Id: I375a7a8039f9b3ad4909e76005725f7d975d8a5e
2014-08-22 01:15:49 +00:00
jenkins-bot
c54bcbc5b9 Merge "resourceloader: Wrap only=script responses in "if(window.mw)"" 2014-08-13 00:50:10 +00:00
Timo Tijhof
9272bc6c47 resourceloader: Wrap only=script responses in "if(window.mw)"
We currently have a few legacy requests to the load.php end point
that bypass the ResourceLoader client by coding a request to
load.php via a "<script src>" directly. Most prominently the
request for the 'site' wiki module (aka MediaWiki:Common.js).

Remove the manual wrapping of embedded private modules as this
is now taken are of by ResourceLoader::makeModuleResponse itself.

Misc:
* Mark "jquery" and "mediawiki" as Raw modules. While the startup
  module had this already, these didn't. Without this, they'd
  get the conditional wrap – which would be a problem since mediawiki.js
  can't be conditional on 'window.mw' for that file defines that
  namespace itself.
* Strip the cache-key comment in the unit tests because the hash
  no longer matches and using the generic 'wiki' dbname was breaking
  DB queries.
* Relates to bug 63587.
* See also 05d0f6fefd which expands the reach of the non-JS
  environment to IE6 and helped expose this bug.

Change-Id: Icf6ede09b51ce212aa70ff6be4b341762ec75b4d
2014-08-12 23:20:42 +00:00
jenkins-bot
bda0f626aa Merge "Cleanup some docs (tests)" 2014-08-11 18:35:42 +00:00
umherirrender
26837cd280 Cleanup some docs (tests)
- Swap "$variable type" to "type $variable"
- Fixed spacing inside docs
- Makes beginning of @param/@var/@throws in capital
- Changed some types to match the more common spelling

Change-Id: Ia041964250d8b7c0349d79dc9b131c5b8696e795
2014-08-11 20:06:52 +02:00
Kunal Mehta
eb37e9d1ff Introduce SkinFactory
Modeled similar to ConfigFactory, this lets skins
register themselves via a callback, allowing for
proper dependency injection.

Loading via $wgValidSkinNames is still supported,
but considered "legacy", not deprecated though.

Skin::newFromKey is now deprecated (and had only
one caller in an extension, which I'll update
afterwards).

Change-Id: I1960483f87c2ef55c994545239b728fa376f17f4
2014-08-09 21:40:54 +01:00
Krinkle
8153489b57 Revert "Revert "Stop always loading MonoBook and Vector""
This reverts commit ad849a2b46.

Change-Id: Ibfed909ede8ad657326d23b02b9481ffaf44b026
2014-08-07 15:05:56 +00:00
Krinkle
ad849a2b46 Revert "Stop always loading MonoBook and Vector"
This reverts commit aef99727f6.

Change-Id: Ic2b1c8336fb4378db2a5012ad60f04869b20cb09
2014-08-07 15:03:29 +00:00
Bartosz Dziewoński
aef99727f6 Stop always loading MonoBook and Vector
Removing the hack added in Ib4bdda5e.

This will cause an error message to be shown to almost every MediaWiki
user who upgrades their installation (including us developers) until
they add entries for their skins to LocalSettings. This is deemed an
acceptable trade-off, and the message makes it easy to resolve the
issue.

Bug: 68402
Change-Id: I2596ef73088ce94d78ce3dc3ae4da9d81023a2cb
2014-08-07 14:06:34 +00:00
Kunal Mehta
a3373a7458 OutputPageTest: Don't assume Vector is the default skin
Whenever Vector is removed from core, this can be replaced with
"fallback" (or something that is shipped with core). Ideally this
test wouldn't depend upon Skin, but that's a whole different issue.

Change-Id: I76a74deb95643e0d05f4d0f7e3e8d78f0efc119c
2014-07-23 21:57:40 +00:00
umherirrender
82d970e356 Tests: setMWGlobals -> setMwGlobals
Change-Id: I6441668fdbc62596efba21d736a73071a46bfe45
2014-07-20 21:50:34 +02:00
umherirrender
2b021dc48a Fixed spacing
- Added/removed spaces around parenthesis
- Added space after switch/if/foreach
- changed else if to elseif

Change-Id: I99cda543e0e077320091addd75c188cb6e3a42c2
2014-07-19 23:12:10 +02:00
Thiemo Mättig
4391b60854 Make OutputPageTest more independent from global state
This does not fix all problems (the "combined" test still fails
horribly on my machine for a reason I don't understand). However,
this patch fixes at least two of the problems:

Make the test independent from the wgResourceLoaderDebug setting.

Make the test independent from the wgLanguageCode setting.

Change-Id: I3aa52fed530d852b34b6058e29620749e11092a0
2014-07-12 16:42:51 +02:00
Kunal Mehta
1e301b1550 Add tests for OutputPage::makeResourceLoaderLink()
Change-Id: I22dc7fd1003f07ab0be61bb4645b45a9db9f2548
2014-07-05 04:25:58 -07:00
addshore
aea1b27db0 @covers tags for more test classes
Change-Id: I19d49c279646a4b4c595700e53b790ba4eb9521e
2013-10-24 20:35:04 +01:00
MatmaRex
1965df8df3 Remove the $wgHandheldForIPhone config variable entirely
It only really made sense in pair with $wgHandheldStyle, and that has
been removed in Ia8d79b4a.

Remove irrelevant tests, adjust still relevant ones.

Change-Id: I7c24128f7b148d0244538ad95bb60bf09ec4b5cb
2013-06-04 21:53:47 +02:00
Siebrand Mazeland
ac63001d8e Update formatting
1 of n.

Change-Id: I852729f08bbb0c5e39c2db44362ccdc7f59dcc08
2013-02-14 12:22:13 +01:00
Matthew Flaschen
11aaf93162 (bug 43942) Skip screen sheets with media queries when printing
* Add test suite, with regression tests as well as tests for the fix.

Change-Id: I66d40673cc610370b66af0129412bc6495673f8d
2013-01-17 16:31:43 -05:00