Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Maintenance release, v0.4.9

commit 53ed1eb73b84ea3d8c566b0c0263b8a80f01db6b 1 parent fb1db30
@andris9 authored
Showing with 292 additions and 266 deletions.
  1. +1 −1  component.json
  2. +276 −250 jstorage.js
  3. +15 −15 jstorage.min.js
View
2  component.json
@@ -1,6 +1,6 @@
{
"name": "jStorage",
- "version": "0.4.8",
+ "version": "0.4.9",
"main": "./jstorage.js",
"author": "Andris Reinman <andris.reinman@gmail.com>",
"dependencies": {}
View
526 jstorage.js
@@ -9,12 +9,12 @@
* Licensed under Unlicense:
*
* This is free and unencumbered software released into the public domain.
- *
+ *
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
- *
+ *
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
@@ -22,50 +22,58 @@
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
* For more information, please refer to <http://unlicense.org/>
*/
- (function(){
+(function() {
+ 'use strict';
+
var
- /* jStorage version */
- JSTORAGE_VERSION = "0.4.8",
+ /* jStorage version */
+ JSTORAGE_VERSION = '0.4.9',
/* detect a dollar object or create one if not found */
$ = window.jQuery || window.$ || (window.$ = {}),
/* check for a JSON handling support */
JSON = {
- parse:
- window.JSON && (window.JSON.parse || window.JSON.decode) ||
- String.prototype.evalJSON && function(str){return String(str).evalJSON();} ||
+ parse: window.JSON && (window.JSON.parse || window.JSON.decode) ||
+ String.prototype.evalJSON && function(str) {
+ return String(str).evalJSON();
+ } ||
$.parseJSON ||
$.evalJSON,
- stringify:
- Object.toJSON ||
+ stringify: Object.toJSON ||
window.JSON && (window.JSON.stringify || window.JSON.encode) ||
$.toJSON
};
// Break if no JSON support was found
- if(!("parse" in JSON) || !("stringify" in JSON)){
- throw new Error("No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page");
+ if (!('parse' in JSON) || !('stringify' in JSON)) {
+ throw new Error('No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page');
}
var
- /* This is the object, that holds the cached values */
- _storage = {__jstorage_meta:{CRC32:{}}},
+ /* This is the object, that holds the cached values */
+ _storage = {
+ __jstorage_meta: {
+ CRC32: {}
+ }
+ },
- /* Actual browser storage (localStorage or globalStorage["domain"]) */
- _storage_service = {jStorage:"{}"},
+ /* Actual browser storage (localStorage or globalStorage['domain']) */
+ _storage_service = {
+ jStorage: '{}'
+ },
/* DOM element for older IE versions, holds userData behavior */
_storage_elm = null,
@@ -99,8 +107,8 @@
* XML nodes are encoded and decoded if the node is the value to be saved
* but not if it's as a property of another object
* Eg. -
- * $.jStorage.set("key", xmlNode); // IS OK
- * $.jStorage.set("key", {xml: xmlNode}); // NOT OK
+ * $.jStorage.set('key', xmlNode); // IS OK
+ * $.jStorage.set('key', {xml: xmlNode}); // NOT OK
*/
_XMLService = {
@@ -108,9 +116,9 @@
* Validates a XML node to be XML
* based on jQuery.isXML function
*/
- isXML: function(elm){
+ isXML: function(elm) {
var documentElement = (elm ? elm.ownerDocument || elm : 0).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
+ return documentElement ? documentElement.nodeName !== 'HTML' : false;
},
/**
@@ -118,15 +126,15 @@
* based on http://www.mercurytide.co.uk/news/article/issues-when-working-ajax/
*/
encode: function(xmlNode) {
- if(!this.isXML(xmlNode)){
+ if (!this.isXML(xmlNode)) {
return false;
}
- try{ // Mozilla, Webkit, Opera
+ try { // Mozilla, Webkit, Opera
return new XMLSerializer().serializeToString(xmlNode);
- }catch(E1) {
- try { // IE
+ } catch (E1) {
+ try { // IE
return xmlNode.xml;
- }catch(E2){}
+ } catch (E2) {}
}
return false;
},
@@ -135,20 +143,20 @@
* Decodes a XML node from string
* loosely based on http://outwestmedia.com/jquery-plugins/xmldom/
*/
- decode: function(xmlString){
- var dom_parser = ("DOMParser" in window && (new DOMParser()).parseFromString) ||
- (window.ActiveXObject && function(_xmlString) {
- var xml_doc = new ActiveXObject("Microsoft.XMLDOM");
- xml_doc.async = "false";
- xml_doc.loadXML(_xmlString);
- return xml_doc;
- }),
- resultXML;
- if(!dom_parser){
+ decode: function(xmlString) {
+ var dom_parser = ('DOMParser' in window && (new DOMParser()).parseFromString) ||
+ (window.ActiveXObject && function(_xmlString) {
+ var xml_doc = new ActiveXObject('Microsoft.XMLDOM');
+ xml_doc.async = 'false';
+ xml_doc.loadXML(_xmlString);
+ return xml_doc;
+ }),
+ resultXML;
+ if (!dom_parser) {
return false;
}
- resultXML = dom_parser.call("DOMParser" in window && (new DOMParser()) || window, xmlString, "text/xml");
- return this.isXML(resultXML)?resultXML:false;
+ resultXML = dom_parser.call('DOMParser' in window && (new DOMParser()) || window, xmlString, 'text/xml');
+ return this.isXML(resultXML) ? resultXML : false;
}
};
@@ -159,76 +167,75 @@
* Initialization function. Detects if the browser supports DOM Storage
* or userData behavior and behaves accordingly.
*/
- function _init(){
+ function _init() {
/* Check if browser supports localStorage */
var localStorageReallyWorks = false;
- if("localStorage" in window){
+ if ('localStorage' in window) {
try {
- window.localStorage.setItem("_tmptest", "tmpval");
+ window.localStorage.setItem('_tmptest', 'tmpval');
localStorageReallyWorks = true;
- window.localStorage.removeItem("_tmptest");
- } catch(BogusQuotaExceededErrorOnIos5) {
+ window.localStorage.removeItem('_tmptest');
+ } catch (BogusQuotaExceededErrorOnIos5) {
// Thanks be to iOS5 Private Browsing mode which throws
// QUOTA_EXCEEDED_ERRROR DOM Exception 22.
}
}
- if(localStorageReallyWorks){
+ if (localStorageReallyWorks) {
try {
- if(window.localStorage) {
+ if (window.localStorage) {
_storage_service = window.localStorage;
- _backend = "localStorage";
+ _backend = 'localStorage';
_observer_update = _storage_service.jStorage_update;
}
- } catch(E3) {/* Firefox fails when touching localStorage and cookies are disabled */}
+ } catch (E3) { /* Firefox fails when touching localStorage and cookies are disabled */ }
}
/* Check if browser supports globalStorage */
- else if("globalStorage" in window){
+ else if ('globalStorage' in window) {
try {
- if(window.globalStorage) {
- if(window.location.hostname == "localhost"){
- _storage_service = window.globalStorage["localhost.localdomain"];
- }
- else{
+ if (window.globalStorage) {
+ if (window.location.hostname == 'localhost') {
+ _storage_service = window.globalStorage['localhost.localdomain'];
+ } else {
_storage_service = window.globalStorage[window.location.hostname];
}
- _backend = "globalStorage";
+ _backend = 'globalStorage';
_observer_update = _storage_service.jStorage_update;
}
- } catch(E4) {/* Firefox fails when touching localStorage and cookies are disabled */}
+ } catch (E4) { /* Firefox fails when touching localStorage and cookies are disabled */ }
}
/* Check if browser supports userData behavior */
else {
- _storage_elm = document.createElement("link");
- if(_storage_elm.addBehavior){
+ _storage_elm = document.createElement('link');
+ if (_storage_elm.addBehavior) {
/* Use a DOM element to act as userData storage */
- _storage_elm.style.behavior = "url(#default#userData)";
+ _storage_elm.style.behavior = 'url(#default#userData)';
/* userData element needs to be inserted into the DOM! */
- document.getElementsByTagName("head")[0].appendChild(_storage_elm);
+ document.getElementsByTagName('head')[0].appendChild(_storage_elm);
- try{
- _storage_elm.load("jStorage");
- }catch(E){
+ try {
+ _storage_elm.load('jStorage');
+ } catch (E) {
// try to reset cache
- _storage_elm.setAttribute("jStorage", "{}");
- _storage_elm.save("jStorage");
- _storage_elm.load("jStorage");
+ _storage_elm.setAttribute('jStorage', '{}');
+ _storage_elm.save('jStorage');
+ _storage_elm.load('jStorage');
}
- var data = "{}";
- try{
- data = _storage_elm.getAttribute("jStorage");
- }catch(E5){}
+ var data = '{}';
+ try {
+ data = _storage_elm.getAttribute('jStorage');
+ } catch (E5) {}
- try{
- _observer_update = _storage_elm.getAttribute("jStorage_update");
- }catch(E6){}
+ try {
+ _observer_update = _storage_elm.getAttribute('jStorage_update');
+ } catch (E6) {}
_storage_service.jStorage = data;
- _backend = "userDataBehavior";
- }else{
+ _backend = 'userDataBehavior';
+ } else {
_storage_elm = null;
return;
}
@@ -247,9 +254,9 @@
_handlePubSub();
// handle cached navigation
- if("addEventListener" in window){
- window.addEventListener("pageshow", function(event){
- if(event.persisted){
+ if ('addEventListener' in window) {
+ window.addEventListener('pageshow', function(event) {
+ if (event.persisted) {
_storageObserver();
}
}, false);
@@ -259,19 +266,19 @@
/**
* Reload data from storage when needed
*/
- function _reloadData(){
- var data = "{}";
+ function _reloadData() {
+ var data = '{}';
- if(_backend == "userDataBehavior"){
- _storage_elm.load("jStorage");
+ if (_backend == 'userDataBehavior') {
+ _storage_elm.load('jStorage');
- try{
- data = _storage_elm.getAttribute("jStorage");
- }catch(E5){}
+ try {
+ data = _storage_elm.getAttribute('jStorage');
+ } catch (E5) {}
- try{
- _observer_update = _storage_elm.getAttribute("jStorage_update");
- }catch(E6){}
+ try {
+ _observer_update = _storage_elm.getAttribute('jStorage_update');
+ } catch (E6) {}
_storage_service.jStorage = data;
}
@@ -287,14 +294,14 @@
/**
* Sets up a storage change observer
*/
- function _setupObserver(){
- if(_backend == "localStorage" || _backend == "globalStorage"){
- if("addEventListener" in window){
- window.addEventListener("storage", _storageObserver, false);
- }else{
- document.attachEvent("onstorage", _storageObserver);
- }
- }else if(_backend == "userDataBehavior"){
+ function _setupObserver() {
+ if (_backend == 'localStorage' || _backend == 'globalStorage') {
+ if ('addEventListener' in window) {
+ window.addEventListener('storage', _storageObserver, false);
+ } else {
+ document.attachEvent('onstorage', _storageObserver);
+ }
+ } else if (_backend == 'userDataBehavior') {
setInterval(_storageObserver, 1000);
}
}
@@ -303,22 +310,22 @@
* Fired on any kind of data change, needs to check if anything has
* really been changed
*/
- function _storageObserver(){
+ function _storageObserver() {
var updateTime;
// cumulate change notifications with timeout
clearTimeout(_observer_timeout);
- _observer_timeout = setTimeout(function(){
+ _observer_timeout = setTimeout(function() {
- if(_backend == "localStorage" || _backend == "globalStorage"){
+ if (_backend == 'localStorage' || _backend == 'globalStorage') {
updateTime = _storage_service.jStorage_update;
- }else if(_backend == "userDataBehavior"){
- _storage_elm.load("jStorage");
- try{
- updateTime = _storage_elm.getAttribute("jStorage_update");
- }catch(E5){}
+ } else if (_backend == 'userDataBehavior') {
+ _storage_elm.load('jStorage');
+ try {
+ updateTime = _storage_elm.getAttribute('jStorage_update');
+ } catch (E5) {}
}
- if(updateTime && updateTime != _observer_update){
+ if (updateTime && updateTime != _observer_update) {
_observer_update = updateTime;
_checkUpdatedKeys();
}
@@ -329,7 +336,7 @@
/**
* Reloads the data and checks if any keys are changed
*/
- function _checkUpdatedKeys(){
+ function _checkUpdatedKeys() {
var oldCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32)),
newCrc32List;
@@ -340,28 +347,28 @@
updated = [],
removed = [];
- for(key in oldCrc32List){
- if(oldCrc32List.hasOwnProperty(key)){
- if(!newCrc32List[key]){
+ for (key in oldCrc32List) {
+ if (oldCrc32List.hasOwnProperty(key)) {
+ if (!newCrc32List[key]) {
removed.push(key);
continue;
}
- if(oldCrc32List[key] != newCrc32List[key] && String(oldCrc32List[key]).substr(0,2) == "2."){
+ if (oldCrc32List[key] != newCrc32List[key] && String(oldCrc32List[key]).substr(0, 2) == '2.') {
updated.push(key);
}
}
}
- for(key in newCrc32List){
- if(newCrc32List.hasOwnProperty(key)){
- if(!oldCrc32List[key]){
+ for (key in newCrc32List) {
+ if (newCrc32List.hasOwnProperty(key)) {
+ if (!oldCrc32List[key]) {
updated.push(key);
}
}
}
- _fireObservers(updated, "updated");
- _fireObservers(removed, "deleted");
+ _fireObservers(updated, 'updated');
+ _fireObservers(removed, 'deleted');
}
/**
@@ -370,26 +377,29 @@
* @param {Array|String} keys Array of key names or a key
* @param {String} action What happened with the value (updated, deleted, flushed)
*/
- function _fireObservers(keys, action){
+ function _fireObservers(keys, action) {
keys = [].concat(keys || []);
- if(action == "flushed"){
+
+ var i, j, len, jlen;
+
+ if (action == 'flushed') {
keys = [];
- for(var key in _observers){
- if(_observers.hasOwnProperty(key)){
+ for (var key in _observers) {
+ if (_observers.hasOwnProperty(key)) {
keys.push(key);
}
}
- action = "deleted";
+ action = 'deleted';
}
- for(var i=0, len = keys.length; i<len; i++){
- if(_observers[keys[i]]){
- for(var j=0, jlen = _observers[keys[i]].length; j<jlen; j++){
+ for (i = 0, len = keys.length; i < len; i++) {
+ if (_observers[keys[i]]) {
+ for (j = 0, jlen = _observers[keys[i]].length; j < jlen; j++) {
_observers[keys[i]][j](keys[i], action);
}
}
- if(_observers["*"]){
- for(var j=0, jlen = _observers["*"].length; j<jlen; j++){
- _observers["*"][j](keys[i], action);
+ if (_observers['*']) {
+ for (j = 0, jlen = _observers['*'].length; j < jlen; j++) {
+ _observers['*'][j](keys[i], action);
}
}
}
@@ -398,19 +408,19 @@
/**
* Publishes key change to listeners
*/
- function _publishChange(){
+ function _publishChange() {
var updateTime = (+new Date()).toString();
- if(_backend == "localStorage" || _backend == "globalStorage"){
+ if (_backend == 'localStorage' || _backend == 'globalStorage') {
try {
_storage_service.jStorage_update = updateTime;
} catch (E8) {
// safari private mode has been enabled after the jStorage initialization
_backend = false;
}
- }else if(_backend == "userDataBehavior"){
- _storage_elm.setAttribute("jStorage_update", updateTime);
- _storage_elm.save("jStorage");
+ } else if (_backend == 'userDataBehavior') {
+ _storage_elm.setAttribute('jStorage_update', updateTime);
+ _storage_elm.save('jStorage');
}
_storageObserver();
@@ -419,39 +429,41 @@
/**
* Loads the data from the storage based on the supported mechanism
*/
- function _load_storage(){
+ function _load_storage() {
/* if jStorage string is retrieved, then decode it */
- if(_storage_service.jStorage){
- try{
+ if (_storage_service.jStorage) {
+ try {
_storage = JSON.parse(String(_storage_service.jStorage));
- }catch(E6){_storage_service.jStorage = "{}";}
- }else{
- _storage_service.jStorage = "{}";
+ } catch (E6) {
+ _storage_service.jStorage = '{}';
+ }
+ } else {
+ _storage_service.jStorage = '{}';
}
- _storage_size = _storage_service.jStorage?String(_storage_service.jStorage).length:0;
+ _storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;
- if(!_storage.__jstorage_meta){
+ if (!_storage.__jstorage_meta) {
_storage.__jstorage_meta = {};
}
- if(!_storage.__jstorage_meta.CRC32){
+ if (!_storage.__jstorage_meta.CRC32) {
_storage.__jstorage_meta.CRC32 = {};
}
}
/**
- * This functions provides the "save" mechanism to store the jStorage object
+ * This functions provides the 'save' mechanism to store the jStorage object
*/
- function _save(){
+ function _save() {
_dropOldEvents(); // remove expired events
- try{
+ try {
_storage_service.jStorage = JSON.stringify(_storage);
// If userData is used as the storage engine, additional
- if(_storage_elm) {
- _storage_elm.setAttribute("jStorage",_storage_service.jStorage);
- _storage_elm.save("jStorage");
+ if (_storage_elm) {
+ _storage_elm.setAttribute('jStorage', _storage_service.jStorage);
+ _storage_elm.save('jStorage');
}
- _storage_size = _storage_service.jStorage?String(_storage_service.jStorage).length:0;
- }catch(E7){/* probably cache is full, nothing is saved this way*/}
+ _storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;
+ } catch (E7) { /* probably cache is full, nothing is saved this way*/ }
}
/**
@@ -459,12 +471,12 @@
*
* @param {String} key Key name
*/
- function _checkKey(key){
- if(typeof key != "string" && typeof key != "number"){
- throw new TypeError("Key name must be string or numeric");
+ function _checkKey(key) {
+ if (typeof key != 'string' && typeof key != 'number') {
+ throw new TypeError('Key name must be string or numeric');
}
- if(key == "__jstorage_meta"){
- throw new TypeError("Reserved key name");
+ if (key == '__jstorage_meta') {
+ throw new TypeError('Reserved key name');
}
return true;
}
@@ -472,12 +484,14 @@
/**
* Removes expired keys
*/
- function _handleTTL(){
- var curtime, i, TTL, CRC32, nextExpire = Infinity, changed = false, deleted = [];
+ function _handleTTL() {
+ var curtime, i, TTL, CRC32, nextExpire = Infinity,
+ changed = false,
+ deleted = [];
clearTimeout(_ttl_timeout);
- if(!_storage.__jstorage_meta || typeof _storage.__jstorage_meta.TTL != "object"){
+ if (!_storage.__jstorage_meta || typeof _storage.__jstorage_meta.TTL != 'object') {
// nothing to do here
return;
}
@@ -486,47 +500,47 @@
TTL = _storage.__jstorage_meta.TTL;
CRC32 = _storage.__jstorage_meta.CRC32;
- for(i in TTL){
- if(TTL.hasOwnProperty(i)){
- if(TTL[i] <= curtime){
+ for (i in TTL) {
+ if (TTL.hasOwnProperty(i)) {
+ if (TTL[i] <= curtime) {
delete TTL[i];
delete CRC32[i];
delete _storage[i];
changed = true;
deleted.push(i);
- }else if(TTL[i] < nextExpire){
+ } else if (TTL[i] < nextExpire) {
nextExpire = TTL[i];
}
}
}
// set next check
- if(nextExpire != Infinity){
+ if (nextExpire != Infinity) {
_ttl_timeout = setTimeout(Math.min(_handleTTL, nextExpire - curtime, 0x7FFFFFFF));
}
// save changes
- if(changed){
+ if (changed) {
_save();
_publishChange();
- _fireObservers(deleted, "deleted");
+ _fireObservers(deleted, 'deleted');
}
}
/**
* Checks if there's any events on hold to be fired to listeners
*/
- function _handlePubSub(){
+ function _handlePubSub() {
var i, len;
- if(!_storage.__jstorage_meta.PubSub){
+ if (!_storage.__jstorage_meta.PubSub) {
return;
}
var pubelm,
_pubsubCurrent = _pubsub_last;
- for(i=len=_storage.__jstorage_meta.PubSub.length-1; i>=0; i--){
+ for (i = len = _storage.__jstorage_meta.PubSub.length - 1; i >= 0; i--) {
pubelm = _storage.__jstorage_meta.PubSub[i];
- if(pubelm[0] > _pubsub_last){
+ if (pubelm[0] > _pubsub_last) {
_pubsubCurrent = pubelm[0];
_fireSubscribers(pubelm[1], pubelm[2]);
}
@@ -541,13 +555,13 @@
* @param {String} channel Channel name
* @param {Mixed} payload Payload data to deliver
*/
- function _fireSubscribers(channel, payload){
- if(_pubsub_observers[channel]){
- for(var i=0, len = _pubsub_observers[channel].length; i<len; i++){
+ function _fireSubscribers(channel, payload) {
+ if (_pubsub_observers[channel]) {
+ for (var i = 0, len = _pubsub_observers[channel].length; i < len; i++) {
// send immutable data that can't be modified by listeners
- try{
+ try {
_pubsub_observers[channel][i](channel, JSON.parse(JSON.stringify(payload)));
- }catch(E){};
+ } catch (E) {}
}
}
}
@@ -555,22 +569,22 @@
/**
* Remove old events from the publish stream (at least 2sec old)
*/
- function _dropOldEvents(){
- if(!_storage.__jstorage_meta.PubSub){
+ function _dropOldEvents() {
+ if (!_storage.__jstorage_meta.PubSub) {
return;
}
var retire = +new Date() - 2000;
- for(var i=0, len = _storage.__jstorage_meta.PubSub.length; i<len; i++){
- if(_storage.__jstorage_meta.PubSub[i][0] <= retire){
+ for (var i = 0, len = _storage.__jstorage_meta.PubSub.length; i < len; i++) {
+ if (_storage.__jstorage_meta.PubSub[i][0] <= retire) {
// deleteCount is needed for IE6
_storage.__jstorage_meta.PubSub.splice(i, _storage.__jstorage_meta.PubSub.length - i);
break;
}
}
- if(!_storage.__jstorage_meta.PubSub.length){
+ if (!_storage.__jstorage_meta.PubSub.length) {
delete _storage.__jstorage_meta.PubSub;
}
@@ -582,15 +596,15 @@
* @param {String} channel Channel name
* @param {Mixed} payload Payload to send to the subscribers
*/
- function _publish(channel, payload){
- if(!_storage.__jstorage_meta){
+ function _publish(channel, payload) {
+ if (!_storage.__jstorage_meta) {
_storage.__jstorage_meta = {};
}
- if(!_storage.__jstorage_meta.PubSub){
+ if (!_storage.__jstorage_meta.PubSub) {
_storage.__jstorage_meta.PubSub = [];
}
- _storage.__jstorage_meta.PubSub.unshift([+new Date, channel, payload]);
+ _storage.__jstorage_meta.PubSub.unshift([+new Date(), channel, payload]);
_save();
_publishChange();
@@ -602,9 +616,9 @@
*
* SOURCE: https://github.com/garycourt/murmurhash-js (MIT licensed)
*
- * @author <a href="mailto:gary.court@gmail.com">Gary Court</a>
+ * @author <a href='mailto:gary.court@gmail.com'>Gary Court</a>
* @see http://github.com/garycourt/murmurhash-js
- * @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a>
+ * @author <a href='mailto:aappleby@gmail.com'>Austin Appleby</a>
* @see http://sites.google.com/site/murmurhash/
*
* @param {string} str ASCII only
@@ -637,9 +651,12 @@
}
switch (l) {
- case 3: h ^= (str.charCodeAt(i + 2) & 0xff) << 16;
- case 2: h ^= (str.charCodeAt(i + 1) & 0xff) << 8;
- case 1: h ^= (str.charCodeAt(i) & 0xff);
+ case 3:
+ h ^= (str.charCodeAt(i + 2) & 0xff) << 16;
+ case 2:
+ h ^= (str.charCodeAt(i + 1) & 0xff) << 8;
+ case 1:
+ h ^= (str.charCodeAt(i) & 0xff);
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
}
@@ -667,33 +684,36 @@
* @param {Number} [options.TTL] - optional TTL value, in milliseconds
* @return {Mixed} the used value
*/
- set: function(key, value, options){
+ set: function(key, value, options) {
_checkKey(key);
options = options || {};
// undefined values are deleted automatically
- if(typeof value == "undefined"){
+ if (typeof value == 'undefined') {
this.deleteKey(key);
return value;
}
- if(_XMLService.isXML(value)){
- value = {_is_xml:true,xml:_XMLService.encode(value)};
- }else if(typeof value == "function"){
+ if (_XMLService.isXML(value)) {
+ value = {
+ _is_xml: true,
+ xml: _XMLService.encode(value)
+ };
+ } else if (typeof value == 'function') {
return undefined; // functions can't be saved!
- }else if(value && typeof value == "object"){
+ } else if (value && typeof value == 'object') {
// clone the object before saving to _storage tree
value = JSON.parse(JSON.stringify(value));
}
_storage[key] = value;
- _storage.__jstorage_meta.CRC32[key] = "2." + murmurhash2_32_gc(JSON.stringify(value), 0x9747b28c);
+ _storage.__jstorage_meta.CRC32[key] = '2.' + murmurhash2_32_gc(JSON.stringify(value), 0x9747b28c);
this.setTTL(key, options.TTL || 0); // also handles saving and _publishChange
- _fireObservers(key, "updated");
+ _fireObservers(key, 'updated');
return value;
},
@@ -704,16 +724,16 @@
* @param {mixed} def - Default value to return, if key didn't exist.
* @return {Mixed} the key value, default value or null
*/
- get: function(key, def){
+ get: function(key, def) {
_checkKey(key);
- if(key in _storage){
- if(_storage[key] && typeof _storage[key] == "object" && _storage[key]._is_xml) {
+ if (key in _storage) {
+ if (_storage[key] && typeof _storage[key] == 'object' && _storage[key]._is_xml) {
return _XMLService.decode(_storage[key].xml);
- }else{
+ } else {
return _storage[key];
}
}
- return typeof(def) == "undefined" ? null : def;
+ return typeof(def) == 'undefined' ? null : def;
},
/**
@@ -722,13 +742,13 @@
* @param {String} key - Key to delete.
* @return {Boolean} true if key existed or false if it didn't
*/
- deleteKey: function(key){
+ deleteKey: function(key) {
_checkKey(key);
- if(key in _storage){
+ if (key in _storage) {
delete _storage[key];
// remove from TTL list
- if(typeof _storage.__jstorage_meta.TTL == "object" &&
- key in _storage.__jstorage_meta.TTL){
+ if (typeof _storage.__jstorage_meta.TTL == 'object' &&
+ key in _storage.__jstorage_meta.TTL) {
delete _storage.__jstorage_meta.TTL[key];
}
@@ -736,7 +756,7 @@
_save();
_publishChange();
- _fireObservers(key, "deleted");
+ _fireObservers(key, 'deleted');
return true;
}
return false;
@@ -749,20 +769,20 @@
* @param {Number} ttl - TTL timeout in milliseconds
* @return {Boolean} true if key existed or false if it didn't
*/
- setTTL: function(key, ttl){
+ setTTL: function(key, ttl) {
var curtime = +new Date();
_checkKey(key);
ttl = Number(ttl) || 0;
- if(key in _storage){
+ if (key in _storage) {
- if(!_storage.__jstorage_meta.TTL){
+ if (!_storage.__jstorage_meta.TTL) {
_storage.__jstorage_meta.TTL = {};
}
// Set TTL value for the key
- if(ttl>0){
+ if (ttl > 0) {
_storage.__jstorage_meta.TTL[key] = curtime + ttl;
- }else{
+ } else {
delete _storage.__jstorage_meta.TTL[key];
}
@@ -782,10 +802,11 @@
* @param {String} key Key to check
* @return {Number} Remaining TTL in milliseconds
*/
- getTTL: function(key){
- var curtime = +new Date(), ttl;
+ getTTL: function(key) {
+ var curtime = +new Date(),
+ ttl;
_checkKey(key);
- if(key in _storage && _storage.__jstorage_meta.TTL && _storage.__jstorage_meta.TTL[key]){
+ if (key in _storage && _storage.__jstorage_meta.TTL && _storage.__jstorage_meta.TTL[key]) {
ttl = _storage.__jstorage_meta.TTL[key] - curtime;
return ttl || 0;
}
@@ -797,11 +818,15 @@
*
* @return {Boolean} Always true
*/
- flush: function(){
- _storage = {__jstorage_meta:{CRC32:{}}};
+ flush: function() {
+ _storage = {
+ __jstorage_meta: {
+ CRC32: {}
+ }
+ };
_save();
_publishChange();
- _fireObservers(null, "flushed");
+ _fireObservers(null, 'flushed');
return true;
},
@@ -809,8 +834,8 @@
* Returns a read-only copy of _storage
*
* @return {Object} Read-only copy of _storage
- */
- storageObj: function(){
+ */
+ storageObj: function() {
function F() {}
F.prototype = _storage;
return new F();
@@ -818,14 +843,15 @@
/**
* Returns an index of all used keys as an array
- * ["key1", "key2",.."keyN"]
+ * ['key1', 'key2',..'keyN']
*
* @return {Array} Used keys
- */
- index: function(){
- var index = [], i;
- for(i in _storage){
- if(_storage.hasOwnProperty(i) && i != "__jstorage_meta"){
+ */
+ index: function() {
+ var index = [],
+ i;
+ for (i in _storage) {
+ if (_storage.hasOwnProperty(i) && i != '__jstorage_meta') {
index.push(i);
}
}
@@ -838,7 +864,7 @@
* @return {Number} Storage size in chars (not the same as in bytes,
* since some chars may take several bytes)
*/
- storageSize: function(){
+ storageSize: function() {
return _storage_size;
},
@@ -847,7 +873,7 @@
*
* @return {String} Backend name
*/
- currentBackend: function(){
+ currentBackend: function() {
return _backend;
},
@@ -856,7 +882,7 @@
*
* @return {Boolean} True if storage can be used
*/
- storageAvailable: function(){
+ storageAvailable: function() {
return !!_backend;
},
@@ -866,9 +892,9 @@
* @param {String} key Key name
* @param {Function} callback Function to run when the key changes
*/
- listenKeyChange: function(key, callback){
+ listenKeyChange: function(key, callback) {
_checkKey(key);
- if(!_observers[key]){
+ if (!_observers[key]) {
_observers[key] = [];
}
_observers[key].push(callback);
@@ -880,21 +906,21 @@
* @param {String} key Key name to unregister listeners against
* @param {Function} [callback] If set, unregister the callback, if not - unregister all
*/
- stopListening: function(key, callback){
+ stopListening: function(key, callback) {
_checkKey(key);
- if(!_observers[key]){
+ if (!_observers[key]) {
return;
}
- if(!callback){
+ if (!callback) {
delete _observers[key];
return;
}
- for(var i = _observers[key].length - 1; i>=0; i--){
- if(_observers[key][i] == callback){
- _observers[key].splice(i,1);
+ for (var i = _observers[key].length - 1; i >= 0; i--) {
+ if (_observers[key][i] == callback) {
+ _observers[key].splice(i, 1);
}
}
},
@@ -905,12 +931,12 @@
* @param {String} channel Channel name
* @param {Function} callback Function to run when the something is published to the channel
*/
- subscribe: function(channel, callback){
- channel = (channel || "").toString();
- if(!channel){
- throw new TypeError("Channel not defined");
+ subscribe: function(channel, callback) {
+ channel = (channel || '').toString();
+ if (!channel) {
+ throw new TypeError('Channel not defined');
}
- if(!_pubsub_observers[channel]){
+ if (!_pubsub_observers[channel]) {
_pubsub_observers[channel] = [];
}
_pubsub_observers[channel].push(callback);
@@ -922,10 +948,10 @@
* @param {String} channel Channel name
* @param {Mixed} payload Payload to deliver
*/
- publish: function(channel, payload){
- channel = (channel || "").toString();
- if(!channel){
- throw new TypeError("Channel not defined");
+ publish: function(channel, payload) {
+ channel = (channel || '').toString();
+ if (!channel) {
+ throw new TypeError('Channel not defined');
}
_publish(channel, payload);
@@ -934,27 +960,27 @@
/**
* Reloads the data from browser storage
*/
- reInit: function(){
+ reInit: function() {
_reloadData();
},
/**
* Removes reference from global objects and saves it as jStorage
*
- * @param {Boolean} option if needed to save object as simple "jStorage" in windows context
+ * @param {Boolean} option if needed to save object as simple 'jStorage' in windows context
*/
- noConflict: function( saveInGlobal ) {
+ noConflict: function(saveInGlobal) {
delete window.$.jStorage;
- if ( saveInGlobal ) {
+ if (saveInGlobal) {
window.jStorage = this;
}
return this;
- }
+ }
};
// Initialize jStorage
_init();
-})();
+})();
View
30 jstorage.min.js
@@ -1,15 +1,15 @@
-(function(){function D(){var a="{}";if("userDataBehavior"==k){d.load("jStorage");try{a=d.getAttribute("jStorage")}catch(b){}try{r=d.getAttribute("jStorage_update")}catch(c){}h.jStorage=a}E();x();F()}function u(){var a;clearTimeout(G);G=setTimeout(function(){if("localStorage"==k||"globalStorage"==k)a=h.jStorage_update;else if("userDataBehavior"==k){d.load("jStorage");try{a=d.getAttribute("jStorage_update")}catch(b){}}if(a&&a!=r){r=a;var l=m.parse(m.stringify(c.__jstorage_meta.CRC32)),p;D();p=m.parse(m.stringify(c.__jstorage_meta.CRC32));
-var e,z=[],f=[];for(e in l)l.hasOwnProperty(e)&&(p[e]?l[e]!=p[e]&&"2."==String(l[e]).substr(0,2)&&z.push(e):f.push(e));for(e in p)p.hasOwnProperty(e)&&(l[e]||z.push(e));s(z,"updated");s(f,"deleted")}},25)}function s(a,b){a=[].concat(a||[]);if("flushed"==b){a=[];for(var c in g)g.hasOwnProperty(c)&&a.push(c);b="deleted"}c=0;for(var p=a.length;c<p;c++){if(g[a[c]])for(var e=0,d=g[a[c]].length;e<d;e++)g[a[c]][e](a[c],b);if(g["*"])for(e=0,d=g["*"].length;e<d;e++)g["*"][e](a[c],b)}}function v(){var a=(+new Date).toString();
-if("localStorage"==k||"globalStorage"==k)try{h.jStorage_update=a}catch(b){k=!1}else"userDataBehavior"==k&&(d.setAttribute("jStorage_update",a),d.save("jStorage"));u()}function E(){if(h.jStorage)try{c=m.parse(String(h.jStorage))}catch(a){h.jStorage="{}"}else h.jStorage="{}";A=h.jStorage?String(h.jStorage).length:0;c.__jstorage_meta||(c.__jstorage_meta={});c.__jstorage_meta.CRC32||(c.__jstorage_meta.CRC32={})}function w(){if(c.__jstorage_meta.PubSub){for(var a=+new Date-2E3,b=0,l=c.__jstorage_meta.PubSub.length;b<
-l;b++)if(c.__jstorage_meta.PubSub[b][0]<=a){c.__jstorage_meta.PubSub.splice(b,c.__jstorage_meta.PubSub.length-b);break}c.__jstorage_meta.PubSub.length||delete c.__jstorage_meta.PubSub}try{h.jStorage=m.stringify(c),d&&(d.setAttribute("jStorage",h.jStorage),d.save("jStorage")),A=h.jStorage?String(h.jStorage).length:0}catch(p){}}function q(a){if("string"!=typeof a&&"number"!=typeof a)throw new TypeError("Key name must be string or numeric");if("__jstorage_meta"==a)throw new TypeError("Reserved key name");
-return!0}function x(){var a,b,l,d,e=Infinity,h=!1,f=[];clearTimeout(H);if(c.__jstorage_meta&&"object"==typeof c.__jstorage_meta.TTL){a=+new Date;l=c.__jstorage_meta.TTL;d=c.__jstorage_meta.CRC32;for(b in l)l.hasOwnProperty(b)&&(l[b]<=a?(delete l[b],delete d[b],delete c[b],h=!0,f.push(b)):l[b]<e&&(e=l[b]));Infinity!=e&&(H=setTimeout(x,e-a));h&&(w(),v(),s(f,"deleted"))}}function F(){var a;if(c.__jstorage_meta.PubSub){var b,l=B;for(a=c.__jstorage_meta.PubSub.length-1;0<=a;a--)if(b=c.__jstorage_meta.PubSub[a],
-b[0]>B){var l=b[0],d=b[1];b=b[2];if(t[d])for(var e=0,h=t[d].length;e<h;e++)try{t[d][e](d,m.parse(m.stringify(b)))}catch(f){}}B=l}}var y=window.jQuery||window.$||(window.$={}),m={parse:window.JSON&&(window.JSON.parse||window.JSON.decode)||String.prototype.evalJSON&&function(a){return String(a).evalJSON()}||y.parseJSON||y.evalJSON,stringify:Object.toJSON||window.JSON&&(window.JSON.stringify||window.JSON.encode)||y.toJSON};if(!("parse"in m&&"stringify"in m))throw Error("No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page");
-var c={__jstorage_meta:{CRC32:{}}},h={jStorage:"{}"},d=null,A=0,k=!1,g={},G=!1,r=0,t={},B=+new Date,H,C={isXML:function(a){return(a=(a?a.ownerDocument||a:0).documentElement)?"HTML"!==a.nodeName:!1},encode:function(a){if(!this.isXML(a))return!1;try{return(new XMLSerializer).serializeToString(a)}catch(b){try{return a.xml}catch(c){}}return!1},decode:function(a){var b="DOMParser"in window&&(new DOMParser).parseFromString||window.ActiveXObject&&function(a){var b=new ActiveXObject("Microsoft.XMLDOM");b.async=
-"false";b.loadXML(a);return b};if(!b)return!1;a=b.call("DOMParser"in window&&new DOMParser||window,a,"text/xml");return this.isXML(a)?a:!1}};y.jStorage={version:"0.4.8",set:function(a,b,d){q(a);d=d||{};if("undefined"==typeof b)return this.deleteKey(a),b;if(C.isXML(b))b={_is_xml:!0,xml:C.encode(b)};else{if("function"==typeof b)return;b&&"object"==typeof b&&(b=m.parse(m.stringify(b)))}c[a]=b;for(var h=c.__jstorage_meta.CRC32,e=m.stringify(b),k=e.length,f=2538058380^k,g=0,n;4<=k;)n=e.charCodeAt(g)&255|
-(e.charCodeAt(++g)&255)<<8|(e.charCodeAt(++g)&255)<<16|(e.charCodeAt(++g)&255)<<24,n=1540483477*(n&65535)+((1540483477*(n>>>16)&65535)<<16),n^=n>>>24,n=1540483477*(n&65535)+((1540483477*(n>>>16)&65535)<<16),f=1540483477*(f&65535)+((1540483477*(f>>>16)&65535)<<16)^n,k-=4,++g;switch(k){case 3:f^=(e.charCodeAt(g+2)&255)<<16;case 2:f^=(e.charCodeAt(g+1)&255)<<8;case 1:f^=e.charCodeAt(g)&255,f=1540483477*(f&65535)+((1540483477*(f>>>16)&65535)<<16)}f^=f>>>13;f=1540483477*(f&65535)+((1540483477*(f>>>16)&
-65535)<<16);h[a]="2."+((f^f>>>15)>>>0);this.setTTL(a,d.TTL||0);s(a,"updated");return b},get:function(a,b){q(a);return a in c?c[a]&&"object"==typeof c[a]&&c[a]._is_xml?C.decode(c[a].xml):c[a]:"undefined"==typeof b?null:b},deleteKey:function(a){q(a);return a in c?(delete c[a],"object"==typeof c.__jstorage_meta.TTL&&a in c.__jstorage_meta.TTL&&delete c.__jstorage_meta.TTL[a],delete c.__jstorage_meta.CRC32[a],w(),v(),s(a,"deleted"),!0):!1},setTTL:function(a,b){var d=+new Date;q(a);b=Number(b)||0;return a in
-c?(c.__jstorage_meta.TTL||(c.__jstorage_meta.TTL={}),0<b?c.__jstorage_meta.TTL[a]=d+b:delete c.__jstorage_meta.TTL[a],w(),x(),v(),!0):!1},getTTL:function(a){var b=+new Date;q(a);return a in c&&c.__jstorage_meta.TTL&&c.__jstorage_meta.TTL[a]?(a=c.__jstorage_meta.TTL[a]-b)||0:0},flush:function(){c={__jstorage_meta:{CRC32:{}}};w();v();s(null,"flushed");return!0},storageObj:function(){function a(){}a.prototype=c;return new a},index:function(){var a=[],b;for(b in c)c.hasOwnProperty(b)&&"__jstorage_meta"!=
-b&&a.push(b);return a},storageSize:function(){return A},currentBackend:function(){return k},storageAvailable:function(){return!!k},listenKeyChange:function(a,b){q(a);g[a]||(g[a]=[]);g[a].push(b)},stopListening:function(a,b){q(a);if(g[a])if(b)for(var c=g[a].length-1;0<=c;c--)g[a][c]==b&&g[a].splice(c,1);else delete g[a]},subscribe:function(a,b){a=(a||"").toString();if(!a)throw new TypeError("Channel not defined");t[a]||(t[a]=[]);t[a].push(b)},publish:function(a,b){a=(a||"").toString();if(!a)throw new TypeError("Channel not defined");
-c.__jstorage_meta||(c.__jstorage_meta={});c.__jstorage_meta.PubSub||(c.__jstorage_meta.PubSub=[]);c.__jstorage_meta.PubSub.unshift([+new Date,a,b]);w();v()},reInit:function(){D()},noConflict:function(a){delete window.$.jStorage;a&&(window.jStorage=this);return this}};(function(){var a=!1;if("localStorage"in window)try{window.localStorage.setItem("_tmptest","tmpval"),a=!0,window.localStorage.removeItem("_tmptest")}catch(b){}if(a)try{window.localStorage&&(h=window.localStorage,k="localStorage",r=h.jStorage_update)}catch(c){}else if("globalStorage"in
-window)try{window.globalStorage&&(h="localhost"==window.location.hostname?window.globalStorage["localhost.localdomain"]:window.globalStorage[window.location.hostname],k="globalStorage",r=h.jStorage_update)}catch(g){}else if(d=document.createElement("link"),d.addBehavior){d.style.behavior="url(#default#userData)";document.getElementsByTagName("head")[0].appendChild(d);try{d.load("jStorage")}catch(e){d.setAttribute("jStorage","{}"),d.save("jStorage"),d.load("jStorage")}a="{}";try{a=d.getAttribute("jStorage")}catch(m){}try{r=
-d.getAttribute("jStorage_update")}catch(f){}h.jStorage=a;k="userDataBehavior"}else{d=null;return}E();x();"localStorage"==k||"globalStorage"==k?"addEventListener"in window?window.addEventListener("storage",u,!1):document.attachEvent("onstorage",u):"userDataBehavior"==k&&setInterval(u,1E3);F();"addEventListener"in window&&window.addEventListener("pageshow",function(a){a.persisted&&u()},!1)})()})();
+(function(){function C(){var a="{}";if("userDataBehavior"==h){d.load("jStorage");try{a=d.getAttribute("jStorage")}catch(b){}try{q=d.getAttribute("jStorage_update")}catch(c){}l.jStorage=a}D();w();E()}function t(){var a;clearTimeout(F);F=setTimeout(function(){if("localStorage"==h||"globalStorage"==h)a=l.jStorage_update;else if("userDataBehavior"==h){d.load("jStorage");try{a=d.getAttribute("jStorage_update")}catch(b){}}if(a&&a!=q){q=a;var m=n.parse(n.stringify(c.__jstorage_meta.CRC32)),k;C();k=n.parse(n.stringify(c.__jstorage_meta.CRC32));
+var e,y=[],g=[];for(e in m)m.hasOwnProperty(e)&&(k[e]?m[e]!=k[e]&&"2."==String(m[e]).substr(0,2)&&y.push(e):g.push(e));for(e in k)k.hasOwnProperty(e)&&(m[e]||y.push(e));r(y,"updated");r(g,"deleted")}},25)}function r(a,b){a=[].concat(a||[]);var c,k,e,d;if("flushed"==b){a=[];for(c in f)f.hasOwnProperty(c)&&a.push(c);b="deleted"}c=0;for(e=a.length;c<e;c++){if(f[a[c]])for(k=0,d=f[a[c]].length;k<d;k++)f[a[c]][k](a[c],b);if(f["*"])for(k=0,d=f["*"].length;k<d;k++)f["*"][k](a[c],b)}}function u(){var a=(+new Date).toString();
+if("localStorage"==h||"globalStorage"==h)try{l.jStorage_update=a}catch(b){h=!1}else"userDataBehavior"==h&&(d.setAttribute("jStorage_update",a),d.save("jStorage"));t()}function D(){if(l.jStorage)try{c=n.parse(String(l.jStorage))}catch(a){l.jStorage="{}"}else l.jStorage="{}";z=l.jStorage?String(l.jStorage).length:0;c.__jstorage_meta||(c.__jstorage_meta={});c.__jstorage_meta.CRC32||(c.__jstorage_meta.CRC32={})}function v(){if(c.__jstorage_meta.PubSub){for(var a=+new Date-2E3,b=0,m=c.__jstorage_meta.PubSub.length;b<
+m;b++)if(c.__jstorage_meta.PubSub[b][0]<=a){c.__jstorage_meta.PubSub.splice(b,c.__jstorage_meta.PubSub.length-b);break}c.__jstorage_meta.PubSub.length||delete c.__jstorage_meta.PubSub}try{l.jStorage=n.stringify(c),d&&(d.setAttribute("jStorage",l.jStorage),d.save("jStorage")),z=l.jStorage?String(l.jStorage).length:0}catch(k){}}function p(a){if("string"!=typeof a&&"number"!=typeof a)throw new TypeError("Key name must be string or numeric");if("__jstorage_meta"==a)throw new TypeError("Reserved key name");
+return!0}function w(){var a,b,m,k,e=Infinity,d=!1,g=[];clearTimeout(G);if(c.__jstorage_meta&&"object"==typeof c.__jstorage_meta.TTL){a=+new Date;m=c.__jstorage_meta.TTL;k=c.__jstorage_meta.CRC32;for(b in m)m.hasOwnProperty(b)&&(m[b]<=a?(delete m[b],delete k[b],delete c[b],d=!0,g.push(b)):m[b]<e&&(e=m[b]));Infinity!=e&&(G=setTimeout(Math.min(w,e-a,2147483647)));d&&(v(),u(),r(g,"deleted"))}}function E(){var a;if(c.__jstorage_meta.PubSub){var b,m=A;for(a=c.__jstorage_meta.PubSub.length-1;0<=a;a--)if(b=
+c.__jstorage_meta.PubSub[a],b[0]>A){var m=b[0],k=b[1];b=b[2];if(s[k])for(var e=0,d=s[k].length;e<d;e++)try{s[k][e](k,n.parse(n.stringify(b)))}catch(g){}}A=m}}var x=window.jQuery||window.$||(window.$={}),n={parse:window.JSON&&(window.JSON.parse||window.JSON.decode)||String.prototype.evalJSON&&function(a){return String(a).evalJSON()}||x.parseJSON||x.evalJSON,stringify:Object.toJSON||window.JSON&&(window.JSON.stringify||window.JSON.encode)||x.toJSON};if(!("parse"in n&&"stringify"in n))throw Error("No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page");
+var c={__jstorage_meta:{CRC32:{}}},l={jStorage:"{}"},d=null,z=0,h=!1,f={},F=!1,q=0,s={},A=+new Date,G,B={isXML:function(a){return(a=(a?a.ownerDocument||a:0).documentElement)?"HTML"!==a.nodeName:!1},encode:function(a){if(!this.isXML(a))return!1;try{return(new XMLSerializer).serializeToString(a)}catch(b){try{return a.xml}catch(c){}}return!1},decode:function(a){var b="DOMParser"in window&&(new DOMParser).parseFromString||window.ActiveXObject&&function(a){var b=new ActiveXObject("Microsoft.XMLDOM");b.async=
+"false";b.loadXML(a);return b};if(!b)return!1;a=b.call("DOMParser"in window&&new DOMParser||window,a,"text/xml");return this.isXML(a)?a:!1}};x.jStorage={version:"0.4.9",set:function(a,b,d){p(a);d=d||{};if("undefined"==typeof b)return this.deleteKey(a),b;if(B.isXML(b))b={_is_xml:!0,xml:B.encode(b)};else{if("function"==typeof b)return;b&&"object"==typeof b&&(b=n.parse(n.stringify(b)))}c[a]=b;for(var k=c.__jstorage_meta.CRC32,e=n.stringify(b),l=e.length,g=2538058380^l,h=0,f;4<=l;)f=e.charCodeAt(h)&255|
+(e.charCodeAt(++h)&255)<<8|(e.charCodeAt(++h)&255)<<16|(e.charCodeAt(++h)&255)<<24,f=1540483477*(f&65535)+((1540483477*(f>>>16)&65535)<<16),f^=f>>>24,f=1540483477*(f&65535)+((1540483477*(f>>>16)&65535)<<16),g=1540483477*(g&65535)+((1540483477*(g>>>16)&65535)<<16)^f,l-=4,++h;switch(l){case 3:g^=(e.charCodeAt(h+2)&255)<<16;case 2:g^=(e.charCodeAt(h+1)&255)<<8;case 1:g^=e.charCodeAt(h)&255,g=1540483477*(g&65535)+((1540483477*(g>>>16)&65535)<<16)}g^=g>>>13;g=1540483477*(g&65535)+((1540483477*(g>>>16)&
+65535)<<16);k[a]="2."+((g^g>>>15)>>>0);this.setTTL(a,d.TTL||0);r(a,"updated");return b},get:function(a,b){p(a);return a in c?c[a]&&"object"==typeof c[a]&&c[a]._is_xml?B.decode(c[a].xml):c[a]:"undefined"==typeof b?null:b},deleteKey:function(a){p(a);return a in c?(delete c[a],"object"==typeof c.__jstorage_meta.TTL&&a in c.__jstorage_meta.TTL&&delete c.__jstorage_meta.TTL[a],delete c.__jstorage_meta.CRC32[a],v(),u(),r(a,"deleted"),!0):!1},setTTL:function(a,b){var d=+new Date;p(a);b=Number(b)||0;return a in
+c?(c.__jstorage_meta.TTL||(c.__jstorage_meta.TTL={}),0<b?c.__jstorage_meta.TTL[a]=d+b:delete c.__jstorage_meta.TTL[a],v(),w(),u(),!0):!1},getTTL:function(a){var b=+new Date;p(a);return a in c&&c.__jstorage_meta.TTL&&c.__jstorage_meta.TTL[a]?(a=c.__jstorage_meta.TTL[a]-b)||0:0},flush:function(){c={__jstorage_meta:{CRC32:{}}};v();u();r(null,"flushed");return!0},storageObj:function(){function a(){}a.prototype=c;return new a},index:function(){var a=[],b;for(b in c)c.hasOwnProperty(b)&&"__jstorage_meta"!=
+b&&a.push(b);return a},storageSize:function(){return z},currentBackend:function(){return h},storageAvailable:function(){return!!h},listenKeyChange:function(a,b){p(a);f[a]||(f[a]=[]);f[a].push(b)},stopListening:function(a,b){p(a);if(f[a])if(b)for(var c=f[a].length-1;0<=c;c--)f[a][c]==b&&f[a].splice(c,1);else delete f[a]},subscribe:function(a,b){a=(a||"").toString();if(!a)throw new TypeError("Channel not defined");s[a]||(s[a]=[]);s[a].push(b)},publish:function(a,b){a=(a||"").toString();if(!a)throw new TypeError("Channel not defined");
+c.__jstorage_meta||(c.__jstorage_meta={});c.__jstorage_meta.PubSub||(c.__jstorage_meta.PubSub=[]);c.__jstorage_meta.PubSub.unshift([+new Date,a,b]);v();u()},reInit:function(){C()},noConflict:function(a){delete window.$.jStorage;a&&(window.jStorage=this);return this}};(function(){var a=!1;if("localStorage"in window)try{window.localStorage.setItem("_tmptest","tmpval"),a=!0,window.localStorage.removeItem("_tmptest")}catch(b){}if(a)try{window.localStorage&&(l=window.localStorage,h="localStorage",q=l.jStorage_update)}catch(c){}else if("globalStorage"in
+window)try{window.globalStorage&&(l="localhost"==window.location.hostname?window.globalStorage["localhost.localdomain"]:window.globalStorage[window.location.hostname],h="globalStorage",q=l.jStorage_update)}catch(f){}else if(d=document.createElement("link"),d.addBehavior){d.style.behavior="url(#default#userData)";document.getElementsByTagName("head")[0].appendChild(d);try{d.load("jStorage")}catch(e){d.setAttribute("jStorage","{}"),d.save("jStorage"),d.load("jStorage")}a="{}";try{a=d.getAttribute("jStorage")}catch(n){}try{q=
+d.getAttribute("jStorage_update")}catch(g){}l.jStorage=a;h="userDataBehavior"}else{d=null;return}D();w();"localStorage"==h||"globalStorage"==h?"addEventListener"in window?window.addEventListener("storage",t,!1):document.attachEvent("onstorage",t):"userDataBehavior"==h&&setInterval(t,1E3);E();"addEventListener"in window&&window.addEventListener("pageshow",function(a){a.persisted&&t()},!1)})()})();
Please sign in to comment.
Something went wrong with that request. Please try again.