Bug 607857. If caret is in a frame that needs reflow we can wrongly position the caret rect. r=roc a=blocking-final
authorTimothy Nikkel <tnikkel@gmail.com>
Wed, 24 Nov 2010 19:35:01 -0600
changeset 58202 c198cabd2743bc3b417461e1ce0da960d02eea0a
parent 58201 f86215099b30cd1e5a68d15a66f989aabc70dd12
child 58203 9cc9952ecc898cc258a50ac8074dc7fa54dfa7f1
push id17201
push usertnikkel@gmail.com
push dateThu, 25 Nov 2010 01:35:45 +0000
treeherdermozilla-central@0a29ac059eb5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, blocking-final
bugs607857
milestone2.0b8pre
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 607857. If caret is in a frame that needs reflow we can wrongly position the caret rect. r=roc a=blocking-final
layout/base/nsCaret.cpp
layout/base/nsCaret.h
--- a/layout/base/nsCaret.cpp
+++ b/layout/base/nsCaret.cpp
@@ -352,24 +352,27 @@ nsresult nsCaret::GetCaretVisible(PRBool
 
 
 //-----------------------------------------------------------------------------
 void nsCaret::SetCaretReadOnly(PRBool inMakeReadonly)
 {
   mReadOnly = inMakeReadonly;
 }
 
-void
+nsresult
 nsCaret::GetGeometryForFrame(nsIFrame* aFrame,
                              PRInt32   aFrameOffset,
                              nsRect*   aRect,
                              nscoord*  aBidiIndicatorSize)
 {
   nsPoint framePos(0, 0);
-  aFrame->GetPointFromOffset(aFrameOffset, &framePos);
+  nsresult rv = aFrame->GetPointFromOffset(aFrameOffset, &framePos);
+  if (NS_FAILED(rv))
+    return rv;
+
   nsIFrame *frame = aFrame->GetContentInsertionFrame();
   NS_ASSERTION(frame, "We should not be in the middle of reflow");
   nscoord baseline = frame->GetCaretBaseline();
   nscoord ascent = 0, descent = 0;
   nsCOMPtr<nsIFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
   NS_ASSERTION(fm, "We should be able to get the font metrics");
   if (fm) {
@@ -396,16 +399,18 @@ nsCaret::GetGeometryForFrame(nsIFrame* a
     nscoord overflow = caretInScroll.XMost() -
       scrolled->GetVisualOverflowRectRelativeToSelf().width;
     if (overflow > 0)
       aRect->x -= overflow;
   }
 
   if (aBidiIndicatorSize)
     *aBidiIndicatorSize = caretMetrics.mBidiIndicatorSize;
+
+  return NS_OK;
 }
 
 nsIFrame* nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect,
                                nscoord* aBidiIndicatorSize)
 {
   nsCOMPtr<nsIDOMNode> focusNode;
   nsresult rv = aSelection->GetFocusNode(getter_AddRefs(focusNode));
   if (NS_FAILED(rv) || !focusNode)
@@ -1084,17 +1089,21 @@ void nsCaret::DrawCaret(PRBool aInvalida
 }
 
 PRBool
 nsCaret::UpdateCaretRects(nsIFrame* aFrame, PRInt32 aFrameOffset)
 {
   NS_ASSERTION(aFrame, "Should have a frame here");
 
   nscoord bidiIndicatorSize;
-  GetGeometryForFrame(aFrame, aFrameOffset, &mCaretRect, &bidiIndicatorSize);
+  nsresult rv =
+    GetGeometryForFrame(aFrame, aFrameOffset, &mCaretRect, &bidiIndicatorSize);
+  if (NS_FAILED(rv)) {
+    return PR_FALSE;
+  }
 
   // on RTL frames the right edge of mCaretRect must be equal to framePos
   const nsStyleVisibility* vis = aFrame->GetStyleVisibility();
   if (NS_STYLE_DIRECTION_RTL == vis->mDirection)
     mCaretRect.x -= mCaretRect.width;
 
 #ifdef IBMBIDI
   mHookRect.Empty();
--- a/layout/base/nsCaret.h
+++ b/layout/base/nsCaret.h
@@ -212,20 +212,20 @@ protected:
                                          PRUint8 aBidiLevel,
                                          PRBool aInvalidate);
 
     struct Metrics {
       nscoord mBidiIndicatorSize; // width and height of bidi indicator
       nscoord mCaretWidth;        // full caret width including bidi indicator
     };
     Metrics ComputeMetrics(nsIFrame* aFrame, PRInt32 aOffset, nscoord aCaretHeight);
-    void GetGeometryForFrame(nsIFrame* aFrame,
-                             PRInt32   aFrameOffset,
-                             nsRect*   aRect,
-                             nscoord*  aBidiIndicatorSize);
+    nsresult GetGeometryForFrame(nsIFrame* aFrame,
+                                 PRInt32   aFrameOffset,
+                                 nsRect*   aRect,
+                                 nscoord*  aBidiIndicatorSize);
 
     // Returns true if the caret should be drawn. When |mDrawn| is true,
     // this returns true, so that we erase the drawn caret. If |aIgnoreDrawnState|
     // is true, we don't take into account whether the caret is currently
     // drawn or not. This can be used to determine if the caret is drawn when
     // it shouldn't be.
     PRBool        MustDrawCaret(PRBool aIgnoreDrawnState);