onclick seems to not be working on web components
Describe the bug
Using onclick on a web-component (ApplePay button, on this case) is not working. The handler function is not being called. If I change to Svelte's 4 on:click the handler function is called normally
As far as I understand the apple-pay-button web-component fires a click event
Reproduction
https://github.com/GCastilho/svelte-5-onclick-bug-reproduction
(Note the usage of 'vite-plugin-mkcert' to use https on localhost. HTTPS is required for the ApplePay button to be displayed)
Logs
No response
System Info
System:
OS: Windows 11 10.0.26100
CPU: (8) x64 Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz
Memory: 3.05 GB / 15.77 GB
Binaries:
Node: 20.16.0 - C:\Program Files\nodejs\node.EXE
npm: 10.8.1 - C:\Program Files\nodejs\npm.CMD
pnpm: 9.7.0 - C:\Program Files\nodejs\pnpm.CMD
Browsers:
Edge: Chromium (131.0.2903.86)
Internet Explorer: 11.0.26100.1882
npmPackages:
svelte: ^5.2.7 => 5.11.2
Severity
blocking an upgrade
From what I know, onclick uses event delegation in Svelte, while on:click is effectively the same as addEventListener. I don't know enough about the Apple Pay web components to know if they have a Shadow DOM, because that influences how events work as well. I'm not sure if/how event delegation works with custom elements either.
@Ocean-OS Apple pay does use Shadow DOM
This is a combination of several things:
- The custom element does stop the propagation of the click event. That means the event is only available on the custom element itself and does not bubble beyond it
- We're assuming that the delegateable events (such as
clickfrom a button) from within custom elements bubble and are composed, i.e. they bubble beyond the shadow root. It's debateable whether or not we should assume that; given that everything can happen within custom elements (as shown here) I would be in favor of never delegating events on custom elements - Within
events.js#create_eventwe're checking if the event hascancelBubbleset totrue, in which case we don't invoke the passed handler. That is wrong, because the custom element did call stopPropagation, so it's alreadytrue, but we're a listener on the last element that still receives the event.
Temporary fix
Wrap it with other buttons
<button onclick={onApplePayButtonClicked}> <apple-pay-button buttonstyle="black" type="plain" locale="en"></apple-pay-button> </button>