Bug 1078991 - Add TouchCaret::GetCaretFocusFrame(). r=roc
authorTing-Yu Lin <tlin@mozilla.com>
Mon, 06 Oct 2014 21:02:00 -0400
changeset 209163 1878882312b0dbcf0144344313f05c82ac859b07
parent 209162 58012cbee5b65b729e12de2a860671b5dd18c8ed
child 209164 f7d5aaa3fc97a04ae155c40f3056d8b4f2890274
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersroc
bugs1078991
milestone35.0a1
Bug 1078991 - Add TouchCaret::GetCaretFocusFrame(). r=roc
layout/base/TouchCaret.cpp
layout/base/TouchCaret.h
--- a/layout/base/TouchCaret.cpp
+++ b/layout/base/TouchCaret.cpp
@@ -84,16 +84,39 @@ TouchCaret::~TouchCaret()
 
   if (mTouchCaretExpirationTimer) {
     mTouchCaretExpirationTimer->Cancel();
     mTouchCaretExpirationTimer = nullptr;
   }
 }
 
 nsIFrame*
+TouchCaret::GetCaretFocusFrame(nsRect* aOutRect)
+{
+  nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
+  if (!presShell) {
+    return nullptr;
+  }
+
+  nsRefPtr<nsCaret> caret = presShell->GetCaret();
+  if (!caret) {
+    return nullptr;
+  }
+
+  nsRect rect;
+  nsIFrame* frame = caret->GetGeometry(&rect);
+
+  if (aOutRect) {
+    *aOutRect = rect;
+  }
+
+  return frame;
+}
+
+nsIFrame*
 TouchCaret::GetCanvasFrame()
 {
   nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
   if (!presShell) {
     return nullptr;
   }
   return presShell->GetCanvasFrame();
 }
@@ -147,26 +170,22 @@ TouchCaret::GetTouchFrameRect()
   dom::Element* touchCaretElement = presShell->GetTouchCaretElement();
   nsIFrame* canvasFrame = GetCanvasFrame();
   return nsLayoutUtils::GetRectRelativeToFrame(touchCaretElement, canvasFrame);
 }
 
 nsRect
 TouchCaret::GetContentBoundary()
 {
-  nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
-  if (!presShell) {
+  nsIFrame* focusFrame = GetCaretFocusFrame();
+  nsIFrame* canvasFrame = GetCanvasFrame();
+  if (!focusFrame || !canvasFrame) {
     return nsRect();
   }
 
-  nsRefPtr<nsCaret> caret = presShell->GetCaret();
-  nsRect focusRect;
-  nsIFrame* focusFrame = caret->GetGeometry(&focusRect);
-  nsIFrame* canvasFrame = GetCanvasFrame();
-
   // Get the editing host to determine the touch caret dragable boundary.
   dom::Element* editingHost = focusFrame->GetContent()->GetEditingHost();
   if (!editingHost) {
     return nsRect();
   }
 
   nsRect resultRect;
   for (nsIFrame* frame = editingHost->GetPrimaryFrame(); frame;
@@ -191,26 +210,20 @@ TouchCaret::GetContentBoundary()
   resultRect.Deflate(kBoundaryAppUnits);
 
   return resultRect;
 }
 
 nscoord
 TouchCaret::GetCaretYCenterPosition()
 {
-  nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
-  if (!presShell) {
-    return 0;
-  }
+  nsRect caretRect;
+  nsIFrame* focusFrame = GetCaretFocusFrame(&caretRect);
+  nsIFrame* canvasFrame = GetCanvasFrame();
 
-  nsRefPtr<nsCaret> caret = presShell->GetCaret();
-  nsRect focusRect;
-  nsIFrame* focusFrame = caret->GetGeometry(&focusRect);
-  nsRect caretRect = focusFrame->GetRectRelativeToSelf();
-  nsIFrame *canvasFrame = GetCanvasFrame();
   nsLayoutUtils::TransformRect(focusFrame, canvasFrame, caretRect);
 
   return (caretRect.y + caretRect.height / 2);
 }
 
 void
 TouchCaret::SetTouchFramePos(const nsPoint& aOrigin)
 {
@@ -240,33 +253,26 @@ TouchCaret::SetTouchFramePos(const nsPoi
 
   touchCaretElement->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
                              styleStr, true);
 }
 
 void
 TouchCaret::MoveCaret(const nsPoint& movePoint)
 {
-  nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
-  if (!presShell) {
+  nsIFrame* focusFrame = GetCaretFocusFrame();
+  nsIFrame* canvasFrame = GetCanvasFrame();
+  if (!focusFrame && !canvasFrame) {
     return;
   }
 
-  // Get scrollable frame.
-  nsRefPtr<nsCaret> caret = presShell->GetCaret();
-  nsRect focusRect;
-  nsIFrame* focusFrame = caret->GetGeometry(&focusRect);
   nsIFrame* scrollable =
     nsLayoutUtils::GetClosestFrameOfType(focusFrame, nsGkAtoms::scrollFrame);
 
   // Convert touch/mouse position to frame coordinates.
-  nsIFrame* canvasFrame = GetCanvasFrame();
-  if (!canvasFrame) {
-    return;
-  }
   nsPoint offsetToCanvasFrame = nsPoint(0,0);
   nsLayoutUtils::TransformPoint(scrollable, canvasFrame, offsetToCanvasFrame);
   nsPoint pt = movePoint - offsetToCanvasFrame;
 
   // Evaluate offsets.
   nsIFrame::ContentOffsets offsets =
     scrollable->GetContentOffsetsFromPoint(pt, nsIFrame::SKIP_HIDDEN);
 
@@ -410,38 +416,29 @@ TouchCaret::IsDisplayable()
   return true;
 }
 
 void
 TouchCaret::UpdatePosition()
 {
   MOZ_ASSERT(mVisible);
 
-  nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
-  if (!presShell) {
-    return;
-  }
-  nsRefPtr<nsCaret> caret = presShell->GetCaret();
+  nsRect focusRect;
+  nsIFrame* focusFrame = GetCaretFocusFrame(&focusRect);
+  nsIFrame* canvasFrame = GetCanvasFrame();
 
-  // Caret is visible and shown, update touch caret.
-  nsRect focusRect;
-  nsIFrame* focusFrame = caret->GetGeometry(&focusRect);
-  if (!focusFrame || focusRect.IsEmpty()) {
+  if (!focusFrame || !canvasFrame || focusRect.IsEmpty()) {
     return;
   }
 
   // Position of the touch caret relative to focusFrame.
   nsPoint pos = nsPoint(focusRect.x + (focusRect.width / 2),
                         focusRect.y + focusRect.height);
 
   // Transform the position to make it relative to canvas frame.
-  nsIFrame* canvasFrame = GetCanvasFrame();
-  if (!canvasFrame) {
-    return;
-  }
   nsLayoutUtils::TransformPoint(focusFrame, canvasFrame, pos);
 
   // Clamp the touch caret position to the scrollframe boundary.
   nsIFrame* closestScrollFrame =
     nsLayoutUtils::GetClosestFrameOfType(focusFrame, nsGkAtoms::scrollFrame);
   while (closestScrollFrame) {
     nsIScrollableFrame* sf = do_QueryFrame(closestScrollFrame);
     nsRect visualRect = sf->GetScrollPortRect();
@@ -493,24 +490,21 @@ TouchCaret::CancelExpirationTimer()
   if (mTouchCaretExpirationTimer) {
     mTouchCaretExpirationTimer->Cancel();
   }
 }
 
 void
 TouchCaret::SetSelectionDragState(bool aState)
 {
-  nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
-  if (!presShell) {
+  nsIFrame* caretFocusFrame = GetCaretFocusFrame();
+  if (!caretFocusFrame) {
     return;
   }
 
-  nsRefPtr<nsCaret> caret = presShell->GetCaret();
-  nsRect focusRect;
-  nsIFrame* caretFocusFrame = caret->GetGeometry(&focusRect);
   nsRefPtr<nsFrameSelection> fs = caretFocusFrame->GetFrameSelection();
   fs->SetDragState(aState);
 }
 
 nsEventStatus
 TouchCaret::HandleEvent(WidgetEvent* aEvent)
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/layout/base/TouchCaret.h
+++ b/layout/base/TouchCaret.h
@@ -72,16 +72,21 @@ private:
   /**
    * SetVisibility will set the visibility of the touch caret.
    * SetVisibility performs an attribute-changed notification which could, in
    * theory, destroy frames.
    */
   void SetVisibility(bool aVisible);
 
   /**
+   * Helper function to get caret's focus frame and caret's bounding rect.
+   */
+  nsIFrame* GetCaretFocusFrame(nsRect* aOutRect = nullptr);
+
+  /**
    * Find the nsCanvasFrame which holds the touch caret.
    */
   nsIFrame* GetCanvasFrame();
 
   /**
    * Retrieve the bounding rectangle of the touch caret.
    *
    * @returns A nsRect representing the bounding rectangle of this touch caret.