diff options
author | Armen Kesablyan | 2012-06-19 00:45:26 -0700 |
---|---|---|
committer | Armen Kesablyan | 2012-06-19 00:45:26 -0700 |
commit | c59eb371559a3061ce53223e249ca97daace5968 (patch) | |
tree | f9540e26c0f273d35f92010605da65dd85bbe70c /node_modules/montage/core/event/binding.js | |
parent | 0f040acabfb7a4bf3138debec5aff869487ceb11 (diff) | |
parent | 918a4f5870e972b6e4e301c3237e065a1ffd26f5 (diff) | |
download | ninja-c59eb371559a3061ce53223e249ca97daace5968.tar.gz |
Merge branch 'master' of github.com:Motorola-Mobility/ninja-internal
Diffstat (limited to 'node_modules/montage/core/event/binding.js')
-rwxr-xr-x | node_modules/montage/core/event/binding.js | 202 |
1 files changed, 58 insertions, 144 deletions
diff --git a/node_modules/montage/core/event/binding.js b/node_modules/montage/core/event/binding.js index 2e226372..c31ee7f9 100755 --- a/node_modules/montage/core/event/binding.js +++ b/node_modules/montage/core/event/binding.js | |||
@@ -82,91 +82,57 @@ var PropertyChangeBindingListener = exports.PropertyChangeBindingListener = Obje | |||
82 | this.deferredValueTarget = ""; | 82 | this.deferredValueTarget = ""; |
83 | } | 83 | } |
84 | }, | 84 | }, |
85 | handleChange: {value: function(event) { | 85 | handleChange:{ |
86 | var targetPropertyPath = this.targetPropertyPath, | 86 | value:function (notification) { |
87 | target = this.target, | 87 | |
88 | localNewValue = event.plus, | 88 | var bindingOriginTriggeredChange, |
89 | localPrevValue = event.minus, | 89 | // Left |
90 | localTarget = event.target, | 90 | bindingOrigin = this.bindingOrigin, |
91 | boundObjectValue, | 91 | bindingOriginPropertyPath = this.bindingPropertyPath, |
92 | sourceObjectValue, | 92 | bindingOriginValue = bindingOrigin.getProperty(bindingOriginPropertyPath), |
93 | dotIndex, | 93 | // Right |
94 | nextPathComponent, | 94 | boundObject = this.target, |
95 | atSignIndex, | 95 | boundObjectPropertyPath = this.targetPropertyPath, |
96 | baseType, | 96 | boundObjectValue; |
97 | bindingDescriptor, | 97 | |
98 | bindingOrigin = this.bindingOrigin, | 98 | // Determine if binding triggered by change on bindingOrigin |
99 | leftOriginated, | 99 | if (boundObject !== bindingOrigin) { |
100 | changeOriginPropertyPath = null, | 100 | // the origin and bound object are different objects; easy enough |
101 | exploredPath, | 101 | bindingOriginTriggeredChange = notification.currentTarget === bindingOrigin; |
102 | valueChanged; | 102 | } else { |
103 | 103 | // otherwise, if the objects are the same the propertyPaths must differ | |
104 | if (target !== bindingOrigin) { | 104 | bindingOriginTriggeredChange = notification.currentPropertyPath === bindingOriginPropertyPath; |
105 | //the left and the right are different objects; easy enough | 105 | } |
106 | leftOriginated = event.target === bindingOrigin; | ||
107 | } else { | ||
108 | //otherwise, they're the same object; time to try and figure out which "side" the event came from | ||
109 | // TODO this is a very weak check that relies on the bindingOrigin using a property and not a full propertyPath | ||
110 | leftOriginated = event.propertyName === this.bindingPropertyPath; | ||
111 | } | ||
112 | |||
113 | if (leftOriginated) { | ||
114 | // This change event targeted the left side of the binding; try to push to the right side | ||
115 | 106 | ||
116 | if (!bindingOrigin.setProperty.changeEvent) { | 107 | if (bindingOriginTriggeredChange) { |
108 | // This change notification targeted the left side of the binding; try to push to the right side | ||
117 | 109 | ||
118 | sourceObjectValue = localNewValue; | 110 | // If this notification was triggered by the right-to-left value push; don't bother setting |
111 | // the value on the left side, that's where all this value changing started | ||
112 | // (The original right-to-left push installs this changeEvent key on the setProperty function) | ||
113 | if (bindingOrigin.setProperty.changeEvent) { | ||
114 | return; | ||
115 | } | ||
119 | 116 | ||
117 | // TODO should not assume revert is available | ||
120 | if (this.bindingDescriptor.converter) { | 118 | if (this.bindingDescriptor.converter) { |
121 | sourceObjectValue = this.bindingDescriptor.converter.revert(sourceObjectValue); | 119 | bindingOriginValue = this.bindingDescriptor.converter.revert(bindingOriginValue); |
122 | } | 120 | } |
123 | 121 | ||
124 | // If this event was triggered by the right-to-left- value push; don't bother setting | ||
125 | // the value on the left side, that's where all this value changing started | ||
126 | // (The original right-to-left push installs this changeEvent key on the setProperty function) | ||
127 | if (this.bindingOriginValueDeferred === true || bindingOrigin._bindingsDisabled) { | 122 | if (this.bindingOriginValueDeferred === true || bindingOrigin._bindingsDisabled) { |
128 | this.deferredValue = sourceObjectValue; | 123 | this.deferredValue = bindingOriginValue; |
129 | this.deferredValueTarget = "target"; | 124 | this.deferredValueTarget = "target"; |
130 | } else { | 125 | } else { |
131 | this.bindingOriginChangeTriggered = true; | 126 | this.bindingOriginChangeTriggered = true; |
132 | // Set the value on the RIGHT side now | 127 | // Set the value on the RIGHT side now |
133 | this.target.setProperty(this.targetPropertyPath, sourceObjectValue); | 128 | boundObject.setProperty(boundObjectPropertyPath, bindingOriginValue); |
134 | this.bindingOriginChangeTriggered = false; | 129 | this.bindingOriginChangeTriggered = false; |
135 | } | 130 | } |
136 | } | ||
137 | |||
138 | } else if (!this.bindingOriginChangeTriggered) { | ||
139 | |||
140 | // If we're handling the event at this point we know the right side triggered it, from somewhere inside the observed propertyPath | ||
141 | // the event target, which just changed, could be any of the objects along the path, but from here on we want to | ||
142 | // treat the event as "change@fullTargetPropertyPath" so adjust the event we have to reflect that | ||
143 | if (this.target && targetPropertyPath) { | ||
144 | event.target = target; | ||
145 | event.propertyPath = targetPropertyPath; | ||
146 | |||
147 | event.plus = target.getProperty(targetPropertyPath); | ||
148 | |||
149 | // If the newValue and the storedPreviousValue are the same, this was a mutation on that object | ||
150 | // we want to show the prevValue that came along from the event lest we point | ||
151 | // somebody a reference to the same array as the prevValue and newValue | ||
152 | if (!Array.isArray(this.previousTargetPropertyPathValue) && event.plus !== this.previousTargetPropertyPathValue) { | ||
153 | event.minus = this.previousTargetPropertyPathValue; | ||
154 | } | ||
155 | |||
156 | } else { | ||
157 | // TODO I'm not sure when this would happen.. | ||
158 | event.target = this; | ||
159 | } | ||
160 | |||
161 | // The binding listener detected some change along the property path it cared about | ||
162 | // make sure the event we "dispatch" has the full change@propertyPath eventType | ||
163 | event.type = this.targetPropertyPath; | ||
164 | 131 | ||
165 | //For bindings, start the right-to-left value push | 132 | } else if (!this.bindingOriginChangeTriggered) { |
166 | if (event.target === this.target && this.bindingPropertyPath && bindingOrigin) { | ||
167 | //console.log("@ % @ % @ % @ % @ % Binding Worked!!"); | ||
168 | 133 | ||
169 | boundObjectValue = event.plus; | 134 | // Start the right-to-left value push |
135 | boundObjectValue = boundObject.getProperty(boundObjectPropertyPath); | ||
170 | 136 | ||
171 | if (this.bindingDescriptor.boundValueMutator) { | 137 | if (this.bindingDescriptor.boundValueMutator) { |
172 | boundObjectValue = this.bindingDescriptor.boundValueMutator(boundObjectValue); | 138 | boundObjectValue = this.bindingDescriptor.boundValueMutator(boundObjectValue); |
@@ -174,75 +140,23 @@ var PropertyChangeBindingListener = exports.PropertyChangeBindingListener = Obje | |||
174 | boundObjectValue = this.bindingDescriptor.converter.convert(boundObjectValue); | 140 | boundObjectValue = this.bindingDescriptor.converter.convert(boundObjectValue); |
175 | } | 141 | } |
176 | 142 | ||
177 | // If the the value about to be pushed over to the bindingOrigin is already there don't call the setter | 143 | if (boundObjectValue !== bindingOriginValue) { |
178 | valueChanged = boundObjectValue !== event.plus ? | ||
179 | (this.bindingOrigin.getProperty(this.bindingPropertyPath) !== boundObjectValue) : true; | ||
180 | |||
181 | if (valueChanged) { | ||
182 | if (this.bindingOriginValueDeferred === true || bindingOrigin._bindingsDisabled) { | 144 | if (this.bindingOriginValueDeferred === true || bindingOrigin._bindingsDisabled) { |
183 | this.deferredValue = boundObjectValue; | 145 | this.deferredValue = boundObjectValue; |
184 | this.deferredValueTarget = "bound"; | 146 | this.deferredValueTarget = "bound"; |
185 | } else { | 147 | } else { |
186 | // Make the original event available to the setter | 148 | // Make the original notification available to the setter |
187 | this.bindingOrigin.setProperty.changeEvent = event; | 149 | bindingOrigin.setProperty.changeEvent = notification; |
188 | // Set the value on the LEFT side now | 150 | // Set the value on the LEFT side now |
189 | this.bindingOrigin.setProperty(this.bindingPropertyPath, boundObjectValue); | 151 | bindingOrigin.setProperty(bindingOriginPropertyPath, boundObjectValue); |
190 | this.bindingOrigin.setProperty.changeEvent = null; | 152 | bindingOrigin.setProperty.changeEvent = null; |
191 | } | 153 | } |
192 | } | 154 | } |
193 | } | ||
194 | // Otherwise, there was probably a listener for a change at this path that was not a part of some binding | ||
195 | // so distribute the event to the original listener | ||
196 | // TODO this is not as full featured as the EventManager event distribution so it may differ, which is bad | ||
197 | else if (this.originalListener) { | ||
198 | if (this.originalListenerIsFunction) { | ||
199 | this.originalListener.call(this.target, event); | ||
200 | } else { | ||
201 | this.originalListener.handleEvent(event); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | // Update the stored value of the propertyPath | ||
206 | this.previousTargetPropertyPathValue = event.plus; | ||
207 | |||
208 | // TODO I'm not exactly sure why this happens here, or really why it does in general | ||
209 | event.minus = localPrevValue; | ||
210 | event.plus = localNewValue; | ||
211 | event.target = localTarget; | ||
212 | 155 | ||
213 | if (localPrevValue) { | 156 | // Update the stored value of the propertyPath |
214 | 157 | this.previousTargetPropertyPathValue = boundObjectValue; | |
215 | // Determine where along the property path the change originated from so we know how to build the path | ||
216 | // to stop observing on things that were removed | ||
217 | //TODO extract this into a "obj.getPathOfObjectAlongPropertyPath" method or something with proper tests | ||
218 | exploredPath = ""; | ||
219 | this.target.getProperty(this.targetPropertyPath, null, null, function(value, currentPathComponent, result) { | ||
220 | |||
221 | if (changeOriginPropertyPath) { | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | exploredPath += "." + currentPathComponent; | ||
226 | |||
227 | if (result === event.target) { | ||
228 | changeOriginPropertyPath = exploredPath.replace(/^\./, ""); | ||
229 | } | ||
230 | }); | ||
231 | } | 158 | } |
232 | } | 159 | } |
233 | |||
234 | targetPropertyPath = null; | ||
235 | <