aboutsummaryrefslogtreecommitdiff
path: root/node_modules/montage/core/event/binding.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/montage/core/event/binding.js')
-rwxr-xr-xnode_modules/montage/core/event/binding.js93
1 files changed, 50 insertions, 43 deletions
diff --git a/node_modules/montage/core/event/binding.js b/node_modules/montage/core/event/binding.js
index 0ce154a1..7a15e5b9 100755
--- a/node_modules/montage/core/event/binding.js
+++ b/node_modules/montage/core/event/binding.js
@@ -88,10 +88,19 @@ Object.defineProperty(ChangeEventDispatchingArray, "splice", {
88 removedMembers = this._splice.apply(this, arguments); 88 removedMembers = this._splice.apply(this, arguments);
89 removedCount = removedMembers.length; 89 removedCount = removedMembers.length;
90 90
91 // I stopped caring about whether or not this splice could be considered an ADDITION or REMOVAL 91 netChange = addedCount - removedCount;
92 // all splices result in a modification now; we could change this if we want to 92
93 // Find the most accurate propertyChange type for this splice,
94 // For the most part it's considered a modification unless the length of the array was modified
95 // if only to not bother notifying listeners for changes of the length of this array
93 changeType = ChangeTypes.MODIFICATION; 96 changeType = ChangeTypes.MODIFICATION;
94 97
98 if (netChange > 0) {
99 changeType = ChangeTypes.ADDITION;
100 } else if (netChange < 0) {
101 changeType = ChangeTypes.REMOVAL;
102 }
103
95 if (this.dispatchChangeEvent) { 104 if (this.dispatchChangeEvent) {
96 changeEvent = new ChangeEventConstructor(); 105 changeEvent = new ChangeEventConstructor();
97 changeEvent.minus = removedMembers; 106 changeEvent.minus = removedMembers;
@@ -103,8 +112,6 @@ Object.defineProperty(ChangeEventDispatchingArray, "splice", {
103 112
104 if (this.dispatchChangeAtIndexEvent) { 113 if (this.dispatchChangeAtIndexEvent) {
105 114
106 netChange = addedCount - removedCount;
107
108 if (typeof howMany === "undefined") { 115 if (typeof howMany === "undefined") {
109 // no howMany argument given: remove all elements after index? 116 // no howMany argument given: remove all elements after index?
110 // TODO this may only be in some implementations 117 // TODO this may only be in some implementations
@@ -498,7 +505,7 @@ var PropertyChangeBindingListener = exports.PropertyChangeBindingListener = Obje
498 localPrevValue = event.minus, 505 localPrevValue = event.minus,
499 localTarget = event.target, 506 localTarget = event.target,
500 type = event.type, 507 type = event.type,
501 changeType = event.propertyChange, //MODIFICATION is 1, ADDITION 2, REMOVAL 3, 508 changeType = event.propertyChange,
502 localPropertyName = event.propertyName, 509 localPropertyName = event.propertyName,
503 boundObjectValue, 510 boundObjectValue,
504 sourceObjectValue, 511 sourceObjectValue,
@@ -508,7 +515,12 @@ var PropertyChangeBindingListener = exports.PropertyChangeBindingListener = Obje
508 baseType, 515 baseType,
509 bindingDescriptor, 516 bindingDescriptor,
510 bindingOrigin = this.bindingOrigin, 517 bindingOrigin = this.bindingOrigin,
511 leftOriginated; 518 leftOriginated,
519 changeOriginPropertyPath = null,
520 exploredPath,
521 remainingPath,
522 i,
523 localPrevValueCount;
512 524
513 if (target !== bindingOrigin) { 525 if (target !== bindingOrigin) {
514 //the left and the right are different objects; easy enough 526 //the left and the right are different objects; easy enough
@@ -617,51 +629,46 @@ var PropertyChangeBindingListener = exports.PropertyChangeBindingListener = Obje
617 event.plus = localNewValue; 629 event.plus = localNewValue;
618 event.target = localTarget; 630 event.target = localTarget;
619 631
632 if (localPrevValue) {
620 633
621 // Now we know that we handled a particular type of change event 634 // Determine where along the property path the change originated from so we know how to build the path
622 // Depending on what happened we may need to remove listeners from a broken propertyPath or 635 // to stop observing on things that were removed
623 // install listeners along the modified (or deeper) propertyPath 636 //TODO extract this into a "obj.getPathOfObjectAlongPropertyPath" method or something with proper tests
624 637 exploredPath = "";
625 // MODIFICATION 1 638 this.target.getProperty(this.targetPropertyPath, null, null, function(value, currentPathComponent, result) {
626 if (changeType === 1) {
627
628 if (localPrevValue) {
629 // TODO remove all the listeners from the localPrev object as far to tne end of the path as possible
630 // localPrevValue.removeEventListener(baseType, this, this.useCapture);
631 }
632
633 if (localNewValue) {
634 // TODO this may be less efficient than we could be, but frankly I don't know how to tell where
635 // in the path you are by the time you get here, so I'm not sure how to install just the part
636 // we need, plus addEventListener seems to use the targetPropertyPath from the listener
637 // regardless of what you pass in fro the eventType.
638 this.target.addEventListener(baseType + "@" + this.targetPropertyPath, this, this.useCapture);
639 }
640 639
641 } 640 if (changeOriginPropertyPath) {
642 //ADDITION 2, REMOVAL 3, typically on collections 641 return;
642 }
643 643
644 //TODO looks like we end up wanting to do the sam thing in both cases right now, I think the TODO in the 644 exploredPath += "." + currentPathComponent;
645 // modification explains why a bit.
646 else {
647 645
648 if (localPrevValue) { 646 if (result === event.target) {
647 changeOriginPropertyPath = exploredPath.replace(/^\./, "");
648 }
649 });
649 650
650 // TODO how do we know the nextPathComponent, we need to know the rest of the path after each 651 if (changeOriginPropertyPath) {
651 // entry in the localPrevValue array 652 remainingPath = this.targetPropertyPath.replace(new RegExp("^" + changeOriginPropertyPath + "\.?"), "");
652// for (var i = 0; i < localPrevValue.length; i++) { 653 } else {
653 localPrevValue.removeEventListener(nextPathComponent ? baseType + "@" + nextPathComponent : baseType, this, this.useCapture); 654 remainingPath = this.targetPropertyPath;
654// }
655 } 655 }
656 656
657 if (localNewValue) { 657 // NOTE this check works around Safari not having a removeEventListener on its CanvasPixelArray
658 this.target.addEventListener(baseType + "@" + this.targetPropertyPath, this, this.useCapture); 658 // TODO investigate if this is an appropriate fix or not
659 } else if (event._event.plus) { 659 if (typeof localPrevValue.removeEventListener === "function") {
660 this.target.addEventListener(baseType + "@" + this.targetPropertyPath, this, this.useCapture); 660 localPrevValue.removeEventListener(baseType + "@" + remainingPath, this, this.useCapture);
661 } 661 }
662 }
662 663
663 664 if (localNewValue) {
665 // Reinstall listeners along the entire propertyPath from the target
666 this.target.addEventListener(baseType + "@" + this.targetPropertyPath, this, this.useCapture);
667 } else if (event._event.plus) {
668 // TODO removing this causes no spec failures; looks suspicious
669 this.target.addEventListener(baseType + "@" + this.targetPropertyPath, this, this.useCapture);
664 } 670 }
671
665 } 672 }
666 targetPropertyPath = null; 673 targetPropertyPath = null;
667 target = null; 674 target = null;
@@ -964,7 +971,7 @@ Object.defineProperty(Object.prototype, "addEventListener", {
964 anEvent.initCustomEvent("change@" + setter.property, true, false, null); 971 anEvent.initCustomEvent("change@" + setter.property, true, false, null);
965 anEvent.minus = prevValue; 972 anEvent.minus = prevValue;
966 anEvent.plus = acceptedValue; 973 anEvent.plus = acceptedValue;
967 anEvent.propertyChange = 1;//MODIFICATION, ADDITION, REMOVAL 974 anEvent.propertyChange = ChangeTypes.MODIFICATION;
968 anEvent.propertyName = setter.property; 975 anEvent.propertyName = setter.property;
969 this.dispatchEvent(anEvent); 976 this.dispatchEvent(anEvent);
970 } 977 }
@@ -1041,7 +1048,7 @@ Object.defineProperty(Object.prototype, "addEventListener", {
1041 anEvent.initCustomEvent("change@" + setter.property, true, false, null); 1048 anEvent.initCustomEvent("change@" + setter.property, true, false, null);
1042 anEvent.minus = prevValue; 1049 anEvent.minus = prevValue;
1043 anEvent.plus = acceptedValue; 1050 anEvent.plus = acceptedValue;
1044 anEvent.propertyChange = 1;//MODIFICATION, ADDITION, REMOVAL 1051 anEvent.propertyChange = ChangeTypes.MODIFICATION;
1045 anEvent.propertyName = setter.property; 1052 anEvent.propertyName = setter.property;
1046 this.dispatchEvent(anEvent); 1053 this.dispatchEvent(anEvent);
1047 } 1054 }