]> git.wh0rd.org - tt-rss.git/blame - lib/dojo/Stateful.js
upgrade Dojo to 1.6.1
[tt-rss.git] / lib / dojo / Stateful.js
CommitLineData
2f01fe57 1/*
81bea17a 2 Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
2f01fe57
AD
3 Available via Academic Free License >= 2.1 OR the modified BSD license.
4 see: http://dojotoolkit.org/license for details
5*/
6
7
a089699c
AD
8if(!dojo._hasResource["dojo.Stateful"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
9dojo._hasResource["dojo.Stateful"] = true;
2f01fe57 10dojo.provide("dojo.Stateful");
a089699c 11
81bea17a 12
a089699c
AD
13dojo.declare("dojo.Stateful", null, {
14 // summary:
15 // Base class for objects that provide named properties with optional getter/setter
16 // control and the ability to watch for property changes
17 // example:
18 // | var obj = new dojo.Stateful();
19 // | obj.watch("foo", function(){
20 // | console.log("foo changed to " + this.get("foo"));
21 // | });
22 // | obj.set("foo","bar");
23 postscript: function(mixin){
24 if(mixin){
25 dojo.mixin(this, mixin);
26 }
27 },
28
29 get: function(/*String*/name){
30 // summary:
31 // Get a property on a Stateful instance.
32 // name:
33 // The property to get.
34 // description:
35 // Get a named property on a Stateful object. The property may
36 // potentially be retrieved via a getter method in subclasses. In the base class
81bea17a 37 // this just retrieves the object's property.
a089699c
AD
38 // For example:
39 // | stateful = new dojo.Stateful({foo: 3});
40 // | stateful.get("foo") // returns 3
41 // | stateful.foo // returns 3
42
43 return this[name];
44 },
45 set: function(/*String*/name, /*Object*/value){
46 // summary:
47 // Set a property on a Stateful instance
48 // name:
81bea17a 49 // The property to set.
a089699c
AD
50 // value:
51 // The value to set in the property.
52 // description:
81bea17a 53 // Sets named properties on a stateful object and notifies any watchers of
a089699c
AD
54 // the property. A programmatic setter may be defined in subclasses.
55 // For example:
56 // | stateful = new dojo.Stateful();
57 // | stateful.watch(function(name, oldValue, value){
58 // | // this will be called on the set below
59 // | }
60 // | stateful.set(foo, 5);
61 //
62 // set() may also be called with a hash of name/value pairs, ex:
63 // | myObj.set({
64 // | foo: "Howdy",
65 // | bar: 3
66 // | })
67 // This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
68 if(typeof name === "object"){
69 for(var x in name){
81bea17a 70 this.set(x, name[x]);
a089699c
AD
71 }
72 return this;
73 }
74 var oldValue = this[name];
75 this[name] = value;
76 if(this._watchCallbacks){
77 this._watchCallbacks(name, oldValue, value);
78 }
79 return this;
80 },
81 watch: function(/*String?*/name, /*Function*/callback){
82 // summary:
83 // Watches a property for changes
84 // name:
81bea17a 85 // Indicates the property to watch. This is optional (the callback may be the
a089699c
AD
86 // only parameter), and if omitted, all the properties will be watched
87 // returns:
81bea17a 88 // An object handle for the watch. The unwatch method of this object
a089699c
AD
89 // can be used to discontinue watching this property:
90 // | var watchHandle = obj.watch("foo", callback);
91 // | watchHandle.unwatch(); // callback won't be called now
92 // callback:
93 // The function to execute when the property changes. This will be called after
94 // the property has been changed. The callback will be called with the |this|
81bea17a 95 // set to the instance, the first argument as the name of the property, the
a089699c
AD
96 // second argument as the old value and the third argument as the new value.
97
98 var callbacks = this._watchCallbacks;
99 if(!callbacks){
100 var self = this;
101 callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){
102 var notify = function(propertyCallbacks){
81bea17a
AD
103 if(propertyCallbacks){
104 propertyCallbacks = propertyCallbacks.slice();
105 for(var i = 0, l = propertyCallbacks.length; i < l; i++){
106 try{
107 propertyCallbacks[i].call(self, name, oldValue, value);
108 }catch(e){
109 console.error(e);
110 }
a089699c
AD
111 }
112 }
113 };
81bea17a 114 notify(callbacks['_' + name]);
a089699c
AD
115 if(!ignoreCatchall){
116 notify(callbacks["*"]); // the catch-all
117 }
118 }; // we use a function instead of an object so it will be ignored by JSON conversion
119 }
120 if(!callback && typeof name === "function"){
121 callback = name;
122 name = "*";
81bea17a
AD
123 }else{
124 // prepend with dash to prevent name conflicts with function (like "name" property)
125 name = '_' + name;
a089699c
AD
126 }
127 var propertyCallbacks = callbacks[name];
128 if(typeof propertyCallbacks !== "object"){
129 propertyCallbacks = callbacks[name] = [];
130 }
131 propertyCallbacks.push(callback);
132 return {
133 unwatch: function(){
134 propertyCallbacks.splice(dojo.indexOf(propertyCallbacks, callback), 1);
135 }
136 };
137 }
138
139});
140
2f01fe57 141}