summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp715
1 files changed, 350 insertions, 365 deletions
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp
index 0486111467d..b9512464833 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp
@@ -47,20 +47,21 @@
#include "core/css/PseudoStyleRequest.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/FrameSelection.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/page/EventHandler.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/RenderGeometryMap.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderScrollbar.h"
#include "core/rendering/RenderScrollbarPart.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "platform/PlatformGestureEvent.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
@@ -73,21 +74,18 @@ namespace WebCore {
const int ResizerControlExpandRatioForTouch = 2;
-RenderLayerScrollableArea::RenderLayerScrollableArea(RenderBox* box)
- : m_box(box)
+RenderLayerScrollableArea::RenderLayerScrollableArea(RenderLayer& layer)
+ : m_layer(layer)
, m_inResizeMode(false)
+ , m_scrollsOverflow(false)
, m_scrollDimensionsDirty(true)
, m_inOverflowRelayout(false)
- , m_needsCompositedScrolling(false)
- , m_willUseCompositedScrollingHasBeenRecorded(false)
- , m_isScrollableAreaHasBeenRecorded(false)
- , m_forceNeedsCompositedScrolling(DoNotForceCompositedScrolling)
, m_scrollCorner(0)
, m_resizer(0)
{
ScrollableArea::setConstrainsScrollingToContentEdge(false);
- Node* node = m_box->node();
+ Node* node = box().node();
if (node && node->isElementNode()) {
// We save and restore only the scrollOffset as the other scroll values are recalculated.
Element* element = toElement(node);
@@ -102,31 +100,31 @@ RenderLayerScrollableArea::RenderLayerScrollableArea(RenderBox* box)
RenderLayerScrollableArea::~RenderLayerScrollableArea()
{
- if (inResizeMode() && !m_box->documentBeingDestroyed()) {
- if (Frame* frame = m_box->frame())
+ if (inResizeMode() && !box().documentBeingDestroyed()) {
+ if (LocalFrame* frame = box().frame())
frame->eventHandler().resizeScrollableAreaDestroyed();
}
- if (Frame* frame = m_box->frame()) {
+ if (LocalFrame* frame = box().frame()) {
if (FrameView* frameView = frame->view()) {
frameView->removeScrollableArea(this);
}
}
- if (m_box->frame() && m_box->frame()->page()) {
- if (ScrollingCoordinator* scrollingCoordinator = m_box->frame()->page()->scrollingCoordinator())
+ if (box().frame() && box().frame()->page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = box().frame()->page()->scrollingCoordinator())
scrollingCoordinator->willDestroyScrollableArea(this);
}
- if (!m_box->documentBeingDestroyed()) {
- Node* node = m_box->node();
+ if (!box().documentBeingDestroyed()) {
+ Node* node = box().node();
if (node && node->isElementNode())
toElement(node)->setSavedLayerScrollOffset(m_scrollOffset);
}
- if (Frame* frame = m_box->frame()) {
+ if (LocalFrame* frame = box().frame()) {
if (FrameView* frameView = frame->view())
- frameView->removeResizerArea(m_box);
+ frameView->removeResizerArea(box());
}
destroyScrollbar(HorizontalScrollbar);
@@ -138,38 +136,40 @@ RenderLayerScrollableArea::~RenderLayerScrollableArea()
m_resizer->destroy();
}
-ScrollableArea* RenderLayerScrollableArea::enclosingScrollableArea() const
-{
- if (RenderBox* enclosingScrollableBox = m_box->enclosingScrollableBox())
- return enclosingScrollableBox->layer()->scrollableArea();
-
- // FIXME: We should return the frame view here (or possibly an ancestor frame view,
- // if the frame view isn't scrollable.
- return 0;
-}
-
GraphicsLayer* RenderLayerScrollableArea::layerForScrolling() const
{
- return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->scrollingContentsLayer() : 0;
+ return box().hasCompositedLayerMapping() ? box().compositedLayerMapping()->scrollingContentsLayer() : 0;
}
GraphicsLayer* RenderLayerScrollableArea::layerForHorizontalScrollbar() const
{
- return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->layerForHorizontalScrollbar() : 0;
+ // See crbug.com/343132.
+ DisableCompositingQueryAsserts disabler;
+
+ return box().hasCompositedLayerMapping() ? box().compositedLayerMapping()->layerForHorizontalScrollbar() : 0;
}
GraphicsLayer* RenderLayerScrollableArea::layerForVerticalScrollbar() const
{
- return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->layerForVerticalScrollbar() : 0;
+ // See crbug.com/343132.
+ DisableCompositingQueryAsserts disabler;
+
+ return box().hasCompositedLayerMapping() ? box().compositedLayerMapping()->layerForVerticalScrollbar() : 0;
}
GraphicsLayer* RenderLayerScrollableArea::layerForScrollCorner() const
{
- return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->layerForScrollCorner() : 0;
+ // See crbug.com/343132.
+ DisableCompositingQueryAsserts disabler;
+
+ return box().hasCompositedLayerMapping() ? box().compositedLayerMapping()->layerForScrollCorner() : 0;
}
void RenderLayerScrollableArea::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
{
+ // See crbug.com/343132.
+ DisableCompositingQueryAsserts disabler;
+
if (scrollbar == m_vBar.get()) {
if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
layer->setNeedsDisplayInRect(rect);
@@ -184,14 +184,34 @@ void RenderLayerScrollableArea::invalidateScrollbarRect(Scrollbar* scrollbar, co
IntRect scrollRect = rect;
// If we are not yet inserted into the tree, there is no need to repaint.
- if (!m_box->parent())
+ if (!box().parent())
return;
if (scrollbar == m_vBar.get())
- scrollRect.move(verticalScrollbarStart(0, m_box->width()), m_box->borderTop());
+ scrollRect.move(verticalScrollbarStart(0, box().width()), box().borderTop());
else
- scrollRect.move(horizontalScrollbarStart(0), m_box->height() - m_box->borderBottom() - scrollbar->height());
- m_box->repaintRectangle(scrollRect);
+ scrollRect.move(horizontalScrollbarStart(0), box().height() - box().borderBottom() - scrollbar->height());
+
+ if (scrollRect.isEmpty())
+ return;
+
+ LayoutRect repaintRect = scrollRect;
+ box().flipForWritingMode(repaintRect);
+
+ IntRect intRect = pixelSnappedIntRect(repaintRect);
+
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && box().frameView()->isInPerformLayout()) {
+ if (scrollbar == m_vBar.get()) {
+ m_verticalBarDamage = intRect;
+ m_hasVerticalBarDamage = true;
+ } else {
+ m_horizontalBarDamage = intRect;
+ m_hasHorizontalBarDamage = true;
+ }
+
+ } else {
+ box().invalidatePaintRectangle(intRect);
+ }
}
void RenderLayerScrollableArea::invalidateScrollCornerRect(const IntRect& rect)
@@ -202,14 +222,14 @@ void RenderLayerScrollableArea::invalidateScrollCornerRect(const IntRect& rect)
}
if (m_scrollCorner)
- m_scrollCorner->repaintRectangle(rect);
+ m_scrollCorner->invalidatePaintRectangle(rect);
if (m_resizer)
- m_resizer->repaintRectangle(rect);
+ m_resizer->invalidatePaintRectangle(rect);
}
bool RenderLayerScrollableArea::isActive() const
{
- Page* page = m_box->frame()->page();
+ Page* page = box().frame()->page();
return page && page->focusController().isActive();
}
@@ -258,53 +278,53 @@ IntRect RenderLayerScrollableArea::scrollCornerRect() const
// (b) Both scrollbars are present.
bool hasHorizontalBar = horizontalScrollbar();
bool hasVerticalBar = verticalScrollbar();
- bool hasResizer = m_box->style()->resize() != RESIZE_NONE;
+ bool hasResizer = box().style()->resize() != RESIZE_NONE;
if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
- return cornerRect(m_box->style(), horizontalScrollbar(), verticalScrollbar(), m_box->pixelSnappedBorderBoxRect());
+ return cornerRect(box().style(), horizontalScrollbar(), verticalScrollbar(), box().pixelSnappedBorderBoxRect());
return IntRect();
}
IntRect RenderLayerScrollableArea::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return scrollbarRect;
IntRect rect = scrollbarRect;
rect.move(scrollbarOffset(scrollbar));
- return view->frameView()->convertFromRenderer(m_box, rect);
+ return view->frameView()->convertFromRenderer(box(), rect);
}
IntRect RenderLayerScrollableArea::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return parentRect;
- IntRect rect = view->frameView()->convertToRenderer(m_box, parentRect);
+ IntRect rect = view->frameView()->convertToRenderer(box(), parentRect);
rect.move(-scrollbarOffset(scrollbar));
return rect;
}
IntPoint RenderLayerScrollableArea::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return scrollbarPoint;
IntPoint point = scrollbarPoint;
point.move(scrollbarOffset(scrollbar));
- return view->frameView()->convertFromRenderer(m_box, point);
+ return view->frameView()->convertFromRenderer(box(), point);
}
IntPoint RenderLayerScrollableArea::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return parentPoint;
- IntPoint point = view->frameView()->convertToRenderer(m_box, parentPoint);
+ IntPoint point = view->frameView()->convertToRenderer(box(), parentPoint);
point.move(-scrollbarOffset(scrollbar));
return point;
@@ -318,7 +338,7 @@ int RenderLayerScrollableArea::scrollSize(ScrollbarOrientation orientation) cons
void RenderLayerScrollableArea::setScrollOffset(const IntPoint& newScrollOffset)
{
- if (!m_box->isMarquee()) {
+ if (!box().isMarquee()) {
// Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).
if (m_scrollDimensionsDirty)
computeScrollDimensions();
@@ -329,62 +349,77 @@ void RenderLayerScrollableArea::setScrollOffset(const IntPoint& newScrollOffset)
setScrollOffset(toIntSize(newScrollOffset));
- Frame* frame = m_box->frame();
- InspectorInstrumentation::willScrollLayer(m_box);
+ LocalFrame* frame = box().frame();
+ ASSERT(frame);
- RenderView* view = m_box->view();
+ RefPtr<FrameView> frameView = box().frameView();
- // We should have a RenderView if we're trying to scroll.
- ASSERT(view);
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ScrollLayer", "data", InspectorScrollLayerEvent::data(&box()));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::willScrollLayer(&box());
// Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll).
// We don't update compositing layers, because we need to do a deep update from the compositing ancestor.
- bool inLayout = view ? view->frameView()->isInLayout() : false;
- if (!inLayout) {
+ if (!frameView->isInPerformLayout()) {
// If we're in the middle of layout, we'll just update layers once layout has finished.
layer()->updateLayerPositionsAfterOverflowScroll();
- if (view) {
- // Update regions, scrolling may change the clip of a particular region.
- view->frameView()->updateAnnotatedRegions();
- view->updateWidgetPositions();
- }
-
+ // Update regions, scrolling may change the clip of a particular region.
+ frameView->updateAnnotatedRegions();
+ // FIXME: We shouldn't call updateWidgetPositions() here since it might tear down the render tree,
+ // for now we just crash to avoid allowing an attacker to use after free.
+ frameView->updateWidgetPositions();
+ RELEASE_ASSERT(frameView->renderView());
updateCompositingLayersAfterScroll();
}
- RenderLayerModelObject* repaintContainer = m_box->containerForRepaint();
- if (frame) {
- // The caret rect needs to be invalidated after scrolling
- frame->selection().setCaretRectNeedsUpdate();
+ const RenderLayerModelObject* repaintContainer = box().containerForPaintInvalidation();
+ // The caret rect needs to be invalidated after scrolling
+ frame->selection().setCaretRectNeedsUpdate();
- FloatQuad quadForFakeMouseMoveEvent = FloatQuad(layer()->repainter().repaintRect());
- if (repaintContainer)
- quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
- frame->eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
- }
+ FloatQuad quadForFakeMouseMoveEvent;
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ quadForFakeMouseMoveEvent = FloatQuad(layer()->renderer()->previousPaintInvalidationRect());
+ else
+ quadForFakeMouseMoveEvent = FloatQuad(layer()->repainter().repaintRect());
+
+ quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
+ frame->eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
bool requiresRepaint = true;
- if (m_box->view()->compositor()->inCompositingMode()) {
+ if (box().view()->compositor()->inCompositingMode()) {
+ // Hits in virtual/gpu/fast/canvas/canvas-scroll-path-into-view.html.
+ DisableCompositingQueryAsserts disabler;
bool onlyScrolledCompositedLayers = scrollsOverflow()
&& !layer()->hasVisibleNonLayerContent()
&& !layer()->hasNonCompositedChild()
&& !layer()->hasBlockSelectionGapBounds()
- && !m_box->isMarquee();
+ && !box().isMarquee();
if (usesCompositedScrolling() || onlyScrolledCompositedLayers)
requiresRepaint = false;
}
// Just schedule a full repaint of our object.
- if (view && requiresRepaint)
- m_box->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(layer()->repainter().repaintRect()));
+ if (requiresRepaint) {
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ if (box().frameView()->isInPerformLayout())
+ box().setShouldDoFullPaintInvalidationAfterLayout(true);
+ else
+ box().invalidatePaintUsingContainer(repaintContainer, pixelSnappedIntRect(layer()->renderer()->previousPaintInvalidationRect()), InvalidationScroll);
+ } else {
+ box().invalidatePaintUsingContainer(repaintContainer, pixelSnappedIntRect(layer()->repainter().repaintRect()), InvalidationScroll);
+ }
+ }
// Schedule the scroll DOM event.
- if (m_box->node())
- m_box->node()->document().enqueueScrollEventForNode(m_box->node());
+ if (box().node())
+ box().node()->document().enqueueScrollEventForNode(box().node());
- InspectorInstrumentation::didScrollLayer(m_box);
+ if (AXObjectCache* cache = box().document().existingAXObjectCache())
+ cache->handleScrollPositionChanged(&box());
+
+ InspectorInstrumentation::didScrollLayer(&box());
}
IntPoint RenderLayerScrollableArea::scrollPosition() const
@@ -399,10 +434,10 @@ IntPoint RenderLayerScrollableArea::minimumScrollPosition() const
IntPoint RenderLayerScrollableArea::maximumScrollPosition() const
{
- if (!m_box->hasOverflowClip())
+ if (!box().hasOverflowClip())
return -scrollOrigin();
- return -scrollOrigin() + enclosingIntRect(m_overflowRect).size() - enclosingIntRect(m_box->clientBoxRect()).size();
+ return -scrollOrigin() + enclosingIntRect(m_overflowRect).size() - enclosingIntRect(box().clientBoxRect()).size();
}
IntRect RenderLayerScrollableArea::visibleContentRect(IncludeScrollbarsInRect scrollbarInclusion) const
@@ -440,12 +475,12 @@ IntSize RenderLayerScrollableArea::overhangAmount() const
IntPoint RenderLayerScrollableArea::lastKnownMousePosition() const
{
- return m_box->frame() ? m_box->frame()->eventHandler().lastKnownMousePosition() : IntPoint();
+ return box().frame() ? box().frame()->eventHandler().lastKnownMousePosition() : IntPoint();
}
bool RenderLayerScrollableArea::shouldSuspendScrollAnimations() const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return true;
return view->frameView()->shouldSuspendScrollAnimations();
@@ -453,7 +488,7 @@ bool RenderLayerScrollableArea::shouldSuspendScrollAnimations() const
bool RenderLayerScrollableArea::scrollbarsCanBeActive() const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return false;
return view->frameView()->scrollbarsCanBeActive();
@@ -461,62 +496,67 @@ bool RenderLayerScrollableArea::scrollbarsCanBeActive() const
IntRect RenderLayerScrollableArea::scrollableAreaBoundingBox() const
{
- return m_box->absoluteBoundingBoxRect();
+ return box().absoluteBoundingBoxRect();
}
bool RenderLayerScrollableArea::userInputScrollable(ScrollbarOrientation orientation) const
{
- if (m_box->isIntristicallyScrollable(orientation))
+ if (box().isIntristicallyScrollable(orientation))
return true;
EOverflow overflowStyle = (orientation == HorizontalScrollbar) ?
- m_box->style()->overflowX() : m_box->style()->overflowY();
+ box().style()->overflowX() : box().style()->overflowY();
return (overflowStyle == OSCROLL || overflowStyle == OAUTO || overflowStyle == OOVERLAY);
}
bool RenderLayerScrollableArea::shouldPlaceVerticalScrollbarOnLeft() const
{
- return m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft();
+ return box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft();
}
int RenderLayerScrollableArea::pageStep(ScrollbarOrientation orientation) const
{
int length = (orientation == HorizontalScrollbar) ?
- m_box->pixelSnappedClientWidth() : m_box->pixelSnappedClientHeight();
+ box().pixelSnappedClientWidth() : box().pixelSnappedClientHeight();
int minPageStep = static_cast<float>(length) * ScrollableArea::minFractionToStepWhenPaging();
int pageStep = max(minPageStep, length - ScrollableArea::maxOverlapBetweenPages());
return max(pageStep, 1);
}
+RenderBox& RenderLayerScrollableArea::box() const
+{
+ return *m_layer.renderBox();
+}
+
RenderLayer* RenderLayerScrollableArea::layer() const
{
- return m_box->layer();
+ return &m_layer;
}
-int RenderLayerScrollableArea::scrollWidth() const
+LayoutUnit RenderLayerScrollableArea::scrollWidth() const
{
if (m_scrollDimensionsDirty)
const_cast<RenderLayerScrollableArea*>(this)->computeScrollDimensions();
- return snapSizeToPixel(m_overflowRect.width(), m_box->clientLeft() + m_box->x());
+ return m_overflowRect.width();
}
-int RenderLayerScrollableArea::scrollHeight() const
+LayoutUnit RenderLayerScrollableArea::scrollHeight() const
{
if (m_scrollDimensionsDirty)
const_cast<RenderLayerScrollableArea*>(this)->computeScrollDimensions();
- return snapSizeToPixel(m_overflowRect.height(), m_box->clientTop() + m_box->y());
+ return m_overflowRect.height();
}
void RenderLayerScrollableArea::computeScrollDimensions()
{
m_scrollDimensionsDirty = false;
- m_overflowRect = m_box->layoutOverflowRect();
- m_box->flipForWritingMode(m_overflowRect);
+ m_overflowRect = box().layoutOverflowRect();
+ box().flipForWritingMode(m_overflowRect);
- int scrollableLeftOverflow = m_overflowRect.x() - m_box->borderLeft() - (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? m_box->verticalScrollbarWidth() : 0);
- int scrollableTopOverflow = m_overflowRect.y() - m_box->borderTop();
+ int scrollableLeftOverflow = m_overflowRect.x() - box().borderLeft() - (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? box().verticalScrollbarWidth() : 0);
+ int scrollableTopOverflow = m_overflowRect.y() - box().borderTop();
setScrollOrigin(IntPoint(-scrollableLeftOverflow, -scrollableTopOverflow));
}
@@ -530,7 +570,7 @@ void RenderLayerScrollableArea::scrollToOffset(const IntSize& scrollOffset, Scro
void RenderLayerScrollableArea::updateAfterLayout()
{
// List box parts handle the scrollbars by themselves so we have nothing to do.
- if (m_box->style()->appearance() == ListboxPart)
+ if (box().style()->appearance() == ListboxPart)
return;
m_scrollDimensionsDirty = true;
@@ -538,7 +578,7 @@ void RenderLayerScrollableArea::updateAfterLayout()
computeScrollDimensions();
- if (!m_box->isMarquee()) {
+ if (!box().isMarquee()) {
// Layout may cause us to be at an invalid scroll position. In this case we need
// to pull our scroll offsets back to the max (or push them up to the min).
IntSize clampedScrollOffset = clampScrollOffset(adjustedScrollOffset());
@@ -552,87 +592,97 @@ void RenderLayerScrollableArea::updateAfterLayout()
bool hasHorizontalOverflow = this->hasHorizontalOverflow();
bool hasVerticalOverflow = this->hasVerticalOverflow();
- // overflow:scroll should just enable/disable.
- if (m_box->style()->overflowX() == OSCROLL)
- horizontalScrollbar()->setEnabled(hasHorizontalOverflow);
- if (m_box->style()->overflowY() == OSCROLL)
- verticalScrollbar()->setEnabled(hasVerticalOverflow);
+ {
+ // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html.
+ DisableCompositingQueryAsserts disabler;
+
+ // overflow:scroll should just enable/disable.
+ if (box().style()->overflowX() == OSCROLL)
+ horizontalScrollbar()->setEnabled(hasHorizontalOverflow);
+ if (box().style()->overflowY() == OSCROLL)
+ verticalScrollbar()->setEnabled(hasVerticalOverflow);
+ }
// overflow:auto may need to lay out again if scrollbars got added/removed.
- bool autoHorizontalScrollBarChanged = m_box->hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
- bool autoVerticalScrollBarChanged = m_box->hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);
+ bool autoHorizontalScrollBarChanged = box().hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
+ bool autoVerticalScrollBarChanged = box().hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);
if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) {
- if (m_box->hasAutoHorizontalScrollbar())
+ if (box().hasAutoHorizontalScrollbar())
setHasHorizontalScrollbar(hasHorizontalOverflow);
- if (m_box->hasAutoVerticalScrollbar())
+ if (box().hasAutoVerticalScrollbar())
setHasVerticalScrollbar(hasVerticalOverflow);
+ if (hasVerticalOverflow || hasHorizontalOverflow)
+ updateScrollCornerStyle();
+
layer()->updateSelfPaintingLayer();
// Force an update since we know the scrollbars have changed things.
- if (m_box->document().hasAnnotatedRegions())
- m_box->document().setAnnotatedRegionsDirty(true);
+ if (box().document().hasAnnotatedRegions())
+ box().document().setAnnotatedRegionsDirty(true);
- m_box->repaint();
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ box().paintInvalidationForWholeRenderer();
- if (m_box->style()->overflowX() == OAUTO || m_box->style()->overflowY() == OAUTO) {
+ if (box().style()->overflowX() == OAUTO || box().style()->overflowY() == OAUTO) {
if (!m_inOverflowRelayout) {
// Our proprietary overflow: overlay value doesn't trigger a layout.
m_inOverflowRelayout = true;
- SubtreeLayoutScope layoutScope(m_box);
- layoutScope.setNeedsLayout(m_box);
- if (m_box->isRenderBlock()) {
- RenderBlock* block = toRenderBlock(m_box);
- block->scrollbarsChanged(autoHorizontalScrollBarChanged, autoVerticalScrollBarChanged);
- block->layoutBlock(true);
+ SubtreeLayoutScope layoutScope(box());
+ layoutScope.setNeedsLayout(&box());
+ if (box().isRenderBlock()) {
+ RenderBlock& block = toRenderBlock(box());
+ block.scrollbarsChanged(autoHorizontalScrollBarChanged, autoVerticalScrollBarChanged);
+ block.layoutBlock(true);
} else {
- m_box->layout();
+ box().layout();
}
m_inOverflowRelayout = false;
}
}
}
- // Set up the range (and page step/line step).
- if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
- int clientWidth = m_box->pixelSnappedClientWidth();
- horizontalScrollbar->setProportion(clientWidth, overflowRect().width());
- }
- if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
- int clientHeight = m_box->pixelSnappedClientHeight();
- verticalScrollbar->setProportion(clientHeight, overflowRect().height());
+ {
+ // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html.
+ DisableCompositingQueryAsserts disabler;
+
+ // Set up the range (and page step/line step).
+ if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
+ int clientWidth = box().pixelSnappedClientWidth();
+ horizontalScrollbar->setProportion(clientWidth, overflowRect().width());
+ }
+ if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
+ int clientHeight = box().pixelSnappedClientHeight();
+ verticalScrollbar->setProportion(clientHeight, overflowRect().height());
+ }
}
updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
-
- // Composited scrolling may need to be enabled or disabled if the amount of overflow changed.
- if (m_box->view() && m_box->view()->compositor()->updateLayerCompositingState(m_box->layer()))
- m_box->view()->compositor()->setCompositingLayersNeedRebuild();
}
bool RenderLayerScrollableArea::hasHorizontalOverflow() const
{
ASSERT(!m_scrollDimensionsDirty);
- return scrollWidth() > m_box->pixelSnappedClientWidth();
+ return scrollWidth() > box().clientWidth();
}
bool RenderLayerScrollableArea::hasVerticalOverflow() const
{
ASSERT(!m_scrollDimensionsDirty);
- return scrollHeight() > m_box->pixelSnappedClientHeight();
+ return scrollHeight() > box().clientHeight();
}
bool RenderLayerScrollableArea::hasScrollableHorizontalOverflow() const
{
- return hasHorizontalOverflow() && m_box->scrollsOverflowX();
+ return hasHorizontalOverflow() && box().scrollsOverflowX();
}
bool RenderLayerScrollableArea::hasScrollableVerticalOverflow() const
{
- return hasVerticalOverflow() && m_box->scrollsOverflowY();
+ return hasVerticalOverflow() && box().scrollsOverflowY();
}
static bool overflowRequiresScrollbar(EOverflow overflow)
@@ -648,14 +698,18 @@ static bool overflowDefinesAutomaticScrollbar(EOverflow overflow)
void RenderLayerScrollableArea::updateAfterStyleChange(const RenderStyle* oldStyle)
{
// List box parts handle the scrollbars by themselves so we have nothing to do.
- if (m_box->style()->appearance() == ListboxPart)
+ if (box().style()->appearance() == ListboxPart)
+ return;
+
+ // RenderView shouldn't provide scrollbars on its own.
+ if (box().isRenderView())
return;
if (!m_scrollDimensionsDirty)
updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
- EOverflow overflowX = m_box->style()->overflowX();
- EOverflow overflowY = m_box->style()->overflowY();
+ EOverflow overflowX = box().style()->overflowX();
+ EOverflow overflowY = box().style()->overflowY();
// To avoid doing a relayout in updateScrollbarsAfterLayout, we try to keep any automatic scrollbar that was already present.
bool needsHorizontalScrollbar = (hasHorizontalScrollbar() && overflowDefinesAutomaticScrollbar(overflowX)) || overflowRequiresScrollbar(overflowX);
@@ -686,10 +740,35 @@ void RenderLayerScrollableArea::updateAfterStyleChange(const RenderStyle* oldSty
updateResizerStyle();
}
+void RenderLayerScrollableArea::updateAfterCompositingChange()
+{
+ layer()->updateScrollingStateAfterCompositingChange();
+}
+
+void RenderLayerScrollableArea::updateAfterOverflowRecalc()
+{
+ computeScrollDimensions();
+ if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
+ int clientWidth = box().pixelSnappedClientWidth();
+ horizontalScrollbar->setProportion(clientWidth, overflowRect().width());
+ }
+ if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
+ int clientHeight = box().pixelSnappedClientHeight();
+ verticalScrollbar->setProportion(clientHeight, overflowRect().height());
+ }
+
+ bool hasHorizontalOverflow = this->hasHorizontalOverflow();
+ bool hasVerticalOverflow = this->hasVerticalOverflow();
+ bool autoHorizontalScrollBarChanged = box().hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
+ bool autoVerticalScrollBarChanged = box().hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);
+ if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged)
+ box().setNeedsLayoutAndFullPaintInvalidation();
+}
+
IntSize RenderLayerScrollableArea::clampScrollOffset(const IntSize& scrollOffset) const
{
- int maxX = scrollWidth() - m_box->pixelSnappedClientWidth();
- int maxY = scrollHeight() - m_box->pixelSnappedClientHeight();
+ int maxX = scrollWidth() - box().pixelSnappedClientWidth();
+ int maxY = scrollHeight() - box().pixelSnappedClientHeight();
int x = std::max(std::min(scrollOffset.width(), maxX), 0);
int y = std::max(std::min(scrollOffset.height(), maxY), 0);
@@ -704,8 +783,8 @@ IntRect RenderLayerScrollableArea::rectForHorizontalScrollbar(const IntRect& bor
const IntRect& scrollCorner = scrollCornerRect();
return IntRect(horizontalScrollbarStart(borderBoxRect.x()),
- borderBoxRect.maxY() - m_box->borderBottom() - m_hBar->height(),
- borderBoxRect.width() - (m_box->borderLeft() + m_box->borderRight()) - scrollCorner.width(),
+ borderBoxRect.maxY() - box().borderBottom() - m_hBar->height(),
+ borderBoxRect.width() - (box().borderLeft() + box().borderRight()) - scrollCorner.width(),
m_hBar->height());
}
@@ -717,54 +796,54 @@ IntRect RenderLayerScrollableArea::rectForVerticalScrollbar(const IntRect& borde
const IntRect& scrollCorner = scrollCornerRect();
return IntRect(verticalScrollbarStart(borderBoxRect.x(), borderBoxRect.maxX()),
- borderBoxRect.y() + m_box->borderTop(),
+ borderBoxRect.y() + box().borderTop(),
m_vBar->width(),
- borderBoxRect.height() - (m_box->borderTop() + m_box->borderBottom()) - scrollCorner.height());
+ borderBoxRect.height() - (box().borderTop() + box().borderBottom()) - scrollCorner.height());
}
LayoutUnit RenderLayerScrollableArea::verticalScrollbarStart(int minX, int maxX) const
{
- if (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
- return minX + m_box->borderLeft();
- return maxX - m_box->borderRight() - m_vBar->width();
+ if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+ return minX + box().borderLeft();
+ return maxX - box().borderRight() - m_vBar->width();
}
LayoutUnit RenderLayerScrollableArea::horizontalScrollbarStart(int minX) const
{
- int x = minX + m_box->borderLeft();
- if (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
- x += m_vBar ? m_vBar->width() : resizerCornerRect(m_box->pixelSnappedBorderBoxRect(), ResizerForPointer).width();
+ int x = minX + box().borderLeft();
+ if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+ x += m_vBar ? m_vBar->width() : resizerCornerRect(box().pixelSnappedBorderBoxRect(), ResizerForPointer).width();
return x;
}
IntSize RenderLayerScrollableArea::scrollbarOffset(const Scrollbar* scrollbar) const
{
if (scrollbar == m_vBar.get())
- return IntSize(verticalScrollbarStart(0, m_box->width()), m_box->borderTop());
+ return IntSize(verticalScrollbarStart(0, box().width()), box().borderTop());
if (scrollbar == m_hBar.get())
- return IntSize(horizontalScrollbarStart(0), m_box->height() - m_box->borderBottom() - scrollbar->height());
+ return IntSize(horizontalScrollbarStart(0), box().height() - box().borderBottom() - scrollbar->height());
ASSERT_NOT_REACHED();
return IntSize();
}
-static inline RenderObject* rendererForScrollbar(RenderObject* renderer)
+static inline RenderObject* rendererForScrollbar(RenderObject& renderer)
{
- if (Node* node = renderer->node()) {
+ if (Node* node = renderer.node()) {
if (ShadowRoot* shadowRoot = node->containingShadowRoot()) {
if (shadowRoot->type() == ShadowRoot::UserAgentShadowRoot)
return shadowRoot->host()->renderer();
}
}
- return renderer;
+ return &renderer;
}
PassRefPtr<Scrollbar> RenderLayerScrollableArea::createScrollbar(ScrollbarOrientation orientation)
{
RefPtr<Scrollbar> widget;
- RenderObject* actualRenderer = rendererForScrollbar(m_box);
+ RenderObject* actualRenderer = rendererForScrollbar(box());
bool hasCustomScrollbarStyle = actualRenderer->isBox() && actualRenderer->style()->hasPseudoStyle(SCROLLBAR);
if (hasCustomScrollbarStyle) {
widget = RenderScrollbar::createCustomScrollbar(this, orientation, actualRenderer->node());
@@ -775,7 +854,7 @@ PassRefPtr<Scrollbar> RenderLayerScrollableArea::createScrollbar(ScrollbarOrient
else
didAddScrollbar(widget.get(), VerticalScrollbar);
}
- m_box->document().view()->addChild(widget.get());
+ box().document().view()->addChild(widget.get());
return widget.release();
}
@@ -790,7 +869,7 @@ void RenderLayerScrollableArea::destroyScrollbar(ScrollbarOrientation orientatio
scrollbar->removeFromParent();
scrollbar->disconnectFromScrollableArea();
- scrollbar = 0;
+ scrollbar = nullptr;
}
void RenderLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar)
@@ -798,10 +877,14 @@ void RenderLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar)
if (hasScrollbar == hasHorizontalScrollbar())
return;
- if (hasScrollbar)
+ if (hasScrollbar) {
+ // This doesn't hit in any tests, but since the equivalent code in setHasVerticalScrollbar
+ // does, presumably this code does as well.
+ DisableCompositingQueryAsserts disabler;
m_hBar = createScrollbar(HorizontalScrollbar);
- else
+ } else {
destroyScrollbar(HorizontalScrollbar);
+ }
// Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
if (m_hBar)
@@ -810,8 +893,8 @@ void RenderLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar)
m_vBar->styleChanged();
// Force an update since we know the scrollbars have changed things.
- if (m_box->document().hasAnnotatedRegions())
- m_box->document().setAnnotatedRegionsDirty(true);
+ if (box().document().hasAnnotatedRegions())
+ box().document().setAnnotatedRegionsDirty(true);
}
void RenderLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar)
@@ -819,10 +902,13 @@ void RenderLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar)
if (hasScrollbar == hasVerticalScrollbar())
return;
- if (hasScrollbar)
+ if (hasScrollbar) {
+ // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html
+ DisableCompositingQueryAsserts disabler;
m_vBar = createScrollbar(VerticalScrollbar);
- else
+ } else {
destroyScrollbar(VerticalScrollbar);
+ }
// Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
if (m_hBar)
@@ -831,8 +917,8 @@ void RenderLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar)
m_vBar->styleChanged();
// Force an update since we know the scrollbars have changed things.
- if (m_box->document().hasAnnotatedRegions())
- m_box->document().setAnnotatedRegionsDirty(true);
+ if (box().document().hasAnnotatedRegions())
+ box().document().setAnnotatedRegionsDirty(true);
}
int RenderLayerScrollableArea::verticalScrollbarWidth(OverlayScrollbarSizeRelevancy relevancy) const
@@ -849,23 +935,12 @@ int RenderLayerScrollableArea::horizontalScrollbarHeight(OverlayScrollbarSizeRel
return m_hBar->height();
}
-void RenderLayerScrollableArea::positionOverflowControls()
-{
- RenderGeometryMap geometryMap(UseTransforms);
- RenderView* view = m_box->view();
- if (m_box->layer() != view->layer() && m_box->layer()->parent())
- geometryMap.pushMappingsToAncestor(m_box->layer()->parent(), 0);
-
- LayoutPoint offsetFromRoot = LayoutPoint(geometryMap.absolutePoint(FloatPoint()));
- positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot)));
-}
-
void RenderLayerScrollableArea::positionOverflowControls(const IntSize& offsetFromRoot)
{
- if (!hasScrollbar() && !m_box->canResize())
+ if (!hasScrollbar() && !box().canResize())
return;
- const IntRect borderBox = m_box->pixelSnappedBorderBoxRect();
+ const IntRect borderBox = box().pixelSnappedBorderBoxRect();
if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
IntRect vBarRect = rectForVerticalScrollbar(borderBox);
vBarRect.move(offsetFromRoot);
@@ -888,26 +963,23 @@ void RenderLayerScrollableArea::positionOverflowControls(const IntSize& offsetFr
// FIXME, this should eventually be removed, once we are certain that composited
// controls get correctly positioned on a compositor update. For now, conservatively
// leaving this unchanged.
- if (m_box->hasCompositedLayerMapping())
- m_box->compositedLayerMapping()->positionOverflowControlsLayers(offsetFromRoot);
-}
-
-bool RenderLayerScrollableArea::scrollsOverflow() const
-{
- if (FrameView* frameView = m_box->view()->frameView())
- return frameView->containsScrollableArea(this);
-
- return false;
+ if (box().hasCompositedLayerMapping())
+ box().compositedLayerMapping()->positionOverflowControlsLayers(offsetFromRoot);
}
void RenderLayerScrollableArea::updateScrollCornerStyle()
{
- RenderObject* actualRenderer = rendererForScrollbar(m_box);
- RefPtr<RenderStyle> corner = m_box->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->style()) : PassRefPtr<RenderStyle>(0);
+ if (!m_scrollCorner && !hasScrollbar())
+ return;
+ if (!m_scrollCorner && hasOverlayScrollbars())
+ return;
+
+ RenderObject* actualRenderer = rendererForScrollbar(box());
+ RefPtr<RenderStyle> corner = box().hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->style()) : PassRefPtr<RenderStyle>(nullptr);
if (corner) {
if (!m_scrollCorner) {
- m_scrollCorner = RenderScrollbarPart::createAnonymous(&m_box->document());
- m_scrollCorner->setParent(m_box);
+ m_scrollCorner = RenderScrollbarPart::createAnonymous(&box().document());
+ m_scrollCorner->setParent(&box());
}
m_scrollCorner->setStyle(corner.release());
} else if (m_scrollCorner) {
@@ -919,7 +991,7 @@ void RenderLayerScrollableArea::updateScrollCornerStyle()
void RenderLayerScrollableArea::paintOverflowControls(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls)
{
// Don't do anything if we have no overflow.
- if (!m_box->hasOverflowClip())
+ if (!box().hasOverflowClip())
return;
IntPoint adjustedPaintOffset = paintOffset;
@@ -947,7 +1019,7 @@ void RenderLayerScrollableArea::paintOverflowControls(GraphicsContext* context,
if (!overflowControlsIntersectRect(localDamgeRect))
return;
- RenderView* renderView = m_box->view();
+ RenderView* renderView = box().view();
RenderLayer* paintingRoot = layer()->enclosingCompositingLayer();
if (!paintingRoot)
@@ -1003,22 +1075,22 @@ void RenderLayerScrollableArea::paintScrollCorner(GraphicsContext* context, cons
bool RenderLayerScrollableArea::hitTestOverflowControls(HitTestResult& result, const IntPoint& localPoint)
{
- if (!hasScrollbar() && !m_box->canResize())
+ if (!hasScrollbar() && !box().canResize())
return false;
IntRect resizeControlRect;
- if (m_box->style()->resize() != RESIZE_NONE) {
- resizeControlRect = resizerCornerRect(m_box->pixelSnappedBorderBoxRect(), ResizerForPointer);
+ if (box().style()->resize() != RESIZE_NONE) {
+ resizeControlRect = resizerCornerRect(box().pixelSnappedBorderBoxRect(), ResizerForPointer);
if (resizeControlRect.contains(localPoint))
return true;
}
int resizeControlSize = max(resizeControlRect.height(), 0);
if (m_vBar && m_vBar->shouldParticipateInHitTesting()) {
- LayoutRect vBarRect(verticalScrollbarStart(0, m_box->width()),
- m_box->borderTop(),
+ LayoutRect vBarRect(verticalScrollbarStart(0, box().width()),
+ box().borderTop(),
m_vBar->width(),
- m_box->height() - (m_box->borderTop() + m_box->borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize));
+ box().height() - (box().borderTop() + box().borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize));
if (vBarRect.contains(localPoint)) {
result.setScrollbar(m_vBar.get());
return true;
@@ -1028,8 +1100,8 @@ bool RenderLayerScrollableArea::hitTestOverflowControls(HitTestResult& result, c
resizeControlSize = max(resizeControlRect.width(), 0);
if (m_hBar && m_hBar->shouldParticipateInHitTesting()) {
LayoutRect hBarRect(horizontalScrollbarStart(0),
- m_box->height() - m_box->borderBottom() - m_hBar->height(),
- m_box->width() - (m_box->borderLeft() + m_box->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
+ box().height() - box().borderBottom() - m_hBar->height(),
+ box().width() - (box().borderLeft() + box().borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
m_hBar->height());
if (hBarRect.contains(localPoint)) {
result.setScrollbar(m_hBar.get());
@@ -1044,9 +1116,9 @@ bool RenderLayerScrollableArea::hitTestOverflowControls(HitTestResult& result, c
IntRect RenderLayerScrollableArea::resizerCornerRect(const IntRect& bounds, ResizerHitTestType resizerHitTestType) const
{
- if (m_box->style()->resize() == RESIZE_NONE)
+ if (box().style()->resize() == RESIZE_NONE)
return IntRect();
- IntRect corner = cornerRect(m_box->style(), horizontalScrollbar(), verticalScrollbar(), bounds);
+ IntRect corner = cornerRect(box().style(), horizontalScrollbar(), verticalScrollbar(), bounds);
if (resizerHitTestType == ResizerForTouch) {
// We make the resizer virtually larger for touch hit testing. With the
@@ -1065,13 +1137,13 @@ IntRect RenderLayerScrollableArea::scrollCornerAndResizerRect() const
{
IntRect scrollCornerAndResizer = scrollCornerRect();
if (scrollCornerAndResizer.isEmpty())
- scrollCornerAndResizer = resizerCornerRect(m_box->pixelSnappedBorderBoxRect(), ResizerForPointer);
+ scrollCornerAndResizer = resizerCornerRect(box().pixelSnappedBorderBoxRect(), ResizerForPointer);
return scrollCornerAndResizer;
}
bool RenderLayerScrollableArea::overflowControlsIntersectRect(const IntRect& localRect) const
{
- const IntRect borderBox = m_box->pixelSnappedBorderBoxRect();
+ const IntRect borderBox = box().pixelSnappedBorderBoxRect();
if (rectForHorizontalScrollbar(borderBox).intersects(localRect))
return true;
@@ -1090,10 +1162,10 @@ bool RenderLayerScrollableArea::overflowControlsIntersectRect(const IntRect& loc
void RenderLayerScrollableArea::paintResizer(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
{
- if (m_box->style()->resize() == RESIZE_NONE)
+ if (box().style()->resize() == RESIZE_NONE)
return;
- IntRect absRect = resizerCornerRect(m_box->pixelSnappedBorderBoxRect(), ResizerForPointer);
+ IntRect absRect = resizerCornerRect(box().pixelSnappedBorderBoxRect(), ResizerForPointer);
absRect.moveBy(paintOffset);
if (!absRect.intersects(damageRect))
return;
@@ -1126,17 +1198,17 @@ void RenderLayerScrollableArea::paintResizer(GraphicsContext* context, const Int
bool RenderLayerScrollableArea::isPointInResizeControl(const IntPoint& absolutePoint, ResizerHitTestType resizerHitTestType) const
{
- if (!m_box->canResize())
+ if (!box().canResize())
return false;
- IntPoint localPoint = roundedIntPoint(m_box->absoluteToLocal(absolutePoint, UseTransforms));
- IntRect localBounds(0, 0, m_box->pixelSnappedWidth(), m_box->pixelSnappedHeight());
+ IntPoint localPoint = roundedIntPoint(box().absoluteToLocal(absolutePoint, UseTransforms));
+ IntRect localBounds(0, 0, box().pixelSnappedWidth(), box().pixelSnappedHeight());
return resizerCornerRect(localBounds, resizerHitTestType).contains(localPoint);
}
bool RenderLayerScrollableArea::hitTestResizerInFragments(const LayerFragments& layerFragments, const HitTestLocation& hitTestLocation) const
{
- if (!m_box->canResize())
+ if (!box().canResize())
return false;
if (layerFragments.isEmpty())
@@ -1153,26 +1225,29 @@ bool RenderLayerScrollableArea::hitTestResizerInFragments(const LayerFragments&
void RenderLayerScrollableArea::updateResizerAreaSet()
{
- Frame* frame = m_box->frame();
+ LocalFrame* frame = box().frame();
if (!frame)
return;
FrameView* frameView = frame->view();
if (!frameView)
return;
- if (m_box->canResize())
- frameView->addResizerArea(m_box);
+ if (box().canResize())
+ frameView->addResizerArea(box());
else
- frameView->removeResizerArea(m_box);
+ frameView->removeResizerArea(box());
}
void RenderLayerScrollableArea::updateResizerStyle()
{
- RenderObject* actualRenderer = rendererForScrollbar(m_box);
- RefPtr<RenderStyle> resizer = m_box->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(RESIZER), actualRenderer->style()) : PassRefPtr<RenderStyle>(0);
+ if (!m_resizer && !box().canResize())
+ return;
+
+ RenderObject* actualRenderer = rendererForScrollbar(box());
+ RefPtr<RenderStyle> resizer = box().hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(RESIZER), actualRenderer->style()) : PassRefPtr<RenderStyle>(nullptr);
if (resizer) {
if (!m_resizer) {
- m_resizer = RenderScrollbarPart::createAnonymous(&m_box->document());
- m_resizer->setParent(m_box);
+ m_resizer = RenderScrollbarPart::createAnonymous(&box().document());
+ m_resizer->setParent(&box());
}
m_resizer->setStyle(resizer.release());
} else if (m_resizer) {
@@ -1183,7 +1258,7 @@ void RenderLayerScrollableArea::updateResizerStyle()
void RenderLayerScrollableArea::drawPlatformResizerImage(GraphicsContext* context, IntRect resizerCornerRect)
{
- float deviceScaleFactor = WebCore::deviceScaleFactor(m_box->frame());
+ float deviceScaleFactor = WebCore::deviceScaleFactor(box().frame());
RefPtr<Image> resizeCornerImage;
IntSize cornerResizerSize;
@@ -1198,10 +1273,10 @@ void RenderLayerScrollableArea::drawPlatformResizerImage(GraphicsContext* contex
cornerResizerSize = resizeCornerImage->size();
}
- if (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
+ if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
context->save();
context->translate(resizerCornerRect.x() + cornerResizerSize.width(), resizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height());
- context->scale(FloatSize(-1.0, 1.0));
+ context->scale(-1.0, 1.0);
context->drawImage(resizeCornerImage.get(), IntRect(IntPoint(), cornerResizerSize));
context->restore();
return;
@@ -1215,21 +1290,21 @@ IntSize RenderLayerScrollableArea::offsetFromResizeCorner(const IntPoint& absolu
// Currently the resize corner is either the bottom right corner or the bottom left corner.
// FIXME: This assumes the location is 0, 0. Is this guaranteed to always be the case?
IntSize elementSize = layer()->size();
- if (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+ if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
elementSize.setWidth(0);
IntPoint resizerPoint = IntPoint(elementSize);
- IntPoint localPoint = roundedIntPoint(m_box->absoluteToLocal(absolutePoint, UseTransforms));
+ IntPoint localPoint = roundedIntPoint(box().absoluteToLocal(absolutePoint, UseTransforms));
return localPoint - resizerPoint;
}
void RenderLayerScrollableArea::resize(const PlatformEvent& evt, const LayoutSize& oldOffset)
{
// FIXME: This should be possible on generated content but is not right now.
- if (!inResizeMode() || !m_box->canResize() || !m_box->node())
+ if (!inResizeMode() || !box().canResize() || !box().node())
return;
- ASSERT(m_box->node()->isElementNode());
- Element* element = toElement(m_box->node());
+ ASSERT(box().node()->isElementNode());
+ Element* element = toElement(box().node());
Document& document = element->document();
@@ -1253,34 +1328,34 @@ void RenderLayerScrollableArea::resize(const PlatformEvent& evt, const LayoutSiz
ASSERT_NOT_REACHED();
}
- float zoomFactor = m_box->style()->effectiveZoom();
+ float zoomFactor = box().style()->effectiveZoom();
LayoutSize newOffset = offsetFromResizeCorner(document.view()->windowToContents(pos));
newOffset.setWidth(newOffset.width() / zoomFactor);
newOffset.setHeight(newOffset.height() / zoomFactor);
- LayoutSize currentSize = LayoutSize(m_box->width() / zoomFactor, m_box->height() / zoomFactor);
+ LayoutSize currentSize = LayoutSize(box().width() / zoomFactor, box().height() / zoomFactor);
LayoutSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentSize);
element->setMinimumSizeForResizing(minimumSize);
LayoutSize adjustedOldOffset = LayoutSize(oldOffset.width() / zoomFactor, oldOffset.height() / zoomFactor);
- if (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
+ if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
newOffset.setWidth(-newOffset.width());
adjustedOldOffset.setWidth(-adjustedOldOffset.width());
}
LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
- bool isBoxSizingBorder = m_box->style()->boxSizing() == BORDER_BOX;
+ bool isBoxSizingBorder = box().style()->boxSizing() == BORDER_BOX;
- EResize resize = m_box->style()->resize();
+ EResize resize = box().style()->resize();
if (resize != RESIZE_VERTICAL && difference.width()) {
if (element->isFormControlElement()) {
// Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
- element->setInlineStyleProperty(CSSPropertyMarginLeft, m_box->marginLeft() / zoomFactor, CSSPrimitiveValue::CSS_PX);
- element->setInlineStyleProperty(CSSPropertyMarginRight, m_box->marginRight() / zoomFactor, CSSPrimitiveValue::CSS_PX);
+ element->setInlineStyleProperty(CSSPropertyMarginLeft, box().marginLeft() / zoomFactor, CSSPrimitiveValue::CSS_PX);
+ element->setInlineStyleProperty(CSSPropertyMarginRight, box().marginRight() / zoomFactor, CSSPrimitiveValue::CSS_PX);
}
- LayoutUnit baseWidth = m_box->width() - (isBoxSizingBorder ? LayoutUnit() : m_box->borderAndPaddingWidth());
+ LayoutUnit baseWidth = box().width() - (isBoxSizingBorder ? LayoutUnit() : box().borderAndPaddingWidth());
baseWidth = baseWidth / zoomFactor;
element->setInlineStyleProperty(CSSPropertyWidth, roundToInt(baseWidth + difference.width()), CSSPrimitiveValue::CSS_PX);
}
@@ -1288,10 +1363,10 @@ void RenderLayerScrollableArea::resize(const PlatformEvent& evt, const LayoutSiz
if (resize != RESIZE_HORIZONTAL && difference.height()) {
if (element->isFormControlElement()) {
// Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
- element->setInlineStyleProperty(CSSPropertyMarginTop, m_box->marginTop() / zoomFactor, CSSPrimitiveValue::CSS_PX);
- element->setInlineStyleProperty(CSSPropertyMarginBottom, m_box->marginBottom() / zoomFactor, CSSPrimitiveValue::CSS_PX);
+ element->setInlineStyleProperty(CSSPropertyMarginTop, box().marginTop() / zoomFactor, CSSPrimitiveValue::CSS_PX);
+ element->setInlineStyleProperty(CSSPropertyMarginBottom, box().marginBottom() / zoomFactor, CSSPrimitiveValue::CSS_PX);
}
- LayoutUnit baseHeight = m_box->height() - (isBoxSizingBorder ? LayoutUnit() : m_box->borderAndPaddingHeight());
+ LayoutUnit baseHeight = box().height() - (isBoxSizingBorder ? LayoutUnit() : box().borderAndPaddingHeight());
baseHeight = baseHeight / zoomFactor;
element->setInlineStyleProperty(CSSPropertyHeight, roundToInt(baseHeight + difference.height()), CSSPrimitiveValue::CSS_PX);
}
@@ -1303,8 +1378,8 @@ void RenderLayerScrollableArea::resize(const PlatformEvent& evt, const LayoutSiz
LayoutRect RenderLayerScrollableArea::exposeRect(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
{
- LayoutRect localExposeRect(m_box->absoluteToLocalQuad(FloatQuad(FloatRect(rect)), UseTransforms).boundingBox());
- LayoutRect layerBounds(0, 0, m_box->clientWidth(), m_box->clientHeight());
+ LayoutRect localExposeRect(box().absoluteToLocalQuad(FloatQuad(FloatRect(rect)), UseTransforms).boundingBox());
+ LayoutRect layerBounds(0, 0, box().clientWidth(), box().clientHeight());
LayoutRect r = ScrollAlignment::getRectToExpose(layerBounds, localExposeRect, alignX, alignY);
IntSize clampedScrollOffset = clampScrollOffset(adjustedScrollOffset() + toIntSize(roundedIntRect(r).location()));
@@ -1315,12 +1390,12 @@ LayoutRect RenderLayerScrollableArea::exposeRect(const LayoutRect& rect, const S
scrollToOffset(clampedScrollOffset);
IntSize scrollOffsetDifference = adjustedScrollOffset() - oldScrollOffset;
localExposeRect.move(-scrollOffsetDifference);
- return LayoutRect(m_box->localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
+ return LayoutRect(box().localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
}
void RenderLayerScrollableArea::updateScrollableAreaSet(bool hasOverflow)
{
- Frame* frame = m_box->frame();
+ LocalFrame* frame = box().frame();
if (!frame)
return;
@@ -1328,148 +1403,58 @@ void RenderLayerScrollableArea::updateScrollableAreaSet(bool hasOverflow)
if (!frameView)
return;
- bool isVisibleToHitTest = m_box->visibleToHitTesting();
- if (HTMLFrameOwnerElement* owner = frame->ownerElement())
+ // FIXME: Does this need to be fixed later for OOPI?
+ bool isVisibleToHitTest = box().visibleToHitTesting();
+ if (HTMLFrameOwnerElement* owner = frame->deprecatedLocalOwner())
isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToHitTesting();
- bool requiresScrollableArea = hasOverflow && isVisibleToHitTest;
- bool updatedScrollableAreaSet = false;
- if (requiresScrollableArea) {
- if (frameView->addScrollableArea(this))
- updatedScrollableAreaSet = true;
- } else {
- if (frameView->removeScrollableArea(this))
- updatedScrollableAreaSet = true;
- }
-
- if (updatedScrollableAreaSet) {
- // Count the total number of RenderLayers that are scrollable areas for
- // any period. We only want to record this at most once per RenderLayer.
- if (requiresScrollableArea && !m_isScrollableAreaHasBeenRecorded) {
- blink::Platform::current()->histogramEnumeration("Renderer.CompositedScrolling", RenderLayer::IsScrollableAreaBucket, RenderLayer::CompositedScrollingHistogramMax);
- m_isScrollableAreaHasBeenRecorded = true;
- }
-
- // We always want composited scrolling if compositor driven accelerated
- // scrolling is enabled. Since we will not update needs composited scrolling
- // in this case, we must force our state to update.
- if (layer()->compositorDrivenAcceleratedScrollingEnabled())
- layer()->didUpdateNeedsCompositedScrolling();
- else if (requiresScrollableArea)
- m_box->view()->compositor()->setNeedsUpdateCompositingRequirementsState();
- else
- setNeedsCompositedScrolling(false);
- }
-}
-
-void RenderLayerScrollableArea::updateNeedsCompositedScrolling()
-{
- TRACE_EVENT0("comp-scroll", "RenderLayer::updateNeedsCompositedScrolling");
-
- layer()->stackingNode()->updateDescendantsAreContiguousInStackingOrder();
- layer()->updateDescendantDependentFlags();
-
- ASSERT(scrollsOverflow());
- const bool needsToBeStackingContainer = layer()->acceleratedCompositingForOverflowScrollEnabled()
- && layer()->stackingNode()->descendantsAreContiguousInStackingOrder()
- && !layer()->hasUnclippedDescendant();
+ bool didNeedCompositedScrolling = needsCompositedScrolling();
- const bool needsToBeStackingContainerDidChange = layer()->stackingNode()->setNeedsToBeStackingContainer(needsToBeStackingContainer);
+ bool didScrollOverflow = m_scrollsOverflow;
- const bool needsCompositedScrolling = needsToBeStackingContainer
- || layer()->compositorDrivenAcceleratedScrollingEnabled();
-
- // We gather a boolean value for use with Google UMA histograms to
- // quantify the actual effects of a set of patches attempting to
- // relax composited scrolling requirements, thereby increasing the
- // number of composited overflow divs.
- if (layer()->acceleratedCompositingForOverflowScrollEnabled())
- blink::Platform::current()->histogramEnumeration("Renderer.NeedsCompositedScrolling", needsCompositedScrolling, 2);
+ m_scrollsOverflow = hasOverflow && isVisibleToHitTest;
+ if (didScrollOverflow == scrollsOverflow())
+ return;
- const bool needsCompositedScrollingDidChange = setNeedsCompositedScrolling(needsCompositedScrolling);
+ if (m_scrollsOverflow)
+ frameView->addScrollableArea(this);
+ else
+ frameView->removeScrollableArea(this);
- if (needsToBeStackingContainerDidChange || needsCompositedScrollingDidChange) {
- // Note, the z-order lists may need to be rebuilt, but our code guarantees
- // that we have not affected stacking, so we will not dirty
- // m_descendantsAreContiguousInStackingOrder for either us or our stacking
- // context or container.
+ if (didNeedCompositedScrolling != needsCompositedScrolling())
layer()->didUpdateNeedsCompositedScrolling();
- }
-}
-
-bool RenderLayerScrollableArea::setNeedsCompositedScrolling(bool needsCompositedScrolling)
-{
- if (this->needsCompositedScrolling() == needsCompositedScrolling)
- return false;
-
- // Count the total number of RenderLayers which need composited scrolling at
- // some point. This should be recorded at most once per RenderLayer, so we
- // check m_willUseCompositedScrollingHasBeenRecorded.
- if (layer()->acceleratedCompositingForOverflowScrollEnabled() && !m_willUseCompositedScrollingHasBeenRecorded) {
- blink::Platform::current()->histogramEnumeration("Renderer.CompositedScrolling", RenderLayer::WillUseCompositedScrollingBucket, RenderLayer::CompositedScrollingHistogramMax);
- m_willUseCompositedScrollingHasBeenRecorded = true;
- }
-
- m_needsCompositedScrolling = needsCompositedScrolling;
-
- return true;
-}
-
-void RenderLayerScrollableArea::updateHasVisibleNonLayerContent()
-{
- layer()->updateHasVisibleNonLayerContent();
}
void RenderLayerScrollableArea::updateCompositingLayersAfterScroll()
{
- RenderLayerCompositor* compositor = m_box->view()->compositor();
+ RenderLayerCompositor* compositor = box().view()->compositor();
if (compositor->inCompositingMode()) {
- // FIXME: Our stacking container is guaranteed to contain all of our descendants that may need
- // repositioning, so we should be able to enqueue a partial update compositing layers from there.
- // this feature was overridden for now by deferred compositing updates.
- if (usesCompositedScrolling())
- compositor->updateCompositingLayers(CompositingUpdateOnCompositedScroll);
- else
- compositor->updateCompositingLayers(CompositingUpdateOnScroll);
+ if (usesCompositedScrolling()) {
+ DisableCompositingQueryAsserts disabler;
+ ASSERT(box().hasCompositedLayerMapping());
+ box().compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+ compositor->setNeedsCompositingUpdate(CompositingUpdateAfterGeometryChange);
+ } else {
+ layer()->setNeedsCompositingInputsUpdate();
+ compositor->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
+ }
}
}
bool RenderLayerScrollableArea::usesCompositedScrolling() const
{
// Scroll form controls on the main thread so they exhibit correct touch scroll event bubbling
- if (m_box && (m_box->isIntristicallyScrollable(VerticalScrollbar) || m_box->isIntristicallyScrollable(HorizontalScrollbar)))
+ if (box().isIntristicallyScrollable(VerticalScrollbar) || box().isIntristicallyScrollable(HorizontalScrollbar))
return false;
- return m_box->hasCompositedLayerMapping() && m_box->compositedLayerMapping()->scrollingLayer();
-}
-
-bool RenderLayerScrollableArea::adjustForForceCompositedScrollingMode(bool value) const
-{
- switch (m_forceNeedsCompositedScrolling) {
- case DoNotForceCompositedScrolling:
- return value;
- case CompositedScrollingAlwaysOn:
- return true;
- case CompositedScrollingAlwaysOff:
- return false;
- }
-
- ASSERT_NOT_REACHED();
- return value;
+ // See https://codereview.chromium.org/176633003/ for the tests that fail without this disabler.
+ DisableCompositingQueryAsserts disabler;
+ return box().hasCompositedLayerMapping() && box().compositedLayerMapping()->scrollingLayer();
}
bool RenderLayerScrollableArea::needsCompositedScrolling() const
{
- return adjustForForceCompositedScrollingMode(m_needsCompositedScrolling);
-}
-
-void RenderLayerScrollableArea::setForceNeedsCompositedScrolling(ForceNeedsCompositedScrollingMode mode)
-{
- if (m_forceNeedsCompositedScrolling == mode)
- return;
-
- m_forceNeedsCompositedScrolling = mode;
- layer()->didUpdateNeedsCompositedScrolling();
+ return scrollsOverflow() && box().view()->compositor()->acceleratedCompositingForOverflowScrollEnabled();
}
} // Namespace WebCore