1- /*!
2- * A.getJS v1.0
3- * http://www.artzstudio.com/A.js/getJS/
4- *
5- * Developed by:
6- * - Dave Artz http://www.artzstudio.com/
7- *
8- * Copyright (c) 2010
9- * Not yet licensed cuz I lack free time.
10- */
11-
121/*
13- * A.getJS is a script that loads JavaScript asynchronously while
14- * preserving execution order via a chaining interface.
15- *
16- * @author Dave Artz
17- * @copyright (c) 2010 Dave Artz
18- */
2+ * A.getJS v0.9
3+ * http://www.artzstudio.com/A.js/getJS/
4+ *
5+ * Developed by:
6+ * - Dave Artz http://www.artzstudio.com/
7+ *
8+ * Copyright (c) 2010
9+ * Not yet licensed cuz I lack free time.
10+ */
11+
12+ /*
13+ * A.getJS is a script that loads JavaScript asynchronously while
14+ * preserving execution order via a chaining interface.
15+ *
16+ * @author Dave Artz
17+ * @copyright (c) 2010 Dave Artz
18+ */
1919( function ( document ) {
2020
21- // Artz: Consider implementing Image() for IE? Might be more bloaty.
22- // http://platform.aol.com/code/upusi/2/edit
23- function getObject ( elem , url , callback , type ) {
24-
25- var object = document . createElement ( elem ) ,
21+ function getScript ( url , callback , type ) {
22+
23+ var script = document . createElement ( "script" ) ,
2624 done = 0 ;
2725
28- object . src = object . data = url ;
29- object . type = type ;
30- object . width = object . height = 0 ;
26+ script . src = url ;
27+ script . type = type || "" ; // Assumes text/javascript.
28+
29+ // This is for Firefox 4
30+ // https://developer.mozilla.org/En/HTML/Element/Script
31+ // We basically make it synchronously like in FF3.
32+ // Not ideal, but we found <object> to be slower
33+ // DOM nodes.
34+ script . async = false ;
3135
3236 // Attach handlers for all browsers
33- object [ strOnLoad ] = object [ strOnReadyStateChange ] = function ( ) {
34-
35- if ( ! done && ( ! object [ strReadyState ] ||
36- object [ strReadyState ] == "loaded" || object [ strReadyState ] == "complete" ) ) {
37-
37+ script [ strOnLoad ] = script [ strOnReadyStateChange ] = function ( ) {
38+
39+ if ( ! done && ( ! script [ strReadyState ] ||
40+ script [ strReadyState ] == "loaded" || script [ strReadyState ] == "complete" ) ) {
41+
3842 // Tell global scripts object this script has loaded.
3943 // Set scriptDone to prevent this function from being called twice.
4044 done = 1 ;
41-
45+
4246 callback ( url ) ;
4347
4448 // Handle memory leak in IE
45- object [ strOnLoad ] = object [ strOnReadyStateChange ] = null ;
46- docElement . removeChild ( object ) ;
49+ script [ strOnLoad ] = script [ strOnReadyStateChange ] = null ;
50+ docElement . removeChild ( script ) ;
4751 }
4852 } ;
4953
50- docElement . appendChild ( object ) ;
54+ docElement . appendChild ( script ) ;
5155}
52-
56+
5357function getJS ( urlKey , urlKeyCallback ) {
58+
59+ function geckoCallback ( url ) {
60+ // If both scripts loaded, it's time to party.
61+ ++ urlCount == urlCountTotal && urlKeyCallback && urlKeyCallback ( ) ;
62+ }
63+
64+ function getJSCallback ( url ) {
65+
66+ // Remember that we have this script cached.
67+ urlCached [ url ] = 1 ;
68+
69+ // If this callback happens to be for the first urlKey
70+ // in the chain, we can trigger the execution.
71+ urlKey == urlKeyChain [ 0 ] && executeJS ( ) ;
72+ }
5473
5574 function executeJS ( ) {
5675
5776 function executeCallback ( ) {
58-
5977 // If all scripts have been cached in the set, it's time
6078 // to execute the urlKey callback after the script loads.
6179 if ( ++ cacheCount == thisUrlsCount ) {
@@ -70,77 +88,67 @@ function getJS ( urlKey, urlKeyCallback ) {
7088 }
7189
7290 for ( var i = 0 ,
73- thisUrlKey = urlKeyChain [ 0 ] || "" ,
74- thisUrls = thisUrlKey . split ( urlSplit ) ,
75- thisUrl ,
76- thisUrlsCount = thisUrls . length ,
77- thisUrlKeyCallback = urlKeyCallbacks [ thisUrlKey ] ,
78- cacheCount = 0 ; i < thisUrlsCount ; i ++ ) {
91+ thisUrlKey = urlKeyChain [ 0 ] || "" ,
92+ thisUrls = thisUrlKey . split ( urlSplit ) ,
93+ thisUrl ,
94+ thisUrlsCount = thisUrls . length ,
95+ thisUrlKeyCallback = urlKeyCallbacks [ thisUrlKey ] ,
96+ cacheCount = 0 ; i < thisUrlsCount ; i ++ ) {
7997
8098 thisUrl = thisUrls [ i ] ;
81-
99+
82100 if ( urlCached [ thisUrl ] ) {
83101 if ( urlExecuted [ thisUrl ] ) {
84102 // If we already executed, just do the callback.
85103 executeCallback ( ) ;
86104 } else {
87105 // Rememeber that this script already executed.
88106 urlExecuted [ thisUrl ] = 1 ;
89- type = "" ; // Clear out the type so we load normally.
90- getObject ( strScript , thisUrl , executeCallback , type ) ;
107+ getScript ( thisUrl , executeCallback ) ;
91108 }
92109 }
93110 }
94111 }
95-
96- function getJSCallback ( url ) {
97112
98- // Remember that we have this script cached.
99- urlCached [ url ] = 1 ;
100-
101- // If this callback happens to be for the first urlKey
102- // in the chain, we can trigger the execution.
103- urlKey == urlKeyChain [ 0 ] && executeJS ( ) ;
104- }
105-
106113 var urls = urlKey . split ( urlSplit ) ,
114+ urlCount = 0 ,
107115 urlCountTotal = urls . length ,
108116 i = 0 ,
109- elem = strScript ,
110117 type ,
111118 urlKeyChain = this . c ; // Contains an arays of urlKeys of this chain, if available.
112119
113- // Gecko no longer does what we want out of the box.
114- // Use object instead .
120+ // Gecko does what we want out of the box, sort of .
121+ // Bypass our super special callback .
115122 if ( isGecko ) {
116123
117- elem = "object" ;
124+ getJSCallback = geckoCallback ;
118125
119126 // Manage callbacks and execution order manually.
120127 } else {
121-
128+
122129 // We set this to something bogus so browsers do not
123130 // execute code on our initial request.
124131 // http://ejohn.org/blog/javascript-micro-templating/
125132 type = "c" ;
133+
134+ // If this is a new chain, start a new array, otherwise push the new guy in.
135+ // This is used to preserve execution order for non FF browsers.
136+ if ( urlKeyChain ) {
137+ // Push the urlKey into the chain.
138+ urlKeyChain . push ( urlKey ) ;
139+ } else {
140+ // Create a new urlKeyChain to pass on to others.
141+ urlKeyChain = [ urlKey ] ;
142+ }
143+
144+ // Remember the original callback for this key for later.
145+ urlKeyCallbacks [ urlKey ] = urlKeyCallback ;
126146 }
127-
128- // If this is a new chain, start a new array, otherwise push the new guy in.
129- // This is used to preserve execution order for non FF browsers.
130- if ( urlKeyChain ) {
131- // Push the urlKey into the chain.
132- urlKeyChain . push ( urlKey ) ;
133- } else {
134- // Create a new urlKeyChain to pass on to others.
135- urlKeyChain = [ urlKey ] ;
136- }
137-
138- // Remember the original callback for this key for later.
139- urlKeyCallbacks [ urlKey ] = urlKeyCallback ;
147+
140148 // Cache the scripts requested.
141149 for ( ; i < urlCountTotal ; i ++ ) {
142150 // Fetch the script.
143- getObject ( elem , urls [ i ] , getJSCallback , type ) ;
151+ getScript ( urls [ i ] , getJSCallback , type ) ;
144152 }
145153
146154 return {
@@ -150,14 +158,13 @@ function getJS ( urlKey, urlKeyCallback ) {
150158}
151159
152160var docElement = document . documentElement ,
153- // Artz: Just making things smaller, uncomment if people care.
154- // head = document.getElementsByTagName("head")[0] || docElement,
161+ // Artz: Just making things smaller, uncomment if people care.
162+ // head = document.getElementsByTagName("head")[0] || docElement,
155163 urlKeyCallbacks = { } ,
156164 urlCached = { } ,
157165 urlExecuted = { } ,
158166 urlSplit = "," ,
159167
160- strScript = "script" ,
161168 strReadyState = "readyState" ,
162169 strOnReadyStateChange = "onreadystatechange" ,
163170 strOnLoad = "onload" ,
0 commit comments