X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/ee06f37b0f6f6d94cd05a6ffae556660f7c4a2bc..c930e9176a5a85509c5b0230e2bff5c22a591432:/pkgs/state-debug.js diff --git a/pkgs/state-debug.js b/pkgs/state-debug.js new file mode 100644 index 00000000..dcc5f714 --- /dev/null +++ b/pkgs/state-debug.js @@ -0,0 +1,274 @@ +/*! + * Ext JS Library 3.0.0 + * Copyright(c) 2006-2009 Ext JS, LLC + * licensing@extjs.com + * http://www.extjs.com/license + */ +/** + * @class Ext.state.Provider + * Abstract base class for state provider implementations. This class provides methods + * for encoding and decoding typed variables including dates and defines the + * Provider interface. + */ +Ext.state.Provider = function(){ + /** + * @event statechange + * Fires when a state change occurs. + * @param {Provider} this This state provider + * @param {String} key The state key which was changed + * @param {String} value The encoded value for the state + */ + this.addEvents("statechange"); + this.state = {}; + Ext.state.Provider.superclass.constructor.call(this); +}; +Ext.extend(Ext.state.Provider, Ext.util.Observable, { + /** + * Returns the current value for a key + * @param {String} name The key name + * @param {Mixed} defaultValue A default value to return if the key's value is not found + * @return {Mixed} The state data + */ + get : function(name, defaultValue){ + return typeof this.state[name] == "undefined" ? + defaultValue : this.state[name]; + }, + + /** + * Clears a value from the state + * @param {String} name The key name + */ + clear : function(name){ + delete this.state[name]; + this.fireEvent("statechange", this, name, null); + }, + + /** + * Sets the value for a key + * @param {String} name The key name + * @param {Mixed} value The value to set + */ + set : function(name, value){ + this.state[name] = value; + this.fireEvent("statechange", this, name, value); + }, + + /** + * Decodes a string previously encoded with {@link #encodeValue}. + * @param {String} value The value to decode + * @return {Mixed} The decoded value + */ + decodeValue : function(cookie){ + var re = /^(a|n|d|b|s|o)\:(.*)$/; + var matches = re.exec(unescape(cookie)); + if(!matches || !matches[1]) return; // non state cookie + var type = matches[1]; + var v = matches[2]; + switch(type){ + case "n": + return parseFloat(v); + case "d": + return new Date(Date.parse(v)); + case "b": + return (v == "1"); + case "a": + var all = []; + var values = v.split("^"); + for(var i = 0, len = values.length; i < len; i++){ + all.push(this.decodeValue(values[i])); + } + return all; + case "o": + var all = {}; + var values = v.split("^"); + for(var i = 0, len = values.length; i < len; i++){ + var kv = values[i].split("="); + all[kv[0]] = this.decodeValue(kv[1]); + } + return all; + default: + return v; + } + }, + + /** + * Encodes a value including type information. Decode with {@link #decodeValue}. + * @param {Mixed} value The value to encode + * @return {String} The encoded value + */ + encodeValue : function(v){ + var enc; + if(typeof v == "number"){ + enc = "n:" + v; + }else if(typeof v == "boolean"){ + enc = "b:" + (v ? "1" : "0"); + }else if(Ext.isDate(v)){ + enc = "d:" + v.toGMTString(); + }else if(Ext.isArray(v)){ + var flat = ""; + for(var i = 0, len = v.length; i < len; i++){ + flat += this.encodeValue(v[i]); + if(i != len-1) flat += "^"; + } + enc = "a:" + flat; + }else if(typeof v == "object"){ + var flat = ""; + for(var key in v){ + if(typeof v[key] != "function" && v[key] !== undefined){ + flat += key + "=" + this.encodeValue(v[key]) + "^"; + } + } + enc = "o:" + flat.substring(0, flat.length-1); + }else{ + enc = "s:" + v; + } + return escape(enc); + } +}); +/** + * @class Ext.state.Manager + * This is the global state manager. By default all components that are "state aware" check this class + * for state information if you don't pass them a custom state provider. In order for this class + * to be useful, it must be initialized with a provider when your application initializes. Example usage: +

+// in your initialization function
+init : function(){
+   Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
+   var win = new Window(...);
+   win.restoreState();
+}
+ 
+ * @singleton + */ +Ext.state.Manager = function(){ + var provider = new Ext.state.Provider(); + + return { + /** + * Configures the default state provider for your application + * @param {Provider} stateProvider The state provider to set + */ + setProvider : function(stateProvider){ + provider = stateProvider; + }, + + /** + * Returns the current value for a key + * @param {String} name The key name + * @param {Mixed} defaultValue The default value to return if the key lookup does not match + * @return {Mixed} The state data + */ + get : function(key, defaultValue){ + return provider.get(key, defaultValue); + }, + + /** + * Sets the value for a key + * @param {String} name The key name + * @param {Mixed} value The state data + */ + set : function(key, value){ + provider.set(key, value); + }, + + /** + * Clears a value from the state + * @param {String} name The key name + */ + clear : function(key){ + provider.clear(key); + }, + + /** + * Gets the currently configured state provider + * @return {Provider} The state provider + */ + getProvider : function(){ + return provider; + } + }; +}(); +/** + * @class Ext.state.CookieProvider + * @extends Ext.state.Provider + * The default Provider implementation which saves state via cookies. + *
Usage: +

+   var cp = new Ext.state.CookieProvider({
+       path: "/cgi-bin/",
+       expires: new Date(new Date().getTime()+(1000*60*60*24*30)), //30 days
+       domain: "extjs.com"
+   });
+   Ext.state.Manager.setProvider(cp);
+ 
+ * @cfg {String} path The path for which the cookie is active (defaults to root '/' which makes it active for all pages in the site) + * @cfg {Date} expires The cookie expiration date (defaults to 7 days from now) + * @cfg {String} domain The domain to save the cookie for. Note that you cannot specify a different domain than + * your page is on, but you can specify a sub-domain, or simply the domain itself like 'extjs.com' to include + * all sub-domains if you need to access cookies across different sub-domains (defaults to null which uses the same + * domain the page is running on including the 'www' like 'www.extjs.com') + * @cfg {Boolean} secure True if the site is using SSL (defaults to false) + * @constructor + * Create a new CookieProvider + * @param {Object} config The configuration object + */ +Ext.state.CookieProvider = function(config){ + Ext.state.CookieProvider.superclass.constructor.call(this); + this.path = "/"; + this.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); //7 days + this.domain = null; + this.secure = false; + Ext.apply(this, config); + this.state = this.readCookies(); +}; + +Ext.extend(Ext.state.CookieProvider, Ext.state.Provider, { + // private + set : function(name, value){ + if(typeof value == "undefined" || value === null){ + this.clear(name); + return; + } + this.setCookie(name, value); + Ext.state.CookieProvider.superclass.set.call(this, name, value); + }, + + // private + clear : function(name){ + this.clearCookie(name); + Ext.state.CookieProvider.superclass.clear.call(this, name); + }, + + // private + readCookies : function(){ + var cookies = {}; + var c = document.cookie + ";"; + var re = /\s?(.*?)=(.*?);/g; + var matches; + while((matches = re.exec(c)) != null){ + var name = matches[1]; + var value = matches[2]; + if(name && name.substring(0,3) == "ys-"){ + cookies[name.substr(3)] = this.decodeValue(value); + } + } + return cookies; + }, + + // private + setCookie : function(name, value){ + document.cookie = "ys-"+ name + "=" + this.encodeValue(value) + + ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) + + ((this.path == null) ? "" : ("; path=" + this.path)) + + ((this.domain == null) ? "" : ("; domain=" + this.domain)) + + ((this.secure == true) ? "; secure" : ""); + }, + + // private + clearCookie : function(name){ + document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" + + ((this.path == null) ? "" : ("; path=" + this.path)) + + ((this.domain == null) ? "" : ("; domain=" + this.domain)) + + ((this.secure == true) ? "; secure" : ""); + } +}); \ No newline at end of file