@@ -1151,8 +1151,8 @@ function $RootScopeProvider() {
1151
1151
* - `currentScope` - `{Scope}`: the scope that is currently handling the event. Once the
1152
1152
* event propagates through the scope hierarchy, this property is set to null.
1153
1153
* - `name` - `{string}`: name of the event.
1154
- * - `stopPropagation` - `{function= }`: calling `stopPropagation` function will cancel
1155
- * further event propagation (available only for events that were `$emit`-ed) .
1154
+ * - `stopPropagation` - `{function}`: calling `stopPropagation` function will cancel
1155
+ * further event propagation.
1156
1156
* - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag
1157
1157
* to true.
1158
1158
* - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called.
@@ -1272,7 +1272,9 @@ function $RootScopeProvider() {
1272
1272
* The event life cycle starts at the scope on which `$broadcast` was called. All
1273
1273
* {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get
1274
1274
* notified. Afterwards, the event propagates to all direct and indirect scopes of the current
1275
- * scope and calls all registered listeners along the way. The event cannot be canceled.
1275
+ * scope and calls all registered listeners along the way. If a scope requests the event stop propagation
1276
+ * then it will not be propagated to any children of that scope, but will continue to propagate to siblings of the
1277
+ * that scope and children of those siblings unless each sibling independently stops the event.
1276
1278
*
1277
1279
* Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
1278
1280
* onto the {@link ng.$exceptionHandler $exceptionHandler} service.
@@ -1284,10 +1286,14 @@ function $RootScopeProvider() {
1284
1286
$broadcast : function ( name , args ) {
1285
1287
var target = this ,
1286
1288
current = target ,
1289
+ stopPropagation = false ,
1287
1290
next = target ,
1288
1291
event = {
1289
1292
name : name ,
1290
1293
targetScope : target ,
1294
+ stopPropagation : function ( ) {
1295
+ stopPropagation = true ;
1296
+ } ,
1291
1297
preventDefault : function ( ) {
1292
1298
event . defaultPrevented = true ;
1293
1299
} ,
@@ -1301,6 +1307,7 @@ function $RootScopeProvider() {
1301
1307
1302
1308
//down while you can, then up and next sibling or up and next sibling until back at root
1303
1309
while ( ( current = next ) ) {
1310
+ stopPropagation = false ;
1304
1311
event . currentScope = current ;
1305
1312
listeners = current . $$listeners [ name ] || [ ] ;
1306
1313
for ( i = 0 , length = listeners . length ; i < length ; i ++ ) {
@@ -1322,8 +1329,8 @@ function $RootScopeProvider() {
1322
1329
// Insanity Warning: scope depth-first traversal
1323
1330
// yes, this code is a bit crazy, but it works and we have tests to prove it!
1324
1331
// this piece should be kept in sync with the traversal in $digest
1325
- // (though it differs due to having the extra check for $$listenerCount)
1326
- if ( ! ( next = ( ( current . $$listenerCount [ name ] && current . $$childHead ) ||
1332
+ // (though it differs due to having the extra check for $$listenerCount and stopPropagation )
1333
+ if ( ! ( next = ( ( current . $$listenerCount [ name ] && ! stopPropagation && current . $$childHead ) ||
1327
1334
( current !== target && current . $$nextSibling ) ) ) ) {
1328
1335
while ( current !== target && ! ( next = current . $$nextSibling ) ) {
1329
1336
current = current . $parent ;
0 commit comments