]> git.wh0rd.org - tt-rss.git/blobdiff - lib/dojo/Stateful.js
build custom layer of Dojo to speed up loading of tt-rss (refs #293)
[tt-rss.git] / lib / dojo / Stateful.js
index 136b319c74a18736cbe1c7e136142c5564b28a64..e4f406309683ba88999fc1d33cfe2f6764726df2 100644 (file)
 */
 
 
-if(!dojo._hasResource["dojo.Stateful"]){
-dojo._hasResource["dojo.Stateful"]=true;
+if(!dojo._hasResource["dojo.Stateful"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.Stateful"] = true;
 dojo.provide("dojo.Stateful");
-dojo.declare("dojo.Stateful",null,{postscript:function(_1){
-if(_1){
-dojo.mixin(this,_1);
-}
-},get:function(_2){
-return this[_2];
-},set:function(_3,_4){
-if(typeof _3==="object"){
-for(var x in _3){
-this.set(x,_3[x]);
-}
-return this;
-}
-var _5=this[_3];
-this[_3]=_4;
-if(this._watchCallbacks){
-this._watchCallbacks(_3,_5,_4);
-}
-return this;
-},watch:function(_6,_7){
-var _8=this._watchCallbacks;
-if(!_8){
-var _9=this;
-_8=this._watchCallbacks=function(_a,_b,_c,_d){
-var _e=function(_f){
-for(var i=0,l=_f&&_f.length;i<l;i++){
-try{
-_f[i].call(_9,_a,_b,_c);
-}
-catch(e){
-console.error(e);
-}
-}
-};
-_e(_8[_a]);
-if(!_d){
-_e(_8["*"]);
-}
-};
-}
-if(!_7&&typeof _6==="function"){
-_7=_6;
-_6="*";
-}
-var _10=_8[_6];
-if(typeof _10!=="object"){
-_10=_8[_6]=[];
-}
-_10.push(_7);
-return {unwatch:function(){
-_10.splice(dojo.indexOf(_10,_7),1);
-}};
-}});
+
+dojo.declare("dojo.Stateful", null, {
+       // summary:
+       //              Base class for objects that provide named properties with optional getter/setter
+       //              control and the ability to watch for property changes
+       // example:
+       //      |       var obj = new dojo.Stateful();
+       //      |       obj.watch("foo", function(){
+       //      |               console.log("foo changed to " + this.get("foo"));
+       //      |       });
+       //      |       obj.set("foo","bar");
+       postscript: function(mixin){
+               if(mixin){
+                       dojo.mixin(this, mixin);
+               }
+       },
+       
+       get: function(/*String*/name){
+               // summary:
+               //              Get a property on a Stateful instance.
+               //      name:
+               //              The property to get.
+               // description:
+               //              Get a named property on a Stateful object. The property may
+               //              potentially be retrieved via a getter method in subclasses. In the base class
+               //              this just retrieves the object's property. 
+               //              For example:
+               //      |       stateful = new dojo.Stateful({foo: 3});
+               //      |       stateful.get("foo") // returns 3
+               //      |       stateful.foo // returns 3
+               
+               return this[name];
+       },
+       set: function(/*String*/name, /*Object*/value){
+               // summary:
+               //              Set a property on a Stateful instance
+               //      name:
+               //              The property to set. 
+               //      value:
+               //              The value to set in the property.
+               // description:
+               //              Sets named properties on a stateful object and notifies any watchers of 
+               //              the property. A programmatic setter may be defined in subclasses.
+               //              For example:
+               //      |       stateful = new dojo.Stateful();
+               //      |       stateful.watch(function(name, oldValue, value){
+               //      |               // this will be called on the set below
+               //      |       }
+               //      |       stateful.set(foo, 5);
+               //
+               //      set() may also be called with a hash of name/value pairs, ex:
+               //      |       myObj.set({
+               //      |               foo: "Howdy",
+               //      |               bar: 3
+               //      |       })
+               //      This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
+               if(typeof name === "object"){
+                       for(var x in name){
+                               this.set(x, name[x]); 
+                       }
+                       return this;
+               }
+               var oldValue = this[name];
+               this[name] = value;
+               if(this._watchCallbacks){
+                       this._watchCallbacks(name, oldValue, value);
+               }
+               return this;
+       },
+       watch: function(/*String?*/name, /*Function*/callback){
+               // summary:
+               //              Watches a property for changes
+               //      name:
+               //              Indicates the property to watch. This is optional (the callback may be the 
+               //              only parameter), and if omitted, all the properties will be watched
+               // returns:
+               //              An object handle for the watch. The unwatch method of this object 
+               //              can be used to discontinue watching this property:
+               //              |       var watchHandle = obj.watch("foo", callback);
+               //              |       watchHandle.unwatch(); // callback won't be called now
+               //      callback:
+               //              The function to execute when the property changes. This will be called after
+               //              the property has been changed. The callback will be called with the |this|
+               //              set to the instance, the first argument as the name of the property, the 
+               //              second argument as the old value and the third argument as the new value.
+               
+               var callbacks = this._watchCallbacks;
+               if(!callbacks){
+                       var self = this;
+                       callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){
+                               var notify = function(propertyCallbacks){
+                                       for(var i = 0, l = propertyCallbacks && propertyCallbacks.length; i < l; i++){
+                                               try{
+                                                       propertyCallbacks[i].call(self, name, oldValue, value);
+                                               }catch(e){
+                                                       console.error(e);
+                                               }
+                                       }
+                               };
+                               notify(callbacks[name]);
+                               if(!ignoreCatchall){
+                                       notify(callbacks["*"]); // the catch-all
+                               }
+                       }; // we use a function instead of an object so it will be ignored by JSON conversion
+               }
+               if(!callback && typeof name === "function"){
+                       callback = name;
+                       name = "*";
+               }
+               var propertyCallbacks = callbacks[name];
+               if(typeof propertyCallbacks !== "object"){
+                       propertyCallbacks = callbacks[name] = [];
+               }
+               propertyCallbacks.push(callback);
+               return {
+                       unwatch: function(){
+                               propertyCallbacks.splice(dojo.indexOf(propertyCallbacks, callback), 1);
+                       }
+               };
+       }
+       
+});
+
 }