microsoft-teamsdiscordmessengercustom-servicesmacoslinuxwindowsinboxwhatsappicloudtweetdeckhipchattelegramhangoutsslackgmailskypefacebook-workplaceoutlookemail
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
5.5 KiB
174 lines
5.5 KiB
9 years ago
|
/**
|
||
|
* @class Ext.state.Provider
|
||
|
* <p>Abstract base class for state provider implementations. The provider is responsible
|
||
|
* for setting values and extracting values to/from the underlying storage source. The
|
||
|
* storage source can vary and the details should be implemented in a subclass. For example
|
||
|
* a provider could use a server side database or the browser localstorage where supported.</p>
|
||
|
*
|
||
|
* <p>This class provides methods for encoding and decoding <b>typed</b> variables including
|
||
|
* dates and defines the Provider interface. By default these methods put the value and the
|
||
|
* type information into a delimited string that can be stored. These should be overridden in
|
||
|
* a subclass if you want to change the format of the encoded value and subsequent decoding.</p>
|
||
|
*/
|
||
|
Ext.define('Ext.state.Provider', {
|
||
|
mixins: {
|
||
|
observable: 'Ext.util.Observable'
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @cfg {String} prefix A string to prefix to items stored in the underlying state store.
|
||
|
* Defaults to <tt>'ext-'</tt>
|
||
|
*/
|
||
|
prefix: 'ext-',
|
||
|
|
||
|
/**
|
||
|
* @event statechange
|
||
|
* Fires when a state change occurs.
|
||
|
* @param {Ext.state.Provider} this This state provider
|
||
|
* @param {String} key The state key which was changed
|
||
|
* @param {String} value The encoded value for the state
|
||
|
*/
|
||
|
|
||
|
constructor : function(config){
|
||
|
var me = this;
|
||
|
Ext.apply(me, config);
|
||
|
me.state = {};
|
||
|
me.mixins.observable.constructor.call(me);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Returns the current value for a key
|
||
|
* @param {String} name The key name
|
||
|
* @param {Object} defaultValue A default value to return if the key's value is not found
|
||
|
* @return {Object} The state data
|
||
|
*/
|
||
|
get : function(name, defaultValue){
|
||
|
var ret = this.state[name];
|
||
|
return ret === undefined ? defaultValue : ret;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Clears a value from the state
|
||
|
* @param {String} name The key name
|
||
|
*/
|
||
|
clear : function(name){
|
||
|
var me = this;
|
||
|
delete me.state[name];
|
||
|
me.fireEvent("statechange", me, name, null);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Sets the value for a key
|
||
|
* @param {String} name The key name
|
||
|
* @param {Object} value The value to set
|
||
|
*/
|
||
|
set : function(name, value){
|
||
|
var me = this;
|
||
|
me.state[name] = value;
|
||
|
me.fireEvent("statechange", me, name, value);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Decodes a string previously encoded with {@link #encodeValue}.
|
||
|
* @param {String} value The value to decode
|
||
|
* @return {Object} The decoded value
|
||
|
*/
|
||
|
decodeValue : function(value){
|
||
|
|
||
|
// a -> Array
|
||
|
// n -> Number
|
||
|
// d -> Date
|
||
|
// b -> Boolean
|
||
|
// s -> String
|
||
|
// o -> Object
|
||
|
// -> Empty (null)
|
||
|
|
||
|
var me = this,
|
||
|
re = /^(a|n|d|b|s|o|e)\:(.*)$/,
|
||
|
matches = re.exec(unescape(value)),
|
||
|
all, type, keyValue, values, vLen, v;
|
||
|
|
||
|
if (!matches || !matches[1]) {
|
||
|
return; // non state
|
||
|
}
|
||
|
|
||
|
type = matches[1];
|
||
|
value = matches[2];
|
||
|
switch (type) {
|
||
|
case 'e':
|
||
|
return null;
|
||
|
case 'n':
|
||
|
return parseFloat(value);
|
||
|
case 'd':
|
||
|
return new Date(Date.parse(value));
|
||
|
case 'b':
|
||
|
return (value === '1');
|
||
|
case 'a':
|
||
|
all = [];
|
||
|
if (value) {
|
||
|
values = value.split('^');
|
||
|
vLen = values.length;
|
||
|
|
||
|
for (v = 0; v < vLen; v++) {
|
||
|
value = values[v];
|
||
|
all.push(me.decodeValue(value));
|
||
|
}
|
||
|
}
|
||
|
return all;
|
||
|
case 'o':
|
||
|
all = {};
|
||
|
if (value) {
|
||
|
values = value.split('^');
|
||
|
vLen = values.length;
|
||
|
|
||
|
for (v = 0; v < vLen; v++) {
|
||
|
value = values[v];
|
||
|
keyValue = value.split('=');
|
||
|
all[keyValue[0]] = me.decodeValue(keyValue[1]);
|
||
|
}
|
||
|
}
|
||
|
return all;
|
||
|
default:
|
||
|
return value;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Encodes a value including type information. Decode with {@link #decodeValue}.
|
||
|
* @param {Object} value The value to encode
|
||
|
* @return {String} The encoded value
|
||
|
*/
|
||
|
encodeValue : function(value){
|
||
|
var flat = '',
|
||
|
i = 0,
|
||
|
enc, len, key;
|
||
|
|
||
|
if (value == null) {
|
||
|
return 'e:1';
|
||
|
} else if(typeof value === 'number') {
|
||
|
enc = 'n:' + value;
|
||
|
} else if(typeof value === 'boolean') {
|
||
|
enc = 'b:' + (value ? '1' : '0');
|
||
|
} else if(Ext.isDate(value)) {
|
||
|
enc = 'd:' + value.toUTCString();
|
||
|
} else if(Ext.isArray(value)) {
|
||
|
for (len = value.length; i < len; i++) {
|
||
|
flat += this.encodeValue(value[i]);
|
||
|
if (i !== len - 1) {
|
||
|
flat += '^';
|
||
|
}
|
||
|
}
|
||
|
enc = 'a:' + flat;
|
||
|
} else if (typeof value === 'object') {
|
||
|
for (key in value) {
|
||
|
if (typeof value[key] !== 'function' && value[key] !== undefined) {
|
||
|
flat += key + '=' + this.encodeValue(value[key]) + '^';
|
||
|
}
|
||
|
}
|
||
|
enc = 'o:' + flat.substring(0, flat.length-1);
|
||
|
} else {
|
||
|
enc = 's:' + value;
|
||
|
}
|
||
|
return escape(enc);
|
||
|
}
|
||
|
});
|