diff --git a/src/wrappers/events.js b/src/wrappers/events.js index f0bdb02..88ce2d5 100644 --- a/src/wrappers/events.js +++ b/src/wrappers/events.js @@ -171,6 +171,19 @@ return rootOfNode(a) === rootOfNode(b); } + function enclosedBy(a, b) { + if (a === b) + return true; + if (a instanceof wrappers.ShadowRoot) { + var host = scope.getHostForShadowRoot(a); + if (!host) + return false; + return enclosedBy(rootOfNode(host), b); + } + return false; + + } + function isMutationEvent(type) { switch (type) { case 'DOMAttrModified': @@ -389,17 +402,16 @@ var eventPath = eventPathTable.get(this); if (eventPath) { var index = 0; - var found = false; - var currentTarget = currentTargetTable.get(this); var lastIndex = eventPath.length - 1; + var baseRoot = rootOfNode(currentTargetTable.get(this)); + for (var i = 0; i <= lastIndex; i++) { - if (!found) - found = eventPath[i].currentTarget === currentTarget; - if (found) { - var node = eventPath[i].currentTarget; - // Do not include the top Window. - if (i !== lastIndex || node instanceof wrappers.Node) - nodeList[index++] = node; + var currentTarget = eventPath[i].currentTarget; + var currentRoot = rootOfNode(currentTarget); + if (enclosedBy(baseRoot, currentRoot) && + // Make sure we do not add Window to the path. + (i !== lastIndex || currentTarget instanceof wrappers.Node)) { + nodeList[index++] = currentTarget; } } nodeList.length = index; diff --git a/test/js/events.js b/test/js/events.js index 361ed74..9737ee4 100644 --- a/test/js/events.js +++ b/test/js/events.js @@ -57,9 +57,8 @@ htmlSuite('Events', function() { } teardown(function() { - if (div) { + if (div && div.parentNode) div.parentNode.removeChild(div); - } div = a = b = c = d = e = f = content = sr = undefined; }); @@ -1184,6 +1183,9 @@ test('retarget order (multiple shadow roots)', function() { tree.e.addEventListener('x', function f(e) { assertArrayEqual( [ + tree.c, + tree.content, + tree.content2, tree.e, tree.sr2, tree.d, @@ -1200,6 +1202,9 @@ test('retarget order (multiple shadow roots)', function() { tree.sr.addEventListener('x', function f(e) { assertArrayEqual( [ + tree.c, + tree.content, + tree.d, tree.sr, tree.b, tree.a, @@ -1210,13 +1215,25 @@ test('retarget order (multiple shadow roots)', function() { tree.sr.removeEventListener('x', f); }); + tree.c.addEventListener('x', function f(e) { + assertArrayEqual( + [ + tree.c, + tree.b, + tree.a, + tree.div, + ], + e.path); + + tree.c.removeEventListener('x', f); + }); + tree.c.dispatchEvent(e); }); test('event.path on body (bubbles)', function() { var e = new Event('x', {bubbles: true}); var doc = wrap(document); - var win = wrap(window); doc.body.addEventListener('x', function f(e) { assertArrayEqual( @@ -1233,6 +1250,7 @@ test('retarget order (multiple shadow roots)', function() { doc.documentElement.addEventListener('x', function f(e) { assertArrayEqual( [ + doc.body, doc.documentElement, doc, ],