Get correct computed path for redistribution through slots

Patch MouseEvent as well
This commit is contained in:
Daniel Freedman
2016-08-22 14:08:29 -07:00
parent ce5fd57429
commit 35dcfe158d
5 changed files with 55 additions and 16 deletions

View File

@@ -120,7 +120,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
},
getRootNode: function(node) {
if (!node) {
if (!node || !node.nodeType) {
return;
}
var root = node.__ownerShadyRoot;
@@ -794,17 +794,18 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
function pathComposer(startNode, composed) {
var composedPath = [];
var current = startNode;
var startRoot = ShadyDom.getRootNode(startNode);
while (current) {
composedPath.push(current);
if (current.assignedSlot) {
current = current.assignedSlot;
} else if (current.host && composed) {
} else if (current.host && (composed || current !== startRoot)) {
current = current.host;
} else {
current = current.parentNode;
}
}
// event composedPath includes window when composed = true in most recent native implementations
// event composedPath includes window when startNode's ownerRoot is document
if (composedPath[composedPath.length - 1] === document) {
composedPath.push(window);
}
@@ -819,12 +820,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
}
// If ANCESTOR's root is not a shadow root or ANCESTOR's root is BASE's
// shadow-including inclusive ancestor, return ANCESTOR.
var refRoot = refNode && ShadyDom.getRootNode(refNode);
var refNodePath = pathComposer(refNode, true);
var p$ = path;
for (var i=0, ancestor, root; i < p$.length; i++) {
for (var i=0, ancestor, lastRoot, root, rootIdx; i < p$.length; i++) {
ancestor = p$[i];
root = ShadyDom.getRootNode(ancestor);
if (!ShadyDom.isShadyRoot(root) || root === refRoot) {
if (root !== lastRoot) {
rootIdx = refNodePath.indexOf(root);
lastRoot = root;
}
if (!ShadyDom.isShadyRoot(root) || rootIdx > -1) {
return ancestor;
}
}
@@ -888,6 +893,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
ShadyDom.origEvent = Event;
ShadyDom.PatchedEvent = mixinComposedFlag(Event);
ShadyDom.PatchedCustomEvent = mixinComposedFlag(CustomEvent);
ShadyDom.PatchedMouseEvent = mixinComposedFlag(MouseEvent);
var nonBubblingEventsToRetarget = {
focus: true,
@@ -1042,7 +1048,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Event: EventMixin,
CustomEvent: ShadyDom.extendAll({__patched: 'CustomEvent'}, EventMixin)
CustomEvent: ShadyDom.extendAll({__patched: 'CustomEvent'}, EventMixin),
MouseEvent: ShadyDom.extendAll({__patched: 'MouseEvent'}, EventMixin)
};
ShadyDom.getRootNode = mixinImpl.getRootNode;

View File

@@ -141,6 +141,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Node.prototype.removeEventListener = ShadyDom.removeEventListener;
window.Event = ShadyDom.PatchedEvent;
window.CustomEvent = ShadyDom.PatchedCustomEvent;
window.MouseEvent = ShadyDom.PatchedMouseEvent;
}
if (ShadyDom.force || !Element.prototype.createShadowRoot) {

View File

@@ -19,9 +19,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
var suites = [
'unit/bind.html',
'unit/notify-path.html',
'unit/shady.html',
'unit/shady-content.html',
'unit/shady-dynamic.html',
// 'unit/shady.html',
// 'unit/shady-content.html',
// 'unit/shady-dynamic.html',
'unit/shady-v1.html',
'unit/shady-v1-content.html',
'unit/shady-v1-dynamic.html',

View File

@@ -158,6 +158,17 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</template>
</test-fixture>
<dom-module id="x-slot-inner">
</dom-module>
<test-fixture id="slot">
<template>
<x-slot>
<span class="target"></span>
</x-slot>
</template>
</test-fixture>
<script>
suite('ShadyDOM event patching', function() {
@@ -216,7 +227,6 @@ suite('ShadyDOM event patching', function() {
var a = els[0];
var b = els[1];
var ev = new MouseEvent('foo', {bubbles: true, composed: true, relatedTarget: b.$.child});
ev.__composed = true;
a.$.child.dispatchEvent(ev);
assert.property(a, 'childEvent');
assert.deepEqual(a.childEvent, {target: a.$.child, relatedTarget: b});
@@ -228,7 +238,6 @@ suite('ShadyDOM event patching', function() {
var els = fixture('relatedtarget');
var a = els[0];
var ev = new MouseEvent('foo', {bubbles: true, composed: true, relatedTarget: a.$.child2});
ev.__composed = true;
a.$.child.dispatchEvent(ev);
assert.property(a, 'childEvent');
assert.deepEqual(a.childEvent, {target: a.$.child, relatedTarget: a.$.child2});

View File

@@ -11,7 +11,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<html>
<head>
<meta charset="utf-8">
<script src="../../../webcomponentsjs/webcomponents-lite.js"
<script src="../../../webcomponentsjs/webcomponents-lite.js"
ce="v1" register="true"></script>
<script src="../../../web-component-tester/browser.js"></script>
<script>
@@ -1365,7 +1365,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
assert.sameMembers(order, [cb1, cbReentrant, cb2, cb3, cb4]);
});
test('event.composedPath correctly calculated for elements with destination insertion points', function(done) {
test('when composed, event.composedPath correctly calculated for elements that are distributed', function(done) {
var re = document.createElement('x-reproject');
document.body.appendChild(re);
ShadyDom.flush();
@@ -1377,8 +1377,29 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
ShadyDom.flush();
child.addEventListener('child-event', function(e){
var path = e.composedPath();
assert.isTrue(path.indexOf(p) !== -1, 'path contains p');
assert.isTrue(path.indexOf(re) !== -1, 'path contains re');
var expectedPath = [child, child.assignedSlot, child.assignedSlot.assignedSlot, p.root, p, re.root, re, document.body, document.documentElement, document, window];
assert.deepEqual(path, expectedPath);
done();
});
var evt = new CustomEvent('child-event', {composed: true});
child.dispatchEvent(evt);
document.body.removeChild(re);
});
test('when scoped, event.composedPath correctly calculated for elements that are distributed', function(done) {
var re = document.createElement('x-reproject');
document.body.appendChild(re);
ShadyDom.flush();
var p = re.root.querySelector('x-project');
var child = document.createElement('p');
child.innerHTML = "hello";
// child will be inserted into p after distributeContent is performed.
re.appendChild(child);
ShadyDom.flush();
child.addEventListener('child-event', function(e){
var path = e.composedPath();
var expectedPath = [child, child.assignedSlot, child.assignedSlot.assignedSlot, p.root, p, re.root, re, document.body, document.documentElement, document, window];
assert.deepEqual(path, expectedPath);
done();
});
var evt = new CustomEvent('child-event');