summaryrefslogtreecommitdiff
path: root/lib/dojo/Stateful.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dojo/Stateful.js')
-rw-r--r--lib/dojo/Stateful.js180
1 files changed, 125 insertions, 55 deletions
diff --git a/lib/dojo/Stateful.js b/lib/dojo/Stateful.js
index 136b319c7..e4f406309 100644
--- a/lib/dojo/Stateful.js
+++ b/lib/dojo/Stateful.js
@@ -5,60 +5,130 @@
*/
-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);
+ }
+ };
+ }
+
+});
+
}