-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Add focusin and focusout events #10235
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13135,6 +13135,8 @@ https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C%21DOCTYPE%20HTML%3E% | |
<li><code data-x="handler-onended">onended</code></li> | ||
<li><code data-x="handler-onerror">onerror</code>*</li> | ||
<li><code data-x="handler-onfocus">onfocus</code>*</li> | ||
<li><code data-x="handler-onfocusin">onfocusin</code>*</li> | ||
<li><code data-x="handler-onfocusout">onfocusout</code>*</li> | ||
<li><code data-x="handler-onformdata">onformdata</code></li> | ||
<li><code data-x="handler-oninput">oninput</code></li> | ||
<li><code data-x="handler-oninvalid">oninvalid</code></li> | ||
|
@@ -79840,9 +79842,17 @@ dictionary <dfn dictionary>ToggleEventInit</dfn> : <span>EventInit</span> { | |
target</var> be null.</p></li> | ||
|
||
<li> | ||
<p>If <var>blur event target</var> is not null, <span>fire a focus event</span> | ||
named <code data-x="event-blur">blur</code> at <var>blur event target</var>, with | ||
<var>related blur target</var> as the related target.</p> | ||
<p>If <var>blur event target</var> is not null:</p> | ||
|
||
<ol> | ||
<li><p><span>Fire a focus event</span> named <code data-x="event-blur">blur</code> at | ||
<var>blur event target</var>, with <var>related blur target</var> as the related target and | ||
bubbles set to false.</p></li> | ||
|
||
<li><p><span>Fire a focus event</span> named <code data-x="event-focusout">focusout</code> at | ||
<var>blur event target</var>, with <var>related blur target</var> as the related target and | ||
bubbles set to true.</p></li> | ||
</ol> | ||
|
||
<p class="note" id="note-sometimes-no-blur-event">In some cases, e.g., if <var>entry</var> is | ||
an <code>area</code> element's shape, a scrollable region, or a <span>viewport</span>, no | ||
|
@@ -79890,9 +79900,17 @@ dictionary <dfn dictionary>ToggleEventInit</dfn> : <span>EventInit</span> { | |
focus target</var> be null.</p></li> | ||
|
||
<li> | ||
<p>If <var>focus event target</var> is not null, <span>fire a focus event</span> | ||
named <code data-x="event-focus">focus</code> at <var>focus event target</var>, with | ||
<var>related focus target</var> as the related target.</p> | ||
<p>If <var>focus event target</var> is not null:</p> | ||
|
||
<ol> | ||
<li><p><span>Fire a focus event</span> named <code data-x="event-focus">focus</code> at | ||
<var>focus event target</var>, with <var>related focus target</var> as the related target and | ||
bubbles set to false.</p></li> | ||
|
||
<li><p><span>Fire a focus event</span> named <code data-x="event-focusin">focusin</code> at | ||
<var>focus event target</var>, with <var>related focus target</var> as the related target and | ||
bubbles set to true.</p></li> | ||
</ol> | ||
|
||
<p class="note">In some cases, e.g. if <var>entry</var> is an <code>area</code> | ||
element's shape, a scrollable region, or a <span>viewport</span>, no event is fired.</p> | ||
|
@@ -79902,12 +79920,12 @@ dictionary <dfn dictionary>ToggleEventInit</dfn> : <span>EventInit</span> { | |
</ol> | ||
|
||
<p>To <dfn>fire a focus event</dfn> named <var>e</var> at an element <var>t</var> with a given | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's make this more of a normal algorithm declaration:
And then update call sites to uniformly be either
or
|
||
related target <var>r</var>, <span data-x="concept-event-fire">fire an event</span> named | ||
<var>e</var> at <var>t</var>, using <code>FocusEvent</code>, with the <code | ||
related target <var>r</var> and bubbles <var>b</var>, <span data-x="concept-event-fire">fire an | ||
event</span> named <var>e</var> at <var>t</var>, using <code>FocusEvent</code>, with the <code | ||
data-x="dom-FocusEvent-relatedTarget">relatedTarget</code> attribute initialized to <var>r</var>, | ||
the <code data-x="dom-UIEvent-view">view</code> attribute initialized to <var>t</var>'s | ||
<span>node document</span>'s <span>relevant global object</span>, and the <span>composed | ||
flag</span> set.</p> | ||
the <code data-x="dom-UIEvent-view">view</code> attribute initialized to <var>t</var>'s <span>node | ||
document</span>'s <span>relevant global object</span>, the <span>composed flag</span> set, and | ||
<code data-x="dom-Event-bubbles">bubbles</code> attribute initialized to <var>b</var>.</p> | ||
|
||
<hr> | ||
|
||
|
@@ -111388,6 +111406,8 @@ typedef <span>OnBeforeUnloadEventHandlerNonNull</span>? <dfn typedef>OnBeforeUnl | |
<tr><td><dfn attribute for="GlobalEventHandlers"><code data-x="handler-onblur">onblur</code></dfn> <td> <code data-x="event-blur">blur</code> <!-- widely used --> | ||
<tr><td><dfn attribute for="GlobalEventHandlers"><code data-x="handler-onerror">onerror</code></dfn> <td> <code data-x="event-error">error</code> | ||
<tr><td><dfn attribute for="GlobalEventHandlers"><code data-x="handler-onfocus">onfocus</code></dfn> <td> <code data-x="event-focus">focus</code> <!-- widely used --> | ||
<tr><td><dfn attribute for="GlobalEventHandlers"><code data-x="handler-onfocusin">onfocusin</code></dfn> <td> <code data-x="event-focusin">focusin</code> | ||
<tr><td><dfn attribute for="GlobalEventHandlers"><code data-x="handler-onfocusout">onfocusout</code></dfn> <td> <code data-x="event-focusout">focusout</code> | ||
<tr><td><dfn attribute for="GlobalEventHandlers"><code data-x="handler-onload">onload</code></dfn> <td> <code data-x="event-load">load</code> | ||
<tr><td><dfn attribute for="GlobalEventHandlers"><code data-x="handler-onresize">onresize</code></dfn> <td> <code data-x="event-resize">resize</code> | ||
<tr><td><dfn attribute for="GlobalEventHandlers"><code data-x="handler-onscroll">onscroll</code></dfn> <td> <code data-x="event-scroll">scroll</code> | ||
|
@@ -111494,6 +111514,8 @@ typedef <span>OnBeforeUnloadEventHandlerNonNull</span>? <dfn typedef>OnBeforeUnl | |
attribute <span>EventHandler</span> <span data-x="handler-onended">onended</span>; | ||
attribute <span>OnErrorEventHandler</span> <span data-x="handler-onerror">onerror</span>; | ||
attribute <span>EventHandler</span> <span data-x="handler-onfocus">onfocus</span>; | ||
attribute <span>EventHandler</span> <span data-x="handler-onfocusin">onfocusin</span>; | ||
attribute <span>EventHandler</span> <span data-x="handler-onfocusout">onfocusout</span>; | ||
attribute <span>EventHandler</span> <span data-x="handler-onformdata">onformdata</span>; | ||
attribute <span>EventHandler</span> <span data-x="handler-oninput">oninput</span>; | ||
attribute <span>EventHandler</span> <span data-x="handler-oninvalid">oninvalid</span>; | ||
|
@@ -140506,6 +140528,18 @@ interface <dfn interface>External</dfn> { | |
<td> <code data-x="event-focus">focus</code> event handler | ||
<td> <span data-x="event handler content attributes">Event handler content attribute</span> | ||
|
||
<tr> | ||
<th id="ix-handler-onfocusin"> <code data-x="">onfocusin</code> | ||
<td> <span data-x="handler-onfocusin">HTML elements</span> | ||
<td> <code data-x="event-focusin">focusin</code> event handler | ||
<td> <span data-x="event handler content attributes">Event handler content attribute</span> | ||
|
||
<tr> | ||
<th id="ix-handler-onfocusout"> <code data-x="">onfocusout</code> | ||
<td> <span data-x="handler-onfocusout">HTML elements</span> | ||
<td> <code data-x="event-focusout">focusout</code> event handler | ||
<td> <span data-x="event handler content attributes">Event handler content attribute</span> | ||
|
||
<tr> | ||
<th id="ix-handler-onformdata"> <code data-x="">onformdata</code> | ||
<td> <span data-x="handler-onformdata">HTML elements</span> | ||
|
@@ -141439,7 +141473,19 @@ INSERT INTERFACES HERE | |
<td> <dfn event for="Window,HTMLElement"><code data-x="event-focus">focus</code></dfn> | ||
<td> <code>Event</code> | ||
<td> <code>Window</code>, elements | ||
<td> Fired at nodes <span data-x="gains focus">gaining focus</span> | ||
<td> Fired at nodes <span data-x="gains focus">gaining focus</span> without bubbling | ||
|
||
<tr> <!-- focusin --> | ||
<td> <dfn event for="Window,HTMLElement"><code data-x="event-focusin">focusin</code></dfn> | ||
<td> <code>Event</code> | ||
<td> <code>Window</code>, elements | ||
<td> Fired at nodes <span data-x="gains focus">gaining focus</span> after the <code data-x="event-focus">focus</code> event with bubbling | ||
|
||
<tr> <!-- focusout --> | ||
<td> <dfn event for="Window,HTMLElement"><code data-x="event-focusout">focusout</code></dfn> | ||
<td> <code>Event</code> | ||
<td> <code>Window</code>, elements | ||
<td> Fired at nodes when they stop being <span>focused</span> after the <code data-x="event-blur">blur</code> event with bubbling | ||
|
||
<tr> <!-- formdata --> | ||
<td> <dfn event for="HTMLElement"><code data-x="event-formdata">formdata</code></dfn> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This * means that they belong to the "Window-reflecting body element event handler set" instead of being the normal list at the top of https://whatpr.org/html/10235/webappapis.html#event-handlers-on-elements,-document-objects,-and-window-objects .
Can you confirm that difference is tested? (I'm honestly not sure exactly how you would test, this will take a bit of research. Or maybe change something in the implementation and see if any tests start failing.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I see that for example
onclick
is in the first table andonfocus
is in the second one.I made a quick test page, and it would seem that document.body doesn't do
onfocus
, but it does toonclick
, and that was the only difference that I found.Does that match up with your understanding?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
skimming the chromium code, I'm not sure what the difference is between onclick and onfocus.
They are both listed equally in all these files:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the difference in your test is due to the difference between
click
being bubbling andfocus
not.The example below https://html.spec.whatwg.org/#the-body-element:window-reflecting-body-element-event-handler-set seems to have a possible test case at least for bubbling events.
I bet in Chromium there's some list hidden somewhere for the special ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see, here it is: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/html_body_element.cc;l=115-216;drc=c0c69be50d661fd4952865e0aaf76952d9272f17
These are just for when they're set as HTML attributes rather than
element.onfocusin
which I am trying to implement in chromium to match safari.It looks like chromium already implements onfocusin as an HTML attribute, but it is not included in the special body->window logic that onfocus has: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/html_element.cc;l=481-482;drc=040547c1a7d0987ca63e18ca010986113637bf51
So I guess that we should put onfocusin/onfocusout in the list that onfocus is not in? So I should remove that asterisk?
I also made a test page here, but the results only made me confused: https://jsfiddle.net/jarhar/84jLcptn/5/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think that makes the most sense.
For testing, I figured out what we can do.
If you look at https://github.com/web-platform-tests/wpt/blob/master/html/webappapis/scripting/events/resources/event-handler-body.js , it pulls a list of all event handlers from the
html.idl
file. It then uses thewindowReflectingBodyElementEventHandlerSet
declaration to test how they should behave.So, if we decide these should be in the "normal" list, we do no work. Updating the spec will eventually cause
html.idl
in the WPT repo to update, which will automatically make those tests start testing the right thing.For your implementation, to verify everything is working correctly, you can modify the
html.idl
file locally, and make sure the tests still pass. When I do that right now, Chromium does not yet pass, I'd guess because the content attribute reflection isn't implemented. If you can confirm your patch makes such a local change pass, then I'll feel confident about our test coverage.