Title: [152303] trunk
Revision
152303
Author
[email protected]
Date
2013-07-02 11:14:47 -0700 (Tue, 02 Jul 2013)

Log Message

constrainScrollPositionForOverhang needs to handle scrollOrigin correctly
https://bugs.webkit.org/show_bug.cgi?id=118176
<rdar://problem/14301271>

Reviewed by Anders Carlsson.

Test: compositing/geometry/fixed-position-flipped-writing-mode.html

WebCore makes use of constrainScrollPositionForOverhang not only for
constraining fixed- and sticky-positioned elements to the viewport, but
also for clamping the tile cache's visible rect.

Therefore, constrainScrollPositionForOverhang needs to correctly take
the scrollOrigin into account. The easiest way I saw to do this was to
reimplement the function in terms of a pair of rect intersections
between a virtual scrollable "viewport" and the document (with a bit
of complication from headers and footers).

The first intersection is performed, then if the viewport doesn't fit,
it is pushed down and to the right, from the origin. Next, we intersect
again, this time pushing the rect up by the amount it overflowed the document
rect from the bottom right. This performs effectively the same constraint
as previously, but handles the scrollOrigin correctly and is also somewhat
easier to read and understand (with pictures).

* page/scrolling/mac/ScrollingTreeScrollingNodeMac.mm:
(WebCore::ScrollingTreeScrollingNodeMac::setScrollLayerPosition):
Subtract the scrollOrigin out of the offset passed to scrollOffsetForFixedPosition,
it's expecting an offset without the origin included.

* platform/ScrollableArea.cpp:
(WebCore::ScrollableArea::constrainScrollPositionForOverhang):
Reimplement the function as described above.

Add a test that ensures that fixed position works with a scrollable document
and direction: rtl, which is one case where scrollOrigin is set.

Disable the test on Mac WebKit1 because of https://bugs.webkit.org/show_bug.cgi?id=118269.

* compositing/geometry/fixed-position-flipped-writing-mode-expected.txt: Added.
* compositing/geometry/fixed-position-flipped-writing-mode.html: Added.
* platform/mac/compositing/geometry/fixed-position-flipped-writing-mode-expected.png: Added.
* platform/mac/TestExpectations:
* platform/mac-wk2/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (152302 => 152303)


--- trunk/LayoutTests/ChangeLog	2013-07-02 18:00:22 UTC (rev 152302)
+++ trunk/LayoutTests/ChangeLog	2013-07-02 18:14:47 UTC (rev 152303)
@@ -1,3 +1,22 @@
+2013-07-02  Tim Horton  <[email protected]>
+
+        constrainScrollPositionForOverhang needs to handle scrollOrigin correctly
+        https://bugs.webkit.org/show_bug.cgi?id=118176
+        <rdar://problem/14301271>
+
+        Reviewed by Anders Carlsson.
+
+        Add a test that ensures that fixed position works with a scrollable document
+        and direction: rtl, which is one case where scrollOrigin is set.
+
+        Disable the test on Mac WebKit1 because of https://bugs.webkit.org/show_bug.cgi?id=118269.
+
+        * compositing/geometry/fixed-position-flipped-writing-mode-expected.txt: Added.
+        * compositing/geometry/fixed-position-flipped-writing-mode.html: Added.
+        * platform/mac/compositing/geometry/fixed-position-flipped-writing-mode-expected.png: Added.
+        * platform/mac/TestExpectations:
+        * platform/mac-wk2/TestExpectations:
+
 2013-07-02  Mario Sanchez Prada  <[email protected]>
 
         Unreviewed gardening. Added new common expectations for test after r151665.

Added: trunk/LayoutTests/compositing/geometry/fixed-position-flipped-writing-mode-expected.txt (0 => 152303)


--- trunk/LayoutTests/compositing/geometry/fixed-position-flipped-writing-mode-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/compositing/geometry/fixed-position-flipped-writing-mode-expected.txt	2013-07-02 18:14:47 UTC (rev 152303)
@@ -0,0 +1,25 @@
+(GraphicsLayer
+  (position -4208.00 0.00)
+  (bounds 5008.00 585.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 5008.00 585.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 4308.00 0.00)
+          (bounds 200.00 585.00)
+          (contentsOpaque 1)
+        )
+        (GraphicsLayer
+          (position 0.00 13.00)
+          (bounds 5000.00 15.00)
+          (opacity 0.00)
+          (usingTiledLayer 1)
+          (drawsContent 1)
+        )
+      )
+    )
+  )
+)
+

Added: trunk/LayoutTests/compositing/geometry/fixed-position-flipped-writing-mode.html (0 => 152303)


--- trunk/LayoutTests/compositing/geometry/fixed-position-flipped-writing-mode.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/geometry/fixed-position-flipped-writing-mode.html	2013-07-02 18:14:47 UTC (rev 152303)
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <title>It should be possible to cover the red box with the green box by scrolling.</title>
+    <style>
+    html {
+        direction: rtl;
+    }
+
+    body {
+        width: 5000px;
+    }
+
+    .box {
+        width: 200px;
+        height: 100%;
+        top: 0px;
+    }
+
+    #background {
+        position: absolute;
+        background-color: red;
+        right: 500px;
+    }
+
+    #cover {
+        position: fixed;
+        background-color: green;
+        left: 50%;
+    }
+
+    #layers {
+        opacity: 0;
+    }
+    </style>
+    <script>
+    if (window.testRunner)
+        testRunner.dumpAsText(true);
+
+    function runTest()
+    {
+        window.scrollTo(-300, 0);
+        if (window.testRunner)
+            document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+    }
+
+    window.addEventListener('load', runTest, false);
+    </script>
+</head>
+<body>
+    <div id="background" class="box"></div>
+    <div id="cover" class="box"></div>
+
+    <pre id="layers">Layer tree goes here.</pre>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/mac/TestExpectations (152302 => 152303)


--- trunk/LayoutTests/platform/mac/TestExpectations	2013-07-02 18:00:22 UTC (rev 152302)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2013-07-02 18:14:47 UTC (rev 152303)
@@ -1336,3 +1336,6 @@
 webkit.org/b/116582 [ Debug ] inspector/styles/import-pseudoclass-crash.html [ Pass Crash ]
 
 webkit.org/b/116592 inspector/geolocation-error.html [ Pass Failure ]
+
+# Asserts in WebKit1-debug due to a preexisting issue with overflow rect computation
+webkit.org/b/118269 compositing/geometry/fixed-position-flipped-writing-mode.html

Added: trunk/LayoutTests/platform/mac/compositing/geometry/fixed-position-flipped-writing-mode-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/mac/compositing/geometry/fixed-position-flipped-writing-mode-expected.png ___________________________________________________________________

Added: svn:mime-type

Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (152302 => 152303)


--- trunk/LayoutTests/platform/mac-wk2/TestExpectations	2013-07-02 18:00:22 UTC (rev 152302)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations	2013-07-02 18:14:47 UTC (rev 152303)
@@ -398,6 +398,9 @@
 webaudio/mediastreamaudiosourcenode.html
 webaudio/codec-tests/vorbis/
 
+# Asserts in WebKit1-debug only, so reenabling.
+compositing/geometry/fixed-position-flipped-writing-mode.html [ Pass ]
+
 ### END OF (5) Features that are not supported in WebKit1, so skipped in mac/TestExpectations then re-enabled here
 ########################################
 

Modified: trunk/Source/WebCore/ChangeLog (152302 => 152303)


--- trunk/Source/WebCore/ChangeLog	2013-07-02 18:00:22 UTC (rev 152302)
+++ trunk/Source/WebCore/ChangeLog	2013-07-02 18:14:47 UTC (rev 152303)
@@ -1,3 +1,39 @@
+2013-07-02  Tim Horton  <[email protected]>
+
+        constrainScrollPositionForOverhang needs to handle scrollOrigin correctly
+        https://bugs.webkit.org/show_bug.cgi?id=118176
+        <rdar://problem/14301271>
+
+        Reviewed by Anders Carlsson.
+
+        Test: compositing/geometry/fixed-position-flipped-writing-mode.html
+
+        WebCore makes use of constrainScrollPositionForOverhang not only for
+        constraining fixed- and sticky-positioned elements to the viewport, but
+        also for clamping the tile cache's visible rect.
+
+        Therefore, constrainScrollPositionForOverhang needs to correctly take
+        the scrollOrigin into account. The easiest way I saw to do this was to
+        reimplement the function in terms of a pair of rect intersections
+        between a virtual scrollable "viewport" and the document (with a bit
+        of complication from headers and footers).
+
+        The first intersection is performed, then if the viewport doesn't fit,
+        it is pushed down and to the right, from the origin. Next, we intersect
+        again, this time pushing the rect up by the amount it overflowed the document
+        rect from the bottom right. This performs effectively the same constraint
+        as previously, but handles the scrollOrigin correctly and is also somewhat
+        easier to read and understand (with pictures).
+
+        * page/scrolling/mac/ScrollingTreeScrollingNodeMac.mm:
+        (WebCore::ScrollingTreeScrollingNodeMac::setScrollLayerPosition):
+        Subtract the scrollOrigin out of the offset passed to scrollOffsetForFixedPosition,
+        it's expecting an offset without the origin included.
+
+        * platform/ScrollableArea.cpp:
+        (WebCore::ScrollableArea::constrainScrollPositionForOverhang):
+        Reimplement the function as described above.
+
 2013-07-02  Christophe Dumez  <[email protected]>
 
         Remove SVGStyledLocatableElement class

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeMac.mm (152302 => 152303)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeMac.mm	2013-07-02 18:00:22 UTC (rev 152302)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeMac.mm	2013-07-02 18:14:47 UTC (rev 152303)
@@ -311,7 +311,8 @@
     ASSERT(!shouldUpdateScrollLayerPositionOnMainThread());
     m_scrollLayer.get().position = CGPointMake(-position.x() + scrollOrigin().x(), -position.y() + scrollOrigin().y());
 
-    IntSize scrollOffsetForFixedChildren = FrameView::scrollOffsetForFixedPosition(viewportRect(), totalContentsSize(), position, scrollOrigin(), frameScaleFactor(), false, headerHeight(), footerHeight());
+    IntPoint scrollOffset = position - toIntSize(scrollOrigin());
+    IntSize scrollOffsetForFixedChildren = FrameView::scrollOffsetForFixedPosition(viewportRect(), totalContentsSize(), scrollOffset, scrollOrigin(), frameScaleFactor(), false, headerHeight(), footerHeight());
     if (m_counterScrollingLayer)
         m_counterScrollingLayer.get().position = FloatPoint(scrollOffsetForFixedChildren);
 
@@ -320,7 +321,7 @@
     // then we should recompute scrollOffsetForFixedChildren for the banner with a scale factor of 1.
     float horizontalScrollOffsetForBanner = scrollOffsetForFixedChildren.width();
     if (frameScaleFactor() != 1)
-        horizontalScrollOffsetForBanner = FrameView::scrollOffsetForFixedPosition(viewportRect(), totalContentsSize(), position, scrollOrigin(), 1, false, headerHeight(), footerHeight()).width();
+        horizontalScrollOffsetForBanner = FrameView::scrollOffsetForFixedPosition(viewportRect(), totalContentsSize(), scrollOffset, scrollOrigin(), 1, false, headerHeight(), footerHeight()).width();
 
     if (m_headerLayer)
         m_headerLayer.get().position = FloatPoint(horizontalScrollOffsetForBanner, 0);

Modified: trunk/Source/WebCore/platform/ScrollableArea.cpp (152302 => 152303)


--- trunk/Source/WebCore/platform/ScrollableArea.cpp	2013-07-02 18:00:22 UTC (rev 152302)
+++ trunk/Source/WebCore/platform/ScrollableArea.cpp	2013-07-02 18:14:47 UTC (rev 152303)
@@ -412,38 +412,32 @@
                    std::max(0, visibleHeight() + horizontalScrollbarHeight));
 }
 
-static int constrainedScrollPosition(int visibleContentSize, int totalContentsSize, int scrollPosition, int scrollOrigin, int headerHeight, int footerHeight)
+IntPoint ScrollableArea::constrainScrollPositionForOverhang(const IntRect& visibleContentRect, const IntSize& totalContentsSize, const IntPoint& scrollPosition, const IntPoint& scrollOrigin, int headerHeight, int footerHeight)
 {
-    int maxValue = totalContentsSize - visibleContentSize - footerHeight;
-    if (maxValue <= 0)
-        return 0;
+    // The viewport rect that we're scrolling shouldn't be larger than our document.
+    IntSize idealScrollRectSize(std::min(visibleContentRect.width(), totalContentsSize.width()), std::min(visibleContentRect.height(), totalContentsSize.height()));
+    
+    IntRect scrollRect(scrollPosition + scrollOrigin - IntSize(0, headerHeight), idealScrollRectSize);
+    IntRect documentRect(IntPoint(), IntSize(totalContentsSize.width(), totalContentsSize.height() - headerHeight - footerHeight));
 
-    if (!scrollOrigin) {
-        if (scrollPosition <= headerHeight)
-            return 0;
-        if (scrollPosition > maxValue)
-            scrollPosition = maxValue - headerHeight;
-        else
-            scrollPosition -= headerHeight;
-    } else {
-        // FIXME: position:fixed elements are currently broken when there is a non-zero y-value in the scroll origin
-        // such as when -webkit-writing-mode:horizontal-bt; is set. But when we fix that, we need to make such
-        // pages work correctly with headers and footers as well. https://bugs.webkit.org/show_bug.cgi?id=113741
-        if (scrollPosition >= 0)
-            return 0;
-        if (scrollPosition < -maxValue)
-            scrollPosition = -maxValue;
+    // Use intersection to constrain our ideal scroll rect by the document rect.
+    scrollRect.intersect(documentRect);
+
+    if (scrollRect.size() != idealScrollRectSize) {
+        // If the rect was clipped, restore its size, effectively pushing it "down" from the top left.
+        scrollRect.setSize(idealScrollRectSize);
+
+        // If we still clip, push our rect "up" from the bottom right.
+        scrollRect.intersect(documentRect);
+        if (scrollRect.width() < idealScrollRectSize.width())
+            scrollRect.move(-(idealScrollRectSize.width() - scrollRect.width()), 0);
+        if (scrollRect.height() < idealScrollRectSize.height())
+            scrollRect.move(0, -(idealScrollRectSize.height() - scrollRect.height()));
     }
 
-    return scrollPosition;
+    return scrollRect.location() - toIntSize(scrollOrigin);
 }
 
-IntPoint ScrollableArea::constrainScrollPositionForOverhang(const IntRect& visibleContentRect, const IntSize& totalContentsSize, const IntPoint& scrollPosition, const IntPoint& scrollOrigin, int headerHeight, int footerHeight)
-{
-    return IntPoint(constrainedScrollPosition(visibleContentRect.width(), totalContentsSize.width(), scrollPosition.x(), scrollOrigin.x(), 0, 0),
-        constrainedScrollPosition(visibleContentRect.height(), totalContentsSize.height(), scrollPosition.y(), scrollOrigin.y(), headerHeight, footerHeight));
-}
-
 IntPoint ScrollableArea::constrainScrollPositionForOverhang(const IntPoint& scrollPosition)
 {
     return constrainScrollPositionForOverhang(visibleContentRect(), totalContentsSize(), scrollPosition, scrollOrigin(), headerHeight(), footerHeight());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to