🌐 AI搜索 & 代理 主页
Skip to content

Commit b75b9ef

Browse files
committed
Fix #13180: don't delegate into SVG <use>
(cherry picked from commits 36457cb..f860e0b)
1 parent 7767234 commit b75b9ef

File tree

2 files changed

+66
-45
lines changed

2 files changed

+66
-45
lines changed

src/event.js

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,10 @@ jQuery.event = {
331331
// Make a writable jQuery.Event from the native event object
332332
event = jQuery.event.fix( event );
333333

334-
var i, j, cur, ret, selMatch, matched, matches, handleObj, sel,
334+
var i, j, ret, matched, handleObj,
335335
handlerQueue = [],
336336
args = core_slice.call( arguments ),
337337
handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
338-
delegateCount = handlers.delegateCount,
339338
special = jQuery.event.special[ event.type ] || {};
340339

341340
// Use the fix-ed jQuery.Event rather than the (read-only) native event
@@ -347,41 +346,8 @@ jQuery.event = {
347346
return;
348347
}
349348

350-
// Determine handlers that should run if there are delegated events
351-
// Avoid non-left-click bubbling in Firefox (#3861)
352-
if ( delegateCount && !(event.button && event.type === "click") ) {
353-
354-
for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
355-
356-
// Ignore clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)
357-
if ( cur.disabled !== true || event.type !== "click" ) {
358-
selMatch = {};
359-
matches = [];
360-
i = 0;
361-
for ( ; i < delegateCount; i++ ) {
362-
handleObj = handlers[ i ];
363-
sel = handleObj.selector;
364-
365-
if ( selMatch[ sel ] === undefined ) {
366-
selMatch[ sel ] = handleObj.needsContext ?
367-
jQuery( sel, this ).index( cur ) >= 0 :
368-
jQuery.find( sel, this, null, [ cur ] ).length;
369-
}
370-
if ( selMatch[ sel ] ) {
371-
matches.push( handleObj );
372-
}
373-
}
374-
if ( matches.length ) {
375-
handlerQueue.push({ elem: cur, handlers: matches });
376-
}
377-
}
378-
}
379-
}
380-
381-
// Add the remaining (directly-bound) handlers
382-
if ( handlers.length > delegateCount ) {
383-
handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
384-
}
349+
// Determine handlers
350+
handlerQueue = jQuery.event.handlers.call( this, event, handlers );
385351

386352
// Run delegates first; they may want to stop propagation beneath us
387353
i = 0;
@@ -419,6 +385,50 @@ jQuery.event = {
419385
return event.result;
420386
},
421387

388+
handlers: function( event, handlers ) {
389+
var i, matches, sel, handleObj,
390+
handlerQueue = [],
391+
delegateCount = handlers.delegateCount,
392+
cur = event.target;
393+
394+
// Find delegate handlers
395+
// Black-hole SVG <use> instance trees (#13180)
396+
// Avoid non-left-click bubbling in Firefox (#3861)
397+
if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
398+
399+
for ( ; cur != this; cur = cur.parentNode || this ) {
400+
401+
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
402+
if ( cur.disabled !== true || event.type !== "click" ) {
403+
matches = [];
404+
for ( i = 0; i < delegateCount; i++ ) {
405+
handleObj = handlers[ i ];
406+
sel = handleObj.selector;
407+
408+
if ( matches[ sel ] === undefined ) {
409+
matches[ sel ] = handleObj.needsContext ?
410+
jQuery( sel, this ).index( cur ) >= 0 :
411+
jQuery.find( sel, this, null, [ cur ] ).length;
412+
}
413+
if ( matches[ sel ] ) {
414+
matches.push( handleObj );
415+
}
416+
}
417+
if ( matches.length ) {
418+
handlerQueue.push({ elem: cur, handlers: matches });
419+
}
420+
}
421+
}
422+
}
423+
424+
// Add the remaining (directly-bound) handlers
425+
if ( delegateCount < handlers.length ) {
426+
handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
427+
}
428+
429+
return handlerQueue;
430+
},
431+
422432
// Includes some event props shared by KeyEvent and MouseEvent
423433
props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
424434

test/unit/event.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,29 +1231,40 @@ test(".trigger() doesn't bubble load event (#10717)", function() {
12311231
jQuery( window ).off( "load" );
12321232
});
12331233

1234-
test("Delegated events in SVG (#10791)", function() {
1234+
test("Delegated events in SVG (#10791; #13180)", function() {
12351235
expect(2);
12361236

1237-
var svg = jQuery(
1237+
var e,
1238+
svg = jQuery(
12381239
"<svg height='1' version='1.1' width='1' xmlns='http://www.w3.org/2000/svg'>" +
1240+
"<defs><rect id='ref' x='10' y='20' width='100' height='60' r='10' rx='10' ry='10'></rect></defs>" +
12391241
"<rect class='svg-by-class' x='10' y='20' width='100' height='60' r='10' rx='10' ry='10'></rect>" +
12401242
"<rect id='svg-by-id' x='10' y='20' width='100' height='60' r='10' rx='10' ry='10'></rect>" +
1243+
"<use id='use' xlink:href='#ref'></use>" +
12411244
"</svg>"
1242-
).appendTo( "body" );
1245+
);
12431246

1244-
jQuery( "body" )
1247+
jQuery("#qunit-fixture")
1248+
.append( svg )
12451249
.on( "click", "#svg-by-id", function() {
12461250
ok( true, "delegated id selector" );
12471251
})
12481252
.on( "click", "[class~='svg-by-class']", function() {
12491253
ok( true, "delegated class selector" );
12501254
})
12511255
.find( "#svg-by-id, [class~='svg-by-class']" )
1252-
.trigger( "click" )
1253-
.end()
1254-
.off( "click" );
1256+
.trigger("click")
1257+
.end();
1258+
1259+
// Fire a native click on an SVGElementInstance (the instance tree of an SVG <use>)
1260+
// to confirm that it doesn't break our event delegation handling (#13180)
1261+
if ( document.createEvent ) {
1262+
e = document.createEvent("MouseEvents");
1263+
e.initEvent( "click", true, true );
1264+
svg.find("#use")[0].instanceRoot.dispatchEvent( e );
1265+
}
12551266

1256-
svg.remove();
1267+
jQuery("#qunit-fixture").off("click");
12571268
});
12581269

12591270
test("Delegated events in forms (#10844; #11145; #8165; #11382, #11764)", function() {

0 commit comments

Comments
 (0)