;(function(window){ if (window.BX.localStorage) return; var BX = window.BX, localStorageInstance = null, _prefix = null, _key = '_bxCurrentKey', _support = false; BX.localStorage = function() { this.keyChanges = {}; // flag to skip self changes in IE BX.bind( (BX.browser.IsIE() && !BX.browser.IsIE9()) ? document : window, // HATE! 'storage', BX.proxy(this._onchange, this) ); setInterval(BX.delegate(this._clear, this), 5000); }; /* localStorage public interface */ BX.localStorage.checkBrowser = function() { return _support; }; BX.localStorage.set = function(key, value, ttl) { return BX.localStorage.instance().set(key, value, ttl); }; BX.localStorage.get = function(key) { return BX.localStorage.instance().get(key); }; BX.localStorage.remove = function(key) { return BX.localStorage.instance().remove(key); }; BX.localStorage.instance = function() { if (!localStorageInstance) { var support = BX.localStorage.checkBrowser(); if (support == 'native') localStorageInstance = new BX.localStorage(); else if (support == 'ie8') localStorageInstance = new BX.localStorageIE8(); else if (support == 'ie7') localStorageInstance = new BX.localStorageIE7(); else { localStorageInstance = { 'set' : BX.DoNothing, 'get' : function(){return null}, 'remove' : BX.DoNothing }; } } return localStorageInstance; }; /* localStorage prototype */ BX.localStorage.prototype.prefix = function() { if (!_prefix) { _prefix = 'bx' + BX.message('USER_ID') + '-' + (BX.message.SITE_ID? BX.message('SITE_ID'): 'admin') + '-'; } return _prefix; }; BX.localStorage.prototype._onchange = function(e) { e = e || window.event; if (!e.key) return; if (BX.browser.DetectIeVersion() > 0 && this.keyChanges[e.key]) { this.keyChanges[e.key] = false; return; } if (!!e.key && e.key.substring(0,this.prefix().length) == this.prefix()) { var d = { key: e.key.substring(this.prefix().length, e.key.length), value: !!e.newValue? this._decode(e.newValue.substring(11, e.newValue.length)): null, oldValue: !!e.oldValue? this._decode(e.oldValue.substring(11, e.oldValue.length)): null }; switch(d.key) { case 'BXGCE': // BX Global Custom Event if (d.value) { BX.onCustomEvent(d.value.e, d.value.p); } break; default: // normal event handlers if (e.newValue) BX.onCustomEvent(window, 'onLocalStorageSet', [d]); if (e.oldValue && !e.newValue) BX.onCustomEvent(window, 'onLocalStorageRemove', [d]); BX.onCustomEvent(window, 'onLocalStorageChange', [d]); break; } } }; BX.localStorage.prototype._clear = function() { var curDate = +new Date(), key, i; for (i=0; i= ttl) localStorage.removeItem(key); } } }; BX.localStorage.prototype._encode = function(value) { if (typeof(value) == 'object') value = JSON.stringify(value); else value = value.toString(); return value; }; BX.localStorage.prototype._decode = function(value) { var answer = null; if (!!value) { try {answer = JSON.parse(value);} catch(e) { answer = value; } } return answer; }; BX.localStorage.prototype._trigger_error = function(e, key, value, ttl) { BX.onCustomEvent(this, 'onLocalStorageError', [e, {key: key, value: value, ttl: ttl}]); }; BX.localStorage.prototype.set = function(key, value, ttl) { if (!ttl || ttl <= 0) ttl = 60; if (key == undefined || key == null || value == undefined) return false; this.keyChanges[this.prefix()+key] = true; try { localStorage.setItem( this.prefix()+key, (Math.round((+new Date())/1000)+ttl)+':'+this._encode(value) ); } catch (e) { this._trigger_error(e, key, value, ttl); } }; BX.localStorage.prototype.get = function(key) { var storageAnswer = localStorage.getItem(this.prefix()+key); if (storageAnswer) { var ttl = storageAnswer.split(':', 1)*1000; if ((+new Date()) <= ttl) { storageAnswer = storageAnswer.substring(11, storageAnswer.length); return this._decode(storageAnswer); } } return null; }; BX.localStorage.prototype.remove = function(key) { this.keyChanges[this.prefix()+key] = true; localStorage.removeItem(this.prefix()+key); }; /************** IE 7 ******************/ BX.localStorageIE7 = function() { this.NS = 'BXLocalStorage'; this.__current_state = {}; this.keyChanges = {}; BX.ready(BX.delegate(this._Init, this)); }; BX.extend(BX.localStorageIE7, BX.localStorage); BX.localStorageIE7.prototype._Init = function() { this.storage_element = document.body.appendChild(BX.create('DIV')); this.storage_element.addBehavior('#default#userData'); this.storage_element.load(this.NS); var doc = this.storage_element.xmlDocument, len = doc.firstChild.attributes.length; for (var i = 0; i= ttl) { doc.firstChild.removeAttribute(k) } } } } this.storage_element.save(this.NS); }; BX.localStorageIE7.prototype.set = function(key, value, ttl) { if (!ttl || ttl <= 0) ttl = 60; try { this.storage_element.load(this.NS); var doc = this.storage_element.xmlDocument; this.keyChanges[this.prefix()+key] = true; doc.firstChild.setAttribute( this.prefix()+key, (Math.round((+new Date())/1000)+ttl)+':'+this._encode(value) ); this.storage_element.save(this.NS); } catch(e) { this._trigger_error(e, key, value, ttl); } }; BX.localStorageIE7.prototype.get = function(key) { this.storage_element.load(this.NS); var doc = this.storage_element.xmlDocument; var storageAnswer = doc.firstChild.getAttribute(this.prefix()+key); if (storageAnswer) { var ttl = storageAnswer.split(':', 1)*1000; if ((+new Date()) <= ttl) { storageAnswer = storageAnswer.substring(11, storageAnswer.length); return this._decode(storageAnswer); } } return null; }; BX.localStorageIE7.prototype.remove = function(key) { this.storage_element.load(this.NS); var doc = this.storage_element.xmlDocument; doc.firstChild.removeAttribute(this.prefix()+key); this.keyChanges[this.prefix()+key] = true; this.storage_element.save(this.NS); }; /************** IE 8 & FF 3.6 ***************/ BX.localStorageIE8 = function() { this.key = _key; this.currentKey = null; this.currentValue = null; BX.localStorageIE8.superclass.constructor.apply(this); }; BX.extend(BX.localStorageIE8, BX.localStorage); BX.localStorageIE8.prototype._onchange = function(e) { if (null == this.currentKey) { this.currentKey = localStorage.getItem(this.key); if (this.currentKey) { this.currentValue = localStorage.getItem(this.prefix() + this.currentKey); } } else { e = { key: this.prefix() + this.currentKey, newValue: localStorage.getItem(this.prefix() + this.currentKey), oldValue: this.currentValue }; this.currentKey = null; this.currentValue = null; // especially for FF3.6 if (this.keyChanges[e.key]) { this.keyChanges[e.key] = false; return; } BX.localStorageIE8.superclass._onchange.apply(this, [e]); } }; BX.localStorageIE8.prototype.set = function(key, value, ttl) { this.currentKey = null; this.keyChanges[this.prefix()+key] = true; try { localStorage.setItem(this.key, key); BX.localStorageIE8.superclass.set.apply(this, arguments); } catch(e) { this._trigger_error(e, key, value, ttl); } }; BX.localStorageIE8.prototype.remove = function(key) { this.currentKey = null; this.keyChanges[this.prefix()+key] = true; localStorage.setItem(this.key, key); BX.localStorageIE8.superclass.remove.apply(this, arguments); }; /* additional functions */ BX.onGlobalCustomEvent = function(eventName, arEventParams, bSkipSelf) { if (!!BX.localStorage.checkBrowser()) BX.localStorage.set('BXGCE', {e:eventName,p:arEventParams}, 1); if (!bSkipSelf) BX.onCustomEvent(eventName, arEventParams); }; /***************** initialize *********************/ try { _support = !!localStorage.setItem; } catch(e) {} if (_support) { _support = 'native'; // hack to check FF3.6 && IE8 var _target = (BX.browser.IsIE() && !BX.browser.IsIE9()) ? document : window, _checkFFnIE8 = function(e) { if (typeof(e||window.event).key == 'undefined') _support = 'ie8'; BX.unbind(_target, 'storage', _checkFFnIE8); BX.localStorage.instance(); }; BX.bind(_target, 'storage', _checkFFnIE8); try { localStorage.setItem(_key, null); } catch(e) { _support = false; BX.localStorage.instance(); } } else if (BX.browser.IsIE7()) { _support = 'ie7'; BX.localStorage.instance(); } })(window);