localforage
Advanced tools
Comparing version 0.9.2 to 0.9.3
{ | ||
"name": "localforage", | ||
"version": "0.9.2", | ||
"version": "0.9.3", | ||
"main": [ | ||
"dist/localforage.min.js" | ||
"dist/localforage.js" | ||
], | ||
@@ -7,0 +7,0 @@ "ignore": [ |
@@ -8,2 +8,3 @@ # About this CHANGELOG | ||
* It is no longer necessary to queue commands using `ready()` when using RequireJS. ([723cc94e06](https://github.com/mozilla/localForage/commit/723cc94e06af4f5ba4c53fa65524ccd5f6c4432e)) | ||
* `setDriver` now accepts an array of drivers to be used, in order of preference, instead of simply a string. The string option is still supported. (eg. now one can use `setDriver(['WebSQL', 'localStorage'])` instead of `setDriver('WebSQL')`) | ||
@@ -10,0 +11,0 @@ |
{ | ||
"name": "localforage", | ||
"version": "0.9.2", | ||
"version": "0.9.3", | ||
"dependencies": { | ||
@@ -5,0 +5,0 @@ "then/promise": "5.0.0" |
@@ -1,1 +0,1 @@ | ||
!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)k.push("exports"===i[l]?g={}:b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:void 0===this?window:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:void(c[a]=b)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a;a="undefined"!=typeof global?global:"undefined"!=typeof window&&window.document?window:self;var b="Promise"in a&&"resolve"in a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;return new a.Promise(function(a){b=a}),f(b)}();b||(a.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h){"use strict";function i(a){if(!v(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof i))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],j(a,this)}function j(a,b){function c(a){o(b,a)}function d(a){q(b,a)}try{a(c,d)}catch(e){d(e)}}function k(a,b,c,d){var e,f,g,h,i=v(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;n(b,e)||(i&&g?o(b,e):h?q(b,f):a===D?o(b,e):a===E&&q(b,e))}function l(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+D]=c,e[f+E]=d}function m(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],k(b,c,d,f);a._subscribers=null}function n(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(u(b)&&(d=b.then,v(d)))return d.call(b,function(d){return c?!0:(c=!0,void(b!==d?o(a,d):p(a,d)))},function(b){return c?!0:(c=!0,void q(a,b))}),!0}catch(e){return c?!0:(q(a,e),!0)}return!1}function o(a,b){a===b?p(a,b):n(a,b)||p(a,b)}function p(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(r,a))}function q(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(s,a))}function r(a){m(a,a._state=D)}function s(a){m(a,a._state=E)}var t=a.config,u=(a.configure,b.objectOrFunction),v=b.isFunction,w=(b.now,c.all),x=d.race,y=e.resolve,z=f.reject,A=g.asap;t.async=A;var B=void 0,C=0,D=1,E=2;i.prototype={constructor:i,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;t.async(function(){k(c._state,d,e[c._state-1],c._detail)})}else l(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},i.all=w,i.race=x,i.resolve=y,i.reject=z,h.Promise=i}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}(),function(){"use strict";function a(a){if(a)for(var b in a)l[b]=a[b];return new j(function(a,b){var c=m.open(l.name,l.version);c.onerror=function(){b(c.error)},c.onupgradeneeded=function(){c.result.createObjectStore(l.storeName)},c.onsuccess=function(){k=c.result,a()}})}function b(a,b){var c=this;return new j(function(d,e){c.ready().then(function(){var c=k.transaction(l.storeName,"readonly").objectStore(l.storeName),f=c.get(a);f.onsuccess=function(){var a=f.result;void 0===a&&(a=null),i(b,a),d(a)},f.onerror=function(){b&&b(null,f.error),e(f.error)}},e)})}function c(a,b,c){var d=this;return new j(function(e,f){d.ready().then(function(){var d=k.transaction(l.storeName,"readwrite").objectStore(l.storeName);null===b&&(b=void 0);var g=d.put(b,a);g.onsuccess=function(){void 0===b&&(b=null),i(c,b),e(b)},g.onerror=function(){c&&c(null,g.error),f(g.error)}},f)})}function d(a,b){var c=this;return new j(function(d,e){c.ready().then(function(){var c=k.transaction(l.storeName,"readwrite").objectStore(l.storeName),f=c["delete"](a);f.onsuccess=function(){i(b),d()},f.onerror=function(){b&&b(f.error),e(f.error)},f.onabort=function(a){var c=a.target.error;"QuotaExceededError"===c&&(b&&b(c),e(c))}},e)})}function e(a){var b=this;return new j(function(c,d){b.ready().then(function(){var b=k.transaction(l.storeName,"readwrite").objectStore(l.storeName),e=b.clear();e.onsuccess=function(){i(a),c()},e.onerror=function(){a&&a(null,e.error),d(e.error)}},d)})}function f(a){var b=this;return new j(function(c,d){b.ready().then(function(){var b=k.transaction(l.storeName,"readonly").objectStore(l.storeName),e=b.count();e.onsuccess=function(){a&&a(e.result),c(e.result)},e.onerror=function(){a&&a(null,e.error),d(e.error)}},d)})}function g(a,b){var c=this;return new j(function(d,e){return 0>a?(b&&b(null),void d(null)):void c.ready().then(function(){var c=k.transaction(l.storeName,"readonly").objectStore(l.storeName),f=!1,g=c.openCursor();g.onsuccess=function(){var c=g.result;return c?void(0===a?(b&&b(c.key),d(c.key)):f?(b&&b(c.key),d(c.key)):(f=!0,c.advance(a))):(b&&b(null),void d(null))},g.onerror=function(){b&&b(null,g.error),e(g.error)}},e)})}function h(a){var b=this;return new j(function(c,d){b.ready().then(function(){var b=k.transaction(l.storeName,"readonly").objectStore(l.storeName),e=b.openCursor(),f=[];e.onsuccess=function(){var b=e.result;return b?(f.push(b.key),void b["continue"]()):(a&&a(f),void c(f))},e.onerror=function(){a&&a(null,e.error),d(e.error)}},d)})}function i(a,b){return a?setTimeout(function(){return a(b)},0):void 0}var j="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,k=null,l={},m=m||this.indexedDB||this.webkitIndexedDB||this.mozIndexedDB||this.OIndexedDB||this.msIndexedDB;if(m){var n={_driver:"asyncStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("asyncStorage",function(){return n}):"undefined"!=typeof module&&module.exports?module.exports=n:this.asyncStorage=n}}.call(this),function(){"use strict";function a(a){if(a)for(var b in a)m[b]=a[b];return l=m.name+"/",n.resolve()}function b(a){var b=this;return new n(function(c,d){b.ready().then(function(){o.clear(),a&&a(),c()},d)})}function c(a,b){var c=this;return new n(function(d,e){c.ready().then(function(){try{var c=o.getItem(l+a);c&&(c=h(c)),b&&b(c),d(c)}catch(f){b&&b(null,f),e(f)}},e)})}function d(a,b){var c=this;return new n(function(d,e){c.ready().then(function(){var c;try{c=o.key(a)}catch(e){c=null}c&&(c=c.substring(l.length)),b&&b(c),d(c)},e)})}function e(a){var b=this;return new n(function(c,d){b.ready().then(function(){for(var b=o.length,d=[],e=0;b>e;e++)d.push(o.key(e).substring(l.length));a&&a(d),c(d)},d)})}function f(a){var b=this;return new n(function(c,d){b.ready().then(function(){var b=o.length;a&&a(b),c(b)},d)})}function g(a,b){var c=this;return new n(function(d,e){c.ready().then(function(){o.removeItem(l+a),b&&b(),d()},e)})}function h(a){if(a.substring(0,r)!==q)return JSON.parse(a);for(var b=a.substring(D),c=a.substring(r,D),d=new ArrayBuffer(2*b.length),e=new Uint16Array(d),f=b.length-1;f>=0;f--)e[f]=b.charCodeAt(f);switch(c){case s:return d;case t:return new Blob([d]);case u:return new Int8Array(d);case v:return new Uint8Array(d);case w:return new Uint8ClampedArray(d);case x:return new Int16Array(d);case z:return new Uint16Array(d);case y:return new Int32Array(d);case A:return new Uint32Array(d);case B:return new Float32Array(d);case C:return new Float64Array(d);default:throw new Error("Unkown type: "+c)}}function i(a){var b="",c=new Uint16Array(a);try{b=String.fromCharCode.apply(null,c)}catch(d){for(var e=0;e<c.length;e++)b+=String.fromCharCode(c[e])}return b}function j(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=q;a instanceof ArrayBuffer?(d=a,e+=s):(d=a.buffer,"[object Int8Array]"===c?e+=u:"[object Uint8Array]"===c?e+=v:"[object Uint8ClampedArray]"===c?e+=w:"[object Int16Array]"===c?e+=x:"[object Uint16Array]"===c?e+=z:"[object Int32Array]"===c?e+=y:"[object Uint32Array]"===c?e+=A:"[object Float32Array]"===c?e+=B:"[object Float64Array]"===c?e+=C:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(q+t+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){this.console&&this.console.error&&this.console.error("Couldn't convert value into a JSON string: ",a),b(null,g)}}function k(a,b,c){var d=this;return new n(function(e,f){d.ready().then(function(){void 0===b&&(b=null);var d=b;j(b,function(b,g){if(g)c&&c(null,g),f(g);else{try{o.setItem(l+a,b)}catch(h){("QuotaExceededError"===h.name||"NS_ERROR_DOM_QUOTA_REACHED"===h.name)&&(c&&c(null,h),f(h))}c&&c(d),e(d)}})},f)})}var l="",m={},n="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,o=null;try{if(!(this.localStorage&&"setItem"in this.localStorage))return;o=this.localStorage}catch(p){return}var q="__lfsc__:",r=q.length,s="arbf",t="blob",u="si08",v="ui08",w="uic8",x="si16",y="si32",z="ur16",A="ui32",B="fl32",C="fl64",D=r+s.length,E={_driver:"localStorageWrapper",_initStorage:a,getItem:c,setItem:k,removeItem:g,clear:b,length:f,key:d,keys:e};"function"==typeof define&&define.amd?define("localStorageWrapper",function(){return E}):"undefined"!=typeof module&&module.exports?module.exports=E:this.localStorageWrapper=E}.call(this),function(){"use strict";function a(a){var b=this;if(a)for(var c in a)p[c]="string"!=typeof a[c]?a[c].toString():a[c];return new m(function(a,c){try{o=n(p.name,p.version,p.description,p.size)}catch(d){return b.setDriver("localStorageWrapper").then(a,c)}o.transaction(function(b){b.executeSql("CREATE TABLE IF NOT EXISTS "+p.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){a()},function(a,b){c(b)})})})}function b(a,b){var c=this;return new m(function(d,e){c.ready().then(function(){o.transaction(function(c){c.executeSql("SELECT * FROM "+p.storeName+" WHERE key = ? LIMIT 1",[a],function(a,c){var e=c.rows.length?c.rows.item(0).value:null;e&&(e=j(e)),b&&b(e),d(e)},function(a,c){b&&b(null,c),e(c)})})},e)})}function c(a,b,c){var d=this;return new m(function(e,f){d.ready().then(function(){void 0===b&&(b=null);var d=b;k(b,function(b,g){g?f(g):o.transaction(function(g){g.executeSql("INSERT OR REPLACE INTO "+p.storeName+" (key, value) VALUES (?, ?)",[a,b],function(){c&&c(d),e(d)},function(a,b){c&&c(null,b),f(b)})},function(a){a.code===a.QUOTA_ERR&&(c&&c(null,a),f(a))})})},f)})}function d(a,b){var c=this;return new m(function(d,e){c.ready().then(function(){o.transaction(function(c){c.executeSql("DELETE FROM "+p.storeName+" WHERE key = ?",[a],function(){b&&b(),d()},function(a,c){b&&b(c),e(c)})})},e)})}function e(a){var b=this;return new m(function(c,d){b.ready().then(function(){o.transaction(function(b){b.executeSql("DELETE FROM "+p.storeName,[],function(){a&&a(),c()},function(b,c){a&&a(c),d(c)})})},d)})}function f(a){var b=this;return new m(function(c,d){b.ready().then(function(){o.transaction(function(b){b.executeSql("SELECT COUNT(key) as c FROM "+p.storeName,[],function(b,d){var e=d.rows.item(0).c;a&&a(e),c(e)},function(b,c){a&&a(null,c),d(c)})})},d)})}function g(a,b){var c=this;return new m(function(d,e){c.ready().then(function(){o.transaction(function(c){c.executeSql("SELECT key FROM "+p.storeName+" WHERE id = ? LIMIT 1",[a+1],function(a,c){var e=c.rows.length?c.rows.item(0).key:null;b&&b(e),d(e)},function(a,c){b&&b(null,c),e(c)})})},e)})}function h(a){var b=this;return new m(function(c,d){b.ready().then(function(){o.transaction(function(b){b.executeSql("SELECT key FROM "+p.storeName,[],function(b,d){for(var e=d.rows.length,f=[],g=0;e>g;g++)f.push(d.rows.item(g).key);a&&a(f),c(f)},function(b,c){a&&a(null,c),d(c)})})},d)})}function i(a){var b,c=new Uint8Array(a),d="";for(b=0;b<c.length;b+=3)d+=l[c[b]>>2],d+=l[(3&c[b])<<4|c[b+1]>>4],d+=l[(15&c[b+1])<<2|c[b+2]>>6],d+=l[63&c[b+2]];return c.length%3===2?d=d.substring(0,d.length-1)+"=":c.length%3===1&&(d=d.substring(0,d.length-2)+"=="),d}function j(a){if(a.substring(0,r)!==q)return JSON.parse(a);var b,c,d,e,f,g=a.substring(D),h=a.substring(r,D),i=.75*g.length,j=g.length,k=0;"="===g[g.length-1]&&(i--,"="===g[g.length-2]&&i--);var m=new ArrayBuffer(i),n=new Uint8Array(m);for(b=0;j>b;b+=4)c=l.indexOf(g[b]),d=l.indexOf(g[b+1]),e=l.indexOf(g[b+2]),f=l.indexOf(g[b+3]),n[k++]=c<<2|d>>4,n[k++]=(15&d)<<4|e>>2,n[k++]=(3&e)<<6|63&f;switch(h){case s:return m;case t:return new Blob([m]);case u:return new Int8Array(m);case v:return new Uint8Array(m);case w:return new Uint8ClampedArray(m);case x:return new Int16Array(m);case z:return new Uint16Array(m);case y:return new Int32Array(m);case A:return new Uint32Array(m);case B:return new Float32Array(m);case C:return new Float64Array(m);default:throw new Error("Unkown type: "+h)}}function k(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=q;a instanceof ArrayBuffer?(d=a,e+=s):(d=a.buffer,"[object Int8Array]"===c?e+=u:"[object Uint8Array]"===c?e+=v:"[object Uint8ClampedArray]"===c?e+=w:"[object Int16Array]"===c?e+=x:"[object Uint16Array]"===c?e+=z:"[object Int32Array]"===c?e+=y:"[object Uint32Array]"===c?e+=A:"[object Float32Array]"===c?e+=B:"[object Float64Array]"===c?e+=C:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(q+t+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){this.console&&this.console.error&&this.console.error("Couldn't convert value into a JSON string: ",a),b(null,g)}}var l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",m="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,n=this.openDatabase,o=null,p={},q="__lfsc__:",r=q.length,s="arbf",t="blob",u="si08",v="ui08",w="uic8",x="si16",y="si32",z="ur16",A="ui32",B="fl32",C="fl64",D=r+s.length;if(n){var E={_driver:"webSQLStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("webSQLStorage",function(){return E}):"undefined"!=typeof module&&module.exports?module.exports=E:this.webSQLStorage=E}}.call(this),function(){"use strict";var a="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,b=1,c=2,d=3,e=d;"function"==typeof define&&define.amd?e=b:"undefined"!=typeof module&&module.exports&&(e=c);var f=this,g={INDEXEDDB:"asyncStorage",LOCALSTORAGE:"localStorageWrapper",WEBSQL:"webSQLStorage",_config:{description:"",name:"localforage",size:4980736,storeName:"keyvaluepairs",version:1},config:function(a){if("object"==typeof a){if(this._ready)return new Error("Can't call config() after localforage has been used.");for(var b in a)this._config[b]=a[b];return!0}return"string"==typeof a?this._config[a]:this._config},driver:function(){return this._driver||null},_ready:!1,_driverSet:null,setDriver:function(d,g,h){var i=this,j=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)};return j(d)||"string"!=typeof d||(d=[d]),this._driverSet=new a(function(j,k){var l=i._getFirstSupportedDriver(d);if(!l){var m=new Error("No available storage method found.");return i._driverSet=a.reject(m),h&&h(m),void k(m)}if(i._ready=null,e===b)return void require([l],function(a){i._extend(a),g&&g(),j()});if(e===c){var n;switch(l){case i.INDEXEDDB:n=require("./drivers/indexeddb");break;case i.LOCALSTORAGE:n=require("./drivers/localstorage");break;case i.WEBSQL:n=require("./drivers/websql")}i._extend(n)}else i._extend(f[l]);g&&g(),j()}),this._driverSet},_getFirstSupportedDriver:function(a){if(a)for(var b=0;b<a.length;b++){var c=a[b];if(this.supports(c))return c}return null},supports:function(a){return!!h[a]},ready:function(b){var c=new a(function(a,b){g._driverSet.then(function(){null===g._ready&&(g._ready=g._initStorage(g._config)),g._ready.then(a,b)},b)});return c.then(b,b),c},_extend:function(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])}},h=function(a){var b=b||a.indexedDB||a.webkitIndexedDB||a.mozIndexedDB||a.OIndexedDB||a.msIndexedDB,c={};return c[g.WEBSQL]=!!a.openDatabase,c[g.INDEXEDDB]=!(!b||"function"!=typeof b.open||null!==b.open("_localforage_spec_test",1).onupgradeneeded),c[g.LOCALSTORAGE]=!!function(){try{return localStorage&&"function"==typeof localStorage.setItem}catch(a){return!1}}(),c}(this),i=[g.INDEXEDDB,g.WEBSQL,g.LOCALSTORAGE];g.setDriver(i),e===b?define(function(){return g}):e===c?module.exports=g:this.localforage=g}.call(this); | ||
!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)k.push("exports"===i[l]?g={}:b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:void 0===this?window:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:void(c[a]=b)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a;a="undefined"!=typeof global?global:"undefined"!=typeof window&&window.document?window:self;var b="Promise"in a&&"resolve"in a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;return new a.Promise(function(a){b=a}),f(b)}();b||(a.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h){"use strict";function i(a){if(!v(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof i))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],j(a,this)}function j(a,b){function c(a){o(b,a)}function d(a){q(b,a)}try{a(c,d)}catch(e){d(e)}}function k(a,b,c,d){var e,f,g,h,i=v(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;n(b,e)||(i&&g?o(b,e):h?q(b,f):a===D?o(b,e):a===E&&q(b,e))}function l(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+D]=c,e[f+E]=d}function m(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],k(b,c,d,f);a._subscribers=null}function n(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(u(b)&&(d=b.then,v(d)))return d.call(b,function(d){return c?!0:(c=!0,void(b!==d?o(a,d):p(a,d)))},function(b){return c?!0:(c=!0,void q(a,b))}),!0}catch(e){return c?!0:(q(a,e),!0)}return!1}function o(a,b){a===b?p(a,b):n(a,b)||p(a,b)}function p(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(r,a))}function q(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(s,a))}function r(a){m(a,a._state=D)}function s(a){m(a,a._state=E)}var t=a.config,u=(a.configure,b.objectOrFunction),v=b.isFunction,w=(b.now,c.all),x=d.race,y=e.resolve,z=f.reject,A=g.asap;t.async=A;var B=void 0,C=0,D=1,E=2;i.prototype={constructor:i,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;t.async(function(){k(c._state,d,e[c._state-1],c._detail)})}else l(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},i.all=w,i.race=x,i.resolve=y,i.reject=z,h.Promise=i}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}(),function(){"use strict";function a(a){var b=this,c={db:null};if(a)for(var d in a)c[d]=a[d];return new l(function(a,d){var e=m.open(c.name,c.version);e.onerror=function(){d(e.error)},e.onupgradeneeded=function(){e.result.createObjectStore(c.storeName)},e.onsuccess=function(){c.db=e.result,b._dbInfo=c,a()}})}function b(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new l(function(b,d){c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readonly").objectStore(e.storeName),g=f.get(a);g.onsuccess=function(){var a=g.result;void 0===a&&(a=null),b(a)},g.onerror=function(){d(g.error)}})["catch"](d)});return j(d,b),d}function c(a,b,c){var d=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var e=new l(function(c,e){d.ready().then(function(){var f=d._dbInfo,g=f.db.transaction(f.storeName,"readwrite").objectStore(f.storeName);null===b&&(b=void 0);var h=g.put(b,a);h.onsuccess=function(){void 0===b&&(b=null),c(b)},h.onerror=function(){e(h.error)}})["catch"](e)});return j(e,c),e}function d(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new l(function(b,d){c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readwrite").objectStore(e.storeName),g=f["delete"](a);g.onsuccess=function(){b()},g.onerror=function(){d(g.error)},g.onabort=function(a){var b=a.target.error;"QuotaExceededError"===b&&d(b)}})["catch"](d)});return j(d,b),d}function e(a){var b=this,c=new l(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readwrite").objectStore(d.storeName),f=e.clear();f.onsuccess=function(){a()},f.onerror=function(){c(f.error)}})["catch"](c)});return j(c,a),c}function f(a){var b=this,c=new l(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readonly").objectStore(d.storeName),f=e.count();f.onsuccess=function(){a(f.result)},f.onerror=function(){c(f.error)}})["catch"](c)});return i(c,a),c}function g(a,b){var c=this,d=new l(function(b,d){return 0>a?void b(null):void c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readonly").objectStore(e.storeName),g=!1,h=f.openCursor();h.onsuccess=function(){var c=h.result;return c?void(0===a?b(c.key):g?b(c.key):(g=!0,c.advance(a))):void b(null)},h.onerror=function(){d(h.error)}})["catch"](d)});return i(d,b),d}function h(a){var b=this,c=new l(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readonly").objectStore(d.storeName),f=e.openCursor(),g=[];f.onsuccess=function(){var b=f.result;return b?(g.push(b.key),void b["continue"]()):void a(g)},f.onerror=function(){c(f.error)}})["catch"](c)});return i(c,a),c}function i(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}function j(a,b){b&&a.then(function(a){k(b,a)},function(a){b(a)})}function k(a,b){return a?setTimeout(function(){return a(null,b)},0):void 0}var l="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,m=m||this.indexedDB||this.webkitIndexedDB||this.mozIndexedDB||this.OIndexedDB||this.msIndexedDB;if(m){var n={_driver:"asyncStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("asyncStorage",function(){return n}):"undefined"!=typeof module&&module.exports?module.exports=n:this.asyncStorage=n}}.call(window),function(){"use strict";function a(a){var b=this,c={};if(a)for(var d in a)c[d]=a[d];return c.keyPrefix=c.name+"/",b._dbInfo=c,m.resolve()}function b(a){var b=this,c=new m(function(a,c){b.ready().then(function(){n.clear(),a()})["catch"](c)});return l(c,a),c}function c(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new m(function(b,d){c.ready().then(function(){try{var e=c._dbInfo,f=n.getItem(e.keyPrefix+a);f&&(f=h(f)),b(f)}catch(g){d(g)}})["catch"](d)});return l(d,b),d}function d(a,b){var c=this,d=new m(function(b,d){c.ready().then(function(){var d,e=c._dbInfo;try{d=n.key(a)}catch(f){d=null}d&&(d=d.substring(e.keyPrefix.length)),b(d)})["catch"](d)});return l(d,b),d}function e(a){var b=this,c=new m(function(a,c){b.ready().then(function(){for(var c=b._dbInfo,d=n.length,e=[],f=0;d>f;f++)e.push(n.key(f).substring(c.keyPrefix.length));a(e)})["catch"](c)});return l(c,a),c}function f(a){var b=this,c=new m(function(a,c){b.ready().then(function(){var b=n.length;a(b)})["catch"](c)});return l(c,a),c}function g(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new m(function(b,d){c.ready().then(function(){var d=c._dbInfo;n.removeItem(d.keyPrefix+a),b()})["catch"](d)});return l(d,b),d}function h(a){if(a.substring(0,q)!==p)return JSON.parse(a);for(var b=a.substring(C),c=a.substring(q,C),d=new ArrayBuffer(2*b.length),e=new Uint16Array(d),f=b.length-1;f>=0;f--)e[f]=b.charCodeAt(f);switch(c){case r:return d;case s:return new Blob([d]);case t:return new Int8Array(d);case u:return new Uint8Array(d);case v:return new Uint8ClampedArray(d);case w:return new Int16Array(d);case y:return new Uint16Array(d);case x:return new Int32Array(d);case z:return new Uint32Array(d);case A:return new Float32Array(d);case B:return new Float64Array(d);default:throw new Error("Unkown type: "+c)}}function i(a){var b="",c=new Uint16Array(a);try{b=String.fromCharCode.apply(null,c)}catch(d){for(var e=0;e<c.length;e++)b+=String.fromCharCode(c[e])}return b}function j(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=p;a instanceof ArrayBuffer?(d=a,e+=r):(d=a.buffer,"[object Int8Array]"===c?e+=t:"[object Uint8Array]"===c?e+=u:"[object Uint8ClampedArray]"===c?e+=v:"[object Int16Array]"===c?e+=w:"[object Uint16Array]"===c?e+=y:"[object Int32Array]"===c?e+=x:"[object Uint32Array]"===c?e+=z:"[object Float32Array]"===c?e+=A:"[object Float64Array]"===c?e+=B:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(p+s+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){window.console.error("Couldn't convert value into a JSON string: ",a),b(g)}}function k(a,b,c){var d=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var e=new m(function(c,e){d.ready().then(function(){void 0===b&&(b=null);var f=b;j(b,function(b,g){if(g)e(g);else{try{var h=d._dbInfo;n.setItem(h.keyPrefix+a,b)}catch(i){("QuotaExceededError"===i.name||"NS_ERROR_DOM_QUOTA_REACHED"===i.name)&&e(i)}c(f)}})})["catch"](e)});return l(e,c),e}function l(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}var m="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,n=null;try{if(!(this.localStorage&&"setItem"in this.localStorage))return;n=this.localStorage}catch(o){return}var p="__lfsc__:",q=p.length,r="arbf",s="blob",t="si08",u="ui08",v="uic8",w="si16",x="si32",y="ur16",z="ui32",A="fl32",B="fl64",C=q+r.length,D={_driver:"localStorageWrapper",_initStorage:a,getItem:c,setItem:k,removeItem:g,clear:b,length:f,key:d,keys:e};"function"==typeof define&&define.amd?define("localStorageWrapper",function(){return D}):"undefined"!=typeof module&&module.exports?module.exports=D:this.localStorageWrapper=D}.call(window),function(){"use strict";function a(a){var b=this,c={db:null};if(a)for(var d in a)c[d]="string"!=typeof a[d]?a[d].toString():a[d];return new n(function(d,e){try{c.db=o(c.name,String(c.version),c.description,c.size)}catch(f){return b.setDriver("localStorageWrapper").then(function(){return b._initStorage(a)}).then(d)["catch"](e)}c.db.transaction(function(a){a.executeSql("CREATE TABLE IF NOT EXISTS "+c.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){b._dbInfo=c,d()},function(a,b){e(b)})})})}function b(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new n(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("SELECT * FROM "+e.storeName+" WHERE key = ? LIMIT 1",[a],function(a,c){var d=c.rows.length?c.rows.item(0).value:null;d&&(d=j(d)),b(d)},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function c(a,b,c){var d=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var e=new n(function(c,e){d.ready().then(function(){void 0===b&&(b=null);var f=b;k(b,function(b,g){if(g)e(g);else{var h=d._dbInfo;h.db.transaction(function(d){d.executeSql("INSERT OR REPLACE INTO "+h.storeName+" (key, value) VALUES (?, ?)",[a,b],function(){c(f)},function(a,b){e(b)})},function(a){a.code===a.QUOTA_ERR&&e(a)})}})})["catch"](e)});return l(e,c),e}function d(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new n(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("DELETE FROM "+e.storeName+" WHERE key = ?",[a],function(){b()},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function e(a){var b=this,c=new n(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("DELETE FROM "+d.storeName,[],function(){a()},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function f(a){var b=this,c=new n(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("SELECT COUNT(key) as c FROM "+d.storeName,[],function(b,c){var d=c.rows.item(0).c;a(d)},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function g(a,b){var c=this,d=new n(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("SELECT key FROM "+e.storeName+" WHERE id = ? LIMIT 1",[a+1],function(a,c){var d=c.rows.length?c.rows.item(0).key:null;b(d)},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function h(a){var b=this,c=new n(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("SELECT key FROM "+d.storeName,[],function(b,c){for(var d=[],e=0;e<c.rows.length;e++)d.push(c.rows.item(e).key);a(d)},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function i(a){var b,c=new Uint8Array(a),d="";for(b=0;b<c.length;b+=3)d+=m[c[b]>>2],d+=m[(3&c[b])<<4|c[b+1]>>4],d+=m[(15&c[b+1])<<2|c[b+2]>>6],d+=m[63&c[b+2]];return c.length%3===2?d=d.substring(0,d.length-1)+"=":c.length%3===1&&(d=d.substring(0,d.length-2)+"=="),d}function j(a){if(a.substring(0,q)!==p)return JSON.parse(a);var b,c,d,e,f,g=a.substring(C),h=a.substring(q,C),i=.75*g.length,j=g.length,k=0;"="===g[g.length-1]&&(i--,"="===g[g.length-2]&&i--);var l=new ArrayBuffer(i),n=new Uint8Array(l);for(b=0;j>b;b+=4)c=m.indexOf(g[b]),d=m.indexOf(g[b+1]),e=m.indexOf(g[b+2]),f=m.indexOf(g[b+3]),n[k++]=c<<2|d>>4,n[k++]=(15&d)<<4|e>>2,n[k++]=(3&e)<<6|63&f;switch(h){case r:return l;case s:return new Blob([l]);case t:return new Int8Array(l);case u:return new Uint8Array(l);case v:return new Uint8ClampedArray(l);case w:return new Int16Array(l);case y:return new Uint16Array(l);case x:return new Int32Array(l);case z:return new Uint32Array(l);case A:return new Float32Array(l);case B:return new Float64Array(l);default:throw new Error("Unkown type: "+h)}}function k(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=p;a instanceof ArrayBuffer?(d=a,e+=r):(d=a.buffer,"[object Int8Array]"===c?e+=t:"[object Uint8Array]"===c?e+=u:"[object Uint8ClampedArray]"===c?e+=v:"[object Int16Array]"===c?e+=w:"[object Uint16Array]"===c?e+=y:"[object Int32Array]"===c?e+=x:"[object Uint32Array]"===c?e+=z:"[object Float32Array]"===c?e+=A:"[object Float64Array]"===c?e+=B:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(p+s+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){window.console.error("Couldn't convert value into a JSON string: ",a),b(null,g)}}function l(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}var m="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,o=this.openDatabase,p="__lfsc__:",q=p.length,r="arbf",s="blob",t="si08",u="ui08",v="uic8",w="si16",x="si32",y="ur16",z="ui32",A="fl32",B="fl64",C=q+r.length;if(o){var D={_driver:"webSQLStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("webSQLStorage",function(){return D}):"undefined"!=typeof module&&module.exports?module.exports=D:this.webSQLStorage=D}}.call(window),function(){"use strict";function a(){for(var a=1;a<arguments.length;a++){var b=arguments[a];if(b)for(var c in b)b.hasOwnProperty(c)&&(arguments[0][c]=b[c])}return arguments[0]}function b(a,b){a[b]=function(){var c=arguments;return a.ready().then(function(){return a[b].apply(a,c)})}}function c(c){this._config=a({},i,c),this._driverSet=null,this._ready=!1,this._dbInfo=null;for(var d=0;d<g.length;d++)b(this,g[d]);this.setDriver(f)}var d="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,e={INDEXEDDB:"asyncStorage",LOCALSTORAGE:"localStorageWrapper",WEBSQL:"webSQLStorage"},f=[e.INDEXEDDB,e.WEBSQL,e.LOCALSTORAGE],g=["clear","getItem","key","keys","length","removeItem","setItem"],h={DEFINE:1,EXPORT:2,WINDOW:3},i={description:"",name:"localforage",size:4980736,storeName:"keyvaluepairs",version:1},j=h.WINDOW;"function"==typeof define&&define.amd?j=h.DEFINE:"undefined"!=typeof module&&module.exports&&(j=h.EXPORT);var k=function(a){var b=b||a.indexedDB||a.webkitIndexedDB||a.mozIndexedDB||a.OIndexedDB||a.msIndexedDB,c={};return c[e.WEBSQL]=!!a.openDatabase,c[e.INDEXEDDB]=!!function(){try{return b&&"function"==typeof b.open&&null===b.open("_localforage_spec_test",1).onupgradeneeded}catch(a){return!1}}(),c[e.LOCALSTORAGE]=!!function(){try{return localStorage&&"function"==typeof localStorage.setItem}catch(a){return!1}}(),c}(this),l=this;c.prototype.INDEXEDDB=e.INDEXEDDB,c.prototype.LOCALSTORAGE=e.LOCALSTORAGE,c.prototype.WEBSQL=e.WEBSQL,c.prototype.config=function(a){if("object"==typeof a){if(this._ready)return new Error("Can't call config() after localforage has been used.");for(var b in a)"storeName"===b&&(a[b]=a[b].replace(/\W/g,"_")),this._config[b]=a[b];return!0}return"string"==typeof a?this._config[a]:this._config},c.prototype.driver=function(){return this._driver||null},c.prototype.ready=function(a){var b=this,c=new d(function(a,c){b._driverSet.then(function(){null===b._ready&&(b._ready=b._initStorage(b._config)),b._ready.then(a,c)})["catch"](c)});return c.then(a,a),c},c.prototype.setDriver=function(a,b,c){var e=this;return"string"==typeof a&&(a=[a]),this._driverSet=new d(function(b,c){var f=e._getFirstSupportedDriver(a);if(!f){var g=new Error("No available storage method found.");return e._driverSet=d.reject(g),void c(g)}if(e._dbInfo=null,e._ready=null,j===h.DEFINE)return void require([f],function(a){e._extend(a),b()});if(j===h.EXPORT){var i;switch(f){case e.INDEXEDDB:i=require("./drivers/indexeddb");break;case e.LOCALSTORAGE:i=require("./drivers/localstorage");break;case e.WEBSQL:i=require("./drivers/websql")}e._extend(i)}else e._extend(l[f]);b()}),this._driverSet.then(b,c),this._driverSet},c.prototype.supports=function(a){return!!k[a]},c.prototype._extend=function(b){a(this,b)},c.prototype._getFirstSupportedDriver=function(a){var b=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)};if(a&&b(a))for(var c=0;c<a.length;c++){var d=a[c];if(this.supports(d))return d}return null},c.prototype.createInstance=function(a){return new c(a)};var m=new c;j===h.DEFINE?define(function(){return m}):j===h.EXPORT?module.exports=m:this.localforage=m}.call(window); |
/*! | ||
localForage -- Offline Storage, Improved | ||
Version 0.9.2 | ||
Version 0.9.3 | ||
http://mozilla.github.io/localForage | ||
@@ -18,5 +18,2 @@ (c) 2013-2014 Mozilla, Apache License 2.0 | ||
var db = null; | ||
var dbInfo = {}; | ||
// Initialize IndexedDB; fall back to vendor-prefixed versions if needed. | ||
@@ -35,2 +32,7 @@ var indexedDB = indexedDB || this.indexedDB || this.webkitIndexedDB || | ||
function _initStorage(options) { | ||
var _this = this; | ||
var dbInfo = { | ||
db: null | ||
}; | ||
if (options) { | ||
@@ -52,3 +54,4 @@ for (var i in options) { | ||
openreq.onsuccess = function() { | ||
db = openreq.result; | ||
dbInfo.db = openreq.result; | ||
_this._dbInfo = dbInfo; | ||
resolve(); | ||
@@ -61,5 +64,14 @@ }; | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly') | ||
.objectStore(dbInfo.storeName); | ||
@@ -74,4 +86,2 @@ var req = store.get(key); | ||
deferCallback(callback,value); | ||
resolve(value); | ||
@@ -81,10 +91,9 @@ }; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeDeferedCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -94,5 +103,14 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readwrite') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readwrite') | ||
.objectStore(dbInfo.storeName); | ||
@@ -120,15 +138,12 @@ | ||
deferCallback(callback, value); | ||
resolve(value); | ||
}; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeDeferedCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -138,5 +153,14 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readwrite') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readwrite') | ||
.objectStore(dbInfo.storeName); | ||
@@ -151,5 +175,2 @@ | ||
req.onsuccess = function() { | ||
deferCallback(callback); | ||
resolve(); | ||
@@ -159,6 +180,2 @@ }; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(req.error); | ||
} | ||
reject(req.error); | ||
@@ -173,11 +190,10 @@ }; | ||
if (error === 'QuotaExceededError') { | ||
if (callback) { | ||
callback(error); | ||
} | ||
reject(error); | ||
} | ||
}; | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeDeferedCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -187,5 +203,7 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readwrite') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readwrite') | ||
.objectStore(dbInfo.storeName); | ||
@@ -195,4 +213,2 @@ var req = store.clear(); | ||
req.onsuccess = function() { | ||
deferCallback(callback); | ||
resolve(); | ||
@@ -202,10 +218,9 @@ }; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeDeferedCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -215,5 +230,7 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly') | ||
.objectStore(dbInfo.storeName); | ||
@@ -223,6 +240,2 @@ var req = store.count(); | ||
req.onsuccess = function() { | ||
if (callback) { | ||
callback(req.result); | ||
} | ||
resolve(req.result); | ||
@@ -232,10 +245,9 @@ }; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -245,8 +257,5 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
if (n < 0) { | ||
if (callback) { | ||
callback(null); | ||
} | ||
resolve(null); | ||
@@ -258,3 +267,4 @@ | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly') | ||
.objectStore(dbInfo.storeName); | ||
@@ -268,6 +278,2 @@ | ||
// this means there weren't enough keys | ||
if (callback) { | ||
callback(null); | ||
} | ||
resolve(null); | ||
@@ -281,6 +287,2 @@ | ||
// wanted. | ||
if (callback) { | ||
callback(cursor.key); | ||
} | ||
resolve(cursor.key); | ||
@@ -295,6 +297,2 @@ } else { | ||
// When we get here, we've got the nth key. | ||
if (callback) { | ||
callback(cursor.key); | ||
} | ||
resolve(cursor.key); | ||
@@ -306,10 +304,9 @@ } | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -320,5 +317,6 @@ | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly') | ||
.objectStore(dbInfo.storeName); | ||
@@ -333,6 +331,2 @@ | ||
if (!cursor) { | ||
if (callback) { | ||
callback(keys); | ||
} | ||
resolve(keys); | ||
@@ -347,12 +341,31 @@ return; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
function executeCallback(promise, callback) { | ||
if (callback) { | ||
promise.then(function(result) { | ||
callback(null, result); | ||
}, function(error) { | ||
callback(error); | ||
}); | ||
} | ||
} | ||
function executeDeferedCallback(promise, callback) { | ||
if (callback) { | ||
promise.then(function(result) { | ||
deferCallback(callback, result); | ||
}, function(error) { | ||
callback(error); | ||
}); | ||
} | ||
} | ||
// Under Chrome the callback is called before the changes (save, clear) | ||
@@ -363,6 +376,6 @@ // are actually made. So we use a defer function which wait that the | ||
// Pull request : https://github.com/mozilla/localForage/pull/178 | ||
function deferCallback(callback, value) { | ||
function deferCallback(callback, result) { | ||
if (callback) { | ||
return setTimeout(function() { | ||
return callback(value); | ||
return callback(null, result); | ||
}, 0); | ||
@@ -393,3 +406,3 @@ } | ||
} | ||
}).call(this); | ||
}).call(window); | ||
// If IndexedDB isn't available, we'll fall back to localStorage. | ||
@@ -402,4 +415,2 @@ // Note that this will have considerable performance and storage | ||
var keyPrefix = ''; | ||
var dbInfo = {}; | ||
// Promises! | ||
@@ -430,2 +441,4 @@ var Promise = (typeof module !== 'undefined' && module.exports) ? | ||
function _initStorage(options) { | ||
var _this = this; | ||
var dbInfo = {}; | ||
if (options) { | ||
@@ -437,4 +450,5 @@ for (var i in options) { | ||
keyPrefix = dbInfo.name + '/'; | ||
dbInfo.keyPrefix = dbInfo.name + '/'; | ||
_this._dbInfo = dbInfo; | ||
return Promise.resolve(); | ||
@@ -465,13 +479,12 @@ } | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
localStorage.clear(); | ||
if (callback) { | ||
callback(); | ||
} | ||
resolve(); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -484,6 +497,15 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
try { | ||
var result = localStorage.getItem(keyPrefix + key); | ||
var dbInfo = _this._dbInfo; | ||
var result = localStorage.getItem(dbInfo.keyPrefix + key); | ||
@@ -498,16 +520,11 @@ // If a result was found, parse it from the serialized | ||
if (callback) { | ||
callback(result); | ||
} | ||
resolve(result); | ||
} catch (e) { | ||
if (callback) { | ||
callback(null, e); | ||
} | ||
reject(e); | ||
} | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -518,4 +535,5 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var dbInfo = _this._dbInfo; | ||
var result; | ||
@@ -530,11 +548,11 @@ try { | ||
if (result) { | ||
result = result.substring(keyPrefix.length); | ||
result = result.substring(dbInfo.keyPrefix.length); | ||
} | ||
if (callback) { | ||
callback(result); | ||
} | ||
resolve(result); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -544,4 +562,5 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var dbInfo = _this._dbInfo; | ||
var length = localStorage.length; | ||
@@ -551,12 +570,12 @@ var keys = []; | ||
for (var i = 0; i < length; i++) { | ||
keys.push(localStorage.key(i).substring(keyPrefix.length)); | ||
keys.push(localStorage.key(i) | ||
.substring(dbInfo.keyPrefix.length)); | ||
} | ||
if (callback) { | ||
callback(keys); | ||
} | ||
resolve(keys); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -567,13 +586,12 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var result = localStorage.length; | ||
if (callback) { | ||
callback(result); | ||
} | ||
resolve(result); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -584,13 +602,21 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
localStorage.removeItem(keyPrefix + key); | ||
var dbInfo = _this._dbInfo; | ||
localStorage.removeItem(dbInfo.keyPrefix + key); | ||
if (callback) { | ||
callback(); | ||
} | ||
resolve(); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -693,3 +719,4 @@ | ||
if (value && (value.toString() === '[object ArrayBuffer]' || | ||
value.buffer && value.buffer.toString() === '[object ArrayBuffer]')) { | ||
value.buffer && | ||
value.buffer.toString() === '[object ArrayBuffer]')) { | ||
// Convert binary arrays to a string and prefix the string with | ||
@@ -725,3 +752,3 @@ // a special marker. | ||
} else { | ||
callback(new Error("Failed to get type for BinaryArray")); | ||
callback(new Error('Failed to get type for BinaryArray')); | ||
} | ||
@@ -731,3 +758,3 @@ } | ||
callback(marker + _bufferToString(buffer)); | ||
} else if (valueString === "[object Blob]") { | ||
} else if (valueString === '[object Blob]') { | ||
// Conver the blob to a binaryArray and then to a string. | ||
@@ -747,7 +774,6 @@ var fileReader = new FileReader(); | ||
} catch (e) { | ||
if (this.console && this.console.error) { | ||
this.console.error("Couldn't convert value into a JSON string: ", value); | ||
} | ||
window.console.error("Couldn't convert value into a JSON " + | ||
'string: ', value); | ||
callback(null, e); | ||
callback(e); | ||
} | ||
@@ -763,3 +789,11 @@ } | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
@@ -777,10 +811,7 @@ // Convert undefined values to null. | ||
if (error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
reject(error); | ||
} else { | ||
try { | ||
localStorage.setItem(keyPrefix + key, value); | ||
var dbInfo = _this._dbInfo; | ||
localStorage.setItem(dbInfo.keyPrefix + key, value); | ||
} catch (e) { | ||
@@ -791,6 +822,2 @@ // localStorage capacity exceeded. | ||
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { | ||
if (callback) { | ||
callback(null, e); | ||
} | ||
reject(e); | ||
@@ -800,13 +827,22 @@ } | ||
if (callback) { | ||
callback(originalValue); | ||
} | ||
resolve(originalValue); | ||
} | ||
}); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
function executeCallback(promise, callback) { | ||
if (callback) { | ||
promise.then(function(result) { | ||
callback(null, result); | ||
}, function(error) { | ||
callback(error); | ||
}); | ||
} | ||
} | ||
var localStorageWrapper = { | ||
@@ -834,3 +870,3 @@ _driver: 'localStorageWrapper', | ||
} | ||
}).call(this); | ||
}).call(window); | ||
/* | ||
@@ -858,4 +894,2 @@ * Includes code from: | ||
var openDatabase = this.openDatabase; | ||
var db = null; | ||
var dbInfo = {}; | ||
@@ -877,3 +911,4 @@ var SERIALIZED_MARKER = '__lfsc__:'; | ||
var TYPE_FLOAT64ARRAY = 'fl64'; | ||
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length; | ||
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + | ||
TYPE_ARRAYBUFFER.length; | ||
@@ -889,6 +924,10 @@ // If WebSQL methods aren't available, we can stop now. | ||
var _this = this; | ||
var dbInfo = { | ||
db: null | ||
}; | ||
if (options) { | ||
for (var i in options) { | ||
dbInfo[i] = typeof(options[i]) !== 'string' ? options[i].toString() : options[i]; | ||
dbInfo[i] = typeof(options[i]) !== 'string' ? | ||
options[i].toString() : options[i]; | ||
} | ||
@@ -901,12 +940,16 @@ } | ||
try { | ||
db = openDatabase(dbInfo.name, dbInfo.version, | ||
dbInfo.description, dbInfo.size); | ||
dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), | ||
dbInfo.description, dbInfo.size); | ||
} catch (e) { | ||
return _this.setDriver('localStorageWrapper').then(resolve, reject); | ||
return _this.setDriver("localStorageWrapper").then(function() { | ||
return _this._initStorage(options); | ||
}).then(resolve)["catch"](reject); | ||
} | ||
// Create our key/value table if it doesn't exist. | ||
db.transaction(function(t) { | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + | ||
' (id INTEGER PRIMARY KEY, key unique, value)', [], function() { | ||
' (id INTEGER PRIMARY KEY, key unique, value)', [], | ||
function() { | ||
_this._dbInfo = dbInfo; | ||
resolve(); | ||
@@ -922,8 +965,19 @@ }, function(t, error) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('SELECT * FROM ' + dbInfo.storeName + | ||
' WHERE key = ? LIMIT 1', [key], function(t, results) { | ||
var result = results.rows.length ? results.rows.item(0).value : null; | ||
' WHERE key = ? LIMIT 1', [key], | ||
function(t, results) { | ||
var result = results.rows.length ? | ||
results.rows.item(0).value : null; | ||
@@ -936,11 +990,4 @@ // Check to see if this is serialized content we need to | ||
if (callback) { | ||
callback(result); | ||
} | ||
resolve(result); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
@@ -950,4 +997,7 @@ reject(error); | ||
}); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -957,3 +1007,11 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
@@ -974,15 +1032,10 @@ // The localStorage API doesn't return undefined values in an | ||
} else { | ||
db.transaction(function(t) { | ||
t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + | ||
' (key, value) VALUES (?, ?)', [key, value], function() { | ||
if (callback) { | ||
callback(originalValue); | ||
} | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('INSERT OR REPLACE INTO ' + | ||
dbInfo.storeName + | ||
' (key, value) VALUES (?, ?)', | ||
[key, value], function() { | ||
resolve(originalValue); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
reject(error); | ||
@@ -1000,6 +1053,2 @@ }); | ||
// TODO: Try to re-run the transaction. | ||
if (callback) { | ||
callback(null, sqlError); | ||
} | ||
reject(sqlError); | ||
@@ -1010,4 +1059,7 @@ } | ||
}); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -1017,16 +1069,19 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('DELETE FROM ' + dbInfo.storeName + | ||
' WHERE key = ?', [key], function() { | ||
if (callback) { | ||
callback(); | ||
} | ||
resolve(); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(error); | ||
} | ||
@@ -1036,4 +1091,7 @@ reject(error); | ||
}); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -1045,21 +1103,19 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function() { | ||
if (callback) { | ||
callback(); | ||
} | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('DELETE FROM ' + dbInfo.storeName, [], | ||
function() { | ||
resolve(); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(error); | ||
} | ||
reject(error); | ||
}); | ||
}); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -1071,5 +1127,7 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
// Ahhh, SQL makes this one soooooo easy. | ||
@@ -1080,11 +1138,4 @@ t.executeSql('SELECT COUNT(key) as c FROM ' + | ||
if (callback) { | ||
callback(result); | ||
} | ||
resolve(result); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
@@ -1094,4 +1145,7 @@ reject(error); | ||
}); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -1108,24 +1162,22 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('SELECT key FROM ' + dbInfo.storeName + | ||
' WHERE id = ? LIMIT 1', [n + 1], function(t, results) { | ||
var result = results.rows.length ? results.rows.item(0).key : null; | ||
if (callback) { | ||
callback(result); | ||
} | ||
' WHERE id = ? LIMIT 1', [n + 1], | ||
function(t, results) { | ||
var result = results.rows.length ? | ||
results.rows.item(0).key : null; | ||
resolve(result); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
reject(error); | ||
}); | ||
}); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -1135,23 +1187,17 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], | ||
function(t, results) { | ||
var length = results.rows.length; | ||
var keys = []; | ||
for (var i = 0; i < length; i++) { | ||
for (var i = 0; i < results.rows.length; i++) { | ||
keys.push(results.rows.item(i).key); | ||
} | ||
if (callback) { | ||
callback(keys); | ||
} | ||
resolve(keys); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
@@ -1161,4 +1207,7 @@ reject(error); | ||
}); | ||
}, reject); | ||
})["catch"](reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -1183,5 +1232,5 @@ | ||
if ((bytes.length % 3) === 2) { | ||
base64String = base64String.substring(0, base64String.length - 1) + "="; | ||
base64String = base64String.substring(0, base64String.length - 1) + '='; | ||
} else if (bytes.length % 3 === 1) { | ||
base64String = base64String.substring(0, base64String.length - 2) + "=="; | ||
base64String = base64String.substring(0, base64String.length - 2) + '=='; | ||
} | ||
@@ -1204,3 +1253,4 @@ | ||
// done with it. | ||
if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { | ||
if (value.substring(0, | ||
SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { | ||
return JSON.parse(value); | ||
@@ -1213,3 +1263,4 @@ } | ||
var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH); | ||
var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH); | ||
var type = value.substring(SERIALIZED_MARKER_LENGTH, | ||
TYPE_SERIALIZED_MARKER_LENGTH); | ||
@@ -1223,5 +1274,5 @@ // Fill the string into a ArrayBuffer. | ||
if (serializedString[serializedString.length - 1] === "=") { | ||
if (serializedString[serializedString.length - 1] === '=') { | ||
bufferLength--; | ||
if (serializedString[serializedString.length - 2] === "=") { | ||
if (serializedString[serializedString.length - 2] === '=') { | ||
bufferLength--; | ||
@@ -1290,3 +1341,4 @@ } | ||
if (value && (value.toString() === '[object ArrayBuffer]' || | ||
value.buffer && value.buffer.toString() === '[object ArrayBuffer]')) { | ||
value.buffer && | ||
value.buffer.toString() === '[object ArrayBuffer]')) { | ||
// Convert binary arrays to a string and prefix the string with | ||
@@ -1322,3 +1374,3 @@ // a special marker. | ||
} else { | ||
callback(new Error("Failed to get type for BinaryArray")); | ||
callback(new Error('Failed to get type for BinaryArray')); | ||
} | ||
@@ -1328,3 +1380,3 @@ } | ||
callback(marker + _bufferToString(buffer)); | ||
} else if (valueString === "[object Blob]") { | ||
} else if (valueString === '[object Blob]') { | ||
// Conver the blob to a binaryArray and then to a string. | ||
@@ -1344,5 +1396,4 @@ var fileReader = new FileReader(); | ||
} catch (e) { | ||
if (this.console && this.console.error) { | ||
this.console.error("Couldn't convert value into a JSON string: ", value); | ||
} | ||
window.console.error("Couldn't convert value into a JSON " + | ||
'string: ', value); | ||
@@ -1354,2 +1405,12 @@ callback(null, e); | ||
function executeCallback(promise, callback) { | ||
if (callback) { | ||
promise.then(function(result) { | ||
callback(null, result); | ||
}, function(error) { | ||
callback(error); | ||
}); | ||
} | ||
} | ||
var webSQLStorage = { | ||
@@ -1376,3 +1437,3 @@ _driver: 'webSQLStorage', | ||
} | ||
}).call(this); | ||
}).call(window); | ||
(function() { | ||
@@ -1385,10 +1446,43 @@ 'use strict'; | ||
// Avoid those magic constants! | ||
var MODULE_TYPE_DEFINE = 1; | ||
var MODULE_TYPE_EXPORT = 2; | ||
var MODULE_TYPE_WINDOW = 3; | ||
var DriverType = { | ||
INDEXEDDB: 'asyncStorage', | ||
LOCALSTORAGE: 'localStorageWrapper', | ||
WEBSQL: 'webSQLStorage' | ||
}; | ||
var DefaultDriverOrder = [ | ||
DriverType.INDEXEDDB, | ||
DriverType.WEBSQL, | ||
DriverType.LOCALSTORAGE | ||
]; | ||
var LibraryMethods = [ | ||
'clear', | ||
'getItem', | ||
'key', | ||
'keys', | ||
'length', | ||
'removeItem', | ||
'setItem' | ||
]; | ||
var ModuleType = { | ||
DEFINE: 1, | ||
EXPORT: 2, | ||
WINDOW: 3 | ||
}; | ||
var DefaultConfig = { | ||
description: '', | ||
name: 'localforage', | ||
// Default DB size is _JUST UNDER_ 5MB, as it's the highest size | ||
// we can use without a prompt. | ||
size: 4980736, | ||
storeName: 'keyvaluepairs', | ||
version: 1.0 | ||
}; | ||
// Attaching to window (i.e. no module loader) is the assumed, | ||
// simple default. | ||
var moduleType = MODULE_TYPE_WINDOW; | ||
var moduleType = ModuleType.WINDOW; | ||
@@ -1398,225 +1492,244 @@ // Find out what kind of module setup we have; if none, we'll just attach | ||
if (typeof define === 'function' && define.amd) { | ||
moduleType = MODULE_TYPE_DEFINE; | ||
moduleType = ModuleType.DEFINE; | ||
} else if (typeof module !== 'undefined' && module.exports) { | ||
moduleType = MODULE_TYPE_EXPORT; | ||
moduleType = ModuleType.EXPORT; | ||
} | ||
// The actual localForage object that we expose as a module or via a | ||
// global. It's extended by pulling in one of our other libraries. | ||
var _this = this; | ||
var localForage = { | ||
INDEXEDDB: 'asyncStorage', | ||
LOCALSTORAGE: 'localStorageWrapper', | ||
WEBSQL: 'webSQLStorage', | ||
// Check to see if IndexedDB is available and if it is the latest | ||
// implementation; it's our preferred backend library. We use "_spec_test" | ||
// as the name of the database because it's not the one we'll operate on, | ||
// but it's useful to make sure its using the right spec. | ||
// See: https://github.com/mozilla/localForage/issues/128 | ||
var driverSupport = (function(_this) { | ||
// Initialize IndexedDB; fall back to vendor-prefixed versions | ||
// if needed. | ||
var indexedDB = indexedDB || _this.indexedDB || _this.webkitIndexedDB || | ||
_this.mozIndexedDB || _this.OIndexedDB || | ||
_this.msIndexedDB; | ||
_config: { | ||
description: '', | ||
name: 'localforage', | ||
// Default DB size is _JUST UNDER_ 5MB, as it's the highest size | ||
// we can use without a prompt. | ||
size: 4980736, | ||
storeName: 'keyvaluepairs', | ||
version: 1.0 | ||
}, | ||
var result = {}; | ||
// Set any config values for localForage; can be called anytime before | ||
// the first API call (e.g. `getItem`, `setItem`). | ||
// We loop through options so we don't overwrite existing config | ||
// values. | ||
config: function(options) { | ||
// If the options argument is an object, we use it to set values. | ||
// Otherwise, we return either a specified config value or all | ||
// config values. | ||
if (typeof(options) === 'object') { | ||
// If localforage is ready and fully initialized, we can't set | ||
// any new configuration values. Instead, we return an error. | ||
if (this._ready) { | ||
return new Error("Can't call config() after localforage " + | ||
"has been used."); | ||
} | ||
result[DriverType.WEBSQL] = !!_this.openDatabase; | ||
result[DriverType.INDEXEDDB] = !!(function() { | ||
try { | ||
return (indexedDB && | ||
typeof indexedDB.open === 'function' && | ||
indexedDB.open('_localforage_spec_test', 1) | ||
.onupgradeneeded === null); | ||
} catch (e) { | ||
return false; | ||
} | ||
})(); | ||
for (var i in options) { | ||
this._config[i] = options[i]; | ||
} | ||
return true; | ||
} else if (typeof(options) === 'string') { | ||
return this._config[options]; | ||
} else { | ||
return this._config; | ||
result[DriverType.LOCALSTORAGE] = !!(function() { | ||
try { | ||
return (localStorage && | ||
typeof localStorage.setItem === 'function'); | ||
} catch (e) { | ||
return false; | ||
} | ||
}, | ||
})(); | ||
driver: function() { | ||
return this._driver || null; | ||
}, | ||
return result; | ||
})(this); | ||
_ready: false, | ||
function extend(/*...*/) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var arg = arguments[i]; | ||
if (arg) { | ||
for (var key in arg) { | ||
if (arg.hasOwnProperty(key)) { | ||
arguments[0][key] = arg[key]; | ||
} | ||
} | ||
} | ||
} | ||
return arguments[0]; | ||
} | ||
_driverSet: null, | ||
function callWhenReady(localForageInstance, libraryMethod) { | ||
localForageInstance[libraryMethod] = function() { | ||
var _args = arguments; | ||
return localForageInstance.ready().then(function() { | ||
return localForageInstance[libraryMethod].apply(localForageInstance, _args); | ||
}); | ||
}; | ||
} | ||
setDriver: function(drivers, callback, errorCallback) { | ||
var self = this; | ||
// The actual localForage object that we expose as a module or via a | ||
// global. It's extended by pulling in one of our other libraries. | ||
var _this = this; | ||
var isArray = Array.isArray || function(arg) { | ||
return Object.prototype.toString.call(arg) === '[object Array]'; | ||
}; | ||
function LocalForage(options) { | ||
this._config = extend({}, DefaultConfig, options); | ||
this._driverSet = null; | ||
this._ready = false; | ||
this._dbInfo = null; | ||
if (!isArray(drivers) && typeof drivers === 'string') { | ||
drivers = [drivers]; | ||
} | ||
// Add a stub for each driver API method that delays the call to the | ||
// corresponding driver method until localForage is ready. These stubs | ||
// will be replaced by the driver methods as soon as the driver is | ||
// loaded, so there is no performance impact. | ||
for (var i = 0; i < LibraryMethods.length; i++) { | ||
callWhenReady(this, LibraryMethods[i]); | ||
} | ||
this._driverSet = new Promise(function(resolve, reject) { | ||
var driverName = self._getFirstSupportedDriver(drivers); | ||
this.setDriver(DefaultDriverOrder); | ||
} | ||
if (!driverName) { | ||
var error = new Error('No available storage method found.'); | ||
self._driverSet = Promise.reject(error); | ||
LocalForage.prototype.INDEXEDDB = DriverType.INDEXEDDB; | ||
LocalForage.prototype.LOCALSTORAGE = DriverType.LOCALSTORAGE; | ||
LocalForage.prototype.WEBSQL = DriverType.WEBSQL; | ||
if (errorCallback) { | ||
errorCallback(error); | ||
} | ||
// Set any config values for localForage; can be called anytime before | ||
// the first API call (e.g. `getItem`, `setItem`). | ||
// We loop through options so we don't overwrite existing config | ||
// values. | ||
LocalForage.prototype.config = function(options) { | ||
// If the options argument is an object, we use it to set values. | ||
// Otherwise, we return either a specified config value or all | ||
// config values. | ||
if (typeof(options) === 'object') { | ||
// If localforage is ready and fully initialized, we can't set | ||
// any new configuration values. Instead, we return an error. | ||
if (this._ready) { | ||
return new Error("Can't call config() after localforage " + | ||
'has been used.'); | ||
} | ||
reject(error); | ||
return; | ||
for (var i in options) { | ||
if (i === 'storeName') { | ||
options[i] = options[i].replace(/\W/g, '_'); | ||
} | ||
self._ready = null; | ||
this._config[i] = options[i]; | ||
} | ||
// We allow localForage to be declared as a module or as a | ||
// library available without AMD/require.js. | ||
if (moduleType === MODULE_TYPE_DEFINE) { | ||
require([driverName], function(lib) { | ||
self._extend(lib); | ||
return true; | ||
} else if (typeof(options) === 'string') { | ||
return this._config[options]; | ||
} else { | ||
return this._config; | ||
} | ||
}; | ||
if (callback) { | ||
callback(); | ||
} | ||
resolve(); | ||
}); | ||
LocalForage.prototype.driver = function() { | ||
return this._driver || null; | ||
}; | ||
return; | ||
} else if (moduleType === MODULE_TYPE_EXPORT) { | ||
// Making it browserify friendly | ||
var driver; | ||
switch (driverName) { | ||
case self.INDEXEDDB: | ||
driver = require('./drivers/indexeddb'); | ||
break; | ||
case self.LOCALSTORAGE: | ||
driver = require('./drivers/localstorage'); | ||
break; | ||
case self.WEBSQL: | ||
driver = require('./drivers/websql'); | ||
} | ||
LocalForage.prototype.ready = function(callback) { | ||
var self = this; | ||
self._extend(driver); | ||
} else { | ||
self._extend(_this[driverName]); | ||
var ready = new Promise(function(resolve, reject) { | ||
self._driverSet.then(function() { | ||
if (self._ready === null) { | ||
self._ready = self._initStorage(self._config); | ||
} | ||
if (callback) { | ||
callback(); | ||
} | ||
self._ready.then(resolve, reject); | ||
})["catch"](reject); | ||
}); | ||
resolve(); | ||
}); | ||
ready.then(callback, callback); | ||
return ready; | ||
}; | ||
return this._driverSet; | ||
}, | ||
LocalForage.prototype.setDriver = function(drivers, callback, | ||
errorCallback) { | ||
var self = this; | ||
_getFirstSupportedDriver: function(drivers) { | ||
if (drivers) { | ||
for (var i = 0; i < drivers.length; i++) { | ||
var driver = drivers[i]; | ||
if (typeof drivers === 'string') { | ||
drivers = [drivers]; | ||
} | ||
if (this.supports(driver)) { | ||
return driver; | ||
} | ||
} | ||
} | ||
this._driverSet = new Promise(function(resolve, reject) { | ||
var driverName = self._getFirstSupportedDriver(drivers); | ||
return null; | ||
}, | ||
if (!driverName) { | ||
var error = new Error('No available storage method found.'); | ||
self._driverSet = Promise.reject(error); | ||
supports: function(driverName) { | ||
return !!driverSupport[driverName]; | ||
}, | ||
reject(error); | ||
ready: function(callback) { | ||
var ready = new Promise(function(resolve, reject) { | ||
localForage._driverSet.then(function() { | ||
if (localForage._ready === null) { | ||
localForage._ready = localForage._initStorage( | ||
localForage._config); | ||
} | ||
return; | ||
} | ||
localForage._ready.then(resolve, reject); | ||
}, reject); | ||
}); | ||
self._dbInfo = null; | ||
self._ready = null; | ||
ready.then(callback, callback); | ||
// We allow localForage to be declared as a module or as a | ||
// library available without AMD/require.js. | ||
if (moduleType === ModuleType.DEFINE) { | ||
require([driverName], function(lib) { | ||
self._extend(lib); | ||
return ready; | ||
}, | ||
resolve(); | ||
}); | ||
_extend: function(libraryMethodsAndProperties) { | ||
for (var i in libraryMethodsAndProperties) { | ||
if (libraryMethodsAndProperties.hasOwnProperty(i)) { | ||
this[i] = libraryMethodsAndProperties[i]; | ||
return; | ||
} else if (moduleType === ModuleType.EXPORT) { | ||
// Making it browserify friendly | ||
var driver; | ||
switch (driverName) { | ||
case self.INDEXEDDB: | ||
driver = require('./drivers/indexeddb'); | ||
break; | ||
case self.LOCALSTORAGE: | ||
driver = require('./drivers/localstorage'); | ||
break; | ||
case self.WEBSQL: | ||
driver = require('./drivers/websql'); | ||
} | ||
self._extend(driver); | ||
} else { | ||
self._extend(_this[driverName]); | ||
} | ||
} | ||
resolve(); | ||
}); | ||
this._driverSet.then(callback, errorCallback); | ||
return this._driverSet; | ||
}; | ||
// Check to see if IndexedDB is available and if it is the latest | ||
// implementation; it's our preferred backend library. We use "_spec_test" | ||
// as the name of the database because it's not the one we'll operate on, | ||
// but it's useful to make sure its using the right spec. | ||
// See: https://github.com/mozilla/localForage/issues/128 | ||
var driverSupport = (function(_this) { | ||
// Initialize IndexedDB; fall back to vendor-prefixed versions | ||
// if needed. | ||
var indexedDB = indexedDB || _this.indexedDB || _this.webkitIndexedDB || | ||
_this.mozIndexedDB || _this.OIndexedDB || | ||
_this.msIndexedDB; | ||
LocalForage.prototype.supports = function(driverName) { | ||
return !!driverSupport[driverName]; | ||
}; | ||
var result = {}; | ||
LocalForage.prototype._extend = function(libraryMethodsAndProperties) { | ||
extend(this, libraryMethodsAndProperties); | ||
}; | ||
result[localForage.WEBSQL] = !!_this.openDatabase; | ||
result[localForage.INDEXEDDB] = !!( | ||
indexedDB && | ||
typeof indexedDB.open === 'function' && | ||
indexedDB.open('_localforage_spec_test', 1) | ||
.onupgradeneeded === null | ||
); | ||
LocalForage.prototype._getFirstSupportedDriver = function(drivers) { | ||
var isArray = Array.isArray || function(arg) { | ||
return Object.prototype.toString.call(arg) === '[object Array]'; | ||
}; | ||
result[localForage.LOCALSTORAGE] = !!(function() { | ||
try { | ||
return (localStorage && | ||
typeof localStorage.setItem === 'function'); | ||
} catch (e) { | ||
return false; | ||
if (drivers && isArray(drivers)) { | ||
for (var i = 0; i < drivers.length; i++) { | ||
var driver = drivers[i]; | ||
if (this.supports(driver)) { | ||
return driver; | ||
} | ||
} | ||
})(); | ||
} | ||
return result; | ||
})(this); | ||
return null; | ||
}; | ||
var driverTestOrder = [ | ||
localForage.INDEXEDDB, | ||
localForage.WEBSQL, | ||
localForage.LOCALSTORAGE | ||
]; | ||
LocalForage.prototype.createInstance = function(options) { | ||
return new LocalForage(options); | ||
}; | ||
localForage.setDriver(driverTestOrder); | ||
var localForage = new LocalForage(); | ||
// We allow localForage to be declared as a module or as a library | ||
// available without AMD/require.js. | ||
if (moduleType === MODULE_TYPE_DEFINE) { | ||
if (moduleType === ModuleType.DEFINE) { | ||
define(function() { | ||
return localForage; | ||
}); | ||
} else if (moduleType === MODULE_TYPE_EXPORT) { | ||
} else if (moduleType === ModuleType.EXPORT) { | ||
module.exports = localForage; | ||
@@ -1626,2 +1739,2 @@ } else { | ||
} | ||
}).call(this); | ||
}).call(window); |
@@ -1,1 +0,1 @@ | ||
(function(){"use strict";function a(a){if(a)for(var b in a)l[b]=a[b];return new j(function(a,b){var c=m.open(l.name,l.version);c.onerror=function(){b(c.error)},c.onupgradeneeded=function(){c.result.createObjectStore(l.storeName)},c.onsuccess=function(){k=c.result,a()}})}function b(a,b){var c=this;return new j(function(d,e){c.ready().then(function(){var c=k.transaction(l.storeName,"readonly").objectStore(l.storeName),f=c.get(a);f.onsuccess=function(){var a=f.result;void 0===a&&(a=null),i(b,a),d(a)},f.onerror=function(){b&&b(null,f.error),e(f.error)}},e)})}function c(a,b,c){var d=this;return new j(function(e,f){d.ready().then(function(){var d=k.transaction(l.storeName,"readwrite").objectStore(l.storeName);null===b&&(b=void 0);var g=d.put(b,a);g.onsuccess=function(){void 0===b&&(b=null),i(c,b),e(b)},g.onerror=function(){c&&c(null,g.error),f(g.error)}},f)})}function d(a,b){var c=this;return new j(function(d,e){c.ready().then(function(){var c=k.transaction(l.storeName,"readwrite").objectStore(l.storeName),f=c["delete"](a);f.onsuccess=function(){i(b),d()},f.onerror=function(){b&&b(f.error),e(f.error)},f.onabort=function(a){var c=a.target.error;"QuotaExceededError"===c&&(b&&b(c),e(c))}},e)})}function e(a){var b=this;return new j(function(c,d){b.ready().then(function(){var b=k.transaction(l.storeName,"readwrite").objectStore(l.storeName),e=b.clear();e.onsuccess=function(){i(a),c()},e.onerror=function(){a&&a(null,e.error),d(e.error)}},d)})}function f(a){var b=this;return new j(function(c,d){b.ready().then(function(){var b=k.transaction(l.storeName,"readonly").objectStore(l.storeName),e=b.count();e.onsuccess=function(){a&&a(e.result),c(e.result)},e.onerror=function(){a&&a(null,e.error),d(e.error)}},d)})}function g(a,b){var c=this;return new j(function(d,e){return 0>a?(b&&b(null),void d(null)):void c.ready().then(function(){var c=k.transaction(l.storeName,"readonly").objectStore(l.storeName),f=!1,g=c.openCursor();g.onsuccess=function(){var c=g.result;return c?void(0===a?(b&&b(c.key),d(c.key)):f?(b&&b(c.key),d(c.key)):(f=!0,c.advance(a))):(b&&b(null),void d(null))},g.onerror=function(){b&&b(null,g.error),e(g.error)}},e)})}function h(a){var b=this;return new j(function(c,d){b.ready().then(function(){var b=k.transaction(l.storeName,"readonly").objectStore(l.storeName),e=b.openCursor(),f=[];e.onsuccess=function(){var b=e.result;return b?(f.push(b.key),void b["continue"]()):(a&&a(f),void c(f))},e.onerror=function(){a&&a(null,e.error),d(e.error)}},d)})}function i(a,b){return a?setTimeout(function(){return a(b)},0):void 0}var j="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,k=null,l={},m=m||this.indexedDB||this.webkitIndexedDB||this.mozIndexedDB||this.OIndexedDB||this.msIndexedDB;if(m){var n={_driver:"asyncStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("asyncStorage",function(){return n}):"undefined"!=typeof module&&module.exports?module.exports=n:this.asyncStorage=n}}).call(this),function(){"use strict";function a(a){if(a)for(var b in a)m[b]=a[b];return l=m.name+"/",n.resolve()}function b(a){var b=this;return new n(function(c,d){b.ready().then(function(){o.clear(),a&&a(),c()},d)})}function c(a,b){var c=this;return new n(function(d,e){c.ready().then(function(){try{var c=o.getItem(l+a);c&&(c=h(c)),b&&b(c),d(c)}catch(f){b&&b(null,f),e(f)}},e)})}function d(a,b){var c=this;return new n(function(d,e){c.ready().then(function(){var c;try{c=o.key(a)}catch(e){c=null}c&&(c=c.substring(l.length)),b&&b(c),d(c)},e)})}function e(a){var b=this;return new n(function(c,d){b.ready().then(function(){for(var b=o.length,d=[],e=0;b>e;e++)d.push(o.key(e).substring(l.length));a&&a(d),c(d)},d)})}function f(a){var b=this;return new n(function(c,d){b.ready().then(function(){var b=o.length;a&&a(b),c(b)},d)})}function g(a,b){var c=this;return new n(function(d,e){c.ready().then(function(){o.removeItem(l+a),b&&b(),d()},e)})}function h(a){if(a.substring(0,r)!==q)return JSON.parse(a);for(var b=a.substring(D),c=a.substring(r,D),d=new ArrayBuffer(2*b.length),e=new Uint16Array(d),f=b.length-1;f>=0;f--)e[f]=b.charCodeAt(f);switch(c){case s:return d;case t:return new Blob([d]);case u:return new Int8Array(d);case v:return new Uint8Array(d);case w:return new Uint8ClampedArray(d);case x:return new Int16Array(d);case z:return new Uint16Array(d);case y:return new Int32Array(d);case A:return new Uint32Array(d);case B:return new Float32Array(d);case C:return new Float64Array(d);default:throw new Error("Unkown type: "+c)}}function i(a){var b="",c=new Uint16Array(a);try{b=String.fromCharCode.apply(null,c)}catch(d){for(var e=0;e<c.length;e++)b+=String.fromCharCode(c[e])}return b}function j(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=q;a instanceof ArrayBuffer?(d=a,e+=s):(d=a.buffer,"[object Int8Array]"===c?e+=u:"[object Uint8Array]"===c?e+=v:"[object Uint8ClampedArray]"===c?e+=w:"[object Int16Array]"===c?e+=x:"[object Uint16Array]"===c?e+=z:"[object Int32Array]"===c?e+=y:"[object Uint32Array]"===c?e+=A:"[object Float32Array]"===c?e+=B:"[object Float64Array]"===c?e+=C:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(q+t+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){this.console&&this.console.error&&this.console.error("Couldn't convert value into a JSON string: ",a),b(null,g)}}function k(a,b,c){var d=this;return new n(function(e,f){d.ready().then(function(){void 0===b&&(b=null);var d=b;j(b,function(b,g){if(g)c&&c(null,g),f(g);else{try{o.setItem(l+a,b)}catch(h){("QuotaExceededError"===h.name||"NS_ERROR_DOM_QUOTA_REACHED"===h.name)&&(c&&c(null,h),f(h))}c&&c(d),e(d)}})},f)})}var l="",m={},n="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,o=null;try{if(!(this.localStorage&&"setItem"in this.localStorage))return;o=this.localStorage}catch(p){return}var q="__lfsc__:",r=q.length,s="arbf",t="blob",u="si08",v="ui08",w="uic8",x="si16",y="si32",z="ur16",A="ui32",B="fl32",C="fl64",D=r+s.length,E={_driver:"localStorageWrapper",_initStorage:a,getItem:c,setItem:k,removeItem:g,clear:b,length:f,key:d,keys:e};"function"==typeof define&&define.amd?define("localStorageWrapper",function(){return E}):"undefined"!=typeof module&&module.exports?module.exports=E:this.localStorageWrapper=E}.call(this),function(){"use strict";function a(a){var b=this;if(a)for(var c in a)p[c]="string"!=typeof a[c]?a[c].toString():a[c];return new m(function(a,c){try{o=n(p.name,p.version,p.description,p.size)}catch(d){return b.setDriver("localStorageWrapper").then(a,c)}o.transaction(function(b){b.executeSql("CREATE TABLE IF NOT EXISTS "+p.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){a()},function(a,b){c(b)})})})}function b(a,b){var c=this;return new m(function(d,e){c.ready().then(function(){o.transaction(function(c){c.executeSql("SELECT * FROM "+p.storeName+" WHERE key = ? LIMIT 1",[a],function(a,c){var e=c.rows.length?c.rows.item(0).value:null;e&&(e=j(e)),b&&b(e),d(e)},function(a,c){b&&b(null,c),e(c)})})},e)})}function c(a,b,c){var d=this;return new m(function(e,f){d.ready().then(function(){void 0===b&&(b=null);var d=b;k(b,function(b,g){g?f(g):o.transaction(function(g){g.executeSql("INSERT OR REPLACE INTO "+p.storeName+" (key, value) VALUES (?, ?)",[a,b],function(){c&&c(d),e(d)},function(a,b){c&&c(null,b),f(b)})},function(a){a.code===a.QUOTA_ERR&&(c&&c(null,a),f(a))})})},f)})}function d(a,b){var c=this;return new m(function(d,e){c.ready().then(function(){o.transaction(function(c){c.executeSql("DELETE FROM "+p.storeName+" WHERE key = ?",[a],function(){b&&b(),d()},function(a,c){b&&b(c),e(c)})})},e)})}function e(a){var b=this;return new m(function(c,d){b.ready().then(function(){o.transaction(function(b){b.executeSql("DELETE FROM "+p.storeName,[],function(){a&&a(),c()},function(b,c){a&&a(c),d(c)})})},d)})}function f(a){var b=this;return new m(function(c,d){b.ready().then(function(){o.transaction(function(b){b.executeSql("SELECT COUNT(key) as c FROM "+p.storeName,[],function(b,d){var e=d.rows.item(0).c;a&&a(e),c(e)},function(b,c){a&&a(null,c),d(c)})})},d)})}function g(a,b){var c=this;return new m(function(d,e){c.ready().then(function(){o.transaction(function(c){c.executeSql("SELECT key FROM "+p.storeName+" WHERE id = ? LIMIT 1",[a+1],function(a,c){var e=c.rows.length?c.rows.item(0).key:null;b&&b(e),d(e)},function(a,c){b&&b(null,c),e(c)})})},e)})}function h(a){var b=this;return new m(function(c,d){b.ready().then(function(){o.transaction(function(b){b.executeSql("SELECT key FROM "+p.storeName,[],function(b,d){for(var e=d.rows.length,f=[],g=0;e>g;g++)f.push(d.rows.item(g).key);a&&a(f),c(f)},function(b,c){a&&a(null,c),d(c)})})},d)})}function i(a){var b,c=new Uint8Array(a),d="";for(b=0;b<c.length;b+=3)d+=l[c[b]>>2],d+=l[(3&c[b])<<4|c[b+1]>>4],d+=l[(15&c[b+1])<<2|c[b+2]>>6],d+=l[63&c[b+2]];return c.length%3===2?d=d.substring(0,d.length-1)+"=":c.length%3===1&&(d=d.substring(0,d.length-2)+"=="),d}function j(a){if(a.substring(0,r)!==q)return JSON.parse(a);var b,c,d,e,f,g=a.substring(D),h=a.substring(r,D),i=.75*g.length,j=g.length,k=0;"="===g[g.length-1]&&(i--,"="===g[g.length-2]&&i--);var m=new ArrayBuffer(i),n=new Uint8Array(m);for(b=0;j>b;b+=4)c=l.indexOf(g[b]),d=l.indexOf(g[b+1]),e=l.indexOf(g[b+2]),f=l.indexOf(g[b+3]),n[k++]=c<<2|d>>4,n[k++]=(15&d)<<4|e>>2,n[k++]=(3&e)<<6|63&f;switch(h){case s:return m;case t:return new Blob([m]);case u:return new Int8Array(m);case v:return new Uint8Array(m);case w:return new Uint8ClampedArray(m);case x:return new Int16Array(m);case z:return new Uint16Array(m);case y:return new Int32Array(m);case A:return new Uint32Array(m);case B:return new Float32Array(m);case C:return new Float64Array(m);default:throw new Error("Unkown type: "+h)}}function k(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=q;a instanceof ArrayBuffer?(d=a,e+=s):(d=a.buffer,"[object Int8Array]"===c?e+=u:"[object Uint8Array]"===c?e+=v:"[object Uint8ClampedArray]"===c?e+=w:"[object Int16Array]"===c?e+=x:"[object Uint16Array]"===c?e+=z:"[object Int32Array]"===c?e+=y:"[object Uint32Array]"===c?e+=A:"[object Float32Array]"===c?e+=B:"[object Float64Array]"===c?e+=C:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(q+t+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){this.console&&this.console.error&&this.console.error("Couldn't convert value into a JSON string: ",a),b(null,g)}}var l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",m="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,n=this.openDatabase,o=null,p={},q="__lfsc__:",r=q.length,s="arbf",t="blob",u="si08",v="ui08",w="uic8",x="si16",y="si32",z="ur16",A="ui32",B="fl32",C="fl64",D=r+s.length;if(n){var E={_driver:"webSQLStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("webSQLStorage",function(){return E}):"undefined"!=typeof module&&module.exports?module.exports=E:this.webSQLStorage=E}}.call(this),function(){"use strict";var a="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,b=1,c=2,d=3,e=d;"function"==typeof define&&define.amd?e=b:"undefined"!=typeof module&&module.exports&&(e=c);var f=this,g={INDEXEDDB:"asyncStorage",LOCALSTORAGE:"localStorageWrapper",WEBSQL:"webSQLStorage",_config:{description:"",name:"localforage",size:4980736,storeName:"keyvaluepairs",version:1},config:function(a){if("object"==typeof a){if(this._ready)return new Error("Can't call config() after localforage has been used.");for(var b in a)this._config[b]=a[b];return!0}return"string"==typeof a?this._config[a]:this._config},driver:function(){return this._driver||null},_ready:!1,_driverSet:null,setDriver:function(d,g,h){var i=this,j=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)};return j(d)||"string"!=typeof d||(d=[d]),this._driverSet=new a(function(j,k){var l=i._getFirstSupportedDriver(d);if(!l){var m=new Error("No available storage method found.");return i._driverSet=a.reject(m),h&&h(m),void k(m)}if(i._ready=null,e===b)return void require([l],function(a){i._extend(a),g&&g(),j()});if(e===c){var n;switch(l){case i.INDEXEDDB:n=require("./drivers/indexeddb");break;case i.LOCALSTORAGE:n=require("./drivers/localstorage");break;case i.WEBSQL:n=require("./drivers/websql")}i._extend(n)}else i._extend(f[l]);g&&g(),j()}),this._driverSet},_getFirstSupportedDriver:function(a){if(a)for(var b=0;b<a.length;b++){var c=a[b];if(this.supports(c))return c}return null},supports:function(a){return!!h[a]},ready:function(b){var c=new a(function(a,b){g._driverSet.then(function(){null===g._ready&&(g._ready=g._initStorage(g._config)),g._ready.then(a,b)},b)});return c.then(b,b),c},_extend:function(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])}},h=function(a){var b=b||a.indexedDB||a.webkitIndexedDB||a.mozIndexedDB||a.OIndexedDB||a.msIndexedDB,c={};return c[g.WEBSQL]=!!a.openDatabase,c[g.INDEXEDDB]=!(!b||"function"!=typeof b.open||null!==b.open("_localforage_spec_test",1).onupgradeneeded),c[g.LOCALSTORAGE]=!!function(){try{return localStorage&&"function"==typeof localStorage.setItem}catch(a){return!1}}(),c}(this),i=[g.INDEXEDDB,g.WEBSQL,g.LOCALSTORAGE];g.setDriver(i),e===b?define(function(){return g}):e===c?module.exports=g:this.localforage=g}.call(this); | ||
(function(){"use strict";function a(a){var b=this,c={db:null};if(a)for(var d in a)c[d]=a[d];return new l(function(a,d){var e=m.open(c.name,c.version);e.onerror=function(){d(e.error)},e.onupgradeneeded=function(){e.result.createObjectStore(c.storeName)},e.onsuccess=function(){c.db=e.result,b._dbInfo=c,a()}})}function b(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new l(function(b,d){c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readonly").objectStore(e.storeName),g=f.get(a);g.onsuccess=function(){var a=g.result;void 0===a&&(a=null),b(a)},g.onerror=function(){d(g.error)}})["catch"](d)});return j(d,b),d}function c(a,b,c){var d=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var e=new l(function(c,e){d.ready().then(function(){var f=d._dbInfo,g=f.db.transaction(f.storeName,"readwrite").objectStore(f.storeName);null===b&&(b=void 0);var h=g.put(b,a);h.onsuccess=function(){void 0===b&&(b=null),c(b)},h.onerror=function(){e(h.error)}})["catch"](e)});return j(e,c),e}function d(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new l(function(b,d){c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readwrite").objectStore(e.storeName),g=f["delete"](a);g.onsuccess=function(){b()},g.onerror=function(){d(g.error)},g.onabort=function(a){var b=a.target.error;"QuotaExceededError"===b&&d(b)}})["catch"](d)});return j(d,b),d}function e(a){var b=this,c=new l(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readwrite").objectStore(d.storeName),f=e.clear();f.onsuccess=function(){a()},f.onerror=function(){c(f.error)}})["catch"](c)});return j(c,a),c}function f(a){var b=this,c=new l(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readonly").objectStore(d.storeName),f=e.count();f.onsuccess=function(){a(f.result)},f.onerror=function(){c(f.error)}})["catch"](c)});return i(c,a),c}function g(a,b){var c=this,d=new l(function(b,d){return 0>a?void b(null):void c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readonly").objectStore(e.storeName),g=!1,h=f.openCursor();h.onsuccess=function(){var c=h.result;return c?void(0===a?b(c.key):g?b(c.key):(g=!0,c.advance(a))):void b(null)},h.onerror=function(){d(h.error)}})["catch"](d)});return i(d,b),d}function h(a){var b=this,c=new l(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readonly").objectStore(d.storeName),f=e.openCursor(),g=[];f.onsuccess=function(){var b=f.result;return b?(g.push(b.key),void b["continue"]()):void a(g)},f.onerror=function(){c(f.error)}})["catch"](c)});return i(c,a),c}function i(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}function j(a,b){b&&a.then(function(a){k(b,a)},function(a){b(a)})}function k(a,b){return a?setTimeout(function(){return a(null,b)},0):void 0}var l="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,m=m||this.indexedDB||this.webkitIndexedDB||this.mozIndexedDB||this.OIndexedDB||this.msIndexedDB;if(m){var n={_driver:"asyncStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("asyncStorage",function(){return n}):"undefined"!=typeof module&&module.exports?module.exports=n:this.asyncStorage=n}}).call(window),function(){"use strict";function a(a){var b=this,c={};if(a)for(var d in a)c[d]=a[d];return c.keyPrefix=c.name+"/",b._dbInfo=c,m.resolve()}function b(a){var b=this,c=new m(function(a,c){b.ready().then(function(){n.clear(),a()})["catch"](c)});return l(c,a),c}function c(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new m(function(b,d){c.ready().then(function(){try{var e=c._dbInfo,f=n.getItem(e.keyPrefix+a);f&&(f=h(f)),b(f)}catch(g){d(g)}})["catch"](d)});return l(d,b),d}function d(a,b){var c=this,d=new m(function(b,d){c.ready().then(function(){var d,e=c._dbInfo;try{d=n.key(a)}catch(f){d=null}d&&(d=d.substring(e.keyPrefix.length)),b(d)})["catch"](d)});return l(d,b),d}function e(a){var b=this,c=new m(function(a,c){b.ready().then(function(){for(var c=b._dbInfo,d=n.length,e=[],f=0;d>f;f++)e.push(n.key(f).substring(c.keyPrefix.length));a(e)})["catch"](c)});return l(c,a),c}function f(a){var b=this,c=new m(function(a,c){b.ready().then(function(){var b=n.length;a(b)})["catch"](c)});return l(c,a),c}function g(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new m(function(b,d){c.ready().then(function(){var d=c._dbInfo;n.removeItem(d.keyPrefix+a),b()})["catch"](d)});return l(d,b),d}function h(a){if(a.substring(0,q)!==p)return JSON.parse(a);for(var b=a.substring(C),c=a.substring(q,C),d=new ArrayBuffer(2*b.length),e=new Uint16Array(d),f=b.length-1;f>=0;f--)e[f]=b.charCodeAt(f);switch(c){case r:return d;case s:return new Blob([d]);case t:return new Int8Array(d);case u:return new Uint8Array(d);case v:return new Uint8ClampedArray(d);case w:return new Int16Array(d);case y:return new Uint16Array(d);case x:return new Int32Array(d);case z:return new Uint32Array(d);case A:return new Float32Array(d);case B:return new Float64Array(d);default:throw new Error("Unkown type: "+c)}}function i(a){var b="",c=new Uint16Array(a);try{b=String.fromCharCode.apply(null,c)}catch(d){for(var e=0;e<c.length;e++)b+=String.fromCharCode(c[e])}return b}function j(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=p;a instanceof ArrayBuffer?(d=a,e+=r):(d=a.buffer,"[object Int8Array]"===c?e+=t:"[object Uint8Array]"===c?e+=u:"[object Uint8ClampedArray]"===c?e+=v:"[object Int16Array]"===c?e+=w:"[object Uint16Array]"===c?e+=y:"[object Int32Array]"===c?e+=x:"[object Uint32Array]"===c?e+=z:"[object Float32Array]"===c?e+=A:"[object Float64Array]"===c?e+=B:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(p+s+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){window.console.error("Couldn't convert value into a JSON string: ",a),b(g)}}function k(a,b,c){var d=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var e=new m(function(c,e){d.ready().then(function(){void 0===b&&(b=null);var f=b;j(b,function(b,g){if(g)e(g);else{try{var h=d._dbInfo;n.setItem(h.keyPrefix+a,b)}catch(i){("QuotaExceededError"===i.name||"NS_ERROR_DOM_QUOTA_REACHED"===i.name)&&e(i)}c(f)}})})["catch"](e)});return l(e,c),e}function l(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}var m="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,n=null;try{if(!(this.localStorage&&"setItem"in this.localStorage))return;n=this.localStorage}catch(o){return}var p="__lfsc__:",q=p.length,r="arbf",s="blob",t="si08",u="ui08",v="uic8",w="si16",x="si32",y="ur16",z="ui32",A="fl32",B="fl64",C=q+r.length,D={_driver:"localStorageWrapper",_initStorage:a,getItem:c,setItem:k,removeItem:g,clear:b,length:f,key:d,keys:e};"function"==typeof define&&define.amd?define("localStorageWrapper",function(){return D}):"undefined"!=typeof module&&module.exports?module.exports=D:this.localStorageWrapper=D}.call(window),function(){"use strict";function a(a){var b=this,c={db:null};if(a)for(var d in a)c[d]="string"!=typeof a[d]?a[d].toString():a[d];return new n(function(d,e){try{c.db=o(c.name,String(c.version),c.description,c.size)}catch(f){return b.setDriver("localStorageWrapper").then(function(){return b._initStorage(a)}).then(d)["catch"](e)}c.db.transaction(function(a){a.executeSql("CREATE TABLE IF NOT EXISTS "+c.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){b._dbInfo=c,d()},function(a,b){e(b)})})})}function b(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new n(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("SELECT * FROM "+e.storeName+" WHERE key = ? LIMIT 1",[a],function(a,c){var d=c.rows.length?c.rows.item(0).value:null;d&&(d=j(d)),b(d)},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function c(a,b,c){var d=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var e=new n(function(c,e){d.ready().then(function(){void 0===b&&(b=null);var f=b;k(b,function(b,g){if(g)e(g);else{var h=d._dbInfo;h.db.transaction(function(d){d.executeSql("INSERT OR REPLACE INTO "+h.storeName+" (key, value) VALUES (?, ?)",[a,b],function(){c(f)},function(a,b){e(b)})},function(a){a.code===a.QUOTA_ERR&&e(a)})}})})["catch"](e)});return l(e,c),e}function d(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new n(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("DELETE FROM "+e.storeName+" WHERE key = ?",[a],function(){b()},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function e(a){var b=this,c=new n(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("DELETE FROM "+d.storeName,[],function(){a()},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function f(a){var b=this,c=new n(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("SELECT COUNT(key) as c FROM "+d.storeName,[],function(b,c){var d=c.rows.item(0).c;a(d)},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function g(a,b){var c=this,d=new n(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("SELECT key FROM "+e.storeName+" WHERE id = ? LIMIT 1",[a+1],function(a,c){var d=c.rows.length?c.rows.item(0).key:null;b(d)},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function h(a){var b=this,c=new n(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("SELECT key FROM "+d.storeName,[],function(b,c){for(var d=[],e=0;e<c.rows.length;e++)d.push(c.rows.item(e).key);a(d)},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function i(a){var b,c=new Uint8Array(a),d="";for(b=0;b<c.length;b+=3)d+=m[c[b]>>2],d+=m[(3&c[b])<<4|c[b+1]>>4],d+=m[(15&c[b+1])<<2|c[b+2]>>6],d+=m[63&c[b+2]];return c.length%3===2?d=d.substring(0,d.length-1)+"=":c.length%3===1&&(d=d.substring(0,d.length-2)+"=="),d}function j(a){if(a.substring(0,q)!==p)return JSON.parse(a);var b,c,d,e,f,g=a.substring(C),h=a.substring(q,C),i=.75*g.length,j=g.length,k=0;"="===g[g.length-1]&&(i--,"="===g[g.length-2]&&i--);var l=new ArrayBuffer(i),n=new Uint8Array(l);for(b=0;j>b;b+=4)c=m.indexOf(g[b]),d=m.indexOf(g[b+1]),e=m.indexOf(g[b+2]),f=m.indexOf(g[b+3]),n[k++]=c<<2|d>>4,n[k++]=(15&d)<<4|e>>2,n[k++]=(3&e)<<6|63&f;switch(h){case r:return l;case s:return new Blob([l]);case t:return new Int8Array(l);case u:return new Uint8Array(l);case v:return new Uint8ClampedArray(l);case w:return new Int16Array(l);case y:return new Uint16Array(l);case x:return new Int32Array(l);case z:return new Uint32Array(l);case A:return new Float32Array(l);case B:return new Float64Array(l);default:throw new Error("Unkown type: "+h)}}function k(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=p;a instanceof ArrayBuffer?(d=a,e+=r):(d=a.buffer,"[object Int8Array]"===c?e+=t:"[object Uint8Array]"===c?e+=u:"[object Uint8ClampedArray]"===c?e+=v:"[object Int16Array]"===c?e+=w:"[object Uint16Array]"===c?e+=y:"[object Int32Array]"===c?e+=x:"[object Uint32Array]"===c?e+=z:"[object Float32Array]"===c?e+=A:"[object Float64Array]"===c?e+=B:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(p+s+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){window.console.error("Couldn't convert value into a JSON string: ",a),b(null,g)}}function l(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}var m="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,o=this.openDatabase,p="__lfsc__:",q=p.length,r="arbf",s="blob",t="si08",u="ui08",v="uic8",w="si16",x="si32",y="ur16",z="ui32",A="fl32",B="fl64",C=q+r.length;if(o){var D={_driver:"webSQLStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("webSQLStorage",function(){return D}):"undefined"!=typeof module&&module.exports?module.exports=D:this.webSQLStorage=D}}.call(window),function(){"use strict";function a(){for(var a=1;a<arguments.length;a++){var b=arguments[a];if(b)for(var c in b)b.hasOwnProperty(c)&&(arguments[0][c]=b[c])}return arguments[0]}function b(a,b){a[b]=function(){var c=arguments;return a.ready().then(function(){return a[b].apply(a,c)})}}function c(c){this._config=a({},i,c),this._driverSet=null,this._ready=!1,this._dbInfo=null;for(var d=0;d<g.length;d++)b(this,g[d]);this.setDriver(f)}var d="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,e={INDEXEDDB:"asyncStorage",LOCALSTORAGE:"localStorageWrapper",WEBSQL:"webSQLStorage"},f=[e.INDEXEDDB,e.WEBSQL,e.LOCALSTORAGE],g=["clear","getItem","key","keys","length","removeItem","setItem"],h={DEFINE:1,EXPORT:2,WINDOW:3},i={description:"",name:"localforage",size:4980736,storeName:"keyvaluepairs",version:1},j=h.WINDOW;"function"==typeof define&&define.amd?j=h.DEFINE:"undefined"!=typeof module&&module.exports&&(j=h.EXPORT);var k=function(a){var b=b||a.indexedDB||a.webkitIndexedDB||a.mozIndexedDB||a.OIndexedDB||a.msIndexedDB,c={};return c[e.WEBSQL]=!!a.openDatabase,c[e.INDEXEDDB]=!!function(){try{return b&&"function"==typeof b.open&&null===b.open("_localforage_spec_test",1).onupgradeneeded}catch(a){return!1}}(),c[e.LOCALSTORAGE]=!!function(){try{return localStorage&&"function"==typeof localStorage.setItem}catch(a){return!1}}(),c}(this),l=this;c.prototype.INDEXEDDB=e.INDEXEDDB,c.prototype.LOCALSTORAGE=e.LOCALSTORAGE,c.prototype.WEBSQL=e.WEBSQL,c.prototype.config=function(a){if("object"==typeof a){if(this._ready)return new Error("Can't call config() after localforage has been used.");for(var b in a)"storeName"===b&&(a[b]=a[b].replace(/\W/g,"_")),this._config[b]=a[b];return!0}return"string"==typeof a?this._config[a]:this._config},c.prototype.driver=function(){return this._driver||null},c.prototype.ready=function(a){var b=this,c=new d(function(a,c){b._driverSet.then(function(){null===b._ready&&(b._ready=b._initStorage(b._config)),b._ready.then(a,c)})["catch"](c)});return c.then(a,a),c},c.prototype.setDriver=function(a,b,c){var e=this;return"string"==typeof a&&(a=[a]),this._driverSet=new d(function(b,c){var f=e._getFirstSupportedDriver(a);if(!f){var g=new Error("No available storage method found.");return e._driverSet=d.reject(g),void c(g)}if(e._dbInfo=null,e._ready=null,j===h.DEFINE)return void require([f],function(a){e._extend(a),b()});if(j===h.EXPORT){var i;switch(f){case e.INDEXEDDB:i=require("./drivers/indexeddb");break;case e.LOCALSTORAGE:i=require("./drivers/localstorage");break;case e.WEBSQL:i=require("./drivers/websql")}e._extend(i)}else e._extend(l[f]);b()}),this._driverSet.then(b,c),this._driverSet},c.prototype.supports=function(a){return!!k[a]},c.prototype._extend=function(b){a(this,b)},c.prototype._getFirstSupportedDriver=function(a){var b=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)};if(a&&b(a))for(var c=0;c<a.length;c++){var d=a[c];if(this.supports(d))return d}return null},c.prototype.createInstance=function(a){return new c(a)};var m=new c;j===h.DEFINE?define(function(){return m}):j===h.EXPORT?module.exports=m:this.localforage=m}.call(window); |
@@ -18,3 +18,3 @@ /* jshint node:true */ | ||
options: { | ||
separator: '', | ||
separator: '' | ||
}, | ||
@@ -32,3 +32,3 @@ localforage: { | ||
'src/localforage.js' | ||
], | ||
] | ||
}, | ||
@@ -39,3 +39,3 @@ options: { | ||
' localForage -- Offline Storage, Improved\n' + | ||
' Version 0.9.2\n' + | ||
' Version 0.9.3\n' + | ||
' http://mozilla.github.io/localForage\n' + | ||
@@ -100,3 +100,4 @@ ' (c) 2013-2014 Mozilla, Apache License 2.0\n' + | ||
'http://localhost:9999/test/test.min.html', | ||
'http://localhost:9999/test/test.require.html' | ||
'http://localhost:9999/test/test.require.html', | ||
'http://localhost:9999/test/test.callwhenready.html' | ||
] | ||
@@ -103,0 +104,0 @@ } |
@@ -11,3 +11,3 @@ { | ||
], | ||
"version": "0.9.2", | ||
"version": "0.9.3", | ||
"homepage": "https://github.com/mozilla/localForage", | ||
@@ -41,3 +41,3 @@ "repository": { | ||
}, | ||
"browser": "dist/localforage.js", | ||
"browser": "src/localforage.js", | ||
"main": "dist/localforage.js", | ||
@@ -47,3 +47,6 @@ "licence": "Apache-2.0", | ||
"url": "http://github.com/mozilla/localForage/issues" | ||
}, | ||
"dependencies": { | ||
"promise": "^5.0.0" | ||
} | ||
} |
@@ -32,3 +32,3 @@ # localForage [![Build Status](https://secure.travis-ci.org/mozilla/localForage.png?branch=master)](http://travis-ci.org/mozilla/localForage) | ||
* **Android Browser 2.1** | ||
* **Android Browser 2.1** | ||
* **Blackberry 7** | ||
@@ -55,3 +55,3 @@ * **Chrome 23** (Chrome 4.0+ with localStorage) | ||
Lost? Need help? Try the | ||
[localForage API documentation](http://mozilla.github.io/localForage). | ||
[localForage API documentation](https://mozilla.github.io/localForage). | ||
@@ -97,2 +97,16 @@ If you're stuck using the library, running the tests, or want to contribute, | ||
Note that callbacks in localForage are Node-style (error argument first) since | ||
`0.9.3`. This means if you're using callbacks, your code should look like this: | ||
```javascript | ||
// Use err as your first argument. | ||
localforage.getItem('key', function(err, value) { | ||
if (err) { | ||
console.error('Oh noes!'); | ||
} | ||
alert(value); | ||
}); | ||
``` | ||
You can store any type in localForage; you aren't limited to strings like in | ||
@@ -117,2 +131,14 @@ localStorage. Even if localStorage is your storage backend, localForage | ||
Note that with Promises, `err` is not the first argument to your function. | ||
Instead, you handle an error with the rejection part of the Promise: | ||
```javascript | ||
// A full setItem() call with Promises. | ||
localforage.setItem('key', 'value').then(function(value) { | ||
alert(value + ' was set!'); | ||
}, function(error) { | ||
console.error(error); | ||
}); | ||
``` | ||
localForage relies on native [ES6 Promises](http://www.promisejs.org/), but | ||
@@ -131,3 +157,3 @@ [ships with an awesome polyfill](https://github.com/jakearchibald/ES6-Promises) | ||
[api]: http://mozilla.github.io/localForage/#setitem | ||
[api]: https://mozilla.github.io/localForage/#setitem | ||
@@ -140,7 +166,7 @@ ## Driver Selection (i.e. forcing localStorage) | ||
to change the driver localForage is using at any time. | ||
```javascript | ||
// If you aren't using JS modules, things are loaded synchronously. | ||
localforage.setDriver('localStorageWrapper'); | ||
alert(localforage.driver); | ||
alert(localforage.driver()); | ||
=> 'localStorageWrapper' | ||
@@ -151,3 +177,3 @@ | ||
localforage.setDriver('localStorageWrapper', function() { | ||
alert(localforage.driver); | ||
alert(localforage.driver()); | ||
}); | ||
@@ -158,3 +184,3 @@ => 'localStorageWrapper' | ||
localforage.setDriver('localStorageWrapper').then(function() { | ||
alert(localforage.driver); | ||
alert(localforage.driver()); | ||
}); | ||
@@ -184,3 +210,3 @@ => 'localStorageWrapper' | ||
size : 4980736, // Size of database, in bytes. WebSQL-only for now. | ||
storeName : 'keyvaluepairs', | ||
storeName : 'keyvaluepairs', // Should be alphanumeric, with underscores. | ||
description : 'some description' | ||
@@ -196,7 +222,5 @@ }); | ||
You can use localForage with [RequireJS](http://requirejs.org/), but note that | ||
because of the way drivers are loaded using RequireJS, you'll want to make sure | ||
`localforage.ready`'s Promise has been fulfilled to ensure all of localForage | ||
is ready to use before you make set/get calls. Essentially, to use localForage | ||
with RequireJS, your code should look like this: | ||
You can use localForage with [RequireJS](http://requirejs.org/), and even though | ||
each driver will be loaded asynchronously with a `require()` call, you can use | ||
localForage without having to confirm that it's ready: | ||
@@ -206,13 +230,12 @@ ```javascript | ||
// As a callback: | ||
localforage.ready(function() { | ||
localforage.setItem('mykey', 'myvalue', console.log); | ||
}); | ||
localforage.setItem('mykey', 'myvalue', console.log); | ||
// With a Promise: | ||
localforage.ready().then(function() { | ||
localforage.setItem('mykey', 'myvalue', console.log); | ||
}); | ||
localforage.setItem('mykey', 'myvalue').then(console.log); | ||
}); | ||
``` | ||
In pre-1.0 versions you had to call `.ready()` to make sure the code was loaded, | ||
but this is no longer necessary. | ||
## Web Workers | ||
@@ -277,19 +300,2 @@ | ||
# Frequently Asked Questions | ||
### Will you add (or accept) support for X storage? | ||
Maybe. If it's legacy storage (< IE 8), for a dead platform (WebOS), or | ||
_really_ obscure (Apple Newton), I'm going to say "no". If it's for a new | ||
browser technology or a platform-specific driver like Chrome Web Apps or | ||
Firefox OS, then "yes" is probably the answer. | ||
### Will you add support for node.js? | ||
No. This is a library focused on offline storage inside a web browser. Node.js | ||
already has lots of storage solutions. The problem this library aims to solve | ||
is that web browsers differ greatly in their support for a common API for | ||
dealing with the same kind of data. Node.js doesn't have that problem; if you | ||
want to use an API, you just add a library to your `package.json`. | ||
# License | ||
@@ -296,0 +302,0 @@ |
@@ -52,7 +52,10 @@ --- | ||
localForage supports both a callback-based and Promises-based API, so you can | ||
use whichever you prefer. At the current time, these docs use the callback API. | ||
**localForage offers a callback API as well as support for the | ||
[ES6 Promises API][]**, so you can use whichever you prefer. | ||
[Download localforage.min.js](http://mozilla.github.io/localForage/localforage.min.js) | ||
[Download localforage.min.js][download] | ||
[download]: https://mozilla.github.io/localForage/localforage.min.js | ||
[ES6 Promises API]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise | ||
# Installation | ||
@@ -66,3 +69,3 @@ | ||
<script src="localforage.js"></script> | ||
<script>localforage.getItem('my alert').then(alert);</script> | ||
<script>localforage.getItem('my alert', alert);</script> | ||
``` | ||
@@ -83,3 +86,3 @@ | ||
```javascript | ||
localforage.getItem('somekey', function(value) { | ||
localforage.getItem('somekey', function(err, value) { | ||
// Run this code once the value has been | ||
@@ -89,9 +92,17 @@ // loaded from the offline store. | ||
}); | ||
localforage.getItem('somekey').then(function(value) { | ||
// The same code, but using ES6 Promises. | ||
console.log(value); | ||
}); | ||
``` | ||
```coffeescript | ||
localforage.getItem "somekey", (value) -> | ||
localforage.getItem "somekey", (err, value) -> | ||
# Run this code once the value has been loaded | ||
# from the offline store. | ||
console.log value | ||
localforage.getItem("somekey").then (value) -> | ||
# The same code, but using ES6 Promises. | ||
console.log(value) | ||
``` | ||
@@ -114,3 +125,3 @@ | ||
```javascript | ||
localforage.setItem('somekey', 'some value', function(value) { | ||
localforage.setItem('somekey', 'some value', function(err, value) { | ||
// Do other things once the value has been saved. | ||
@@ -121,3 +132,3 @@ console.log(value); | ||
// Unlike localStorage, you can store non-strings. | ||
localforage.setItem('my array', [1, 2, 'three'], function(value) { | ||
localforage.setItem('my array', [1, 2, 'three'], function(err, value) { | ||
// This will output `1`. | ||
@@ -144,3 +155,3 @@ console.log(value[0]); | ||
```coffeescript | ||
localforage.getItem "somekey", "some value" (value) -> | ||
localforage.setItem "somekey", "some value", (err, value) -> | ||
# Do other things once the value has been saved. | ||
@@ -150,3 +161,3 @@ console.log value | ||
# Unlike localStorage, you can store non-strings. | ||
localforage.setItem "my array", [1, 2, "three"], (value) -> | ||
localforage.setItem "my array", [1, 2, "three"], (err, value) -> | ||
# This will output `1`. | ||
@@ -241,3 +252,3 @@ console.log value[0] | ||
```javascript | ||
localforage.length(function(numberOfKeys) { | ||
localforage.length(function(err, numberOfKeys) { | ||
// Outputs the length of the database. | ||
@@ -249,3 +260,3 @@ console.log(numberOfKeys); | ||
```coffeescript | ||
localforage.length (numberOfKeys) -> | ||
localforage.length (err, numberOfKeys) -> | ||
# Outputs the length of the database. | ||
@@ -262,3 +273,3 @@ console.log numberOfKeys | ||
```javascript | ||
localforage.key(2, function(keyName) { | ||
localforage.key(2, function(err, keyName) { | ||
// Name of the key. | ||
@@ -270,3 +281,3 @@ console.log(keyName); | ||
```coffeescript | ||
localforage.key 2, (keyName) -> | ||
localforage.key 2, (err, keyName) -> | ||
# Name of the key. | ||
@@ -288,3 +299,3 @@ console.log keyName | ||
```javascript | ||
localforage.keys(function(keys) { | ||
localforage.keys(function(err, keys) { | ||
// An array of all the key names. | ||
@@ -296,3 +307,3 @@ console.log(keys); | ||
```coffeescript | ||
localforage.keys (keys) -> | ||
localforage.keys (err, keys) -> | ||
# An array of all the key names. | ||
@@ -316,6 +327,6 @@ console.log keys | ||
// Force localStorage to be the backend driver. | ||
localforage.setDriver('localStorageWrapper'); | ||
localforage.setDriver(localforage.LOCALSTORAGE); | ||
// Supply a list of drivers, in order of preference. | ||
localforage.setDriver(['WebSQLStorage', 'localStorageWrapper']); | ||
localforage.setDriver([localforage.WEBSQL, localforage.INDEXEDDB]); | ||
``` | ||
@@ -325,6 +336,6 @@ | ||
# Force localStorage to be the backend driver. | ||
localforage.setDriver "localStorageWrapper" | ||
localforage.setDriver localforage.LOCALSTORAGE | ||
# Supply a list of drivers, in order of preference. | ||
localforage.setDriver ["WebSQLStorage", "localStorageWrapper"] | ||
localforage.setDriver [localforage.WEBSQL, localforage.INDEXEDDB] | ||
``` | ||
@@ -345,4 +356,8 @@ | ||
If you would like to force usage of a particular driver you can use | ||
`setDriver()`. | ||
`setDriver()` with one or more of the following parameters. | ||
* localforage.INDEXEDDB | ||
* localforage.WEBSQL | ||
* localforage.LOCALSTORAGE | ||
<aside class="notice"> | ||
@@ -397,3 +412,5 @@ If the backend you're trying to load isn't available on the user's browser, | ||
table in the database. In localStorage, this is used as a key prefix for | ||
all keys stored in localStorage.<br> | ||
all keys stored in localStorage. <strong>Must be alphanumeric, | ||
with underscores.</strong> Any non-alphanumeric characters will be converted | ||
to underscores.<br> | ||
Default: <code>'keyvaluepairs'</code> | ||
@@ -400,0 +417,0 @@ </dd> |
@@ -1,1 +0,1 @@ | ||
!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)k.push("exports"===i[l]?g={}:b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:void 0===this?window:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:void(c[a]=b)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a;a="undefined"!=typeof global?global:"undefined"!=typeof window&&window.document?window:self;var b="Promise"in a&&"resolve"in a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;return new a.Promise(function(a){b=a}),f(b)}();b||(a.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h){"use strict";function i(a){if(!v(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof i))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],j(a,this)}function j(a,b){function c(a){o(b,a)}function d(a){q(b,a)}try{a(c,d)}catch(e){d(e)}}function k(a,b,c,d){var e,f,g,h,i=v(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;n(b,e)||(i&&g?o(b,e):h?q(b,f):a===D?o(b,e):a===E&&q(b,e))}function l(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+D]=c,e[f+E]=d}function m(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],k(b,c,d,f);a._subscribers=null}function n(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(u(b)&&(d=b.then,v(d)))return d.call(b,function(d){return c?!0:(c=!0,void(b!==d?o(a,d):p(a,d)))},function(b){return c?!0:(c=!0,void q(a,b))}),!0}catch(e){return c?!0:(q(a,e),!0)}return!1}function o(a,b){a===b?p(a,b):n(a,b)||p(a,b)}function p(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(r,a))}function q(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(s,a))}function r(a){m(a,a._state=D)}function s(a){m(a,a._state=E)}var t=a.config,u=(a.configure,b.objectOrFunction),v=b.isFunction,w=(b.now,c.all),x=d.race,y=e.resolve,z=f.reject,A=g.asap;t.async=A;var B=void 0,C=0,D=1,E=2;i.prototype={constructor:i,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;t.async(function(){k(c._state,d,e[c._state-1],c._detail)})}else l(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},i.all=w,i.race=x,i.resolve=y,i.reject=z,h.Promise=i}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}(),function(){"use strict";function a(a){if(a)for(var b in a)l[b]=a[b];return new j(function(a,b){var c=m.open(l.name,l.version);c.onerror=function(){b(c.error)},c.onupgradeneeded=function(){c.result.createObjectStore(l.storeName)},c.onsuccess=function(){k=c.result,a()}})}function b(a,b){var c=this;return new j(function(d,e){c.ready().then(function(){var c=k.transaction(l.storeName,"readonly").objectStore(l.storeName),f=c.get(a);f.onsuccess=function(){var a=f.result;void 0===a&&(a=null),i(b,a),d(a)},f.onerror=function(){b&&b(null,f.error),e(f.error)}},e)})}function c(a,b,c){var d=this;return new j(function(e,f){d.ready().then(function(){var d=k.transaction(l.storeName,"readwrite").objectStore(l.storeName);null===b&&(b=void 0);var g=d.put(b,a);g.onsuccess=function(){void 0===b&&(b=null),i(c,b),e(b)},g.onerror=function(){c&&c(null,g.error),f(g.error)}},f)})}function d(a,b){var c=this;return new j(function(d,e){c.ready().then(function(){var c=k.transaction(l.storeName,"readwrite").objectStore(l.storeName),f=c["delete"](a);f.onsuccess=function(){i(b),d()},f.onerror=function(){b&&b(f.error),e(f.error)},f.onabort=function(a){var c=a.target.error;"QuotaExceededError"===c&&(b&&b(c),e(c))}},e)})}function e(a){var b=this;return new j(function(c,d){b.ready().then(function(){var b=k.transaction(l.storeName,"readwrite").objectStore(l.storeName),e=b.clear();e.onsuccess=function(){i(a),c()},e.onerror=function(){a&&a(null,e.error),d(e.error)}},d)})}function f(a){var b=this;return new j(function(c,d){b.ready().then(function(){var b=k.transaction(l.storeName,"readonly").objectStore(l.storeName),e=b.count();e.onsuccess=function(){a&&a(e.result),c(e.result)},e.onerror=function(){a&&a(null,e.error),d(e.error)}},d)})}function g(a,b){var c=this;return new j(function(d,e){return 0>a?(b&&b(null),void d(null)):void c.ready().then(function(){var c=k.transaction(l.storeName,"readonly").objectStore(l.storeName),f=!1,g=c.openCursor();g.onsuccess=function(){var c=g.result;return c?void(0===a?(b&&b(c.key),d(c.key)):f?(b&&b(c.key),d(c.key)):(f=!0,c.advance(a))):(b&&b(null),void d(null))},g.onerror=function(){b&&b(null,g.error),e(g.error)}},e)})}function h(a){var b=this;return new j(function(c,d){b.ready().then(function(){var b=k.transaction(l.storeName,"readonly").objectStore(l.storeName),e=b.openCursor(),f=[];e.onsuccess=function(){var b=e.result;return b?(f.push(b.key),void b["continue"]()):(a&&a(f),void c(f))},e.onerror=function(){a&&a(null,e.error),d(e.error)}},d)})}function i(a,b){return a?setTimeout(function(){return a(b)},0):void 0}var j="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,k=null,l={},m=m||this.indexedDB||this.webkitIndexedDB||this.mozIndexedDB||this.OIndexedDB||this.msIndexedDB;if(m){var n={_driver:"asyncStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("asyncStorage",function(){return n}):"undefined"!=typeof module&&module.exports?module.exports=n:this.asyncStorage=n}}.call(this),function(){"use strict";function a(a){if(a)for(var b in a)m[b]=a[b];return l=m.name+"/",n.resolve()}function b(a){var b=this;return new n(function(c,d){b.ready().then(function(){o.clear(),a&&a(),c()},d)})}function c(a,b){var c=this;return new n(function(d,e){c.ready().then(function(){try{var c=o.getItem(l+a);c&&(c=h(c)),b&&b(c),d(c)}catch(f){b&&b(null,f),e(f)}},e)})}function d(a,b){var c=this;return new n(function(d,e){c.ready().then(function(){var c;try{c=o.key(a)}catch(e){c=null}c&&(c=c.substring(l.length)),b&&b(c),d(c)},e)})}function e(a){var b=this;return new n(function(c,d){b.ready().then(function(){for(var b=o.length,d=[],e=0;b>e;e++)d.push(o.key(e).substring(l.length));a&&a(d),c(d)},d)})}function f(a){var b=this;return new n(function(c,d){b.ready().then(function(){var b=o.length;a&&a(b),c(b)},d)})}function g(a,b){var c=this;return new n(function(d,e){c.ready().then(function(){o.removeItem(l+a),b&&b(),d()},e)})}function h(a){if(a.substring(0,r)!==q)return JSON.parse(a);for(var b=a.substring(D),c=a.substring(r,D),d=new ArrayBuffer(2*b.length),e=new Uint16Array(d),f=b.length-1;f>=0;f--)e[f]=b.charCodeAt(f);switch(c){case s:return d;case t:return new Blob([d]);case u:return new Int8Array(d);case v:return new Uint8Array(d);case w:return new Uint8ClampedArray(d);case x:return new Int16Array(d);case z:return new Uint16Array(d);case y:return new Int32Array(d);case A:return new Uint32Array(d);case B:return new Float32Array(d);case C:return new Float64Array(d);default:throw new Error("Unkown type: "+c)}}function i(a){var b="",c=new Uint16Array(a);try{b=String.fromCharCode.apply(null,c)}catch(d){for(var e=0;e<c.length;e++)b+=String.fromCharCode(c[e])}return b}function j(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=q;a instanceof ArrayBuffer?(d=a,e+=s):(d=a.buffer,"[object Int8Array]"===c?e+=u:"[object Uint8Array]"===c?e+=v:"[object Uint8ClampedArray]"===c?e+=w:"[object Int16Array]"===c?e+=x:"[object Uint16Array]"===c?e+=z:"[object Int32Array]"===c?e+=y:"[object Uint32Array]"===c?e+=A:"[object Float32Array]"===c?e+=B:"[object Float64Array]"===c?e+=C:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(q+t+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){this.console&&this.console.error&&this.console.error("Couldn't convert value into a JSON string: ",a),b(null,g)}}function k(a,b,c){var d=this;return new n(function(e,f){d.ready().then(function(){void 0===b&&(b=null);var d=b;j(b,function(b,g){if(g)c&&c(null,g),f(g);else{try{o.setItem(l+a,b)}catch(h){("QuotaExceededError"===h.name||"NS_ERROR_DOM_QUOTA_REACHED"===h.name)&&(c&&c(null,h),f(h))}c&&c(d),e(d)}})},f)})}var l="",m={},n="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,o=null;try{if(!(this.localStorage&&"setItem"in this.localStorage))return;o=this.localStorage}catch(p){return}var q="__lfsc__:",r=q.length,s="arbf",t="blob",u="si08",v="ui08",w="uic8",x="si16",y="si32",z="ur16",A="ui32",B="fl32",C="fl64",D=r+s.length,E={_driver:"localStorageWrapper",_initStorage:a,getItem:c,setItem:k,removeItem:g,clear:b,length:f,key:d,keys:e};"function"==typeof define&&define.amd?define("localStorageWrapper",function(){return E}):"undefined"!=typeof module&&module.exports?module.exports=E:this.localStorageWrapper=E}.call(this),function(){"use strict";function a(a){var b=this;if(a)for(var c in a)p[c]="string"!=typeof a[c]?a[c].toString():a[c];return new m(function(a,c){try{o=n(p.name,p.version,p.description,p.size)}catch(d){return b.setDriver("localStorageWrapper").then(a,c)}o.transaction(function(b){b.executeSql("CREATE TABLE IF NOT EXISTS "+p.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){a()},function(a,b){c(b)})})})}function b(a,b){var c=this;return new m(function(d,e){c.ready().then(function(){o.transaction(function(c){c.executeSql("SELECT * FROM "+p.storeName+" WHERE key = ? LIMIT 1",[a],function(a,c){var e=c.rows.length?c.rows.item(0).value:null;e&&(e=j(e)),b&&b(e),d(e)},function(a,c){b&&b(null,c),e(c)})})},e)})}function c(a,b,c){var d=this;return new m(function(e,f){d.ready().then(function(){void 0===b&&(b=null);var d=b;k(b,function(b,g){g?f(g):o.transaction(function(g){g.executeSql("INSERT OR REPLACE INTO "+p.storeName+" (key, value) VALUES (?, ?)",[a,b],function(){c&&c(d),e(d)},function(a,b){c&&c(null,b),f(b)})},function(a){a.code===a.QUOTA_ERR&&(c&&c(null,a),f(a))})})},f)})}function d(a,b){var c=this;return new m(function(d,e){c.ready().then(function(){o.transaction(function(c){c.executeSql("DELETE FROM "+p.storeName+" WHERE key = ?",[a],function(){b&&b(),d()},function(a,c){b&&b(c),e(c)})})},e)})}function e(a){var b=this;return new m(function(c,d){b.ready().then(function(){o.transaction(function(b){b.executeSql("DELETE FROM "+p.storeName,[],function(){a&&a(),c()},function(b,c){a&&a(c),d(c)})})},d)})}function f(a){var b=this;return new m(function(c,d){b.ready().then(function(){o.transaction(function(b){b.executeSql("SELECT COUNT(key) as c FROM "+p.storeName,[],function(b,d){var e=d.rows.item(0).c;a&&a(e),c(e)},function(b,c){a&&a(null,c),d(c)})})},d)})}function g(a,b){var c=this;return new m(function(d,e){c.ready().then(function(){o.transaction(function(c){c.executeSql("SELECT key FROM "+p.storeName+" WHERE id = ? LIMIT 1",[a+1],function(a,c){var e=c.rows.length?c.rows.item(0).key:null;b&&b(e),d(e)},function(a,c){b&&b(null,c),e(c)})})},e)})}function h(a){var b=this;return new m(function(c,d){b.ready().then(function(){o.transaction(function(b){b.executeSql("SELECT key FROM "+p.storeName,[],function(b,d){for(var e=d.rows.length,f=[],g=0;e>g;g++)f.push(d.rows.item(g).key);a&&a(f),c(f)},function(b,c){a&&a(null,c),d(c)})})},d)})}function i(a){var b,c=new Uint8Array(a),d="";for(b=0;b<c.length;b+=3)d+=l[c[b]>>2],d+=l[(3&c[b])<<4|c[b+1]>>4],d+=l[(15&c[b+1])<<2|c[b+2]>>6],d+=l[63&c[b+2]];return c.length%3===2?d=d.substring(0,d.length-1)+"=":c.length%3===1&&(d=d.substring(0,d.length-2)+"=="),d}function j(a){if(a.substring(0,r)!==q)return JSON.parse(a);var b,c,d,e,f,g=a.substring(D),h=a.substring(r,D),i=.75*g.length,j=g.length,k=0;"="===g[g.length-1]&&(i--,"="===g[g.length-2]&&i--);var m=new ArrayBuffer(i),n=new Uint8Array(m);for(b=0;j>b;b+=4)c=l.indexOf(g[b]),d=l.indexOf(g[b+1]),e=l.indexOf(g[b+2]),f=l.indexOf(g[b+3]),n[k++]=c<<2|d>>4,n[k++]=(15&d)<<4|e>>2,n[k++]=(3&e)<<6|63&f;switch(h){case s:return m;case t:return new Blob([m]);case u:return new Int8Array(m);case v:return new Uint8Array(m);case w:return new Uint8ClampedArray(m);case x:return new Int16Array(m);case z:return new Uint16Array(m);case y:return new Int32Array(m);case A:return new Uint32Array(m);case B:return new Float32Array(m);case C:return new Float64Array(m);default:throw new Error("Unkown type: "+h)}}function k(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=q;a instanceof ArrayBuffer?(d=a,e+=s):(d=a.buffer,"[object Int8Array]"===c?e+=u:"[object Uint8Array]"===c?e+=v:"[object Uint8ClampedArray]"===c?e+=w:"[object Int16Array]"===c?e+=x:"[object Uint16Array]"===c?e+=z:"[object Int32Array]"===c?e+=y:"[object Uint32Array]"===c?e+=A:"[object Float32Array]"===c?e+=B:"[object Float64Array]"===c?e+=C:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(q+t+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){this.console&&this.console.error&&this.console.error("Couldn't convert value into a JSON string: ",a),b(null,g)}}var l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",m="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,n=this.openDatabase,o=null,p={},q="__lfsc__:",r=q.length,s="arbf",t="blob",u="si08",v="ui08",w="uic8",x="si16",y="si32",z="ur16",A="ui32",B="fl32",C="fl64",D=r+s.length;if(n){var E={_driver:"webSQLStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("webSQLStorage",function(){return E}):"undefined"!=typeof module&&module.exports?module.exports=E:this.webSQLStorage=E}}.call(this),function(){"use strict";var a="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,b=1,c=2,d=3,e=d;"function"==typeof define&&define.amd?e=b:"undefined"!=typeof module&&module.exports&&(e=c);var f=this,g={INDEXEDDB:"asyncStorage",LOCALSTORAGE:"localStorageWrapper",WEBSQL:"webSQLStorage",_config:{description:"",name:"localforage",size:4980736,storeName:"keyvaluepairs",version:1},config:function(a){if("object"==typeof a){if(this._ready)return new Error("Can't call config() after localforage has been used.");for(var b in a)this._config[b]=a[b];return!0}return"string"==typeof a?this._config[a]:this._config},driver:function(){return this._driver||null},_ready:!1,_driverSet:null,setDriver:function(d,g,h){var i=this,j=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)};return j(d)||"string"!=typeof d||(d=[d]),this._driverSet=new a(function(j,k){var l=i._getFirstSupportedDriver(d);if(!l){var m=new Error("No available storage method found.");return i._driverSet=a.reject(m),h&&h(m),void k(m)}if(i._ready=null,e===b)return void require([l],function(a){i._extend(a),g&&g(),j()});if(e===c){var n;switch(l){case i.INDEXEDDB:n=require("./drivers/indexeddb");break;case i.LOCALSTORAGE:n=require("./drivers/localstorage");break;case i.WEBSQL:n=require("./drivers/websql")}i._extend(n)}else i._extend(f[l]);g&&g(),j()}),this._driverSet},_getFirstSupportedDriver:function(a){if(a)for(var b=0;b<a.length;b++){var c=a[b];if(this.supports(c))return c}return null},supports:function(a){return!!h[a]},ready:function(b){var c=new a(function(a,b){g._driverSet.then(function(){null===g._ready&&(g._ready=g._initStorage(g._config)),g._ready.then(a,b)},b)});return c.then(b,b),c},_extend:function(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])}},h=function(a){var b=b||a.indexedDB||a.webkitIndexedDB||a.mozIndexedDB||a.OIndexedDB||a.msIndexedDB,c={};return c[g.WEBSQL]=!!a.openDatabase,c[g.INDEXEDDB]=!(!b||"function"!=typeof b.open||null!==b.open("_localforage_spec_test",1).onupgradeneeded),c[g.LOCALSTORAGE]=!!function(){try{return localStorage&&"function"==typeof localStorage.setItem}catch(a){return!1}}(),c}(this),i=[g.INDEXEDDB,g.WEBSQL,g.LOCALSTORAGE];g.setDriver(i),e===b?define(function(){return g}):e===c?module.exports=g:this.localforage=g}.call(this); | ||
!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)k.push("exports"===i[l]?g={}:b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:void 0===this?window:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:void(c[a]=b)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a;a="undefined"!=typeof global?global:"undefined"!=typeof window&&window.document?window:self;var b="Promise"in a&&"resolve"in a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;return new a.Promise(function(a){b=a}),f(b)}();b||(a.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h){"use strict";function i(a){if(!v(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof i))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],j(a,this)}function j(a,b){function c(a){o(b,a)}function d(a){q(b,a)}try{a(c,d)}catch(e){d(e)}}function k(a,b,c,d){var e,f,g,h,i=v(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;n(b,e)||(i&&g?o(b,e):h?q(b,f):a===D?o(b,e):a===E&&q(b,e))}function l(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+D]=c,e[f+E]=d}function m(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],k(b,c,d,f);a._subscribers=null}function n(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(u(b)&&(d=b.then,v(d)))return d.call(b,function(d){return c?!0:(c=!0,void(b!==d?o(a,d):p(a,d)))},function(b){return c?!0:(c=!0,void q(a,b))}),!0}catch(e){return c?!0:(q(a,e),!0)}return!1}function o(a,b){a===b?p(a,b):n(a,b)||p(a,b)}function p(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(r,a))}function q(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(s,a))}function r(a){m(a,a._state=D)}function s(a){m(a,a._state=E)}var t=a.config,u=(a.configure,b.objectOrFunction),v=b.isFunction,w=(b.now,c.all),x=d.race,y=e.resolve,z=f.reject,A=g.asap;t.async=A;var B=void 0,C=0,D=1,E=2;i.prototype={constructor:i,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;t.async(function(){k(c._state,d,e[c._state-1],c._detail)})}else l(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},i.all=w,i.race=x,i.resolve=y,i.reject=z,h.Promise=i}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}(),function(){"use strict";function a(a){var b=this,c={db:null};if(a)for(var d in a)c[d]=a[d];return new l(function(a,d){var e=m.open(c.name,c.version);e.onerror=function(){d(e.error)},e.onupgradeneeded=function(){e.result.createObjectStore(c.storeName)},e.onsuccess=function(){c.db=e.result,b._dbInfo=c,a()}})}function b(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new l(function(b,d){c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readonly").objectStore(e.storeName),g=f.get(a);g.onsuccess=function(){var a=g.result;void 0===a&&(a=null),b(a)},g.onerror=function(){d(g.error)}})["catch"](d)});return j(d,b),d}function c(a,b,c){var d=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var e=new l(function(c,e){d.ready().then(function(){var f=d._dbInfo,g=f.db.transaction(f.storeName,"readwrite").objectStore(f.storeName);null===b&&(b=void 0);var h=g.put(b,a);h.onsuccess=function(){void 0===b&&(b=null),c(b)},h.onerror=function(){e(h.error)}})["catch"](e)});return j(e,c),e}function d(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new l(function(b,d){c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readwrite").objectStore(e.storeName),g=f["delete"](a);g.onsuccess=function(){b()},g.onerror=function(){d(g.error)},g.onabort=function(a){var b=a.target.error;"QuotaExceededError"===b&&d(b)}})["catch"](d)});return j(d,b),d}function e(a){var b=this,c=new l(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readwrite").objectStore(d.storeName),f=e.clear();f.onsuccess=function(){a()},f.onerror=function(){c(f.error)}})["catch"](c)});return j(c,a),c}function f(a){var b=this,c=new l(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readonly").objectStore(d.storeName),f=e.count();f.onsuccess=function(){a(f.result)},f.onerror=function(){c(f.error)}})["catch"](c)});return i(c,a),c}function g(a,b){var c=this,d=new l(function(b,d){return 0>a?void b(null):void c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readonly").objectStore(e.storeName),g=!1,h=f.openCursor();h.onsuccess=function(){var c=h.result;return c?void(0===a?b(c.key):g?b(c.key):(g=!0,c.advance(a))):void b(null)},h.onerror=function(){d(h.error)}})["catch"](d)});return i(d,b),d}function h(a){var b=this,c=new l(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readonly").objectStore(d.storeName),f=e.openCursor(),g=[];f.onsuccess=function(){var b=f.result;return b?(g.push(b.key),void b["continue"]()):void a(g)},f.onerror=function(){c(f.error)}})["catch"](c)});return i(c,a),c}function i(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}function j(a,b){b&&a.then(function(a){k(b,a)},function(a){b(a)})}function k(a,b){return a?setTimeout(function(){return a(null,b)},0):void 0}var l="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,m=m||this.indexedDB||this.webkitIndexedDB||this.mozIndexedDB||this.OIndexedDB||this.msIndexedDB;if(m){var n={_driver:"asyncStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("asyncStorage",function(){return n}):"undefined"!=typeof module&&module.exports?module.exports=n:this.asyncStorage=n}}.call(window),function(){"use strict";function a(a){var b=this,c={};if(a)for(var d in a)c[d]=a[d];return c.keyPrefix=c.name+"/",b._dbInfo=c,m.resolve()}function b(a){var b=this,c=new m(function(a,c){b.ready().then(function(){n.clear(),a()})["catch"](c)});return l(c,a),c}function c(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new m(function(b,d){c.ready().then(function(){try{var e=c._dbInfo,f=n.getItem(e.keyPrefix+a);f&&(f=h(f)),b(f)}catch(g){d(g)}})["catch"](d)});return l(d,b),d}function d(a,b){var c=this,d=new m(function(b,d){c.ready().then(function(){var d,e=c._dbInfo;try{d=n.key(a)}catch(f){d=null}d&&(d=d.substring(e.keyPrefix.length)),b(d)})["catch"](d)});return l(d,b),d}function e(a){var b=this,c=new m(function(a,c){b.ready().then(function(){for(var c=b._dbInfo,d=n.length,e=[],f=0;d>f;f++)e.push(n.key(f).substring(c.keyPrefix.length));a(e)})["catch"](c)});return l(c,a),c}function f(a){var b=this,c=new m(function(a,c){b.ready().then(function(){var b=n.length;a(b)})["catch"](c)});return l(c,a),c}function g(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new m(function(b,d){c.ready().then(function(){var d=c._dbInfo;n.removeItem(d.keyPrefix+a),b()})["catch"](d)});return l(d,b),d}function h(a){if(a.substring(0,q)!==p)return JSON.parse(a);for(var b=a.substring(C),c=a.substring(q,C),d=new ArrayBuffer(2*b.length),e=new Uint16Array(d),f=b.length-1;f>=0;f--)e[f]=b.charCodeAt(f);switch(c){case r:return d;case s:return new Blob([d]);case t:return new Int8Array(d);case u:return new Uint8Array(d);case v:return new Uint8ClampedArray(d);case w:return new Int16Array(d);case y:return new Uint16Array(d);case x:return new Int32Array(d);case z:return new Uint32Array(d);case A:return new Float32Array(d);case B:return new Float64Array(d);default:throw new Error("Unkown type: "+c)}}function i(a){var b="",c=new Uint16Array(a);try{b=String.fromCharCode.apply(null,c)}catch(d){for(var e=0;e<c.length;e++)b+=String.fromCharCode(c[e])}return b}function j(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=p;a instanceof ArrayBuffer?(d=a,e+=r):(d=a.buffer,"[object Int8Array]"===c?e+=t:"[object Uint8Array]"===c?e+=u:"[object Uint8ClampedArray]"===c?e+=v:"[object Int16Array]"===c?e+=w:"[object Uint16Array]"===c?e+=y:"[object Int32Array]"===c?e+=x:"[object Uint32Array]"===c?e+=z:"[object Float32Array]"===c?e+=A:"[object Float64Array]"===c?e+=B:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(p+s+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){window.console.error("Couldn't convert value into a JSON string: ",a),b(g)}}function k(a,b,c){var d=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var e=new m(function(c,e){d.ready().then(function(){void 0===b&&(b=null);var f=b;j(b,function(b,g){if(g)e(g);else{try{var h=d._dbInfo;n.setItem(h.keyPrefix+a,b)}catch(i){("QuotaExceededError"===i.name||"NS_ERROR_DOM_QUOTA_REACHED"===i.name)&&e(i)}c(f)}})})["catch"](e)});return l(e,c),e}function l(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}var m="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,n=null;try{if(!(this.localStorage&&"setItem"in this.localStorage))return;n=this.localStorage}catch(o){return}var p="__lfsc__:",q=p.length,r="arbf",s="blob",t="si08",u="ui08",v="uic8",w="si16",x="si32",y="ur16",z="ui32",A="fl32",B="fl64",C=q+r.length,D={_driver:"localStorageWrapper",_initStorage:a,getItem:c,setItem:k,removeItem:g,clear:b,length:f,key:d,keys:e};"function"==typeof define&&define.amd?define("localStorageWrapper",function(){return D}):"undefined"!=typeof module&&module.exports?module.exports=D:this.localStorageWrapper=D}.call(window),function(){"use strict";function a(a){var b=this,c={db:null};if(a)for(var d in a)c[d]="string"!=typeof a[d]?a[d].toString():a[d];return new n(function(d,e){try{c.db=o(c.name,String(c.version),c.description,c.size)}catch(f){return b.setDriver("localStorageWrapper").then(function(){return b._initStorage(a)}).then(d)["catch"](e)}c.db.transaction(function(a){a.executeSql("CREATE TABLE IF NOT EXISTS "+c.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){b._dbInfo=c,d()},function(a,b){e(b)})})})}function b(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new n(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("SELECT * FROM "+e.storeName+" WHERE key = ? LIMIT 1",[a],function(a,c){var d=c.rows.length?c.rows.item(0).value:null;d&&(d=j(d)),b(d)},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function c(a,b,c){var d=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var e=new n(function(c,e){d.ready().then(function(){void 0===b&&(b=null);var f=b;k(b,function(b,g){if(g)e(g);else{var h=d._dbInfo;h.db.transaction(function(d){d.executeSql("INSERT OR REPLACE INTO "+h.storeName+" (key, value) VALUES (?, ?)",[a,b],function(){c(f)},function(a,b){e(b)})},function(a){a.code===a.QUOTA_ERR&&e(a)})}})})["catch"](e)});return l(e,c),e}function d(a,b){var c=this;"string"!=typeof a&&(window.console.warn(a+" used as a key, but it is not a string."),a=String(a));var d=new n(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("DELETE FROM "+e.storeName+" WHERE key = ?",[a],function(){b()},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function e(a){var b=this,c=new n(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("DELETE FROM "+d.storeName,[],function(){a()},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function f(a){var b=this,c=new n(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("SELECT COUNT(key) as c FROM "+d.storeName,[],function(b,c){var d=c.rows.item(0).c;a(d)},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function g(a,b){var c=this,d=new n(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("SELECT key FROM "+e.storeName+" WHERE id = ? LIMIT 1",[a+1],function(a,c){var d=c.rows.length?c.rows.item(0).key:null;b(d)},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function h(a){var b=this,c=new n(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("SELECT key FROM "+d.storeName,[],function(b,c){for(var d=[],e=0;e<c.rows.length;e++)d.push(c.rows.item(e).key);a(d)},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function i(a){var b,c=new Uint8Array(a),d="";for(b=0;b<c.length;b+=3)d+=m[c[b]>>2],d+=m[(3&c[b])<<4|c[b+1]>>4],d+=m[(15&c[b+1])<<2|c[b+2]>>6],d+=m[63&c[b+2]];return c.length%3===2?d=d.substring(0,d.length-1)+"=":c.length%3===1&&(d=d.substring(0,d.length-2)+"=="),d}function j(a){if(a.substring(0,q)!==p)return JSON.parse(a);var b,c,d,e,f,g=a.substring(C),h=a.substring(q,C),i=.75*g.length,j=g.length,k=0;"="===g[g.length-1]&&(i--,"="===g[g.length-2]&&i--);var l=new ArrayBuffer(i),n=new Uint8Array(l);for(b=0;j>b;b+=4)c=m.indexOf(g[b]),d=m.indexOf(g[b+1]),e=m.indexOf(g[b+2]),f=m.indexOf(g[b+3]),n[k++]=c<<2|d>>4,n[k++]=(15&d)<<4|e>>2,n[k++]=(3&e)<<6|63&f;switch(h){case r:return l;case s:return new Blob([l]);case t:return new Int8Array(l);case u:return new Uint8Array(l);case v:return new Uint8ClampedArray(l);case w:return new Int16Array(l);case y:return new Uint16Array(l);case x:return new Int32Array(l);case z:return new Uint32Array(l);case A:return new Float32Array(l);case B:return new Float64Array(l);default:throw new Error("Unkown type: "+h)}}function k(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=p;a instanceof ArrayBuffer?(d=a,e+=r):(d=a.buffer,"[object Int8Array]"===c?e+=t:"[object Uint8Array]"===c?e+=u:"[object Uint8ClampedArray]"===c?e+=v:"[object Int16Array]"===c?e+=w:"[object Uint16Array]"===c?e+=y:"[object Int32Array]"===c?e+=x:"[object Uint32Array]"===c?e+=z:"[object Float32Array]"===c?e+=A:"[object Float64Array]"===c?e+=B:b(new Error("Failed to get type for BinaryArray"))),b(e+i(d))}else if("[object Blob]"===c){var f=new FileReader;f.onload=function(){var a=i(this.result);b(p+s+a)},f.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(g){window.console.error("Couldn't convert value into a JSON string: ",a),b(null,g)}}function l(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}var m="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,o=this.openDatabase,p="__lfsc__:",q=p.length,r="arbf",s="blob",t="si08",u="ui08",v="uic8",w="si16",x="si32",y="ur16",z="ui32",A="fl32",B="fl64",C=q+r.length;if(o){var D={_driver:"webSQLStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g,keys:h};"function"==typeof define&&define.amd?define("webSQLStorage",function(){return D}):"undefined"!=typeof module&&module.exports?module.exports=D:this.webSQLStorage=D}}.call(window),function(){"use strict";function a(){for(var a=1;a<arguments.length;a++){var b=arguments[a];if(b)for(var c in b)b.hasOwnProperty(c)&&(arguments[0][c]=b[c])}return arguments[0]}function b(a,b){a[b]=function(){var c=arguments;return a.ready().then(function(){return a[b].apply(a,c)})}}function c(c){this._config=a({},i,c),this._driverSet=null,this._ready=!1,this._dbInfo=null;for(var d=0;d<g.length;d++)b(this,g[d]);this.setDriver(f)}var d="undefined"!=typeof module&&module.exports?require("promise"):this.Promise,e={INDEXEDDB:"asyncStorage",LOCALSTORAGE:"localStorageWrapper",WEBSQL:"webSQLStorage"},f=[e.INDEXEDDB,e.WEBSQL,e.LOCALSTORAGE],g=["clear","getItem","key","keys","length","removeItem","setItem"],h={DEFINE:1,EXPORT:2,WINDOW:3},i={description:"",name:"localforage",size:4980736,storeName:"keyvaluepairs",version:1},j=h.WINDOW;"function"==typeof define&&define.amd?j=h.DEFINE:"undefined"!=typeof module&&module.exports&&(j=h.EXPORT);var k=function(a){var b=b||a.indexedDB||a.webkitIndexedDB||a.mozIndexedDB||a.OIndexedDB||a.msIndexedDB,c={};return c[e.WEBSQL]=!!a.openDatabase,c[e.INDEXEDDB]=!!function(){try{return b&&"function"==typeof b.open&&null===b.open("_localforage_spec_test",1).onupgradeneeded}catch(a){return!1}}(),c[e.LOCALSTORAGE]=!!function(){try{return localStorage&&"function"==typeof localStorage.setItem}catch(a){return!1}}(),c}(this),l=this;c.prototype.INDEXEDDB=e.INDEXEDDB,c.prototype.LOCALSTORAGE=e.LOCALSTORAGE,c.prototype.WEBSQL=e.WEBSQL,c.prototype.config=function(a){if("object"==typeof a){if(this._ready)return new Error("Can't call config() after localforage has been used.");for(var b in a)"storeName"===b&&(a[b]=a[b].replace(/\W/g,"_")),this._config[b]=a[b];return!0}return"string"==typeof a?this._config[a]:this._config},c.prototype.driver=function(){return this._driver||null},c.prototype.ready=function(a){var b=this,c=new d(function(a,c){b._driverSet.then(function(){null===b._ready&&(b._ready=b._initStorage(b._config)),b._ready.then(a,c)})["catch"](c)});return c.then(a,a),c},c.prototype.setDriver=function(a,b,c){var e=this;return"string"==typeof a&&(a=[a]),this._driverSet=new d(function(b,c){var f=e._getFirstSupportedDriver(a);if(!f){var g=new Error("No available storage method found.");return e._driverSet=d.reject(g),void c(g)}if(e._dbInfo=null,e._ready=null,j===h.DEFINE)return void require([f],function(a){e._extend(a),b()});if(j===h.EXPORT){var i;switch(f){case e.INDEXEDDB:i=require("./drivers/indexeddb");break;case e.LOCALSTORAGE:i=require("./drivers/localstorage");break;case e.WEBSQL:i=require("./drivers/websql")}e._extend(i)}else e._extend(l[f]);b()}),this._driverSet.then(b,c),this._driverSet},c.prototype.supports=function(a){return!!k[a]},c.prototype._extend=function(b){a(this,b)},c.prototype._getFirstSupportedDriver=function(a){var b=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)};if(a&&b(a))for(var c=0;c<a.length;c++){var d=a[c];if(this.supports(d))return d}return null},c.prototype.createInstance=function(a){return new c(a)};var m=new c;j===h.DEFINE?define(function(){return m}):j===h.EXPORT?module.exports=m:this.localforage=m}.call(window); |
@@ -12,5 +12,2 @@ // Some code originally from async_storage.js in | ||
var db = null; | ||
var dbInfo = {}; | ||
// Initialize IndexedDB; fall back to vendor-prefixed versions if needed. | ||
@@ -29,2 +26,7 @@ var indexedDB = indexedDB || this.indexedDB || this.webkitIndexedDB || | ||
function _initStorage(options) { | ||
var _this = this; | ||
var dbInfo = { | ||
db: null | ||
}; | ||
if (options) { | ||
@@ -46,3 +48,4 @@ for (var i in options) { | ||
openreq.onsuccess = function() { | ||
db = openreq.result; | ||
dbInfo.db = openreq.result; | ||
_this._dbInfo = dbInfo; | ||
resolve(); | ||
@@ -55,5 +58,14 @@ }; | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly') | ||
.objectStore(dbInfo.storeName); | ||
@@ -68,4 +80,2 @@ var req = store.get(key); | ||
deferCallback(callback,value); | ||
resolve(value); | ||
@@ -75,10 +85,9 @@ }; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeDeferedCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -88,5 +97,14 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readwrite') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readwrite') | ||
.objectStore(dbInfo.storeName); | ||
@@ -114,15 +132,12 @@ | ||
deferCallback(callback, value); | ||
resolve(value); | ||
}; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeDeferedCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -132,5 +147,14 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readwrite') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readwrite') | ||
.objectStore(dbInfo.storeName); | ||
@@ -145,5 +169,2 @@ | ||
req.onsuccess = function() { | ||
deferCallback(callback); | ||
resolve(); | ||
@@ -153,6 +174,2 @@ }; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(req.error); | ||
} | ||
reject(req.error); | ||
@@ -167,11 +184,10 @@ }; | ||
if (error === 'QuotaExceededError') { | ||
if (callback) { | ||
callback(error); | ||
} | ||
reject(error); | ||
} | ||
}; | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeDeferedCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -181,5 +197,7 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readwrite') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readwrite') | ||
.objectStore(dbInfo.storeName); | ||
@@ -189,4 +207,2 @@ var req = store.clear(); | ||
req.onsuccess = function() { | ||
deferCallback(callback); | ||
resolve(); | ||
@@ -196,10 +212,9 @@ }; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeDeferedCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -209,5 +224,7 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly') | ||
.objectStore(dbInfo.storeName); | ||
@@ -217,6 +234,2 @@ var req = store.count(); | ||
req.onsuccess = function() { | ||
if (callback) { | ||
callback(req.result); | ||
} | ||
resolve(req.result); | ||
@@ -226,10 +239,9 @@ }; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -239,8 +251,5 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
if (n < 0) { | ||
if (callback) { | ||
callback(null); | ||
} | ||
resolve(null); | ||
@@ -252,3 +261,4 @@ | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly') | ||
.objectStore(dbInfo.storeName); | ||
@@ -262,6 +272,2 @@ | ||
// this means there weren't enough keys | ||
if (callback) { | ||
callback(null); | ||
} | ||
resolve(null); | ||
@@ -275,6 +281,2 @@ | ||
// wanted. | ||
if (callback) { | ||
callback(cursor.key); | ||
} | ||
resolve(cursor.key); | ||
@@ -289,6 +291,2 @@ } else { | ||
// When we get here, we've got the nth key. | ||
if (callback) { | ||
callback(cursor.key); | ||
} | ||
resolve(cursor.key); | ||
@@ -300,10 +298,9 @@ } | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -314,5 +311,6 @@ | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly') | ||
var dbInfo = _this._dbInfo; | ||
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly') | ||
.objectStore(dbInfo.storeName); | ||
@@ -327,6 +325,2 @@ | ||
if (!cursor) { | ||
if (callback) { | ||
callback(keys); | ||
} | ||
resolve(keys); | ||
@@ -341,12 +335,31 @@ return; | ||
req.onerror = function() { | ||
if (callback) { | ||
callback(null, req.error); | ||
} | ||
reject(req.error); | ||
}; | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
function executeCallback(promise, callback) { | ||
if (callback) { | ||
promise.then(function(result) { | ||
callback(null, result); | ||
}, function(error) { | ||
callback(error); | ||
}); | ||
} | ||
} | ||
function executeDeferedCallback(promise, callback) { | ||
if (callback) { | ||
promise.then(function(result) { | ||
deferCallback(callback, result); | ||
}, function(error) { | ||
callback(error); | ||
}); | ||
} | ||
} | ||
// Under Chrome the callback is called before the changes (save, clear) | ||
@@ -357,6 +370,6 @@ // are actually made. So we use a defer function which wait that the | ||
// Pull request : https://github.com/mozilla/localForage/pull/178 | ||
function deferCallback(callback, value) { | ||
function deferCallback(callback, result) { | ||
if (callback) { | ||
return setTimeout(function() { | ||
return callback(value); | ||
return callback(null, result); | ||
}, 0); | ||
@@ -387,2 +400,2 @@ } | ||
} | ||
}).call(this); | ||
}).call(window); |
@@ -8,4 +8,2 @@ // If IndexedDB isn't available, we'll fall back to localStorage. | ||
var keyPrefix = ''; | ||
var dbInfo = {}; | ||
// Promises! | ||
@@ -36,2 +34,4 @@ var Promise = (typeof module !== 'undefined' && module.exports) ? | ||
function _initStorage(options) { | ||
var _this = this; | ||
var dbInfo = {}; | ||
if (options) { | ||
@@ -43,4 +43,5 @@ for (var i in options) { | ||
keyPrefix = dbInfo.name + '/'; | ||
dbInfo.keyPrefix = dbInfo.name + '/'; | ||
_this._dbInfo = dbInfo; | ||
return Promise.resolve(); | ||
@@ -71,13 +72,12 @@ } | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
localStorage.clear(); | ||
if (callback) { | ||
callback(); | ||
} | ||
resolve(); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -90,6 +90,15 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
try { | ||
var result = localStorage.getItem(keyPrefix + key); | ||
var dbInfo = _this._dbInfo; | ||
var result = localStorage.getItem(dbInfo.keyPrefix + key); | ||
@@ -104,16 +113,11 @@ // If a result was found, parse it from the serialized | ||
if (callback) { | ||
callback(result); | ||
} | ||
resolve(result); | ||
} catch (e) { | ||
if (callback) { | ||
callback(null, e); | ||
} | ||
reject(e); | ||
} | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -124,4 +128,5 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var dbInfo = _this._dbInfo; | ||
var result; | ||
@@ -136,11 +141,11 @@ try { | ||
if (result) { | ||
result = result.substring(keyPrefix.length); | ||
result = result.substring(dbInfo.keyPrefix.length); | ||
} | ||
if (callback) { | ||
callback(result); | ||
} | ||
resolve(result); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -150,4 +155,5 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var dbInfo = _this._dbInfo; | ||
var length = localStorage.length; | ||
@@ -157,12 +163,12 @@ var keys = []; | ||
for (var i = 0; i < length; i++) { | ||
keys.push(localStorage.key(i).substring(keyPrefix.length)); | ||
keys.push(localStorage.key(i) | ||
.substring(dbInfo.keyPrefix.length)); | ||
} | ||
if (callback) { | ||
callback(keys); | ||
} | ||
resolve(keys); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -173,13 +179,12 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
var result = localStorage.length; | ||
if (callback) { | ||
callback(result); | ||
} | ||
resolve(result); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -190,13 +195,21 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
localStorage.removeItem(keyPrefix + key); | ||
var dbInfo = _this._dbInfo; | ||
localStorage.removeItem(dbInfo.keyPrefix + key); | ||
if (callback) { | ||
callback(); | ||
} | ||
resolve(); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -299,3 +312,4 @@ | ||
if (value && (value.toString() === '[object ArrayBuffer]' || | ||
value.buffer && value.buffer.toString() === '[object ArrayBuffer]')) { | ||
value.buffer && | ||
value.buffer.toString() === '[object ArrayBuffer]')) { | ||
// Convert binary arrays to a string and prefix the string with | ||
@@ -331,3 +345,3 @@ // a special marker. | ||
} else { | ||
callback(new Error("Failed to get type for BinaryArray")); | ||
callback(new Error('Failed to get type for BinaryArray')); | ||
} | ||
@@ -337,3 +351,3 @@ } | ||
callback(marker + _bufferToString(buffer)); | ||
} else if (valueString === "[object Blob]") { | ||
} else if (valueString === '[object Blob]') { | ||
// Conver the blob to a binaryArray and then to a string. | ||
@@ -353,7 +367,6 @@ var fileReader = new FileReader(); | ||
} catch (e) { | ||
if (this.console && this.console.error) { | ||
this.console.error("Couldn't convert value into a JSON string: ", value); | ||
} | ||
window.console.error("Couldn't convert value into a JSON " + | ||
'string: ', value); | ||
callback(null, e); | ||
callback(e); | ||
} | ||
@@ -369,3 +382,11 @@ } | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
@@ -383,10 +404,7 @@ // Convert undefined values to null. | ||
if (error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
reject(error); | ||
} else { | ||
try { | ||
localStorage.setItem(keyPrefix + key, value); | ||
var dbInfo = _this._dbInfo; | ||
localStorage.setItem(dbInfo.keyPrefix + key, value); | ||
} catch (e) { | ||
@@ -397,6 +415,2 @@ // localStorage capacity exceeded. | ||
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { | ||
if (callback) { | ||
callback(null, e); | ||
} | ||
reject(e); | ||
@@ -406,13 +420,22 @@ } | ||
if (callback) { | ||
callback(originalValue); | ||
} | ||
resolve(originalValue); | ||
} | ||
}); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
function executeCallback(promise, callback) { | ||
if (callback) { | ||
promise.then(function(result) { | ||
callback(null, result); | ||
}, function(error) { | ||
callback(error); | ||
}); | ||
} | ||
} | ||
var localStorageWrapper = { | ||
@@ -440,2 +463,2 @@ _driver: 'localStorageWrapper', | ||
} | ||
}).call(this); | ||
}).call(window); |
@@ -23,4 +23,2 @@ /* | ||
var openDatabase = this.openDatabase; | ||
var db = null; | ||
var dbInfo = {}; | ||
@@ -42,3 +40,4 @@ var SERIALIZED_MARKER = '__lfsc__:'; | ||
var TYPE_FLOAT64ARRAY = 'fl64'; | ||
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length; | ||
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + | ||
TYPE_ARRAYBUFFER.length; | ||
@@ -54,6 +53,10 @@ // If WebSQL methods aren't available, we can stop now. | ||
var _this = this; | ||
var dbInfo = { | ||
db: null | ||
}; | ||
if (options) { | ||
for (var i in options) { | ||
dbInfo[i] = typeof(options[i]) !== 'string' ? options[i].toString() : options[i]; | ||
dbInfo[i] = typeof(options[i]) !== 'string' ? | ||
options[i].toString() : options[i]; | ||
} | ||
@@ -66,12 +69,19 @@ } | ||
try { | ||
db = openDatabase(dbInfo.name, dbInfo.version, | ||
dbInfo.description, dbInfo.size); | ||
dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), | ||
dbInfo.description, dbInfo.size); | ||
} catch (e) { | ||
return _this.setDriver('localStorageWrapper').then(resolve, reject); | ||
return _this.setDriver('localStorageWrapper') | ||
.then(function() { | ||
return _this._initStorage(options); | ||
}) | ||
.then(resolve) | ||
.catch(reject); | ||
} | ||
// Create our key/value table if it doesn't exist. | ||
db.transaction(function(t) { | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + | ||
' (id INTEGER PRIMARY KEY, key unique, value)', [], function() { | ||
' (id INTEGER PRIMARY KEY, key unique, value)', [], | ||
function() { | ||
_this._dbInfo = dbInfo; | ||
resolve(); | ||
@@ -87,8 +97,19 @@ }, function(t, error) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('SELECT * FROM ' + dbInfo.storeName + | ||
' WHERE key = ? LIMIT 1', [key], function(t, results) { | ||
var result = results.rows.length ? results.rows.item(0).value : null; | ||
' WHERE key = ? LIMIT 1', [key], | ||
function(t, results) { | ||
var result = results.rows.length ? | ||
results.rows.item(0).value : null; | ||
@@ -101,11 +122,4 @@ // Check to see if this is serialized content we need to | ||
if (callback) { | ||
callback(result); | ||
} | ||
resolve(result); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
@@ -115,4 +129,7 @@ reject(error); | ||
}); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -122,3 +139,11 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
@@ -139,15 +164,10 @@ // The localStorage API doesn't return undefined values in an | ||
} else { | ||
db.transaction(function(t) { | ||
t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + | ||
' (key, value) VALUES (?, ?)', [key, value], function() { | ||
if (callback) { | ||
callback(originalValue); | ||
} | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('INSERT OR REPLACE INTO ' + | ||
dbInfo.storeName + | ||
' (key, value) VALUES (?, ?)', | ||
[key, value], function() { | ||
resolve(originalValue); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
reject(error); | ||
@@ -165,6 +185,2 @@ }); | ||
// TODO: Try to re-run the transaction. | ||
if (callback) { | ||
callback(null, sqlError); | ||
} | ||
reject(sqlError); | ||
@@ -175,4 +191,7 @@ } | ||
}); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -182,16 +201,19 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
// Cast the key to a string, as that's all we can set as a key. | ||
if (typeof key !== 'string') { | ||
window.console.warn(key + | ||
' used as a key, but it is not a string.'); | ||
key = String(key); | ||
} | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('DELETE FROM ' + dbInfo.storeName + | ||
' WHERE key = ?', [key], function() { | ||
if (callback) { | ||
callback(); | ||
} | ||
resolve(); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(error); | ||
} | ||
@@ -201,4 +223,7 @@ reject(error); | ||
}); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -210,21 +235,19 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function() { | ||
if (callback) { | ||
callback(); | ||
} | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('DELETE FROM ' + dbInfo.storeName, [], | ||
function() { | ||
resolve(); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(error); | ||
} | ||
reject(error); | ||
}); | ||
}); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -236,5 +259,7 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
// Ahhh, SQL makes this one soooooo easy. | ||
@@ -245,11 +270,4 @@ t.executeSql('SELECT COUNT(key) as c FROM ' + | ||
if (callback) { | ||
callback(result); | ||
} | ||
resolve(result); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
@@ -259,4 +277,7 @@ reject(error); | ||
}); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -273,24 +294,22 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('SELECT key FROM ' + dbInfo.storeName + | ||
' WHERE id = ? LIMIT 1', [n + 1], function(t, results) { | ||
var result = results.rows.length ? results.rows.item(0).key : null; | ||
if (callback) { | ||
callback(result); | ||
} | ||
' WHERE id = ? LIMIT 1', [n + 1], | ||
function(t, results) { | ||
var result = results.rows.length ? | ||
results.rows.item(0).key : null; | ||
resolve(result); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
reject(error); | ||
}); | ||
}); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -300,23 +319,17 @@ | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
var promise = new Promise(function(resolve, reject) { | ||
_this.ready().then(function() { | ||
db.transaction(function(t) { | ||
var dbInfo = _this._dbInfo; | ||
dbInfo.db.transaction(function(t) { | ||
t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], | ||
function(t, results) { | ||
var length = results.rows.length; | ||
var keys = []; | ||
for (var i = 0; i < length; i++) { | ||
for (var i = 0; i < results.rows.length; i++) { | ||
keys.push(results.rows.item(i).key); | ||
} | ||
if (callback) { | ||
callback(keys); | ||
} | ||
resolve(keys); | ||
}, function(t, error) { | ||
if (callback) { | ||
callback(null, error); | ||
} | ||
@@ -326,4 +339,7 @@ reject(error); | ||
}); | ||
}, reject); | ||
}).catch(reject); | ||
}); | ||
executeCallback(promise, callback); | ||
return promise; | ||
} | ||
@@ -348,5 +364,5 @@ | ||
if ((bytes.length % 3) === 2) { | ||
base64String = base64String.substring(0, base64String.length - 1) + "="; | ||
base64String = base64String.substring(0, base64String.length - 1) + '='; | ||
} else if (bytes.length % 3 === 1) { | ||
base64String = base64String.substring(0, base64String.length - 2) + "=="; | ||
base64String = base64String.substring(0, base64String.length - 2) + '=='; | ||
} | ||
@@ -369,3 +385,4 @@ | ||
// done with it. | ||
if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { | ||
if (value.substring(0, | ||
SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { | ||
return JSON.parse(value); | ||
@@ -378,3 +395,4 @@ } | ||
var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH); | ||
var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH); | ||
var type = value.substring(SERIALIZED_MARKER_LENGTH, | ||
TYPE_SERIALIZED_MARKER_LENGTH); | ||
@@ -388,5 +406,5 @@ // Fill the string into a ArrayBuffer. | ||
if (serializedString[serializedString.length - 1] === "=") { | ||
if (serializedString[serializedString.length - 1] === '=') { | ||
bufferLength--; | ||
if (serializedString[serializedString.length - 2] === "=") { | ||
if (serializedString[serializedString.length - 2] === '=') { | ||
bufferLength--; | ||
@@ -455,3 +473,4 @@ } | ||
if (value && (value.toString() === '[object ArrayBuffer]' || | ||
value.buffer && value.buffer.toString() === '[object ArrayBuffer]')) { | ||
value.buffer && | ||
value.buffer.toString() === '[object ArrayBuffer]')) { | ||
// Convert binary arrays to a string and prefix the string with | ||
@@ -487,3 +506,3 @@ // a special marker. | ||
} else { | ||
callback(new Error("Failed to get type for BinaryArray")); | ||
callback(new Error('Failed to get type for BinaryArray')); | ||
} | ||
@@ -493,3 +512,3 @@ } | ||
callback(marker + _bufferToString(buffer)); | ||
} else if (valueString === "[object Blob]") { | ||
} else if (valueString === '[object Blob]') { | ||
// Conver the blob to a binaryArray and then to a string. | ||
@@ -509,5 +528,4 @@ var fileReader = new FileReader(); | ||
} catch (e) { | ||
if (this.console && this.console.error) { | ||
this.console.error("Couldn't convert value into a JSON string: ", value); | ||
} | ||
window.console.error("Couldn't convert value into a JSON " + | ||
'string: ', value); | ||
@@ -519,2 +537,12 @@ callback(null, e); | ||
function executeCallback(promise, callback) { | ||
if (callback) { | ||
promise.then(function(result) { | ||
callback(null, result); | ||
}, function(error) { | ||
callback(error); | ||
}); | ||
} | ||
} | ||
var webSQLStorage = { | ||
@@ -541,2 +569,2 @@ _driver: 'webSQLStorage', | ||
} | ||
}).call(this); | ||
}).call(window); |
@@ -8,10 +8,43 @@ (function() { | ||
// Avoid those magic constants! | ||
var MODULE_TYPE_DEFINE = 1; | ||
var MODULE_TYPE_EXPORT = 2; | ||
var MODULE_TYPE_WINDOW = 3; | ||
var DriverType = { | ||
INDEXEDDB: 'asyncStorage', | ||
LOCALSTORAGE: 'localStorageWrapper', | ||
WEBSQL: 'webSQLStorage' | ||
}; | ||
var DefaultDriverOrder = [ | ||
DriverType.INDEXEDDB, | ||
DriverType.WEBSQL, | ||
DriverType.LOCALSTORAGE | ||
]; | ||
var LibraryMethods = [ | ||
'clear', | ||
'getItem', | ||
'key', | ||
'keys', | ||
'length', | ||
'removeItem', | ||
'setItem' | ||
]; | ||
var ModuleType = { | ||
DEFINE: 1, | ||
EXPORT: 2, | ||
WINDOW: 3 | ||
}; | ||
var DefaultConfig = { | ||
description: '', | ||
name: 'localforage', | ||
// Default DB size is _JUST UNDER_ 5MB, as it's the highest size | ||
// we can use without a prompt. | ||
size: 4980736, | ||
storeName: 'keyvaluepairs', | ||
version: 1.0 | ||
}; | ||
// Attaching to window (i.e. no module loader) is the assumed, | ||
// simple default. | ||
var moduleType = MODULE_TYPE_WINDOW; | ||
var moduleType = ModuleType.WINDOW; | ||
@@ -21,225 +54,244 @@ // Find out what kind of module setup we have; if none, we'll just attach | ||
if (typeof define === 'function' && define.amd) { | ||
moduleType = MODULE_TYPE_DEFINE; | ||
moduleType = ModuleType.DEFINE; | ||
} else if (typeof module !== 'undefined' && module.exports) { | ||
moduleType = MODULE_TYPE_EXPORT; | ||
moduleType = ModuleType.EXPORT; | ||
} | ||
// The actual localForage object that we expose as a module or via a | ||
// global. It's extended by pulling in one of our other libraries. | ||
var _this = this; | ||
var localForage = { | ||
INDEXEDDB: 'asyncStorage', | ||
LOCALSTORAGE: 'localStorageWrapper', | ||
WEBSQL: 'webSQLStorage', | ||
// Check to see if IndexedDB is available and if it is the latest | ||
// implementation; it's our preferred backend library. We use "_spec_test" | ||
// as the name of the database because it's not the one we'll operate on, | ||
// but it's useful to make sure its using the right spec. | ||
// See: https://github.com/mozilla/localForage/issues/128 | ||
var driverSupport = (function(_this) { | ||
// Initialize IndexedDB; fall back to vendor-prefixed versions | ||
// if needed. | ||
var indexedDB = indexedDB || _this.indexedDB || _this.webkitIndexedDB || | ||
_this.mozIndexedDB || _this.OIndexedDB || | ||
_this.msIndexedDB; | ||
_config: { | ||
description: '', | ||
name: 'localforage', | ||
// Default DB size is _JUST UNDER_ 5MB, as it's the highest size | ||
// we can use without a prompt. | ||
size: 4980736, | ||
storeName: 'keyvaluepairs', | ||
version: 1.0 | ||
}, | ||
var result = {}; | ||
// Set any config values for localForage; can be called anytime before | ||
// the first API call (e.g. `getItem`, `setItem`). | ||
// We loop through options so we don't overwrite existing config | ||
// values. | ||
config: function(options) { | ||
// If the options argument is an object, we use it to set values. | ||
// Otherwise, we return either a specified config value or all | ||
// config values. | ||
if (typeof(options) === 'object') { | ||
// If localforage is ready and fully initialized, we can't set | ||
// any new configuration values. Instead, we return an error. | ||
if (this._ready) { | ||
return new Error("Can't call config() after localforage " + | ||
"has been used."); | ||
} | ||
result[DriverType.WEBSQL] = !!_this.openDatabase; | ||
result[DriverType.INDEXEDDB] = !!(function() { | ||
try { | ||
return (indexedDB && | ||
typeof indexedDB.open === 'function' && | ||
indexedDB.open('_localforage_spec_test', 1) | ||
.onupgradeneeded === null); | ||
} catch (e) { | ||
return false; | ||
} | ||
})(); | ||
for (var i in options) { | ||
this._config[i] = options[i]; | ||
} | ||
return true; | ||
} else if (typeof(options) === 'string') { | ||
return this._config[options]; | ||
} else { | ||
return this._config; | ||
result[DriverType.LOCALSTORAGE] = !!(function() { | ||
try { | ||
return (localStorage && | ||
typeof localStorage.setItem === 'function'); | ||
} catch (e) { | ||
return false; | ||
} | ||
}, | ||
})(); | ||
driver: function() { | ||
return this._driver || null; | ||
}, | ||
return result; | ||
})(this); | ||
_ready: false, | ||
function extend(/*...*/) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var arg = arguments[i]; | ||
if (arg) { | ||
for (var key in arg) { | ||
if (arg.hasOwnProperty(key)) { | ||
arguments[0][key] = arg[key]; | ||
} | ||
} | ||
} | ||
} | ||
return arguments[0]; | ||
} | ||
_driverSet: null, | ||
function callWhenReady(localForageInstance, libraryMethod) { | ||
localForageInstance[libraryMethod] = function() { | ||
var _args = arguments; | ||
return localForageInstance.ready().then(function() { | ||
return localForageInstance[libraryMethod].apply(localForageInstance, _args); | ||
}); | ||
}; | ||
} | ||
setDriver: function(drivers, callback, errorCallback) { | ||
var self = this; | ||
// The actual localForage object that we expose as a module or via a | ||
// global. It's extended by pulling in one of our other libraries. | ||
var _this = this; | ||
var isArray = Array.isArray || function(arg) { | ||
return Object.prototype.toString.call(arg) === '[object Array]'; | ||
}; | ||
function LocalForage(options) { | ||
this._config = extend({}, DefaultConfig, options); | ||
this._driverSet = null; | ||
this._ready = false; | ||
this._dbInfo = null; | ||
if (!isArray(drivers) && typeof drivers === 'string') { | ||
drivers = [drivers]; | ||
} | ||
// Add a stub for each driver API method that delays the call to the | ||
// corresponding driver method until localForage is ready. These stubs | ||
// will be replaced by the driver methods as soon as the driver is | ||
// loaded, so there is no performance impact. | ||
for (var i = 0; i < LibraryMethods.length; i++) { | ||
callWhenReady(this, LibraryMethods[i]); | ||
} | ||
this._driverSet = new Promise(function(resolve, reject) { | ||
var driverName = self._getFirstSupportedDriver(drivers); | ||
this.setDriver(DefaultDriverOrder); | ||
} | ||
if (!driverName) { | ||
var error = new Error('No available storage method found.'); | ||
self._driverSet = Promise.reject(error); | ||
LocalForage.prototype.INDEXEDDB = DriverType.INDEXEDDB; | ||
LocalForage.prototype.LOCALSTORAGE = DriverType.LOCALSTORAGE; | ||
LocalForage.prototype.WEBSQL = DriverType.WEBSQL; | ||
if (errorCallback) { | ||
errorCallback(error); | ||
} | ||
// Set any config values for localForage; can be called anytime before | ||
// the first API call (e.g. `getItem`, `setItem`). | ||
// We loop through options so we don't overwrite existing config | ||
// values. | ||
LocalForage.prototype.config = function(options) { | ||
// If the options argument is an object, we use it to set values. | ||
// Otherwise, we return either a specified config value or all | ||
// config values. | ||
if (typeof(options) === 'object') { | ||
// If localforage is ready and fully initialized, we can't set | ||
// any new configuration values. Instead, we return an error. | ||
if (this._ready) { | ||
return new Error("Can't call config() after localforage " + | ||
'has been used.'); | ||
} | ||
reject(error); | ||
return; | ||
for (var i in options) { | ||
if (i === 'storeName') { | ||
options[i] = options[i].replace(/\W/g, '_'); | ||
} | ||
self._ready = null; | ||
this._config[i] = options[i]; | ||
} | ||
// We allow localForage to be declared as a module or as a | ||
// library available without AMD/require.js. | ||
if (moduleType === MODULE_TYPE_DEFINE) { | ||
require([driverName], function(lib) { | ||
self._extend(lib); | ||
return true; | ||
} else if (typeof(options) === 'string') { | ||
return this._config[options]; | ||
} else { | ||
return this._config; | ||
} | ||
}; | ||
if (callback) { | ||
callback(); | ||
} | ||
resolve(); | ||
}); | ||
LocalForage.prototype.driver = function() { | ||
return this._driver || null; | ||
}; | ||
return; | ||
} else if (moduleType === MODULE_TYPE_EXPORT) { | ||
// Making it browserify friendly | ||
var driver; | ||
switch (driverName) { | ||
case self.INDEXEDDB: | ||
driver = require('./drivers/indexeddb'); | ||
break; | ||
case self.LOCALSTORAGE: | ||
driver = require('./drivers/localstorage'); | ||
break; | ||
case self.WEBSQL: | ||
driver = require('./drivers/websql'); | ||
} | ||
LocalForage.prototype.ready = function(callback) { | ||
var self = this; | ||
self._extend(driver); | ||
} else { | ||
self._extend(_this[driverName]); | ||
var ready = new Promise(function(resolve, reject) { | ||
self._driverSet.then(function() { | ||
if (self._ready === null) { | ||
self._ready = self._initStorage(self._config); | ||
} | ||
if (callback) { | ||
callback(); | ||
} | ||
self._ready.then(resolve, reject); | ||
}).catch(reject); | ||
}); | ||
resolve(); | ||
}); | ||
ready.then(callback, callback); | ||
return ready; | ||
}; | ||
return this._driverSet; | ||
}, | ||
LocalForage.prototype.setDriver = function(drivers, callback, | ||
errorCallback) { | ||
var self = this; | ||
_getFirstSupportedDriver: function(drivers) { | ||
if (drivers) { | ||
for (var i = 0; i < drivers.length; i++) { | ||
var driver = drivers[i]; | ||
if (typeof drivers === 'string') { | ||
drivers = [drivers]; | ||
} | ||
if (this.supports(driver)) { | ||
return driver; | ||
} | ||
} | ||
} | ||
this._driverSet = new Promise(function(resolve, reject) { | ||
var driverName = self._getFirstSupportedDriver(drivers); | ||
return null; | ||
}, | ||
if (!driverName) { | ||
var error = new Error('No available storage method found.'); | ||
self._driverSet = Promise.reject(error); | ||
supports: function(driverName) { | ||
return !!driverSupport[driverName]; | ||
}, | ||
reject(error); | ||
ready: function(callback) { | ||
var ready = new Promise(function(resolve, reject) { | ||
localForage._driverSet.then(function() { | ||
if (localForage._ready === null) { | ||
localForage._ready = localForage._initStorage( | ||
localForage._config); | ||
} | ||
return; | ||
} | ||
localForage._ready.then(resolve, reject); | ||
}, reject); | ||
}); | ||
self._dbInfo = null; | ||
self._ready = null; | ||
ready.then(callback, callback); | ||
// We allow localForage to be declared as a module or as a | ||
// library available without AMD/require.js. | ||
if (moduleType === ModuleType.DEFINE) { | ||
require([driverName], function(lib) { | ||
self._extend(lib); | ||
return ready; | ||
}, | ||
resolve(); | ||
}); | ||
_extend: function(libraryMethodsAndProperties) { | ||
for (var i in libraryMethodsAndProperties) { | ||
if (libraryMethodsAndProperties.hasOwnProperty(i)) { | ||
this[i] = libraryMethodsAndProperties[i]; | ||
return; | ||
} else if (moduleType === ModuleType.EXPORT) { | ||
// Making it browserify friendly | ||
var driver; | ||
switch (driverName) { | ||
case self.INDEXEDDB: | ||
driver = require('./drivers/indexeddb'); | ||
break; | ||
case self.LOCALSTORAGE: | ||
driver = require('./drivers/localstorage'); | ||
break; | ||
case self.WEBSQL: | ||
driver = require('./drivers/websql'); | ||
} | ||
self._extend(driver); | ||
} else { | ||
self._extend(_this[driverName]); | ||
} | ||
} | ||
resolve(); | ||
}); | ||
this._driverSet.then(callback, errorCallback); | ||
return this._driverSet; | ||
}; | ||
// Check to see if IndexedDB is available and if it is the latest | ||
// implementation; it's our preferred backend library. We use "_spec_test" | ||
// as the name of the database because it's not the one we'll operate on, | ||
// but it's useful to make sure its using the right spec. | ||
// See: https://github.com/mozilla/localForage/issues/128 | ||
var driverSupport = (function(_this) { | ||
// Initialize IndexedDB; fall back to vendor-prefixed versions | ||
// if needed. | ||
var indexedDB = indexedDB || _this.indexedDB || _this.webkitIndexedDB || | ||
_this.mozIndexedDB || _this.OIndexedDB || | ||
_this.msIndexedDB; | ||
LocalForage.prototype.supports = function(driverName) { | ||
return !!driverSupport[driverName]; | ||
}; | ||
var result = {}; | ||
LocalForage.prototype._extend = function(libraryMethodsAndProperties) { | ||
extend(this, libraryMethodsAndProperties); | ||
}; | ||
result[localForage.WEBSQL] = !!_this.openDatabase; | ||
result[localForage.INDEXEDDB] = !!( | ||
indexedDB && | ||
typeof indexedDB.open === 'function' && | ||
indexedDB.open('_localforage_spec_test', 1) | ||
.onupgradeneeded === null | ||
); | ||
LocalForage.prototype._getFirstSupportedDriver = function(drivers) { | ||
var isArray = Array.isArray || function(arg) { | ||
return Object.prototype.toString.call(arg) === '[object Array]'; | ||
}; | ||
result[localForage.LOCALSTORAGE] = !!(function() { | ||
try { | ||
return (localStorage && | ||
typeof localStorage.setItem === 'function'); | ||
} catch (e) { | ||
return false; | ||
if (drivers && isArray(drivers)) { | ||
for (var i = 0; i < drivers.length; i++) { | ||
var driver = drivers[i]; | ||
if (this.supports(driver)) { | ||
return driver; | ||
} | ||
} | ||
})(); | ||
} | ||
return result; | ||
})(this); | ||
return null; | ||
}; | ||
var driverTestOrder = [ | ||
localForage.INDEXEDDB, | ||
localForage.WEBSQL, | ||
localForage.LOCALSTORAGE | ||
]; | ||
LocalForage.prototype.createInstance = function(options) { | ||
return new LocalForage(options); | ||
}; | ||
localForage.setDriver(driverTestOrder); | ||
var localForage = new LocalForage(); | ||
// We allow localForage to be declared as a module or as a library | ||
// available without AMD/require.js. | ||
if (moduleType === MODULE_TYPE_DEFINE) { | ||
if (moduleType === ModuleType.DEFINE) { | ||
define(function() { | ||
return localForage; | ||
}); | ||
} else if (moduleType === MODULE_TYPE_EXPORT) { | ||
} else if (moduleType === ModuleType.EXPORT) { | ||
module.exports = localForage; | ||
@@ -249,2 +301,2 @@ } else { | ||
} | ||
}).call(this); | ||
}).call(window); |
@@ -1,2 +0,2 @@ | ||
/* global after:true, before:true, beforeEach:true, describe:true, expect:true, it:true, Modernizr:true, Promise:true, require:true */ | ||
/* global afterEach:true, before:true, beforeEach:true, describe:true, expect:true, it:true, Modernizr:true, Promise:true, require:true */ | ||
var DRIVERS = [ | ||
@@ -13,6 +13,2 @@ localforage.INDEXEDDB, | ||
describe('localForage API', function() { | ||
beforeEach(function(done) { | ||
localforage.clear(done); | ||
}); | ||
// If this test is failing, you are likely missing the Promises polyfill, | ||
@@ -35,6 +31,7 @@ // installed via bower. Read more here: | ||
appropriateDriver = | ||
(localforage.supports(localforage.WEBSQL) && localforage.WEBSQL) || | ||
(localforage.supports(localforage.INDEXEDDB) && | ||
localforage.INDEXEDDB) || | ||
(localforage.supports(localforage.localStorage) && | ||
(localforage.supports(localforage.WEBSQL) && | ||
localforage.WEBSQL) || | ||
(localforage.supports(localforage.LOCALSTORAGE) && | ||
localforage.localStorage); | ||
@@ -45,17 +42,29 @@ }); | ||
appropriateDriver + ')', function(done) { | ||
if (appropriateDriver) { | ||
localforage.ready().then(function() { | ||
expect(localforage.driver()).to.be(appropriateDriver); | ||
done(); | ||
}); | ||
} else { | ||
localforage.ready().then(null, function(error) { | ||
expect(error).to.be.an(Error); | ||
expect(error.message).to | ||
.be('No available storage method found.'); | ||
expect(localforage.driver()).to.be(null); | ||
done(); | ||
}); | ||
} | ||
localforage.ready().then(function() { | ||
expect(localforage.driver()).to.be(appropriateDriver); | ||
done(); | ||
}, function(error) { | ||
expect(error).to.be.an(Error); | ||
expect(error.message).to | ||
.be('No available storage method found.'); | ||
expect(localforage.driver()).to.be(null); | ||
done(); | ||
}); | ||
}); | ||
it('does not support object parameter to setDriver', function(done) { | ||
var driverPreferedOrder = { | ||
'0': localforage.INDEXEDDB, | ||
'1': localforage.WEBSQL, | ||
'2': localforage.LOCALSTORAGE, | ||
length: 3 | ||
}; | ||
localforage.setDriver(driverPreferedOrder).then(null, function(error) { | ||
expect(error).to.be.an(Error); | ||
expect(error.message).to | ||
.be('No available storage method found.'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -105,2 +114,3 @@ | ||
expect(localforage.ready).to.be.a('function'); | ||
expect(localforage.createInstance).to.be.a('function'); | ||
}); | ||
@@ -119,3 +129,3 @@ | ||
it('has an empty length by default', function(done) { | ||
localforage.length(function(length) { | ||
localforage.length(function(err, length) { | ||
expect(length).to.be(0); | ||
@@ -131,3 +141,3 @@ done(); | ||
it('returns null for undefined key [callback]', function(done) { | ||
localforage.getItem('key', function(value) { | ||
localforage.getItem('key', function(err, value) { | ||
expect(value).to.be(null); | ||
@@ -145,6 +155,6 @@ done(); | ||
it('saves an item [callback]', function(done) { | ||
localforage.setItem('office', 'Initech', function(setValue) { | ||
localforage.setItem('office', 'Initech', function(err, setValue) { | ||
expect(setValue).to.be('Initech'); | ||
localforage.getItem('office', function(value) { | ||
localforage.getItem('office', function(err, value) { | ||
expect(value).to.be(setValue); | ||
@@ -167,10 +177,12 @@ done(); | ||
it('saves an item over an existing key [callback]', function(done) { | ||
localforage.setItem('4th floor', 'Mozilla', function(setValue) { | ||
localforage.setItem('4th floor', 'Mozilla', | ||
function(err, setValue) { | ||
expect(setValue).to.be('Mozilla'); | ||
localforage.setItem('4th floor', 'Quora', function(newValue) { | ||
localforage.setItem('4th floor', 'Quora', | ||
function(err, newValue) { | ||
expect(newValue).to.not.be(setValue); | ||
expect(newValue).to.be('Quora'); | ||
localforage.getItem('4th floor', function(value) { | ||
localforage.getItem('4th floor', function(err, value) { | ||
expect(value).to.not.be(setValue); | ||
@@ -201,3 +213,3 @@ expect(value).to.be(newValue); | ||
it('returns null when saving undefined [callback]', function(done) { | ||
localforage.setItem('undef', undefined, function(setValue) { | ||
localforage.setItem('undef', undefined, function(err, setValue) { | ||
expect(setValue).to.be(null); | ||
@@ -217,3 +229,3 @@ | ||
it('returns null for a non-existant key [callback]', function(done) { | ||
localforage.getItem('undef', function(value) { | ||
localforage.getItem('undef', function(err, value) { | ||
expect(value).to.be(null); | ||
@@ -243,3 +255,3 @@ | ||
it('returns null from an undefined key [callback]', function(done) { | ||
localforage.key(0, function(key) { | ||
localforage.key(0, function(err, key) { | ||
expect(key).to.be(null); | ||
@@ -260,3 +272,3 @@ | ||
localforage.setItem('office', 'Initech').then(function() { | ||
localforage.key(0, function(key) { | ||
localforage.key(0, function(err, key) { | ||
expect(key).to.be('office'); | ||
@@ -282,7 +294,8 @@ | ||
localforage.removeItem('office', function() { | ||
localforage.getItem('office', function(emptyValue) { | ||
localforage.getItem('office', | ||
function(err, emptyValue) { | ||
expect(emptyValue).to.be(null); | ||
localforage.getItem('otherOffice', | ||
function(value) { | ||
function(err, value) { | ||
expect(value).to.be('Initrode'); | ||
@@ -318,10 +331,10 @@ | ||
localforage.setItem('otherOffice', 'Initrode', function() { | ||
localforage.length(function(length) { | ||
localforage.length(function(err, length) { | ||
expect(length).to.be(2); | ||
localforage.clear(function() { | ||
localforage.getItem('office', function(value) { | ||
localforage.getItem('office', function(err, value) { | ||
expect(value).to.be(null); | ||
localforage.length(function(length) { | ||
localforage.length(function(err, length) { | ||
expect(length).to.be(0); | ||
@@ -360,6 +373,6 @@ | ||
it('has a length after saving an item [callback]', function(done) { | ||
localforage.length(function(length) { | ||
localforage.length(function(err, length) { | ||
expect(length).to.be(0); | ||
localforage.setItem('rapper', 'Black Thought', function() { | ||
localforage.length(function(length) { | ||
localforage.length(function(err, length) { | ||
expect(length).to.be(1); | ||
@@ -385,4 +398,135 @@ | ||
}); | ||
// Deal with non-string keys, see issue #250 | ||
// https://github.com/mozilla/localForage/issues/250 | ||
it('casts an undefined key to a String', function(done) { | ||
localforage.setItem(undefined, 'goodness!').then(function(value) { | ||
expect(value).to.be('goodness!'); | ||
return localforage.getItem(undefined); | ||
}).then(function(value) { | ||
expect(value).to.be('goodness!'); | ||
return localforage.removeItem(undefined); | ||
}).then(function() { | ||
return localforage.length(); | ||
}).then(function(length) { | ||
expect(length).to.be(0); | ||
done(); | ||
}); | ||
}); | ||
it('casts a null key to a String', function(done) { | ||
localforage.setItem(null, 'goodness!').then(function(value) { | ||
expect(value).to.be('goodness!'); | ||
return localforage.getItem(null); | ||
}).then(function(value) { | ||
expect(value).to.be('goodness!'); | ||
return localforage.removeItem(null); | ||
}).then(function() { | ||
return localforage.length(); | ||
}).then(function(length) { | ||
expect(length).to.be(0); | ||
done(); | ||
}); | ||
}); | ||
it('casts a float key to a String', function(done) { | ||
localforage.setItem(537.35737, 'goodness!').then(function(value) { | ||
expect(value).to.be('goodness!'); | ||
return localforage.getItem(537.35737); | ||
}).then(function(value) { | ||
expect(value).to.be('goodness!'); | ||
return localforage.removeItem(537.35737); | ||
}).then(function() { | ||
return localforage.length(); | ||
}).then(function(length) { | ||
expect(length).to.be(0); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe(driverName + ' driver instance', function() { | ||
'use strict'; | ||
var localforage2 = null; | ||
var Promise; | ||
before(function(done) { | ||
Promise = window.Promise || require('promise'); | ||
localforage2 = localforage.createInstance({ | ||
name: 'storage2', | ||
// We need a small value here | ||
// otherwise local PhantomJS test | ||
// will fail with SECURITY_ERR. | ||
// TravisCI seem to work fine though. | ||
size: 1024, | ||
storeName: 'storagename2' | ||
}); | ||
Promise.all([ | ||
localforage.setDriver(driverName), | ||
localforage2.setDriver(driverName) | ||
]) | ||
.then(function() { | ||
done(); | ||
}); | ||
}); | ||
beforeEach(function(done) { | ||
Promise.all([ | ||
localforage.clear(), | ||
localforage2.clear() | ||
]).then(function() { | ||
done(); | ||
}); | ||
}); | ||
it('is not be able to access values of other instances', function(done) { | ||
Promise.all([ | ||
localforage.setItem('key1', 'value1a'), | ||
localforage2.setItem('key2', 'value2a') | ||
]).then(function() { | ||
return Promise.all([ | ||
localforage.getItem('key2').then(function(value) { | ||
expect(value).to.be(null); | ||
}), | ||
localforage2.getItem('key1').then(function(value) { | ||
expect(value).to.be(null); | ||
}) | ||
]); | ||
}).then(function() { | ||
done(); | ||
}, function(errors) { | ||
done(new Error(errors)); | ||
}); | ||
}); | ||
it('retrieves the proper value when using the same key with other instances', function(done) { | ||
Promise.all([ | ||
localforage.setItem('key', 'value1'), | ||
localforage2.setItem('key', 'value2') | ||
]).then(function() { | ||
return Promise.all([ | ||
localforage.getItem('key').then(function(value) { | ||
expect(value).to.be('value1'); | ||
}), | ||
localforage2.getItem('key').then(function(value) { | ||
expect(value).to.be('value2'); | ||
}) | ||
]); | ||
}).then(function() { | ||
done(); | ||
}, function(errors) { | ||
done(new Error(errors)); | ||
}); | ||
}); | ||
}); | ||
describe(driverName + ' driver', function() { | ||
@@ -421,23 +565,28 @@ 'use strict'; | ||
describe(driverName + ' driver when ready() gets rejected', function() { | ||
describe(driverName + ' driver when the callback throws an Error', function() { | ||
'use strict'; | ||
var _oldReady; | ||
var testObj = { | ||
throwFunc: function() { | ||
testObj.throwFuncCalls++; | ||
throw new Error('Thrown test error'); | ||
}, | ||
throwFuncCalls: 0 | ||
}; | ||
before(function(done) { | ||
_oldReady = localforage.ready; | ||
localforage.ready = function() { | ||
return Promise.reject(); | ||
}; | ||
beforeEach(function(done) { | ||
testObj.throwFuncCalls = 0; | ||
done(); | ||
}); | ||
after(function(done) { | ||
localforage.ready = _oldReady; | ||
_oldReady = null; | ||
done(); | ||
it('resolves the promise of getItem()', function(done) { | ||
localforage.getItem('key', testObj.throwFunc).then(function() { | ||
expect(testObj.throwFuncCalls).to.be(1); | ||
done(); | ||
}); | ||
}); | ||
it('rejects getItem() promise', function(done) { | ||
localforage.getItem().then(null, function(/*err*/) { | ||
it('resolves the promise of setItem()', function(done) { | ||
localforage.setItem('key', 'test', testObj.throwFunc).then(function() { | ||
expect(testObj.throwFuncCalls).to.be(1); | ||
done(); | ||
@@ -447,4 +596,5 @@ }); | ||
it('rejects setItem() promise', function(done) { | ||
localforage.setItem().then(null, function(/*err*/) { | ||
it('resolves the promise of clear()', function(done) { | ||
localforage.clear(testObj.throwFunc).then(function() { | ||
expect(testObj.throwFuncCalls).to.be(1); | ||
done(); | ||
@@ -454,4 +604,5 @@ }); | ||
it('rejects clear() promise', function(done) { | ||
localforage.clear().then(null, function(/*err*/) { | ||
it('resolves the promise of length()', function(done) { | ||
localforage.length(testObj.throwFunc).then(function() { | ||
expect(testObj.throwFuncCalls).to.be(1); | ||
done(); | ||
@@ -461,4 +612,5 @@ }); | ||
it('rejects length() promise', function(done) { | ||
localforage.length().then(null, function(/*err*/) { | ||
it('resolves the promise of removeItem()', function(done) { | ||
localforage.removeItem('key', testObj.throwFunc).then(function() { | ||
expect(testObj.throwFuncCalls).to.be(1); | ||
done(); | ||
@@ -468,4 +620,5 @@ }); | ||
it('rejects removeItem() promise', function(done) { | ||
localforage.removeItem().then(null, function(/*err*/) { | ||
it('resolves the promise of key()', function(done) { | ||
localforage.key('key', testObj.throwFunc).then(function() { | ||
expect(testObj.throwFuncCalls).to.be(1); | ||
done(); | ||
@@ -475,11 +628,44 @@ }); | ||
it('rejects key() promise', function(done) { | ||
localforage.key().then(null, function(/*err*/) { | ||
it('resolves the promise of keys()', function(done) { | ||
localforage.keys(testObj.throwFunc).then(function() { | ||
expect(testObj.throwFuncCalls).to.be(1); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('rejects keys() promise', function(done) { | ||
localforage.keys().then(null, function(/*err*/) { | ||
done(); | ||
describe(driverName + ' driver when ready() gets rejected', function() { | ||
'use strict'; | ||
var _oldReady; | ||
beforeEach(function(done) { | ||
_oldReady = localforage.ready; | ||
localforage.ready = function() { | ||
return Promise.reject(); | ||
}; | ||
done(); | ||
}); | ||
afterEach(function(done) { | ||
localforage.ready = _oldReady; | ||
_oldReady = null; | ||
done(); | ||
}); | ||
var driverApiMethods = [ | ||
'getItem', | ||
'setItem', | ||
'clear', | ||
'length', | ||
'removeItem', | ||
'key', | ||
'keys' | ||
]; | ||
driverApiMethods.forEach(function(methodName) { | ||
it('rejects ' + methodName + '() promise', function(done) { | ||
localforage[methodName]().then(null, function(/*err*/) { | ||
done(); | ||
}); | ||
}); | ||
@@ -486,0 +672,0 @@ }); |
@@ -34,3 +34,3 @@ /* global before:true, beforeEach:true, describe:true, expect:true, it:true */ | ||
var error = "Error: Can't call config() after localforage " + | ||
"has been used."; | ||
'has been used.'; | ||
@@ -70,2 +70,15 @@ expect(configResult).to.not.be(true); | ||
it('converts bad config values across drivers', function() { | ||
localforage.config({ | ||
name: 'My Cool App', | ||
// https://github.com/mozilla/localForage/issues/247 | ||
storeName: 'my store&front-v1', | ||
version: 2.0 | ||
}); | ||
expect(localforage.config('name')).to.be('My Cool App'); | ||
expect(localforage.config('storeName')).to.be('my_store_front_v1'); | ||
expect(localforage.config('version')).to.be(2.0); | ||
}); | ||
it('uses the config values in ' + localforage.driver(), function(done) { | ||
@@ -96,4 +109,4 @@ localforage.config({ | ||
} else if (localforage.driver() === localforage.WEBSQL) { | ||
window.openDatabase('My Cool App', (2.0).toString(), | ||
'', 4980736).transaction(function(t) { | ||
window.openDatabase('My Cool App', String(2.0), '', | ||
4980736).transaction(function(t) { | ||
t.executeSql('SELECT * FROM storeFront WHERE key = ? ' + | ||
@@ -100,0 +113,0 @@ 'LIMIT 1', ['some key'], |
@@ -29,6 +29,6 @@ /* global before:true, beforeEach:true, describe:true, expect:true, it:true, Modernizr:true */ | ||
it('saves a string [callback]', function(done) { | ||
localforage.setItem('office', 'Initech', function(setValue) { | ||
localforage.setItem('office', 'Initech', function(err, setValue) { | ||
expect(setValue).to.be('Initech'); | ||
localforage.getItem('office', function(value) { | ||
localforage.getItem('office', function(err, value) { | ||
expect(value).to.be(setValue); | ||
@@ -51,7 +51,7 @@ done(); | ||
it('saves a number [callback]', function(done) { | ||
localforage.setItem('number', 546, function(setValue) { | ||
localforage.setItem('number', 546, function(err, setValue) { | ||
expect(setValue).to.be(546); | ||
expect(setValue).to.be.a('number'); | ||
localforage.getItem('number', function(value) { | ||
localforage.getItem('number', function(err, value) { | ||
expect(value).to.be(setValue); | ||
@@ -77,7 +77,7 @@ expect(value).to.be.a('number'); | ||
it('saves a boolean [callback]', function(done) { | ||
localforage.setItem('boolean', false, function(setValue) { | ||
localforage.setItem('boolean', false, function(err, setValue) { | ||
expect(setValue).to.be(false); | ||
expect(setValue).to.be.a('boolean'); | ||
localforage.getItem('boolean', function(value) { | ||
localforage.getItem('boolean', function(err, value) { | ||
expect(value).to.be(setValue); | ||
@@ -103,6 +103,6 @@ expect(value).to.be.a('boolean'); | ||
it('saves null [callback]', function(done) { | ||
localforage.setItem('null', null, function(setValue) { | ||
localforage.setItem('null', null, function(err, setValue) { | ||
expect(setValue).to.be(null); | ||
localforage.getItem('null', function(value) { | ||
localforage.getItem('null', function(err, value) { | ||
expect(value).to.be(null); | ||
@@ -125,6 +125,6 @@ done(); | ||
it('saves undefined as null [callback]', function(done) { | ||
localforage.setItem('null', undefined, function(setValue) { | ||
localforage.setItem('null', undefined, function(err, setValue) { | ||
expect(setValue).to.be(null); | ||
localforage.getItem('null', function(value) { | ||
localforage.getItem('null', function(err, value) { | ||
expect(value).to.be(null); | ||
@@ -147,7 +147,7 @@ done(); | ||
it('saves a float [callback]', function(done) { | ||
localforage.setItem('float', 546.041, function(setValue) { | ||
localforage.setItem('float', 546.041, function(err, setValue) { | ||
expect(setValue).to.be(546.041); | ||
expect(setValue).to.be.a('number'); | ||
localforage.getItem('float', function(value) { | ||
localforage.getItem('float', function(err, value) { | ||
expect(value).to.be(setValue); | ||
@@ -174,7 +174,7 @@ expect(value).to.be.a('number'); | ||
it('saves an array [callback]', function(done) { | ||
localforage.setItem('array', arrayToSave, function(setValue) { | ||
localforage.setItem('array', arrayToSave, function(err, setValue) { | ||
expect(setValue.length).to.be(arrayToSave.length); | ||
expect(setValue instanceof Array).to.be(true); | ||
localforage.getItem('array', function(value) { | ||
localforage.getItem('array', function(err, value) { | ||
expect(value.length).to.be(arrayToSave.length); | ||
@@ -215,3 +215,3 @@ expect(value instanceof Array).to.be(true); | ||
it('saves a nested object [callback]', function(done) { | ||
localforage.setItem('obj', objectToSave, function(setValue) { | ||
localforage.setItem('obj', objectToSave, function(err, setValue) { | ||
expect(Object.keys(setValue).length) | ||
@@ -221,3 +221,3 @@ .to.be(Object.keys(objectToSave).length); | ||
localforage.getItem('obj', function(value) { | ||
localforage.getItem('obj', function(err, value) { | ||
expect(Object.keys(value).length) | ||
@@ -265,3 +265,3 @@ .to.be(Object.keys(objectToSave).length); | ||
var response = request.response; | ||
localforage.setItem('ab', response, function(sab) { | ||
localforage.setItem('ab', response, function(err, sab) { | ||
expect(sab.toString()) | ||
@@ -275,3 +275,3 @@ .to.be('[object ArrayBuffer]'); | ||
// open transaction issue? | ||
localforage.getItem('ab', function(arrayBuff) { | ||
localforage.getItem('ab', function(err, arrayBuff) { | ||
expect(arrayBuff.toString()) | ||
@@ -301,4 +301,4 @@ .to.be('[object ArrayBuffer]'); | ||
localforage.setItem('array', array, function(writeValue) { | ||
localforage.getItem('array', function(readValue) { | ||
localforage.setItem('array', array, function(err, writeValue) { | ||
localforage.getItem('array', function(err, readValue) { | ||
expect(readValue instanceof Int8Array).to.be(true); | ||
@@ -323,4 +323,4 @@ expect(readValue[2]).to.be(array[2]); | ||
localforage.setItem('array', array, function(writeValue) { | ||
localforage.getItem('array', function(readValue) { | ||
localforage.setItem('array', array, function(err, writeValue) { | ||
localforage.getItem('array', function(err, readValue) { | ||
expect(readValue instanceof Uint8Array).to.be(true); | ||
@@ -346,4 +346,4 @@ expect(readValue[0]).to.be(array[0]); | ||
localforage.setItem('array', array, function(writeValue) { | ||
localforage.getItem('array', function(readValue) { | ||
localforage.setItem('array', array, function(err, writeValue) { | ||
localforage.getItem('array', function(err, readValue) { | ||
expect(readValue instanceof Uint8ClampedArray) | ||
@@ -371,4 +371,4 @@ .to.be(true); | ||
localforage.setItem('array', array, function(writeValue) { | ||
localforage.getItem('array', function(readValue) { | ||
localforage.setItem('array', array, function(err, writeValue) { | ||
localforage.getItem('array', function(err, readValue) { | ||
expect(readValue instanceof Int16Array).to.be(true); | ||
@@ -393,4 +393,4 @@ expect(readValue[0]).to.be(array[0]); | ||
localforage.setItem('array', array, function(writeValue) { | ||
localforage.getItem('array', function(readValue) { | ||
localforage.setItem('array', array, function(err, writeValue) { | ||
localforage.getItem('array', function(err, readValue) { | ||
expect(readValue instanceof Uint16Array).to.be(true); | ||
@@ -415,4 +415,4 @@ expect(readValue[0]).to.be(array[0]); | ||
localforage.setItem('array', array, function(writeValue) { | ||
localforage.getItem('array', function(readValue) { | ||
localforage.setItem('array', array, function(err, writeValue) { | ||
localforage.getItem('array', function(err, readValue) { | ||
expect(readValue instanceof Int32Array).to.be(true); | ||
@@ -437,4 +437,4 @@ expect(readValue[0]).to.be(array[0]); | ||
localforage.setItem('array', array, function(writeValue) { | ||
localforage.getItem('array', function(readValue) { | ||
localforage.setItem('array', array, function(err, writeValue) { | ||
localforage.getItem('array', function(err, readValue) { | ||
expect(readValue instanceof Uint32Array).to.be(true); | ||
@@ -459,4 +459,4 @@ expect(readValue[0]).to.be(array[0]); | ||
localforage.setItem('array', array, function(writeValue) { | ||
localforage.getItem('array', function(readValue) { | ||
localforage.setItem('array', array, function(err, writeValue) { | ||
localforage.getItem('array', function(err, readValue) { | ||
expect(readValue instanceof Float32Array).to.be(true); | ||
@@ -481,4 +481,4 @@ expect(readValue[0]).to.be(array[0]); | ||
localforage.setItem('array', array, function(writeValue) { | ||
localforage.getItem('array', function(readValue) { | ||
localforage.setItem('array', array, function(err, writeValue) { | ||
localforage.getItem('array', function(err, readValue) { | ||
expect(readValue instanceof Float64Array).to.be(true); | ||
@@ -485,0 +485,0 @@ expect(readValue[0]).to.be(array[0]); |
@@ -27,5 +27,5 @@ /* global describe:true, expect:true, it:true, Modernizr:true */ | ||
it('fails to load localForage [callback]', function(done) { | ||
localforage.ready(function(error) { | ||
expect(error).to.be.an(Error); | ||
expect(error.message).to.be('No available storage method found.'); | ||
localforage.ready(function(err) { | ||
expect(err).to.be.an(Error); | ||
expect(err.message).to.be('No available storage method found.'); | ||
done(); | ||
@@ -36,5 +36,5 @@ }); | ||
it('fails to load localForage [promise]', function(done) { | ||
localforage.ready().then(null, function(error) { | ||
expect(error).to.be.an(Error); | ||
expect(error.message).to.be('No available storage method found.'); | ||
localforage.ready().then(null, function(err) { | ||
expect(err).to.be.an(Error); | ||
expect(err.message).to.be('No available storage method found.'); | ||
done(); | ||
@@ -53,6 +53,5 @@ }); | ||
it('fails to setDriver ' + driverName + ' [callback]', function(done) { | ||
localforage.setDriver(driverName, null, function(error) { | ||
expect(error).to.be.an(Error); | ||
expect(error.message).to | ||
.be('No available storage method found.'); | ||
localforage.setDriver(driverName, null, function(err) { | ||
expect(err).to.be.an(Error); | ||
expect(err.message).to.be('No available storage method found.'); | ||
done(); | ||
@@ -63,6 +62,5 @@ }); | ||
it('fails to setDriver ' + driverName + ' [promise]', function(done) { | ||
localforage.setDriver(driverName).then(null, function(error) { | ||
expect(error).to.be.an(Error); | ||
expect(error.message).to | ||
.be('No available storage method found.'); | ||
localforage.setDriver(driverName).then(null, function(err) { | ||
expect(err).to.be.an(Error); | ||
expect(err.message).to.be('No available storage method found.'); | ||
done(); | ||
@@ -74,5 +72,5 @@ }); | ||
it('fails to setDriver using array parameter [callback]', function(done) { | ||
localforage.setDriver(DRIVERS, null, function(error) { | ||
expect(error).to.be.an(Error); | ||
expect(error.message).to.be('No available storage method found.'); | ||
localforage.setDriver(DRIVERS, null, function(err) { | ||
expect(err).to.be.an(Error); | ||
expect(err.message).to.be('No available storage method found.'); | ||
done(); | ||
@@ -83,5 +81,5 @@ }); | ||
it('fails to setDriver using array parameter [promise]', function(done) { | ||
localforage.setDriver(DRIVERS).then(null, function(error) { | ||
expect(error).to.be.an(Error); | ||
expect(error.message).to.be('No available storage method found.'); | ||
localforage.setDriver(DRIVERS).then(null, function(err) { | ||
expect(err).to.be.an(Error); | ||
expect(err.message).to.be('No available storage method found.'); | ||
done(); | ||
@@ -88,0 +86,0 @@ }); |
@@ -15,3 +15,3 @@ /*globals importScripts:true, self:true */ | ||
localforage.setItem('web worker', e.data.value, function() { | ||
localforage.getItem('web worker', function(value) { | ||
localforage.getItem('web worker', function(err, value) { | ||
self.postMessage({ | ||
@@ -18,0 +18,0 @@ body: value |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
949298
101
11407
298
1
17
+ Addedpromise@^5.0.0
+ Addedasap@1.0.0(transitive)
+ Addedpromise@5.0.0(transitive)