From b3b0aaa0ec3eae25873b30a105578f7aea3acc7c Mon Sep 17 00:00:00 2001 From: Boris Serdiuk Date: Tue, 25 Aug 2015 12:48:01 +0300 Subject: [PATCH] feat($rootScope): implement event.stopPropagation() for $broadcast-ed events --- src/ng/rootScope.js | 8 +++++--- test/ng/rootScopeSpec.js | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/ng/rootScope.js b/src/ng/rootScope.js index 3bbabfb7cf6c..c70115b1cbad 100644 --- a/src/ng/rootScope.js +++ b/src/ng/rootScope.js @@ -1099,7 +1099,7 @@ function $RootScopeProvider() { * event propagates through the scope hierarchy, this property is set to null. * - `name` - `{string}`: name of the event. * - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel - * further event propagation (available only for events that were `$emit`-ed). + * further event propagation. * - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag * to true. * - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called. @@ -1232,9 +1232,11 @@ function $RootScopeProvider() { var target = this, current = target, next = target, + stopPropagation = false, event = { name: name, targetScope: target, + stopPropagation: function() {stopPropagation = true;}, preventDefault: function() { event.defaultPrevented = true; }, @@ -1270,8 +1272,8 @@ function $RootScopeProvider() { // yes, this code is a bit crazy, but it works and we have tests to prove it! // this piece should be kept in sync with the traversal in $digest // (though it differs due to having the extra check for $$listenerCount) - if (!(next = ((current.$$listenerCount[name] && current.$$childHead) || - (current !== target && current.$$nextSibling)))) { + if (!(next = ((current.$$listenerCount[name] && !stopPropagation && current.$$childHead) || + (current !== target && ((stopPropagation = false) || current.$$nextSibling))))) { while (current !== target && !(next = current.$$nextSibling)) { current = current.$parent; } diff --git a/test/ng/rootScopeSpec.js b/test/ng/rootScopeSpec.js index a598499d6c3a..761eb31f3234 100644 --- a/test/ng/rootScopeSpec.js +++ b/test/ng/rootScopeSpec.js @@ -2007,6 +2007,20 @@ describe('Scope', function() { })); + it('should allow stopping event propagation', inject(function($rootScope) { + child2.$on('myEvent', function(event) { event.stopPropagation(); }); + $rootScope.$broadcast('myEvent'); + expect(log).toEqual('0>1>11>2>3>'); + })); + + + it('should stop propagation only for one scope chain', inject(function($rootScope) { + child1.$on('myEvent', function(event) { event.stopPropagation(); }); + $rootScope.$broadcast('myEvent'); + expect(log).toEqual('0>1>2>21>211>22>23>3>'); + })); + + it('should broadcast an event from a child scope', function() { child2.$broadcast('myEvent'); expect(log).toBe('2>21>211>22>23>');