Bug 681867. text-overflow only needs to affect the scrolling behavior of the block container with text-overflow. r=mats,a=legneato
authorRobert O'Callahan <robert@ocallahan.org>
Thu, 20 Oct 2011 17:56:07 +1300
changeset 78884 90a4c98c1ae33f10545a3cd142cfc6eb77c9e9df
parent 78883 fde58d9f353986268bf62ddc4f46868a89b40c43
child 78885 4b3528fc67a84ae1bccd066ca066a30aecd8e7dd
push idunknown
push userunknown
push dateunknown
reviewersmats, legneato
bugs681867
milestone9.0a2
Bug 681867. text-overflow only needs to affect the scrolling behavior of the block container with text-overflow. r=mats,a=legneato
layout/generic/TextOverflow.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -44,16 +44,17 @@
 #include "nsCaret.h"
 #include "nsContentUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
 #include "nsRect.h"
 #include "nsRenderingContext.h"
 #include "nsTextFrame.h"
+#include "nsGfxScrollFrame.h"
 
 namespace mozilla {
 namespace css {
 
 static const PRUnichar kEllipsisChar[] = { 0x2026, 0x0 };
 static const PRUnichar kASCIIPeriodsChar[] = { '.', '.', '.', 0x0 };
 
 // Return an ellipsis if the font supports it,
@@ -288,25 +289,20 @@ TextOverflow::WillProcessLines(nsDisplay
   return textOverflow.forget();
 }
 
 void
 TextOverflow::DidProcessLines()
 {
   nsIScrollableFrame* scroll = nsLayoutUtils::GetScrollableFrameFor(mBlock);
   if (scroll) {
-    // Create a dummy item covering the entire area, it doesn't paint
-    // but reports true for IsVaryingRelativeToMovingFrame().
     nsIFrame* scrollFrame = do_QueryFrame(scroll);
-    nsDisplayItem* marker = new (mBuilder)
-      nsDisplayForcePaintOnScroll(mBuilder, scrollFrame);
-    if (marker) {
-      mMarkerList->AppendNewToBottom(marker);
-      mBlock->PresContext()->SetHasFixedBackgroundFrame();
-    }
+    // Make sure that the next time this scrollframe is scrolled, we invalidate
+    // its entire contents.
+    scrollFrame->AddStateBits(NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL);
   }
 }
 
 void
 TextOverflow::ExamineFrameSubtree(nsIFrame*       aFrame,
                                   const nsRect&   aContentArea,
                                   const nsRect&   aInsideMarkersArea,
                                   FrameHashtable* aFramesToHide,
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1613,16 +1613,19 @@ static void AdjustViews(nsIFrame* aFrame
       AdjustViews(childFrames.get());
     }
   }
 }
 
 static PRBool
 CanScrollWithBlitting(nsIFrame* aFrame)
 {
+  if (aFrame->GetStateBits() & NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL)
+    return PR_FALSE;
+
   for (nsIFrame* f = aFrame; f;
        f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
     if (nsSVGIntegrationUtils::UsingEffectsForFrame(f) ||
         f->IsFrameOfType(nsIFrame::eSVG)) {
       return PR_FALSE;
     }
     nsIScrollableFrame* sf = do_QueryFrame(f);
     if (sf && nsLayoutUtils::HasNonZeroCorner(f->GetStyleBorder()->mBorderRadius))
@@ -1726,16 +1729,17 @@ void nsGfxScrollFrameInner::ScrollVisual
 
   rootPresContext->RequestUpdatePluginGeometry(mOuter);
 
   AdjustViews(mScrolledFrame);
   // We need to call this after fixing up the view positions
   // to be consistent with the frame hierarchy.
   PRUint32 flags = nsIFrame::INVALIDATE_REASON_SCROLL_REPAINT;
   PRBool canScrollWithBlitting = CanScrollWithBlitting(mOuter);
+  mOuter->RemoveStateBits(NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL);
   if (IsScrollingActive()) {
     if (!canScrollWithBlitting) {
       MarkInactive();
     } else {
       flags |= nsIFrame::INVALIDATE_NO_THEBES_LAYERS;
     }
   }
   if (canScrollWithBlitting) {
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -59,16 +59,22 @@ class nsPresContext;
 class nsIPresShell;
 class nsIContent;
 class nsIAtom;
 class nsIDocument;
 class nsIScrollFrameInternal;
 class nsPresState;
 struct ScrollReflowState;
 
+// When set, the next scroll operation on the scrollframe will invalidate its
+// entire contents. Useful for text-overflow.
+// This bit is cleared after each time the scrollframe is scrolled. Whoever
+// needs to set it should set it again on each paint.
+#define NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL NS_FRAME_STATE_BIT(20)
+
 class nsGfxScrollFrameInner : public nsIReflowCallback {
 public:
   class AsyncScroll;
 
   nsGfxScrollFrameInner(nsContainerFrame* aOuter, PRBool aIsRoot);
   ~nsGfxScrollFrameInner();
 
   typedef nsIScrollableFrame::ScrollbarStyles ScrollbarStyles;