| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 | define("dojo/Stateful", ["./_base/declare", "./_base/lang", "./_base/array"], function(declare, lang, array) {	// module:	//		dojo/Stateful	// summary:	//		TODOCreturn 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){			lang.mixin(this, mixin);		}	},	get: function(/*String*/name){		// summary:		//		Get a property on a Stateful instance.		//	name:		//		The property to get.		//	returns:		//		The property value on this Stateful instance.		// 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]; //Any	},	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.		//	returns:		//		The function returns this dojo.Stateful instance.		// 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){				if(name.hasOwnProperty(x) && x !="_watchCallbacks"){					this.set(x, name[x]);				}			}			return this;		}		var oldValue = this[name];		this[name] = value;		if(this._watchCallbacks){			this._watchCallbacks(name, oldValue, value);		}		return this; //dojo.Stateful	},	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){					if(propertyCallbacks){						propertyCallbacks = propertyCallbacks.slice();						for(var i = 0, l = propertyCallbacks.length; i < l; i++){							propertyCallbacks[i].call(self, name, oldValue, value);						}					}				};				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 = "*";		}else{			// prepend with dash to prevent name conflicts with function (like "name" property)			name = '_' + name;		}		var propertyCallbacks = callbacks[name];		if(typeof propertyCallbacks !== "object"){			propertyCallbacks = callbacks[name] = [];		}		propertyCallbacks.push(callback);		return {			unwatch: function(){				propertyCallbacks.splice(array.indexOf(propertyCallbacks, callback), 1);			}		}; //Object	}});});
 |