Bug 1282752 Part 4: Implement the new text retrieval behavior. draft
authorBrad Werth <bwerth@mozilla.com>
Fri, 28 Oct 2016 12:35:50 -0700
changeset 431068 9daa30943bb0cb98cbf915b3def9e6fae4d33a95
parent 431067 8daf08a22e1afda93820f080aa7bead43606c68f
child 535361 9f1d3794efad4877948acfcf66ee03e5e19127d0
push id34000
push userbwerth@mozilla.com
push dateFri, 28 Oct 2016 19:38:20 +0000
bugs1282752
milestone52.0a1
Bug 1282752 Part 4: Implement the new text retrieval behavior. MozReview-Commit-ID: 7j5BjruBNb9
dom/base/nsRange.cpp
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -2900,37 +2900,59 @@ GetTextFrameForContent(nsIContent* aCont
 static nsresult GetPartialTextRect(nsLayoutUtils::RectCallback* aCallback,
                                    mozilla::dom::DOMStringList* aText,
                                    nsIContent* aContent, int32_t aStartOffset,
                                    int32_t aEndOffset, bool aClampToEdge,
                                    bool aFlushLayout)
 {
   nsTextFrame* textFrame = GetTextFrameForContent(aContent, aFlushLayout);
   if (textFrame) {
+    // If we'll need it later, collect the full content text now.
+    nsAutoString textContent;
+    if (aText) {
+      mozilla::ErrorResult err; // ignored
+      aContent->GetTextContent(textContent, err);
+    }
+
     nsIFrame* relativeTo = nsLayoutUtils::GetContainingBlockForClientRect(textFrame);
     for (nsTextFrame* f = textFrame; f; f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
       int32_t fstart = f->GetContentOffset(), fend = f->GetContentEnd();
       if (fend <= aStartOffset || fstart >= aEndOffset)
         continue;
 
+      // Calculate the text content offsets we'll need if text is requested.
+      int32_t textContentStart = fstart;
+      int32_t textContentEnd = fend;
+
       // overlapping with the offset we want
       f->EnsureTextRun(nsTextFrame::eInflated);
       NS_ENSURE_TRUE(f->GetTextRun(nsTextFrame::eInflated), NS_ERROR_OUT_OF_MEMORY);
       bool rtl = f->GetTextRun(nsTextFrame::eInflated)->IsRightToLeft();
       nsRect r = f->GetRectRelativeToSelf();
       if (fstart < aStartOffset) {
         // aStartOffset is within this frame
         ExtractRectFromOffset(f, aStartOffset, &r, rtl, aClampToEdge);
+        textContentStart = aStartOffset;
       }
       if (fend > aEndOffset) {
         // aEndOffset is in the middle of this frame
         ExtractRectFromOffset(f, aEndOffset, &r, !rtl, aClampToEdge);
+        textContentEnd = aEndOffset;
       }
       r = nsLayoutUtils::TransformFrameRectToAncestor(f, r, relativeTo);
       aCallback->AddRect(r);
+
+      // Finally capture the text, if requested.
+      if (aText) {
+        const nsAString& textSubstring =
+          Substring(textContent,
+                    textContentStart,
+                    (textContentEnd - textContentStart));
+        aText->Add(textSubstring);
+      }
     }
   }
   return NS_OK;
 }
 
 /* static */ void
 nsRange::CollectClientRectsAndText(
   nsLayoutUtils::RectCallback* aCollector,
@@ -3068,16 +3090,22 @@ void
 nsRange::GetClientRectsAndTexts(
   mozilla::dom::ClientRectsAndTexts& aResult,
   ErrorResult& aErr)
 {
   if (!mStartParent) {
     return;
   }
 
+  aResult.mRectList.Construct();
+  aResult.mRectList.Value() = new DOMRectList(static_cast<nsIDOMRange*>(this));
+
+  aResult.mTextList.Construct();
+  aResult.mTextList.Value() = new DOMStringList();
+
   nsLayoutUtils::RectListBuilder builder(aResult.mRectList.Value());
 
   CollectClientRectsAndText(&builder, aResult.mTextList.Value(), this,
     mStartParent, mStartOffset, mEndParent, mEndOffset, true, true);
 }
 
 NS_IMETHODIMP
 nsRange::GetUsedFontFaces(nsIDOMFontFaceList** aResult)