Bug 1140625 - Recursive call GetFrameForNodeOffset if text node has no frame. r=roc
authorMorris Tseng <mtseng@mozilla.com>
Thu, 19 Mar 2015 02:47:00 -0400
changeset 266157 65d48bfeb65499937cf1679b5d9949f270737c90
parent 266156 1b76bac87d825887ca19e7eab0a8455f740486c5
child 266158 7b4e1bd6c8aa4908668363a67492dce17a1beecd
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1140625
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1140625 - Recursive call GetFrameForNodeOffset if text node has no frame. r=roc
layout/generic/nsSelection.cpp
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -1886,23 +1886,35 @@ nsFrameSelection::GetFrameForNodeOffset(
             nsresult rv = textNode->GetLength(&textLength);
             if (NS_FAILED(rv))
               return nullptr;
 
             *aReturnOffset = (int32_t)textLength;
           }
           else
             *aReturnOffset = 0;
-        }
-        else
-        {
-          // If we're at a collapsed whitespace content node (which
-          // does not have a primary frame), just use the original node
-          // to get the frame on which we should put the caret.
-          theNode = aNode;
+        } else {
+          int32_t numChildren = aNode->GetChildCount();
+          int32_t newChildIndex =
+            aHint == CARET_ASSOCIATE_BEFORE ? childIndex - 1 : childIndex + 1;
+
+          if (newChildIndex >= 0 && newChildIndex < numChildren) {
+            nsCOMPtr<nsIContent> newChildNode = aNode->GetChildAt(newChildIndex);
+            if (!newChildNode)
+              return nullptr;
+
+            theNode = newChildNode;
+            int32_t newOffset =
+              aHint == CARET_ASSOCIATE_BEFORE ? theNode->GetChildCount() : 0;
+            return GetFrameForNodeOffset(theNode, newOffset, aHint, aReturnOffset);
+          } else {
+            // newChildIndex is illegal which means we're at first or last
+            // child. Just use original node to get the frame.
+            theNode = aNode;
+          }
         }
       }
     }
   }
 
   // If the node is a ShadowRoot, the frame needs to be adjusted,
   // because a ShadowRoot does not get a frame. Its children are rendered
   // as children of the host.