Open Bug 1831650 Opened 1 year ago Updated 1 month ago

Click events are duplicated for form-associated custom elements placed inside of a label element

Categories

(Core :: DOM: Core & HTML, defect)

Firefox 112
defect

Tracking

()

Tracking Status
firefox-esr102 --- wontfix
firefox-esr115 --- wontfix
firefox115 --- wontfix
firefox116 --- wontfix
firefox117 --- wontfix
firefox118 --- wontfix

People

(Reporter: cob.bzmoz, Assigned: edgar)

References

(Blocks 1 open bug, Regression, )

Details

(Keywords: nightly-community, regression)

Attachments

(2 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0

Steps to reproduce:

  1. Define a custom element that is form-associated (static formAssociated = true).
  2. Have the custom element's constructor create a shadow root and, inside of that, an unnamed slot element. Have the custom element's constructor add a "click" event listener to the custom element. The listener should console.log all incoming events.
  3. In your HTML markup, place an instance of that element inside of a LABEL element.
  4. Place a visible and clickable element inside of the custom element, e.g. a DIV or an SVG.
  5. Click on the inner (slotted) element.
  6. Use JavaScript to dispatch a "click" event to the custom element. Here, I am referring to constructing a new MouseEvent with "click" as its argument, and then calling dispatchEvent.
  7. Use JavaScript to dispatch a "click" event to the custom element's shadow root or any descendant thereof.

The attached HTML file can be used to perform steps 1 through 5.

Version affected is Firefox stable, 112.0.2 (64-bit). My current user-agent string is "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0".

Actual results:

The actual result of steps 1 - 5 is that the event is duplicated. The original event lists the slotted element as its target, and bubbles outward from the slotted element to the containing custom element and beyond. If this event's default action is not prevented, then Firefox creates a new click event listing the custom element as its target and the slotted element as its explicitOriginalTarget. This event bubbles outward from the custom element to the rest of the document. A "click" listener set on the custom element will therefore catch both events.

Continuing onward, the actual result of step 6 is that two "click" events are fired, both listing the form-associated custom element as their target.

Continuing onward, the actual result of step 7 is that two "click" events are fired, both listing the form-associated custom element as their target. The first event lists the intended target as its originalTarget, but the explicitOriginalTarget is still the whole custom element.

Bizarrely, in all cases of event duplication, the duplicate event has a timeStamp around 15 to 50 milliseconds after the original event.

These issues only occur if the custom element is form-associated and if it is wrapped in a LABEL element. Form-associated custom elements produce the expected results if they are not in a LABEL. Custom elements inside of a label produce the expected results if they are not form-associated.

Expected results:

The expected result of steps 1 - 5 is that Firefox should only have fired a single click event, with the slotted element as its target, and this event should have bubbled outward to the entire document.

The expected result of step 6 is that Firefox should only have fired a single click event, with the custom element as its target.

The expected result of step 7 is that Firefox should only have fired a single click event, with the intended target (i.e. shadow root or descendant) as its target.

This behavior causes major problems for custom elements used to implement checkbox form controls and other toggleable/clickable form controls, as responding to both of a pair of duplicated click events would break the checkbox (e.g. clicking it toggles it twice, producing no change).

If a form-associated custom element is placed inside of a label, the only way to avoid reacting twice to every click is: if event.target is the custom element, then you must ignore the click event if either of explicitOriginalTarget and originalTarget are non-null and not equal to the custom element. This will allow you to ignore the second fired event in each duplicated pair. However, as these are non-standard properties, and it's not possible to know with 100% certainty which event (the first or the second) is the incorrectly-fired event, this workaround is not future-proof. (What if y'all decide that the first event is the fake one? What if y'all change the behavior of these non-standard properties? MDN doesn't even offer a clear description of the logic by which they get their values.)

The Bugbug bot thinks this bug should belong to the 'Core::DOM: Core & HTML' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → DOM: Core & HTML
Product: Firefox → Core
Severity: -- → S3

I also encountered this bug. Example to reproduce:

<html>
<body>
<label>Label<my-checkbox></my-checkbox></label>
<script>
class MyCheckbox extends HTMLElement {
static formAssociated=true;
constructor() {
super();
this.addEventListener('click', e=>console.log('click',e));
var shadow=this.attachShadow({mode: 'open'});
shadow.innerHTML='<div>shadow CLICK ME</div>';
}
}
customElements.define('my-checkbox', MyCheckbox);
</script>
</body>
</html>

Attached file Example to reproduce

I also encountered this bug. Example to reproduce attached.

_

Why status is UNCONFIRMED?

Regression window:
https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=6ed00b7f71c2a534bd8c824c6c54442b202efb15&tochange=b64579fab76b572919af61bcaf45350572f91b92

The former build: When shadow CLICK ME is clicked, one event is fired. But when Label is clicked, no event is fired.
The latter build: When shadow CLICK ME is clicked, two events are fired. But when Label is clicked, one event is fired.

So, this seems to be implementation bug of Bug 1556373.

Expected results:
Clicking on shadow CLICK ME or Label should both fire only one event, like Chrome.

Status: UNCONFIRMED → NEW
Ever confirmed: true
Regressed by: 1556373

:edgar, since you are the author of the regressor, bug 1556373, could you take a look?

For more information, please visit BugBot documentation.

Flags: needinfo?(echen)

This could also happens to elements that are in the labeled element category but are not considered interactive content, such as the output element, e.g. https://codepen.io/edgarchen-the-decoder/pen/yLQGORG. There is a spec discussion for this, https://github.com/whatwg/html/issues/5415. I feel Chrome/Safari behavior make more sense.

Assignee: nobody → echen
Flags: needinfo?(echen)

Set release status flags based on info from the regressing bug 1556373

See Also: → 1852086

Let's wait for bug 1851970 which is going to use EventTarget::ActivationBehavior for label element.

See Also: → 1884450
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: