Page MenuHomePhabricator

mw.loader.load calls document.write from asynchronous scripts
Closed, ResolvedPublic

Description

While debugging a user script I came across this bug, which may be responsible for some of the issues occurring in the last time.

Tested MediaWiki version is 1.18wmf1, browser is Firefox 10.0.1. The script doesn't call document.write anywhere directly, so all calls to document.write are done by mw.loader.load.

I found several warnings in the web console, saying
A call to document.write from an asynchronously loaded extern script was ignored.
(translated from German, original: Ein Aufruf von document.write() durch ein asynchron geladenes externes Skript wurde ignoriert.)

So mw.loader.load should pay attention not to load anything by document.write unless this definitely can be done without problems. In this case several scripts were just missing.


Version: unspecified
Severity: normal

Details

Reference
bz34542

Event Timeline

bzimport raised the priority of this task from to Unbreak Now!.Nov 22 2014, 12:14 AM
bzimport set Reference to bz34542.

RL has really changed since 1.18 so I doubt this problem is still around. Could you test with SVN head or the 1.19 branch?

(In reply to comment #1)

RL has really changed since 1.18 so I doubt this problem is still around.
Could you test with SVN head or the 1.19 branch?

The main change is that RL is now even faster, which means that document.write is used more often. The problem is reproducible on beta.wmflabs:

  1. Visit http://de.wikipedia.beta.wmflabs.org/w/index.php?title=Spezial:Einstellungen#mw-prefsection-gadgets
  2. Enable the gadget markAdmins ("markAdmins markiert auf Spezial-, Benutzer-, Diskussions-, Projekt-, Datei- und Hilfeseiten sowie in Versionsunterschieden und der Versionsgeschichte Benutzer mit erweiterten Rechten.")

This gadget loads the real script with mw.loader.load. It should append an (A) to all usernames who are sysops.

  1. Visit http://de.wikipedia.beta.wmflabs.org/wiki/Spezial:Letzte_%C3%84nderungen

Since most of the users are sysops you should see an (A) after many usernames (at least Umherirrender (A/B), and Schnark (A)). But with Firefox 10 they are missing, instead you will find the above warning in the log. In browser which don't implement async loading like Firefox 3.6 and IE 8 the gadget works as expected.

This bug seems to be the explanation for bug 34517, so I'll adjust milestone and importance to match those of 34517.

There is code in mediawiki.js that ensures that document.write() is not used after document ready. I don't know how we'd prevent this in a better way.

I am unable to reproduce the issue described in Comment 2 using FF 9. The "A" and "A/B" markers appear correctly.

nor can I reproduce it with Chrome 17

(In reply to comment #3)

There is code in mediawiki.js that ensures that document.write() is not used
after document ready. I don't know how we'd prevent this in a better way.

https://developer.mozilla.org/en/html/element/script#Attributes says:
"In Firefox 4.0, the async DOM property defaults to true for script-created scripts" (i.e. almost all scripts in a typical page served by MediaWiki are async scripts) and "Never call document.write() from an async script. In Gecko 1.9.2, calling document.write() has an unpredictable effect. In Gecko 2.0, calling document.write() from an async script has no effect (other than printing a warning to the error console)." And I don't think that 'never' means 'only before document ready'. The English warning is "A call to document.write() from an asynchronously-loaded external script was ignored."

Since no gadgets are working at the moment (probably some caching issues) I can't test the bug, but I'm quite sure that this really is a bug that needs to be fixed as soon as possible.

Created attachment 10087
Screenshot: using mw.loader.load('...', '...', true)

I can still reproduce the issue with Firefox 10 on wmlabs.beta. I changed the call to mw.loader.load to use three parameters. When I use true for the third parameter everything works, no matter how often you reload the page. See screenshot.

Attached:

bug1.PNG (1×1 px, 151 KB)

Created attachment 10088
Screenshot: using mw.loader.load('...', '...', false)

But when I use false for the third parameter I sometimes get the warning about an ignored document.write, and the marks are missing. See screenshot.

The only difference is, that in the first case document.write is definitely not used, while in the second case it is used. Since there is obviously a bug in the second case document.write mustn't be used there, either.

Attached:

bug2.PNG (1×1 px, 146 KB)

beau wrote:

Reproducible on pl.wikisource using Chromium 17.0.963.56 and Firefox 10.0.1.

Fixed in r112533 by making the third parameter (async) default to true if a URL is specified, and to false otherwise. Will deploy this to the live site in a minute.

Related URL: https://gerrit.wikimedia.org/r/61494 (Gerrit Change Ic3d0c937268d0943d2f770f3ca18bcf4e1eed346)

Related URL: https://gerrit.wikimedia.org/r/61495 (Gerrit Change Ic3d0c937268d0943d2f770f3ca18bcf4e1eed346)