aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Spring <pierre@nelm.io>2017-06-13 18:22:08 +0200
committerTimmy Willison <4timmywil@gmail.com>2017-07-10 11:55:32 -0400
commit490db839fb08a9b461e77dbe0138c7e6045aacd8 (patch)
tree0699ed90c27e478000bd1d5bfe03f3eb5b5e364d
parent0bf499ca24982714c816a836345c027939ccb3c6 (diff)
downloadjquery-490db839fb08a9b461e77dbe0138c7e6045aacd8.tar.gz
jquery-490db839fb08a9b461e77dbe0138c7e6045aacd8.zip
Event: `stopPropagation()` on native event-handler
Fixes gh-3693 Close gh-3694
-rw-r--r--src/event/trigger.js21
-rw-r--r--test/unit/event.js41
2 files changed, 58 insertions, 4 deletions
diff --git a/src/event/trigger.js b/src/event/trigger.js
index ef391370f..c3b048026 100644
--- a/src/event/trigger.js
+++ b/src/event/trigger.js
@@ -10,18 +10,21 @@ define( [
"use strict";
-var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
+var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+ stopPropagationCallback = function( e ) {
+ e.stopPropagation();
+ };
jQuery.extend( jQuery.event, {
trigger: function( event, data, elem, onlyHandlers ) {
- var i, cur, tmp, bubbleType, ontype, handle, special,
+ var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
eventPath = [ elem || document ],
type = hasOwn.call( event, "type" ) ? event.type : event,
namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
- cur = tmp = elem = elem || document;
+ cur = lastElement = tmp = elem = elem || document;
// Don't do events on text and comment nodes
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
@@ -93,7 +96,7 @@ jQuery.extend( jQuery.event, {
// Fire handlers on the event path
i = 0;
while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
-
+ lastElement = cur;
event.type = i > 1 ?
bubbleType :
special.bindType || type;
@@ -136,7 +139,17 @@ jQuery.extend( jQuery.event, {
// Prevent re-triggering of the same event, since we already bubbled it above
jQuery.event.triggered = type;
+
+ if ( event.isPropagationStopped() ) {
+ lastElement.addEventListener( type, stopPropagationCallback );
+ }
+
elem[ type ]();
+
+ if ( event.isPropagationStopped() ) {
+ lastElement.removeEventListener( type, stopPropagationCallback );
+ }
+
jQuery.event.triggered = undefined;
if ( tmp ) {
diff --git a/test/unit/event.js b/test/unit/event.js
index 0c379d051..30e057a80 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -440,6 +440,47 @@ QUnit.test( "on bubbling, isDefaultPrevented, stopImmediatePropagation", functio
$anchor2[ 0 ].removeEventListener( "click", neverCallMe );
} );
+QUnit.test( "triggered events stopPropagation() for natively-bound events", function( assert ) {
+ assert.expect( 1 );
+
+ var $button = jQuery( "#button" ),
+ $parent = $button.parent(),
+ neverCallMe = function() {
+ assert.ok( false, "propagation should have been stopped" );
+ },
+ stopPropagationCallback = function( e ) {
+ assert.ok( true, "propagation is stopped" );
+ e.stopPropagation();
+ };
+
+ $parent[ 0 ].addEventListener( "click", neverCallMe );
+ $button.on( "click", stopPropagationCallback );
+ $button.trigger( "click" );
+ $parent[ 0 ].removeEventListener( "click", neverCallMe );
+ $button.off( "click", stopPropagationCallback );
+} );
+
+QUnit.test( "trigger() works with events that were previously stopped", function( assert ) {
+ assert.expect( 0 );
+
+ var $button = jQuery( "#button" ),
+ $parent = $button.parent(),
+ neverCallMe = function() {
+ assert.ok( false, "propagation should have been stopped" );
+ };
+
+ $parent[ 0 ].addEventListener( "click", neverCallMe );
+ $button.on( "click", neverCallMe );
+
+ var clickEvent = jQuery.Event( "click" );
+ clickEvent.stopPropagation();
+ $button.trigger( clickEvent );
+
+ $parent[ 0 ].removeEventListener( "click", neverCallMe );
+ $button.off( "click", neverCallMe );
+} );
+
+
QUnit.test( "on(), iframes", function( assert ) {
assert.expect( 1 );