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.js82
1 files changed, 62 insertions, 20 deletions
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, {
205 dependentDescriptorsIndex: {value: null}, 205 dependentDescriptorsIndex: {value: null},
206 mutationDependencyIndex: {value: null}, 206 mutationDependencyIndex: {value: null},
207 mutationListenersCount: {value: 0}, 207 mutationListenersCount: {value: 0},
208 observedDependentProperties: {value: null},
208 209
209 initWithTargetPath: { 210 initWithTargetPath: {
210 value: function(target, path) { 211 value: function(target, path) {
@@ -216,7 +217,8 @@ var ChangeNotificationDescriptor = Montage.create(Montage, {
216 }, 217 },
217 registerListener: { 218 registerListener: {
218 value: function(listener, beforeChange, mutation) { 219 value: function(listener, beforeChange, mutation) {
219 var listenerKey = listener.uuid; 220 var listenerKey = listener.uuid,
221 listeners;
220 222
221 if (beforeChange) { 223 if (beforeChange) {
222 listeners = this.willChangeListeners; 224 listeners = this.willChangeListeners;
@@ -247,7 +249,8 @@ var ChangeNotificationDescriptor = Montage.create(Montage, {
247 }, 249 },
248 unregisterListener: { 250 unregisterListener: {
249 value: function(listener, beforeChange) { 251 value: function(listener, beforeChange) {
250 var listenerKey = listener.uuid; 252 var listenerKey = listener.uuid,
253 listeners;
251 254
252 if (beforeChange) { 255 if (beforeChange) {
253 listeners = this.willChangeListeners; 256 listeners = this.willChangeListeners;
@@ -533,7 +536,14 @@ var ChangeNotificationDescriptor = Montage.create(Montage, {
533 var listener, 536 var listener,
534 dependentDescriptorsIndex = this.dependentDescriptorsIndex, 537 dependentDescriptorsIndex = this.dependentDescriptorsIndex,
535 dependenciesIndex = notification._dependenciesIndex, 538 dependenciesIndex = notification._dependenciesIndex,
536 isMutationNotification; 539 isMutationNotification,
540 uuid = this.uuid;
541
542 // we need to stop circular property dependencies.
543 // e.g.: object.foo depends on object.bar and object.bar depends on object.foo.
544 if (notification[uuid]) {
545 return;
546 }
537 547
538 // TODO: maybe I should replicate this 548 // TODO: maybe I should replicate this
539 if (arguments.length < 2) { 549 if (arguments.length < 2) {
@@ -563,7 +573,9 @@ var ChangeNotificationDescriptor = Montage.create(Montage, {
563 if (dependentDescriptorsIndex) { 573 if (dependentDescriptorsIndex) {
564 notification._dependenciesIndex = dependentDescriptorsIndex[key]; 574 notification._dependenciesIndex = dependentDescriptorsIndex[key];
565 } 575 }
576 notification[uuid] = true;
566 listener.listenerFunction.call(listener.listenerTarget, notification); 577 listener.listenerFunction.call(listener.listenerTarget, notification);
578 notification[uuid] = false;
567 } 579 }
568 } 580 }
569 notification._dependenciesIndex = dependenciesIndex; 581 notification._dependenciesIndex = dependenciesIndex;
@@ -681,12 +693,14 @@ var ObjectPropertyChangeDispatcherManager = Object.create(null, {
681 notification; 693 notification;
682 694
683 if (!descriptor) { 695 if (!descriptor) {
696 originalSetter.apply(this, arguments);
684 return; 697 return;
685 } 698 }
686 699
687 previousValue = this[propertyName]; 700 previousValue = this[propertyName];
688 if (previousValue === value) { 701 if (previousValue === value) {
689 // Nothing to do here 702 originalSetter.apply(this, arguments);
703 // Nothing more to do here
690 return; 704 return;
691 } 705 }
692 706
@@ -756,12 +770,13 @@ Object.defineProperty(Object.prototype, "dispatchPropertyChange", {
756 for (i = 0; i < callbackArgumentIndex; i++) { 770 for (i = 0; i < callbackArgumentIndex; i++) {
757 iProperty = arguments[i]; 771 iProperty = arguments[i];
758 descriptor = ChangeNotification.getPropertyChangeDescriptor(this, iProperty); 772 descriptor = ChangeNotification.getPropertyChangeDescriptor(this, iProperty);
759 if (descriptor) { 773 if (descriptor && !descriptor.isActive) {
760 notification = Object.create(PropertyChangeNotification); 774 notification = Object.create(PropertyChangeNotification);
761 observedProperties.push(iProperty, descriptor, notification); 775 observedProperties.push(iProperty, descriptor, notification);
762 776
763 notification.target = this; 777 notification.target = this;
764 notification.minus = this.getProperty(iProperty); 778 notification.minus = this.getProperty(iProperty);
779 descriptor.isActive = true;
765 descriptor.handleWillChange(notification); 780 descriptor.handleWillChange(notification);
766 } 781 }
767 } 782 }
@@ -775,6 +790,7 @@ Object.defineProperty(Object.prototype, "dispatchPropertyChange", {
775 790
776 notification.plus = this.getProperty(iProperty); 791 notification.plus = this.getProperty(iProperty);
777 descriptor.handleChange(notification); 792 descriptor.handleChange(notification);
793 descriptor.isActive = false;
778 } 794 }
779 795
780 } 796 }
@@ -818,9 +834,19 @@ Object.defineProperty(Object.prototype, "addPropertyChangeListener", {
818 // TODO should adding a dispatcher on a dependent property also be subjected to checking for 834 // TODO should adding a dispatcher on a dependent property also be subjected to checking for
819 // automaticDispatchPropertyChangeListener, probably 835 // automaticDispatchPropertyChangeListener, probably
820 if (dependentPropertyPaths) { 836 if (dependentPropertyPaths) {
837
838 if (!descriptor.observedDependentProperties) {
839 descriptor.observedDependentProperties = {};
840 }
841
821 for (i = 0; (iPath = dependentPropertyPaths[i]); i++) { 842 for (i = 0; (iPath = dependentPropertyPaths[i]); i++) {
822 this.addPropertyChangeListener(iPath, descriptor, beforeChange, false); 843
823 descriptor.registerDependency(this, iPath, null); 844 if (!descriptor.observedDependentProperties[iPath]) {
845 descriptor.observedDependentProperties[iPath] = true;
846
847 this.addPropertyChangeListener(iPath, descriptor, beforeChange, false);
848 descriptor.registerDependency(this, iPath, null);
849 }
824 } 850 }
825 } 851 }
826 } 852 }
@@ -861,16 +887,16 @@ var PrefixedPropertyDescriptor = {
861 configurable: true 887 configurable: true
862}; 888};
863 889
864var PropertyChangeNotification = exports.PropertyChangeNotification = Object.create(null, { 890var PropertyChangeNotification = exports.PropertyChangeNotification = {
865 phase: {writable: true, value: null}, 891 phase: null,
866 target: {writable: true, value: null}, 892 target: null,
867 propertyPath: {writable: true, value: null}, 893 propertyPath: null,
868 minus: {writable: true, value: null}, 894 minus: null,
869 plus: {writable: true, value: null}, 895 plus: null,
870 currentTarget: {writable: true, value: null}, 896 currentTarget: null,
871 currentPropertyPath: {writable: true, value: null}, 897 currentPropertyPath: null,
872 isMutation: {writable: true, value: false} 898 isMutation: false
873}); 899};
874 900
875var ChangeNotificationDispatchingArray = exports.ChangeNotificationDispatchingArray = []; 901var ChangeNotificationDispatchingArray = exports.ChangeNotificationDispatchingArray = [];
876var _index_array_regexp = /^[0-9]+$/; 902var _index_array_regexp = /^[0-9]+$/;
@@ -878,13 +904,15 @@ var _unobservable_array_property_regexp = /^length$/;
878Object.defineProperty(Array.prototype, "addPropertyChangeListener", { 904Object.defineProperty(Array.prototype, "addPropertyChangeListener", {
879 value: function(path, listener, beforeChange, ignoreMutation) { 905 value: function(path, listener, beforeChange, ignoreMutation) {
880 var listenChange, listenIndexChange, listenFunctionChange, 906 var listenChange, listenIndexChange, listenFunctionChange,
881 descriptor; 907 descriptor,
908 dotIndex;
882 909
883 if (!listener) { 910 if (!listener) {
884 return; 911 return;
885 } 912 }
886 913
887 if (path == null || path.indexOf(".") == -1) { 914 if (path == null || (dotIndex = path.indexOf(".")) == -1) {
915
888 916
889 if (_unobservable_array_property_regexp.test(path)) { 917 if (_unobservable_array_property_regexp.test(path)) {
890 return; 918 return;
@@ -909,6 +937,12 @@ Object.defineProperty(Array.prototype, "addPropertyChangeListener", {
909 } 937 }
910 } else { 938 } else {
911 Object.prototype.addPropertyChangeListener.apply(this, arguments); 939 Object.prototype.addPropertyChangeListener.apply(this, arguments);
940 // We need to do this because the Object.prototype.addPropertyChangeListener doesn't create dependencies
941 // for no-dot paths, but in array array.path will have dependencies when path is not an index or null.
942 if (dotIndex == -1) {
943 descriptor = ChangeNotification.getPropertyChangeDescriptor(this, path);
944 descriptor.setupDependencies(this, path, beforeChange, !ignoreMutation);
945 }
912 } 946 }
913 } 947 }
914}); 948});
@@ -918,6 +952,7 @@ Object.defineProperty(ChangeNotificationDispatchingArray, "_dispatchArrayChangeN
918 configurable: false, 952 configurable: false,
919 value: function(methodName, methodArguments, index, howManyToRemove, newValues) { 953 value: function(methodName, methodArguments, index, howManyToRemove, newValues) {
920 var descriptor = ChangeNotification.getPropertyChangeDescriptor(this, null), 954 var descriptor = ChangeNotification.getPropertyChangeDescriptor(this, null),