blob: 7f4a5e8ae2882346687d95c6794423d41565079c [file] [log] [blame]
/*
* Copyright (C) 2003, 2009, 2012 Apple Inc. All rights reserved.
*
* Portions are Copyright (C) 1998 Netscape Communications Corporation.
*
* Other contributors:
* Robert O'Callahan <roc+@cs.cmu.edu>
* David Baron <dbaron@fas.harvard.edu>
* Christian Biesinger <cbiesinger@web.de>
* Randall Jesup <rjesup@wgate.com>
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Josh Soref <timeless@mac.com>
* Boris Zbarsky <bzbarsky@mit.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
* Alternatively, the contents of this file may be used under the terms
* of either the Mozilla Public License Version 1.1, found at
* http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
* License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
* (the "GPL"), in which case the provisions of the MPL or the GPL are
* applicable instead of those above. If you wish to allow use of your
* version of this file only under the terms of one of those two
* licenses (the MPL or the GPL) and not to allow others to use your
* version of this file under the LGPL, indicate your decision by
* deletingthe provisions above and replace them with the notice and
* other provisions required by the MPL or the GPL, as the case may be.
* If you do not delete the provisions above, a recipient may use your
* version of this file under any of the LGPL, the MPL or the GPL.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_LAYER_SCROLLABLE_AREA_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_LAYER_SCROLLABLE_AREA_H_
#include <memory>
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/scroll_anchor.h"
#include "third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h"
#include "third_party/blink/renderer/core/paint/paint_layer_fragment.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
namespace blink {
enum ResizerHitTestType { kResizerForPointer, kResizerForTouch };
class ComputedStyle;
class HitTestResult;
class LayoutBox;
class LayoutScrollbarPart;
struct PaintInvalidatorContext;
class PaintLayer;
class ScrollingCoordinator;
class StickyPositionScrollingConstraints;
class SubtreeLayoutScope;
struct CORE_EXPORT PaintLayerScrollableAreaRareData {
USING_FAST_MALLOC(PaintLayerScrollableAreaRareData);
public:
PaintLayerScrollableAreaRareData();
StickyConstraintsMap sticky_constraints_map_;
DISALLOW_COPY_AND_ASSIGN(PaintLayerScrollableAreaRareData);
};
// PaintLayerScrollableArea represents the scrollable area of a LayoutBox.
//
// To be scrollable, an element requires ‘overflow’ != visible. Note that this
// doesn’t imply having scrollbars as you can always programmatically scroll
// when ‘overflow’ is hidden (using JavaScript's element.scrollTo or
// scrollLeft).
//
// The size and scroll origin of the scrollable area are based on layout
// dimensions. They are recomputed after layout in updateScrollDimensions.
//
// updateScrollDimensions also determines if scrollbars need to be allocated,
// destroyed or updated as a result of layout. This is based on the value of the
// 'overflow' property. Having non-overlay scrollbars automatically allocates a
// scrollcorner (m_scrollCorner), which is used to style the intersection of the
// two scrollbars.
//
// Note that scrollbars are placed based on the LayoutBox's computed
// 'direction'. See https://webkit.org/b/54623 for some context.
//
// The ‘resize' property allocates a resizer (m_resizer), which is overlaid on
// top of the scroll corner. It is used to resize an element using the mouse.
//
// The scrollbars and scroll corner can also be hardware accelerated
// and thus get their own GraphicsLayer (see the layerFor* functions).
// This only happens if the associated PaintLayer is itself composited.
//
//
// ***** OVERLAY SCROLLBARS *****
// Overlay scrollbars are painted on top of the box's content. As such they
// don't use any space in the box. Software overlay scrollbars are painted by
// PaintLayerPainter::paintOverlayScrollbars after all content as part of a
// separate tree traversal. The reason for this 2nd traversal is that they need
// to be painted on top of everything. Hardware accelerated overlay scrollbars
// are painted by their associated GraphicsLayer that sets the paint flag
// PaintLayerPaintingOverlayScrollbars.
class CORE_EXPORT PaintLayerScrollableArea final
: public GarbageCollectedFinalized<PaintLayerScrollableArea>,
public ScrollableArea {
USING_GARBAGE_COLLECTED_MIXIN(PaintLayerScrollableArea);
friend class Internals;
private:
class ScrollbarManager {
DISALLOW_NEW();
// Helper class to manage the life cycle of Scrollbar objects. Some layout
// containers (e.g., flexbox, table) run multi-pass layout on their
// children, applying different constraints. If a child has overflow:auto,
// it may gain and lose scrollbars multiple times during multi-pass layout,
// causing pointless allocation/deallocation thrashing, and potentially
// leading to other problems (crbug.com/528940).
// ScrollbarManager allows a ScrollableArea to delay the destruction of a
// scrollbar that is no longer needed, until the end of multi-pass layout.
// If the scrollbar is then re-added before multi-pass layout finishes, the
// previously "deleted" scrollbar will be restored, rather than constructing
// a new one.
public:
ScrollbarManager(PaintLayerScrollableArea& scrollable_area)
: scrollable_area_(scrollable_area),
h_bar_is_attached_(0),
v_bar_is_attached_(0) {}
PaintLayerScrollableArea* ScrollableArea() const {
return scrollable_area_.Get();
}
Scrollbar* HorizontalScrollbar() const {
return h_bar_is_attached_ ? h_bar_.Get() : nullptr;
}
Scrollbar* VerticalScrollbar() const {
return v_bar_is_attached_ ? v_bar_.Get() : nullptr;
}
bool HasHorizontalScrollbar() const { return HorizontalScrollbar(); }
bool HasVerticalScrollbar() const { return VerticalScrollbar(); }
void SetHasHorizontalScrollbar(bool has_scrollbar);
void SetHasVerticalScrollbar(bool has_scrollbar);
void DestroyDetachedScrollbars();
void Dispose();
void Trace(blink::Visitor*);
private:
Scrollbar* CreateScrollbar(ScrollbarOrientation);
void DestroyScrollbar(ScrollbarOrientation);
Member<PaintLayerScrollableArea> scrollable_area_;
// The scrollbars associated with scrollable_area_. Both can nullptr.
Member<Scrollbar> h_bar_;
Member<Scrollbar> v_bar_;
unsigned h_bar_is_attached_ : 1;
unsigned v_bar_is_attached_ : 1;
};
public:
// If a PreventRelayoutScope object is alive, updateAfterLayout() will not
// re-run box layout as a result of adding or removing scrollbars.
// Instead, it will mark the PLSA as needing relayout of its box.
// When the last PreventRelayoutScope object is popped off the stack,
// box().setNeedsLayout(), and box().scrollbarsChanged() for LayoutBlock's,
// will be called as appropriate for all marked PLSA's.
class PreventRelayoutScope {
STACK_ALLOCATED();
public:
PreventRelayoutScope(SubtreeLayoutScope&);
~PreventRelayoutScope();
static bool RelayoutIsPrevented() { return count_; }
static void SetBoxNeedsLayout(PaintLayerScrollableArea&,
bool had_horizontal_scrollbar,
bool had_vertical_scrollbar);
static bool RelayoutNeeded() { return count_ == 0 && relayout_needed_; }
static void ResetRelayoutNeeded();
private:
static int count_;
static SubtreeLayoutScope* layout_scope_;
static bool relayout_needed_;
static PersistentHeapVector<Member<PaintLayerScrollableArea>>*
needs_relayout_;
};
// If a FreezeScrollbarScope object is alive, updateAfterLayout() will not
// recompute the existence of overflow:auto scrollbars.
class FreezeScrollbarsScope {
STACK_ALLOCATED();
public:
FreezeScrollbarsScope() { count_++; }
~FreezeScrollbarsScope() { count_--; }
static bool ScrollbarsAreFrozen() { return count_; }
private:
static int count_;
};
// If a DelayScrollOffsetClampScope object is alive, updateAfterLayout() will
// not clamp scroll offsets to ensure they are in the valid range. When the
// last DelayScrollOffsetClampScope object is destructed, all
// PaintLayerScrollableArea's that delayed clamping their offsets will
// immediately clamp them.
class CORE_EXPORT DelayScrollOffsetClampScope {
STACK_ALLOCATED();
public:
DelayScrollOffsetClampScope();
~DelayScrollOffsetClampScope();
static bool ClampingIsDelayed() { return count_; }
static void SetNeedsClamp(PaintLayerScrollableArea*);
private:
static void ClampScrollableAreas();
static int count_;
static PersistentHeapVector<Member<PaintLayerScrollableArea>>* needs_clamp_;
};
// FIXME: We should pass in the LayoutBox but this opens a window
// for crashers during PaintLayer setup (see crbug.com/368062).
static PaintLayerScrollableArea* Create(PaintLayer& layer) {
return new PaintLayerScrollableArea(layer);
}
~PaintLayerScrollableArea() override;
void Dispose();
bool HasBeenDisposed() const override;
void ForceVerticalScrollbarForFirstLayout() { SetHasVerticalScrollbar(true); }
bool HasHorizontalScrollbar() const { return HorizontalScrollbar(); }
bool HasVerticalScrollbar() const { return VerticalScrollbar(); }
Scrollbar* HorizontalScrollbar() const override {
return scrollbar_manager_.HorizontalScrollbar();
}
Scrollbar* VerticalScrollbar() const override {
return scrollbar_manager_.VerticalScrollbar();
}
void CalculateScrollbarModes(ScrollbarMode& h_mode,
ScrollbarMode& v_mode) const;
PlatformChromeClient* GetChromeClient() const override;
SmoothScrollSequencer* GetSmoothScrollSequencer() const override;
// For composited scrolling, we allocate an extra GraphicsLayer to hold
// onto the scrolling content. The layer can be shifted on the GPU and
// composited at little cost.
// Note that this is done in CompositedLayerMapping, this function being
// only a helper.
GraphicsLayer* LayerForScrolling() const override;
void DidScroll(const gfx::ScrollOffset&) override;
// GraphicsLayers for the scrolling components.
//
// Any function can return nullptr if they are not accelerated.
GraphicsLayer* LayerForHorizontalScrollbar() const override;
GraphicsLayer* LayerForVerticalScrollbar() const override;
GraphicsLayer* LayerForScrollCorner() const override;
bool ShouldScrollOnMainThread() const override;
bool ShouldUseIntegerScrollOffset() const override;
bool IsActive() const override;
bool IsScrollCornerVisible() const override;
IntRect ScrollCornerRect() const override;
IntRect ConvertFromScrollbarToContainingEmbeddedContentView(
const Scrollbar&,
const IntRect&) const override;
IntPoint ConvertFromScrollbarToContainingEmbeddedContentView(
const Scrollbar&,
const IntPoint&) const override;
IntPoint ConvertFromContainingEmbeddedContentViewToScrollbar(
const Scrollbar&,
const IntPoint&) const override;
IntPoint ConvertFromRootFrame(const IntPoint&) const override;
int ScrollSize(ScrollbarOrientation) const override;
IntSize ScrollOffsetInt() const override;
ScrollOffset GetScrollOffset() const override;
IntSize MinimumScrollOffsetInt() const override;
IntSize MaximumScrollOffsetInt() const override;
IntRect VisibleContentRect(
IncludeScrollbarsInRect = kExcludeScrollbars) const override;
LayoutRect VisibleScrollSnapportRect(
IncludeScrollbarsInRect = kExcludeScrollbars) const override;
IntSize ContentsSize() const override;
void ContentsResized() override;
bool IsScrollable() const override;
IntPoint LastKnownMousePosition() const override;
bool ScrollAnimatorEnabled() const override;
bool ShouldSuspendScrollAnimations() const override;
bool ScrollbarsCanBeActive() const override;
void ScrollbarVisibilityChanged() override;
void ScrollbarFrameRectChanged() override;
IntRect ScrollableAreaBoundingBox() const override;
void RegisterForAnimation() override;
void DeregisterForAnimation() override;
bool UserInputScrollable(ScrollbarOrientation) const override;
bool ShouldPlaceVerticalScrollbarOnLeft() const override;
int PageStep(ScrollbarOrientation) const override;
ScrollBehavior ScrollBehaviorStyle() const override;
CompositorAnimationHost* GetCompositorAnimationHost() const override;
CompositorAnimationTimeline* GetCompositorAnimationTimeline() const override;
void GetTickmarks(Vector<IntRect>&) const override;
void VisibleSizeChanged();
// FIXME: We shouldn't allow access to m_overflowRect outside this class.
LayoutRect OverflowRect() const { return overflow_rect_; }
void ScrollToAbsolutePosition(
const FloatPoint& position,
ScrollBehavior scroll_behavior = kScrollBehaviorInstant,
ScrollType scroll_type = kProgrammaticScroll) {
SetScrollOffset(position - ScrollOrigin(), scroll_type, scroll_behavior);
}
// This will set the scroll position without clamping, and it will do all
// post-update work even if the scroll position didn't change.
void SetScrollOffsetUnconditionally(const ScrollOffset&,
ScrollType = kProgrammaticScroll);
// This will set the scroll position without clamping, and it will do all
// post-update work even if the scroll position didn't change.
void SetScrollPositionUnconditionally(const DoublePoint&,
ScrollType = kProgrammaticScroll);
// TODO(szager): Actually run these after all of layout is finished.
// Currently, they run at the end of box()'es layout (or after all flexbox
// layout has finished) but while document layout is still happening.
void UpdateAfterLayout();
void ClampScrollOffsetAfterOverflowChange();
void DidChangeGlobalRootScroller() override;
void UpdateAfterStyleChange(const ComputedStyle*);
void UpdateAfterOverflowRecalc();
void UpdateAfterCompositingChange() override;
bool HasScrollbar() const {
return HasHorizontalScrollbar() || HasVerticalScrollbar();
}
bool HasOverflowControls() const {
return HasScrollbar() || ScrollCorner() || Resizer();
}
LayoutScrollbarPart* ScrollCorner() const { return scroll_corner_; }
void Resize(const IntPoint& pos, const LayoutSize& old_offset);
IntSize OffsetFromResizeCorner(const IntPoint& absolute_point) const;
bool InResizeMode() const { return in_resize_mode_; }
void SetInResizeMode(bool in_resize_mode) {
in_resize_mode_ = in_resize_mode;
}
LayoutUnit ScrollWidth() const;
LayoutUnit ScrollHeight() const;
int PixelSnappedScrollWidth() const;
int PixelSnappedScrollHeight() const;
int VerticalScrollbarWidth(
OverlayScrollbarClipBehavior =
kIgnorePlatformOverlayScrollbarSize) const override;
int HorizontalScrollbarHeight(
OverlayScrollbarClipBehavior =
kIgnorePlatformOverlayScrollbarSize) const override;
DoubleSize AdjustedScrollOffset() const {
return ToDoubleSize(DoublePoint(ScrollOrigin()) + scroll_offset_);
}
void PositionOverflowControls();
// isPointInResizeControl() is used for testing if a pointer/touch position is
// in the resize control area.
bool IsPointInResizeControl(const IntPoint& absolute_point,
ResizerHitTestType) const;
bool HitTestOverflowControls(HitTestResult&, const IntPoint& local_point);
bool HitTestResizerInFragments(const PaintLayerFragments&,
const HitTestLocation&) const;
// Returns the new offset, after scrolling, of the given rect in absolute
// coordinates, clipped by the parent's client rect.
LayoutRect ScrollIntoView(const LayoutRect&,
const WebScrollIntoViewParams&) override;
// Returns true if scrollable area is in the FrameView's collection of
// scrollable areas. This can only happen if we're scrollable, visible to hit
// test, and do in fact overflow. This means that 'overflow: hidden' or
// 'pointer-events: none' layers never get added to the FrameView's
// collection.
bool ScrollsOverflow() const { return scrolls_overflow_; }
// Rectangle encompassing the scroll corner and resizer rect.
IntRect ScrollCornerAndResizerRect() const;
void UpdateNeedsCompositedScrolling(bool layer_has_been_composited = false);
bool NeedsCompositedScrolling() const { return needs_composited_scrolling_; }
// Sets whether there is a PaintLayer whose ScrollParent() is the
// owner of this PaintLayerScrollableArea.
void SetHasPaintLayerScrollChild(bool val) {
has_paint_layer_scroll_child_ = val;
}
bool HasPaintLayerScrollChild() const {
return has_paint_layer_scroll_child_;
}
IntRect ResizerCornerRect(const IntRect&, ResizerHitTestType) const;
PaintLayer* Layer() const override;
LayoutScrollbarPart* Resizer() const { return resizer_; }
const IntPoint& CachedOverlayScrollbarOffset() {
return cached_overlay_scrollbar_offset_;
}
void SetCachedOverlayScrollbarOffset(const IntPoint& offset) {
cached_overlay_scrollbar_offset_ = offset;
}
IntRect RectForHorizontalScrollbar(const IntRect& border_box_rect) const;
IntRect RectForVerticalScrollbar(const IntRect& border_box_rect) const;
bool ScheduleAnimation() override;
bool ShouldPerformScrollAnchoring() const override;
bool RestoreScrollAnchor(const SerializedAnchor&) override;
ScrollAnchor* GetScrollAnchor() override { return &scroll_anchor_; }
bool IsPaintLayerScrollableArea() const override { return true; }
LayoutBox* GetLayoutBox() const override;
FloatQuad LocalToVisibleContentQuad(const FloatQuad&,
const LayoutObject*,
unsigned = 0) const final;
scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final;
bool ShouldRebuildHorizontalScrollbarLayer() const {
return rebuild_horizontal_scrollbar_layer_;
}
bool ShouldRebuildVerticalScrollbarLayer() const {
return rebuild_vertical_scrollbar_layer_;
}
void ResetRebuildScrollbarLayerFlags();
// Did DelayScrollOffsetClampScope prevent us from running
// clampScrollOffsetsAfterLayout() in updateAfterLayout()?
bool NeedsScrollOffsetClamp() const { return needs_scroll_offset_clamp_; }
void SetNeedsScrollOffsetClamp(bool val) { needs_scroll_offset_clamp_ = val; }
// Did PreventRelayoutScope prevent us from running re-layout due to
// adding/subtracting scrollbars in updateAfterLayout()?
bool NeedsRelayout() const { return needs_relayout_; }
void SetNeedsRelayout(bool val) { needs_relayout_ = val; }
// Were we laid out with a horizontal scrollbar at the time we were marked as
// needing relayout by PreventRelayoutScope?
bool HadHorizontalScrollbarBeforeRelayout() const {
return had_horizontal_scrollbar_before_relayout_;
}
void SetHadHorizontalScrollbarBeforeRelayout(bool val) {
had_horizontal_scrollbar_before_relayout_ = val;
}
// Were we laid out with a vertical scrollbar at the time we were marked as
// needing relayout by PreventRelayoutScope?
bool HadVerticalScrollbarBeforeRelayout() const {
return had_vertical_scrollbar_before_relayout_;
}
void SetHadVerticalScrollbarBeforeRelayout(bool val) {
had_vertical_scrollbar_before_relayout_ = val;
}
StickyConstraintsMap& GetStickyConstraintsMap() {
return EnsureRareData().sticky_constraints_map_;
}
void InvalidateAllStickyConstraints();
void InvalidateStickyConstraintsFor(PaintLayer*,
bool needs_compositing_update = true);
void InvalidatePaintForStickyDescendants();
bool HasStickyDescendants() const;
bool HasNonCompositedStickyDescendants() const;
uint32_t GetNonCompositedMainThreadScrollingReasons() {
return non_composited_main_thread_scrolling_reasons_;
}
uint64_t Id() const;
ScrollbarTheme& GetPageScrollbarTheme() const override;
// Return the thickness of the existing scrollbar; or, if there is no
// existing scrollbar, then calculate the thickness it would have if it
// existed. Returns zero if the (real or hypothetical) scrollbar is an overlay
// scrollbar.
int HypotheticalScrollbarThickness(ScrollbarOrientation) const;
void WillRemoveScrollbar(Scrollbar&, ScrollbarOrientation) override;
void InvalidatePaintOfScrollControlsIfNeeded(const PaintInvalidatorContext&);
// Should be called when the previous visual rects are no longer valid.
void ClearPreviousVisualRects();
void DidScrollWithScrollbar(ScrollbarPart, ScrollbarOrientation) override;
CompositorElementId GetCompositorElementId() const override;
void Trace(blink::Visitor*) override;
private:
explicit PaintLayerScrollableArea(PaintLayer&);
bool HasHorizontalOverflow() const;
bool HasVerticalOverflow() const;
bool VisualViewportSuppliesScrollbars() const;
bool NeedsScrollbarReconstruction() const;
void UpdateScrollOrigin();
void UpdateScrollDimensions();
void UpdateScrollbarEnabledState();
// Update the proportions used for thumb rect dimensions.
void UpdateScrollbarProportions();
void UpdateScrollOffset(const ScrollOffset&, ScrollType) override;
void InvalidatePaintForScrollOffsetChange(bool offset_was_zero);
int VerticalScrollbarStart(int min_x, int max_x) const;
int HorizontalScrollbarStart(int min_x) const;
IntSize ScrollbarOffset(const Scrollbar&) const;
enum ComputeScrollbarExistenceOption { kDefault, kForbidAddingAutoBars };
void ComputeScrollbarExistence(
bool& needs_horizontal_scrollbar,
bool& needs_vertical_scrollbar,
ComputeScrollbarExistenceOption = kDefault) const;
// If the content fits entirely in the area without auto scrollbars, returns
// true to try to remove them. This is a heuristic and can be incorrect if the
// content size depends on the scrollbar size (e.g., percentage sizing).
bool TryRemovingAutoScrollbars(const bool& needs_horizontal_scrollbar,
const bool& needs_vertical_scrollbar);
// Returns true iff scrollbar existence changed.
bool SetHasHorizontalScrollbar(bool has_scrollbar);
bool SetHasVerticalScrollbar(bool has_scrollbar);
void SnapAfterScrollbarDragging(ScrollbarOrientation) override;
void UpdateScrollCornerStyle();
LayoutSize MinimumSizeForResizing(float zoom_factor);
LayoutRect LayoutContentRect(IncludeScrollbarsInRect) const;
// See comments on isPointInResizeControl.
void UpdateResizerAreaSet();
void UpdateResizerStyle(const ComputedStyle* old_style);
void UpdateScrollableAreaSet();
void UpdateCompositingLayersAfterScroll();
ScrollingCoordinator* GetScrollingCoordinator() const;
PaintLayerScrollableAreaRareData* RareData() { return rare_data_.get(); }
const PaintLayerScrollableAreaRareData* RareData() const {
return rare_data_.get();
}
PaintLayerScrollableAreaRareData& EnsureRareData() {
if (!rare_data_)
rare_data_ = std::make_unique<PaintLayerScrollableAreaRareData>();
return *rare_data_.get();
}
bool ComputeNeedsCompositedScrolling(const bool, const PaintLayer*);
IntRect CornerRect(const IntRect& bounds) const;
void ScrollControlWasSetNeedsPaintInvalidation() override;
void SetHorizontalScrollbarVisualRect(const LayoutRect&);
void SetVerticalScrollbarVisualRect(const LayoutRect&);
void SetScrollCornerAndResizerVisualRect(const LayoutRect&);
// PaintLayer is destructed before PaintLayerScrollable area, during this
// time before PaintLayerScrollableArea has been collected layer_ will
// be set to nullptr by the Dispose method.
PaintLayer* layer_;
// Keeps track of whether the layer is currently resizing, so events can cause
// resizing to start and stop.
unsigned in_resize_mode_ : 1;
unsigned scrolls_overflow_ : 1;
// True if we are in an overflow scrollbar relayout.
unsigned in_overflow_relayout_ : 1;
// True if a second overflow scrollbar relayout is permitted.
unsigned allow_second_overflow_relayout_ : 1;
// FIXME: once cc can handle composited scrolling with clip paths, we will
// no longer need this bit.
unsigned needs_composited_scrolling_ : 1;
// Set to indicate that a scrollbar layer, if present, needs to be rebuilt
// in the next compositing update because the underlying blink::Scrollbar
// instance has been reconstructed.
unsigned rebuild_horizontal_scrollbar_layer_ : 1;
unsigned rebuild_vertical_scrollbar_layer_ : 1;
unsigned needs_scroll_offset_clamp_ : 1;
unsigned needs_relayout_ : 1;
unsigned had_horizontal_scrollbar_before_relayout_ : 1;
unsigned had_vertical_scrollbar_before_relayout_ : 1;
unsigned has_paint_layer_scroll_child_ : 1;
// The width/height of our scrolled area.
// This is OverflowModel's layout overflow translated to physical
// coordinates. See OverflowModel for the different overflow and
// LayoutBoxModelObject for the coordinate systems.
LayoutRect overflow_rect_;
// ScrollbarManager holds the Scrollbar instances.
ScrollbarManager scrollbar_manager_;
// This is the offset from the beginning of content flow.
ScrollOffset scroll_offset_;
IntPoint cached_overlay_scrollbar_offset_;
// LayoutObject to hold our custom scroll corner.
LayoutScrollbarPart* scroll_corner_;
// LayoutObject to hold our custom resizer.
LayoutScrollbarPart* resizer_;
ScrollAnchor scroll_anchor_;
std::unique_ptr<PaintLayerScrollableAreaRareData> rare_data_;
// MainThreadScrollingReason due to the properties of the LayoutObject
uint32_t non_composited_main_thread_scrolling_reasons_;
bool horizontal_scrollbar_previously_was_overlay_;
bool vertical_scrollbar_previously_was_overlay_;
LayoutRect horizontal_scrollbar_visual_rect_;
LayoutRect vertical_scrollbar_visual_rect_;
LayoutRect scroll_corner_and_resizer_visual_rect_;
};
DEFINE_TYPE_CASTS(PaintLayerScrollableArea,
ScrollableArea,
scrollableArea,
scrollableArea->IsPaintLayerScrollableArea(),
scrollableArea.IsPaintLayerScrollableArea());
} // namespace blink
#endif // LayerScrollableArea_h