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 |