Bug 1283828 - Ensure output arguments are set in GetFrameForFirstRangeStartOrLastRangeEnd if returned frame isn't nullptr. draft
authorTing-Yu Lin <tlin@mozilla.com>
Mon, 04 Jul 2016 17:39:15 +0800
changeset 383492 5acccc8ddee30387c9f113f6b72aa37d14a75db0
parent 383328 39dffbba764210b25bfc1e749b4f16db77fa0d46
child 524494 15c25d9b8343c39dea3e6df0b9abebd9ccc111c5
push id22040
push usertlin@mozilla.com
push dateMon, 04 Jul 2016 09:39:38 +0000
bugs1283828
milestone50.0a1
Bug 1283828 - Ensure output arguments are set in GetFrameForFirstRangeStartOrLastRangeEnd if returned frame isn't nullptr. 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) {