Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / src / state / Provider.js
index 42da936..f7bccde 100644 (file)
@@ -1,28 +1,42 @@
-/*!
- * Ext JS Library 3.2.0
- * Copyright(c) 2006-2010 Ext JS, Inc.
- * 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 <b>typed</b> variables including dates and defines the
- * Provider interface.
+ * <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.state.Provider = function(){
+Ext.define('Ext.state.Provider', {
+    mixins: {
+        observable: 'Ext.util.Observable'
+    },
+    
     /**
-     * @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
+     * @cfg {String} prefix A string to prefix to items stored in the underlying state store. 
+     * Defaults to <tt>'ext-'</tt>
      */
-    this.addEvents("statechange");
-    this.state = {};
-    Ext.state.Provider.superclass.constructor.call(this);
-};
-Ext.extend(Ext.state.Provider, Ext.util.Observable, {
+    prefix: 'ext-',
+    
+    constructor : function(config){
+        config = config || {};
+        var me = this;
+        Ext.apply(me, config);
+        /**
+         * @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
+         */
+        me.addEvents("statechange");
+        me.state = {};
+        me.mixins.observable.constructor.call(me);
+    },
+    
     /**
      * Returns the current value for a key
      * @param {String} name The key name
@@ -39,8 +53,9 @@ Ext.extend(Ext.state.Provider, Ext.util.Observable, {
      * @param {String} name The key name
      */
     clear : function(name){
-        delete this.state[name];
-        this.fireEvent("statechange", this, name, null);
+        var me = this;
+        delete me.state[name];
+        me.fireEvent("statechange", me, name, null);
     },
 
     /**
@@ -49,8 +64,9 @@ Ext.extend(Ext.state.Provider, Ext.util.Observable, {
      * @param {Mixed} value The value to set
      */
     set : function(name, value){
-        this.state[name] = value;
-        this.fireEvent("statechange", this, name, value);
+        var me = this;
+        me.state[name] = value;
+        me.fireEvent("statechange", me, name, value);
     },
 
     /**
@@ -58,38 +74,58 @@ Ext.extend(Ext.state.Provider, Ext.util.Observable, {
      * @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 = [];
-                if(v != ''){
-                    Ext.each(v.split('^'), function(val){
-                        all.push(this.decodeValue(val));
-                    }, this);
+    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,
+            value,
+            keyValue;
+            
+        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 != ''){
+                    Ext.each(value.split('^'), function(val){
+                        all.push(me.decodeValue(val));
+                    }, me);
                 }
                 return all;
-           case "o":
-                var all = {};
-                if(v != ''){
-                    Ext.each(v.split('^'), function(val){
-                        var kv = val.split('=');
-                        all[kv[0]] = this.decodeValue(kv[1]);
-                    }, this);
+           case 'o':
+                all = {};
+                if(value != ''){
+                    Ext.each(value.split('^'), function(val){
+                        keyValue = val.split('=');
+                        all[keyValue[0]] = me.decodeValue(keyValue[1]);
+                    }, me);
                 }
                 return all;
            default:
-                return v;
+                return value;
         }
     },
 
@@ -98,32 +134,39 @@ Ext.extend(Ext.state.Provider, Ext.util.Observable, {
      * @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 += "^";
+    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.toGMTString();
+        } 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 v == "object"){
-            var flat = "";
-            for(var key in v){
-                if(typeof v[key] != "function" && v[key] !== undefined){
-                    flat += key + "=" + this.encodeValue(v[key]) + "^";
+            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:" + v;
+            enc = 'o:' + flat.substring(0, flat.length-1);
+        } else {
+            enc = 's:' + value;
         }
         return escape(enc);
     }
-});
+});
\ No newline at end of file