aboutsummaryrefslogtreecommitdiff
path: root/node_modules/montage/core/change-notification.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/montage/core/change-notification.js')
-rw-r--r--node_modules/montage/core/change-notification.js1418
1 files changed, 1418 insertions, 0 deletions
diff --git a/node_modules/montage/core/change-notification.js b/node_modules/montage/core/change-notification.js
new file mode 100644
index 00000000..bfe5ff2d
--- /dev/null
+++ b/node_modules/montage/core/change-notification.js
@@ -0,0 +1,1418 @@
1/* <copyright>
2 This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
3 No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
4 (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
5 </copyright> */
6
7/**
8 @module montage/core/event/change-notification
9*/
10
11var Montage = require("montage").Montage,
12 logger = require("core/logger").logger("change-notification"),
13 UNDERSCORE = "_";
14
15// key: <path>, <target uuid>, <listener uuid>
16var _descriptorsDirectory = Object.create(null);
17
18// key: <target uuid>, <path>
19var _willChangeDescriptorsDirectory = Object.create(null);
20var _willChangeDescriptorsIndexesDirectory = Object.create(null);
21var _changeDescriptorsDirectory = Object.create(null);
22var _changeDescriptorsIndexesDirectory = Object.create(null);
23
24exports.__reset__ = function() {
25 _descriptorsDirectory = Object.create(null);
26 _willChangeDescriptorsDirectory = Object.create(null);
27 _willChangeDescriptorsIndexesDirectory = Object.create(null);
28 _changeDescriptorsDirectory = Object.create(null);
29 _changeDescriptorsIndexesDirectory = Object.create(null);
30 // also need to remove all installed setters
31};
32
33exports.__debug__ = function() {
34 console.log("_descriptorsDirectory", _descriptorsDirectory);
35 console.log("_willChangeDescriptorsDirectory", _willChangeDescriptorsDirectory, _willChangeDescriptorsIndexesDirectory);
36 console.log("_changeDescriptorsDirectory", _changeDescriptorsDirectory, _changeDescriptorsIndexesDirectory);
37};
38
39var ChangeNotification = exports.ChangeNotification = Object.create(Montage, {
40 // (object) => <object>.uuid
41 //
42 // (target_n): {
43 // <propertyPath_n>: {
44 // target,
45 // propertyPath,
46 // willChangeListeners: {
47 // (listener_n): {
48 // listenerTarget,
49 // listenerFunction,
50 // listensToMutation
51 // }
52 // },
53 // changeListeners: same as willChangeListeners,
54 // willChangeListenersCount: Object.keys(willChangeListeners).length,
55 // changeListenersCount: Object.keys(changeListeners).length,
56 // handleWillChange: function()
57 // handleChange: function()
58 // }
59 // }
60 _descriptorsRegistry: {
61 writable: true,
62 value: Object.create(null)
63 },
64
65 _createFunctionDescriptor: {
66 value: function(target, listener, beforeChange, mutation) {
67 var identifier,
68 functionName,
69 functionDescriptor = Object.create(ChangeNotificationFunctionDescriptor);
70
71 if (typeof listener === "function") {
72 functionDescriptor.listenerFunction = listener;
73 functionDescriptor.listenerTarget = target;
74 } else {
75 identifier = target.identifier;
76
77 if (identifier) {
78 identifier = identifier.toCapitalized();
79
80 functionName = "handle" + identifier + (beforeChange ? "WillChange" : "Change");
81 if (typeof listener[functionName] === "function") {
82 functionDescriptor.listenerFunctionName = functionName;
83 functionDescriptor.listenerFunction = listener[functionName];
84 functionDescriptor.listenerTarget = listener;
85 }
86 }
87
88 if (!functionDescriptor.listenerFunction) {
89 functionName = "handle" + (beforeChange ? "WillChange" : "Change");
90 if (typeof listener[functionName] === "function") {
91 functionDescriptor.listenerFunctionName = functionName;
92 functionDescriptor.listenerFunction = listener[functionName];
93 functionDescriptor.listenerTarget = listener;
94 }
95 }
96 }
97
98 if (!functionDescriptor.listenerFunction) {
99 console.log("Could not find valid listener when installing", target, listener);
100 throw "Could not find valid listener when installing";
101 }
102
103 functionDescriptor.listensToMutation = mutation;
104 return functionDescriptor;
105 }
106 },
107
108 registerPropertyChangeListener: {
109 value: function(target, path, listener, beforeChange, mutation) {
110 var targetKey = target.uuid,
111 registry = this._descriptorsRegistry,
112 targetEntry = registry[targetKey],
113 descriptor;
114
115 if (path == null) {
116 path = "*";
117 mutation = true;
118 }
119
120 if (!targetEntry) {
121 targetEntry = registry[targetKey] = Object.create(null);
122 targetEntry.propertyPathCount = 0;
123 }
124
125 descriptor = targetEntry[path];
126 if (!descriptor) {
127 descriptor = targetEntry[path] = Object.create(ChangeNotificationDescriptor).initWithTargetPath(target, path);
128 targetEntry.propertyPathCount++;
129 }
130 descriptor.registerListener(listener, beforeChange, mutation);
131
132 return descriptor;
133 }
134 },
135
136 unregisterPropertyChangeListener: {
137 value: function(target, path, listener, beforeChange) {
138 var targetKey = target.uuid,
139 registry = this._descriptorsRegistry,
140 targetEntry = registry[targetKey],
141 descriptor;
142
143 if (path == null) {
144 path = "*";
145 }
146
147 if (targetEntry) {
148 descriptor = targetEntry[path];
149 if (descriptor) {
150 // TODO: should this function return the number of listeners?
151 descriptor.unregisterListener(listener, beforeChange);
152 if (descriptor.willChangeListenersCount === 0 &&
153 descriptor.changeListenersCount === 0) {
154 delete targetEntry[path];
155 if (--targetEntry.propertyPathCount === 0) {
156 delete registry[targetKey];
157 }
158 }
159 }
160 }
161 }
162 },
163
164 getPropertyChangeDescriptor: {
165 value: function(target, path) {
166 var targetEntry = this._descriptorsRegistry[target.uuid];
167
168 if (targetEntry) {
169 if (path == null) {
170 path = "*";
171 }
172 return targetEntry[path];
173 }
174 }
175 },
176
177 __debug__: {
178 value: function() {
179 console.log("_descriptorsRegistry: ", this._descriptorsRegistry);
180 }
181 },
182
183 __reset__: {
184 value: function() {
185 this._descriptorsRegistry = Object.create(null);
186 }
187 }
188});
189
190var ChangeNotificationDescriptor = Montage.create(Montage, {
191 target: {value: null},
192 propertyPath: {value: null},
193 willChangeListeners: {value: null},
194 changeListeners: {value: null},
195 willChangeListenersCount: {value: 0},
196 changeListenersCount: {value: 0},
197 isActive: {value: false},
198 // list of all objects that this listener needed to start listening to.
199 // these are the objects in the target.getProperty(path).
200 // format [(target, propertyName, remainingPath)*]
201 dependencies: {value: null},
202 hasWillChangeDependencies: {value: false},
203 hasChangeDependencies: {value: false},
204 // index of where this listener is expected to be in its dependent listeners
205 dependentDescriptorsIndex: {value: null},
206 mutationDependencyIndex: {value: null},
207 mutationListenersCount: {value: 0},
208
209 initWithTargetPath: {
210 value: function(target, path) {
211 this.target = target;
212 this.propertyPath = path;
213
214 return this;
215 }
216 },
217 registerListener: {
218 value: function(listener, beforeChange, mutation) {
219 var listenerKey = listener.uuid;
220
221 if (beforeChange) {
222 listeners = this.willChangeListeners;