-
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
Define timing of focus fixup rule precisely when triggered by style changes. #8225
Comments
I think I tried to implement this in the update rendering steps: https://bugs.webkit.org/show_bug.cgi?id=237273#c1 , it's the easiest way (since you don't have to find every single place where "is this element focusable?" changes and hook it up there). It works, although the spec implies we should do synchronously and not async, so I just left it there for now. |
(As for the current state, we don't implement the focus fixup rule for most part, aside for finding the right element to focus when showing/hiding a dialog) |
See this Chromium bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1275097. It's currently done in a semi-hacky way, e.g. with timers. @Loirooriol tried to fix this up at one point and make it synchronous, so perhaps he has more comments. It feels odd to do this in "update the rendering", but that is likely the most performant place to do it. I'm afraid of the patch above - it'll likely slow things down considerably, since we'll be forcing style updates more often. |
Yeah I tried to make it synchronous, but since style changes can affect focusability, then things like Then I agree that doing it in "update the rendering" seems more reasonable. |
So, there seemed to be consensus today on doing this at some point during update the rendering. I sent a patch updating the tests here: https://bugzilla.mozilla.org/show_bug.cgi?id=1788741 However, that uncovers a case where all browsers are interoperable in removing focus synchronously, which is focused element removal. Not sure to what extent we want that to be special, do we want to keep that behavior? It might be reasonable. |
Interestingly, we just discussed this case w.r.t. the pop-up API. I'm in favor of keeping that behavior (synchronously fire events for focused element removal), given that it's interoperable, and changing it scares me. |
Worth noting that Blink also blurs synchronously when losing the tabindex: <!DOCTYPE html>
<div id="test" tabindex="1"></div>
<script>
test.focus();
console.log(document.activeElement); // test
test.removeAttribute("tabindex");
console.log(document.activeElement); // document.body
</script> But no interoperability here so changing may be fine. |
* Split it into two variants: one which runs synchronously on HTML element removal, and one which runs during "update the rendering". Closes #8225. * Be clear that the fixup does not cause any of the normal focus algorithms to run, and thus blur and change events do not fire. Also, delete the confusing "somehow unfocused without another element being explicitly focused" sentence. Fixes #3847. Fixes #6729.
* Split it into two variants: one which runs synchronously on HTML element removal, and one which runs during "update the rendering". Closes #8225. * After this split, only the "update the rendering" variant causes the normal focus algorithms to run, and thus blur and change events to fire. * Delete the confusing "somehow unfocused without another element being explicitly focused" sentence. Fixes #3847. Fixes #6729.
* Split it into two variants: one which runs synchronously on HTML element removal, and one which runs during "update the rendering". Closes #8225. * After this split, only the "update the rendering" variant causes the normal focus algorithms to run, and thus blur and change events to fire. * Delete the confusing "somehow unfocused without another element being explicitly focused" sentence. Fixes #3847. Fixes #6729.
* Split it into two variants: one which runs synchronously on HTML element removal, and one which runs during "update the rendering". Closes #8225. * After this split, only the "update the rendering" variant causes the normal focus algorithms to run, and thus blur and change events to fire. * Delete the confusing "somehow unfocused without another element being explicitly focused" sentence. Fixes #3847. Fixes #6729.
I was looking into implementing the focus fixup rule in Gecko, and per spec it's not clear when it should happen when it happens as a response to style changes.
Consider this testcase:
Naively, reading the current spec, I'd expect the element to be blurred after the style update (basically, as a result of
getBoundingClientRect()
). It seems Blink at least does it at a well defined point in the "update the rendering" steps (which is reasonable too).I thought WebKit implemented this but at least the Safari version I have access to behaves like Firefox.
I think I'd be fine making this a proper step in the "update the rendering", it seems odd that getBoundingClientRect() would fire a blur event.
@mfreed7 / @josepharhar, it seems blink sometimes applies the focus fixup rule sync (when making the form control disabled for example), but in the case of style changes it does it async. I think I'd rather have a single point in update-the-rendering where this happens but I'm curious if there's any reason to do it sync sometimes. Also I wonder when are you doing it r/n?
The text was updated successfully, but these errors were encountered: