-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdna.min.js
3 lines (3 loc) · 15.7 KB
/
dna.min.js
1
2
3
/*! Javascript DNA v1.0 | (c) Daniel Ševčík | www.webdevelopers.eu */
"use strict";if("function"!=typeof jQuery)throw new Error("DNA requires jQuery");!function($,window){function DNACore(){this.queue=[],this.configs=[],this.resources={}}function getOptsCategorize(e,r,t){var n=[$.type(e)];return $.isPlainObject(e)&&n.push("plainObject"),$.isNumeric(e)&&n.push("numeric"),$.isXMLDoc(e)&&n.push("xmlDocument"),r.some(function(o,i){return!!r[i].match.some(function(r){return getOptsMatch(e,r,n)},this)&&(r[i].recursive?$.isPlainObject(e)?$.each(e,function(e,r){t[e]||(t[e]=[]),t[e].push(r)}):$.each(e,function(e,n){getOptsCategorize(n,r,t)}.bind(this)):t[r[i].name].push(e),!0)},this)}function getOptsMatch(e,r,t){switch(typeof r){case"function":return r(e);case"object":return-1!==$.inArray("string",t)&&r.test(e);case"string":return"*"==r||-1!==$.inArray(r,t);default:$.error('Cannot parse opts. Unexpected match type "'+typeof r+'"')}return!1}function requireMulti(e,r){var t=[];try{dna.core.getOpts(e,[["names","string"],"recursive"]).names.forEach(function(e){t.push(requireSingle.call(this,e,r))}.bind(this))}catch(e){return $.Deferred().reject(new DNAError(e)).promise()}return $.when.apply(this,t)}function requireSingle(e,r){var t,n=[],o=$.Deferred();if(-1!=$.inArray(e,r)&&$.error("DNA: Recursive requirement: "+r.join(" > ")+" > "+e+" (recursion)"),t=dna.core.getConfig(e),t||$.error('DNA: Cannot satisfy the requirement "'+e+'"'),t._dfd)return t._dfd;t._dfd=o.promise(),n.push(downloadResources(t));var i=r.slice();return i.push(e),n.push(requireMulti.call(this,[t.require],i)),$.when.apply(this,n).done(function(r){var n;evaluateScripts(r,t).done(function(r){t.proto[0]&&(r?$.each(t.proto.slice(t.proto.length>1?1:0),function(e,t){install(t,r)}):o.reject(new DNAError('DNA: Cannot find the Proto object window["'+t.proto+'"]: '+JSON.stringify(t),602,{config:t}))),r&&t.service&&install(t.service,new r),t.data&&"object"==typeof r&&(void 0===dna.data[t.data]?dna.data[t.data]=r:$.isArray(dna.data[t.data])?dna.data[t.data]=dna.data[t.data].concat(r):dna.data[t.data]=$.extend(dna.data[t.data],r),n=!0),t.id==e?n=t:dna[e]&&(n=dna[e]),n?o.resolve(n):o.reject(new DNAError('DNA: Cannot find the requested object dna["'+e+'"]: '+JSON.stringify(t),603,{config:t}))}).fail(function(){o.reject.apply(this,arguments)})}).fail(function(){o.reject.apply(this,arguments)}),t._dfd}function requireConfig(e){}function downloadResources(e){var r=dna.core.getOpts(e.load,[["urls","string"],"recursive"]).urls,t=[];r.forEach(function(r){t.push(downloadResourcesSingle(r,e))});var n=$.Deferred();return $.when.apply(this,t).done(function(){for(var e=[],r=0;r<arguments.length;r++)e.push(arguments[r]);n.resolve(e)}).fail(function(){n.reject.apply(this,arguments)}),n}function evaluateScripts(e,r){function t(i){if(!i)return e.length?o.reject(new DNAError("Scripts queue is not empty and we got no data!",607,{script:i,queue:e})):o.resolve(n);var a=settings.factory[r.eval||"dna"],s=$.Deferred().done(function(r){n=r||n,t(e.shift())}).fail(function(e){o.reject(new DNAError("Evaluation of the script failed.",608,e))});if("function"!=typeof a)return s.reject(new DNAError('Unknown evaluation type "'+r.eval+'"',604,r));try{a(s,i,r.proto[0],r)}catch(e){return s.reject(new DNAError(e))}return s}var n,o=$.Deferred();return t(e.shift()),o}function downloadResourcesSingle(e,r){var t,n=$.Deferred(),o=e.match(/^https?:/),i=o?e.split("#"):[e];return t=function(t){if("function"==typeof t)return void n.resolve(t);if(1==i.length)return void n.resolve(t+(o?" //# sourceURL="+e+"#dna":""));var a=document.implementation.createHTMLDocument("html","","");a.childNodes[1].innerHTML=t;try{var s=$("#"+i[1],a);if(!s.length)throw'Bundled resource "#'+i[1]+'" not found in "'+e+'"'}catch(r){return void n.reject(new DNAError('Cannot extract resource "#'+i[1]+'" from bundle "'+e+": "+(r.message||r),609,r))}var c=$.trim(s.text());if(c.length)n.resolve(c+" //# sourceURL="+e);else if(s.attr("src")){var u=s.get(0).src||s.attr("src")||s.get(0).href||s.attr("href");u?downloadResourcesSingle(dna.core.resolveURL(u,e),r).done(function(){n.resolve.apply(this,arguments)}).fail(function(){n.reject.apply(this,arguments)}):n.reject(new DNAError('The script "'+e+'" has no contents and no reference to other external resource.',605,{script:s.get(0),source:t,url:e}))}else n.reject(404,'Cannot load script "'+e+'"')},download(i[0],r).done(t).fail(function(){n.reject.apply(this,arguments)}),n}function validateString(e,r,t){return e&&r.test(e)||$.error("DNA: "+t+" String "+JSON.stringify(e)+" does not match the pattern "+r),!0}function download(e,r){if(dna.core.resources[e])return dna.core.resources[e];var t=$.Deferred();dna.core.resources[e]=t.promise();var n=e.match(/^([a-z][a-z0-9+.-]*):/i)[1];return t.fail(function(e){new DNAError(e)}),settings.downloader[n]&&!1!==settings.downloader[n](t,e,r)||settings.downloader["*"](t,e,r),dna.core.resources[e]}function rewriteURL(e,r){var t=e;return settings.rewrite.forEach(function(n){e=n(e,t,r)||e}),e=dna.core.resolveURL(e,r)}function cleanConfigFast(e){return delete e._clean,e.proto=e.proto?e.proto.split("="):[],e}function readyConfig(e){if(e._ready)return e;delete e._dfd,e.load=dna.core.getOpts(e.load,[["urls","string"],"recursive"]).urls.map(function(r){return rewriteURL(r,e.baseURL)});var r=dna.core.getOpts(e.require,[["jsonURLs",/\//],["require","string"],"recursive"]);return e.require=r.require,r.jsonURLs.length&&(r.jsonURLs=r.jsonURLs.map(function(r){return rewriteURL(r,e.baseURL)}),dna(r.jsonURLs)),"array"!==$.type(e.require)&&(e.require=e.require?[e.require]:[]),"array"!==$.type(e.load)&&(e.load=e.load?[e.load]:[]),e.context=e.context||!1,"window"===e.context?e._context=window:e._context=e.context&&contexts[e.context]||{},e.context&&(contexts[e.context]=e._context),e._ready=!0,e}function install(e,r){dna[e]=r,installed.push(e)}function DNAError(e,r,t){e instanceof Error?(this.name=e.name||"DNAError",this.message=e.message||"Unknown Error.",this.code=e.code||700,this.detail=e.detail||e):(this.name="DNAError",this.message=e||"Ups!",this.code=r||700,this.detail=t),t instanceof DNAError||"error"==$.type(t)?this.stack=t.stack:this.stack=(new Error).stack,t instanceof DNAError||console.error("DNAError #"+this.code+": "+e,t,this.stack)}var settings={timeout:5e3,rewrite:[],downloader:{remote:function(e,r,t){var n=document.createElement("script"),o=document.getElementsByTagName("script")[0];n.type="text/javascript",n.async=!0,n.setAttribute("data-origin","Javascript DNA"),n.onload=function(){e.resolve("true /* Already executed */")},n.onerror=function(){e.reject(new Error("Failed to load: "+r))},o.parentNode.insertBefore(n,o),n.src=r.replace(/^remote:/,"")},javascript:function(e,r,t){e.resolve(r.replace(/^javascript:/,""))},json:function(e,r,t){var n=dna.core.resolveURL(r.replace(/^json:/,"").replace("'","\\'"),t.baseURL);$.getJSON(n).done(function(r){e.resolve(function(e){e.resolve(r)})}).fail(function(r,t,o){console.log("DNA: Failed to download JSON file!",n,arguments),e.reject(o)})},config:function(e,r,t){var n=dna.core.resolveURL(r.replace(/^config:/,"").replace("'","\\'")+"#dna",t.baseURL);dna(n),e.resolve("/* DNA Config Downloader Dummy */ true;")},css:function(e,r,t){for(var n=dna.core.resolveURL(r.replace(/^css:/,"").replace("'","\\'")+"#dna",t.baseURL),o=$("link[rel='stylesheet']"),i=0;i<o.length;i++)if((o[i].href||"").replace(/#.*/,"")===n.replace(/#.*/,"")){console.log("DNA: CSS is already present: "+n),e.resolve("/* Already included */ true;");break}e.resolve(function(e){var r=function(){e.resolve()},t=$('<link rel="stylesheet" data-origin="dna" type="text/css" />').attr("href",""+n);setTimeout(r,5e3),t.get(0).onload=r,t.appendTo("head")})},"*":function(e,r,t){return $.ajax({url:r,dataType:"text",cache:!0,type:"GET",async:!0,headers:{"X-Requested-With":"DNA"}}).done(function(r){e.resolve(r)}).fail(function(n,o,i){e.reject.call(this,new DNAError('Download "'+r+'" failed: '+n.status+" "+o+" "+i,606,{config:t,xhr:n,textStatus:o,error:i}))}),!0}},factory:{dna:function(dfd,toEvaluate,protoName,config){protoName=protoName||"undefined";try{if("function"==typeof toEvaluate)toEvaluate(dfd,config._context,protoName,config);else{var evalStr=toEvaluate+"\n\n/* Javascript DNA: Compat Layer */;\ntypeof "+protoName+" == 'undefined' ? undefined : "+protoName;dfd.resolve(function(context){return context==window?window.eval(evalStr):function(){return eval(evalStr)}.call(context)}(config._context))}}catch(e){var sourceURL=("string"==typeof toEvaluate&&toEvaluate.match(/\/\/#\s+sourceURL=(.+)$/)||[null,""])[1];dfd.reject(new DNAError("Failed to evaluate the script "+sourceURL+" : "+(e.message||e),610,e))}},deferred:function(factory,jString,protoName,config){!function(factory){config.context==window?window.eval(jString):eval(jString)}(factory)}}},console=window.console||{log:function(){}};console.error=console.error||console.log;var installed=[],contexts={},dna=function(){var e=arguments,r=$.Deferred().done(function(){$(window).trigger("dna:done",[{dnaArguments:e,arguments:arguments}])}).fail(function(){$(window).trigger("dna:fail",[{dnaArguments:e,arguments:arguments}])}).always(function(){$(window).trigger("dna:always",[{dnaArguments:e,arguments:arguments}])}),t=function(){r.reject.apply(this,arguments)},n=dna.core.getOpts(arguments,[{recursive:!0,match:"array"},["jsonURLs",/\//],["required","string"],["settings",function(e){return $.isPlainObject(e)&&!e.proto&&!e.id&&!e.data}],["configs","plainObject"],["callbacks","function"]]);if(n.settings.forEach(dna.core.set),n.jsonURLs.length+n.required.length+n.configs.length==0)return dna.core.checkQueue(),r.resolve().done(n.callbacks).promise();try{n.configs.forEach(dna.core.configure.bind(dna.core)),n.required.length&&$("html").is(".debug")&&console.log("DNA: Satisfying requirements: %o",n.required);var o=n.jsonURLs.map(function(e){return rewriteURL(e,null)}).filter(function(e){return!dna.core.resources[e]});$.when.apply(this,o.map(download)).done(function(){var e=$.makeArray(arguments).map(function(e,r){var t=dna.core.getOpts($.parseJSON(e),[["configs","plainObject"],"recursive",["other","*"]]);return t.configs=t.configs.map(function(e){return e.baseURL=n.jsonURLs[r],e}),[t.configs,t.other]});setTimeout(function(){var e=[];if(dna.core.canSatisfy(n.required,e),e.length){var r='DNA: Failed to satisfy the requirements "'+JSON.stringify(n.required)+'" in '+Math.round(settings.timeout/1e3)+" seconds ("+e.join(" ")+")";t(r),$.error(r)}},settings.timeout),dna(e).done(function(){dna.core.whenSatisfied(n.required).done(function(){$.when.apply(this,n.required.map(function(e){return dna.core.require(e)})).done(n.callbacks,function(){r.resolve.apply(this,arguments)}).fail(t)}).fail(t)}).fail(t)}).fail(t)}catch(e){r.reject(new DNAError(e))}return r.promise()};install("push",function(){return dna.apply(this,arguments),dna.core.queue.length}),DNACore.prototype.version="1.0",DNACore.prototype.queue=null,DNACore.prototype.configs=null,DNACore.prototype.resources=null,DNACore.prototype.resolveURL=function(){for(var e=document.implementation.createHTMLDocument("html","",""),r=e.head.appendChild(e.createElement("base")),t=e.body.appendChild(e.createElement("a")),n=location?location.href:"https://no-location-href.example.com/",o=arguments.length-1;0<=o;o--)"string"==typeof arguments[o]&&arguments[o].length&&(arguments[o].match(/^[a-z0-9+.-]+:/i)?n=arguments[o]:(r.setAttribute("href",n),t.setAttribute("href",arguments[o]),n=t.href));return n},DNACore.prototype.rewriteURL=rewriteURL,DNACore.prototype.set=function(e){$.each(e,function(e,r){switch(e){case"factory":delete r.dna,settings[e]=$.extend(settings[e],r);break;case"downloader":delete r["*"],settings[e]=$.extend(settings[e],r);break;case"rewrite":settings[e]=settings[e].concat(r);break;default:settings[e]=r}})},DNACore.prototype.configure=function(e){var r=!1;e=$.extend({},e),e.data&&(e.id||e.proto||e.service)&&$.error("The Data Config "+e.data+" must not have `id`, `proto`, or `service` properties defined: "+JSON.stringify(e)),e.id&&(r=validateString(e.id,/^[a-zA-Z0-9_:@#$*.-]+$/i,"Invalid `id` name in "+JSON.stringify(e)+".")),e.service&&(r=validateString(e.service,/^[a-zA-Z0-9_:@#$*.-]*$/,"Invalid `service` name in "+JSON.stringify(e)+".")),e.proto&&(r=validateString(e.proto,/^[A-Z][a-zA-Z0-9_]*(=[a-zA-Z0-9_:@#$*.-]+)*$/,"Invalid `proto` name in "+JSON.stringify(e)+".")),e.data&&(r=!0),r||$.error("At least one must be specified `id` or `service` or `proto` or `data` in Config "+JSON.stringify(e)),e.service&&!e.proto&&$.error('Service "'+e.service+'" requires the `proto` property: '+JSON.stringify(e)),cleanConfigFast(e),[e.id,e.service,e.data].filter(function(e){return!!e}).concat(e.proto.slice(e.proto.length>1?1:0)).forEach(function(r){var t=dna.core.getConfig(r);if(void 0===dna[r])dna[r]=null;else if(e.data&&t)e.load=t.load.concat(e.load),dna.core.configs=dna.core.configs.filter(function(e){return e.data!==r});else if(t.proto.length||t.service||t.require.length){var n=['DNA: Conflicting property `dna["'+r+'"]`.'];dna[r]&&-1==$.inArray(r,installed)?n.push('YOU MUST NOT MODIFY `dna` PROPERTIES DIRECTLY! The existing `dna["'+r+'"]` property was not installed as standard DNA module.'):t?n.push("Conflicting config exists: "+JSON.stringify(t)+".\nNote: All `id`, `proto` and `service` names must be unique accross the board."):n.push('Conflicting special DNA core property: dna["'+r+'"]. Name `'+r+"` is reserved."),$.error(n.join("\n"))}else dna.core.configs=dna.core.configs.filter(function(r){return r.id!==e.id}),dna[r]=void 0,console.log("DNA: Redeclaring "+e.id)}),this.configs.push(e),$(window).trigger("dna:config:new",e),e.data&&dna.data[e.data]&&dna(e.data)},DNACore.prototype.canSatisfy=function(e,r,t){if(r=r||[],void 0===e||0==e.length)return!0;t=t||[];for(var n in e){if(-1!==$.inArray(e[n],t))throw new DNAError("DNA: Recursive requirement loop: "+t.join(" > ")+" > "+e[n],601,{requirements:e,stack:t});var o=this.getConfig(e[n]);if(!o)return r.push("Config with super-identifier `"+e[n]+"` not defined yet."),!1;if(o.eval&&!settings.factory[o.eval])return!1;var i=t.slice();if(i.push(e[n]),!this.canSatisfy(o.require,r,i))return!1}return!0},DNACore.prototype.whenSatisfied=function(){var e=$.Deferred(),r=dna.core.getOpts(arguments,[["jsonURLs",/\//],["requirements","string"],["callbacks","function"],"recursive"]);return $.each(r,function(e){}),r._dfd=e,this.queue.push(r),this.checkQueue(),e},DNACore.prototype.checkQueue=function(){for(var e=this.queue.length-1;0<=e;e--){var r=this.queue[e],t=[];try{var n=this.canSatisfy(r.requirements,t)}catch(t){this.queue.splice(e,1),r._dfd.reject(new DNAError(t));break}n&&(this.queue.splice(e,1),$(r.callbacks).each(function(e,r){r()}),r._dfd.resolve(r))}},DNACore.prototype.getConfig=function(e){for(var r=0;r<this.configs.length;r++){var t=this.configs[r];if(t.id==e||t.service==e||t.data==e||-1!==$.inArray(e,t.proto,t.proto.length>1?1:0))return readyConfig(t)}return null},DNACore.prototype.getOpts=function(e,r){var t={};return r.forEach(function(e,n){"recursive"==r[n]&&(r[n]={match:["array","object"],recursive:!0}),$.isArray(r[n])&&(r[n]={name:r[n][0],match:r[n][1]}),"object"!=typeof r[n]&&$.error("Capture item must be of type object or array."),$.isArray(r[n].match)||(r[n].match=[r[n].match]),r[n].recursive||(t[r[n].name]=[])}),$.each($.makeArray(e),function(e,n){try{if(!getOptsCategorize(n,r,t))throw Error("Cannot categorize arguments.")}catch(e){$.error("Unexpected opt ("+typeof n+") `"+n.toString()+"`: "+e.message)}}.bind(this)),t},DNACore.prototype.require=function(){return requireMulti.call(this,$.makeArray(arguments),[])},DNAError.prototype=Object.create(Error.prototype),DNAError.prototype.toString=function(){return"DNAError"},DNAError.prototype.constructor=DNAError,install("Error",DNAError),install("core",new DNACore),install("data",{}),console.log("DNA v"+dna.core.version+" ready.");var initQueue=window.dna||[];window.dna=dna;for(var i=0;i<initQueue.length;i++)window.dna.apply(this,[initQueue[i]])}(jQuery,window);
//# sourceMappingURL=dna.min.map