shadow-root-clonable.html (3823B)
1 <!DOCTYPE html> 2 <title>Shadow root clonable flag</title> 3 <link rel='author' href='mailto:krosylight@mozilla.com'> 4 <link rel='author' href='mailto:masonf@chromium.org'> 5 <link rel='help' href='https://dom.spec.whatwg.org/#shadowroot-clonable'> 6 <link rel='help' href='https://github.com/whatwg/dom/issues/1249#issuecomment-1917772229'> 7 <script src='/resources/testharness.js'></script> 8 <script src='/resources/testharnessreport.js'></script> 9 10 <body> 11 <script> 12 test(() => { 13 const div = document.createElement("div"); 14 const root = div.attachShadow({ mode: "open", clonable: true }); 15 root.innerHTML = '<input><div><span></span></div>'; 16 assert_true(root.clonable, "clonable attribute"); 17 18 const clone = div.cloneNode(true); 19 const clonedRoot = clone.shadowRoot; 20 assert_true(clonedRoot.clonable, "clone gets the same clonable state"); 21 assert_equals(clonedRoot.children.length, 2, "children count"); 22 assert_equals(clonedRoot.children[0].localName, "input", "children content"); 23 assert_equals(clonedRoot.children[1].firstElementChild.localName, "span", "grandchildren content"); 24 25 const shallowClone = div.cloneNode(false); 26 const shallowClonedRoot = shallowClone.shadowRoot; 27 assert_true(shallowClonedRoot.clonable, "clone gets the same clonable state"); 28 assert_equals(shallowClonedRoot.children.length, 2, "shallow clone still deep-clones the shadow root"); 29 assert_equals(shallowClonedRoot.children[0].localName, "input", "shadow children content"); 30 assert_equals(shallowClonedRoot.children[1].firstElementChild.localName, "span", "shadow grandchildren content"); 31 }, "attachShadow with clonable: true"); 32 33 for (const clonable of [false, undefined]) { 34 test(() => { 35 const div = document.createElement("div"); 36 const root = div.attachShadow({ mode: "open", clonable }); 37 root.appendChild(document.createElement("input")); 38 assert_false(root.clonable, "clonable attribute"); 39 40 const clone = div.cloneNode(true); 41 assert_true(!clone.shadowRoot, "shadow should not be cloned"); 42 }, `attachShadow with clonable: ${clonable}`); 43 } 44 45 test(() => { 46 const div = document.createElement("div"); 47 div.setHTMLUnsafe('<div><template shadowrootmode=open><input></template></div>'); 48 const root = div.firstElementChild.shadowRoot; 49 assert_true(!!root); 50 assert_false(root.clonable, "clonable is *not* automatically true for declarative shadow root"); 51 52 const clone = div.cloneNode(true); 53 const clonedRoot = clone.firstElementChild.shadowRoot; 54 assert_true(!clonedRoot,'no shadow root gets cloned'); 55 }, "declarative shadow roots do *not* get clonable: true automatically"); 56 57 test(() => { 58 const div = document.createElement("div"); 59 div.setHTMLUnsafe('<div><template shadowrootmode=open shadowrootclonable><input></template></div>'); 60 const root = div.firstElementChild.shadowRoot; 61 assert_true(!!root); 62 assert_true(root.clonable, "clonable gets added when shadowrootclonable is present"); 63 64 const clone = div.cloneNode(true); 65 const clonedRoot = clone.firstElementChild.shadowRoot; 66 assert_true(!!clonedRoot); 67 assert_equals(clonedRoot.children.length, 1, "children count"); 68 assert_equals(clonedRoot.children[0].localName, "input", "children content"); 69 }, "declarative shadow roots can opt in to clonable with shadowrootclonable"); 70 </script> 71 72 <template id="test"> 73 <div id="host"> 74 <template shadowrootmode=open><input></template> 75 </div> 76 </template> 77 78 <script> 79 test(() => { 80 const template = document.querySelector('#test'); 81 const root = template.content.querySelector('#host').shadowRoot; 82 assert_true(!!root); 83 const clone = template.content.cloneNode(true); 84 const clonedRoot = clone.querySelector('#host').shadowRoot; 85 assert_true(!clonedRoot,'no shadow root gets cloned'); 86 }, "declarative shadow roots inside templates do *not* get cloned automatically"); 87 </script>