Merge pull request #1982 from dolox/master

Added Fallback v1.0.5
This commit is contained in:
Thomas Davis
2013-11-20 20:47:26 -08:00
3 changed files with 302 additions and 0 deletions
+265
View File
@@ -0,0 +1,265 @@
/* fallback.js v1.0.5 | https://github.com/dolox/fallback/ | Salvatore Garbesi <sal@dolox.com> | (c) 2013 Dolox Inc. */
(function(window) {
'use strict';
var fallback = {
callback: null,
callbacks: [],
head: document.getElementsByTagName('head')[0],
libraries: {},
libraries_count: 0,
loaded: {},
loaded_count: 0,
fail: {},
fail_count: 0,
shim: {}
};
fallback.is_array = function(variable) {
if (variable instanceof Array) {
return true;
}
return false;
};
fallback.is_defined = function(variable) {
/* jslint evil: true */
if (eval('window.' + variable)) {
return true;
}
return false;
};
fallback.is_function = function(variable) {
if (({}).toString.call(variable) === '[object Function]') {
return true;
}
return false;
};
fallback.is_object = function(variable) {
if (typeof variable === 'object') {
return true;
}
return false;
};
fallback.index_of = function(object, value) {
var index;
for (index in object) {
if (object[index] === value) {
return index;
}
}
return -1;
};
fallback.initialize = function() {
var library, urls;
for (library in this.libraries) {
if (this.libraries[library]) {
urls = this.libraries[library];
if (!this.is_array(urls)) {
this.libraries[library] = urls = [urls];
}
this.libraries_count++;
if (!this.shim[library]) {
this.spawn(library, urls[0], 0);
}
}
}
};
fallback.completed = function() {
this.ready_invocation();
if (this.libraries_count === this.loaded_count + this.fail_count) {
if (this.is_function(this.callback)) {
this.callback(this.loaded, this.fail);
}
this.callback = null;
}
};
fallback.error = function(library, index) {
index = parseInt(index,0);
if (!this.fail[library]) {
this.fail[library] = [];
}
this.fail[library][this.fail[library].length] = this.libraries[library][index];
if (index < this.libraries[library].length - 1) {
this.spawn(library, this.libraries[library][index + 1], index + 1);
} else {
this.fail_count++;
}
this.completed();
};
fallback.load = function(libraries, options, callback) {
if (this.is_function(options)) {
callback = options;
options = {};
}
if (!this.is_object(options)) {
options = {};
}
if (options.shim) {
this.shim = options.shim;
}
if (!this.is_function(callback)) {
callback = function() {};
}
this.callback = callback;
this.libraries = libraries;
this.initialize();
};
fallback.ready = function(libraries, callback) {
var options = {
callback: callback,
libraries: libraries
};
if (!this.is_array(libraries)) {
options.callback = libraries;
options.libraries = [];
}
this.callbacks[this.callbacks.length] = options;
this.ready_invocation();
};
fallback.ready_invocation = function() {
var index, options, count, library, wipe;
for (index in this.callbacks) {
if (this.is_object(this.callbacks[index])) {
options = this.callbacks[index];
wipe = false;
if (options.libraries.length > 0) {
count = 0;
for (library in this.loaded) {
if (this.index_of(options.libraries, library) >= 0) {
count++;
}
}
if (count === options.libraries.length) {
options.callback();
wipe = true;
}
} else if (this.libraries_count === this.loaded_count + this.fail_count) {
options.callback(this.loaded, this.fail);
wipe = true;
}
if (wipe) {
delete this.callbacks[index];
}
}
}
};
fallback.spawn = function(library, url, index) {
var element;
if (this.is_defined(library)) {
return fallback.success(library, index);
}
if (url.indexOf('.css') > -1) {
element = document.createElement('link');
element.rel = 'stylesheet';
element.href = url;
} else {
element = document.createElement('script');
element.src = url;
}
element.onload = function() {
fallback.success(library, index);
};
element.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
this.onreadystatechange = null;
if (!fallback.is_defined(library)) {
fallback.error(library, index);
} else {
fallback.success(library, index);
}
}
};
element.onerror = function() {
fallback.error(library, index);
};
this.head.appendChild(element);
};
fallback.success = function(library, index) {
this.loaded[library] = this.libraries[library][index];
this.loaded_count++;
if (this.shim) {
this.shim_invocation(library);
}
this.completed();
};
fallback.shim_invocation = function() {
var count, index, shim, shimming;
for (shim in this.shim) {
if (this.shim[shim]) {
shimming = this.shim[shim];
count = 0;
if (!this.loaded[shim]) {
for (index in shimming) {
if (this.loaded[shimming[index]]) {
count++;
}
}
if (count === shimming.length) {
this.spawn(shim, this.libraries[shim][0], 0);
delete this.shim[shim];
}
}
}
}
};
window.fallback = fallback;
})(window);
+6
View File
@@ -0,0 +1,6 @@
/* fallback.js v1.0.5 | https://github.com/dolox/fallback/ | Salvatore Garbesi <sal@dolox.com> | (c) 2013 Dolox Inc. */
(function(f){var e={b:null,c:[],head:document.getElementsByTagName("head")[0],a:{},g:0,loaded:{},h:0,d:{},e:0,shim:{},l:function(a){return a instanceof Array?!0:!1},m:function(a){return eval("window."+a)?!0:!1},f:function(a){return"[object Function]"==={}.toString.call(a)?!0:!1},n:function(a){return"object"===typeof a?!0:!1},p:function(a,b){for(var c in a)if(a[c]===b)return c;return-1},q:function(){var a,b;for(a in this.a)this.a[a]&&(b=this.a[a],this.l(b)||(this.a[a]=b=[b]),this.g++,this.shim[a]||
this.i(a,b[0],0))},k:function(){this.o();this.g===this.h+this.e&&(this.f(this.b)&&this.b(this.loaded,this.d),this.b=null)},error:function(a,b){b=parseInt(b,0);this.d[a]||(this.d[a]=[]);this.d[a][this.d[a].length]=this.a[a][b];b<this.a[a].length-1?this.i(a,this.a[a][b+1],b+1):this.e++;this.k()},load:function(a,b,c){this.f(b)&&(c=b,b={});this.n(b)||(b={});b.shim&&(this.shim=b.shim);this.f(c)||(c=function(){});this.b=c;this.a=a;this.q()},ready:function(a,b){var c={b:b,a:a};this.l(a)||(c.b=a,c.a=[]);
this.c[this.c.length]=c;this.o()},o:function(){var a,b,c,d,e;for(a in this.c)if(this.n(this.c[a])){b=this.c[a];e=!1;if(0<b.a.length){c=0;for(d in this.loaded)0<=this.p(b.a,d)&&c++;c===b.a.length&&(b.b(),e=!0)}else this.g===this.h+this.e&&(b.b(this.loaded,this.d),e=!0);e&&delete this.c[a]}},i:function(a,b,c){var d;if(this.m(a))return e.j(a,c);-1<b.indexOf(".css")?(d=document.createElement("link"),d.rel="stylesheet",d.href=b):(d=document.createElement("script"),d.src=b);d.onload=function(){e.j(a,c)};
d.onreadystatechange=function(){this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState||(this.onreadystatechange=null,e.m(a)?e.j(a,c):e.error(a,c))};d.onerror=function(){e.error(a,c)};this.head.appendChild(d)},j:function(a,b){this.loaded[a]=this.a[a][b];this.h++;this.shim&&this.r(a);this.k()},r:function(){var a,b,c,d;for(c in this.shim)if(this.shim[c]&&(d=this.shim[c],a=0,!this.loaded[c])){for(b in d)this.loaded[d[b]]&&a++;a===d.length&&(this.i(c,this.a[c][0],0),delete this.shim[c])}}};
f.fallback=e})(window);
+31
View File
@@ -0,0 +1,31 @@
{
"name": "fallback",
"filename": "fallback.min.js",
"version": "1.0.5",
"description": "JavaScript library for dynamically loading CSS and JS files. Also provides the ability to load multiple files from a CDN with multiple fallback options and shimming!",
"homepage": "http://fallback.io/",
"keywords": [
"fallback",
"failover",
"ondemand",
"require",
"ajax",
"component"
],
"maintainers": [
{
"name": "Salvatore Garbesi",
"email": "sal@dolox.com",
"twitter": "sgarbesi"
}
],
"repositories": [
{
"type": "git",
"url": "git://github.com/dolox/fallback.git"
}
]
}