Bug 1078991 - Add TouchCaret::GetCaretFocusFrame(). r=roc
authorTing-Yu Lin <tlin@mozilla.com>
Mon, 06 Oct 2014 21:02:00 -0400
changeset 232378 1878882312b0dbcf0144344313f05c82ac859b07
parent 232377 58012cbee5b65b729e12de2a860671b5dd18c8ed
child 232379 f7d5aaa3fc97a04ae155c40f3056d8b4f2890274
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1078991
milestone35.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 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.