/src/blanketRequire.js
JavaScript | 328 lines | 276 code | 14 blank | 38 comment | 58 complexity | b98c42aa81a8da2831c8f6e7d36934d0 MD5 | raw file
Possible License(s): MIT
- (function(_blanket){
- _blanket.extend({
- utils: {
- normalizeBackslashes: function(str) {
- return str.replace(/\\/g, '/');
- },
- matchPatternAttribute: function(filename,pattern){
- if (typeof pattern === 'string'){
- if (pattern.indexOf("[") === 0){
- //treat as array
- var pattenArr = pattern.slice(1,pattern.length-1).split(",");
- return pattenArr.some(function(elem){
- return _blanket.utils.matchPatternAttribute(filename,_blanket.utils.normalizeBackslashes(elem.slice(1,-1)));
- //return filename.indexOf(_blanket.utils.normalizeBackslashes(elem.slice(1,-1))) > -1;
- });
- }else if ( pattern.indexOf("//") === 0){
- var ex = pattern.slice(2,pattern.lastIndexOf('/'));
- var mods = pattern.slice(pattern.lastIndexOf('/')+1);
- var regex = new RegExp(ex,mods);
- return regex.test(filename);
- }else if (pattern.indexOf("#") === 0){
- return window[pattern.slice(1)].call(window,filename);
- }else{
- return filename.indexOf(_blanket.utils.normalizeBackslashes(pattern)) > -1;
- }
- }else if ( pattern instanceof Array ){
- return pattern.some(function(elem){
- return _blanket.utils.matchPatternAttribute(filename,elem);
- });
- }else if (pattern instanceof RegExp){
- return pattern.test(filename);
- }else if (typeof pattern === "function"){
- return pattern.call(window,filename);
- }
- },
- blanketEval: function(data){
- _blanket._addScript(data);
- },
- collectPageScripts: function(){
- var toArray = Array.prototype.slice;
- var scripts = toArray.call(document.scripts);
- var selectedScripts=[],scriptNames=[];
- var filter = _blanket.options("filter");
- if(filter != null){
- //global filter in place, data-cover-only
- var antimatch = _blanket.options("antifilter");
- selectedScripts = toArray.call(document.scripts)
- .filter(function(s){
- return toArray.call(s.attributes).filter(function(sn){
- return sn.nodeName === "src" && _blanket.utils.matchPatternAttribute(sn.nodeValue,filter) &&
- (typeof antimatch === "undefined" || !_blanket.utils.matchPatternAttribute(sn.nodeValue,antimatch));
- }).length === 1;
- });
- }else{
- selectedScripts = toArray.call(document.querySelectorAll("script[data-cover]"));
- }
- scriptNames = selectedScripts.map(function(s){
- return _blanket.utils.qualifyURL(
- toArray.call(s.attributes).filter(
- function(sn){
- return sn.nodeName === "src";
- })[0].nodeValue).replace(".js","");
- });
- if (!filter){
- _blanket.options("filter","['"+scriptNames.join("','")+"']");
- }
- return scriptNames;
- },
- loadAll: function(nextScript,cb,preprocessor){
- /**
- * load dependencies
- * @param {nextScript} factory for priority level
- * @param {cb} the done callback
- */
- var currScript=nextScript();
- var isLoaded = _blanket.utils.scriptIsLoaded(
- currScript,
- _blanket.utils.ifOrdered,
- nextScript,
- cb
- );
-
- if (!(_blanket.utils.cache[currScript] && _blanket.utils.cache[currScript].loaded)){
- var attach = function(){
- if (_blanket.options("debug")) {console.log("BLANKET-Mark script:"+currScript+", as loaded and move to next script.");}
- isLoaded();
- };
- var whenDone = function(result){
- if (_blanket.options("debug")) {console.log("BLANKET-File loading finished");}
- if (typeof result !== 'undefined'){
- if (_blanket.options("debug")) {console.log("BLANKET-Add file to DOM.");}
- _blanket._addScript(result);
- }
- attach();
- };
- _blanket.utils.attachScript(
- {
- url: currScript
- },
- function (content){
- _blanket.utils.processFile(
- content,
- currScript,
- whenDone,
- whenDone
- );
- }
- );
- }else{
- isLoaded();
- }
- },
- attachScript: function(options,cb){
- var timeout = _blanket.options("timeout") || 3000;
- setTimeout(function(){
- if (!_blanket.utils.cache[options.url].loaded){
- throw new Error("error loading source script");
- }
- },timeout);
- _blanket.utils.getFile(
- options.url,
- cb,
- function(){ throw new Error("error loading source script");}
- );
- },
- ifOrdered: function(nextScript,cb){
- /**
- * ordered loading callback
- * @param {nextScript} factory for priority level
- * @param {cb} the done callback
- */
- var currScript = nextScript(true);
- if (currScript){
- _blanket.utils.loadAll(nextScript,cb);
- }else{
- cb(new Error("Error in loading chain."));
- }
- },
- scriptIsLoaded: function(url,orderedCb,nextScript,cb){
- /**
- * returns a callback that checks a loading list to see if a script is loaded.
- * @param {orderedCb} callback if ordered loading is being done
- * @param {nextScript} factory for next priority level
- * @param {cb} the done callback
- */
- if (_blanket.options("debug")) {console.log("BLANKET-Returning function");}
- return function(){
- if (_blanket.options("debug")) {console.log("BLANKET-Marking file as loaded: "+url);}
-
- _blanket.utils.cache[url].loaded=true;
-
- if (_blanket.utils.allLoaded()){
- if (_blanket.options("debug")) {console.log("BLANKET-All files loaded");}
- cb();
- }else if (orderedCb){
- //if it's ordered we need to
- //traverse down to the next
- //priority level
- if (_blanket.options("debug")) {console.log("BLANKET-Load next file.");}
- orderedCb(nextScript,cb);
- }
- };
- },
- cache: {},
- allLoaded: function (){
- /**
- * check if depdencies are loaded in cache
- */
- var cached = Object.keys(_blanket.utils.cache);
- for (var i=0;i<cached.length;i++){
- if (!_blanket.utils.cache[cached[i]].loaded){
- return false;
- }
- }
- return true;
- },
- processFile: function (content,url,cb,oldCb) {
- var match = _blanket.options("filter");
- //we check the never matches first
- var antimatch = _blanket.options("antifilter");
- if (typeof antimatch !== "undefined" &&
- _blanket.utils.matchPatternAttribute(url.replace(/\.js$/,""),antimatch)
- ){
- oldCb(content);
- if (_blanket.options("debug")) {console.log("BLANKET-File will never be instrumented:"+url);}
- _blanket.requiringFile(url,true);
- }else if (_blanket.utils.matchPatternAttribute(url.replace(/\.js$/,""),match)){
- if (_blanket.options("debug")) {console.log("BLANKET-Attempting instrument of:"+url);}
- _blanket.instrument({
- inputFile: content,
- inputFileName: url
- },function(instrumented){
- try{
- if (_blanket.options("debug")) {console.log("BLANKET-instrument of:"+url+" was successfull.");}
- _blanket.utils.blanketEval(instrumented);
- cb();
- _blanket.requiringFile(url,true);
- }
- catch(err){
- if (_blanket.options("ignoreScriptError")){
- //we can continue like normal if
- //we're ignoring script errors,
- //but otherwise we don't want
- //to completeLoad or the error might be
- //missed.
- if (_blanket.options("debug")) { console.log("BLANKET-There was an error loading the file:"+url); }
- cb(content);
- _blanket.requiringFile(url,true);
- }else{
- throw new Error("Error parsing instrumented code: "+err);
- }
- }
- });
- }else{
- if (_blanket.options("debug")) { console.log("BLANKET-Loading (without instrumenting) the file:"+url);}
- oldCb(content);
- _blanket.requiringFile(url,true);
- }
- },
- createXhr: function(){
- var xhr, i, progId;
- if (typeof XMLHttpRequest !== "undefined") {
- return new XMLHttpRequest();
- } else if (typeof ActiveXObject !== "undefined") {
- for (i = 0; i < 3; i += 1) {
- progId = progIds[i];
- try {
- xhr = new ActiveXObject(progId);
- } catch (e) {}
- if (xhr) {
- progIds = [progId]; // so faster next time
- break;
- }
- }
- }
- return xhr;
- },
- getFile: function(url, callback, errback, onXhr){
- var foundInSession = false;
- if (_blanket.blanketSession){
- var files = Object.keys(_blanket.blanketSession);
- for (var i=0; i<files.length;i++ ){
- var key = files[i];
- if (url.indexOf(key) > -1){
- callback(_blanket.blanketSession[key]);
- foundInSession=true;
- return;
- }
- }
- }
- if (!foundInSession){
- var xhr = _blanket.utils.createXhr();
- xhr.open('GET', url, true);
- //Allow overrides specified in config
- if (onXhr) {
- onXhr(xhr, url);
- }
- xhr.onreadystatechange = function (evt) {
- var status, err;
-
- //Do not explicitly handle errors, those should be
- //visible via console output in the browser.
- if (xhr.readyState === 4) {
- status = xhr.status;
- if ((status > 399 && status < 600) /*||
- (status === 0 &&
- navigator.userAgent.toLowerCase().indexOf('firefox') > -1)
- */ ) {
- //An http 4xx or 5xx error. Signal an error.
- err = new Error(url + ' HTTP status: ' + status);
- err.xhr = xhr;
- errback(err);
- } else {
- callback(xhr.responseText);
- }
- }
- };
- try{
- xhr.send(null);
- }catch(e){
- if (e.code && (e.code === 101 || e.code === 1012) && _blanket.options("ignoreCors") === false){
- //running locally and getting error from browser
- _blanket.showManualLoader();
- } else {
- throw e;
- }
- }
- }
- }
- }
- });
- (function(){
- var require = blanket.options("commonJS") ? blanket._commonjs.require : window.require;
- var requirejs = blanket.options("commonJS") ? blanket._commonjs.requirejs : window.requirejs;
- if (!_blanket.options("engineOnly") && _blanket.options("existingRequireJS")){
- _blanket.utils.oldloader = requirejs.load;
- requirejs.load = function (context, moduleName, url) {
- _blanket.requiringFile(url);
- _blanket.utils.getFile(url,
- function(content){
- _blanket.utils.processFile(
- content,
- url,
- function newLoader(){
- context.completeLoad(moduleName);
- },
- function oldLoader(){
- _blanket.utils.oldloader(context, moduleName, url);
- }
- );
- }, function (err) {
- _blanket.requiringFile();
- throw err;
- });
- };
- }
- })();
- })(blanket);