[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 /** 2 * @provides javelin-resource 3 * @requires javelin-util 4 * javelin-uri 5 * javelin-install 6 * 7 * @javelin 8 */ 9 10 JX.install('Resource', { 11 12 statics: { 13 14 _loading: {}, 15 _loaded: {}, 16 _links: [], 17 _callbacks: [], 18 19 /** 20 * Loads one or many static resources (JavaScript or CSS) and executes a 21 * callback once these resources have finished loading. 22 * 23 * @param string|array static resource or list of resources to be loaded 24 * @param function callback when resources have finished loading 25 */ 26 load: function(list, callback) { 27 var resources = {}, 28 uri, resource, path, type; 29 30 list = JX.$AX(list); 31 32 // In the event there are no resources to wait on, call the callback and 33 // exit. NOTE: it's better to do this check outside this function and not 34 // call through JX.Resource, but it's not always easy/possible to do so 35 if (!list.length) { 36 setTimeout(callback, 0); 37 return; 38 } 39 40 for (var ii = 0; ii < list.length; ii++) { 41 uri = new JX.URI(list[ii]); 42 resource = uri.toString(); 43 path = uri.getPath(); 44 resources[resource] = true; 45 46 if (JX.Resource._loaded[resource]) { 47 setTimeout(JX.bind(JX.Resource, JX.Resource._complete, resource), 0); 48 } else if (!JX.Resource._loading[resource]) { 49 JX.Resource._loading[resource] = true; 50 if (path.indexOf('.css') == path.length - 4) { 51 JX.Resource._loadCSS(resource); 52 } else { 53 JX.Resource._loadJS(resource); 54 } 55 } 56 } 57 58 JX.Resource._callbacks.push({ 59 resources: resources, 60 callback: callback 61 }); 62 }, 63 64 _loadJS: function(uri) { 65 var script = document.createElement('script'); 66 var load_callback = function() { 67 JX.Resource._complete(uri); 68 }; 69 var error_callback = function() { 70 JX.$E('Resource: JS file download failure: ' + uri); 71 }; 72 73 JX.copy(script, { 74 type: 'text/javascript', 75 src: uri 76 }); 77 78 script.onload = load_callback; 79 script.onerror = error_callback; 80 script.onreadystatechange = function() { 81 var state = this.readyState; 82 if (state == 'complete' || state == 'loaded') { 83 load_callback(); 84 } 85 }; 86 document.getElementsByTagName('head')[0].appendChild(script); 87 }, 88 89 _loadCSS: function(uri) { 90 var link = JX.copy(document.createElement('link'), { 91 type: 'text/css', 92 rel: 'stylesheet', 93 href: uri, 94 'data-href': uri // don't trust href 95 }); 96 document.getElementsByTagName('head')[0].appendChild(link); 97 98 JX.Resource._links.push(link); 99 if (!JX.Resource._timer) { 100 JX.Resource._timer = setInterval(JX.Resource._poll, 20); 101 } 102 }, 103 104 _poll: function() { 105 var sheets = document.styleSheets, 106 ii = sheets.length, 107 links = JX.Resource._links; 108 109 // Cross Origin CSS loading 110 // http://yearofmoo.com/2011/03/cross-browser-stylesheet-preloading/ 111 while (ii--) { 112 var link = sheets[ii], 113 owner = link.ownerNode || link.owningElement, 114 jj = links.length; 115 if (owner) { 116 while (jj--) { 117 if (owner == links[jj]) { 118 JX.Resource._complete(links[jj]['data-href']); 119 links.splice(jj, 1); 120 } 121 } 122 } 123 } 124 125 if (!links.length) { 126 clearInterval(JX.Resource._timer); 127 JX.Resource._timer = null; 128 } 129 }, 130 131 _complete: function(uri) { 132 var list = JX.Resource._callbacks, 133 current, ii; 134 135 delete JX.Resource._loading[uri]; 136 JX.Resource._loaded[uri] = true; 137 138 var errors = []; 139 for (ii = 0; ii < list.length; ii++) { 140 current = list[ii]; 141 delete current.resources[uri]; 142 if (!JX.Resource._hasResources(current.resources)) { 143 try { 144 current.callback(); 145 } catch (error) { 146 errors.push(error); 147 } 148 list.splice(ii--, 1); 149 } 150 } 151 152 if (errors.length) { 153 throw errors[0]; 154 } 155 }, 156 157 _hasResources: function(resources) { 158 for (var hasResources in resources) { 159 return true; 160 } 161 return false; 162 } 163 164 }, 165 166 initialize: function() { 167 var list = JX.$A(document.getElementsByTagName('link')), 168 ii = list.length, 169 node; 170 while ((node = list[--ii])) { 171 if (node.type == 'text/css' && node.href) { 172 JX.Resource._loaded[(new JX.URI(node.href)).toString()] = true; 173 } 174 } 175 176 list = JX.$A(document.getElementsByTagName('script')); 177 ii = list.length; 178 while ((node = list[--ii])) { 179 if (node.type == 'text/javascript' && node.src) { 180 JX.Resource._loaded[(new JX.URI(node.src)).toString()] = true; 181 } 182 } 183 } 184 185 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |