Skip to content

Instantly share code, notes, and snippets.

@tomalec
Last active February 8, 2018 01:03
Show Gist options
  • Save tomalec/a20af4eee86640defdc7aeccccc78c1c to your computer and use it in GitHub Desktop.
Save tomalec/a20af4eee86640defdc7aeccccc78c1c to your computer and use it in GitHub Desktop.
<div id="host-1"><shadowroot mode="open">shadow</shadowroot></div>
<script>
it('Once parsed should create shadow root in parent element - **host**, and append own content into there.', function() {
const host = document.querySelector('#host-1');
assert(host.shadowRoot, "should have shadowRoot property attached");
assert(host.shadowRoot.innerHTML === 'shadow');
});
</script>
<div id="host-1"></div>
<script>
it('`host.innerHTML = \'<shadowroot>shadow</shadowroot>light\'` gets parsed and processed as declarative shadow dom', ()=>{
const host = document.querySelector('#host-1');
host.innerHTML = `<shadowroot mode="open">shadow</shadowroot>light`;
assert(host.shadowRoot, "should have shadowRoot property attached");
assert(host.shadowRoot.innerHTML === 'shadow');
});
</script>
<div id="host-2"></div>
<script>
it('Once parsed <shadowroot> must not appear in host.childNodes, nor host.children list. ', function() {
const host = document.querySelector('#host-2');
host.innerHTML = `<shadowroot mode="open">shadow</shadowroot>`;
assert(!host.hasChildNodes());
assert(host.children.length === 0);
});
</script>
<div id="host-3"></div>
<script>
it('Once parsed <shadowroot> must not appear in `host.innerHTML`', function() {
const host = document.querySelector('#host-3');
host.innerHTML = `<shadowroot mode="open">shadow</shadowroot>`;
assert(host.innerHTML === '');
});
</script>
<div id="host-4"></div>
<script>
it("`host.appendChild(document.createElement('shadowroot'))` does append `HTMLUnknownElement`", function() {
const host = document.querySelector('#host-4');
const sroot = document.createElement('shadowroot');
sroot.setAttribute('mode', 'open');
host.appendChild(sroot);
assert(!host.shadowRoot);
assert(host.hasChildNodes());
assert(host.children.length === 1);
assert(host.children[0] instanceof HTMLUnknownElement);
});
</script>
<div id="fixture-container"></div>
<script>
var container = document.querySelector('#fixture-container');
afterEach(function() {
container.innerHTML = '';
});
it('with mode set to "open", should create open shadow root', function() {
host = document.createElement('div');
container.appendChild(host);
host.innerHTML = `<shadowroot mode="open">shadow</shadowroot>`;
assert(host.shadowRoot, "should have shadowRoot property attached");
});
it('with mode set to "closed", should create closed shadow root', function() {
host = document.createElement('div');
container.appendChild(host);
host.innerHTML = '<span>I am green</span><shadowroot mode="closed"><style>::slotted(span){color:green; display: flex;}</style><slot></slot></shadowroot>';
assert(!host.shadowRoot, "should not have shadowRoot property attached");
// check presence of closed shadow dom, by checkin if styles were applied
assert(window.getComputedStyle(host.firstElementChild).display === 'flex');
});
describe('with mode set to "foo", ', function() {
var host;
beforeEach(function() {
host = document.createElement('div');
container.appendChild(host);
host.innerHTML = '<span>I am black</span><shadowroot mode="foo"><style>::slotted(span){color:green; display: flex;}</style><slot></slot></shadowroot>';
});
it('should not create shadow root', function() {
assert(!host.shadowRoot, "should not have shadowRoot property attached");
// check presence of closed shadow dom, by checkin if styles were applied
assert(!(window.getComputedStyle(host.firstElementChild).display === 'flex'), 'should not attach closed shadow root => should apply styles');
});
it('should keep `<shadowroot>` as `HTMLUnknownElement`', function() {
assert(host.querySelector('shadowroot') !== null);
assert(host.querySelector('shadowroot') instanceof HTMLUnknownElement);
});
});
describe('with mode attribute not set, ', function() {
var host;
beforeEach(function() {
host = document.createElement('div');
container.appendChild(host);
host.innerHTML = '<span>I am black</span><shadowroot><style>::slotted(span){color:green; display: flex;}</style><slot></slot></shadowroot>';
});
it('should not create shadow root', function() {
assert(!host.shadowRoot);
// check presence of closed shadow dom, by checking if styles were applied
assert(!(window.getComputedStyle(host.firstElementChild).display === 'flex'), 'should not attach closed shadow root => should apply styles');
});
it('should keep `<shadowroot>` as `HTMLUnknownElement`', function() {
assert(host.querySelector('shadowroot') !== null);
assert(host.querySelector('shadowroot') instanceof HTMLUnknownElement);
});
});
</script>
<div id="host-6"><shadowroot mode="open"><script>window['dsd-script-executed'] = true;</script></shadowroot></div>
<script>
it('Scripts in <shadowroot> are processed', function() {
const host = document.querySelector('#host-6');
assert(window['dsd-script-executed'] === true);
});
</script>
<div id="host-7"><shadowroot mode="open">shadow</shadowroot></div>
<script>
describe('declarative-shadow-dom', function() {
it('calling attachShadow on the element that already has the shadow root attached by declarative <shadowroot> must behave exactly the same as for double imperative call - throw', function() {
const host = document.querySelector('#host-7');
function callAttachShadow(){
host.attachShadow({mode:'open'});
}
expect(callAttachShadow).to.throw();
});
});
</script>
<select id="host-8"></select>
<script>
it('element cannot be used in the elements that cannot have shadow root (see the list for imperative API), in such cases it becomes `HTMLUnknownElement`', function() {
const host = document.querySelector('#host-8');
window.onerror = function(message){
assert(message.includes('Shadow') || message.includes('shadow'), "should throw error about Shadow DOM");
return true
};
host.innerHTML = `<shadowroot mode="open">shadow</shadowroot>`;
assert(!host.shadowRoot, "should not have shadowRoot property attached");
});
</script>
<div id="host-9"></div>
<script>
var host;
before(function(){
host = document.querySelector('#host-9');
host.attachShadow({mode:'open'});
host.shadowRoot.innerHTML = 'already got one';
});
it('<shadowroot> element used in the elements that already have a shadow root must not try to attach Shadow Root and must not appear in `childNodes`', function(done) {
host.innerHTML = `<shadowroot mode="open">new shadow</shadowroot>`;
assert(host.shadowRoot, "should have shadowRoot property attached");
assert(host.shadowRoot.innerHTML === 'already got one', "shadowRoot should contain the old one");
assert(host.childNodes.length === 0, "must not appear in `childNodes`");
});
</script>
<div id="host-10"><shadowroot mode="open">already got one</shadowroot></div>
<script>
it('Another (valid) <shadowroot mode="open|closed"> inside the node that already has a parsed <shadowroot>, should make the same effect as <shadowroot> in the element that already has shadow root.', function(done) {
host = document.querySelector('#host-10');
host.innerHTML = `<shadowroot mode="open">new shadow</shadowroot>`;
assert(host.shadowRoot, "should have shadowRoot property attached");
assert(host.shadowRoot.innerHTML === 'already got one', "shadowRoot should contain the old one");
assert(host.childNodes.length === 0, "must not appear in `childNodes`");
});
</script>
<template id="template-10">
<div id="host-10"><shadowroot mode="open">shadow</shadowroot></div>
</template>
<div id="container"></div>
<script>
describe('<shadowroot> can be used inside the content of a <template>', function() {
var host;
before(function(){
template = document.querySelector('#template-10');
host = template.content.querySelector('#host-10');
});
it('should not attach a shadow root to its parent element', function() {
assert(!host.shadowRoot, "should not have shadowRoot property attached");
});
it('should be available in `.childNodes` as `HTMLShadowRootElement`', function() {
assert(host.childNodes[0], "should appear in childNodes");
assert(host.childNodes[0], "should be HTMLShadowRootElement");
});
describe('once template is cloned and connected to the document', function(){
var clonedHost;
before(function(){
const clone = document.importNode(template.content, true);
clonedHost = clone.querySelector('#host-10');
document.querySelector('#container').appendChild(clone);
});
it('should attach a shadow root to its parent element', function() {
assert(clonedHost.shadowRoot, "should have shadowRoot property attached");
assert(clonedHost.shadowRoot.innerHTML === 'shadow');
});
it('should not be available in `.childNodes`', function() {
assert(clonedHost.childNodes.length == 0, "should not appear in childNodes");
});
});
});
</script>
<h1>Set of tests for Delcarative Shadow DOM proposal</h1>
<p>to be updated ad provided for each rule</p>
<!-- Fixtures -->
<div id="host-1"><shadowroot mode="open">shadow</shadowroot></div>
<script>
it('Once parsed should create shadow root in parent element - **host**, and append own content into there.', ()=>{
const host = document.querySelector('#host-1');
assert(host.shadowRoot);
});
it('`host.innerHTML = \'<shadowroot>shadow</shadowroot>light\'` gets parsed and processed as declarative shadow dom', ()=>{
const host = document.createElement('div');
host.innerHTML = `<shadowroot mode="open">shadow</shadowroot>light`;
assert(host.shadowRoot);
});
it('Once parsed it must not appear in `host.childNodes`, nor `host.children` list.', ()=>{
const host = document.createElement('div');
host.innerHTML = `<shadowroot mode="open">shadow</shadowroot>`;
assert(!host.hasChildNodes());
assert(host.children.length === 0);
});
it('`host.appendChild(document.createElement(\'shadowroot\'))` does append `HTMLUnknownElement`', ()=>{
const host = document.createElement('div');
const sroot = document.createElement('shadowroot');
sroot.mode = 'open';
host.appendChild(sroot);
assert(!host.shadowRoot);
assert(host.hasChildNodes());
assert(host.children.length === 1);
assert(host.children[1] instanceof HTMLUnknownElement);
});
it('It should have `mode` attribute equal to `open` or `closed`, otherwise process as `HTMLUnknownElement`', ()=>{
const host = document.createElement('div');
host.innerHTML = `<shadowroot mode="open">shadow</shadowroot>`;
assert(host.shadowRoot);
assert(!host.hasChildNodes());
assert(host.children.length === 0);
host.innerHTML = `<shadowroot mode="closed">shadow</shadowroot>`;
assert(!host.hasChildNodes());
assert(host.children.length === 0);
host.innerHTML = `<shadowroot mode="foo">shadow</shadowroot>`;
assert(!host.shadowRoot);
assert(host.hasChildNodes());
assert(host.children.length === 1);
assert(host.children[1] instanceof HTMLUnknownElement);
host.innerHTML = `<shadowroot>shadow</shadowroot>`;
assert(!host.shadowRoot);
assert(host.hasChildNodes());
assert(host.children.length === 1);
assert(host.children[1] instanceof HTMLUnknownElement);
});
// Proposed by @hayatoito at https://github.com/whatwg/dom/issues/510#issuecomment-331323635
// Construct a dom tree in an imperative way
const p = document.createElement('div');
const s = document.createElement('shadowroot');
s.mode = "open";
p.appendChild(s);
assert(p.hasChildNodes());
assert(!p.shadowRoot);
// Then, we *serialize* and *deserialize* |p|.
const inner_html = p.innerHTML;
assert(inner_html === '<shadowroot mode="open"></shadowroot>');
p.innerHTML = inner_html;
// Now, |p| changed.
assert(!p.hasChildNodes());
assert(p.shadowRoot);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment