Skip to content

Commit

Permalink
Add ability to clone a template containing declarative Shadow DOM
Browse files Browse the repository at this point in the history
Prior to this CL, this would not work correctly:

<template id=target>
  <div>
    <template shadowroot=open>Content</template>
  </div>
</template>

<script>
  document.body.appendChild(target.content.cloneNode(true));
</script>

The inner declarative Shadow DOM (<template shadowroot>) would not get
cloned from the template content to the clone. With this CL, it now
works correctly. Several tests were added to test nested template
and declarative Shadow DOM nodes.

This CL mirrors the DOM spec changes made in [1].

[1] whatwg/dom#858

Bug: 1042130
Change-Id: I05792e038dc694ac00d13531c657afaed754f747
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2175062
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
Commit-Queue: Mason Freed <masonfreed@chromium.org>
Auto-Submit: Mason Freed <masonfreed@chromium.org>
Cr-Commit-Position: refs/heads/master@{#766528}
  • Loading branch information
mfreed7 authored and chromium-wpt-export-bot committed May 7, 2020
1 parent 928a59a commit 6565926
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
70 changes: 70 additions & 0 deletions shadow-dom/declarative/declarative-shadow-dom-basic.tentative.html
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,76 @@

</script>

<template id="template-containing-shadow">
<div class="innerdiv">
<template shadowroot=open>Content</template>
</div>
</template>
<script>
test(() => {
const template = document.querySelector('#template-containing-shadow');
const host1 = document.createElement('div');
document.body.appendChild(host1);
host1.appendChild(template.content.cloneNode(true));
let innerDiv = host1.querySelector('div.innerdiv');
const shadowRoot1 = innerDiv.shadowRoot;
assert_true(!!shadowRoot1,"Inner div should have a shadow root");
assert_equals(innerDiv.querySelector('template'), null, "No leftover template node");

const host2 = document.createElement('div');
document.body.appendChild(host2);
host2.appendChild(template.content.cloneNode(true));
innerDiv = host2.querySelector('div.innerdiv');
const shadowRoot2 = innerDiv.shadowRoot;
assert_true(!!shadowRoot2,"Inner div should have a shadow root");
assert_equals(innerDiv.querySelector('template'), null, "No leftover template node");

assert_not_equals(shadowRoot1,shadowRoot2,'Should not get back the same shadow root');
}, 'Declarative Shadow DOM: template containing declarative shadow root');
</script>

<template id="template-containing-ua-shadow">
<div class="innerdiv">
<template shadowroot=open>
<video></video> <!--Assumed to have UA shadow root-->
</template>
</div>
</template>
<script>
test(() => {
const template = document.querySelector('#template-containing-ua-shadow');
const host = document.createElement('div');
document.body.appendChild(host);
// Mostly make sure clone of template *does* clone the
// shadow root, and doesn't crash on cloning the <video>.
host.appendChild(template.content.cloneNode(true));
let innerDiv = host.querySelector('div.innerdiv');
const shadowRoot = innerDiv.shadowRoot;
assert_true(!!shadowRoot,"Inner div should have a shadow root");
assert_equals(innerDiv.querySelector('template'), null, "No leftover template node");
assert_true(!!innerDiv.shadowRoot.querySelector('video'),'Video element should be present');
}, 'Declarative Shadow DOM: template containing declarative shadow root and UA shadow root');
</script>

<template id="template-containing-ua-shadow-closed">
<div class="innerdiv">
<template shadowroot=closed>
<video></video> <!--Assumed to have UA shadow root-->
</template>
</div>
</template>
<script>
test(() => {
const template = document.querySelector('#template-containing-ua-shadow-closed');
const host = document.createElement('div');
document.body.appendChild(host);
host.appendChild(template.content.cloneNode(true));
let innerDiv = host.querySelector('div.innerdiv');
// TODO(masonfreed): once ElementInternals.shadowRoot exists, check for it here.
assert_true(!innerDiv.shadowRoot,"Inner div should have a closed shadow root");
}, 'Declarative Shadow DOM: template containing closed declarative shadow root and UA shadow root');
</script>

<template id="root-element-shadow">
<template shadowroot=open>Content</template>
</template>
Expand Down
5 changes: 5 additions & 0 deletions shadow-dom/declarative/script-access.tentative.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
assert_equals(n.content, null, 'Declarative template content should *still* be null');
assert_equals(n.innerHTML, "", 'Declarative template innerHTML should *still* be empty');
assert_equals(n.getInnerHTML({includeShadowRoots: true}), "", 'Declarative template getInnerHTML() should *still* be empty');

// Try cloning the in-progress declarative template - shouldn't work.
const clone = n.cloneNode(true);
assert_equals(clone.children.length,0,'Clone should not contain anything');
assert_equals(clone.content.children.length,0,'Clone should not contain anything');
break;
case 'noroot':
// Make sure adding 'shadowroot' attribute doesn't trigger a shadow root,
Expand Down

0 comments on commit 6565926

Please sign in to comment.