Bug 1283828 - Ensure output arguments are set in GetFrameForFirstRangeStartOrLastRangeEnd if returned frame isn't nullptr. r=mats, a=gchang
authorTing-Yu Lin <tlin@mozilla.com>
Mon, 04 Jul 2016 17:39:15 +0800
changeset 341852 6b83c0bda78d8b87c30e49e6aa81007871e8d2bd
parent 341851 65cb053a14bcc2279217cbb551d6839e37de0830
child 341853 74df8f458a42a81ca54f36ee81cb77bf8eab040b
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats, gchang
bugs1283828
milestone49.0a2
Bug 1283828 - Ensure output arguments are set in GetFrameForFirstRangeStartOrLastRangeEnd if returned frame isn't nullptr. r=mats, a=gchang MozReview-Commit-ID: 3sC3HLPrOtF
layout/base/AccessibleCaretManager.cpp
--- a/layout/base/AccessibleCaretManager.cpp
+++ b/layout/base/AccessibleCaretManager.cpp
@@ -943,16 +943,17 @@ AccessibleCaretManager::GetFrameForFirst
   nsDirection aDirection, int32_t* aOutOffset, nsINode** aOutNode,
   int32_t* aOutNodeOffset) const
 {
   if (!mPresShell) {
     return nullptr;
   }
 
   MOZ_ASSERT(GetCaretMode() == CaretMode::Selection);
+  MOZ_ASSERT(aOutOffset, "aOutOffset shouldn't be nullptr!");
 
   nsRange* range = nullptr;
   RefPtr<nsINode> startNode;
   RefPtr<nsINode> endNode;
   int32_t nodeOffset = 0;
   CaretAssociationHint hint;
 
   RefPtr<Selection> selection = GetSelection();
@@ -972,46 +973,53 @@ AccessibleCaretManager::GetFrameForFirst
     hint = CARET_ASSOCIATE_BEFORE;
   }
 
   nsCOMPtr<nsIContent> startContent = do_QueryInterface(startNode);
   RefPtr<nsFrameSelection> fs = GetFrameSelection();
   nsIFrame* startFrame =
     fs->GetFrameForNodeOffset(startContent, nodeOffset, hint, aOutOffset);
 
+  if (!startFrame) {
+    ErrorResult err;
+    RefPtr<TreeWalker> walker = mPresShell->GetDocument()->CreateTreeWalker(
+      *startNode, nsIDOMNodeFilter::SHOW_ALL, nullptr, err);
+
+    if (!walker) {
+      return nullptr;
+    }
+
+    startFrame = startContent ? startContent->GetPrimaryFrame() : nullptr;
+    while (!startFrame && startNode != endNode) {
+      startNode = findInFirstRangeStart ? walker->NextNode(err)
+                                        : walker->PreviousNode(err);
+
+      if (!startNode) {
+        break;
+      }
+
+      startContent = startNode->AsContent();
+      startFrame = startContent ? startContent->GetPrimaryFrame() : nullptr;
+    }
+
+    // We are walking among the nodes in the content tree, so the node offset
+    // relative to startNode should be set to 0.
+    nodeOffset = 0;
+    *aOutOffset = 0;
+  }
+
   if (startFrame) {
     if (aOutNode) {
       *aOutNode = startNode.get();
     }
     if (aOutNodeOffset) {
       *aOutNodeOffset = nodeOffset;
     }
-    return startFrame;
-  }
-
-  ErrorResult err;
-  RefPtr<TreeWalker> walker = mPresShell->GetDocument()->CreateTreeWalker(
-    *startNode, nsIDOMNodeFilter::SHOW_ALL, nullptr, err);
-
-  if (!walker) {
-    return nullptr;
   }
 
-  startFrame = startContent ? startContent->GetPrimaryFrame() : nullptr;
-  while (!startFrame && startNode != endNode) {
-    startNode = findInFirstRangeStart ? walker->NextNode(err)
-                                      : walker->PreviousNode(err);
-
-    if (!startNode) {
-      break;
-    }
-
-    startContent = startNode->AsContent();
-    startFrame = startContent ? startContent->GetPrimaryFrame() : nullptr;
-  }
   return startFrame;
 }
 
 bool
 AccessibleCaretManager::RestrictCaretDraggingOffsets(
   nsIFrame::ContentOffsets& aOffsets)
 {
   if (!mPresShell) {