| /* |
| * 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); |
| |
| Scrollbar* CreateScrollbar(ScrollbarOrientation); |
| void DestroyDetachedScrollbars(); |
| void Dispose(); |
| |
| void Trace(blink::Visitor*); |
| |
| private: |
| 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(); |
| } |
| Scrollbar* CreateScrollbar(ScrollbarOrientation orientation) override { |
| return scrollbar_manager_.CreateScrollbar(orientation); |
| } |
| |
| 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; |
| |
| 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 |