Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix HTMLTemplateElement implementation to reflect standards behavior #63

Merged

Conversation

thescientist13
Copy link
Member

@thescientist13 thescientist13 commented Jun 11, 2022

Related Issue

resolves #51

Summary of Changes

  1. Update dom-shim.js to correctly have the <template> tag logic inside HTMLTemplateElement
  2. Updated specs slightly to reflect correct <template> implementation
  3. Update documentation site off of incorrect <template> implementation

TODO

  1. Make sure this.mode works from attachShadow - support configurable shadowroot attribute for <template> tags #65
  2. Downstream sanity testing
    • WC@TheEdge
    • Greenwood

Questions

  1. Cross reference with getInnerHTML to make sure things are / will be still compatible -verify / ensure proper serialization of shadow roots excluding closed shadow roots from getInnerHTML #16
  2. do we need a get innerHTML for HTMLTemplateElement? - tracked in `<template>` tags with variable interpolation for Declarative Shadow DOM #66
  3. Create a discussion for better way to use <templates> but with variables / template literal placeholders. Or just create render functions?.... But then you lose the free <template> tag from using document.createElement('template'). Maybe create some experimental set function for template.innerHTML = '....' that can take args and destructure them? - `<template>` tags with variable interpolation for Declarative Shadow DOM #66

@thescientist13 thescientist13 added the bug Something isn't working label Jun 11, 2022
@thescientist13 thescientist13 changed the title refactor HTMLTemplateElement implementation to manage template tag cr… fix HTMLTemplateElement implementation to reflect standards behavior Jun 11, 2022
@thescientist13 thescientist13 marked this pull request as draft June 11, 2022 01:02
@thescientist13
Copy link
Member Author

So one thing I'm not super clear on is how instances of <template> tags (HTMLTemplateElement) and ShadowRoot work together, specifically around the shadowroot="open" attribute and mode.

Specifically, as per this PR, when creating a template, it returns its contents inside <template> tags, eg.

<wcc-footer>
  <template shadowroot="open">
    <footer class="footer">
      <h4>My Blog &copy; 2022</h4>
    </footer>
  </template>
</wcc-footer>

And when instantiating a Shadow Root in a custom element, we can set the mode that way, e.g.

class Footer extends HTMLElement {
  connectedCallback() {
    if (!this.shadowRoot) {
      this.attachShadow({ mode: 'open' });
      this.shadowRoot.appendChild(template.content.cloneNode(true));
    }
  }
}

So how does a template get access to the mode, which we would want so as to properly set the shadowroot attribute? Presumably some users may want the option of open / closed, and this may also impact how we implement #16.

They are two different things with different class hierarchies from what I understand, so not sure what option to pursue here? I can think of a couple options at least just to get the ball rolling

  1. User sets the attribute manually on a <template>
    const template = document.createElement('template');
    
    template.innerHTML = `    
      <footer class="footer">
        <h4>My Blog &copy; ${new Date().getFullYear()}</h4>
      </footer>
    `;
    
    template.setAttribute('shadowroot', 'open');
  2. Have the compiler check for mode when serializing and update it that way
    async function renderComponentRoots(tree) {
      for (const node of tree.childNodes) {
        if (node.tagName && node.tagName.indexOf('-') > 0) {
          ...
          
          const elementHtml = elementInstance.shadowRoot
            ? elementInstance.getInnerHTML({ includeShadowRoots: true })
            : elementInstance.innerHTML;
          const elementTree = parseFragment(elementHtml);
    
          // if we have a shadowRoot, set the `<template>` shadowroot attribute according to shadowRoot.mode
          if(elementInstance.shadowRoot) {
            const mode = elementInstance.shadowRoot.mode;
            //  do something with the tree and set the attribute on the `<template>` accordingly
          }
    
          ...
        }
    
        ...
      }
    
      return tree;
    }
  3. Just leave it hardcoded to shadowroot="open" (for now) 🙃

I think either way, the main thing to accomplish with this PR is to get <template> coming from the right place and set the standards in place compared to how it was implemented before. I can make another issue to work out how to link mode and shadowroot attribute, if they are even in fact related. I'm thinking option #2 seems pretty feasible though.

@thescientist13 thescientist13 force-pushed the bug/issue-51-fix-html-template-element-implementation branch from a0f25e6 to 9b1496a Compare June 14, 2022 12:51
@thescientist13 thescientist13 merged commit 81c57de into master Jun 14, 2022
@thescientist13 thescientist13 deleted the bug/issue-51-fix-html-template-element-implementation branch June 14, 2022 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DOM shim not accurately creating templates (HTMLTemplateElement)
1 participant