resourceloader: Remove outdated readyState handler for base modules request
authorTimo Tijhof <krinklemail@gmail.com>
Tue, 31 Oct 2017 02:16:52 +0000 (19:16 -0700)
committerTimo Tijhof <krinklemail@gmail.com>
Tue, 31 Oct 2017 02:31:13 +0000 (19:31 -0700)
There is a bug in IE10 where under certain conditions[1], the browser will
fire 'onreadystatechange' on script tags before the script has executed.

To avoid this bug, simply remove this outdated compatibility code. It was
originally placed in startup.js in 2011 for compatibility with IE6-8, and
was inspired by the internal source code behind jQuery's ajax transport for
script tags.

jQuery no longer does this either and uses 'script.onload' in all browsers,
which is supported by IE 9 and above. MediaWiki currently requires IE 10
for its Grade A experience.

Looking further, it actually seems that Microsoft has now retroactively
documented that readyState="loaded" in IE6-10, for script tags, represents
the completion of the download, not the execution. [2] Presumably the reason
we did not find this bug earlier is because of the rare conditions [1], and
because even then, on most page views, readyState="loaded" is never fired.
Instead, usually the event is skipped by IE and the first and only readyState
event is readyState="complete".

[1] The conditions are: A relatively short HTML page, with a script from
<script async href=".."> that in turn appends a dynamic script tag, where
the <script async> is followed by a <link rel=stylesheet> that is relatively
large/complex (possibly due to use of cross-domain @imports, not sure).

[2] https://connect.microsoft.com/IE/feedback/details/729164/ie10-dynamic-script-element-fires-loaded-readystate-prematurely

Bug: T178943
Change-Id: Id3de61515e4701a7ef59e4a4d8643a0e09f8f589

resources/src/startup.js

index d672d76..e8585c3 100644 (file)
@@ -155,14 +155,12 @@ window.isCompatible = function ( str ) {
 
        script = document.createElement( 'script' );
        script.src = $VARS.baseModulesUri;
-       script.onload = script.onreadystatechange = function () {
-               if ( !script.readyState || /loaded|complete/.test( script.readyState ) ) {
-                       // Clean up
-                       script.onload = script.onreadystatechange = null;
-                       script = null;
-                       // Callback
-                       startUp();
-               }
+       script.onload = function () {
+               // Clean up
+               script.onload = null;
+               script = null;
+               // Callback
+               startUp();
        };
        document.getElementsByTagName( 'head' )[ 0 ].appendChild( script );
 }() );