Skip to content

Commit

Permalink
Fixed handling of <content> outside a Shadow DOM (#3656)
Browse files Browse the repository at this point in the history
Fixed handling of <content> outside a Shadow DOM

It turns out that some folks are putting stuff inside a content tag and
expecting it to be displayed if the tag is outside a shadow DOM (and
replaced if it's inside a shadow DOM).

While investigating this, I discovered that we need to support Shadow
DOM v1 as well the (deprecated) Shadow DOM v0 API that we currently use.
Expect further patches...
  • Loading branch information
mcharsley authored and juangj committed Mar 17, 2017
1 parent 8cb6e19 commit d98e795
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 11 deletions.
25 changes: 18 additions & 7 deletions javascript/atoms/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -1269,13 +1269,24 @@ bot.dom.appendVisibleTextLinesFromNodeInComposedDom_ = function(
var castElem = /** @type {!Element} */ (node);

if (bot.dom.isElement(node, 'CONTENT')) {
// If the element is <content> then just append the contents of the
// nodes that have been distributed into it.
var contentElem = /** @type {!Object} */ (node);
goog.array.forEach(contentElem.getDistributedNodes(), function(node) {
bot.dom.appendVisibleTextLinesFromNodeInComposedDom_(
node, lines, shown, whitespace, textTransform);
});
var parentNode = node;
while (parentNode.parentNode) {
parentNode = parentNode.parentNode;
}
if (parentNode instanceof ShadowRoot) {
// If the element is <content> and we're inside a shadow DOM then just
// append the contents of the nodes that have been distributed into it.
var contentElem = /** @type {!Object} */ (node);
goog.array.forEach(contentElem.getDistributedNodes(), function(node) {
bot.dom.appendVisibleTextLinesFromNodeInComposedDom_(
node, lines, shown, whitespace, textTransform);
});
} else {
// if we're not inside a shadow DOM, then we just treat <content>
// as an unknown element and use anything inside the tag
bot.dom.appendVisibleTextLinesFromElementInComposedDom_(
castElem, lines);
}
} else if (bot.dom.isElement(node, 'SHADOW')) {
// if the element is <shadow> then find the owning shadowRoot
var parentNode = node;
Expand Down
22 changes: 18 additions & 4 deletions javascript/atoms/test/html5/shadow_dom_test.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ <H1>Page for Shadow DOM chromedriver tests</H1>
Base-level Stuff
</div>
</div>
<div id="divWithNoShadowDOM">
<content>
Text inside a content tag outside any shadow DOM. Should be displayed
</content>

<template id="parentTemplate">
<div id="parentDiv">
Expand All @@ -38,7 +42,9 @@ <H3 id="olderHeading">Older Child</H3>
As the older child of a nested shadow root, this is the most likely
to go wrong bit of the page.
<H4>Older Child Contents</H4>
<content></content>
<content>
Text inside the older child content tag. Should be replaced
</content>
</div>
</div>
</template>
Expand All @@ -48,7 +54,9 @@ <H4>Older Child Contents</H4>
<H3>Younger Child</H3>
<div style="border-style:dotted;border-color:blue">
<H4>Younger Child Contents</H4>
<content id="youngChildContent" select=".stuffForYoungChild"></content>
<content id="youngChildContent" select=".stuffForYoungChild">
Text inside the younger content tag. Should be replaced
</content>
</div>
<div style="border-style:dashed;border-color:blue">
<H4>Younger Child Shadow</H4>
Expand Down Expand Up @@ -121,6 +129,8 @@ <H4>Younger Child Shadow</H4>
"* /deep/ #youngerChildDiv"));
var olderChildDiv = /** @type {!Element} */ (document.querySelector(
"* /deep/ #olderChildDiv"));
var divWithNoShadowDOM = /** @type {!Element} */ (document.querySelector(
"#divWithNoShadowDOM"));
var expectedOlderChildContents = "Older Child\n" +
"As the older child of a nested shadow root, this is the most " +
"likely to go wrong bit of the page.\n" +
Expand All @@ -137,19 +147,23 @@ <H4>Younger Child Shadow</H4>

var expectedParentContents = expectedYoungerChildContents;

var expectedOutsideShadowDomContents = "Text inside a content tag " +
"outside any shadow DOM. Should be displayed";

var expectedPageContents = "Page for Shadow DOM chromedriver tests\n" +
"The page has a shadow root that in turn contains two shadow roots. " +
"So we can check behaviour with both nested roots and younger/" +
"older sibling roots. The various sections are highlighted with " +
"colored borders to make it more obvious where each element comes " +
"from.\n" +
expectedParentContents;
expectedParentContents + "\n" + expectedOutsideShadowDomContents;

assertEquals(expectedOlderChildContents,
bot.dom.getVisibleText(olderChildDiv));
assertEquals(expectedYoungerChildContents,
bot.dom.getVisibleText(youngerChildDiv));
assertEquals(expectedParentContents, bot.dom.getVisibleText(parentDiv));
assertEquals(expectedOutsideShadowDomContents, bot.dom.getVisibleText(divWithNoShadowDOM));
assertEquals(expectedPageContents,
bot.dom.getVisibleText(/** @type {!Element} */ (document.body)));
}
Expand Down

0 comments on commit d98e795

Please sign in to comment.