123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- /*! store2 - v2.14.3 - 2024-02-14
- * Copyright (c) 2024 Nathan Bubna; Licensed MIT */
- ;(function(window, define) {
- var _ = {
- version: "2.14.3",
- areas: {},
- apis: {},
- nsdelim: '.',
- // utilities
- inherit: function(api, o) {
- for (var p in api) {
- if (!o.hasOwnProperty(p)) {
- Object.defineProperty(o, p, Object.getOwnPropertyDescriptor(api, p));
- }
- }
- return o;
- },
- stringify: function(d, fn) {
- return d === undefined || typeof d === "function" ? d+'' : JSON.stringify(d,fn||_.replace);
- },
- parse: function(s, fn) {
- // if it doesn't parse, return as is
- try{ return JSON.parse(s,fn||_.revive); }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 (typeof data === "function"){ return store.transact(key, data, overwrite); }// fn=data, alt=overwrite
- if (data !== undefined){ return store.set(key, data, overwrite); }
- if (typeof key === "string" || typeof key === "number"){ return store.get(key); }
- if (typeof key === "function"){ return store.each(key); }
- if (!key){ return store.clear(); }
- return store.setAll(key, data);// overwrite=data, data=key
- });
- store._id = id;
- try {
- var testKey = '__store2_test';
- area.setItem(testKey, 'ok');
- store._area = area;
- area.removeItem(testKey);
- } catch (e) {
- store._area = _.storage('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, singleArea, delim) {
- delim = delim || this._delim || _.nsdelim;
- if (!namespace){
- return this._ns ? this._ns.substring(0,this._ns.length-delim.length) : '';
- }
- var ns = namespace, store = this[ns];
- if (!store || !store.namespace) {
- store = _.Store(this._id, this._area, this._ns+ns+delim);//new namespaced api
- store._delim = delim;
- if (!this[ns]){ this[ns] = store; }
- if (!singleArea) {
- for (var name in _.areas) {
- store.area(name, _.areas[name]);
- }
- }
- }
- return store;
- },
- isFake: function(force) {
- if (force) {
- this._real = this._area;
- this._area = _.storage('fake');
- } else if (force === false) {
- this._area = this._real || this._area;
- }
- 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, fill) {// fill is used by keys(fillList) and getAll(fillList))
- 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, this.get(key), fill) === false) {
- break;
- }
- }
- if (m > _.length(this._area)) { m--; i--; }// in case of removeItem
- }
- return fill || this;
- },
- keys: function(fillList) {
- return this.each(function(k, v, list){ list.push(k); }, fillList || []);
- },
- get: function(key, alt) {
- var s = _.get(this._area, this._in(key)),
- fn;
- if (typeof alt === "function") {
- fn = alt;
- alt = null;
- }
- return s !== null ? _.parse(s, fn) :
- alt != null ? alt : s;
- },
- getAll: function(fillObj) {
- return this.each(function(k, v, all){ all[k] = v; }, fillObj || {});
- },
- transact: function(key, fn, alt) {
- var val = this.get(key, alt),
- ret = fn(val);
- this.set(key, ret === undefined ? val : ret);
- return this;
- },
- set: function(key, data, overwrite) {
- var d = this.get(key),
- replacer;
- if (d != null && overwrite === false) {
- return data;
- }
- if (typeof overwrite === "function") {
- replacer = overwrite;
- overwrite = undefined;
- }
- return _.set(this._area, this._in(key), _.stringify(data, replacer), 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;
- },
- add: function(key, data, replacer) {
- var d = this.get(key);
- if (d instanceof Array) {
- data = d.concat(data);
- } else if (d !== null) {
- var type = typeof d;
- if (type === typeof data && type === 'object') {
- for (var k in data) {
- d[k] = data[k];
- }
- data = d;
- } else {
- data = d + data;
- }
- }
- _.set(this._area, this._in(key), _.stringify(data, replacer));
- return data;
- },
- remove: function(key, alt) {
- var d = this.get(key, alt);
- _.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
- storage: function(name) {
- return _.inherit(_.storageAPI, { items: {}, name: name });
- },
- 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.items){ this.removeItem(k); } }
- }// end _.storageAPI
- };
- var 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){}})());
- store.area("page", _.storage("page"));
- if (typeof define === 'function' && define.amd !== undefined) {
- define('store2', [], function () {
- return store;
- });
- } else if (typeof module !== 'undefined' && module.exports) {
- module.exports = store;
- } else {
- // expose the primary store fn to the global object and save conflicts
- if (window.store){ _.conflict = window.store; }
- window.store = store;
- }
- })(this, this && this.define);
|