Skip to content
This repository was archived by the owner on Sep 20, 2019. It is now read-only.

Slot element fallback content affects custom element rendering order #664

Closed
ruphin opened this issue Jan 21, 2017 · 5 comments
Closed

Slot element fallback content affects custom element rendering order #664

ruphin opened this issue Jan 21, 2017 · 5 comments

Comments

@ruphin
Copy link
Contributor

ruphin commented Jan 21, 2017

There seems to be a bug in the v1 polyfill for Chrome (webcomponents-none.js)

Description

When a <slot> element with fallback content is placed directly in the root of a Custom Element's <template>, it alters the rendering order of all content of that element: it will re-order content bottom-to-top.

The issue only occurs if the following conditions are met:

  • On Chrome
  • If the webcomponentsjs (v1) polyfill is loaded
  • If a <slot> element is placed in the root of a <template>
  • That <slot> element has fallback content
  • The fallback content is used

Reproduction

<!DOCTYPE html>

<script src="/bower_components/webcomponentsjs/webcomponents-loader.js" charset="utf-8"></script>

<h1>Before Webcomponentsjs</h1>
<!-- This renders fine -->
<before-webcomponentsjs>
</before-webcomponentsjs>

<h1>After Webcomponentsjs</h1>
<!-- This renders fine -->
<h2>Without Fallback Content</h2>
<after-webcomponentsjs>
  <p slot="first">First Line</p>
</after-webcomponentsjs>

<h2>With Fallback Content</h2>
<!-- This renders in reverse order -->
<after-webcomponentsjs>
</after-webcomponentsjs>

<template id="element-template">
  <h3>First Header</h3>
  <slot name="first">
    <p>First Line - fallback</p>
  </slot>
  <h3>Second Header</h3>
  <div>
    <slot name="second">
      <p>Second Line</p>
    </slot>
  </div>
</template>

<script>
  window.addEventListener('WebComponentsReady', () => {
    class AfterWebcomponentsjs extends HTMLElement {
      constructor() {
        super();
        let template = document.getElementById('element-template');
        let content = template.content.cloneNode(true);
        this.attachShadow({mode: 'open'});
        this.shadowRoot.appendChild(content);
      }
    }
    customElements.define('after-webcomponentsjs', AfterWebcomponentsjs);
  });

  class BeforeWebcomponentsjs extends HTMLElement {
    constructor() {
      super();
      let template = document.getElementById('element-template');
      let content = template.content.cloneNode(true);
      this.attachShadow({mode: 'open'});
      this.shadowRoot.appendChild(content);
    }
  }
  customElements.define('before-webcomponentsjs', BeforeWebcomponentsjs);
</script>

You can find it deployed here: https://webcomponents.ruph.in/webcomponentsjsbug.html

Browsers affected

Chrome

@ruphin
Copy link
Contributor Author

ruphin commented Jan 21, 2017

Quick demonstration of the problem:

rec

@notwaldorf
Copy link
Contributor

@ruphin What happens if you don't import the polyfill at all? Does it work? The v1 polyfill for Chrome basically does nothing other than setup some Polymer related things, which you don't seem to be using, so I'm wondering if this is a Chrome bug.

@ruphin
Copy link
Contributor Author

ruphin commented Jan 23, 2017

Everything works fine without the polyfill. The <before-webcomponentsjs> element is registered before webcomponentsjs is loaded, and as you can see in the example that one is unaffected. Removing the webcomponentsjs import from the file altogether doesn't change anything in that regard. I can absolutely only trigger this issue when the polyfill is loaded, so it must be affecting something.

It might be related to a Chrome bug that I found with fallback content in slots. Even without the polyfill Chrome has some wacky behaviour in content selection of slotted content:

chromebug

<!DOCTYPE html>

<my-element>
</my-element>

<template id="element-template">
 <slot name="a">
   <p>Line one</p>
 </slot>
 <p>Line two</p>
 <p>Line three</p>
</template>

<script>
class MyElement extends HTMLElement {
 constructor() {
   super();
   let template = document.getElementById('element-template');
   let content = template.content.cloneNode(true);
   this.attachShadow({mode: 'open'});
   this.shadowRoot.appendChild(content);
 }
}
customElements.define('my-element', MyElement);
</script>

Not exactly sure where to report that issue.

@bicknellr
Copy link
Contributor

https://crbug.com/683776 , for reference

@TimvdLippe
Copy link
Contributor

Closing per above comment. That CRBug has been addressed in Chromium.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants