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

Bug: 1510466
Change-Id: Ie25b72f369ca0542555f91010b0f22d295403728
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5239277
Auto-Submit: Mason Freed <masonf@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Commit-Queue: David Baron <dbaron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1253059}
  • Loading branch information
Mason Freed authored and marcoscaceres committed Feb 23, 2024
1 parent 6868aef commit 54df64f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 10 deletions.
10 changes: 0 additions & 10 deletions shadow-dom/declarative/clonable.window.js

This file was deleted.

49 changes: 49 additions & 0 deletions shadow-dom/shadow-root-clonable.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!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");
}, "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 54df64f

Please sign in to comment.