whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
7.98k stars 2.6k forks source link

Change when button has activation behavior #10032

Open vinhill opened 8 months ago

vinhill commented 8 months ago

What is the issue with the HTML Standard?

The specification is currently phrased such that a button always has activation behavior. According to the dispatch algorithm, there is at a maximum one activation target for every dispatch of an activation event.

Problem

This does not fully correspond to browser implementations. Specifically, there are issues around

  1. Anchor with child button, issue #1567
    • <a href="link"><form><button type="button">click</button></form></a>. When a button with type=button is nested within an anchor and clicked, the link will be followed in Chrome, Firefox and Safari.
    • <a href="link"><button type="reset">click</button></a>. For a button that is not type=button, an ancestor link is followed if the button has no form owner in Chrome, Firefox and Safari.
  2. button that has a popovertarget
    • <a href="#link"><button popovertarget="foo">click</button></a><article id="foo">article</article> In Chrome but not in Firefox, clicking the button will activate the popover and follow the link. This corresponds to both the link and button being activation target. I'm unable to test on Safari.

I'm unsure whether 2. is intended behavior. When replacing the anchor with a form, the popover won't be activated. Maybe someone from Chromium can comment?

Consequences if button does not always have activation behavior

We should make sure that clicking a button nested within a summary will not toggle a details element. Maybe by stating that the activation behavior of a summary element is to do nothing if the event is targeted at an interactive content descendant. Gecko already does something similar.

The behavior around activation should be conserved. Although a button might not have activation behavior, it should be able to activate it via e.g. the keyboard.

If a button within a form changes from type=button to type=submit during an click handler, the button will not submit the form anymore. See issue #1568.

Possible solutions

We could state that a button has activation behavior if

We would need to mitigate above consequences and collect data on whether there are use cases for switching the button type during a click handler.

Or, under certain conditions, button activation behavior could be to activate an anchor ancestor. Between step 3 and 4 of button activation behavior, we could insert something like

Or, we could specify the behavior of Chromium and Safari.

@whatwg/forms @zcorpan

annevk commented 8 months ago

https://github.com/whatwg/html/issues/1567#issuecomment-1882843263 has a suggested way to write this down a lot clearer. And then the outcome needs to meet these criteria:

EdgarChen commented 7 months ago
2. button that has a `popovertarget`

   * `<a href="#link"><button popovertarget="foo">click</button></a><article id="foo">article</article>` In Chrome but not in Firefox, clicking the button will activate the popover and follow the link. This corresponds to both the link and button being activation target. I'm unable to test on Safari.

I update the test a bit,

data:text/html,<a href="javascript:alert('link%20followed');"><button popovertarget=foo>click</button></a><div id=foo popover>popover</div>

Safari behaves the same as Chrome.

EdgarChen commented 7 months ago

<input type=button> has a similar issue,

Test with

data:text/html,<a id=link href="javascript:alert('link%20followed');"><input type=button value=click></a>

a's activate behavior is triggered.

And test with input type button with popovertarget

data:text/html,<a href="javascript:alert('link%20followed');"><input type=button value=click popovertarget=foo></a><div id=foo popover>popover</div>

Chrome and Safari triggers both a's activate behavior and the popover.

vinhill commented 7 months ago

Another issue

data:text/html,<a href="javascript:alert('link')"><form action="javascript:alert('submit')"><input type=submit onclick="this.type='button'"></form></a>

According to the spec, the input element is activation target. But Firefox as well as Chrome trigger the link. Introducing a has-activation-behavior algorithm as described in https://github.com/whatwg/html/issues/1567#issuecomment-1882843263 probably would not mitigate this.

annevk commented 7 months ago

@vinhill It seems a simpler version of that would be data:text/html,<form%20action="javascript:alert('submit')"><input%20type=submit%20onclick="this.type='button'"></form>. Something with activation behavior makes itself ineligible for activation behavior (and therefore we end up looking at the parent in the complicated case). But yeah, addressing that might require some heavier restructuring. And it's definitely broken in both its simple and complex forms today.

vinhill commented 6 months ago

Both of my proposed solutions are probably not a good idea.

I read the code from Blink and WebKit, maybe we can align the specification to their implementation through the following changes

For comparison, here is the corresponding code for default handling the event in Blink and WebKit.

An open question for me is whether popover should cause the default handled flag to be set. It doesn't seem to be the case in Chromium (see here), but as stated above, I'm unsure if this is intended.

annevk commented 6 months ago

cc @rniwa @nt1m @mfreed7