ionic-team / stencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.
https://stenciljs.com
Other
12.42k stars 778 forks source link

blur Event bubble on some browsers #2699

Open kensodemann opened 3 years ago

kensodemann commented 3 years ago

Stencil version:

 @stencil/core@2.0.3

I'm submitting a:

[x] bug report [ ] feature request [ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/

Current behavior: The blur event bubbles to the Host on Safari and Firefox, but not on Chrome or other Chromium based browsers.

Expected behavior: Bubbling behavior would be consistent. I am not sure which is intended, though typically a blur would not bubble.

Steps to reproduce: Use the following repo: https://github.com/jcfranco/stencil-odd-event-bubbling

serve it and then run on the following browsers with the console open:

It should be obvious what to do based on the prompts on the screen.

When using the top custom element you will see the blur does not bubble beyond the input. When using the bottom Stencil based component you will see the blur bubble to the Host but only on Safari and Firefox.

claviska commented 3 years ago

The test case appears to be incorrect. The "host" event it's listening to is a <div> inside the shadow DOM, not the host element.

This is important because blur doesn't bubble, but it will be retargeted to the host element if it occurs within a shadow DOM.

<script>
  customElements.define('blur-test',
    class BlurTest extends HTMLElement {
      connectedCallback() {
        this.attachShadow({
          mode: 'open',
        });

        this.shadowRoot.innerHTML =
          `<div id="fake-host">
            <input id="input" placeholder="focus here first" />
            <button>then click here</button>
          </div>
          `;

        this.shadowRoot.getElementById('fake-host')
          .addEventListener('blur', (event) => console.log('blur-test::host blur', event));

        this.shadowRoot.getElementById('input')
          .addEventListener('blur', (event) => console.log('blur-test::input blur', event));
      }
    });
</script>

To listen for the event on the host element (which makes it the same as the Stencil component), the first listener should look like this:

        this.addEventListener('blur', (event) => console.log('blur-test::host blur', event));

I updated the test case locally and I'm seeing consistent results in all browsers when clicking the input and then the button. 👍

However, there is a subtle difference in Chrome compared to Safari and Firefox (at least in macOS). in Chrome, clicking the button gives it focus whereas Safari and Firefox do not. (See this fiddle in Chrome, Safari, and Firefox https://jsfiddle.net/nemvpz34/1/)

As such, you may see an extra blur event when clicking off the button in Chrome. This is expected because of the focus behavior mentioned above.

ionitron-bot[bot] commented 3 years ago

Thanks for the issue! This issue is being closed due to inactivity. If this is still an issue with the latest version of Stencil, please create a new issue and ensure the template is fully filled out.

Thank you for using Stencil!

kensodemann commented 3 years ago

This is on a list of items to be fixed. Should remain open.