Author: darklama
Description:
mw.loader.using always calls ready callback for unregistered modules,
when the callback shouldn't get called at all.
Examples:
mw.loader.using('', function() { alert('running...'); });
mw.loader.using([], function() { alert('running...'); });
mw.loader.using([''], function() { alert('running...'); });
mw.loader.using('foobar', function() { alert('running...'); });
mw.loader.using(['foobar'], function() { alert('running...'); });
I've been able to trace this back to a few problems that are
probably also causing bugs in other parts of mediawiki.js as well.
First, resolve() returns [] for each module that isn't previously
registered. In most places the return value of resolve() is put
back into the same variable as was passed (like
dependencies = resolve(dependencies)), when the original value
might be needed for comparison.
Second, the variable passed as the second argument of filter()
is replaced with all registered modules when passed []. As
can happen when the return value of resolve() is used and it
is passed unregistered modules. Again the original value of
the second argument might be needed for comparison.
Third, compare() may return true or false in ways not intended
at times. Like when used to compare filtered and unfiltered
return results of resolve(unregistered modules). The filtered
and unfiltered results may be the same at times depending on
the current state of all registered modules. The ready()
or error() callback function is called immediately if the
filtered and unfiltered list of all registered modules
happens to be the same at the time.
Four, if somehow both compare tests manage to fail, every
registered module will be passed to request(). Whatever happens
to be the first registered module will have its dependencies
appended to everything else, this new list will be added to
jobs and queue, and work() will do a lot of extra work.
Finally, AFAIK if request() is somehow called neither callbacks
are called because request() doesn't call them and doesn't pass
them onto queue, so work() has no way of calling them either.
Version: unspecified
Severity: normal