(bug 35240) Fix mw.loader state machine.
Main changes:
* handlePending() correctly handles "missing" and "error" states
and propagates error states up the dependency tree.
* handlePending() is called whenever a module enters one of the
states "ready", "error", or "missing" (in execute() and
mw.loader.state()).
* load() filters out not only undefined modules, but -- by the logic of
the comment there -- also modules in state "error" or "missing".
Minor changes:
* recurse() renamed to sortDependencies(), also uses a hash for
unresolved now instead of an array.
* execute() was never called with the second parameter "callback", hence
I've removed it.
* simplified the "are all dependencies 'ready'?" test and moved it to
its own function.
The change comes with additional QUnit tests for mw.loader. If I run
these tests against the current mediawiki.js, several of them fail. In
particular test #86 ("mw.loader real missing dependency") is
instructive: if the server returns "missing" for a module, dependent
modules never progress beyond "loaded", and if there are jobs (from
mw.loader.using()) depending on such a missing module (directly or
indirectly), neither ready() nor error() is ever called.
Running the tests against the changed mediawiki.js in this change, they
all succeed for me.
Patchset 2: whitespace changes, $_GET instead of $_REQUEST in
testloader.
Patchset 3: XML::encodeJsVar() in testloader, deepEqual() in Qunit
tests.
Patchset 4: rebase
Patchset 5: Amend commit message only (typo)
Change-Id: Ia67edfc07fc9237def04ed13bb2cee16e519d7af