Skip to content

Commit

Permalink
Add support for the shadow root clonable flag
Browse files Browse the repository at this point in the history
This landed in the these two spec PRs:

  whatwg/dom#892
  whatwg/dom#1237

and was discussed here:

  whatwg/dom#1137
  whatwg/dom#1236

This CL adds support for clonable, behind a new ShadowRootClonable
flag. There was already a very basic test, but I added a few
more cases.

This should be fairly web compatible, but there is a risk since with
this feature enabled, declarative shadow roots in the main document
(as opposed to in a <template> element) will now be cloned. I will
launch this feature carefully. Safari has already shipped, and Gecko
has implemented this and plans to ship soon.

Chromestatus:
https://chromestatus.com/feature/5161435196030976

I2P:
https://groups.google.com/a/chromium.org/g/blink-dev/c/nZhPt0ePCAA

Fixed: 1510466
Change-Id: Ie25b72f369ca0542555f91010b0f22d295403728
  • Loading branch information
mfreed7 authored and chromium-wpt-export-bot committed Jan 27, 2024
1 parent 2901a5a commit 46e59f4
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 10 deletions.
10 changes: 0 additions & 10 deletions shadow-dom/declarative/clonable.window.js

This file was deleted.

54 changes: 54 additions & 0 deletions shadow-dom/shadow-root-clonable.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!DOCTYPE html>
<title>Shadow root clonable flag</title>
<link rel='author' href='mailto:krosylight@mozilla.com'>
<link rel='author' href='mailto:masonf@chromium.org'>
<link rel='help' href='https://dom.spec.whatwg.org/#shadowroot-clonable'>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>

<body>
<script>
test(() => {
const div = document.createElement("div");
const root = div.attachShadow({ mode: "open", clonable: true });
root.appendChild(document.createElement("input"));
assert_true(root.clonable, "clonable attribute");

const clone = div.cloneNode(true);
const clonedRoot = clone.shadowRoot;
assert_true(clonedRoot.clonable, "clone gets the same clonable state");
assert_equals(clonedRoot.children.length, 1, "children count");
assert_equals(clonedRoot.children[0].localName, "input", "children content");

const shallowClone = div.cloneNode(false);
const shallowClonedRoot = shallowClone.shadowRoot;
assert_true(shallowClonedRoot.clonable, "clone gets the same clonable state");
assert_equals(shallowClonedRoot.children.length, 0, "shallow");
}, "attachShadow with clonable: true");

for (const clonable of [false, undefined]) {
test(() => {
const div = document.createElement("div");
const root = div.attachShadow({ mode: "open", clonable });
root.appendChild(document.createElement("input"));
assert_false(root.clonable, "clonable attribute");

const clone = div.cloneNode(true);
assert_true(!clone.shadowRoot, "shadow should not be cloned");
}, `attachShadow with clonable: ${clonable}`);
}

test(() => {
const div = document.createElement("div");
div.setHTMLUnsafe('<div><template shadowrootmode=open><input></template></div>');
const root = div.firstElementChild.shadowRoot;
assert_true(!!root);
assert_true(root.clonable, "clonable is automatically true for declarative shadow root");

const clone = div.cloneNode(true);
const clonedRoot = clone.firstElementChild.shadowRoot;
assert_true(!!clonedRoot);
assert_equals(clonedRoot.children.length, 1, "children count");
assert_equals(clonedRoot.children[0].localName, "input", "children content");
}, "declarative shadow roots get clonable: true automatically");
</script>

0 comments on commit 46e59f4

Please sign in to comment.