Search code examples
javascripthtmlweb-componentshadow-domslot

HTML Templates Slots and Teats on a bull


Can someone confirm, or point me to proposed documentation for, the rules for matching a Host Element's "slot=" designator with a Template's <slot> tag?

I had very much hoped that it was a simply NAME matching process regardless of depth/position of the corresponding Slots in the Light DOM versus the Shadow DOM, but, sadly, it appears that ancestry lineage is an overriding factor. IOW a child slot in the Light DOM will not populate a grandchild slot in the shadow DOM even if names match. Is this correct?

It reminds me very much of COBOL's MOVE CORR rules regarding Levels but surely this restriction presupposes the main-page author's intimate knowledge of the Component's Shadow DOM rendering SLOTs unfit for purpose?

Browser: Chrome 58.0.3029.96 (64-bit)

This seems to say descendant depth should not be an issue as long as roots are ok. Or have I read it wrong?

Example:

<!DOCTYPE html>
<html>
<head>
<template id="contact-template">
    <style>
        :host { border: solid 1px #ccc; border-radius: 0.5rem; padding: 0.5rem; margin: 0.5rem; }
        b { display: inline-block; width: 5rem; }
    </style>
    <b>HELLO</b><br/>
    <b>Name</b>: <slot name="fullName"><slot name="firstName"></slot> <slot name="lastName"></slot></slot><br>
    <b>Email</b>: <slot name="email">Unknown</slot><br>
    <b>Address</b>: <slot name="address">Unknown</slot>
    <slot></slot>
</template>
<script>
window.addEventListener('DOMContentLoaded', function () {
  var contacts = document.getElementById('contacts').children;
    var template = document.getElementById('contact-template').content;
    alert("Hello"+contacts.length);
        document.getElementById("d").attachShadow({mode: 'open'}).appendChild(template.cloneNode(true));

    return;

    for (var i = 0; i < contacts.length; i++)
        contacts[i].attachShadow({mode: 'open'}).appendChild(template.cloneNode(true));
});
</script>
</head>
<body onload="load()">

<p id="demo">Click the button to change the text in this paragraph.</p>

<button onclick="myFunction()">Try it</button>
<div id="contacts">
<div id="d">
<span slot="email">span it</span>
  <div name="removeToWork">
        <div slot="fullName">Commit Queue</div>
        (<a slot="email" href="mailto:[email protected]">[email protected]</a>)<br>
        <span slot="address">One Infinite Loop, Cupertino, CA 95014</span>
  </div>
</div>


<script>
function myFunction() {
    document.getElementById("demo").innerHTML = "Hello World";
}

function load() {

}

</script>

</body>
</html>

Solution

  • The slotable (an element with the slot attribute) will be inserted in the shadow DOM only if it's a direct child of the shadow DOM host.

    From the specification:

    1. For each slotable child of host, slotable, in tree order, run these substeps:

    So grandchilds won't match.

    <div id="host">
      <div slot="s1">Can match</div>
      <div slot="s2">Can match</div>
      <div>
         <div slot="s3">Won't match</div>
      </div>
    </div>