PageRenderTime 43ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/blanketRequire.js

https://github.com/geekdave/blanket
JavaScript | 328 lines | 276 code | 14 blank | 38 comment | 58 complexity | b98c42aa81a8da2831c8f6e7d36934d0 MD5 | raw file
Possible License(s): MIT
  1. (function(_blanket){
  2. _blanket.extend({
  3. utils: {
  4. normalizeBackslashes: function(str) {
  5. return str.replace(/\\/g, '/');
  6. },
  7. matchPatternAttribute: function(filename,pattern){
  8. if (typeof pattern === 'string'){
  9. if (pattern.indexOf("[") === 0){
  10. //treat as array
  11. var pattenArr = pattern.slice(1,pattern.length-1).split(",");
  12. return pattenArr.some(function(elem){
  13. return _blanket.utils.matchPatternAttribute(filename,_blanket.utils.normalizeBackslashes(elem.slice(1,-1)));
  14. //return filename.indexOf(_blanket.utils.normalizeBackslashes(elem.slice(1,-1))) > -1;
  15. });
  16. }else if ( pattern.indexOf("//") === 0){
  17. var ex = pattern.slice(2,pattern.lastIndexOf('/'));
  18. var mods = pattern.slice(pattern.lastIndexOf('/')+1);
  19. var regex = new RegExp(ex,mods);
  20. return regex.test(filename);
  21. }else if (pattern.indexOf("#") === 0){
  22. return window[pattern.slice(1)].call(window,filename);
  23. }else{
  24. return filename.indexOf(_blanket.utils.normalizeBackslashes(pattern)) > -1;
  25. }
  26. }else if ( pattern instanceof Array ){
  27. return pattern.some(function(elem){
  28. return _blanket.utils.matchPatternAttribute(filename,elem);
  29. });
  30. }else if (pattern instanceof RegExp){
  31. return pattern.test(filename);
  32. }else if (typeof pattern === "function"){
  33. return pattern.call(window,filename);
  34. }
  35. },
  36. blanketEval: function(data){
  37. _blanket._addScript(data);
  38. },
  39. collectPageScripts: function(){
  40. var toArray = Array.prototype.slice;
  41. var scripts = toArray.call(document.scripts);
  42. var selectedScripts=[],scriptNames=[];
  43. var filter = _blanket.options("filter");
  44. if(filter != null){
  45. //global filter in place, data-cover-only
  46. var antimatch = _blanket.options("antifilter");
  47. selectedScripts = toArray.call(document.scripts)
  48. .filter(function(s){
  49. return toArray.call(s.attributes).filter(function(sn){
  50. return sn.nodeName === "src" && _blanket.utils.matchPatternAttribute(sn.nodeValue,filter) &&
  51. (typeof antimatch === "undefined" || !_blanket.utils.matchPatternAttribute(sn.nodeValue,antimatch));
  52. }).length === 1;
  53. });
  54. }else{
  55. selectedScripts = toArray.call(document.querySelectorAll("script[data-cover]"));
  56. }
  57. scriptNames = selectedScripts.map(function(s){
  58. return _blanket.utils.qualifyURL(
  59. toArray.call(s.attributes).filter(
  60. function(sn){
  61. return sn.nodeName === "src";
  62. })[0].nodeValue).replace(".js","");
  63. });
  64. if (!filter){
  65. _blanket.options("filter","['"+scriptNames.join("','")+"']");
  66. }
  67. return scriptNames;
  68. },
  69. loadAll: function(nextScript,cb,preprocessor){
  70. /**
  71. * load dependencies
  72. * @param {nextScript} factory for priority level
  73. * @param {cb} the done callback
  74. */
  75. var currScript=nextScript();
  76. var isLoaded = _blanket.utils.scriptIsLoaded(
  77. currScript,
  78. _blanket.utils.ifOrdered,
  79. nextScript,
  80. cb
  81. );
  82. if (!(_blanket.utils.cache[currScript] && _blanket.utils.cache[currScript].loaded)){
  83. var attach = function(){
  84. if (_blanket.options("debug")) {console.log("BLANKET-Mark script:"+currScript+", as loaded and move to next script.");}
  85. isLoaded();
  86. };
  87. var whenDone = function(result){
  88. if (_blanket.options("debug")) {console.log("BLANKET-File loading finished");}
  89. if (typeof result !== 'undefined'){
  90. if (_blanket.options("debug")) {console.log("BLANKET-Add file to DOM.");}
  91. _blanket._addScript(result);
  92. }
  93. attach();
  94. };
  95. _blanket.utils.attachScript(
  96. {
  97. url: currScript
  98. },
  99. function (content){
  100. _blanket.utils.processFile(
  101. content,
  102. currScript,
  103. whenDone,
  104. whenDone
  105. );
  106. }
  107. );
  108. }else{
  109. isLoaded();
  110. }
  111. },
  112. attachScript: function(options,cb){
  113. var timeout = _blanket.options("timeout") || 3000;
  114. setTimeout(function(){
  115. if (!_blanket.utils.cache[options.url].loaded){
  116. throw new Error("error loading source script");
  117. }
  118. },timeout);
  119. _blanket.utils.getFile(
  120. options.url,
  121. cb,
  122. function(){ throw new Error("error loading source script");}
  123. );
  124. },
  125. ifOrdered: function(nextScript,cb){
  126. /**
  127. * ordered loading callback
  128. * @param {nextScript} factory for priority level
  129. * @param {cb} the done callback
  130. */
  131. var currScript = nextScript(true);
  132. if (currScript){
  133. _blanket.utils.loadAll(nextScript,cb);
  134. }else{
  135. cb(new Error("Error in loading chain."));
  136. }
  137. },
  138. scriptIsLoaded: function(url,orderedCb,nextScript,cb){
  139. /**
  140. * returns a callback that checks a loading list to see if a script is loaded.
  141. * @param {orderedCb} callback if ordered loading is being done
  142. * @param {nextScript} factory for next priority level
  143. * @param {cb} the done callback
  144. */
  145. if (_blanket.options("debug")) {console.log("BLANKET-Returning function");}
  146. return function(){
  147. if (_blanket.options("debug")) {console.log("BLANKET-Marking file as loaded: "+url);}
  148. _blanket.utils.cache[url].loaded=true;
  149. if (_blanket.utils.allLoaded()){
  150. if (_blanket.options("debug")) {console.log("BLANKET-All files loaded");}
  151. cb();
  152. }else if (orderedCb){
  153. //if it's ordered we need to
  154. //traverse down to the next
  155. //priority level
  156. if (_blanket.options("debug")) {console.log("BLANKET-Load next file.");}
  157. orderedCb(nextScript,cb);
  158. }
  159. };
  160. },
  161. cache: {},
  162. allLoaded: function (){
  163. /**
  164. * check if depdencies are loaded in cache
  165. */
  166. var cached = Object.keys(_blanket.utils.cache);
  167. for (var i=0;i<cached.length;i++){
  168. if (!_blanket.utils.cache[cached[i]].loaded){
  169. return false;
  170. }
  171. }
  172. return true;
  173. },
  174. processFile: function (content,url,cb,oldCb) {
  175. var match = _blanket.options("filter");
  176. //we check the never matches first
  177. var antimatch = _blanket.options("antifilter");
  178. if (typeof antimatch !== "undefined" &&
  179. _blanket.utils.matchPatternAttribute(url.replace(/\.js$/,""),antimatch)
  180. ){
  181. oldCb(content);
  182. if (_blanket.options("debug")) {console.log("BLANKET-File will never be instrumented:"+url);}
  183. _blanket.requiringFile(url,true);
  184. }else if (_blanket.utils.matchPatternAttribute(url.replace(/\.js$/,""),match)){
  185. if (_blanket.options("debug")) {console.log("BLANKET-Attempting instrument of:"+url);}
  186. _blanket.instrument({
  187. inputFile: content,
  188. inputFileName: url
  189. },function(instrumented){
  190. try{
  191. if (_blanket.options("debug")) {console.log("BLANKET-instrument of:"+url+" was successfull.");}
  192. _blanket.utils.blanketEval(instrumented);
  193. cb();
  194. _blanket.requiringFile(url,true);
  195. }
  196. catch(err){
  197. if (_blanket.options("ignoreScriptError")){
  198. //we can continue like normal if
  199. //we're ignoring script errors,
  200. //but otherwise we don't want
  201. //to completeLoad or the error might be
  202. //missed.
  203. if (_blanket.options("debug")) { console.log("BLANKET-There was an error loading the file:"+url); }
  204. cb(content);
  205. _blanket.requiringFile(url,true);
  206. }else{
  207. throw new Error("Error parsing instrumented code: "+err);
  208. }
  209. }
  210. });
  211. }else{
  212. if (_blanket.options("debug")) { console.log("BLANKET-Loading (without instrumenting) the file:"+url);}
  213. oldCb(content);
  214. _blanket.requiringFile(url,true);
  215. }
  216. },
  217. createXhr: function(){
  218. var xhr, i, progId;
  219. if (typeof XMLHttpRequest !== "undefined") {
  220. return new XMLHttpRequest();
  221. } else if (typeof ActiveXObject !== "undefined") {
  222. for (i = 0; i < 3; i += 1) {
  223. progId = progIds[i];
  224. try {
  225. xhr = new ActiveXObject(progId);
  226. } catch (e) {}
  227. if (xhr) {
  228. progIds = [progId]; // so faster next time
  229. break;
  230. }
  231. }
  232. }
  233. return xhr;
  234. },
  235. getFile: function(url, callback, errback, onXhr){
  236. var foundInSession = false;
  237. if (_blanket.blanketSession){
  238. var files = Object.keys(_blanket.blanketSession);
  239. for (var i=0; i<files.length;i++ ){
  240. var key = files[i];
  241. if (url.indexOf(key) > -1){
  242. callback(_blanket.blanketSession[key]);
  243. foundInSession=true;
  244. return;
  245. }
  246. }
  247. }
  248. if (!foundInSession){
  249. var xhr = _blanket.utils.createXhr();
  250. xhr.open('GET', url, true);
  251. //Allow overrides specified in config
  252. if (onXhr) {
  253. onXhr(xhr, url);
  254. }
  255. xhr.onreadystatechange = function (evt) {
  256. var status, err;
  257. //Do not explicitly handle errors, those should be
  258. //visible via console output in the browser.
  259. if (xhr.readyState === 4) {
  260. status = xhr.status;
  261. if ((status > 399 && status < 600) /*||
  262. (status === 0 &&
  263. navigator.userAgent.toLowerCase().indexOf('firefox') > -1)
  264. */ ) {
  265. //An http 4xx or 5xx error. Signal an error.
  266. err = new Error(url + ' HTTP status: ' + status);
  267. err.xhr = xhr;
  268. errback(err);
  269. } else {
  270. callback(xhr.responseText);
  271. }
  272. }
  273. };
  274. try{
  275. xhr.send(null);
  276. }catch(e){
  277. if (e.code && (e.code === 101 || e.code === 1012) && _blanket.options("ignoreCors") === false){
  278. //running locally and getting error from browser
  279. _blanket.showManualLoader();
  280. } else {
  281. throw e;
  282. }
  283. }
  284. }
  285. }
  286. }
  287. });
  288. (function(){
  289. var require = blanket.options("commonJS") ? blanket._commonjs.require : window.require;
  290. var requirejs = blanket.options("commonJS") ? blanket._commonjs.requirejs : window.requirejs;
  291. if (!_blanket.options("engineOnly") && _blanket.options("existingRequireJS")){
  292. _blanket.utils.oldloader = requirejs.load;
  293. requirejs.load = function (context, moduleName, url) {
  294. _blanket.requiringFile(url);
  295. _blanket.utils.getFile(url,
  296. function(content){
  297. _blanket.utils.processFile(
  298. content,
  299. url,
  300. function newLoader(){
  301. context.completeLoad(moduleName);
  302. },
  303. function oldLoader(){
  304. _blanket.utils.oldloader(context, moduleName, url);
  305. }
  306. );
  307. }, function (err) {
  308. _blanket.requiringFile();
  309. throw err;
  310. });
  311. };
  312. }
  313. })();
  314. })(blanket);