Bug 1441279 - 6. Register accessible caret observers across docshell tree; r?bz draft
authorJim Chen <nchen@mozilla.com>
Mon, 02 Apr 2018 17:13:46 -0400
changeset 776315 a4533a4ca752a6735d42473d34969a32d68049fe
parent 776314 8356785a2c7356d067dc69a62e73f58f07072c62
child 776349 a4666f45354ce53fc853dabfec12fe9dcba030ae
push id104840
push userbmo:nchen@mozilla.com
push dateMon, 02 Apr 2018 21:15:36 +0000
reviewersbz
bugs1441279
milestone61.0a1
Bug 1441279 - 6. Register accessible caret observers across docshell tree; r?bz AccessibleCaretManager uses scroll and reflow observers to detect when to update the position of carets. However, it currently only registers the observers on the leaf docshell, so only changes in the innermost iframe are detected; that is, it fails to update caret position when an ancestor iframe is scrolled. This patch makes it register observers on all ancestor docshells so that changes in ancestor iframes are detected as well. MozReview-Commit-ID: bwiSjj8936
layout/base/AccessibleCaretEventHub.cpp
--- a/layout/base/AccessibleCaretEventHub.cpp
+++ b/layout/base/AccessibleCaretEventHub.cpp
@@ -395,18 +395,25 @@ AccessibleCaretEventHub::Init()
   nsPresContext* presContext = mPresShell->GetPresContext();
   MOZ_ASSERT(presContext, "PresContext should be given in PresShell::Init()");
 
   nsIDocShell* docShell = presContext->GetDocShell();
   if (!docShell) {
     return;
   }
 
-  docShell->AddWeakReflowObserver(this);
-  docShell->AddWeakScrollObserver(this);
+  nsCOMPtr<nsIDocShell> curDocShell = docShell;
+  do {
+    curDocShell->AddWeakReflowObserver(this);
+    curDocShell->AddWeakScrollObserver(this);
+
+    nsCOMPtr<nsIDocShellTreeItem> tmp;
+    curDocShell->GetSameTypeParent(getter_AddRefs(tmp));
+    curDocShell = do_QueryInterface(tmp);
+  } while (curDocShell);
 
   mDocShell = static_cast<nsDocShell*>(docShell);
 
   if (sUseLongTapInjector) {
     mLongTapInjectorTimer = NS_NewTimer();
   }
 
   mManager = MakeUnique<AccessibleCaretManager>(mPresShell);
@@ -416,20 +423,24 @@ AccessibleCaretEventHub::Init()
 
 void
 AccessibleCaretEventHub::Terminate()
 {
   if (!mInitialized) {
     return;
   }
 
-  RefPtr<nsDocShell> docShell(mDocShell.get());
-  if (docShell) {
-    docShell->RemoveWeakReflowObserver(this);
-    docShell->RemoveWeakScrollObserver(this);
+  nsCOMPtr<nsIDocShell> curDocShell = mDocShell.get();
+  while (curDocShell) {
+    curDocShell->RemoveWeakReflowObserver(this);
+    curDocShell->RemoveWeakScrollObserver(this);
+
+    nsCOMPtr<nsIDocShellTreeItem> tmp;
+    curDocShell->GetSameTypeParent(getter_AddRefs(tmp));
+    curDocShell = do_QueryInterface(tmp);
   }
 
   if (mLongTapInjectorTimer) {
     mLongTapInjectorTimer->Cancel();
   }
 
   mManager->Terminate();
   mPresShell = nullptr;