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