core/skin/m2.yurecnt.ru/js/core_ls.js

500 lines
10 KiB
JavaScript

;(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<localStorage.length; i++)
{
key = localStorage.key(i);
if (key.substring(0,2) == 'bx')
{
var ttl = localStorage.getItem(key).split(':', 1)*1000;
if (curDate >= 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<len; i++)
{
if (!!doc.firstChild.attributes[i])
{
var k = doc.firstChild.attributes[i].nodeName;
if (k.substring(0,this.prefix().length) == this.prefix())
{
this.__current_state[k] = doc.firstChild.attributes[i].nodeValue;
}
}
}
setInterval(BX.delegate(this._Listener, this), 500);
setInterval(BX.delegate(this._clear, this), 5000);
};
BX.localStorageIE7.prototype._Listener = function(bInit)
{
this.storage_element.load(this.NS);
var doc = this.storage_element.xmlDocument,
len = doc.firstChild.attributes.length,
i,k,v;
var new_state = {}, arChanges = [];
for (i = 0; i<len; i++)
{
if (!!doc.firstChild.attributes[i])
{
k = doc.firstChild.attributes[i].nodeName;
if (k.substring(0,this.prefix().length) == this.prefix())
{
v = doc.firstChild.attributes[i].nodeValue;
if (this.__current_state[k] != v)
{
arChanges.push({
key: k, newValue: v, oldValue: this.__current_state[k]
});
}
new_state[k] = v;
delete this.__current_state[k];
}
}
}
for (i in this.__current_state)
{
if(this.__current_state.hasOwnProperty(i))
{
arChanges.push({
key: i, newValue: undefined, oldValue: this.__current_state[i]
});
}
}
this.__current_state = new_state;
for (i=0; i<arChanges.length; i++)
{
this._onchange(arChanges[i]);
}
};
BX.localStorageIE7.prototype._clear = function()
{
this.storage_element.load(this.NS);
var doc = this.storage_element.xmlDocument,
len = doc.firstChild.attributes.length,
curDate = +new Date(),
i,k,v,ttl;
for (i = 0; i<len; i++)
{
if (!!doc.firstChild.attributes[i])
{
k = doc.firstChild.attributes[i].nodeName;
if (k.substring(0,2) == 'bx')
{
v = doc.firstChild.attributes[i].nodeValue;
ttl = v.split(':', 1)*1000;
if (curDate >= 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);