UNPKG

imdone

Version:

A task board and wiki in one!

219 lines (211 loc) 8.43 kB
/** * Copyright (c) 2013, ESHA Research * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html */ ;(function(window) { var _ = { version: "<%= pkg.version %>", areas: {}, apis: {}, // utilities inherit: function(api, o) { for (var p in api) { if (!o.hasOwnProperty(p)) { o[p] = api[p]; } } return o; }, stringify: function(d) { return d === undefined || typeof d === "function" ? d+'' : JSON.stringify(d); }, parse: function(s) { // if it doesn't parse, return as is try{ return JSON.parse(s); }catch(e){ return s; } }, // extension hooks fn: function(name, fn) { _.storeAPI[name] = fn; for (var api in _.apis) { _.apis[api][name] = fn; } }, get: function(area, key){ return area.getItem(key); }, set: function(area, key, string){ area.setItem(key, string); }, remove: function(area, key){ area.removeItem(key); }, key: function(area, i){ return area.key(i); }, length: function(area){ return area.length; }, clear: function(area){ area.clear(); }, // core functions Store: function(id, area, namespace) { var store = _.inherit(_.storeAPI, function(key, data, overwrite) { if (arguments.length === 0){ return store.getAll(); } if (data !== undefined){ return store.set(key, data, overwrite); } if (typeof key === "string"){ return store.get(key); } if (!key){ return store.clear(); } return store.setAll(key, data);// overwrite=data, data=key }); store._id = id; store._area = area || _.inherit(_.storageAPI, { items: {}, name: 'fake' }); store._ns = namespace || ''; if (!_.areas[id]) { _.areas[id] = store._area; } if (!_.apis[store._ns+store._id]) { _.apis[store._ns+store._id] = store; } return store; }, storeAPI: { // admin functions area: function(id, area) { var store = this[id]; if (!store || !store.area) { store = _.Store(id, area, this._ns);//new area-specific api in this namespace if (!this[id]){ this[id] = store; } } return store; }, namespace: function(namespace, noSession) { if (!namespace){ return this._ns ? this._ns.substring(0,this._ns.length-1) : ''; } var ns = namespace, store = this[ns]; if (!store || !store.namespace) { store = _.Store(this._id, this._area, this._ns+ns+'.');//new namespaced api if (!this[ns]){ this[ns] = store; } if (!noSession){ store.area('session', _.areas.session); } } return store; }, isFake: function(){ return this._area.name === 'fake'; }, toString: function() { return 'store'+(this._ns?'.'+this.namespace():'')+'['+this._id+']'; }, // storage functions has: function(key) { if (this._area.has) { return this._area.has(this._in(key));//extension hook } return !!(this._in(key) in this._area); }, size: function(){ return this.keys().length; }, each: function(fn, and) { for (var i=0, m=_.length(this._area); i<m; i++) { var key = this._out(_.key(this._area, i)); if (key !== undefined) { if (fn.call(this, key, and || this.get(key)) === false) { break; } } if (m > _.length(this._area)) { m--; i--; }// in case of removeItem } return and || this; }, keys: function() { return this.each(function(k, list){ list.push(k); }, []); }, get: function(key, alt) { var s = _.get(this._area, this._in(key)); return s !== null ? _.parse(s) : alt || s;// support alt for easy default mgmt }, getAll: function() { return this.each(function(k, all){ all[k] = this.get(k); }, {}); }, set: function(key, data, overwrite) { var d = this.get(key); if (d != null && overwrite === false) { return data; } return _.set(this._area, this._in(key), _.stringify(data), overwrite) || d; }, setAll: function(data, overwrite) { var changed, val; for (var key in data) { val = data[key]; if (this.set(key, val, overwrite) !== val) { changed = true; } } return changed; }, remove: function(key) { var d = this.get(key); _.remove(this._area, this._in(key)); return d; }, clear: function() { if (!this._ns) { _.clear(this._area); } else { this.each(function(k){ _.remove(this._area, this._in(k)); }, 1); } return this; }, clearAll: function() { var area = this._area; for (var id in _.areas) { if (_.areas.hasOwnProperty(id)) { this._area = _.areas[id]; this.clear(); } } this._area = area; return this; }, // internal use functions _in: function(k) { if (typeof k !== "string"){ k = _.stringify(k); } return this._ns ? this._ns + k : k; }, _out: function(k) { return this._ns ? k && k.indexOf(this._ns) === 0 ? k.substring(this._ns.length) : undefined : // so each() knows to skip it k; } },// end _.storeAPI storageAPI: { length: 0, has: function(k){ return this.items.hasOwnProperty(k); }, key: function(i) { var c = 0; for (var k in this.items){ if (this.has(k) && i === c++) { return k; } } }, setItem: function(k, v) { if (!this.has(k)) { this.length++; } this.items[k] = v; }, removeItem: function(k) { if (this.has(k)) { delete this.items[k]; this.length--; } }, getItem: function(k){ return this.has(k) ? this.items[k] : null; }, clear: function(){ for (var k in this.list){ this.removeItem(k); } }, toString: function(){ return this.length+' items in '+this.name+'Storage'; } }// end _.storageAPI }; // setup the primary store fn if (window.store){ _.conflict = window.store; } var store = window.store = // safely set this up (throws error in IE10/32bit mode for local files) _.Store("local", (function(){try{ return localStorage; }catch(e){}})()); store.local = store;// for completeness store._ = _;// for extenders and debuggers... // safely setup store.session (throws exception in FF for file:/// urls) store.area("session", (function(){try{ return sessionStorage; }catch(e){}})()); if (typeof module !== 'undefined' && module.exports) { module.exports = store; } })(window);