Shadow DOM v1 CSS polyfill

https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom

It caused me all the excitement that I could write my own web page from scratch without polymer.

For search only, css :host, for example, does not work in Edge and FireFox. I can do without html importuntil w3c finds out what they want to do with es6 modules, but each browser that has its own half-implemented version of Shadow DOM without css clicks on my buttons.

So I still need a full polymer stack in order to have web components in all browsers.

<script src="../webcomponentsjs/webcomponents-lite.js"></script>

<link rel="import" href="../hello-world.html">

<hello-world>Hello World Polymer 2.x</hello-world>

Does anyone know how polyfill Edge and FireFox actually have a Shadow DOM and not a native Shadow DOM that pretends to be one?

This is what I tried, but I can't figure out how to tell Edge and FireFox to put their shadow wannabe in a different place and use shadydom / shadycss.

https://jsbin.com/quvozo

<!DOCTYPE html>
<html>

<head>
  <title>Components</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"/>
</head>

<body>
  <hello-world>Hello World ES2015</hello-world>
  <script>
    function loadScript(src, main) {
      return new Promise(function(resolve, reject) {
        const script = document.createElement('script');
        script.async = true;
        script.src = src;
        script.onload = resolve;
        script.onerror = reject;
        document.head.appendChild(script);
      });
    }
    let polyfilled = false;
    const loadPromises = [];
    if (!('customElements' in window)) {
      loadPromises.push(loadScript('https://raw.githubusercontent.com/webcomponents/custom-elements/master/custom-elements.min.js'));
    }
    if (!HTMLElement.prototype.attachShadow) {
      polyfilled = true
      loadPromises.push(loadScript('https://raw.githubusercontent.com/webcomponents/shadydom/master/shadydom.min.js'));
      loadPromises.push(loadScript('https://raw.githubusercontent.com/webcomponents/shadycss/master/shadycss.min.js'));
    }
    Promise.all(loadPromises)
      .then(e => console.log(`polyfilled ${polyfilled}`))
      .then(e => {
        class HelloWorld extends HTMLElement {
          constructor() {
            super()
            this.template = document.createElement('template')
            this.template.innerHTML = `
              <style>
                :host {
                  display: block;
                  box-sizing: border-box;
                  border: 1px solid red;
                  margin-top: 10px;
                  padding: 0px 5px;
                }
              </style>
              <p>Test <slot></slot></p>
            `
            if (polyfilled) ShadyCSS.prepareTemplate(this.template, 'hello-world');
          }
          connectedCallback() {
            const shadowRoot = this.attachShadow({ mode: 'open' })
            shadowRoot.appendChild(this.template.content.cloneNode(true))
            if (polyfilled) ShadyCSS.applyStyle(this);
          }
        }
        customElements.define('hello-world', HelloWorld)
      })
  </script>
</body>

</html>
Run codeHide result
+4
source share
1 answer
  • Shadow DOM polyfill will not create a real DOM DOW object, but normal DOM elements,
  • The custom element specification will not allow you to add elements to a regular DOM tree in constructor(),

Therefore, you should attachfake the Shadow DOM afterwards, that is, inside the method connectedCallback(), and not inside the method constructor().

ShadyCSS polyfill works great with Edge and Firefox.

+3

Source: https://habr.com/ru/post/1660739/


All Articles