mercredi 23 octobre 2019

EmberJS and web components: extend an existing HTML tag within an initializer (is it possible?)

Edit: this issue only seems to be in the .hbs rendering as this code does work when the extended web component is inserted in the top level index.html of the EmberJS project

Edit 2: However, when I put it in a minimal .hbs example, then it did work. So it is clearly an interaction with EmberJS rendering and perhaps with Handlebars, somehow.

I am trying to understand how to use web components in EmberJS. I know that I could rewrite a web component into an EmberJS component, but that is not the point. I want to know how to directly integrate web components into EmberJS.

There is a tutorial that describes how to make custom web components and put that in EmberJS by making an initializer.

https://tenbit.co/blog/a-simple-way-to-integrate-web-components-with-your-ember-app/

So you'd think, that it is a piece of cake to do the same thing for an extended native HTML component right? It turns out that it isn't.

Here is a minimal example of what isn't working. In this particular example <p>hello world</p> gets displayed but <p>hello Mars</p> does not. However, in the standalone HTML file (see on the bottom of this post) which has the same classes and define() calls, then it does work.

I also made an EmberJS Twiddle, in which you can see it: https://ember-twiddle.com/5b85957f52aba288bfe9e94ce42b811e

// app/initializers/custom-elements.js
class HelloWorld extends HTMLElement {
  constructor() {
    super();
    console.log("constructor() HelloWorld");
    let shadowRoot = this.attachShadow({ mode: "open" });
    shadowRoot.innerHTML = `<p>hello world</p>`;
  }
}

//similar to HelloWorld -- it's simply an extension
class TestingAParagraph extends HTMLParagraphElement {
  constructor() {
    super();
    console.log("constructor() TestingAParagraph");
    let shadowRoot = this.attachShadow({ mode: "open" });
    shadowRoot.innerHTML = `<p>hello Mars</p>`;
  }
}

export function initialize(application) {
  window.customElements.define("hello-world", HelloWorld);
  window.customElements.define("testing-a-paragraph", TestingAParagraph, {
    extends: "p"
  });
}

export default {
  initialize
};

Here is the Handlebars file:


<p>Bladiebla</p>
<hello-world></hello-world>
<p>A test is coming</p>
<p is="testing-a-paragraph"></p>

Note: this minimal example does work as a standalone HTML file.

<!DOCTYPE html>
    <html>
    <head>
      <script type="text/javascript">
        // app/initializers/custom-elements.js
        class HelloWorld extends HTMLElement {
          constructor() {
            super();
            console.log("constructor() HelloWorld");
            let shadowRoot = this.attachShadow({ mode: "open" });
            shadowRoot.innerHTML = `<p>hello world</p>`;
          }
        }
    
        //similar to HelloWorld -- it's simply an extension
        class TestingAParagraph extends HTMLParagraphElement {
          constructor() {
            super();
            console.log("constructor() TestingAParagraph");
            let shadowRoot = this.attachShadow({ mode: "open" });
            shadowRoot.innerHTML = `<p>hello Mars</p>`;
          }
        }
    
    
        window.customElements.define("hello-world", HelloWorld);
        window.customElements.define("testing-a-paragraph", TestingAParagraph, {
          extends: "p"
        });
      </script>
    </head>
    <body>
      <p>Bladiebla</p>
      <hello-world></hello-world>
      <p>A test is coming</p>
      <p is="testing-a-paragraph"></p>
    </body>
    </html>



Aucun commentaire:

Enregistrer un commentaire