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 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 int PaintLayerScrollableArea::pixelSnappedScrollWidth() const | 580 int PaintLayerScrollableArea::pixelSnappedScrollWidth() const |
581 { | 581 { |
582 return snapSizeToPixel(scrollWidth(), box().clientLeft() + box().location().
x()); | 582 return snapSizeToPixel(scrollWidth(), box().clientLeft() + box().location().
x()); |
583 } | 583 } |
584 | 584 |
585 int PaintLayerScrollableArea::pixelSnappedScrollHeight() const | 585 int PaintLayerScrollableArea::pixelSnappedScrollHeight() const |
586 { | 586 { |
587 return snapSizeToPixel(scrollHeight(), box().clientTop() + box().location().
y()); | 587 return snapSizeToPixel(scrollHeight(), box().clientTop() + box().location().
y()); |
588 } | 588 } |
589 | 589 |
590 void PaintLayerScrollableArea::computeScrollDimensions() | 590 void PaintLayerScrollableArea::updateScrollOrigin() |
| 591 { |
| 592 if (!overflowRect().size().isZero()) { |
| 593 LayoutPoint scrollableOverflow = m_overflowRect.location() - LayoutSize(
box().borderLeft(), box().borderTop()); |
| 594 setScrollOrigin(flooredIntPoint(-scrollableOverflow) + box().originAdjus
tmentForScrollbars()); |
| 595 } |
| 596 } |
| 597 |
| 598 void PaintLayerScrollableArea::updateScrollDimensions() |
591 { | 599 { |
592 m_overflowRect = box().layoutOverflowRect(); | 600 m_overflowRect = box().layoutOverflowRect(); |
593 box().flipForWritingMode(m_overflowRect); | 601 box().flipForWritingMode(m_overflowRect); |
594 | 602 updateScrollOrigin(); |
595 LayoutPoint scrollableOverflow = m_overflowRect.location() - LayoutSize(box(
).borderLeft(), box().borderTop()); | |
596 setScrollOrigin(flooredIntPoint(-scrollableOverflow) + box().originAdjustmen
tForScrollbars()); | |
597 } | 603 } |
598 | 604 |
599 void PaintLayerScrollableArea::scrollToPosition(const DoublePoint& scrollPositio
n, ScrollOffsetClamping clamp, ScrollBehavior scrollBehavior, ScrollType scrollT
ype) | 605 void PaintLayerScrollableArea::scrollToPosition(const DoublePoint& scrollPositio
n, ScrollOffsetClamping clamp, ScrollBehavior scrollBehavior, ScrollType scrollT
ype) |
600 { | 606 { |
601 cancelProgrammaticScrollAnimation(); | |
602 | |
603 DoublePoint newScrollPosition = clamp == ScrollOffsetClamped ? clampScrollPo
sition(scrollPosition) : scrollPosition; | 607 DoublePoint newScrollPosition = clamp == ScrollOffsetClamped ? clampScrollPo
sition(scrollPosition) : scrollPosition; |
604 if (newScrollPosition != scrollPositionDouble()) | 608 if (newScrollPosition != scrollPositionDouble()) |
605 ScrollableArea::setScrollPosition(newScrollPosition, scrollType, scrollB
ehavior); | 609 ScrollableArea::setScrollPosition(newScrollPosition, scrollType, scrollB
ehavior); |
606 } | 610 } |
607 | 611 |
608 bool PaintLayerScrollableArea::updateAfterLayout(SubtreeLayoutScope* delayedLayo
utScope) | 612 void PaintLayerScrollableArea::updateAfterLayout() |
609 { | 613 { |
610 ASSERT(box().hasOverflowClip()); | 614 ASSERT(box().hasOverflowClip()); |
611 | 615 |
612 bool didMarkForDelayedLayout = false; | 616 bool relayoutIsPrevented = PreventRelayoutScope::relayoutIsPrevented(); |
| 617 bool scrollbarsAreFrozen = FreezeScrollbarsScope::scrollbarsAreFrozen(); |
613 | 618 |
614 if (needsScrollbarReconstruction()) { | 619 if (needsScrollbarReconstruction()) { |
615 m_scrollbarManager.setCanDetachScrollbars(false); | |
616 setHasHorizontalScrollbar(false); | 620 setHasHorizontalScrollbar(false); |
617 setHasVerticalScrollbar(false); | 621 setHasVerticalScrollbar(false); |
618 } | 622 } |
619 | 623 |
620 m_scrollbarManager.setCanDetachScrollbars(true); | 624 updateScrollDimensions(); |
621 | |
622 IntPoint originalOrigin = scrollOrigin(); | |
623 computeScrollDimensions(); | |
624 | |
625 // Layout may cause us to be at an invalid scroll position. In this case we
need | |
626 // to pull our scroll offsets back to the max (or push them up to the min). | |
627 DoublePoint clampedScrollPosition = clampScrollPosition(scrollPositionDouble
()); | |
628 if (clampedScrollPosition != scrollPositionDouble()) { | |
629 scrollToPosition(clampedScrollPosition); | |
630 } else if (originalOrigin != scrollOrigin()) { | |
631 // TODO: We should be able to use scrollOriginChanged() here, but we can
't because | |
632 // PaintLayerScrollableArea does not maintain that flag: it gets set, bu
t it never | |
633 // gets unset. We should unset the flag after layout. | |
634 scrollPositionChanged(scrollPositionDouble(), ProgrammaticScroll); | |
635 } | |
636 | |
637 m_scrollbarManager.setCanDetachScrollbars(false); | |
638 | 625 |
639 bool hasHorizontalOverflow = this->hasHorizontalOverflow(); | 626 bool hasHorizontalOverflow = this->hasHorizontalOverflow(); |
640 bool hasVerticalOverflow = this->hasVerticalOverflow(); | 627 bool hasVerticalOverflow = this->hasVerticalOverflow(); |
641 | 628 |
642 { | 629 { |
643 // Hits in compositing/overflow/automatically-opt-into-composited-scroll
ing-after-style-change.html. | 630 // Hits in compositing/overflow/automatically-opt-into-composited-scroll
ing-after-style-change.html. |
644 DisableCompositingQueryAsserts disabler; | 631 DisableCompositingQueryAsserts disabler; |
645 | 632 |
646 // overflow:scroll should just enable/disable. | 633 // overflow:scroll should just enable/disable. |
647 if (box().style()->overflowX() == OverflowScroll && horizontalScrollbar(
)) | 634 if (box().style()->overflowX() == OverflowScroll && horizontalScrollbar(
)) |
648 horizontalScrollbar()->setEnabled(hasHorizontalOverflow); | 635 horizontalScrollbar()->setEnabled(hasHorizontalOverflow); |
649 if (box().style()->overflowY() == OverflowScroll && verticalScrollbar()) | 636 if (box().style()->overflowY() == OverflowScroll && verticalScrollbar()) |
650 verticalScrollbar()->setEnabled(hasVerticalOverflow); | 637 verticalScrollbar()->setEnabled(hasVerticalOverflow); |
651 } | 638 } |
652 | 639 |
653 // We need to layout again if scrollbars are added or removed by overflow:au
to, | 640 // We need to layout again if scrollbars are added or removed by overflow:au
to, |
654 // or by changing between native and custom. | 641 // or by changing between native and custom. |
655 bool horizontalScrollBarChanged = (box().hasAutoHorizontalScrollbar() && (ha
sHorizontalScrollbar() != hasHorizontalOverflow)) | 642 bool horizontalScrollbarChanged = (box().hasAutoHorizontalScrollbar() && (ha
sHorizontalScrollbar() != hasHorizontalOverflow)) |
656 || (box().style()->overflowX() == OverflowScroll && !horizontalScrollbar
()); | 643 || (box().style()->overflowX() == OverflowScroll && !horizontalScrollbar
()); |
657 bool verticalScrollBarChanged = (box().hasAutoVerticalScrollbar() && (hasVer
ticalScrollbar() != hasVerticalOverflow)) | 644 bool verticalScrollbarChanged = (box().hasAutoVerticalScrollbar() && (hasVer
ticalScrollbar() != hasVerticalOverflow)) |
658 || (box().style()->overflowY() == OverflowScroll && !verticalScrollbar()
); | 645 || (box().style()->overflowY() == OverflowScroll && !verticalScrollbar()
); |
659 if (!visualViewportSuppliesScrollbars() && (horizontalScrollBarChanged || ve
rticalScrollBarChanged)) { | 646 if (!scrollbarsAreFrozen && !visualViewportSuppliesScrollbars() && (horizont
alScrollbarChanged || verticalScrollbarChanged)) { |
660 if (box().hasAutoHorizontalScrollbar()) | 647 if (box().hasAutoHorizontalScrollbar()) |
661 setHasHorizontalScrollbar(hasHorizontalOverflow); | 648 setHasHorizontalScrollbar(hasHorizontalOverflow); |
662 else if (box().style()->overflowX() == OverflowScroll) | 649 else if (box().style()->overflowX() == OverflowScroll) |
663 setHasHorizontalScrollbar(true); | 650 setHasHorizontalScrollbar(true); |
664 if (box().hasAutoVerticalScrollbar()) | 651 if (box().hasAutoVerticalScrollbar()) |
665 setHasVerticalScrollbar(hasVerticalOverflow); | 652 setHasVerticalScrollbar(hasVerticalOverflow); |
666 else if (box().style()->overflowY() == OverflowScroll) | 653 else if (box().style()->overflowY() == OverflowScroll) |
667 setHasVerticalScrollbar(true); | 654 setHasVerticalScrollbar(true); |
668 | 655 |
669 if (hasVerticalOverflow || hasHorizontalOverflow) | 656 if (hasVerticalOverflow || hasHorizontalOverflow) |
670 updateScrollCornerStyle(); | 657 updateScrollCornerStyle(); |
671 | 658 |
672 layer()->updateSelfPaintingLayer(); | 659 layer()->updateSelfPaintingLayer(); |
673 | 660 |
674 // Force an update since we know the scrollbars have changed things. | 661 // Force an update since we know the scrollbars have changed things. |
675 if (box().document().hasAnnotatedRegions()) | 662 if (box().document().hasAnnotatedRegions()) |
676 box().document().setAnnotatedRegionsDirty(true); | 663 box().document().setAnnotatedRegionsDirty(true); |
677 | 664 |
678 // Our proprietary overflow: overlay value doesn't trigger a layout. | 665 // Our proprietary overflow: overlay value doesn't trigger a layout. |
679 if ((horizontalScrollBarChanged && box().style()->overflowX() != Overflo
wOverlay) || (verticalScrollBarChanged && box().style()->overflowY() != Overflow
Overlay)) { | 666 if ((horizontalScrollbarChanged && box().style()->overflowX() != Overflo
wOverlay) || (verticalScrollbarChanged && box().style()->overflowY() != Overflow
Overlay)) { |
680 if (!m_inOverflowRelayout) { | 667 if (!m_inOverflowRelayout) { |
681 m_inOverflowRelayout = true; | 668 if ((verticalScrollbarChanged && box().isHorizontalWritingMode()
) |
682 if (delayedLayoutScope) { | 669 || (horizontalScrollbarChanged && !box().isHorizontalWriting
Mode())) { |
| 670 box().setPreferredLogicalWidthsDirty(); |
| 671 box().updateLogicalWidth(); |
| 672 } |
| 673 if (relayoutIsPrevented) { |
683 if (box().isLayoutBlock()) | 674 if (box().isLayoutBlock()) |
684 toLayoutBlock(box()).scrollbarsChanged(horizontalScrollB
arChanged, verticalScrollBarChanged); | 675 toLayoutBlock(box()).scrollbarsChanged(horizontalScrollb
arChanged, verticalScrollbarChanged); |
685 delayedLayoutScope->setNeedsLayout(&box(), LayoutInvalidatio
nReason::ScrollbarChanged); | 676 PreventRelayoutScope::setNeedsLayout(box()); |
686 didMarkForDelayedLayout = true; | |
687 } else { | 677 } else { |
| 678 m_inOverflowRelayout = true; |
688 SubtreeLayoutScope layoutScope(box()); | 679 SubtreeLayoutScope layoutScope(box()); |
689 layoutScope.setNeedsLayout(&box(), LayoutInvalidationReason:
:ScrollbarChanged); | 680 layoutScope.setNeedsLayout(&box(), LayoutInvalidationReason:
:ScrollbarChanged); |
690 if (box().isLayoutBlock()) { | 681 if (box().isLayoutBlock()) { |
691 LayoutBlock& block = toLayoutBlock(box()); | 682 LayoutBlock& block = toLayoutBlock(box()); |
692 block.scrollbarsChanged(horizontalScrollBarChanged, vert
icalScrollBarChanged); | 683 block.scrollbarsChanged(horizontalScrollbarChanged, vert
icalScrollbarChanged); |
693 block.layoutBlock(true); | 684 block.layoutBlock(true); |
694 } else { | 685 } else { |
695 box().layout(); | 686 box().layout(); |
696 } | 687 } |
| 688 m_inOverflowRelayout = false; |
| 689 m_scrollbarManager.destroyDetachedScrollbars(); |
697 } | 690 } |
698 LayoutObject* parent = box().parent(); | 691 LayoutObject* parent = box().parent(); |
699 if (parent && parent->isFlexibleBox()) | 692 if (parent && parent->isFlexibleBox()) |
700 toLayoutFlexibleBox(parent)->clearCachedMainSizeForChild(box
()); | 693 toLayoutFlexibleBox(parent)->clearCachedMainSizeForChild(box
()); |
701 m_inOverflowRelayout = false; | |
702 } | 694 } |
703 } | 695 } |
704 } | 696 } |
705 | 697 |
706 { | 698 { |
707 // Hits in compositing/overflow/automatically-opt-into-composited-scroll
ing-after-style-change.html. | 699 // Hits in compositing/overflow/automatically-opt-into-composited-scroll
ing-after-style-change.html. |
708 DisableCompositingQueryAsserts disabler; | 700 DisableCompositingQueryAsserts disabler; |
709 | 701 |
710 // Set up the range (and page step/line step). | 702 // Set up the range (and page step/line step). |
711 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { | 703 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { |
712 int clientWidth = box().pixelSnappedClientWidth(); | 704 int clientWidth = box().pixelSnappedClientWidth(); |
713 horizontalScrollbar->setProportion(clientWidth, overflowRect().width
()); | 705 horizontalScrollbar->setProportion(clientWidth, overflowRect().width
()); |
714 } | 706 } |
715 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { | 707 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { |
716 int clientHeight = box().pixelSnappedClientHeight(); | 708 int clientHeight = box().pixelSnappedClientHeight(); |
717 verticalScrollbar->setProportion(clientHeight, overflowRect().height
()); | 709 verticalScrollbar->setProportion(clientHeight, overflowRect().height
()); |
718 } | 710 } |
719 } | 711 } |
720 | 712 |
721 if (hasOverlayScrollbars()) { | 713 if (!scrollbarsAreFrozen && hasOverlayScrollbars()) { |
722 if (!scrollSize(HorizontalScrollbar)) | 714 if (!scrollSize(HorizontalScrollbar)) |
723 setHasHorizontalScrollbar(false); | 715 setHasHorizontalScrollbar(false); |
724 if (!scrollSize(VerticalScrollbar)) | 716 if (!scrollSize(VerticalScrollbar)) |
725 setHasVerticalScrollbar(false); | 717 setHasVerticalScrollbar(false); |
726 } | 718 } |
727 | 719 |
728 bool hasOverflow = hasScrollableHorizontalOverflow() || hasScrollableVertica
lOverflow(); | 720 clampScrollPositionsAfterLayout(); |
729 updateScrollableAreaSet(hasOverflow); | 721 |
| 722 if (!scrollbarsAreFrozen) { |
| 723 bool hasOverflow = hasScrollableHorizontalOverflow() || hasScrollableVer
ticalOverflow(); |
| 724 updateScrollableAreaSet(hasOverflow); |
| 725 } |
730 | 726 |
731 DisableCompositingQueryAsserts disabler; | 727 DisableCompositingQueryAsserts disabler; |
732 positionOverflowControls(); | 728 positionOverflowControls(); |
| 729 } |
733 | 730 |
734 return didMarkForDelayedLayout; | 731 |
| 732 void PaintLayerScrollableArea::clampScrollPositionsAfterLayout() |
| 733 { |
| 734 // If a vertical scrollbar was removed, the min/max scroll positions may hav
e changed, |
| 735 // so the scroll positions needs to be clamped. If the scroll position did
not change, |
| 736 // but the scroll origin *did* change, we still need to notify the scrollbar
s to |
| 737 // update their dimensions. |
| 738 |
| 739 if (DelayScrollPositionClampScope::clampingIsDelayed()) { |
| 740 DelayScrollPositionClampScope::setNeedsClamp(this); |
| 741 return; |
| 742 } |
| 743 |
| 744 DoublePoint newScrollPosition = clampScrollPosition(scrollPositionDouble()); |
| 745 if (newScrollPosition != scrollPositionDouble()) |
| 746 ScrollableArea::setScrollPosition(newScrollPosition, ProgrammaticScroll)
; |
| 747 else if (scrollOriginChanged()) |
| 748 scrollPositionChanged(newScrollPosition, ProgrammaticScroll); |
| 749 |
| 750 setNeedsScrollPositionClamp(false); |
| 751 resetScrollOriginChanged(); |
735 } | 752 } |
736 | 753 |
737 ScrollBehavior PaintLayerScrollableArea::scrollBehaviorStyle() const | 754 ScrollBehavior PaintLayerScrollableArea::scrollBehaviorStyle() const |
738 { | 755 { |
739 return box().style()->getScrollBehavior(); | 756 return box().style()->getScrollBehavior(); |
740 } | 757 } |
741 | 758 |
742 bool PaintLayerScrollableArea::hasHorizontalOverflow() const | 759 bool PaintLayerScrollableArea::hasHorizontalOverflow() const |
743 { | 760 { |
744 return pixelSnappedScrollWidth() > box().pixelSnappedClientWidth(); | 761 return pixelSnappedScrollWidth() > box().pixelSnappedClientWidth(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 // Avoid drawing two sets of scrollbars when one is provided by the visual v
iewport. | 809 // Avoid drawing two sets of scrollbars when one is provided by the visual v
iewport. |
793 if (visualViewportSuppliesScrollbars()) { | 810 if (visualViewportSuppliesScrollbars()) { |
794 setHasHorizontalScrollbar(false); | 811 setHasHorizontalScrollbar(false); |
795 setHasVerticalScrollbar(false); | 812 setHasVerticalScrollbar(false); |
796 return; | 813 return; |
797 } | 814 } |
798 | 815 |
799 EOverflow overflowX = box().style()->overflowX(); | 816 EOverflow overflowX = box().style()->overflowX(); |
800 EOverflow overflowY = box().style()->overflowY(); | 817 EOverflow overflowY = box().style()->overflowY(); |
801 | 818 |
802 // To avoid doing a relayout in updateScrollbarsAfterLayout, we try to keep
any automatic scrollbar that was already present. | |
803 bool needsHorizontalScrollbar = (hasHorizontalScrollbar() && overflowDefines
AutomaticScrollbar(overflowX)) || overflowRequiresScrollbar(overflowX); | 819 bool needsHorizontalScrollbar = (hasHorizontalScrollbar() && overflowDefines
AutomaticScrollbar(overflowX)) || overflowRequiresScrollbar(overflowX); |
804 bool needsVerticalScrollbar = (hasVerticalScrollbar() && overflowDefinesAuto
maticScrollbar(overflowY)) || overflowRequiresScrollbar(overflowY); | 820 bool needsVerticalScrollbar = (hasVerticalScrollbar() && overflowDefinesAuto
maticScrollbar(overflowY)) || overflowRequiresScrollbar(overflowY); |
805 | 821 |
806 // Look for the scrollbarModes and reset the needs Horizontal & vertical Scr
ollbar values based on scrollbarModes, as during force style change | 822 // Look for the scrollbarModes and reset the needs Horizontal & vertical Scr
ollbar values based on scrollbarModes, as during force style change |
807 // StyleResolver::styleForDocument returns documentStyle with no overflow v
alues, due to which we are destorying the scrollbars that was | 823 // StyleResolver::styleForDocument returns documentStyle with no overflow v
alues, due to which we are destorying the scrollbars that was |
808 // already present. | 824 // already present. |
809 if (box().isLayoutView()) { | 825 if (box().isLayoutView()) { |
810 if (LocalFrame* frame = box().frame()) { | 826 if (LocalFrame* frame = box().frame()) { |
811 if (FrameView* frameView = frame->view()) { | 827 if (FrameView* frameView = frame->view()) { |
812 ScrollbarMode hMode; | 828 ScrollbarMode hMode; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 { | 879 { |
864 layer()->updateScrollingStateAfterCompositingChange(); | 880 layer()->updateScrollingStateAfterCompositingChange(); |
865 const bool layersChanged = m_topmostScrollChild != m_nextTopmostScrollChild; | 881 const bool layersChanged = m_topmostScrollChild != m_nextTopmostScrollChild; |
866 m_topmostScrollChild = m_nextTopmostScrollChild; | 882 m_topmostScrollChild = m_nextTopmostScrollChild; |
867 m_nextTopmostScrollChild = nullptr; | 883 m_nextTopmostScrollChild = nullptr; |
868 return layersChanged; | 884 return layersChanged; |
869 } | 885 } |
870 | 886 |
871 void PaintLayerScrollableArea::updateAfterOverflowRecalc() | 887 void PaintLayerScrollableArea::updateAfterOverflowRecalc() |
872 { | 888 { |
873 computeScrollDimensions(); | 889 updateScrollDimensions(); |
874 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { | 890 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { |
875 int clientWidth = box().pixelSnappedClientWidth(); | 891 int clientWidth = box().pixelSnappedClientWidth(); |
876 horizontalScrollbar->setProportion(clientWidth, overflowRect().width()); | 892 horizontalScrollbar->setProportion(clientWidth, overflowRect().width()); |
877 } | 893 } |
878 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { | 894 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { |
879 int clientHeight = box().pixelSnappedClientHeight(); | 895 int clientHeight = box().pixelSnappedClientHeight(); |
880 verticalScrollbar->setProportion(clientHeight, overflowRect().height()); | 896 verticalScrollbar->setProportion(clientHeight, overflowRect().height()); |
881 } | 897 } |
882 | 898 |
883 bool hasHorizontalOverflow = this->hasHorizontalOverflow(); | 899 bool hasHorizontalOverflow = this->hasHorizontalOverflow(); |
884 bool hasVerticalOverflow = this->hasVerticalOverflow(); | 900 bool hasVerticalOverflow = this->hasVerticalOverflow(); |
885 bool autoHorizontalScrollBarChanged = box().hasAutoHorizontalScrollbar() &&
(hasHorizontalScrollbar() != hasHorizontalOverflow); | 901 bool autoHorizontalScrollbarChanged = box().hasAutoHorizontalScrollbar() &&
(hasHorizontalScrollbar() != hasHorizontalOverflow); |
886 bool autoVerticalScrollBarChanged = box().hasAutoVerticalScrollbar() && (has
VerticalScrollbar() != hasVerticalOverflow); | 902 bool autoVerticalScrollbarChanged = box().hasAutoVerticalScrollbar() && (has
VerticalScrollbar() != hasVerticalOverflow); |
887 if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) | 903 if (autoHorizontalScrollbarChanged || autoVerticalScrollbarChanged) |
888 box().setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::U
nknown); | 904 box().setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::U
nknown); |
889 } | 905 } |
890 | 906 |
891 IntRect PaintLayerScrollableArea::rectForHorizontalScrollbar(const IntRect& bord
erBoxRect) const | 907 IntRect PaintLayerScrollableArea::rectForHorizontalScrollbar(const IntRect& bord
erBoxRect) const |
892 { | 908 { |
893 if (!hasHorizontalScrollbar()) | 909 if (!hasHorizontalScrollbar()) |
894 return IntRect(); | 910 return IntRect(); |
895 | 911 |
896 const IntRect& scrollCorner = scrollCornerRect(); | 912 const IntRect& scrollCorner = scrollCornerRect(); |
897 | 913 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 if (hasVerticalScrollbar() && verticalScrollbar()->isCustomScrollbar()) { | 1011 if (hasVerticalScrollbar() && verticalScrollbar()->isCustomScrollbar()) { |
996 if (actualLayoutObject != toLayoutScrollbar(verticalScrollbar())->owning
LayoutObject()) | 1012 if (actualLayoutObject != toLayoutScrollbar(verticalScrollbar())->owning
LayoutObject()) |
997 didCustomScrollbarOwnerChanged = true; | 1013 didCustomScrollbarOwnerChanged = true; |
998 } | 1014 } |
999 | 1015 |
1000 return hasAnyScrollbar && ((shouldUseCustom != hasCustom) || (shouldUseCusto
m && didCustomScrollbarOwnerChanged)); | 1016 return hasAnyScrollbar && ((shouldUseCustom != hasCustom) || (shouldUseCusto
m && didCustomScrollbarOwnerChanged)); |
1001 } | 1017 } |
1002 | 1018 |
1003 void PaintLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar) | 1019 void PaintLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar) |
1004 { | 1020 { |
| 1021 if (FreezeScrollbarsScope::scrollbarsAreFrozen()) |
| 1022 return; |
| 1023 |
1005 if (hasScrollbar == hasHorizontalScrollbar()) | 1024 if (hasScrollbar == hasHorizontalScrollbar()) |
1006 return; | 1025 return; |
1007 | 1026 |
1008 setScrollbarNeedsPaintInvalidation(HorizontalScrollbar); | 1027 setScrollbarNeedsPaintInvalidation(HorizontalScrollbar); |
1009 | 1028 |
1010 m_scrollbarManager.setHasHorizontalScrollbar(hasScrollbar); | 1029 m_scrollbarManager.setHasHorizontalScrollbar(hasScrollbar, !m_inOverflowRela
yout); |
| 1030 |
| 1031 updateScrollOrigin(); |
1011 | 1032 |
1012 // Destroying or creating one bar can cause our scrollbar corner to come and
go. We need to update the opposite scrollbar's style. | 1033 // Destroying or creating one bar can cause our scrollbar corner to come and
go. We need to update the opposite scrollbar's style. |
1013 if (hasHorizontalScrollbar()) | 1034 if (hasHorizontalScrollbar()) |
1014 horizontalScrollbar()->styleChanged(); | 1035 horizontalScrollbar()->styleChanged(); |
1015 if (hasVerticalScrollbar()) | 1036 if (hasVerticalScrollbar()) |
1016 verticalScrollbar()->styleChanged(); | 1037 verticalScrollbar()->styleChanged(); |
1017 | 1038 |
1018 setScrollCornerNeedsPaintInvalidation(); | 1039 setScrollCornerNeedsPaintInvalidation(); |
1019 | 1040 |
1020 // Force an update since we know the scrollbars have changed things. | 1041 // Force an update since we know the scrollbars have changed things. |
1021 if (box().document().hasAnnotatedRegions()) | 1042 if (box().document().hasAnnotatedRegions()) |
1022 box().document().setAnnotatedRegionsDirty(true); | 1043 box().document().setAnnotatedRegionsDirty(true); |
1023 } | 1044 } |
1024 | 1045 |
1025 void PaintLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar) | 1046 void PaintLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar) |
1026 { | 1047 { |
| 1048 if (FreezeScrollbarsScope::scrollbarsAreFrozen()) |
| 1049 return; |
| 1050 |
1027 if (hasScrollbar == hasVerticalScrollbar()) | 1051 if (hasScrollbar == hasVerticalScrollbar()) |
1028 return; | 1052 return; |
1029 | 1053 |
1030 setScrollbarNeedsPaintInvalidation(VerticalScrollbar); | 1054 setScrollbarNeedsPaintInvalidation(VerticalScrollbar); |
1031 | 1055 |
1032 m_scrollbarManager.setHasVerticalScrollbar(hasScrollbar); | 1056 m_scrollbarManager.setHasVerticalScrollbar(hasScrollbar, !m_inOverflowRelayo
ut); |
| 1057 |
| 1058 updateScrollOrigin(); |
1033 | 1059 |
1034 // Destroying or creating one bar can cause our scrollbar corner to come and
go. We need to update the opposite scrollbar's style. | 1060 // Destroying or creating one bar can cause our scrollbar corner to come and
go. We need to update the opposite scrollbar's style. |
1035 if (hasHorizontalScrollbar()) | 1061 if (hasHorizontalScrollbar()) |
1036 horizontalScrollbar()->styleChanged(); | 1062 horizontalScrollbar()->styleChanged(); |
1037 if (hasVerticalScrollbar()) | 1063 if (hasVerticalScrollbar()) |
1038 verticalScrollbar()->styleChanged(); | 1064 verticalScrollbar()->styleChanged(); |
1039 | 1065 |
1040 setScrollCornerNeedsPaintInvalidation(); | 1066 setScrollCornerNeedsPaintInvalidation(); |
1041 | 1067 |
1042 // Force an update since we know the scrollbars have changed things. | 1068 // Force an update since we know the scrollbars have changed things. |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1493 { | 1519 { |
1494 if (LocalFrame* frame = box().frame()) { | 1520 if (LocalFrame* frame = box().frame()) { |
1495 if (Page* page = frame->page()) | 1521 if (Page* page = frame->page()) |
1496 return page->scrollingCoordinator() ? page->scrollingCoordinator()->
compositorAnimationTimeline() : nullptr; | 1522 return page->scrollingCoordinator() ? page->scrollingCoordinator()->
compositorAnimationTimeline() : nullptr; |
1497 } | 1523 } |
1498 return nullptr; | 1524 return nullptr; |
1499 } | 1525 } |
1500 | 1526 |
1501 PaintLayerScrollableArea::ScrollbarManager::ScrollbarManager(PaintLayerScrollabl
eArea& scrollableArea) | 1527 PaintLayerScrollableArea::ScrollbarManager::ScrollbarManager(PaintLayerScrollabl
eArea& scrollableArea) |
1502 : m_scrollableArea(&scrollableArea) | 1528 : m_scrollableArea(&scrollableArea) |
1503 , m_canDetachScrollbars(0) | |
1504 , m_hBarIsAttached(0) | 1529 , m_hBarIsAttached(0) |
1505 , m_vBarIsAttached(0) | 1530 , m_vBarIsAttached(0) |
1506 { | 1531 { |
1507 } | 1532 } |
1508 | 1533 |
1509 void PaintLayerScrollableArea::ScrollbarManager::dispose() | 1534 void PaintLayerScrollableArea::ScrollbarManager::dispose() |
1510 { | 1535 { |
1511 m_canDetachScrollbars = m_hBarIsAttached = m_vBarIsAttached = 0; | 1536 m_hBarIsAttached = m_vBarIsAttached = 0; |
1512 destroyScrollbar(HorizontalScrollbar); | 1537 destroyScrollbar(HorizontalScrollbar); |
1513 destroyScrollbar(VerticalScrollbar); | 1538 destroyScrollbar(VerticalScrollbar); |
1514 } | 1539 } |
1515 | 1540 |
1516 void PaintLayerScrollableArea::ScrollbarManager::setCanDetachScrollbars(bool det
ach) | 1541 void PaintLayerScrollableArea::ScrollbarManager::destroyDetachedScrollbars() |
1517 { | 1542 { |
1518 ASSERT(!m_hBarIsAttached || m_hBar); | 1543 ASSERT(!m_hBarIsAttached || m_hBar); |
1519 ASSERT(!m_vBarIsAttached || m_vBar); | 1544 ASSERT(!m_vBarIsAttached || m_vBar); |
1520 m_canDetachScrollbars = detach ? 1 : 0; | 1545 if (m_hBar && !m_hBarIsAttached) |
1521 if (!detach) { | 1546 destroyScrollbar(HorizontalScrollbar); |
1522 if (m_hBar && !m_hBarIsAttached) | 1547 if (m_vBar && !m_vBarIsAttached) |
1523 destroyScrollbar(HorizontalScrollbar); | 1548 destroyScrollbar(VerticalScrollbar); |
1524 if (m_vBar && !m_vBarIsAttached) | |
1525 destroyScrollbar(VerticalScrollbar); | |
1526 } | |
1527 } | 1549 } |
1528 | 1550 |
1529 void PaintLayerScrollableArea::ScrollbarManager::setHasHorizontalScrollbar(bool
hasScrollbar) | 1551 void PaintLayerScrollableArea::ScrollbarManager::setHasHorizontalScrollbar(bool
hasScrollbar, bool canDetach) |
1530 { | 1552 { |
1531 if (hasScrollbar) { | 1553 if (hasScrollbar) { |
1532 // This doesn't hit in any tests, but since the equivalent code in setHa
sVerticalScrollbar | 1554 // This doesn't hit in any tests, but since the equivalent code in setHa
sVerticalScrollbar |
1533 // does, presumably this code does as well. | 1555 // does, presumably this code does as well. |
1534 DisableCompositingQueryAsserts disabler; | 1556 DisableCompositingQueryAsserts disabler; |
1535 if (!m_hBar) { | 1557 if (!m_hBar) { |
1536 m_hBar = createScrollbar(HorizontalScrollbar); | 1558 m_hBar = createScrollbar(HorizontalScrollbar); |
1537 m_hBarIsAttached = 1; | 1559 m_hBarIsAttached = 1; |
1538 if (!m_hBar->isCustomScrollbar()) | 1560 if (!m_hBar->isCustomScrollbar()) |
1539 m_scrollableArea->didAddScrollbar(*m_hBar, HorizontalScrollbar); | 1561 m_scrollableArea->didAddScrollbar(*m_hBar, HorizontalScrollbar); |
1540 } else { | 1562 } else { |
1541 m_hBarIsAttached = 1; | 1563 m_hBarIsAttached = 1; |
1542 } | 1564 } |
1543 | |
1544 } else { | 1565 } else { |
1545 m_hBarIsAttached = 0; | 1566 m_hBarIsAttached = 0; |
1546 if (!m_canDetachScrollbars) | 1567 if (!canDetach) |
1547 destroyScrollbar(HorizontalScrollbar); | 1568 destroyScrollbar(HorizontalScrollbar); |
1548 } | 1569 } |
1549 } | 1570 } |
1550 | 1571 |
1551 void PaintLayerScrollableArea::ScrollbarManager::setHasVerticalScrollbar(bool ha
sScrollbar) | 1572 void PaintLayerScrollableArea::ScrollbarManager::setHasVerticalScrollbar(bool ha
sScrollbar, bool canDetach) |
1552 { | 1573 { |
1553 if (hasScrollbar) { | 1574 if (hasScrollbar) { |
1554 DisableCompositingQueryAsserts disabler; | 1575 DisableCompositingQueryAsserts disabler; |
1555 if (!m_vBar) { | 1576 if (!m_vBar) { |
1556 m_vBar = createScrollbar(VerticalScrollbar); | 1577 m_vBar = createScrollbar(VerticalScrollbar); |
1557 m_vBarIsAttached = 1; | 1578 m_vBarIsAttached = 1; |
1558 if (!m_vBar->isCustomScrollbar()) | 1579 if (!m_vBar->isCustomScrollbar()) |
1559 m_scrollableArea->didAddScrollbar(*m_vBar, VerticalScrollbar); | 1580 m_scrollableArea->didAddScrollbar(*m_vBar, VerticalScrollbar); |
1560 } else { | 1581 } else { |
1561 m_vBarIsAttached = 1; | 1582 m_vBarIsAttached = 1; |
1562 } | 1583 } |
1563 | |
1564 } else { | 1584 } else { |
1565 m_vBarIsAttached = 0; | 1585 m_vBarIsAttached = 0; |
1566 if (!m_canDetachScrollbars) | 1586 if (!canDetach) |
1567 destroyScrollbar(VerticalScrollbar); | 1587 destroyScrollbar(VerticalScrollbar); |
1568 } | 1588 } |
1569 } | 1589 } |
1570 | 1590 |
1571 Scrollbar* PaintLayerScrollableArea::ScrollbarManager::createScrollbar(Scrollbar
Orientation orientation) | 1591 Scrollbar* PaintLayerScrollableArea::ScrollbarManager::createScrollbar(Scrollbar
Orientation orientation) |
1572 { | 1592 { |
1573 ASSERT(orientation == HorizontalScrollbar ? !m_hBarIsAttached : !m_vBarIsAtt
ached); | 1593 ASSERT(orientation == HorizontalScrollbar ? !m_hBarIsAttached : !m_vBarIsAtt
ached); |
1574 Scrollbar* scrollbar = nullptr; | 1594 Scrollbar* scrollbar = nullptr; |
1575 const LayoutObject& actualLayoutObject = layoutObjectForScrollbar(m_scrollab
leArea->box()); | 1595 const LayoutObject& actualLayoutObject = layoutObjectForScrollbar(m_scrollab
leArea->box()); |
1576 bool hasCustomScrollbarStyle = actualLayoutObject.isBox() && actualLayoutObj
ect.styleRef().hasPseudoStyle(PseudoIdScrollbar); | 1596 bool hasCustomScrollbarStyle = actualLayoutObject.isBox() && actualLayoutObj
ect.styleRef().hasPseudoStyle(PseudoIdScrollbar); |
(...skipping 30 matching lines...) Expand all Loading... |
1607 scrollbar = nullptr; | 1627 scrollbar = nullptr; |
1608 } | 1628 } |
1609 | 1629 |
1610 DEFINE_TRACE(PaintLayerScrollableArea::ScrollbarManager) | 1630 DEFINE_TRACE(PaintLayerScrollableArea::ScrollbarManager) |
1611 { | 1631 { |
1612 visitor->trace(m_scrollableArea); | 1632 visitor->trace(m_scrollableArea); |
1613 visitor->trace(m_hBar); | 1633 visitor->trace(m_hBar); |
1614 visitor->trace(m_vBar); | 1634 visitor->trace(m_vBar); |
1615 } | 1635 } |
1616 | 1636 |
| 1637 int PaintLayerScrollableArea::PreventRelayoutScope::m_count = 0; |
| 1638 SubtreeLayoutScope* PaintLayerScrollableArea::PreventRelayoutScope::m_layoutScop
e = nullptr; |
| 1639 bool PaintLayerScrollableArea::PreventRelayoutScope::m_relayoutNeeded = false; |
| 1640 WTF::Vector<LayoutObject*>* PaintLayerScrollableArea::PreventRelayoutScope::m_ne
edsRelayout = nullptr; |
| 1641 |
| 1642 PaintLayerScrollableArea::PreventRelayoutScope::PreventRelayoutScope(SubtreeLayo
utScope& layoutScope) |
| 1643 { |
| 1644 if (!m_count) { |
| 1645 ASSERT(!m_layoutScope); |
| 1646 ASSERT(!m_needsRelayout || m_needsRelayout->isEmpty()); |
| 1647 m_layoutScope = &layoutScope; |
| 1648 } |
| 1649 PreventRelayoutScope::increment(); |
| 1650 } |
| 1651 |
| 1652 PaintLayerScrollableArea::PreventRelayoutScope::~PreventRelayoutScope() |
| 1653 { |
| 1654 PreventRelayoutScope::decrement(); |
| 1655 } |
| 1656 |
| 1657 void PaintLayerScrollableArea::PreventRelayoutScope::increment() |
| 1658 { |
| 1659 ASSERT(m_count == 0 || m_layoutScope); |
| 1660 m_count++; |
| 1661 } |
| 1662 |
| 1663 void PaintLayerScrollableArea::PreventRelayoutScope::decrement() |
| 1664 { |
| 1665 if (--m_count == 0) { |
| 1666 if (m_relayoutNeeded) { |
| 1667 for (auto layoutObject : *m_needsRelayout) |
| 1668 m_layoutScope->setNeedsLayout(layoutObject, LayoutInvalidationRe
ason::ScrollbarChanged); |
| 1669 m_needsRelayout->clear(); |
| 1670 } |
| 1671 m_layoutScope = nullptr; |
| 1672 } |
| 1673 } |
| 1674 |
| 1675 void PaintLayerScrollableArea::PreventRelayoutScope::setNeedsLayout(LayoutObject
& layoutObject) |
| 1676 { |
| 1677 ASSERT(m_count); |
| 1678 ASSERT(m_layoutScope); |
| 1679 m_relayoutNeeded = true; |
| 1680 if (!m_needsRelayout) |
| 1681 m_needsRelayout = new WTF::Vector<LayoutObject*>(); |
| 1682 m_needsRelayout->append(&layoutObject); |
| 1683 } |
| 1684 |
| 1685 void PaintLayerScrollableArea::PreventRelayoutScope::resetRelayoutNeeded() |
| 1686 { |
| 1687 ASSERT(m_count == 0); |
| 1688 if (m_needsRelayout) |
| 1689 m_needsRelayout->clear(); |
| 1690 m_relayoutNeeded = false; |
| 1691 } |
| 1692 |
| 1693 int PaintLayerScrollableArea::FreezeScrollbarsScope::m_count = 0; |
| 1694 |
| 1695 int PaintLayerScrollableArea::DelayScrollPositionClampScope::m_count = 0; |
| 1696 PersistentHeapVector<Member<PaintLayerScrollableArea>>* PaintLayerScrollableArea
::DelayScrollPositionClampScope::m_needsClamp = nullptr; |
| 1697 |
| 1698 PaintLayerScrollableArea::DelayScrollPositionClampScope::DelayScrollPositionClam
pScope() |
| 1699 { |
| 1700 if (!m_needsClamp) |
| 1701 m_needsClamp = new PersistentHeapVector<Member<PaintLayerScrollableArea>
>(); |
| 1702 ASSERT(m_count > 0 || m_needsClamp->isEmpty()); |
| 1703 DelayScrollPositionClampScope::increment(); |
| 1704 } |
| 1705 |
| 1706 PaintLayerScrollableArea::DelayScrollPositionClampScope::~DelayScrollPositionCla
mpScope() |
| 1707 { |
| 1708 DelayScrollPositionClampScope::decrement(); |
| 1709 } |
| 1710 |
| 1711 void PaintLayerScrollableArea::DelayScrollPositionClampScope::increment() |
| 1712 { |
| 1713 m_count++; |
| 1714 } |
| 1715 |
| 1716 void PaintLayerScrollableArea::DelayScrollPositionClampScope::decrement() |
| 1717 { |
| 1718 if (--m_count == 0) |
| 1719 DelayScrollPositionClampScope::clampScrollableAreas(); |
| 1720 } |
| 1721 |
| 1722 void PaintLayerScrollableArea::DelayScrollPositionClampScope::setNeedsClamp(Pain
tLayerScrollableArea* scrollableArea) |
| 1723 { |
| 1724 if (!scrollableArea->needsScrollPositionClamp()) { |
| 1725 scrollableArea->setNeedsScrollPositionClamp(true); |
| 1726 m_needsClamp->append(scrollableArea); |
| 1727 } |
| 1728 } |
| 1729 |
| 1730 void PaintLayerScrollableArea::DelayScrollPositionClampScope::clampScrollableAre
as() |
| 1731 { |
| 1732 for (auto& scrollableArea : *m_needsClamp) |
| 1733 scrollableArea->clampScrollPositionsAfterLayout(); |
| 1734 delete m_needsClamp; |
| 1735 m_needsClamp = nullptr; |
| 1736 } |
| 1737 |
1617 } // namespace blink | 1738 } // namespace blink |
OLD | NEW |