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

input[type=checkbox] is mutable even when disabled on every browser #5000

Closed
saschanaz opened this issue Oct 10, 2019 · 13 comments · Fixed by #5805
Closed

input[type=checkbox] is mutable even when disabled on every browser #5000

saschanaz opened this issue Oct 10, 2019 · 13 comments · Fixed by #5805

Comments

@saschanaz
Copy link
Member

saschanaz commented Oct 10, 2019

Test page: https://disabled-form-element.glitch.me/

The page dispatches a synthesized click event when you click the "Click" button to the checkbox and every browser (Firefox, Chrome, and Epiphany (WebKit; I have no Safari 😅)) mutates the disabled checkbox. This violates the spec:

When an input element is disabled, it is not mutable.

But based on the actual behaviors, should this be allowed?

Edit: issue number 5000 🎉

@saschanaz saschanaz changed the title Input is mutable even when disabled on every browser input[type=checkbox] is mutable even when disabled on every browser Oct 10, 2019
@annevk
Copy link
Member

annevk commented Oct 10, 2019

Is this #4328 perhaps?

@saschanaz
Copy link
Member Author

#4328 seems to be about elements disabled after legacy-pre-activation behavior but this is more about the elements that already have been disabled.

@saschanaz
Copy link
Member Author

@mfreed7
Copy link
Contributor

mfreed7 commented Jun 30, 2020

For reference, it appears that all modern browsers will toggle the disabled checkbox, and issue an 'input' event, when a synthetic 'click' event is sent. My guess would be that the spec should be clarified to match existing browser behavior in this case.

@saschanaz
Copy link
Member Author

saschanaz commented Aug 11, 2020

I explored to modify the spec but got a blocker. 6.4 Activation behavior of elements says:

Certain elements in HTML have an activation behavior, which means that the user can activate them. This is always caused by a click event.

... but both Firefox and Chrome trigger it without a click event. It seems that fixing this requires modifying DOM event dispatch algorithm, which would become a broader (and dirtier with exceptions) spec change than I thought. What do you think, would it be worth to do that or do you have an alternative way to fix this?

Ah never mind, DOM does not care about disabled, no need to fix it.

@josepharhar
Copy link
Contributor

This section of the spec says this:

A form control that is disabled must prevent any click events that are queued on the user interaction task source from being dispatched on the element.

However, the WPT added for this shows that dispatchEvent(new MouseEvent('click')) should still work on disabled form controls. I see that gecko and webkit allow dispatchEvent, but blink does not. I'll try to make blink aligned. Should the sentence in the spec also be updated to allow dispatchEvent, or is dispatchEvent already allowed in the spec somehow?

Also, the code in blink which implements this sentence in the spec about click events will completely cancel the click event and prevent it from being dispatched on any nodes if there is any node in the event path which is a disabled form control. However, it seems like this is not what gecko or webkit are doing - they still emit click events on child and/or parent nodes of the disabled form control for various types of clicks. I assume that our new test also permits click events on child and/or parent nodes of disabled form controls: web-platform-tests/wpt#32381 If we update this sentence, this should probably be spelled out too.

@saschanaz
Copy link
Member Author

Should the sentence in the spec also be updated to allow dispatchEvent, or is dispatchEvent already allowed in the spec somehow?

The spec limits the behavior to events from user interaction task source, so I believe it does not block dispatchEvent.

However, it seems like this is not what gecko or webkit are doing - they still emit click events on child and/or parent nodes of the disabled form control for various types of clicks.

Per https://wpt.fyi/results/html/semantics/forms/event-propagate-disabled.html?diff&filter=ADC&run_id=5757896716451840&run_id=5695315419070464 Gecko does not do that, do you have a test case that shows the behavior? It completely blocks pointerdown/up/click per my observation.

I assume that our new test also permits click events on child and/or parent nodes of disabled form controls: web-platform-tests/wpt#32381 If we update this sentence, this should probably be spelled out too.

Yup, I'll prepare a spec PR soon when I get confident enough that we have enough consensus around the tests.

@josepharhar
Copy link
Contributor

The spec limits the behavior to events from user interaction task source, so I believe it does not block dispatchEvent.

Awesome!

Gecko does not do that, do you have a test case that shows the behavior? It completely blocks pointerdown/up/click per my observation.

<div id=testparent>
  <button disabled id=test>disabled button
    <span id=testchild style="border:1px solid black">child span</span>
  </button>
</div>

<div id=output></div>

<script>
  function log(str) {
    output.insertAdjacentHTML('beforeend', `<div>${str}</div>`);
  }
  test.addEventListener('click', () => log('click handler'));
  testparent.addEventListener('click', () => log('parent click handler'));
  testchild.addEventListener('click', () => log('child click handler'));
</script>

Physically clicking "child span" fires the click event on no elements in blink, fires only on the child element in gecko, and fires on the child and parent elements in webkit.

After my fix to implement web-platform-tests/wpt#32381 in blink, then blink webkit and gecko will all have the same behavior for testchild.click() and testchild.dispatchEvent(new MouseEvent('click')).

@saschanaz
Copy link
Member Author

Physically clicking "child span" fires the click event on no elements in blink,

With --enable-experimental-web-platform-features, right? Without the flag it shows the same behavior as WebKit.

fires only on the child element in gecko, and fires on the child and parent elements in webkit.

After my fix to implement web-platform-tests/wpt#32381 in blink, then blink webkit and gecko will all have the same behavior for testchild.click() and testchild.dispatchEvent(new MouseEvent('click')).

👍

@josepharhar
Copy link
Contributor

With --enable-experimental-web-platform-features, right? Without the flag it shows the same behavior as WebKit.

Oof, I don't think the flag should be taking away events like that, I'll have to look into it. Is there a test case in web-platform-tests/wpt#32381 which covers this? What is the desired behavior?

@saschanaz
Copy link
Member Author

saschanaz commented Jun 23, 2022

We want things to bubble, so in this case we need to follow what WebKit (and Blink by default!) does.

Is there a test case in web-platform-tests/wpt#32381 which covers this?

No, I'll have to add one...

@josepharhar
Copy link
Contributor

I think the test titled Trusted click on <button disabled=""><span class="target">Span</span></button>, observed from <body> should cover this, right...?

@saschanaz
Copy link
Member Author

Hmm yes, I mean the one that "checks whether the child element gets the event" does not exist and probably worth having one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

4 participants