| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. |
| 3 * | 3 * |
| 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
| 5 * | 5 * |
| 6 * Other contributors: | 6 * Other contributors: |
| 7 * Robert O'Callahan <roc+@cs.cmu.edu> | 7 * Robert O'Callahan <roc+@cs.cmu.edu> |
| 8 * David Baron <dbaron@fas.harvard.edu> | 8 * David Baron <dbaron@fas.harvard.edu> |
| 9 * Christian Biesinger <cbiesinger@gmail.com> | 9 * Christian Biesinger <cbiesinger@gmail.com> |
| 10 * Randall Jesup <rjesup@wgate.com> | 10 * Randall Jesup <rjesup@wgate.com> |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 int PaintLayerScrollableArea::pixelSnappedScrollWidth() const | 583 int PaintLayerScrollableArea::pixelSnappedScrollWidth() const |
| 584 { | 584 { |
| 585 return snapSizeToPixel(scrollWidth(), box().clientLeft() + box().location().
x()); | 585 return snapSizeToPixel(scrollWidth(), box().clientLeft() + box().location().
x()); |
| 586 } | 586 } |
| 587 | 587 |
| 588 int PaintLayerScrollableArea::pixelSnappedScrollHeight() const | 588 int PaintLayerScrollableArea::pixelSnappedScrollHeight() const |
| 589 { | 589 { |
| 590 return snapSizeToPixel(scrollHeight(), box().clientTop() + box().location().
y()); | 590 return snapSizeToPixel(scrollHeight(), box().clientTop() + box().location().
y()); |
| 591 } | 591 } |
| 592 | 592 |
| 593 void PaintLayerScrollableArea::computeScrollDimensions() | 593 void PaintLayerScrollableArea::updateScrollOrigin() |
| 594 { | 594 { |
| 595 m_overflowRect = box().layoutOverflowRect(); | 595 // This should do nothing prior to first layout; the if-clause will catch th
at. |
| 596 box().flipForWritingMode(m_overflowRect); | 596 if (overflowRect().isEmpty()) |
| 597 | 597 return; |
| 598 LayoutPoint scrollableOverflow = m_overflowRect.location() - LayoutSize(box(
).borderLeft(), box().borderTop()); | 598 LayoutPoint scrollableOverflow = m_overflowRect.location() - LayoutSize(box(
).borderLeft(), box().borderTop()); |
| 599 setScrollOrigin(flooredIntPoint(-scrollableOverflow) + box().originAdjustmen
tForScrollbars()); | 599 setScrollOrigin(flooredIntPoint(-scrollableOverflow) + box().originAdjustmen
tForScrollbars()); |
| 600 } | 600 } |
| 601 | 601 |
| 602 void PaintLayerScrollableArea::updateScrollDimensions() |
| 603 { |
| 604 m_overflowRect = box().layoutOverflowRect(); |
| 605 box().flipForWritingMode(m_overflowRect); |
| 606 updateScrollOrigin(); |
| 607 } |
| 608 |
| 602 void PaintLayerScrollableArea::scrollToPosition(const DoublePoint& scrollPositio
n, ScrollOffsetClamping clamp, ScrollBehavior scrollBehavior, ScrollType scrollT
ype) | 609 void PaintLayerScrollableArea::scrollToPosition(const DoublePoint& scrollPositio
n, ScrollOffsetClamping clamp, ScrollBehavior scrollBehavior, ScrollType scrollT
ype) |
| 603 { | 610 { |
| 604 cancelProgrammaticScrollAnimation(); | |
| 605 | |
| 606 DoublePoint newScrollPosition = clamp == ScrollOffsetClamped ? clampScrollPo
sition(scrollPosition) : scrollPosition; | 611 DoublePoint newScrollPosition = clamp == ScrollOffsetClamped ? clampScrollPo
sition(scrollPosition) : scrollPosition; |
| 607 if (newScrollPosition != scrollPositionDouble()) | 612 if (newScrollPosition != scrollPositionDouble()) |
| 608 ScrollableArea::setScrollPosition(newScrollPosition, scrollType, scrollB
ehavior); | 613 ScrollableArea::setScrollPosition(newScrollPosition, scrollType, scrollB
ehavior); |
| 609 } | 614 } |
| 610 | 615 |
| 611 bool PaintLayerScrollableArea::updateAfterLayout(SubtreeLayoutScope* delayedLayo
utScope) | 616 void PaintLayerScrollableArea::updateAfterLayout() |
| 612 { | 617 { |
| 613 ASSERT(box().hasOverflowClip()); | 618 ASSERT(box().hasOverflowClip()); |
| 614 | 619 |
| 615 bool didMarkForDelayedLayout = false; | 620 bool relayoutIsPrevented = PreventRelayoutScope::relayoutIsPrevented(); |
| 621 bool scrollbarsAreFrozen = m_inOverflowRelayout || FreezeScrollbarsScope::sc
rollbarsAreFrozen(); |
| 616 | 622 |
| 617 if (needsScrollbarReconstruction()) { | 623 if (needsScrollbarReconstruction()) { |
| 618 m_scrollbarManager.setCanDetachScrollbars(false); | |
| 619 setHasHorizontalScrollbar(false); | 624 setHasHorizontalScrollbar(false); |
| 620 setHasVerticalScrollbar(false); | 625 setHasVerticalScrollbar(false); |
| 621 } | 626 } |
| 622 | 627 |
| 623 m_scrollbarManager.setCanDetachScrollbars(true); | 628 updateScrollDimensions(); |
| 624 | |
| 625 IntPoint originalOrigin = scrollOrigin(); | |
| 626 computeScrollDimensions(); | |
| 627 | |
| 628 // Layout may cause us to be at an invalid scroll position. In this case we
need | |
| 629 // to pull our scroll offsets back to the max (or push them up to the min). | |
| 630 DoublePoint clampedScrollPosition = clampScrollPosition(scrollPositionDouble
()); | |
| 631 if (clampedScrollPosition != scrollPositionDouble()) { | |
| 632 scrollToPosition(clampedScrollPosition); | |
| 633 } else if (originalOrigin != scrollOrigin()) { | |
| 634 // TODO: We should be able to use scrollOriginChanged() here, but we can
't because | |
| 635 // PaintLayerScrollableArea does not maintain that flag: it gets set, bu
t it never | |
| 636 // gets unset. We should unset the flag after layout. | |
| 637 scrollPositionChanged(scrollPositionDouble(), ProgrammaticScroll); | |
| 638 } | |
| 639 | |
| 640 m_scrollbarManager.setCanDetachScrollbars(false); | |
| 641 | 629 |
| 642 bool hasHorizontalOverflow = this->hasHorizontalOverflow(); | 630 bool hasHorizontalOverflow = this->hasHorizontalOverflow(); |
| 643 bool hasVerticalOverflow = this->hasVerticalOverflow(); | 631 bool hasVerticalOverflow = this->hasVerticalOverflow(); |
| 644 | 632 |
| 645 // Don't add auto scrollbars if the box contents aren't visible. | 633 // Don't add auto scrollbars if the box contents aren't visible. |
| 646 bool shouldHaveAutoHorizontalScrollbar = hasHorizontalOverflow && box().pixe
lSnappedClientHeight(); | 634 bool shouldHaveAutoHorizontalScrollbar = hasHorizontalOverflow && box().pixe
lSnappedClientHeight(); |
| 647 bool shouldHaveAutoVerticalScrollbar = hasVerticalOverflow && box().pixelSna
ppedClientWidth(); | 635 bool shouldHaveAutoVerticalScrollbar = hasVerticalOverflow && box().pixelSna
ppedClientWidth(); |
| 648 | 636 |
| 649 { | 637 { |
| 650 // Hits in compositing/overflow/automatically-opt-into-composited-scroll
ing-after-style-change.html. | 638 // Hits in compositing/overflow/automatically-opt-into-composited-scroll
ing-after-style-change.html. |
| 651 DisableCompositingQueryAsserts disabler; | 639 DisableCompositingQueryAsserts disabler; |
| 652 | 640 |
| 653 // overflow:scroll should just enable/disable. | 641 // overflow:scroll should just enable/disable. |
| 654 if (box().style()->overflowX() == OverflowScroll && horizontalScrollbar(
)) | 642 if (box().style()->overflowX() == OverflowScroll && horizontalScrollbar(
)) |
| 655 horizontalScrollbar()->setEnabled(hasHorizontalOverflow); | 643 horizontalScrollbar()->setEnabled(hasHorizontalOverflow); |
| 656 if (box().style()->overflowY() == OverflowScroll && verticalScrollbar()) | 644 if (box().style()->overflowY() == OverflowScroll && verticalScrollbar()) |
| 657 verticalScrollbar()->setEnabled(hasVerticalOverflow); | 645 verticalScrollbar()->setEnabled(hasVerticalOverflow); |
| 658 } | 646 } |
| 659 | 647 |
| 660 // We need to layout again if scrollbars are added or removed by overflow:au
to, | 648 // We need to layout again if scrollbars are added or removed by overflow:au
to, |
| 661 // or by changing between native and custom. | 649 // or by changing between native and custom. |
| 662 bool horizontalScrollBarChanged = (box().hasAutoHorizontalScrollbar() && (ha
sHorizontalScrollbar() != shouldHaveAutoHorizontalScrollbar)) | 650 bool horizontalScrollbarShouldChange = (box().hasAutoHorizontalScrollbar() &
& (hasHorizontalScrollbar() != shouldHaveAutoHorizontalScrollbar)) |
| 663 || (box().style()->overflowX() == OverflowScroll && !horizontalScrollbar
()); | 651 || (box().style()->overflowX() == OverflowScroll && !horizontalScrollbar
()); |
| 664 bool verticalScrollBarChanged = (box().hasAutoVerticalScrollbar() && (hasVer
ticalScrollbar() != shouldHaveAutoVerticalScrollbar)) | 652 bool verticalScrollbarShouldChange = (box().hasAutoVerticalScrollbar() && (h
asVerticalScrollbar() != shouldHaveAutoVerticalScrollbar)) |
| 665 || (box().style()->overflowY() == OverflowScroll && !verticalScrollbar()
); | 653 || (box().style()->overflowY() == OverflowScroll && !verticalScrollbar()
); |
| 666 if (!m_inOverflowRelayout | 654 bool scrollbarsWillChange = !scrollbarsAreFrozen && !visualViewportSuppliesS
crollbars() |
| 667 && !visualViewportSuppliesScrollbars() | 655 && (horizontalScrollbarShouldChange || verticalScrollbarShouldChange); |
| 668 && (horizontalScrollBarChanged || verticalScrollBarChanged)) { | 656 |
| 657 if (scrollbarsWillChange) { |
| 669 if (box().hasAutoHorizontalScrollbar()) | 658 if (box().hasAutoHorizontalScrollbar()) |
| 670 setHasHorizontalScrollbar(shouldHaveAutoHorizontalScrollbar); | 659 setHasHorizontalScrollbar(shouldHaveAutoHorizontalScrollbar); |
| 671 else if (box().style()->overflowX() == OverflowScroll) | 660 else if (box().style()->overflowX() == OverflowScroll) |
| 672 setHasHorizontalScrollbar(true); | 661 setHasHorizontalScrollbar(true); |
| 673 if (box().hasAutoVerticalScrollbar()) | 662 if (box().hasAutoVerticalScrollbar()) |
| 674 setHasVerticalScrollbar(shouldHaveAutoVerticalScrollbar); | 663 setHasVerticalScrollbar(shouldHaveAutoVerticalScrollbar); |
| 675 else if (box().style()->overflowY() == OverflowScroll) | 664 else if (box().style()->overflowY() == OverflowScroll) |
| 676 setHasVerticalScrollbar(true); | 665 setHasVerticalScrollbar(true); |
| 677 | 666 |
| 678 if (hasScrollbar()) | 667 if (hasScrollbar()) |
| 679 updateScrollCornerStyle(); | 668 updateScrollCornerStyle(); |
| 680 | 669 |
| 681 layer()->updateSelfPaintingLayer(); | 670 layer()->updateSelfPaintingLayer(); |
| 682 | 671 |
| 683 // Force an update since we know the scrollbars have changed things. | 672 // Force an update since we know the scrollbars have changed things. |
| 684 if (box().document().hasAnnotatedRegions()) | 673 if (box().document().hasAnnotatedRegions()) |
| 685 box().document().setAnnotatedRegionsDirty(true); | 674 box().document().setAnnotatedRegionsDirty(true); |
| 686 | 675 |
| 687 // Our proprietary overflow: overlay value doesn't trigger a layout. | 676 // Our proprietary overflow: overlay value doesn't trigger a layout. |
| 688 if ((horizontalScrollBarChanged && box().style()->overflowX() != Overflo
wOverlay) || (verticalScrollBarChanged && box().style()->overflowY() != Overflow
Overlay)) { | 677 if ((horizontalScrollbarShouldChange && box().style()->overflowX() != Ov
erflowOverlay) |
| 689 if ((verticalScrollBarChanged && box().isHorizontalWritingMode()) | 678 || (verticalScrollbarShouldChange && box().style()->overflowY() != O
verflowOverlay)) { |
| 690 || (horizontalScrollBarChanged && !box().isHorizontalWritingMode
())) { | 679 if ((verticalScrollbarShouldChange && box().isHorizontalWritingMode(
)) |
| 680 || (horizontalScrollbarShouldChange && !box().isHorizontalWritin
gMode())) { |
| 691 box().setPreferredLogicalWidthsDirty(); | 681 box().setPreferredLogicalWidthsDirty(); |
| 692 } | 682 } |
| 693 if (delayedLayoutScope) { | 683 if (relayoutIsPrevented) { |
| 684 // We're not doing re-layout right now, but we still want to |
| 685 // add the scrollbar to the logical width now, to facilitate par
ent layout. |
| 694 box().updateLogicalWidth(); | 686 box().updateLogicalWidth(); |
| 695 if (box().isLayoutBlock()) | 687 if (box().isLayoutBlock()) |
| 696 toLayoutBlock(box()).scrollbarsChanged(horizontalScrollBarCh
anged, verticalScrollBarChanged); | 688 toLayoutBlock(box()).scrollbarsChanged(horizontalScrollbarSh
ouldChange, verticalScrollbarShouldChange); |
| 697 delayedLayoutScope->setNeedsLayout(&box(), LayoutInvalidationRea
son::ScrollbarChanged); | 689 PreventRelayoutScope::setNeedsLayout(box()); |
| 698 didMarkForDelayedLayout = true; | |
| 699 } else { | 690 } else { |
| 700 m_inOverflowRelayout = true; | 691 m_inOverflowRelayout = true; |
| 701 SubtreeLayoutScope layoutScope(box()); | 692 SubtreeLayoutScope layoutScope(box()); |
| 702 layoutScope.setNeedsLayout(&box(), LayoutInvalidationReason::Scr
ollbarChanged); | 693 layoutScope.setNeedsLayout(&box(), LayoutInvalidationReason::Scr
ollbarChanged); |
| 703 if (box().isLayoutBlock()) { | 694 if (box().isLayoutBlock()) { |
| 704 LayoutBlock& block = toLayoutBlock(box()); | 695 LayoutBlock& block = toLayoutBlock(box()); |
| 705 block.scrollbarsChanged(horizontalScrollBarChanged, vertical
ScrollBarChanged); | 696 block.scrollbarsChanged(horizontalScrollbarShouldChange, ver
ticalScrollbarShouldChange); |
| 706 block.layoutBlock(true); | 697 block.layoutBlock(true); |
| 707 } else { | 698 } else { |
| 708 box().layout(); | 699 box().layout(); |
| 709 } | 700 } |
| 710 m_inOverflowRelayout = false; | 701 m_inOverflowRelayout = false; |
| 702 m_scrollbarManager.destroyDetachedScrollbars(); |
| 711 } | 703 } |
| 712 LayoutObject* parent = box().parent(); | 704 LayoutObject* parent = box().parent(); |
| 713 if (parent && parent->isFlexibleBox()) | 705 if (parent && parent->isFlexibleBox()) |
| 714 toLayoutFlexibleBox(parent)->clearCachedMainSizeForChild(box()); | 706 toLayoutFlexibleBox(parent)->clearCachedMainSizeForChild(box()); |
| 715 } | 707 } |
| 716 } | 708 } |
| 717 | 709 |
| 718 { | 710 { |
| 719 // Hits in compositing/overflow/automatically-opt-into-composited-scroll
ing-after-style-change.html. | 711 // Hits in compositing/overflow/automatically-opt-into-composited-scroll
ing-after-style-change.html. |
| 720 DisableCompositingQueryAsserts disabler; | 712 DisableCompositingQueryAsserts disabler; |
| 721 | 713 |
| 722 // Set up the range (and page step/line step). | 714 // Set up the range (and page step/line step). |
| 723 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { | 715 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { |
| 724 int clientWidth = box().pixelSnappedClientWidth(); | 716 int clientWidth = box().pixelSnappedClientWidth(); |
| 725 horizontalScrollbar->setProportion(clientWidth, overflowRect().width
()); | 717 horizontalScrollbar->setProportion(clientWidth, overflowRect().width
()); |
| 726 } | 718 } |
| 727 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { | 719 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { |
| 728 int clientHeight = box().pixelSnappedClientHeight(); | 720 int clientHeight = box().pixelSnappedClientHeight(); |
| 729 verticalScrollbar->setProportion(clientHeight, overflowRect().height
()); | 721 verticalScrollbar->setProportion(clientHeight, overflowRect().height
()); |
| 730 } | 722 } |
| 731 } | 723 } |
| 732 | 724 |
| 733 if (hasOverlayScrollbars()) { | 725 if (!scrollbarsAreFrozen && hasOverlayScrollbars()) { |
| 734 if (!scrollSize(HorizontalScrollbar)) | 726 if (!scrollSize(HorizontalScrollbar)) |
| 735 setHasHorizontalScrollbar(false); | 727 setHasHorizontalScrollbar(false); |
| 736 if (!scrollSize(VerticalScrollbar)) | 728 if (!scrollSize(VerticalScrollbar)) |
| 737 setHasVerticalScrollbar(false); | 729 setHasVerticalScrollbar(false); |
| 738 } | 730 } |
| 739 | 731 |
| 740 bool hasOverflow = hasScrollableHorizontalOverflow() || hasScrollableVertica
lOverflow(); | 732 clampScrollPositionsAfterLayout(); |
| 741 updateScrollableAreaSet(hasOverflow); | 733 |
| 734 if (!scrollbarsAreFrozen) { |
| 735 bool hasOverflow = hasScrollableHorizontalOverflow() || hasScrollableVer
ticalOverflow(); |
| 736 updateScrollableAreaSet(hasOverflow); |
| 737 } |
| 742 | 738 |
| 743 DisableCompositingQueryAsserts disabler; | 739 DisableCompositingQueryAsserts disabler; |
| 744 positionOverflowControls(); | 740 positionOverflowControls(); |
| 741 } |
| 745 | 742 |
| 746 return didMarkForDelayedLayout; | 743 |
| 744 void PaintLayerScrollableArea::clampScrollPositionsAfterLayout() |
| 745 { |
| 746 // If a vertical scrollbar was removed, the min/max scroll positions may hav
e changed, |
| 747 // so the scroll positions needs to be clamped. If the scroll position did
not change, |
| 748 // but the scroll origin *did* change, we still need to notify the scrollbar
s to |
| 749 // update their dimensions. |
| 750 |
| 751 if (DelayScrollPositionClampScope::clampingIsDelayed()) { |
| 752 DelayScrollPositionClampScope::setNeedsClamp(this); |
| 753 return; |
| 754 } |
| 755 |
| 756 DoublePoint clampedScrollPosition = clampScrollPosition(scrollPositionDouble
()); |
| 757 if (clampedScrollPosition != scrollPositionDouble()) |
| 758 ScrollableArea::setScrollPosition(clampedScrollPosition, ProgrammaticScr
oll); |
| 759 else if (scrollOriginChanged()) |
| 760 scrollPositionChanged(clampedScrollPosition, ProgrammaticScroll); |
| 761 |
| 762 setNeedsScrollPositionClamp(false); |
| 763 resetScrollOriginChanged(); |
| 747 } | 764 } |
| 748 | 765 |
| 749 ScrollBehavior PaintLayerScrollableArea::scrollBehaviorStyle() const | 766 ScrollBehavior PaintLayerScrollableArea::scrollBehaviorStyle() const |
| 750 { | 767 { |
| 751 return box().style()->getScrollBehavior(); | 768 return box().style()->getScrollBehavior(); |
| 752 } | 769 } |
| 753 | 770 |
| 754 bool PaintLayerScrollableArea::hasHorizontalOverflow() const | 771 bool PaintLayerScrollableArea::hasHorizontalOverflow() const |
| 755 { | 772 { |
| 756 return pixelSnappedScrollWidth() > box().pixelSnappedClientWidth(); | 773 return pixelSnappedScrollWidth() > box().pixelSnappedClientWidth(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 // Avoid drawing two sets of scrollbars when one is provided by the visual v
iewport. | 821 // Avoid drawing two sets of scrollbars when one is provided by the visual v
iewport. |
| 805 if (visualViewportSuppliesScrollbars()) { | 822 if (visualViewportSuppliesScrollbars()) { |
| 806 setHasHorizontalScrollbar(false); | 823 setHasHorizontalScrollbar(false); |
| 807 setHasVerticalScrollbar(false); | 824 setHasVerticalScrollbar(false); |
| 808 return; | 825 return; |
| 809 } | 826 } |
| 810 | 827 |
| 811 EOverflow overflowX = box().style()->overflowX(); | 828 EOverflow overflowX = box().style()->overflowX(); |
| 812 EOverflow overflowY = box().style()->overflowY(); | 829 EOverflow overflowY = box().style()->overflowY(); |
| 813 | 830 |
| 814 // To avoid doing a relayout in updateScrollbarsAfterLayout, we try to keep
any automatic scrollbar that was already present. | |
| 815 bool needsHorizontalScrollbar = (hasHorizontalScrollbar() && overflowDefines
AutomaticScrollbar(overflowX)) || overflowRequiresScrollbar(overflowX); | 831 bool needsHorizontalScrollbar = (hasHorizontalScrollbar() && overflowDefines
AutomaticScrollbar(overflowX)) || overflowRequiresScrollbar(overflowX); |
| 816 bool needsVerticalScrollbar = (hasVerticalScrollbar() && overflowDefinesAuto
maticScrollbar(overflowY)) || overflowRequiresScrollbar(overflowY); | 832 bool needsVerticalScrollbar = (hasVerticalScrollbar() && overflowDefinesAuto
maticScrollbar(overflowY)) || overflowRequiresScrollbar(overflowY); |
| 817 | 833 |
| 818 // Look for the scrollbarModes and reset the needs Horizontal & vertical Scr
ollbar values based on scrollbarModes, as during force style change | 834 // Look for the scrollbarModes and reset the needs Horizontal & vertical Scr
ollbar values based on scrollbarModes, as during force style change |
| 819 // StyleResolver::styleForDocument returns documentStyle with no overflow v
alues, due to which we are destorying the scrollbars that was | 835 // StyleResolver::styleForDocument returns documentStyle with no overflow v
alues, due to which we are destorying the scrollbars that was |
| 820 // already present. | 836 // already present. |
| 821 if (box().isLayoutView()) { | 837 if (box().isLayoutView()) { |
| 822 if (LocalFrame* frame = box().frame()) { | 838 if (LocalFrame* frame = box().frame()) { |
| 823 if (FrameView* frameView = frame->view()) { | 839 if (FrameView* frameView = frame->view()) { |
| 824 ScrollbarMode hMode; | 840 ScrollbarMode hMode; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 { | 891 { |
| 876 layer()->updateScrollingStateAfterCompositingChange(); | 892 layer()->updateScrollingStateAfterCompositingChange(); |
| 877 const bool layersChanged = m_topmostScrollChild != m_nextTopmostScrollChild; | 893 const bool layersChanged = m_topmostScrollChild != m_nextTopmostScrollChild; |
| 878 m_topmostScrollChild = m_nextTopmostScrollChild; | 894 m_topmostScrollChild = m_nextTopmostScrollChild; |
| 879 m_nextTopmostScrollChild = nullptr; | 895 m_nextTopmostScrollChild = nullptr; |
| 880 return layersChanged; | 896 return layersChanged; |
| 881 } | 897 } |
| 882 | 898 |
| 883 void PaintLayerScrollableArea::updateAfterOverflowRecalc() | 899 void PaintLayerScrollableArea::updateAfterOverflowRecalc() |
| 884 { | 900 { |
| 885 computeScrollDimensions(); | 901 updateScrollDimensions(); |
| 886 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { | 902 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { |
| 887 int clientWidth = box().pixelSnappedClientWidth(); | 903 int clientWidth = box().pixelSnappedClientWidth(); |
| 888 horizontalScrollbar->setProportion(clientWidth, overflowRect().width()); | 904 horizontalScrollbar->setProportion(clientWidth, overflowRect().width()); |
| 889 } | 905 } |
| 890 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { | 906 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { |
| 891 int clientHeight = box().pixelSnappedClientHeight(); | 907 int clientHeight = box().pixelSnappedClientHeight(); |
| 892 verticalScrollbar->setProportion(clientHeight, overflowRect().height()); | 908 verticalScrollbar->setProportion(clientHeight, overflowRect().height()); |
| 893 } | 909 } |
| 894 | 910 |
| 895 bool hasHorizontalOverflow = this->hasHorizontalOverflow(); | 911 bool hasHorizontalOverflow = this->hasHorizontalOverflow(); |
| 896 bool hasVerticalOverflow = this->hasVerticalOverflow(); | 912 bool hasVerticalOverflow = this->hasVerticalOverflow(); |
| 897 bool autoHorizontalScrollBarChanged = box().hasAutoHorizontalScrollbar() &&
(hasHorizontalScrollbar() != hasHorizontalOverflow); | 913 bool autoHorizontalScrollbarChanged = box().hasAutoHorizontalScrollbar() &&
(hasHorizontalScrollbar() != hasHorizontalOverflow); |
| 898 bool autoVerticalScrollBarChanged = box().hasAutoVerticalScrollbar() && (has
VerticalScrollbar() != hasVerticalOverflow); | 914 bool autoVerticalScrollbarChanged = box().hasAutoVerticalScrollbar() && (has
VerticalScrollbar() != hasVerticalOverflow); |
| 899 if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) | 915 if (autoHorizontalScrollbarChanged || autoVerticalScrollbarChanged) |
| 900 box().setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::U
nknown); | 916 box().setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::U
nknown); |
| 901 } | 917 } |
| 902 | 918 |
| 903 IntRect PaintLayerScrollableArea::rectForHorizontalScrollbar(const IntRect& bord
erBoxRect) const | 919 IntRect PaintLayerScrollableArea::rectForHorizontalScrollbar(const IntRect& bord
erBoxRect) const |
| 904 { | 920 { |
| 905 if (!hasHorizontalScrollbar()) | 921 if (!hasHorizontalScrollbar()) |
| 906 return IntRect(); | 922 return IntRect(); |
| 907 | 923 |
| 908 const IntRect& scrollCorner = scrollCornerRect(); | 924 const IntRect& scrollCorner = scrollCornerRect(); |
| 909 | 925 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1007 if (hasVerticalScrollbar() && verticalScrollbar()->isCustomScrollbar()) { | 1023 if (hasVerticalScrollbar() && verticalScrollbar()->isCustomScrollbar()) { |
| 1008 if (actualLayoutObject != toLayoutScrollbar(verticalScrollbar())->owning
LayoutObject()) | 1024 if (actualLayoutObject != toLayoutScrollbar(verticalScrollbar())->owning
LayoutObject()) |
| 1009 didCustomScrollbarOwnerChanged = true; | 1025 didCustomScrollbarOwnerChanged = true; |
| 1010 } | 1026 } |
| 1011 | 1027 |
| 1012 return hasAnyScrollbar && ((shouldUseCustom != hasCustom) || (shouldUseCusto
m && didCustomScrollbarOwnerChanged)); | 1028 return hasAnyScrollbar && ((shouldUseCustom != hasCustom) || (shouldUseCusto
m && didCustomScrollbarOwnerChanged)); |
| 1013 } | 1029 } |
| 1014 | 1030 |
| 1015 void PaintLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar) | 1031 void PaintLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar) |
| 1016 { | 1032 { |
| 1033 if (FreezeScrollbarsScope::scrollbarsAreFrozen()) |
| 1034 return; |
| 1035 |
| 1017 if (hasScrollbar == hasHorizontalScrollbar()) | 1036 if (hasScrollbar == hasHorizontalScrollbar()) |
| 1018 return; | 1037 return; |
| 1019 | 1038 |
| 1020 setScrollbarNeedsPaintInvalidation(HorizontalScrollbar); | 1039 setScrollbarNeedsPaintInvalidation(HorizontalScrollbar); |
| 1021 | 1040 |
| 1022 m_scrollbarManager.setHasHorizontalScrollbar(hasScrollbar); | 1041 m_scrollbarManager.setHasHorizontalScrollbar(hasScrollbar); |
| 1023 | 1042 |
| 1043 updateScrollOrigin(); |
| 1044 |
| 1024 // Destroying or creating one bar can cause our scrollbar corner to come and
go. We need to update the opposite scrollbar's style. | 1045 // Destroying or creating one bar can cause our scrollbar corner to come and
go. We need to update the opposite scrollbar's style. |
| 1025 if (hasHorizontalScrollbar()) | 1046 if (hasHorizontalScrollbar()) |
| 1026 horizontalScrollbar()->styleChanged(); | 1047 horizontalScrollbar()->styleChanged(); |
| 1027 if (hasVerticalScrollbar()) | 1048 if (hasVerticalScrollbar()) |
| 1028 verticalScrollbar()->styleChanged(); | 1049 verticalScrollbar()->styleChanged(); |
| 1029 | 1050 |
| 1030 setScrollCornerNeedsPaintInvalidation(); | 1051 setScrollCornerNeedsPaintInvalidation(); |
| 1031 | 1052 |
| 1032 // Force an update since we know the scrollbars have changed things. | 1053 // Force an update since we know the scrollbars have changed things. |
| 1033 if (box().document().hasAnnotatedRegions()) | 1054 if (box().document().hasAnnotatedRegions()) |
| 1034 box().document().setAnnotatedRegionsDirty(true); | 1055 box().document().setAnnotatedRegionsDirty(true); |
| 1035 } | 1056 } |
| 1036 | 1057 |
| 1037 void PaintLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar) | 1058 void PaintLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar) |
| 1038 { | 1059 { |
| 1060 if (FreezeScrollbarsScope::scrollbarsAreFrozen()) |
| 1061 return; |
| 1062 |
| 1039 if (hasScrollbar == hasVerticalScrollbar()) | 1063 if (hasScrollbar == hasVerticalScrollbar()) |
| 1040 return; | 1064 return; |
| 1041 | 1065 |
| 1042 setScrollbarNeedsPaintInvalidation(VerticalScrollbar); | 1066 setScrollbarNeedsPaintInvalidation(VerticalScrollbar); |
| 1043 | 1067 |
| 1044 m_scrollbarManager.setHasVerticalScrollbar(hasScrollbar); | 1068 m_scrollbarManager.setHasVerticalScrollbar(hasScrollbar); |
| 1045 | 1069 |
| 1070 updateScrollOrigin(); |
| 1071 |
| 1046 // Destroying or creating one bar can cause our scrollbar corner to come and
go. We need to update the opposite scrollbar's style. | 1072 // Destroying or creating one bar can cause our scrollbar corner to come and
go. We need to update the opposite scrollbar's style. |
| 1047 if (hasHorizontalScrollbar()) | 1073 if (hasHorizontalScrollbar()) |
| 1048 horizontalScrollbar()->styleChanged(); | 1074 horizontalScrollbar()->styleChanged(); |
| 1049 if (hasVerticalScrollbar()) | 1075 if (hasVerticalScrollbar()) |
| 1050 verticalScrollbar()->styleChanged(); | 1076 verticalScrollbar()->styleChanged(); |
| 1051 | 1077 |
| 1052 setScrollCornerNeedsPaintInvalidation(); | 1078 setScrollCornerNeedsPaintInvalidation(); |
| 1053 | 1079 |
| 1054 // Force an update since we know the scrollbars have changed things. | 1080 // Force an update since we know the scrollbars have changed things. |
| 1055 if (box().document().hasAnnotatedRegions()) | 1081 if (box().document().hasAnnotatedRegions()) |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1506 { | 1532 { |
| 1507 if (LocalFrame* frame = box().frame()) { | 1533 if (LocalFrame* frame = box().frame()) { |
| 1508 if (Page* page = frame->page()) | 1534 if (Page* page = frame->page()) |
| 1509 return page->scrollingCoordinator() ? page->scrollingCoordinator()->
compositorAnimationTimeline() : nullptr; | 1535 return page->scrollingCoordinator() ? page->scrollingCoordinator()->
compositorAnimationTimeline() : nullptr; |
| 1510 } | 1536 } |
| 1511 return nullptr; | 1537 return nullptr; |
| 1512 } | 1538 } |
| 1513 | 1539 |
| 1514 PaintLayerScrollableArea::ScrollbarManager::ScrollbarManager(PaintLayerScrollabl
eArea& scrollableArea) | 1540 PaintLayerScrollableArea::ScrollbarManager::ScrollbarManager(PaintLayerScrollabl
eArea& scrollableArea) |
| 1515 : m_scrollableArea(&scrollableArea) | 1541 : m_scrollableArea(&scrollableArea) |
| 1516 , m_canDetachScrollbars(0) | |
| 1517 , m_hBarIsAttached(0) | 1542 , m_hBarIsAttached(0) |
| 1518 , m_vBarIsAttached(0) | 1543 , m_vBarIsAttached(0) |
| 1519 { | 1544 { |
| 1520 } | 1545 } |
| 1521 | 1546 |
| 1522 void PaintLayerScrollableArea::ScrollbarManager::dispose() | 1547 void PaintLayerScrollableArea::ScrollbarManager::dispose() |
| 1523 { | 1548 { |
| 1524 m_canDetachScrollbars = m_hBarIsAttached = m_vBarIsAttached = 0; | 1549 m_hBarIsAttached = m_vBarIsAttached = 0; |
| 1525 destroyScrollbar(HorizontalScrollbar); | 1550 destroyScrollbar(HorizontalScrollbar); |
| 1526 destroyScrollbar(VerticalScrollbar); | 1551 destroyScrollbar(VerticalScrollbar); |
| 1527 } | 1552 } |
| 1528 | 1553 |
| 1529 void PaintLayerScrollableArea::ScrollbarManager::setCanDetachScrollbars(bool det
ach) | 1554 void PaintLayerScrollableArea::ScrollbarManager::destroyDetachedScrollbars() |
| 1530 { | 1555 { |
| 1531 ASSERT(!m_hBarIsAttached || m_hBar); | 1556 ASSERT(!m_hBarIsAttached || m_hBar); |
| 1532 ASSERT(!m_vBarIsAttached || m_vBar); | 1557 ASSERT(!m_vBarIsAttached || m_vBar); |
| 1533 m_canDetachScrollbars = detach ? 1 : 0; | 1558 if (m_hBar && !m_hBarIsAttached) |
| 1534 if (!detach) { | 1559 destroyScrollbar(HorizontalScrollbar); |
| 1535 if (m_hBar && !m_hBarIsAttached) | 1560 if (m_vBar && !m_vBarIsAttached) |
| 1536 destroyScrollbar(HorizontalScrollbar); | 1561 destroyScrollbar(VerticalScrollbar); |
| 1537 if (m_vBar && !m_vBarIsAttached) | |
| 1538 destroyScrollbar(VerticalScrollbar); | |
| 1539 } | |
| 1540 } | 1562 } |
| 1541 | 1563 |
| 1542 void PaintLayerScrollableArea::ScrollbarManager::setHasHorizontalScrollbar(bool
hasScrollbar) | 1564 void PaintLayerScrollableArea::ScrollbarManager::setHasHorizontalScrollbar(bool
hasScrollbar) |
| 1543 { | 1565 { |
| 1544 if (hasScrollbar) { | 1566 if (hasScrollbar) { |
| 1545 // This doesn't hit in any tests, but since the equivalent code in setHa
sVerticalScrollbar | 1567 // This doesn't hit in any tests, but since the equivalent code in setHa
sVerticalScrollbar |
| 1546 // does, presumably this code does as well. | 1568 // does, presumably this code does as well. |
| 1547 DisableCompositingQueryAsserts disabler; | 1569 DisableCompositingQueryAsserts disabler; |
| 1548 if (!m_hBar) { | 1570 if (!m_hBar) { |
| 1549 m_hBar = createScrollbar(HorizontalScrollbar); | 1571 m_hBar = createScrollbar(HorizontalScrollbar); |
| 1550 m_hBarIsAttached = 1; | 1572 m_hBarIsAttached = 1; |
| 1551 if (!m_hBar->isCustomScrollbar()) | 1573 if (!m_hBar->isCustomScrollbar()) |
| 1552 m_scrollableArea->didAddScrollbar(*m_hBar, HorizontalScrollbar); | 1574 m_scrollableArea->didAddScrollbar(*m_hBar, HorizontalScrollbar); |
| 1553 } else { | 1575 } else { |
| 1554 m_hBarIsAttached = 1; | 1576 m_hBarIsAttached = 1; |
| 1555 } | 1577 } |
| 1556 | |
| 1557 } else { | 1578 } else { |
| 1558 m_hBarIsAttached = 0; | 1579 m_hBarIsAttached = 0; |
| 1559 if (!m_canDetachScrollbars) | 1580 destroyScrollbar(HorizontalScrollbar); |
| 1560 destroyScrollbar(HorizontalScrollbar); | |
| 1561 } | 1581 } |
| 1562 } | 1582 } |
| 1563 | 1583 |
| 1564 void PaintLayerScrollableArea::ScrollbarManager::setHasVerticalScrollbar(bool ha
sScrollbar) | 1584 void PaintLayerScrollableArea::ScrollbarManager::setHasVerticalScrollbar(bool ha
sScrollbar) |
| 1565 { | 1585 { |
| 1566 if (hasScrollbar) { | 1586 if (hasScrollbar) { |
| 1567 DisableCompositingQueryAsserts disabler; | 1587 DisableCompositingQueryAsserts disabler; |
| 1568 if (!m_vBar) { | 1588 if (!m_vBar) { |
| 1569 m_vBar = createScrollbar(VerticalScrollbar); | 1589 m_vBar = createScrollbar(VerticalScrollbar); |
| 1570 m_vBarIsAttached = 1; | 1590 m_vBarIsAttached = 1; |
| 1571 if (!m_vBar->isCustomScrollbar()) | 1591 if (!m_vBar->isCustomScrollbar()) |
| 1572 m_scrollableArea->didAddScrollbar(*m_vBar, VerticalScrollbar); | 1592 m_scrollableArea->didAddScrollbar(*m_vBar, VerticalScrollbar); |
| 1573 } else { | 1593 } else { |
| 1574 m_vBarIsAttached = 1; | 1594 m_vBarIsAttached = 1; |
| 1575 } | 1595 } |
| 1576 | |
| 1577 } else { | 1596 } else { |
| 1578 m_vBarIsAttached = 0; | 1597 m_vBarIsAttached = 0; |
| 1579 if (!m_canDetachScrollbars) | 1598 destroyScrollbar(VerticalScrollbar); |
| 1580 destroyScrollbar(VerticalScrollbar); | |
| 1581 } | 1599 } |
| 1582 } | 1600 } |
| 1583 | 1601 |
| 1584 Scrollbar* PaintLayerScrollableArea::ScrollbarManager::createScrollbar(Scrollbar
Orientation orientation) | 1602 Scrollbar* PaintLayerScrollableArea::ScrollbarManager::createScrollbar(Scrollbar
Orientation orientation) |
| 1585 { | 1603 { |
| 1586 ASSERT(orientation == HorizontalScrollbar ? !m_hBarIsAttached : !m_vBarIsAtt
ached); | 1604 ASSERT(orientation == HorizontalScrollbar ? !m_hBarIsAttached : !m_vBarIsAtt
ached); |
| 1587 Scrollbar* scrollbar = nullptr; | 1605 Scrollbar* scrollbar = nullptr; |
| 1588 const LayoutObject& actualLayoutObject = layoutObjectForScrollbar(m_scrollab
leArea->box()); | 1606 const LayoutObject& actualLayoutObject = layoutObjectForScrollbar(m_scrollab
leArea->box()); |
| 1589 bool hasCustomScrollbarStyle = actualLayoutObject.isBox() && actualLayoutObj
ect.styleRef().hasPseudoStyle(PseudoIdScrollbar); | 1607 bool hasCustomScrollbarStyle = actualLayoutObject.isBox() && actualLayoutObj
ect.styleRef().hasPseudoStyle(PseudoIdScrollbar); |
| 1590 if (hasCustomScrollbarStyle) { | 1608 if (hasCustomScrollbarStyle) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1620 scrollbar = nullptr; | 1638 scrollbar = nullptr; |
| 1621 } | 1639 } |
| 1622 | 1640 |
| 1623 DEFINE_TRACE(PaintLayerScrollableArea::ScrollbarManager) | 1641 DEFINE_TRACE(PaintLayerScrollableArea::ScrollbarManager) |
| 1624 { | 1642 { |
| 1625 visitor->trace(m_scrollableArea); | 1643 visitor->trace(m_scrollableArea); |
| 1626 visitor->trace(m_hBar); | 1644 visitor->trace(m_hBar); |
| 1627 visitor->trace(m_vBar); | 1645 visitor->trace(m_vBar); |
| 1628 } | 1646 } |
| 1629 | 1647 |
| 1648 int PaintLayerScrollableArea::PreventRelayoutScope::s_count = 0; |
| 1649 SubtreeLayoutScope* PaintLayerScrollableArea::PreventRelayoutScope::s_layoutScop
e = nullptr; |
| 1650 bool PaintLayerScrollableArea::PreventRelayoutScope::s_relayoutNeeded = false; |
| 1651 WTF::Vector<LayoutObject*>* PaintLayerScrollableArea::PreventRelayoutScope::s_ne
edsRelayout = nullptr; |
| 1652 |
| 1653 PaintLayerScrollableArea::PreventRelayoutScope::PreventRelayoutScope(SubtreeLayo
utScope& layoutScope) |
| 1654 { |
| 1655 if (!s_count) { |
| 1656 DCHECK(!s_layoutScope); |
| 1657 DCHECK(!s_needsRelayout || s_needsRelayout->isEmpty()); |
| 1658 s_layoutScope = &layoutScope; |
| 1659 } |
| 1660 s_count++; |
| 1661 } |
| 1662 |
| 1663 PaintLayerScrollableArea::PreventRelayoutScope::~PreventRelayoutScope() |
| 1664 { |
| 1665 if (--s_count == 0) { |
| 1666 if (s_relayoutNeeded) { |
| 1667 for (auto layoutObject : *s_needsRelayout) |
| 1668 s_layoutScope->setNeedsLayout(layoutObject, LayoutInvalidationRe
ason::ScrollbarChanged); |
| 1669 s_needsRelayout->clear(); |
| 1670 } |
| 1671 s_layoutScope = nullptr; |
| 1672 } |
| 1673 } |
| 1674 |
| 1675 void PaintLayerScrollableArea::PreventRelayoutScope::setNeedsLayout(LayoutObject
& layoutObject) |
| 1676 { |
| 1677 DCHECK(s_count); |
| 1678 DCHECK(s_layoutScope); |
| 1679 s_relayoutNeeded = true; |
| 1680 if (!s_needsRelayout) |
| 1681 s_needsRelayout = new WTF::Vector<LayoutObject*>(); |
| 1682 s_needsRelayout->append(&layoutObject); |
| 1683 } |
| 1684 |
| 1685 void PaintLayerScrollableArea::PreventRelayoutScope::resetRelayoutNeeded() |
| 1686 { |
| 1687 DCHECK_EQ(s_count, 0); |
| 1688 DCHECK(!s_needsRelayout || s_needsRelayout->isEmpty()); |
| 1689 s_relayoutNeeded = false; |
| 1690 } |
| 1691 |
| 1692 int PaintLayerScrollableArea::FreezeScrollbarsScope::s_count = 0; |
| 1693 |
| 1694 int PaintLayerScrollableArea::DelayScrollPositionClampScope::s_count = 0; |
| 1695 PersistentHeapVector<Member<PaintLayerScrollableArea>>* PaintLayerScrollableArea
::DelayScrollPositionClampScope::s_needsClamp = nullptr; |
| 1696 |
| 1697 PaintLayerScrollableArea::DelayScrollPositionClampScope::DelayScrollPositionClam
pScope() |
| 1698 { |
| 1699 if (!s_needsClamp) |
| 1700 s_needsClamp = new PersistentHeapVector<Member<PaintLayerScrollableArea>
>(); |
| 1701 DCHECK(s_count > 0 || s_needsClamp->isEmpty()); |
| 1702 s_count++; |
| 1703 } |
| 1704 |
| 1705 PaintLayerScrollableArea::DelayScrollPositionClampScope::~DelayScrollPositionCla
mpScope() |
| 1706 { |
| 1707 if (--s_count == 0) |
| 1708 DelayScrollPositionClampScope::clampScrollableAreas(); |
| 1709 } |
| 1710 |
| 1711 void PaintLayerScrollableArea::DelayScrollPositionClampScope::setNeedsClamp(Pain
tLayerScrollableArea* scrollableArea) |
| 1712 { |
| 1713 if (!scrollableArea->needsScrollPositionClamp()) { |
| 1714 scrollableArea->setNeedsScrollPositionClamp(true); |
| 1715 s_needsClamp->append(scrollableArea); |
| 1716 } |
| 1717 } |
| 1718 |
| 1719 void PaintLayerScrollableArea::DelayScrollPositionClampScope::clampScrollableAre
as() |
| 1720 { |
| 1721 for (auto& scrollableArea : *s_needsClamp) |
| 1722 scrollableArea->clampScrollPositionsAfterLayout(); |
| 1723 delete s_needsClamp; |
| 1724 s_needsClamp = nullptr; |
| 1725 } |
| 1726 |
| 1630 } // namespace blink | 1727 } // namespace blink |
| OLD | NEW |