Diff
Modified: trunk/LayoutTests/ChangeLog (192192 => 192193)
--- trunk/LayoutTests/ChangeLog 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/LayoutTests/ChangeLog 2015-11-10 01:07:47 UTC (rev 192193)
@@ -1,3 +1,22 @@
+2015-11-09 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Sometimes unable to scroll fixed div when the body is scrollable
+ https://bugs.webkit.org/show_bug.cgi?id=151015
+ <rdar://problem/23445723>
+
+ Reviewed by Simon Fraser.
+
+ Adds a new test that scrolling a fixed div is possible when the page is scrolled. Also
+ changes some existing non-fast-scrollable region tests to match the new behavior for
+ computing non-fast-scrollable regions for fixed scrollable elements (see ChangeLog
+ entry in WebCore for more details).
+
+ * tiled-drawing/scrolling/non-fast-region/fixed-div-in-scrollable-page-expected.txt: Added.
+ * tiled-drawing/scrolling/non-fast-region/fixed-div-in-scrollable-page.html: Added.
+ * tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt:
+ * tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt:
+ * tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt:
+
2015-11-09 Ryan Haddad <ryanhad...@apple.com>
Unreviewed, rolling out r192181.
Added: trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/fixed-div-in-scrollable-page-expected.txt (0 => 192193)
--- trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/fixed-div-in-scrollable-page-expected.txt (rev 0)
+++ trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/fixed-div-in-scrollable-page-expected.txt 2015-11-10 01:07:47 UTC (rev 192193)
@@ -0,0 +1 @@
+0, 0 - 1315, 1528
Added: trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/fixed-div-in-scrollable-page.html (0 => 192193)
--- trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/fixed-div-in-scrollable-page.html (rev 0)
+++ trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/fixed-div-in-scrollable-page.html 2015-11-10 01:07:47 UTC (rev 192193)
@@ -0,0 +1,42 @@
+<html>
+<head>
+ <script src=""
+ <style>
+ body {
+ margin: 0;
+ }
+
+ .fixed {
+ background: #fff;
+ position: fixed;
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ }
+
+ .tall {
+ height: 2000px;
+ }
+
+ .wide {
+ width: 2000px;
+ }
+ </style>
+ <script>
+ function dumpRegion()
+ {
+ if (window.internals) {
+ var rects = window.internals.nonFastScrollableRects();
+ document.getElementById('output').textContent = rectsAsString(rects);
+ }
+ }
+ </script>
+</head>
+<body _onload_="dumpRegion()">
+ <div class="fixed">
+ <div class="tall"></div>
+ </div>
+ <div class="tall wide"></div>
+ <pre id="output"></pre>
+</body>
+</html>
Modified: trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt (192192 => 192193)
--- trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt 2015-11-10 01:07:47 UTC (rev 192193)
@@ -1 +1 @@
-0, 0 - 785, 628
+50, 50 - 150, 178
Modified: trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt (192192 => 192193)
--- trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt 2015-11-10 01:07:47 UTC (rev 192193)
@@ -1 +1 @@
-0, 0 - 800, 600
+60, 60 - 160, 160
Modified: trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt (192192 => 192193)
--- trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/LayoutTests/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt 2015-11-10 01:07:47 UTC (rev 192193)
@@ -1 +1 @@
-0, 0 - 800, 600
+10, 10 - 110, 110
Modified: trunk/Source/WebCore/ChangeLog (192192 => 192193)
--- trunk/Source/WebCore/ChangeLog 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/ChangeLog 2015-11-10 01:07:47 UTC (rev 192193)
@@ -1,3 +1,46 @@
+2015-11-09 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Sometimes unable to scroll fixed div when the body is scrollable
+ https://bugs.webkit.org/show_bug.cgi?id=151015
+ <rdar://problem/23445723>
+
+ Reviewed by Simon Fraser.
+
+ Currently, if we scroll a page containing a fixed scrollable area, the non-fast-scrollable region corresponding to a fixed
+ area will not move down to reflect its new bounds in absolute coordinates, making it impossible to scroll position: fixed
+ overflow elements when the body's scroll position changes. To fix this, we inflate the non-fast-scrollable region
+ corresponding to scrollable position: fixed elements such that their regions encompass the area, relative to the page,
+ wherein the fixed element may lie when the page is scrolled by any amount within its scroll limits.
+
+ We also optimize the non-fast-scrollable regions emitted by elements that handle wheel events. Currently, if a fixed element
+ also has a wheel event handler, we take the entire document's rect to be non-fast-scrollable. This patch changes this region
+ to behave the same way as fixed scrollable elements above.
+
+ This patch also folds some common logic used to accomplish this into FrameView for use by RenderLayerCompositor and RenderView.
+
+ Test: tiled-drawing/scrolling/non-fast-region/fixed-div-in-scrollable-page.html
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::fixedScrollableAreaBoundsInflatedForScrolling):
+ (WebCore::FrameView::scrollOffsetRespectingCustomFixedPosition):
+ * page/FrameView.h:
+ * page/scrolling/ScrollingCoordinator.cpp:
+ (WebCore::ScrollingCoordinator::absoluteNonFastScrollableRegionForFrame):
+ * platform/ScrollableArea.h:
+ (WebCore::ScrollableArea::scrollableAreaBoundingBox):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::scrollableAreaBoundingBox):
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::computeExtent):
+ (WebCore::fixedPositionOffset): Deleted.
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::mapLocalToContainer):
+ (WebCore::RenderView::pushMappingToContainer):
+ (WebCore::RenderView::mapAbsoluteToLocalPoint):
+ (WebCore::RenderView::computeRectForRepaint):
+ (WebCore::fixedPositionOffset): Deleted.
+
2015-11-09 Ryan Haddad <ryanhad...@apple.com>
Unreviewed, rolling out r192181.
Modified: trunk/Source/WebCore/page/FrameView.cpp (192192 => 192193)
--- trunk/Source/WebCore/page/FrameView.cpp 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/page/FrameView.cpp 2015-11-10 01:07:47 UTC (rev 192193)
@@ -1076,6 +1076,25 @@
view->compositor().scheduleLayerFlush(true /* canThrottle */);
}
+LayoutRect FrameView::fixedScrollableAreaBoundsInflatedForScrolling(const LayoutRect& uninflatedBounds) const
+{
+ LayoutSize scrollPosition = scrollOffsetRespectingCustomFixedPosition();
+
+ LayoutSize topLeftExpansion = scrollPosition - toLayoutSize(minimumScrollPosition());
+ LayoutSize bottomRightExpansion = toLayoutSize(maximumScrollPosition()) - scrollPosition;
+
+ return LayoutRect(uninflatedBounds.location() - topLeftExpansion, uninflatedBounds.size() + topLeftExpansion + bottomRightExpansion);
+}
+
+LayoutSize FrameView::scrollOffsetRespectingCustomFixedPosition() const
+{
+#if PLATFORM(IOS)
+ return useCustomFixedPositionLayoutRect() ? customFixedPositionLayoutRect().location() - LayoutPoint() : scrollOffset();
+#else
+ return scrollOffsetForFixedPosition();
+#endif
+}
+
void FrameView::setHeaderHeight(int headerHeight)
{
if (frame().page())
@@ -3543,7 +3562,7 @@
return nullptr;
}
-IntRect FrameView::scrollableAreaBoundingBox() const
+IntRect FrameView::scrollableAreaBoundingBox(bool*) const
{
RenderWidget* ownerRenderer = frame().ownerRenderer();
if (!ownerRenderer)
Modified: trunk/Source/WebCore/page/FrameView.h (192192 => 192193)
--- trunk/Source/WebCore/page/FrameView.h 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/page/FrameView.h 2015-11-10 01:07:47 UTC (rev 192193)
@@ -495,6 +495,9 @@
WEBCORE_EXPORT GraphicsLayer* setWantsLayerForBottomOverHangArea(bool) const;
#endif
+ LayoutRect fixedScrollableAreaBoundsInflatedForScrolling(const LayoutRect& uninflatedBounds) const;
+ LayoutSize scrollOffsetRespectingCustomFixedPosition() const;
+
virtual int headerHeight() const override { return m_headerHeight; }
WEBCORE_EXPORT void setHeaderHeight(int);
virtual int footerHeight() const override { return m_footerHeight; }
@@ -624,7 +627,7 @@
virtual void scrollTo(const IntSize&) override;
virtual void setVisibleScrollerThumbRect(const IntRect&) override;
virtual ScrollableArea* enclosingScrollableArea() const override;
- virtual IntRect scrollableAreaBoundingBox() const override;
+ virtual IntRect scrollableAreaBoundingBox(bool* = nullptr) const override;
virtual bool scrollAnimatorEnabled() const override;
virtual GraphicsLayer* layerForScrolling() const override;
virtual GraphicsLayer* layerForHorizontalScrollbar() const override;
Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (192192 => 192193)
--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2015-11-10 01:07:47 UTC (rev 192193)
@@ -134,7 +134,11 @@
if (scrollableArea->usesAsyncScrolling())
continue;
- IntRect box = scrollableArea->scrollableAreaBoundingBox();
+ bool isInsideFixed;
+ IntRect box = scrollableArea->scrollableAreaBoundingBox(&isInsideFixed);
+ if (isInsideFixed)
+ box = IntRect(frameView->fixedScrollableAreaBoundsInflatedForScrolling(LayoutRect(box)));
+
nonFastScrollableRegion.unite(box);
}
}
@@ -168,11 +172,9 @@
Document::RegionFixedPair wheelHandlerRegion = frame.document()->absoluteRegionForEventTargets(frame.document()->wheelEventTargets());
bool wheelHandlerInFixedContent = wheelHandlerRegion.second;
if (wheelHandlerInFixedContent) {
- // FIXME: if a fixed element has a wheel event handler, for now just cover the entire document
- // with the slow-scrolling region. This could be improved.
// FIXME: need to handle position:sticky here too.
- bool inFixed;
- wheelHandlerRegion.first.unite(enclosingIntRect(frame.document()->absoluteEventHandlerBounds(inFixed)));
+ LayoutRect inflatedWheelHandlerBounds = frameView->fixedScrollableAreaBoundsInflatedForScrolling(LayoutRect(wheelHandlerRegion.first.bounds()));
+ wheelHandlerRegion.first.unite(enclosingIntRect(inflatedWheelHandlerBounds));
}
nonFastScrollableRegion.unite(wheelHandlerRegion.first);
Modified: trunk/Source/WebCore/platform/ScrollableArea.h (192192 => 192193)
--- trunk/Source/WebCore/platform/ScrollableArea.h 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/platform/ScrollableArea.h 2015-11-10 01:07:47 UTC (rev 192193)
@@ -228,7 +228,7 @@
virtual bool hasScrollableOrRubberbandableAncestor() = 0;
// Returns the bounding box of this scrollable area, in the coordinate system of the enclosing scroll view.
- virtual IntRect scrollableAreaBoundingBox() const = 0;
+ virtual IntRect scrollableAreaBoundingBox(bool* = nullptr) const = 0;
virtual bool isRubberBandInProgress() const { return false; }
virtual bool isScrollSnapInProgress() const { return false; }
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (192192 => 192193)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2015-11-10 01:07:47 UTC (rev 192193)
@@ -1486,9 +1486,9 @@
return nullptr;
}
-IntRect RenderLayer::scrollableAreaBoundingBox() const
+IntRect RenderLayer::scrollableAreaBoundingBox(bool* isInsideFixed) const
{
- return renderer().absoluteBoundingBoxRect();
+ return renderer().absoluteBoundingBoxRect(/* useTransforms */ true, isInsideFixed);
}
bool RenderLayer::isRubberBandInProgress() const
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (192192 => 192193)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2015-11-10 01:07:47 UTC (rev 192193)
@@ -874,7 +874,7 @@
virtual IntPoint lastKnownMousePosition() const override;
virtual bool isHandlingWheelEvent() const override;
virtual bool shouldSuspendScrollAnimations() const override;
- virtual IntRect scrollableAreaBoundingBox() const override;
+ virtual IntRect scrollableAreaBoundingBox(bool* isInsideFixed = nullptr) const override;
virtual bool isRubberBandInProgress() const override;
virtual bool updatesScrollLayerPositionOnMainThread() const override { return true; }
virtual bool forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const override;
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (192192 => 192193)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2015-11-10 01:07:47 UTC (rev 192193)
@@ -1185,14 +1185,6 @@
return nullptr;
}
-#if PLATFORM(IOS)
-// FIXME: Share with RenderView.
-static inline LayoutSize fixedPositionOffset(const FrameView& frameView)
-{
- return frameView.useCustomFixedPositionLayoutRect() ? (frameView.customFixedPositionLayoutRect().location() - LayoutPoint()) : frameView.scrollOffset();
-}
-#endif
-
void RenderLayerCompositor::computeExtent(const OverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& extent) const
{
if (extent.extentComputed)
@@ -1224,20 +1216,7 @@
else
viewportRect = m_renderView.frameView().viewportConstrainedVisibleContentRect();
-#if PLATFORM(IOS)
- LayoutSize scrollPosition = fixedPositionOffset(m_renderView.frameView());
-#else
- LayoutSize scrollPosition = m_renderView.frameView().scrollOffsetForFixedPosition();
-#endif
-
- LayoutPoint minimumScrollPosition = m_renderView.frameView().minimumScrollPosition();
- LayoutPoint maximumScrollPosition = m_renderView.frameView().maximumScrollPosition();
-
- LayoutSize topLeftExpansion = scrollPosition - toLayoutSize(minimumScrollPosition);
- LayoutSize bottomRightExpansion = toLayoutSize(maximumScrollPosition) - scrollPosition;
-
- extent.bounds.setLocation(extent.bounds.location() - topLeftExpansion);
- extent.bounds.setSize(extent.bounds.size() + topLeftExpansion + bottomRightExpansion);
+ extent.bounds = m_renderView.frameView().fixedScrollableAreaBoundsInflatedForScrolling(extent.bounds);
}
extent.extentComputed = true;
Modified: trunk/Source/WebCore/rendering/RenderListBox.cpp (192192 => 192193)
--- trunk/Source/WebCore/rendering/RenderListBox.cpp 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/rendering/RenderListBox.cpp 2015-11-10 01:07:47 UTC (rev 192193)
@@ -803,7 +803,7 @@
return enclosingLayer() && enclosingLayer()->hasScrollableOrRubberbandableAncestor();
}
-IntRect RenderListBox::scrollableAreaBoundingBox() const
+IntRect RenderListBox::scrollableAreaBoundingBox(bool*) const
{
return absoluteBoundingBoxRect();
}
Modified: trunk/Source/WebCore/rendering/RenderListBox.h (192192 => 192193)
--- trunk/Source/WebCore/rendering/RenderListBox.h 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/rendering/RenderListBox.h 2015-11-10 01:07:47 UTC (rev 192193)
@@ -133,7 +133,7 @@
virtual ScrollableArea* enclosingScrollableArea() const override;
virtual bool isScrollableOrRubberbandable() override;
virtual bool hasScrollableOrRubberbandableAncestor() override;
- virtual IntRect scrollableAreaBoundingBox() const override;
+ virtual IntRect scrollableAreaBoundingBox(bool* = nullptr) const override;
// NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea.
void scrollTo(int newOffset);
Modified: trunk/Source/WebCore/rendering/RenderView.cpp (192192 => 192193)
--- trunk/Source/WebCore/rendering/RenderView.cpp 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebCore/rendering/RenderView.cpp 2015-11-10 01:07:47 UTC (rev 192193)
@@ -427,13 +427,6 @@
return clientLogicalHeight();
}
-#if PLATFORM(IOS)
-static inline LayoutSize fixedPositionOffset(const FrameView& frameView)
-{
- return frameView.useCustomFixedPositionLayoutRect() ? (frameView.customFixedPositionLayoutRect().location() - LayoutPoint()) : frameView.scrollOffset();
-}
-#endif
-
void RenderView::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
{
// If a container was specified, and was not nullptr or the RenderView,
@@ -448,11 +441,7 @@
}
if (mode & IsFixed)
-#if PLATFORM(IOS)
- transformState.move(fixedPositionOffset(m_frameView));
-#else
- transformState.move(frameView().scrollOffsetForFixedPosition());
-#endif
+ transformState.move(frameView().scrollOffsetRespectingCustomFixedPosition());
}
const RenderObject* RenderView::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
@@ -461,11 +450,7 @@
// then we should have found it by now.
ASSERT_ARG(ancestorToStopAt, !ancestorToStopAt || ancestorToStopAt == this);
-#if PLATFORM(IOS)
- LayoutSize scrollOffset = fixedPositionOffset(frameView());
-#else
- LayoutSize scrollOffset = frameView().scrollOffsetForFixedPosition();
-#endif
+ LayoutSize scrollOffset = frameView().scrollOffsetRespectingCustomFixedPosition();
if (!ancestorToStopAt && shouldUseTransformFromContainer(nullptr)) {
TransformationMatrix t;
@@ -480,11 +465,7 @@
void RenderView::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
{
if (mode & IsFixed)
-#if PLATFORM(IOS)
- transformState.move(fixedPositionOffset(frameView()));
-#else
- transformState.move(frameView().scrollOffsetForFixedPosition());
-#endif
+ transformState.move(frameView().scrollOffsetRespectingCustomFixedPosition());
if (mode & UseTransforms && shouldUseTransformFromContainer(nullptr)) {
TransformationMatrix t;
@@ -716,11 +697,7 @@
}
if (fixed) {
-#if PLATFORM(IOS)
- adjustedRect.move(fixedPositionOffset(frameView()));
-#else
- adjustedRect.move(frameView().scrollOffsetForFixedPosition());
-#endif
+ adjustedRect.move(frameView().scrollOffsetRespectingCustomFixedPosition());
}
// Apply our transform if we have one (because of full page zooming).
Modified: trunk/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.h (192192 => 192193)
--- trunk/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.h 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.h 2015-11-10 01:07:47 UTC (rev 192193)
@@ -188,7 +188,7 @@
virtual WebCore::ScrollableArea* enclosingScrollableArea() const override;
virtual bool isScrollableOrRubberbandable() override { return true; }
virtual bool hasScrollableOrRubberbandableAncestor() override { return true; }
- virtual WebCore::IntRect scrollableAreaBoundingBox() const override;
+ virtual WebCore::IntRect scrollableAreaBoundingBox(bool* = nullptr) const override;
virtual void setScrollOffset(const WebCore::IntPoint&) override;
virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&) override;
virtual void invalidateScrollCornerRect(const WebCore::IntRect&) override;
Modified: trunk/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.mm (192192 => 192193)
--- trunk/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.mm 2015-11-10 00:55:28 UTC (rev 192192)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.mm 2015-11-10 01:07:47 UTC (rev 192193)
@@ -743,7 +743,7 @@
return nullptr;
}
-IntRect PDFPlugin::scrollableAreaBoundingBox() const
+IntRect PDFPlugin::scrollableAreaBoundingBox(bool*) const
{
return pluginView()->frameRect();
}