Created attachment 69791 [details]
Focus remains on element after its parent container is styled with display:none.
Wait a second until element is hidden.
Press any key.
You will receive a message, proving now-hidden element still has focus.
This is a difference with Firefox, but I don't see why this is necessarily a bad behavior.
Inconsistency is bad
An element keeps its focus after being hidden
But a hidden element cannot gain focus
In fact, Internet Explorer is like Firefox when you set style.display="none" (I was reporting the bug with that demo)
http://xirc.chez.com/ie9-focus-1.html (focus then style.display)
Allowed by Opera / Safari
http://xirc.chez.com/ie9-focus-2.html (focus then className)
Allowed by Opera / Safari / Internet Explorer
http://xirc.chez.com/ie9-focus-3.html (style.display then focus)
Allowed by Opera
http://xirc.chez.com/ie9-focus-4.html (className then focus)
Allowed by Opera
Yes, we should be different if IE and Firefox both do the same thing.
here the issue seems to be cancelFocusAppearenceUpdate() call. Which does remove the focus appearance but does not set the focus back to 0. The current usage of this call is only in focus() & detach() calls in Element.cpp. We can add setFocus(0) in this function definition to avoid retaining of the focus after display:none. Element::blur() does the same thing, which we might able to use here.
Is this issue to be fixed? Seems to be inconsistent on different platforms.
I think we have similar issue https://bugs.webkit.org/show_bug.cgi?id=40338 .
(In reply to comment #5)
> Is this issue to be fixed? Seems to be inconsistent on different platforms.
I think we should fix it. But it'll be nice to bring it up on whatwg to specify this behavior if it hasn't been done so already.
One tricky part of fixing this bug will be that we must fire blur event before removing the focus. Since we wouldn't know whether an element is visible or not until style recalc, it might have a weird side effects.
For example, we had decided to remove the focus when at the end of style-recalc, we might have a trouble dealing with situations like:
var element = ...
element.style.display = 'none';
element.title = 'hello'; // blur hasn't fired yet here
var x = element.offsetTop; // blur fires here
Because style recalc doesn't happen until offsetTop is obtained in the last line.
Right, so if we fire the blur event and then call blur instead of cancelFocusApperance() will be right way to do it? Also, i tried with blur replacing cancelFocusApperance, but its causing few layout tests to be failed. Need to look in more detail.
We should be very careful when considering changes in this area. Accepting key events on an invisible element is a fairly common technique - my understanding is that even Google Docs does something similar.
(In reply to comment #9)
> Right, so if we fire the blur event and then call blur instead of cancelFocusApperance() will be right way to do it? Also, i tried with blur replacing cancelFocusApperance, but its causing few layout tests to be failed. Need to look in more detail.
The real question is when to call those functions. Checking the computed value of display property of the focused node every time style changes is prohibitively inefficient and expensive. On the other hand, if we wait until style recalc happens, then there will be a noticeable delay between the time the element was hidden and blur is fired.
The whatwg mailing list thread for the issue -
To paraphrase Ian's response, the spec requires the focus be dropped in this case.
Also see https://bugs.webkit.org/show_bug.cgi?id=40338.
It seems only Chrome behaves like this, and the spec text seems to support that behavior:
Issues in other bugtrackers:
* Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=559561
* Edge: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/1308960/