@@ -133,6 +133,7 @@ function $RootScopeProvider(){
133
133
this . $$asyncQueue = [ ] ;
134
134
this . $$postDigestQueue = [ ] ;
135
135
this . $$listeners = { } ;
136
+ this . $$listenerCount = { } ;
136
137
this . $$isolateBindings = { } ;
137
138
}
138
139
@@ -192,6 +193,7 @@ function $RootScopeProvider(){
192
193
}
193
194
child [ 'this' ] = child ;
194
195
child . $$listeners = { } ;
196
+ child . $$listenerCount = { } ;
195
197
child . $parent = this ;
196
198
child . $$watchers = child . $$nextSibling = child . $$childHead = child . $$childTail = null ;
197
199
child . $$prevSibling = this . $$childTail ;
@@ -696,6 +698,8 @@ function $RootScopeProvider(){
696
698
this . $$destroyed = true ;
697
699
if ( this === $rootScope ) return ;
698
700
701
+ forEach ( this . $$listenerCount , bind ( null , decrementListenerCount , this ) ) ;
702
+
699
703
if ( parent . $$childHead == this ) parent . $$childHead = this . $$nextSibling ;
700
704
if ( parent . $$childTail == this ) parent . $$childTail = this . $$prevSibling ;
701
705
if ( this . $$prevSibling ) this . $$prevSibling . $$nextSibling = this . $$nextSibling ;
@@ -885,8 +889,18 @@ function $RootScopeProvider(){
885
889
}
886
890
namedListeners . push ( listener ) ;
887
891
892
+ var current = this ;
893
+ do {
894
+ if ( ! current . $$listenerCount [ name ] ) {
895
+ current . $$listenerCount [ name ] = 0 ;
896
+ }
897
+ current . $$listenerCount [ name ] ++ ;
898
+ } while ( ( current = current . $parent ) ) ;
899
+
900
+ var self = this ;
888
901
return function ( ) {
889
902
namedListeners [ indexOf ( namedListeners , listener ) ] = null ;
903
+ decrementListenerCount ( self , 1 , name ) ;
890
904
} ;
891
905
} ,
892
906
@@ -998,8 +1012,7 @@ function $RootScopeProvider(){
998
1012
listeners , i , length ;
999
1013
1000
1014
//down while you can, then up and next sibling or up and next sibling until back at root
1001
- do {
1002
- current = next ;
1015
+ while ( ( current = next ) ) {
1003
1016
event . currentScope = current ;
1004
1017
listeners = current . $$listeners [ name ] || [ ] ;
1005
1018
for ( i = 0 , length = listeners . length ; i < length ; i ++ ) {
@@ -1021,12 +1034,14 @@ function $RootScopeProvider(){
1021
1034
// Insanity Warning: scope depth-first traversal
1022
1035
// yes, this code is a bit crazy, but it works and we have tests to prove it!
1023
1036
// this piece should be kept in sync with the traversal in $digest
1024
- if ( ! ( next = ( current . $$childHead || ( current !== target && current . $$nextSibling ) ) ) ) {
1037
+ // (though it differs due to having the extra check for $$listenerCount)
1038
+ if ( ! ( next = ( ( current . $$listenerCount [ name ] && current . $$childHead ) ||
1039
+ ( current !== target && current . $$nextSibling ) ) ) ) {
1025
1040
while ( current !== target && ! ( next = current . $$nextSibling ) ) {
1026
1041
current = current . $parent ;
1027
1042
}
1028
1043
}
1029
- } while ( ( current = next ) ) ;
1044
+ }
1030
1045
1031
1046
return event ;
1032
1047
}
@@ -1055,6 +1070,16 @@ function $RootScopeProvider(){
1055
1070
return fn ;
1056
1071
}
1057
1072
1073
+ function decrementListenerCount ( current , count , name ) {
1074
+ do {
1075
+ current . $$listenerCount [ name ] -= count ;
1076
+
1077
+ if ( current . $$listenerCount [ name ] === 0 ) {
1078
+ delete current . $$listenerCount [ name ] ;
1079
+ }
1080
+ } while ( ( current = current . $parent ) ) ;
1081
+ }
1082
+
1058
1083
/**
1059
1084
* function used as an initial value for watchers.
1060
1085
* because it's unique we can easily tell it apart from other values
0 commit comments