Bug 1078991 - Add TouchCaret::GetCaretFocusFrame(). r=roc
--- 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.