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); | |
eae
2016/06/02 22:57:25
It's a bit weird that InlineBox::flipForWritingMod
szager1
2016/06/03 22:33:11
Done.
| |
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 newScrollPosition = clampScrollPosition(scrollPositionDouble()); | |
eae
2016/06/02 22:57:25
clampedScrollPosition might be a better name?
szager1
2016/06/03 22:33:11
Done.
| |
757 if (newScrollPosition != scrollPositionDouble()) | |
758 ScrollableArea::setScrollPosition(newScrollPosition, ProgrammaticScroll) ; | |
759 else if (scrollOriginChanged()) | |
760 scrollPositionChanged(newScrollPosition, 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 |