Diffstat (limited to 'frontend/beta/js/YUI-extensions/State.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/YUI-extensions/State.js | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI-extensions/State.js b/frontend/beta/js/YUI-extensions/State.js new file mode 100644 index 0000000..76a9618 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/State.js | |||
@@ -0,0 +1,264 @@ | |||
1 | YAHOO.namespace('ext.state'); | ||
2 | /** | ||
3 | * @class YAHOO.ext.state.Provider | ||
4 | * Abstract base class for provider implementations. This class provides methods | ||
5 | * for encoding and decoding <b>typed</b> variables including dates and defines the | ||
6 | * Provider interface. | ||
7 | */ | ||
8 | YAHOO.ext.state.Provider = function(){ | ||
9 | YAHOO.ext.state.Provider.superclass.constructor.call(this); | ||
10 | /** | ||
11 | * @event statechange | ||
12 | * Fires when a state change occurs. | ||
13 | * @param {Provider} this | ||
14 | * @param {String} key The state key which was changed | ||
15 | * @param {String} value The encoded value for the state | ||
16 | */ | ||
17 | this.events = { | ||
18 | 'statechange': new YAHOO.util.CustomEvent('statechange') | ||
19 | }; | ||
20 | this.state = {}; | ||
21 | }; | ||
22 | YAHOO.extendX(YAHOO.ext.state.Provider, YAHOO.ext.util.Observable, { | ||
23 | /** | ||
24 | * Get the current value for a key. | ||
25 | * @param {String} name | ||
26 | * @param {Mixed} defaultValue | ||
27 | * @return {Mixed} | ||
28 | */ | ||
29 | get : function(name, defaultValue){ | ||
30 | return typeof this.state[name] == 'undefined' ? | ||
31 | defaultValue : this.state[name]; | ||
32 | }, | ||
33 | |||
34 | /** | ||
35 | * Clear a value from the state. | ||
36 | */ | ||
37 | clear : function(name){ | ||
38 | delete this.state[name]; | ||
39 | this.fireEvent('statechange', this, name, null); | ||
40 | }, | ||
41 | |||
42 | /** | ||
43 | * Set the value for a key. | ||
44 | * @param {String} name | ||
45 | * @param {Mixed} value | ||
46 | */ | ||
47 | set : function(name, value){ | ||
48 | this.state[name] = value; | ||
49 | this.fireEvent('statechange', this, name, value); | ||
50 | }, | ||
51 | |||
52 | /** | ||
53 | * Decodes a string previously encoded with {@link #encodeValue}. | ||
54 | * @param {String} value | ||
55 | * @return {Mixed} The value | ||
56 | */ | ||
57 | decodeValue : function(cookie){ | ||
58 | var re = /^(a|n|d|b|s|o)\:(.*)$/; | ||
59 | var matches = re.exec(unescape(cookie)); | ||
60 | if(!matches || !matches[1]) return; // non state cookie | ||
61 | var type = matches[1]; | ||
62 | var v = matches[2]; | ||
63 | switch(type){ | ||
64 | case 'n': | ||
65 | return parseFloat(v); | ||
66 | case 'd': | ||
67 | return new Date(Date.parse(v)); | ||
68 | case 'b': | ||
69 | return (v == '1'); | ||
70 | case 'a': | ||
71 | var all = []; | ||
72 | var values = v.split('^'); | ||
73 | for(var i = 0, len = values.length; i < len; i++){ | ||
74 | all.push(this.decodeValue(values[i])) | ||
75 | } | ||
76 | return all; | ||
77 | case 'o': | ||
78 | var all = {}; | ||
79 | var values = v.split('^'); | ||
80 | for(var i = 0, len = values.length; i < len; i++){ | ||
81 | var kv = values[i].split('='); | ||
82 | all[kv[0]] = this.decodeValue(kv[1]); | ||
83 | } | ||
84 | return all; | ||
85 | default: | ||
86 | return v; | ||
87 | } | ||
88 | }, | ||
89 | |||
90 | /** | ||
91 | * Encode a value including type information. | ||
92 | * @param {Mixed} value | ||
93 | * @return {String} | ||
94 | */ | ||
95 | encodeValue : function(v){ | ||
96 | var enc; | ||
97 | if(typeof v == 'number'){ | ||
98 | enc = 'n:' + v; | ||
99 | }else if(typeof v == 'boolean'){ | ||
100 | enc = 'b:' + (v ? '1' : '0'); | ||
101 | }else if(v instanceof Date){ | ||
102 | enc = 'd:' + v.toGMTString(); | ||
103 | }else if(v instanceof Array){ | ||
104 | var flat = ''; | ||
105 | for(var i = 0, len = v.length; i < len; i++){ | ||
106 | flat += this.encodeValue(v[i]); | ||
107 | if(i != len-1) flat += '^'; | ||
108 | } | ||
109 | enc = 'a:' + flat; | ||
110 | }else if(typeof v == 'object'){ | ||
111 | var flat = ''; | ||
112 | for(var key in v){ | ||
113 | if(typeof v[key] != 'function'){ | ||
114 | flat += key + '=' + this.encodeValue(v[key]) + '^'; | ||
115 | } | ||
116 | } | ||
117 | enc = 'o:' + flat.substring(0, flat.length-1); | ||
118 | }else{ | ||
119 | enc = 's:' + v; | ||
120 | } | ||
121 | return escape(enc); | ||
122 | } | ||
123 | }); | ||
124 | |||
125 | /** | ||
126 | * @class YAHOO.ext.state.Manager | ||
127 | * This is the global state manager. By default all components that are "state aware" check this class | ||
128 | * for state information if you don't pass them a custom state provider. In order for this class | ||
129 | * to be useful, it must be initialized with a provider when your application initializes. | ||
130 | <pre><code> | ||
131 | // in your initialization function | ||
132 | init : function(){ | ||
133 | YAHOO.ext.state.Manager.setProvider(new YAHOO.ext.state.CookieProvider()); | ||
134 | ... | ||
135 | // supposed you have a {@link YAHOO.ext.BorderLayout} | ||
136 | var layout = new YAHOO.ext.BorderLayout(...); | ||
137 | layout.restoreState(); | ||
138 | // or a {YAHOO.ext.BasicDialog} | ||
139 | var dialog = new YAHOO.ext.BasicDialog(...); | ||
140 | dialog.restoreState(); | ||
141 | </code></pre> | ||
142 | * @singleton | ||
143 | */ | ||
144 | YAHOO.ext.state.Manager = new function(){ | ||
145 | var provider = new YAHOO.ext.state.Provider(); | ||
146 | |||
147 | return { | ||
148 | /** | ||
149 | * Configures the default provider for your application. | ||
150 | * @param {Provider} stateProvider | ||
151 | */ | ||
152 | setProvider : function(stateProvider){ | ||
153 | provider = stateProvider; | ||
154 | }, | ||
155 | |||
156 | /** | ||
157 | * Get the current value for a key. | ||
158 | * @param {String} name | ||
159 | * @param {Mixed} defaultValue | ||
160 | * @return {Mixed} | ||
161 | */ | ||
162 | get : function(key, defaultValue){ | ||
163 | return provider.get(key, defaultValue); | ||
164 | }, | ||
165 | |||
166 | /** | ||
167 | * Set the value for a key. | ||
168 | * @param {String} name | ||
169 | * @param {Mixed} value | ||
170 | */ | ||
171 | set : function(key, value){ | ||
172 | provider.set(key, value); | ||
173 | }, | ||
174 | |||
175 | /** | ||
176 | * Clear a value from the state. | ||
177 | */ | ||
178 | clear : function(key){ | ||
179 | provider.clear(key); | ||
180 | }, | ||
181 | |||
182 | /** | ||
183 | * Gets the currently configured provider. | ||
184 | * @return {Provider} | ||
185 | */ | ||
186 | getProvider : function(){ | ||
187 | return provider; | ||
188 | } | ||
189 | }; | ||
190 | }(); | ||
191 | |||
192 | /** | ||
193 | * @class YAHOO.ext.state.CookieProvider | ||
194 | * @extends YAHOO.ext.state.Provider | ||
195 | * The default Provider implementation. The example below includes all valid configuration options and their | ||
196 | * default values. | ||
197 | <pre><code> | ||
198 | var cp = new YAHOO.ext.state.CookieProvider({ | ||
199 | path: '/', | ||
200 | expires: new Date(new Date().getTime()+(1000*60*60*24*7)); //7 days | ||
201 | domain: null, | ||
202 | secure: false | ||
203 | }) | ||
204 | YAHOO.ext.state.Manager.setProvider(cp); | ||
205 | </code></pre> | ||
206 | * @constructor | ||
207 | * Create a new CookieProvider | ||
208 | * @param {Object} config The configuration object | ||
209 | */ | ||
210 | YAHOO.ext.state.CookieProvider = function(config){ | ||
211 | YAHOO.ext.state.CookieProvider.superclass.constructor.call(this); | ||
212 | this.path = '/'; | ||
213 | this.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); //7 days | ||
214 | this.domain = null; | ||
215 | this.secure = false; | ||
216 | YAHOO.ext.util.Config.apply(this, config); | ||
217 | this.state = this.readCookies(); | ||
218 | }; | ||
219 | |||
220 | YAHOO.extendX(YAHOO.ext.state.CookieProvider, YAHOO.ext.state.Provider, { | ||
221 | set : function(name, value){ | ||
222 | if(typeof value == 'undefined' || value === null){ | ||
223 | this.clear(name); | ||
224 | return; | ||
225 | } | ||
226 | this.setCookie(name, value); | ||
227 | YAHOO.ext.state.CookieProvider.superclass.set.call(this, name, value); | ||
228 | }, | ||
229 | |||
230 | clear : function(name){ | ||
231 | this.clearCookie(name); | ||
232 | YAHOO.ext.state.CookieProvider.superclass.clear.call(this, name); | ||
233 | }, | ||
234 | |||
235 | readCookies : function(){ | ||
236 | var cookies = {}; | ||
237 | var c = document.cookie + ';'; | ||
238 | var re = /\s?(.*?)=(.*?);/g; | ||
239 | var matches; | ||
240 | while((matches = re.exec(c)) != null){ | ||
241 | var name = matches[1]; | ||
242 | var value = matches[2]; | ||
243 | if(name && name.substring(0,3) == 'ys-'){ | ||
244 | cookies[name.substr(3)] = this.decodeValue(value); | ||
245 | } | ||
246 | } | ||
247 | return cookies; | ||
248 | }, | ||
249 | |||
250 | setCookie : function(name, value){ | ||
251 | document.cookie = "ys-"+ name + "=" + this.encodeValue(value) + | ||
252 | ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) + | ||
253 | ((this.path == null) ? "" : ("; path=" + this.path)) + | ||
254 | ((this.domain == null) ? "" : ("; domain=" + this.domain)) + | ||
255 | ((this.secure == true) ? "; secure" : ""); | ||
256 | }, | ||
257 | |||
258 | clearCookie : function(name){ | ||
259 | document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" + | ||
260 | ((this.path == null) ? "" : ("; path=" + this.path)) + | ||
261 | ((this.domain == null) ? "" : ("; domain=" + this.domain)) + | ||
262 | ((this.secure == true) ? "; secure" : ""); | ||
263 | } | ||
264 | }); | ||