Chromium Code Reviews| Index: third_party/WebKit/Source/core/paint/DeprecatedPaintLayerScrollableArea.h |
| diff --git a/third_party/WebKit/Source/core/paint/DeprecatedPaintLayerScrollableArea.h b/third_party/WebKit/Source/core/paint/DeprecatedPaintLayerScrollableArea.h |
| index cb28579ff697d3220dd7284a72f1124fd6b7083d..afa9ff63e2553bc88a7c2d792648e64dd47c606b 100644 |
| --- a/third_party/WebKit/Source/core/paint/DeprecatedPaintLayerScrollableArea.h |
| +++ b/third_party/WebKit/Source/core/paint/DeprecatedPaintLayerScrollableArea.h |
| @@ -67,6 +67,48 @@ class CORE_EXPORT DeprecatedPaintLayerScrollableArea final : public NoBaseWillBe |
| WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DeprecatedPaintLayerScrollableArea); |
| friend class Internals; |
| +private: |
| + class ScrollbarManager { |
| + // 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(DeprecatedPaintLayerScrollableArea&); |
| + |
| + void dispose(); |
| + |
| + bool canDetachScrollbars() const { return m_canDetachScrollbars; } |
| + void setCanDetachScrollbars(bool); |
|
skobes
2015/09/26 01:57:06
Add a comment here that documents what this api do
szager1
2015/09/26 04:48:31
Done.
|
| + Scrollbar* horizontalScrollbar() const { return m_hBarIsAttached ? m_hBar.get(): nullptr; } |
| + Scrollbar* verticalScrollbar() const { return m_vBarIsAttached ? m_vBar.get() : nullptr; } |
| + bool hasHorizontalScrollbar() const { return horizontalScrollbar(); } |
| + bool hasVerticalScrollbar() const { return verticalScrollbar(); } |
| + |
| + void setHasHorizontalScrollbar(bool hasScrollbar); |
| + void setHasVerticalScrollbar(bool hasScrollbar); |
| + |
| + DECLARE_TRACE(); |
| + |
| + private: |
| + PassRefPtrWillBeRawPtr<Scrollbar> createScrollbar(ScrollbarOrientation); |
| + void destroyScrollbar(ScrollbarOrientation, bool invalidate = false); |
| + |
| + private: |
| + DeprecatedPaintLayerScrollableArea& m_scrollableArea; |
| + RefPtrWillBeMember<Scrollbar> m_hBar; |
| + RefPtrWillBeMember<Scrollbar> m_vBar; |
| + unsigned m_canDetachScrollbars: 1; |
|
skobes
2015/09/26 01:57:06
Is there a reason to prefer unsigned:1 to bool?
szager1
2015/09/26 04:48:31
No reason, just following convention.
szager1
2015/09/26 04:53:26
Actually, after reading some StackOverflow, I retr
|
| + unsigned m_hBarIsAttached: 1; |
| + unsigned m_vBarIsAttached: 1; |
| + }; |
| + |
| public: |
| // FIXME: We should pass in the LayoutBox but this opens a window |
| // for crashers during DeprecatedPaintLayer setup (see crbug.com/368062). |
| @@ -81,8 +123,8 @@ public: |
| bool hasHorizontalScrollbar() const { return horizontalScrollbar(); } |
| bool hasVerticalScrollbar() const { return verticalScrollbar(); } |
| - Scrollbar* horizontalScrollbar() const override { return m_hBar.get(); } |
| - Scrollbar* verticalScrollbar() const override { return m_vBar.get(); } |
| + Scrollbar* horizontalScrollbar() const override { return m_scrollbarManager.horizontalScrollbar(); } |
| + Scrollbar* verticalScrollbar() const override { return m_scrollbarManager.verticalScrollbar(); } |
| HostWindow* hostWindow() const override; |
| @@ -162,7 +204,7 @@ public: |
| bool updateAfterCompositingChange() override; |
| - bool hasScrollbar() const { return m_hBar || m_vBar; } |
| + bool hasScrollbar() const { return hasHorizontalScrollbar() || hasVerticalScrollbar(); } |
| LayoutScrollbarPart* scrollCorner() const { return m_scrollCorner; } |
| @@ -254,9 +296,6 @@ private: |
| LayoutUnit horizontalScrollbarStart(int minX) const; |
| IntSize scrollbarOffset(const Scrollbar*) const; |
| - PassRefPtrWillBeRawPtr<Scrollbar> createScrollbar(ScrollbarOrientation); |
| - void destroyScrollbar(ScrollbarOrientation); |
| - |
| void setHasHorizontalScrollbar(bool hasScrollbar); |
| void setHasVerticalScrollbar(bool hasScrollbar); |
| @@ -289,15 +328,14 @@ private: |
| // The width/height of our scrolled area. |
| LayoutRect m_overflowRect; |
| + // ScrollbarManager holds the Scrollbar instances. |
| + ScrollbarManager m_scrollbarManager; |
| + |
| // This is the (scroll) offset from scrollOrigin(). |
| DoubleSize m_scrollOffset; |
| IntPoint m_cachedOverlayScrollbarOffset; |
| - // For areas with overflow, we have a pair of scrollbars. |
| - RefPtrWillBeMember<Scrollbar> m_hBar; |
| - RefPtrWillBeMember<Scrollbar> m_vBar; |
| - |
| // LayoutObject to hold our custom scroll corner. |
| LayoutScrollbarPart* m_scrollCorner; |