]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * @class Ext.state.Provider\r | |
3 | * <p>Abstract base class for state provider implementations. The provider is responsible\r | |
4 | * for setting values and extracting values to/from the underlying storage source. The \r | |
5 | * storage source can vary and the details should be implemented in a subclass. For example\r | |
6 | * a provider could use a server side database or the browser localstorage where supported.</p>\r | |
7 | *\r | |
8 | * <p>This class provides methods for encoding and decoding <b>typed</b> variables including \r | |
9 | * dates and defines the Provider interface. By default these methods put the value and the\r | |
10 | * type information into a delimited string that can be stored. These should be overridden in \r | |
11 | * a subclass if you want to change the format of the encoded value and subsequent decoding.</p>\r | |
12 | */\r | |
13 | Ext.define('Ext.state.Provider', {\r | |
14 | mixins: {\r | |
15 | observable: 'Ext.util.Observable'\r | |
16 | },\r | |
17 | \r | |
18 | /**\r | |
19 | * @cfg {String} prefix A string to prefix to items stored in the underlying state store. \r | |
20 | * Defaults to <tt>'ext-'</tt>\r | |
21 | */\r | |
22 | prefix: 'ext-',\r | |
23 | \r | |
24 | /**\r | |
25 | * @event statechange\r | |
26 | * Fires when a state change occurs.\r | |
27 | * @param {Ext.state.Provider} this This state provider\r | |
28 | * @param {String} key The state key which was changed\r | |
29 | * @param {String} value The encoded value for the state\r | |
30 | */\r | |
31 | \r | |
32 | constructor : function(config){\r | |
33 | var me = this;\r | |
34 | Ext.apply(me, config);\r | |
35 | me.state = {};\r | |
36 | me.mixins.observable.constructor.call(me);\r | |
37 | },\r | |
38 | \r | |
39 | /**\r | |
40 | * Returns the current value for a key\r | |
41 | * @param {String} name The key name\r | |
42 | * @param {Object} defaultValue A default value to return if the key's value is not found\r | |
43 | * @return {Object} The state data\r | |
44 | */\r | |
45 | get : function(name, defaultValue){\r | |
46 | var ret = this.state[name];\r | |
47 | return ret === undefined ? defaultValue : ret;\r | |
48 | },\r | |
49 | \r | |
50 | /**\r | |
51 | * Clears a value from the state\r | |
52 | * @param {String} name The key name\r | |
53 | */\r | |
54 | clear : function(name){\r | |
55 | var me = this;\r | |
56 | delete me.state[name];\r | |
57 | me.fireEvent("statechange", me, name, null);\r | |
58 | },\r | |
59 | \r | |
60 | /**\r | |
61 | * Sets the value for a key\r | |
62 | * @param {String} name The key name\r | |
63 | * @param {Object} value The value to set\r | |
64 | */\r | |
65 | set : function(name, value){\r | |
66 | var me = this;\r | |
67 | me.state[name] = value;\r | |
68 | me.fireEvent("statechange", me, name, value);\r | |
69 | },\r | |
70 | \r | |
71 | /**\r | |
72 | * Decodes a string previously encoded with {@link #encodeValue}.\r | |
73 | * @param {String} value The value to decode\r | |
74 | * @return {Object} The decoded value\r | |
75 | */\r | |
76 | decodeValue : function(value){\r | |
77 | \r | |
78 | // a -> Array\r | |
79 | // n -> Number\r | |
80 | // d -> Date\r | |
81 | // b -> Boolean\r | |
82 | // s -> String\r | |
83 | // o -> Object\r | |
84 | // -> Empty (null)\r | |
85 | \r | |
86 | var me = this,\r | |
87 | re = /^(a|n|d|b|s|o|e)\:(.*)$/,\r | |
88 | matches = re.exec(unescape(value)),\r | |
89 | all, type, keyValue, values, vLen, v;\r | |
90 | \r | |
91 | if (!matches || !matches[1]) {\r | |
92 | return; // non state\r | |
93 | }\r | |
94 | \r | |
95 | type = matches[1];\r | |
96 | value = matches[2];\r | |
97 | switch (type) {\r | |
98 | case 'e':\r | |
99 | return null;\r | |
100 | case 'n':\r | |
101 | return parseFloat(value);\r | |
102 | case 'd':\r | |
103 | return new Date(Date.parse(value));\r | |
104 | case 'b':\r | |
105 | return (value === '1');\r | |
106 | case 'a':\r | |
107 | all = [];\r | |
108 | if (value) {\r | |
109 | values = value.split('^');\r | |
110 | vLen = values.length;\r | |
111 | \r | |
112 | for (v = 0; v < vLen; v++) {\r | |
113 | value = values[v];\r | |
114 | all.push(me.decodeValue(value));\r | |
115 | }\r | |
116 | }\r | |
117 | return all;\r | |
118 | case 'o':\r | |
119 | all = {};\r | |
120 | if (value) {\r | |
121 | values = value.split('^');\r | |
122 | vLen = values.length;\r | |
123 | \r | |
124 | for (v = 0; v < vLen; v++) {\r | |
125 | value = values[v];\r | |
126 | keyValue = value.split('=');\r | |
127 | all[keyValue[0]] = me.decodeValue(keyValue[1]);\r | |
128 | }\r | |
129 | }\r | |
130 | return all;\r | |
131 | default:\r | |
132 | return value;\r | |
133 | }\r | |
134 | },\r | |
135 | \r | |
136 | /**\r | |
137 | * Encodes a value including type information. Decode with {@link #decodeValue}.\r | |
138 | * @param {Object} value The value to encode\r | |
139 | * @return {String} The encoded value\r | |
140 | */\r | |
141 | encodeValue : function(value){\r | |
142 | var flat = '',\r | |
143 | i = 0,\r | |
144 | enc, len, key;\r | |
145 | \r | |
146 | if (value == null) {\r | |
147 | return 'e:1'; \r | |
148 | } else if(typeof value === 'number') {\r | |
149 | enc = 'n:' + value;\r | |
150 | } else if(typeof value === 'boolean') {\r | |
151 | enc = 'b:' + (value ? '1' : '0');\r | |
152 | } else if(Ext.isDate(value)) {\r | |
153 | enc = 'd:' + value.toUTCString();\r | |
154 | } else if(Ext.isArray(value)) {\r | |
155 | for (len = value.length; i < len; i++) {\r | |
156 | flat += this.encodeValue(value[i]);\r | |
157 | if (i !== len - 1) {\r | |
158 | flat += '^';\r | |
159 | }\r | |
160 | }\r | |
161 | enc = 'a:' + flat;\r | |
162 | } else if (typeof value === 'object') {\r | |
163 | for (key in value) {\r | |
164 | if (typeof value[key] !== 'function' && value[key] !== undefined) {\r | |
165 | flat += key + '=' + this.encodeValue(value[key]) + '^';\r | |
166 | }\r | |
167 | }\r | |
168 | enc = 'o:' + flat.substring(0, flat.length-1);\r | |
169 | } else {\r | |
170 | enc = 's:' + value;\r | |
171 | }\r | |
172 | return escape(enc);\r | |
173 | }\r | |
174 | }); |