This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 27430 - Synthetic click activation for non activatable elements
Summary: Synthetic click activation for non activatable elements
Status: RESOLVED WORKSFORME
Alias: None
Product: WHATWG
Classification: Unclassified
Component: HTML (show other bugs)
Version: unspecified
Hardware: PC Linux
: P2 normal
Target Milestone: Unsorted
Assignee: Ian 'Hixie' Hickson
QA Contact: contributor
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-11-25 12:13 UTC by Manish Goregaokar
Modified: 2015-07-06 16:10 UTC (History)
3 users (show)

See Also:


Attachments

Description Manish Goregaokar 2014-11-25 12:13:09 UTC
This[1] makes it seem like all HTMLElements have the ability to be synthetically activated.

However, the synthetic activation steps[2] talk of pre-click activation and post-click activation, which are only defined for activatable elements (<a>, <input>, etc). This makes it seem like only elements with activation behavior can be synthetically activated.

At the same time, the authentic activation steps[3] are very clearly defined for all types of elements -- they explicitly look for the nearest activatable element and run pre/post/canceled activation steps on it, if any. This makes it seem more like the previous point is true given that it doesn't have any explicit checks.


So, which is it? Can generic Elements be synthetically activated? If so, what are you supposed to do when they themselves are not activatable? If not, what should <*>.click() do when the element is not activatable?


On a side note, can we do with the click in progress flag being used only if the element is activatable? I see the utility of it -- it makes it easier to have sane canceled activation if the user is not allowed to nest activation calls; however IMO calling .click() from the click handler of a non-activatable element should not cause any problems (This helps reduce the amount of flags each element has to carry with it, which is a perf gain).


 [1]: https://html.spec.whatwg.org/multipage/interaction.html#dom-click makes it seem 
 [2]: https://html.spec.whatwg.org/multipage/interaction.html#run-synthetic-click-activation-steps
 [3]: https://html.spec.whatwg.org/multipage/interaction.html#run-authentic-click-activation-steps
Comment 1 Manish Goregaokar 2014-11-25 12:26:46 UTC
Actually, there is a slight problem with the click in progress flag on activatable elements as well. During authentic activation, the flag is set on the originally clicked element, but NOT the nearest activatable element. Perhaps that should be done too (or only that should be done)? Again, there doesn't seem to be a problem with .click() within an onclick handler for non activatable elements, however it will cause complications for activatable elements. Not setting it on the nearest activatable element allows for the following:


<activatable>
<span> </span>
</activatable>

<activatable>.onclick = function(){<a>.click()}

can lead to the activation steps being nested, which makes it harder to handle canceled activation (you either need to save a stack of "previous state", or just save one previous state and erroneously overwrite it each time)
Comment 2 Ian 'Hixie' Hickson 2015-04-24 20:27:23 UTC
(In reply to Manish Goregaokar from comment #0)
> This[1] makes it seem like all HTMLElements have the ability to be
> synthetically activated.

Yes, all HTMLElements have a click() method that "run[s the] synthetic click activation steps" for that element.


> However, the synthetic activation steps[2] talk of pre-click activation and
> post-click activation, which are only defined for activatable elements (<a>,
> <input>, etc).

Specifically, the algorithm for synthetic activation steps says "Run pre-click activation steps on the element", and the spec says "When a user agent is to run pre-click activation steps on an element, it must run the pre-click activation steps defined for that element, if any", so if there aren't any, that's just a no-op step.


> This makes it seem like only elements with activation
> behavior can be synthetically activated.

This doesn't follow. At worst, if the synthetic activation steps said to do something that wasn't defined for all elements, that would be an error in the spec. It would not change the earlier conclusion that any element can be synthetically activated.


> At the same time, the authentic activation steps[3] are very clearly defined
> for all types of elements -- they explicitly look for the nearest
> activatable element and run pre/post/canceled activation steps on it, if
> any. This makes it seem more like the previous point is true given that it
> doesn't have any explicit checks.

I don't understand. The step about pre-click activation steps in particular invokes the same logic as far as I can tell.


> So, which is it? Can generic Elements be synthetically activated?

Yes.


> what are you supposed to do when they themselves are not activatable?

Not sure what you mean by "activatable". You follow the algorithm, most of which is no-ops, and the only real effect is to fire a 'click' event.


> On a side note, can we do with the click in progress flag being used only if
> the element is activatable? I see the utility of it -- it makes it easier to
> have sane canceled activation if the user is not allowed to nest activation
> calls; however IMO calling .click() from the click handler of a
> non-activatable element should not cause any problems (This helps reduce the
> amount of flags each element has to carry with it, which is a perf gain).

There are pages on the Web that call click() reentrantly so browsers evolved this check as a defense against that. We have to have it because browsers have it.


(In reply to Manish Goregaokar from comment #1)
> Actually, there is a slight problem with the click in progress flag on
> activatable elements as well. During authentic activation, the flag is set
> on the originally clicked element, but NOT the nearest activatable element.
> Perhaps that should be done too (or only that should be done)? Again, there
> doesn't seem to be a problem with .click() within an onclick handler for non
> activatable elements, however it will cause complications for activatable
> elements.

This flag is intended to match the weird implementation behaviour. If you can show that browsers do it a different way, then it can be changed, but otherwise, it's probably stuck the way it is.

The flag wouldn't be there at all if it wasn't for existing behaviour.
Comment 3 Manish Goregaokar 2015-04-25 10:36:34 UTC
Ah, I missed the "if any" bit.

> This flag is intended to match the weird implementation behaviour. If you
> can show that browsers do it a different way, then it can be changed, but
> otherwise, it's probably stuck the way it is.
> 
> The flag wouldn't be there at all if it wasn't for existing behaviour.

Wouldn't it lead to reentrancy bugs if the flag wasn't set on both the element being clicked and the nearest activatable element?

(Not able to come up with an example though)
Comment 4 Ian 'Hixie' Hickson 2015-05-05 21:30:05 UTC
The re-entrancy bugs would be with code that does this. You can trivially have infinite loops in your code, e.g.:

   <script> while (1) { } </script>

If it was up to me, we wouldn't guard against this kind of thing here at all.
Comment 5 Manish Goregaokar 2015-05-06 06:25:38 UTC
Alright, thanks.
Comment 6 Josh Matthews 2015-07-06 16:10:55 UTC
FWIW I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=1180670, https://code.google.com/p/chromium/issues/detail?id=507267&thanks=507267&ts=1436188111, and https://bugs.webkit.org/show_bug.cgi?id=146637 on browsers that make synthetic click activation events find the nearest activatable element contrary to the current spec.