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

Include supporting events in the capture and bubble phases #909

Open
rajsite opened this issue Nov 9, 2020 · 5 comments
Open

Include supporting events in the capture and bubble phases #909

rajsite opened this issue Nov 9, 2020 · 5 comments
Labels
Additional Tests For issues that identify good additional tests to run on all libraries

Comments

@rajsite
Copy link

rajsite commented Nov 9, 2020

I think it would be useful to test that libraries supporting custom elements include the ability to listen for events from either the capture or the bubble phase.

We recently ran into an issue where the Angular Framework can only listen to bubble events while Angular Elements can only emit capture phase events. In this case the Angular Framework was not able to easily consume arbitrary custom elements (created by Angular Framework).

@justinfagnani
Copy link
Contributor

justinfagnani commented Feb 19, 2021

It doesn't look like Angular Elements emit "capture phase" events (there really isn't such a thing), they're just emitting non-bubbling events. Many template systems, if they don't use event delegation, will be able to listen to these events just fine because the listener is put directly on the event target.

So I'm not sure if there should be a test for capturing listeners specifically, but it might make sense to have a test to see if event delegation interferes with non-bubbling events. So fire a non-bubbling event on a nested element with an event binding and see if it's handled:

let handled = false;
const handleTest = (e: Event) => {
  handled = true;
};
render(html`<div><div id="target" @test=${handleTest}></div></div>`, container);
const el = container.querySelector('#target');
el.dispatchEvent(new Event('test'));
assert(handled);

@rajsite
Copy link
Author

rajsite commented Feb 19, 2021

It doesn't look like Angular Elements emit "capture phase" events (there really isn't such a thing), they're just emitting non-bubbling events.

Fair enough, I should have spoke more precisely, but sounds like the idea came across.

it might make sense to have a test to see if event delegation interferes with non-bubbling events

Makes sense to me, but it appears the example given does not exercise event delegation. Shouldn't it register the event listener on the parent or am I missing the intention of the example test?

ie:

let handled = false;
const handleTest = (e: Event) => {
  handled = true;
};
render(html`<div @test=${handleTest}><div id="target"></div></div>`, container);
const el = container.querySelector('#target');
el.dispatchEvent(new Event('test'));
assert(handled);

@justinfagnani
Copy link
Contributor

The intent of the test is to make sure that the template language can listen to non-bubbling events like that. If a system used event delegation at some component root, then the handler wouldn't be called.

You change would be a good negative test. The handler should not be called in that case, since the event doesn't bubble. Calling the handler would be a bug in the event targeting logic of the delegation system.

@rajsite
Copy link
Author

rajsite commented Feb 19, 2021

I think I better understand what you are describing.

it might make sense to have a test to see if event delegation interferes with non-bubbling events

If a system used event delegation at some component root, then the handler wouldn't be called.

Your test was written to validate that the framework does not interfere in some way with listeners placed directly on the event target (by the system relying on event delegation and for example stopping immediate propagation, etc.).

The scenario I ran into was listening for events fired by child elements created at runtime by the custom element we are consuming (and there not available to bind to by the framework directly at edit time):

ie at edit time:

render(html`<my-element @test=${handleTest}></my-element>`, container);

and at runtime my-element creates children custom elements that fire events. If these were web components leveraging shadow dom I'd expect the events fired by my-elements's children custom elements to be re-targetted to my-element. But as just custom elements not leveraging shadow dom their behavior seems perfectly reasonable not attempting to re-target (?).

Since the repo is custom-elements-everywhere and not web-components-everywhere 😉 then maybe it would be useful for frameworks to be able to handle this case generally (which would require being able to configure event listener's capture mode). Hopefully that clarifies the intention of this issue.

@rictic rictic added the Additional Tests For issues that identify good additional tests to run on all libraries label Dec 29, 2021
@coryrylan
Copy link

Another example of where a test around detecting bubbling/non-bubbling events would be the use of .NET Blazor. I can use custom elements however Blazor only captures global or bubbled events. This means for most of the web components I work on that don't bubble, Blazor will never catch.

Here is a snippet from the Blazor docs
https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor

If you're attempting to fire a custom event, bubbles must be enabled by setting its value to true. Otherwise, the event doesn't reach the Blazor handler for processing into the C# custom EventHandlerAttribute method. For more information, see MDN Web Docs: Event bubbling.

Without access to the underlying web component and setting it to bubble, it makes it very difficult to use web components. I have to hack the custom event to bubble for Blazor to see it. Also to compound the issue, since Blazor only understands global events it can't distinguish the event detail types if the event has the same name as another component custom event. https://github.com/coryrylan/clarity-blazor/blob/main/EventHandlers.cs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Additional Tests For issues that identify good additional tests to run on all libraries
Projects
None yet
Development

No branches or pull requests

4 participants