[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

mitz at apple.com mitz at apple.com
Thu Apr 8 00:23:50 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit c08d1576a477b763d8bb027f72cc68b957b858fd
Author: mitz at apple.com <mitz at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Dec 7 18:22:33 2009 +0000

    WebCore: Fixed <rdar://problem/7437820> Weird selection artifacts
    
    Reviewed by Darin Adler.
    
    Tests: fast/repaint/block-selection-gap-stale-cache-2.html
           fast/repaint/block-selection-gap-stale-cache.html
    
    Instead of caching the block selection gaps’ bounds in the RenderView at setSelection()
    time, cache them in each RenderLayer at paint time. This prevents the cache from getting
    stale due to layout changes and overflow scrolling.
    
    * rendering/RenderBlock.cpp:
    (WebCore::RenderBlock::selectionGapRectsForRepaint): Account for overflow scroll.
    (WebCore::RenderBlock::paintSelection): Update the enclosing layer’s selection gaps bounds.
    * rendering/RenderLayer.cpp:
    (WebCore::RenderLayer::addBlockSelectionGapsBounds): Added. Updates the selection gaps
    bounds to include the given rect.
    (WebCore::RenderLayer::clearBlockSelectionGapsBounds): Added. Recursively clears the cached
    selection gaps bounds.
    (WebCore::RenderLayer::repaintBlockSelectionGaps): Added. Recursively invalidates the
    selection gaps bounds.
    * rendering/RenderLayer.h:
    * rendering/RenderView.cpp:
    (WebCore::RenderView::setSelection): Clear the layer-level selection gaps bounds instead
    of the view-level cache.
    (WebCore::RenderView::clearSelection): Changed to call repaintBlockSelectionGaps().
    * rendering/RenderView.h:
    
    LayoutTests: Tests for <rdar://problem/7437820> Weird selection artifacts
    
    Reviewed by Darin Adler.
    
    * fast/repaint/block-selection-gap-stale-cache-2.html: Added.
    * fast/repaint/block-selection-gap-stale-cache.html: Added.
    * platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.checksum: Added.
    * platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.png: Added.
    * platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.txt: Added.
    * platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.checksum: Added.
    * platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.png: Added.
    * platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.txt: Added.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51776 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 256c7ec..1ec02e7 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,18 @@
+2009-12-07  Dan Bernstein  <mitz at apple.com>
+
+        Reviewed by Darin Adler.
+
+        Tests for <rdar://problem/7437820> Weird selection artifacts
+
+        * fast/repaint/block-selection-gap-stale-cache-2.html: Added.
+        * fast/repaint/block-selection-gap-stale-cache.html: Added.
+        * platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.checksum: Added.
+        * platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.png: Added.
+        * platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.txt: Added.
+        * platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.checksum: Added.
+        * platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.png: Added.
+        * platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.txt: Added.
+
 2009-12-07  Nikolas Zimmermann  <nzimmermann at rim.com>
 
         Not reviewed.
diff --git a/LayoutTests/fast/repaint/block-selection-gap-stale-cache-2.html b/LayoutTests/fast/repaint/block-selection-gap-stale-cache-2.html
new file mode 100644
index 0000000..dd4f5b3
--- /dev/null
+++ b/LayoutTests/fast/repaint/block-selection-gap-stale-cache-2.html
@@ -0,0 +1,24 @@
+<head>
+    <style>
+        ::selection { background-color: red; }
+    </style>
+    <script src="resources/repaint.js" type="text/javascript" charset="utf-8"></script>
+    <script type="text/javascript" charset="utf-8">
+    function repaintTest()
+    {
+        sel.empty();
+    }
+    </script>
+</head>
+<body onload="runRepaintTest()">
+<div style="height: 100px; overflow-y: scroll;">
+    <div style="margin-top: 50px;"><div id="target" style="display: inline-block; width: 100px; height: 100px;"></div><br></div>&nbsp;
+</div>
+<script>
+    var sel = getSelection();
+    var target = document.getElementById("target");
+
+    sel.setBaseAndExtent(target, 0, target.parentElement.nextSibling, 0);
+    document.body.offsetTop;
+    target.parentElement.parentElement.scrollTop = 50;
+</script>
diff --git a/LayoutTests/fast/repaint/block-selection-gap-stale-cache.html b/LayoutTests/fast/repaint/block-selection-gap-stale-cache.html
new file mode 100644
index 0000000..36e5fa5
--- /dev/null
+++ b/LayoutTests/fast/repaint/block-selection-gap-stale-cache.html
@@ -0,0 +1,22 @@
+<head>
+    <style>
+        ::selection { background-color: red; }
+    </style>
+    <script src="resources/repaint.js" type="text/javascript" charset="utf-8"></script>
+    <script type="text/javascript" charset="utf-8">
+    function repaintTest()
+    {
+        sel.empty();
+    }
+    </script>
+</head>
+<body onload="runRepaintTest()">
+<div><div id="target" style="display: inline-block; width: 100px; height: 50px;"></div><br></div>&nbsp;
+<script>
+    var sel = getSelection();
+    var target = document.getElementById("target");
+
+    sel.setBaseAndExtent(target, 0, target.parentElement.nextSibling, 0);
+    document.body.offsetTop;
+    target.style.height = "100px";
+</script>
diff --git a/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.checksum b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.checksum
new file mode 100644
index 0000000..afb012b
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.checksum
@@ -0,0 +1 @@
+50df4ee7274cb52bd125742c8bb4d4e3
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.png b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.png
new file mode 100644
index 0000000..5cd6b14
Binary files /dev/null and b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.txt b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.txt
new file mode 100644
index 0000000..f062974
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-2-expected.txt
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+layer at (8,8) size 784x100 clip at (8,8) size 769x100 scrollY 50 scrollHeight 168
+  RenderBlock {DIV} at (0,0) size 784x100
+    RenderBlock {DIV} at (0,50) size 769x100
+      RenderBlock {DIV} at (0,0) size 100x100
+      RenderBR {BR} at (100,100) size 0x0
+    RenderBlock (anonymous) at (0,150) size 769x18
+      RenderText {#text} at (0,0) size 4x18
+        text run at (0,0) width 4: " "
diff --git a/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.checksum b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.checksum
new file mode 100644
index 0000000..b91151b
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.checksum
@@ -0,0 +1 @@
+d844ead5d8fbff7fc2d6556946bd9aed
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.png b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.png
new file mode 100644
index 0000000..4fac213
Binary files /dev/null and b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.txt b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.txt
new file mode 100644
index 0000000..dd9a775
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/repaint/block-selection-gap-stale-cache-expected.txt
@@ -0,0 +1,12 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {DIV} at (0,0) size 784x100
+        RenderBlock {DIV} at (0,0) size 100x100
+        RenderBR {BR} at (100,100) size 0x0
+      RenderBlock (anonymous) at (0,100) size 784x18
+        RenderText {#text} at (0,0) size 4x18
+          text run at (0,0) width 4: " "
+        RenderText {#text} at (0,0) size 0x0
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 6d39adf..f25a04e 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,33 @@
+2009-12-07  Dan Bernstein  <mitz at apple.com>
+
+        Reviewed by Darin Adler.
+
+        Fixed <rdar://problem/7437820> Weird selection artifacts
+
+        Tests: fast/repaint/block-selection-gap-stale-cache-2.html
+               fast/repaint/block-selection-gap-stale-cache.html
+
+        Instead of caching the block selection gaps’ bounds in the RenderView at setSelection()
+        time, cache them in each RenderLayer at paint time. This prevents the cache from getting
+        stale due to layout changes and overflow scrolling.
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::selectionGapRectsForRepaint): Account for overflow scroll.
+        (WebCore::RenderBlock::paintSelection): Update the enclosing layer’s selection gaps bounds.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::addBlockSelectionGapsBounds): Added. Updates the selection gaps
+        bounds to include the given rect.
+        (WebCore::RenderLayer::clearBlockSelectionGapsBounds): Added. Recursively clears the cached
+        selection gaps bounds.
+        (WebCore::RenderLayer::repaintBlockSelectionGaps): Added. Recursively invalidates the
+        selection gaps bounds.
+        * rendering/RenderLayer.h:
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::setSelection): Clear the layer-level selection gaps bounds instead
+        of the view-level cache.
+        (WebCore::RenderView::clearSelection): Changed to call repaintBlockSelectionGaps().
+        * rendering/RenderView.h:
+
 2009-12-07  Philippe Normand  <pnormand at igalia.com>
 
         Reviewed by Gustavo Noronha.
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index f130a1c..8d2e3d1 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -1919,12 +1919,17 @@ GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintC
     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
     mapLocalToContainer(repaintContainer, false, false, transformState);
     FloatPoint offsetFromRepaintContainer = transformState.mappedPoint();
+    int x = offsetFromRepaintContainer.x();
+    int y = offsetFromRepaintContainer.y();
+
+    if (hasOverflowClip())
+        layer()->subtractScrolledContentOffset(x, y);
 
     int lastTop = 0;
     int lastLeft = leftSelectionOffset(this, lastTop);
     int lastRight = rightSelectionOffset(this, lastTop);
     
-    return fillSelectionGaps(this, offsetFromRepaintContainer.x(), offsetFromRepaintContainer.y(), offsetFromRepaintContainer.x(), offsetFromRepaintContainer.y(), lastTop, lastLeft, lastRight);
+    return fillSelectionGaps(this, x, y, x, y, lastTop, lastLeft, lastRight);
 }
 
 void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
@@ -1934,7 +1939,14 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
         int lastLeft = leftSelectionOffset(this, lastTop);
         int lastRight = rightSelectionOffset(this, lastTop);
         paintInfo.context->save();
-        fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
+        IntRect gapRectsBounds = fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
+        if (!gapRectsBounds.isEmpty()) {
+            if (RenderLayer* layer = enclosingLayer()) {
+                IntSize offset = hasLayer() ? IntSize() : offsetFromAncestorContainer(layer->renderer());
+                gapRectsBounds.move(offset - IntSize(tx, ty));
+                layer->addBlockSelectionGapsBounds(gapRectsBounds);
+            }
+        }
         paintInfo.context->restore();
     }
 }
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 3d0cc6f..819afc7 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -2852,6 +2852,36 @@ IntRect RenderLayer::selfClipRect() const
     return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect)).enclosingBoundingBox();
 }
 
+void RenderLayer::addBlockSelectionGapsBounds(const IntRect& bounds)
+{
+    m_blockSelectionGapsBounds.unite(bounds);
+}
+
+void RenderLayer::clearBlockSelectionGapsBounds()
+{
+    m_blockSelectionGapsBounds = IntRect();
+    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+        child->clearBlockSelectionGapsBounds();
+}
+
+void RenderLayer::repaintBlockSelectionGaps()
+{
+    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+        child->repaintBlockSelectionGaps();
+
+    if (m_blockSelectionGapsBounds.isEmpty())
+        return;
+
+    IntRect rect = m_blockSelectionGapsBounds;
+    rect.move(-scrolledContentOffset());
+    if (renderer()->hasOverflowClip())
+        rect.intersect(toRenderBox(renderer())->overflowClipRect(0, 0));
+    if (renderer()->hasClip())
+        rect.intersect(toRenderBox(renderer())->clipRect(0, 0));
+    if (!rect.isEmpty())
+        renderer()->repaintRectangle(rect);
+}
+
 bool RenderLayer::intersectsDamageRect(const IntRect& layerBounds, const IntRect& damageRect, const RenderLayer* rootLayer) const
 {
     // Always examine the canvas and the root.
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index 313c30d..af64fc4 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -312,6 +312,10 @@ public:
     void clearClipRectsIncludingDescendants();
     void clearClipRects();
 
+    void addBlockSelectionGapsBounds(const IntRect&);
+    void clearBlockSelectionGapsBounds();
+    void repaintBlockSelectionGaps();
+
     // Get the enclosing stacking context for this layer.  A stacking context is a layer
     // that has a non-auto z-index.
     RenderLayer* stackingContext() const;
@@ -648,6 +652,9 @@ protected:
     RenderScrollbarPart* m_scrollCorner;
     RenderScrollbarPart* m_resizer;
 
+private:
+    IntRect m_blockSelectionGapsBounds;
+
 #if USE(ACCELERATED_COMPOSITING)
     OwnPtr<RenderLayerBacking> m_backing;
 #endif
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index 2b1a525..8e7b97a 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -431,7 +431,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
         o = o->nextInPreOrder();
     }
 
-    m_cachedSelectionBounds = IntRect();
+    m_layer->clearBlockSelectionGapsBounds();
 
     // Now that the selection state has been updated for the new objects, walk them again and
     // put them in the new objects list.
@@ -444,12 +444,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
                 RenderBlockSelectionInfo* blockInfo = newSelectedBlocks.get(cb);
                 if (blockInfo)
                     break;
-                blockInfo = new RenderBlockSelectionInfo(cb);
-                newSelectedBlocks.set(cb, blockInfo);
-                IntRect rect = blockInfo->rects();
-                if (blockInfo->repaintContainer())
-                    rect = blockInfo->repaintContainer()->localToAbsoluteQuad(FloatQuad(rect)).enclosingBoundingBox();
-                m_cachedSelectionBounds.unite(rect);
+                newSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
                 cb = cb->containingBlock();
             }
         }
@@ -526,7 +521,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
 
 void RenderView::clearSelection()
 {
-    repaintRectangleInViewAndCompositedLayers(m_cachedSelectionBounds);
+    m_layer->repaintBlockSelectionGaps();
     setSelection(0, -1, 0, -1, RepaintNewMinusOld);
 }
 
diff --git a/WebCore/rendering/RenderView.h b/WebCore/rendering/RenderView.h
index 6b8da14..f601e91 100644
--- a/WebCore/rendering/RenderView.h
+++ b/WebCore/rendering/RenderView.h
@@ -193,8 +193,6 @@ protected:
     RenderWidgetSet m_widgets;
 
 private:
-    IntRect m_cachedSelectionBounds;
-
     int m_bestTruncatedAt;
     int m_truncatorWidth;
     int m_minimumColumnHeight;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list