Skip to content

Commit

Permalink
Fix issue with event path in case of reprojection.
Browse files Browse the repository at this point in the history
This fixes the issues we saw with e701c2e
  • Loading branch information
arv committed Apr 19, 2013
1 parent 1a3cb5c commit 5ccb302
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 21 deletions.
48 changes: 28 additions & 20 deletions src/ShadowRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,26 @@
}

var distributedChildNodesTable = new SideTable();
var shadowDOMRendererTable = new SideTable();
var nextOlderShadowTreeTable = new SideTable();
var insertionParentTable = new SideTable();
var eventParentTable = new SideTable();
var insertionParentTable = new SideTable();
var nextOlderShadowTreeTable = new SideTable();
var rendererForHostTable = new SideTable();
var shadowDOMRendererTable = new SideTable();

function distributeChildToInsertionPoint(child, insertionPoint) {
getDistributedChildNodes(insertionPoint).push(child);
insertionParentTable.set(child, insertionPoint);

// If we have "a -> content1" and we now get (a, content2) the
// event parent chaing needs to be "a -> content1 -> content2".
var eventParent = child;
var tmp;
while (tmp = eventParentTable.get(eventParent)) {
eventParent = tmp;
}
if (eventParent !== insertionPoint)
eventParentTable.set(eventParent, insertionPoint);

eventParentTable.set(eventParent, insertionPoint);
eventParentTable.set(insertionPoint, undefined);
}

function resetDistributedChildNodes(insertionPoint) {
Expand Down Expand Up @@ -181,12 +185,9 @@
if (!anyRemoved)
return pool;

var newPool = [];
for (var i = 0; i < pool.length; i++) {
if (pool[i] !== undefined)
newPool.push(pool[i]);
}
return newPool;
return pool.filter(function(item) {
return item !== undefined;
});
}

// Matching Insertion Points
Expand Down Expand Up @@ -283,6 +284,15 @@
this.associateNode(host);
}

function getRendererForHost(host) {
var renderer = rendererForHostTable.get(host);
if (!renderer) {
renderer = new ShadowRenderer(host);
rendererForHostTable.set(host, renderer);
}
return renderer;
}

ShadowRenderer.prototype = {
// http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#rendering-shadow-trees
render: function() {
Expand Down Expand Up @@ -318,7 +328,7 @@
renderNode: function(visualParent, tree, node, isNested) {
if (isShadowHost(node)) {
this.appendChild(visualParent, node);
var renderer = new ShadowRenderer(node);
var renderer = getRendererForHost(node);
renderer.render();
} else if (isInsertionPoint(node)) {
this.renderInsertionPoint(visualParent, tree, node, isNested);
Expand Down Expand Up @@ -451,21 +461,21 @@

function isInsertionPoint(node) {
// Should this include <shadow>?
return node.tagName == 'CONTENT';
return node.localName === 'content';
}

function isActiveInsertionPoint(node) {
// <content> inside another <content> or <shadow> is considered inactive.
return node.tagName === 'CONTENT';
return node.localName === 'content';
}

function isShadowInsertionPoint(node) {
return node.tagName === 'SHADOW';
return node.localName === 'shadow';
}

function isActiveShadowInsertionPoint(node) {
// <shadow> inside another <content> or <shadow> is considered inactive.
return node.tagName === 'SHADOW';
return node.localName === 'shadow';
}

function isShadowHost(shadowHost) {
Expand All @@ -491,9 +501,7 @@
}

function assignShadowTreeToShadowInsertionPoint(tree, point) {
// TODO: No one is reading the map below.
// console.log('Assign %o to %o', tree, point);
// treeToShadowInsertionPointMap.set(tree, point);
insertionParentTable.set(tree, point);
}

// http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#rendering-shadow-trees
Expand Down Expand Up @@ -527,8 +535,8 @@
}
});

scope.ShadowRenderer = ShadowRenderer;
scope.eventParentTable = eventParentTable;
scope.getRendererForHost = getRendererForHost;
scope.getShadowTrees = getShadowTrees;
scope.nextOlderShadowTreeTable = nextOlderShadowTreeTable;
scope.renderAllPending = renderAllPending;
Expand Down
2 changes: 1 addition & 1 deletion src/wrappers/Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
var newShadowRoot = new wrappers.ShadowRoot(this);
shadowRootTable.set(this, newShadowRoot);

var renderer = new scope.ShadowRenderer(this);
var renderer = scope.getRendererForHost(this);

this.invalidateShadowRenderer();

Expand Down
64 changes: 64 additions & 0 deletions test/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -965,5 +965,69 @@ test('retarget order (multiple shadow roots)', function() {
assert.equal(e, wrap(unwrap(e)));
});

test('event path in presence of shadow element', function() {
var div = document.createElement('div');

var menuButton = document.createElement('menu-button');
menuButton.innerHTML = '<a></a><b></b>';
var a = menuButton.firstChild;
var b = menuButton.lastChild;

var menuButtonSr = menuButton.createShadowRoot();
menuButtonSr.innerHTML = '<menu><content name="menu-button"></content></menu>';
var menu = menuButtonSr.firstChild;
var menuButtonContent = menu.firstChild;

var selectorSr = menu.createShadowRoot();
selectorSr.innerHTML = '<content name="selector"></content>';
var selectorContent = selectorSr.firstChild;

var menuSr = menu.createShadowRoot();
menuSr.innerHTML = 'xxx<shadow name="menu"></shadow>xxx';
var menuShadow = menuSr.firstElementChild;

menuButton.offsetWidth;

var tree = {
div: div,
menuButton: menuButton,
a: a,
b: b,
menuButtonSr: menuButtonSr,
menu: menu,
menuButtonContent: menuButtonContent,
menuSr: menuSr,
menuShadow: menuShadow,
selectorSr: selectorSr,
selectorContent: selectorContent,
};

var log = [];
addListeners(tree, 'x', log);

a.dispatchEvent(new Event('x', {bubbles: true}));

var expected = [
'menuButton, a, undefined, CAPTURING_PHASE',
'menuButtonSr, a, undefined, CAPTURING_PHASE',
'menu, a, undefined, CAPTURING_PHASE',
'menuSr, a, undefined, CAPTURING_PHASE',
'menuShadow, a, undefined, CAPTURING_PHASE',
'selectorSr, a, undefined, CAPTURING_PHASE',
'selectorContent, a, undefined, CAPTURING_PHASE',
'menuButtonContent, a, undefined, CAPTURING_PHASE',
'a, a, undefined, AT_TARGET',
'a, a, undefined, AT_TARGET',
'menuButtonContent, a, undefined, BUBBLING_PHASE',
'selectorContent, a, undefined, BUBBLING_PHASE',
'selectorSr, a, undefined, BUBBLING_PHASE',
'menuShadow, a, undefined, BUBBLING_PHASE',
'menuSr, a, undefined, BUBBLING_PHASE',
'menu, a, undefined, BUBBLING_PHASE',
'menuButtonSr, a, undefined, BUBBLING_PHASE',
'menuButton, a, undefined, BUBBLING_PHASE',
];
assertArrayEqual(expected, log);
});

});

0 comments on commit 5ccb302

Please sign in to comment.