diff options
author | Andrew Dolgov <[email protected]> | 2011-03-04 19:02:28 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2011-03-04 19:02:59 +0300 |
commit | a089699c8915636ba4f158d77dba9b012bc93208 (patch) | |
tree | b2d7d051f1f55d44a6be07d3ee137e5a7ccfcefb /lib/dojo/Stateful.js | |
parent | cfad9259a6feacfa8194b1312770ae6db1ecce50 (diff) |
build custom layer of Dojo to speed up loading of tt-rss (refs #293)
Diffstat (limited to 'lib/dojo/Stateful.js')
-rw-r--r-- | lib/dojo/Stateful.js | 180 |
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); + } + }; + } + +}); + } |