Skip to content

Commit

Permalink
added IE10 and IE6 fixes from 0.6.8
Browse files Browse the repository at this point in the history
  • Loading branch information
unscriptable committed Oct 9, 2012
1 parent b0023ed commit a9c4cc4
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 79 deletions.
29 changes: 16 additions & 13 deletions src/curl.js
Expand Up @@ -9,29 +9,30 @@
* Licensed under the MIT License at:
* http://www.opensource.org/licenses/mit-license.php
*
* @version 0.6.2
*/
(function (global) {

var
version = '0.6.2',
version = '0.6.2a',
userCfg = global['curl'],
doc = global.document,
head = doc && (doc['head'] || doc.getElementsByTagName('head')[0]),
// // constants / flags
// to keep IE from crying, we need to put scripts before any
// <base> elements, but after any <meta>. this should do it:
insertBeforeEl = head && head.getElementsByTagName('base')[0] || null,
// constants / flags
msgUsingExports = {},
msgFactoryExecuted = {},
interactive = {},
// this is the list of scripts that IE is loading. one of these will
// be the "interactive" script. too bad IE doesn't send a readystatechange
// event to tell us exactly which one.
activeScripts = {},
// readyStates for IE6-9
readyStates = 'addEventListener' in global ? {} : { 'loaded': 1, 'complete': 1 },
// these are always handy :)
cleanPrototype = {},
toString = cleanPrototype.toString,
undef,
// script ready states that signify it's loaded
readyStates = { 'loaded': 1, 'interactive': interactive, 'complete': 1 },
// local cache of resource definitions (lightweight promises)
cache = {},
// preload are files that must be loaded before any others
Expand Down Expand Up @@ -230,7 +231,7 @@
function toUrl (n) {
// even though internally, we don't seem to need to do
// toAbsId, the AMD spec says we need to do this for plugins.
// also, thesec states that we should not append an extension
// also, the spec states that we should not append an extension
// in this function.
return core.resolvePathInfo(toAbsId(n), cfg).url;
}
Expand Down Expand Up @@ -517,6 +518,9 @@
function process (ev) {
ev = ev || global.event;
// detect when it's done loading
// ev.type == 'load' is for all browsers except IE6-9
// IE6-9 need to use onreadystatechange and look for
// el.readyState in {loaded, complete} (yes, we need both)
if (ev.type == 'load' || readyStates[el.readyState]) {
delete activeScripts[def.id];
// release event listeners
Expand Down Expand Up @@ -547,9 +551,8 @@
// IE will load the script sync if it's in the cache, so
// indicate the current resource definition if this happens.
activeScripts[def.id] = el;
// use insertBefore to keep IE from throwing Operation Aborted (thx Bryan Forbes!)
head.insertBefore(el, head.firstChild);

head.insertBefore(el, insertBeforeEl);
},

extractCjsDeps: function (defFunc) {
Expand All @@ -569,7 +572,7 @@
else if (!currQuote) {
ids.push(id);
}
return m; // uses least RAM/CPU
return ''; // uses least RAM/CPU
});
return ids;
},
Expand Down Expand Up @@ -683,7 +686,7 @@
// signal any waiters/parents that we can export
// early (see progress callback in getDep below).
// note: this may fire for `require` as well, if it
// is listed after `module` or `exports` in teh deps list,
// is listed after `module` or `exports` in the deps list,
// but that is okay since all waiters will only record
// it once.
if (parentDef.exports) {
Expand Down Expand Up @@ -906,15 +909,15 @@
},

getCurrentDefName: function () {
// IE marks the currently executing thread as "interactive"
// IE6-9 mark the currently executing thread as "interactive"
// Note: Opera lies about which scripts are "interactive", so we
// just have to test for it. Opera provides a true browser test, not
// a UA sniff, thankfully.
// learned this trick from James Burke's RequireJS
var def;
if (!isType(global.opera, 'Opera')) {
for (var d in activeScripts) {
if (readyStates[activeScripts[d].readyState] == interactive) {
if (activeScripts[d].readyState == 'interactive') {
def = d;
break;
}
Expand Down
101 changes: 35 additions & 66 deletions src/curl/plugin/js.js
Expand Up @@ -28,14 +28,12 @@
* http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
*
*/
(function (global, doc) {
(function (global, doc, testGlobalVar) {
define(/*=='js',==*/ ['curl/_privileged'], function (priv) {
"use strict";
var cache = {},
queue = [],
supportsAsyncFalse = doc && doc.createElement('script').async == true,
readyStates = { 'loaded': 1, 'interactive': 1, 'complete': 1 },
orsc = 'onreadystatechange',
head = doc && (doc['head'] || doc.getElementsByTagName('head')[0]),
waitForOrderedScript,
undef;

Expand All @@ -44,43 +42,31 @@
name + '.' + defaultExt : name;
}

// TODO: find a way to reuse the loadScript from curl.js
function loadScript (def, success, failure) {
// script processing rules learned from RequireJS

var deadline, el;
var deadline, completed, el;

// default deadline is very far in the future (5 min)
// devs should set something reasonable if they want to use it
deadline = new Date().valueOf() + (def.timeoutMsec || 300) * 1000;

// insert script
el = doc.createElement('script');
deadline = new Date().valueOf() + (def.timeoutMsec || 300000);

// initial script processing
function process (ev) {
ev = ev || global.event;
// detect when it's done loading
if (ev.type == 'load' || readyStates[el.readyState]) {
// release event listeners
el.onload = el[orsc] = el.onerror = "";
if (def.exports) def.resolved = testGlobalVar(def.exports);
if (!def.exports || def.resolved) {
success(el);
}
else {
fail();
}
function process () {
completed = true;
if (def.exports) def.resolved = testGlobalVar(def.exports);
if (!def.exports || def.resolved) {
success(el); // pass el so it can be removed (text/cache)
}
else {
failure();
}
}

function fail () {
// some browsers send an event, others send a string,
// but none of them send anything useful, so just say we failed:
el.onload = el[orsc] = el.onerror = "";
if (failure) {
failure(new Error('Script error or http error: ' + def.url));
}
function fail (ex) {
// Exception is squashed by curl.js unfortunately
completed = true;
failure(ex);
}

// some browsers (Opera and IE6-8) don't support onerror and don't fire
Expand All @@ -89,31 +75,19 @@
// is defined (see below)
function poller () {
// if the script loaded
if (el.onload && readyStates[el.readyState]) {
process({});
}
// if neither process or fail as run and our deadline is in the past
else if (el.onload && deadline < new Date()) {
fail();
}
else {
setTimeout(poller, 10);
if (!completed) {
// if neither process or fail as run and our deadline is in the past
if (deadline < new Date()) {
failure();
}
else {
setTimeout(poller, 10);
}
}
}
if (failure && def.exports) setTimeout(poller, 10);

// set type first since setting other properties could
// prevent us from setting this later
el.type = def.mimetype || 'text/javascript';
// using dom0 event handlers instead of wordy w3c/ms
el.onload = el[orsc] = process;
el.onerror = fail;
el.charset = def.charset || 'utf-8';
el.async = !def.order;
el.src = def.url;

// use insertBefore to keep IE from throwing Operation Aborted (thx Bryan Forbes!)
head.insertBefore(el, head.firstChild);
el = priv['core'].loadScript(def, process, fail);

}

Expand All @@ -137,16 +111,7 @@

}

function testGlobalVar (varName) {
try {
return eval('global.' + varName);
}
catch (ex) {
return undef;
}
}

define(/*=='js',==*/ {
return {

// the !options force us to cache ids in the plugin
'dynamic': true,
Expand Down Expand Up @@ -194,8 +159,8 @@
def.mimetype = 'text/cache';
loadScript(def,
// remove the fake script when loaded
function (el) { el.parentNode.removeChild(el); },
false
function (el) { el && el.parentNode.removeChild(el); },
function () {}
);
def.mimetype = '';
}
Expand All @@ -209,6 +174,10 @@

}

});

}(this, this.document));
};
});
}(
this,
this.document,
function () { try { return eval(arguments[0]); } catch (ex) { return; } }
));

0 comments on commit a9c4cc4

Please sign in to comment.