From f7e4257745ccd44b8d24555f0ef787429d6e472c Mon Sep 17 00:00:00 2001 From: Valerio Virgillito Date: Tue, 5 Jun 2012 00:11:03 -0700 Subject: adding the latest v0.10 montage Signed-off-by: Valerio Virgillito --- node_modules/montage/core/change-notification.js | 82 ++++++++++++++++++------ 1 file changed, 62 insertions(+), 20 deletions(-) (limited to 'node_modules/montage/core/change-notification.js') diff --git a/node_modules/montage/core/change-notification.js b/node_modules/montage/core/change-notification.js index bfe5ff2d..3f6d884e 100644 --- a/node_modules/montage/core/change-notification.js +++ b/node_modules/montage/core/change-notification.js @@ -205,6 +205,7 @@ var ChangeNotificationDescriptor = Montage.create(Montage, { dependentDescriptorsIndex: {value: null}, mutationDependencyIndex: {value: null}, mutationListenersCount: {value: 0}, + observedDependentProperties: {value: null}, initWithTargetPath: { value: function(target, path) { @@ -216,7 +217,8 @@ var ChangeNotificationDescriptor = Montage.create(Montage, { }, registerListener: { value: function(listener, beforeChange, mutation) { - var listenerKey = listener.uuid; + var listenerKey = listener.uuid, + listeners; if (beforeChange) { listeners = this.willChangeListeners; @@ -247,7 +249,8 @@ var ChangeNotificationDescriptor = Montage.create(Montage, { }, unregisterListener: { value: function(listener, beforeChange) { - var listenerKey = listener.uuid; + var listenerKey = listener.uuid, + listeners; if (beforeChange) { listeners = this.willChangeListeners; @@ -533,7 +536,14 @@ var ChangeNotificationDescriptor = Montage.create(Montage, { var listener, dependentDescriptorsIndex = this.dependentDescriptorsIndex, dependenciesIndex = notification._dependenciesIndex, - isMutationNotification; + isMutationNotification, + uuid = this.uuid; + + // we need to stop circular property dependencies. + // e.g.: object.foo depends on object.bar and object.bar depends on object.foo. + if (notification[uuid]) { + return; + } // TODO: maybe I should replicate this if (arguments.length < 2) { @@ -563,7 +573,9 @@ var ChangeNotificationDescriptor = Montage.create(Montage, { if (dependentDescriptorsIndex) { notification._dependenciesIndex = dependentDescriptorsIndex[key]; } + notification[uuid] = true; listener.listenerFunction.call(listener.listenerTarget, notification); + notification[uuid] = false; } } notification._dependenciesIndex = dependenciesIndex; @@ -681,12 +693,14 @@ var ObjectPropertyChangeDispatcherManager = Object.create(null, { notification; if (!descriptor) { + originalSetter.apply(this, arguments); return; } previousValue = this[propertyName]; if (previousValue === value) { - // Nothing to do here + originalSetter.apply(this, arguments); + // Nothing more to do here return; } @@ -756,12 +770,13 @@ Object.defineProperty(Object.prototype, "dispatchPropertyChange", { for (i = 0; i < callbackArgumentIndex; i++) { iProperty = arguments[i]; descriptor = ChangeNotification.getPropertyChangeDescriptor(this, iProperty); - if (descriptor) { + if (descriptor && !descriptor.isActive) { notification = Object.create(PropertyChangeNotification); observedProperties.push(iProperty, descriptor, notification); notification.target = this; notification.minus = this.getProperty(iProperty); + descriptor.isActive = true; descriptor.handleWillChange(notification); } } @@ -775,6 +790,7 @@ Object.defineProperty(Object.prototype, "dispatchPropertyChange", { notification.plus = this.getProperty(iProperty); descriptor.handleChange(notification); + descriptor.isActive = false; } } @@ -818,9 +834,19 @@ Object.defineProperty(Object.prototype, "addPropertyChangeListener", { // TODO should adding a dispatcher on a dependent property also be subjected to checking for // automaticDispatchPropertyChangeListener, probably if (dependentPropertyPaths) { + + if (!descriptor.observedDependentProperties) { + descriptor.observedDependentProperties = {}; + } + for (i = 0; (iPath = dependentPropertyPaths[i]); i++) { - this.addPropertyChangeListener(iPath, descriptor, beforeChange, false); - descriptor.registerDependency(this, iPath, null); + + if (!descriptor.observedDependentProperties[iPath]) { + descriptor.observedDependentProperties[iPath] = true; + + this.addPropertyChangeListener(iPath, descriptor, beforeChange, false); + descriptor.registerDependency(this, iPath, null); + } } } } @@ -861,16 +887,16 @@ var PrefixedPropertyDescriptor = { configurable: true }; -var PropertyChangeNotification = exports.PropertyChangeNotification = Object.create(null, { - phase: {writable: true, value: null}, - target: {writable: true, value: null}, - propertyPath: {writable: true, value: null}, - minus: {writable: true, value: null}, - plus: {writable: true, value: null}, - currentTarget: {writable: true, value: null}, - currentPropertyPath: {writable: true, value: null}, - isMutation: {writable: true, value: false} -}); +var PropertyChangeNotification = exports.PropertyChangeNotification = { + phase: null, + target: null, + propertyPath: null, + minus: null, + plus: null, + currentTarget: null, + currentPropertyPath: null, + isMutation: false +}; var ChangeNotificationDispatchingArray = exports.ChangeNotificationDispatchingArray = []; var _index_array_regexp = /^[0-9]+$/; @@ -878,13 +904,15 @@ var _unobservable_array_property_regexp = /^length$/; Object.defineProperty(Array.prototype, "addPropertyChangeListener", { value: function(path, listener, beforeChange, ignoreMutation) { var listenChange, listenIndexChange, listenFunctionChange, - descriptor; + descriptor, + dotIndex; if (!listener) { return; } - if (path == null || path.indexOf(".") == -1) { + if (path == null || (dotIndex = path.indexOf(".")) == -1) { + if (_unobservable_array_property_regexp.test(path)) { return; @@ -909,6 +937,12 @@ Object.defineProperty(Array.prototype, "addPropertyChangeListener", { } } else { Object.prototype.addPropertyChangeListener.apply(this, arguments); + // We need to do this because the Object.prototype.addPropertyChangeListener doesn't create dependencies + // for no-dot paths, but in array array.path will have dependencies when path is not an index or null. + if (dotIndex == -1) { + descriptor = ChangeNotification.getPropertyChangeDescriptor(this, path); + descriptor.setupDependencies(this, path, beforeChange, !ignoreMutation); + } } } }); @@ -918,6 +952,7 @@ Object.defineProperty(ChangeNotificationDispatchingArray, "_dispatchArrayChangeN configurable: false, value: function(methodName, methodArguments, index, howManyToRemove, newValues) { var descriptor = ChangeNotification.getPropertyChangeDescriptor(this, null), + result, notification, indexNotification = Object.create(PropertyChangeNotification), delta, @@ -1235,6 +1270,7 @@ Object.defineProperty(ChangeNotificationDispatchingArray, "sort", { indexNotification, oldValue, newValue, + indexArray, _sortIndexArray, _sortIndexArrayLength; @@ -1340,6 +1376,7 @@ Object.defineProperty(Object.prototype, "__debugChangeNotifications__", { configurable: false, value: function() { var registry = ChangeNotification._descriptorsRegistry[this.uuid], + path, log = []; if (registry) { @@ -1367,7 +1404,12 @@ Object.defineProperty(Object.prototype, "__debugChangeNotifications__", { var listenerFunctionName = changeListeners[key].listenerFunctionName; var info = Montage.getInfoForObject(listenerTarget); if (info.objectName === "PropertyChangeBindingListener") { - bindings.push("\"" + listenerTarget.bindingPropertyPath + "\" @ " + Montage.getInfoForObject(listenerTarget.bindingOrigin).objectName + "(", listenerTarget.bindingOrigin, ")"); + if (listenerTarget.bindingOrigin === this && listenerTarget.bindingPropertyPath === path) { + bindings.push("\"" + listenerTarget.targetPropertyPath + "\" @ " + (Montage.getInfoForObject(listenerTarget.target).objectName || "") + "(", listenerTarget.target, ")"); + } else { + bindings.push("\"" + listenerTarget.bindingPropertyPath + "\" @ " + (Montage.getInfoForObject(listenerTarget.bindingOrigin).objectName || "") + "(", listenerTarget.bindingOrigin, ")"); + } + bindings.push("\n\t "); } } -- cgit v1.2.3