Bug 1369072 - part2: PresShell::HandleEvent() should retarget KeyboardEvent if focused document is invisible r?smaug draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 05 Sep 2017 19:39:33 +0900
changeset 661242 c8a85f8076e25ee0dfaa794251532e105f8dd83f
parent 661241 f913f68f2af214e9c40fed5dee35cab9398449eb
child 661243 a15e7cc33c88847be123cc32f975774bd8e60035
child 661334 20a2132b22ac3eeda72b2080eea9a8971c8f19ec
push id78698
push usermasayuki@d-toybox.com
push dateFri, 08 Sep 2017 07:58:14 +0000
reviewerssmaug
bugs1369072
milestone57.0a1
Bug 1369072 - part2: PresShell::HandleEvent() should retarget KeyboardEvent if focused document is invisible r?smaug When focused document is invisible, PresShell::HandleEvent() won't dispatch any events. However, if it's KeyboardEvent, user cannot do anything only with keyboard. So, in this case, PresShell should retarget keyboard events to first visible ancestor. MozReview-Commit-ID: CvCBcYwvfbe
layout/base/PresShell.cpp
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -7316,18 +7316,31 @@ PresShell::HandleEvent(nsIFrame* aFrame,
                (aEvent->mClass == eMouseEventClass) ||
                (aEvent->mClass == eWheelEventClass)) {
       retargetEventDoc = GetPrimaryContentDocument();
 #endif
     }
 
     if (retargetEventDoc) {
       nsCOMPtr<nsIPresShell> presShell = retargetEventDoc->GetShell();
-      if (!presShell)
-        return NS_OK;
+      // Even if the document doesn't have PresShell, i.e., it's invisible, we
+      // need to dispatch only KeyboardEvent in its nearest visible document
+      // because key focus shouldn't be caught by invisible document.
+      if (!presShell) {
+        if (!aEvent->HasKeyEventMessage()) {
+          return NS_OK;
+        }
+        while (!presShell) {
+          retargetEventDoc = retargetEventDoc->GetParentDocument();
+          if (!retargetEventDoc) {
+            return NS_OK;
+          }
+          presShell = retargetEventDoc->GetShell();
+        }
+      }
 
       if (presShell != this) {
         nsIFrame* frame = presShell->GetRootFrame();
         if (!frame) {
           if (aEvent->mMessage == eQueryTextContent ||
               aEvent->IsContentCommandEvent()) {
             return NS_OK;
           }