| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 7 * Copyright (C) 2010 Google Inc. All rights reserved. | 7 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 #include "core/layout/LayoutGeometryMap.h" | 34 #include "core/layout/LayoutGeometryMap.h" |
| 35 #include "core/layout/LayoutInline.h" | 35 #include "core/layout/LayoutInline.h" |
| 36 #include "core/layout/LayoutTheme.h" | 36 #include "core/layout/LayoutTheme.h" |
| 37 #include "core/layout/LayoutView.h" | 37 #include "core/layout/LayoutView.h" |
| 38 #include "core/layout/compositing/CompositedLayerMapping.h" | 38 #include "core/layout/compositing/CompositedLayerMapping.h" |
| 39 #include "core/layout/compositing/PaintLayerCompositor.h" | 39 #include "core/layout/compositing/PaintLayerCompositor.h" |
| 40 #include "core/paint/ObjectPaintInvalidator.h" | 40 #include "core/paint/ObjectPaintInvalidator.h" |
| 41 #include "core/paint/PaintLayer.h" | 41 #include "core/paint/PaintLayer.h" |
| 42 #include "core/style/ShadowList.h" | 42 #include "core/style/ShadowList.h" |
| 43 #include "platform/LengthFunctions.h" | 43 #include "platform/LengthFunctions.h" |
| 44 #include "platform/geometry/TransformState.h" |
| 44 #include "wtf/PtrUtil.h" | 45 #include "wtf/PtrUtil.h" |
| 45 | 46 |
| 46 namespace blink { | 47 namespace blink { |
| 47 | 48 |
| 48 class FloatStateForStyleChange { | 49 class FloatStateForStyleChange { |
| 49 public: | 50 public: |
| 50 static void setWasFloating(LayoutBoxModelObject* boxModelObject, bool wasFlo
ating) | 51 static void setWasFloating(LayoutBoxModelObject* boxModelObject, bool wasFlo
ating) |
| 51 { | 52 { |
| 52 s_wasFloating = wasFloating; | 53 s_wasFloating = wasFloating; |
| 53 s_boxModelObject = boxModelObject; | 54 s_boxModelObject = boxModelObject; |
| (...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 StickyPositionScrollingConstraints constraints; | 687 StickyPositionScrollingConstraints constraints; |
| 687 FloatSize skippedContainersOffset; | 688 FloatSize skippedContainersOffset; |
| 688 LayoutBlock* containingBlock = this->containingBlock(); | 689 LayoutBlock* containingBlock = this->containingBlock(); |
| 689 // Skip anonymous containing blocks. | 690 // Skip anonymous containing blocks. |
| 690 while (containingBlock->isAnonymous()) { | 691 while (containingBlock->isAnonymous()) { |
| 691 skippedContainersOffset += toFloatSize(FloatPoint(containingBlock->frame
Rect().location())); | 692 skippedContainersOffset += toFloatSize(FloatPoint(containingBlock->frame
Rect().location())); |
| 692 containingBlock = containingBlock->containingBlock(); | 693 containingBlock = containingBlock->containingBlock(); |
| 693 } | 694 } |
| 694 LayoutBox* scrollAncestor = layer()->ancestorOverflowLayer()->isRootLayer()
? nullptr : toLayoutBox(layer()->ancestorOverflowLayer()->layoutObject()); | 695 LayoutBox* scrollAncestor = layer()->ancestorOverflowLayer()->isRootLayer()
? nullptr : toLayoutBox(layer()->ancestorOverflowLayer()->layoutObject()); |
| 695 | 696 |
| 696 LayoutRect containerContentRect = containingBlock->layoutOverflowRect(); | |
| 697 LayoutUnit maxContainerWidth = containingBlock->isLayoutView() ? containingB
lock->logicalWidth() : containingBlock->containingBlockLogicalWidthForContent(); | 697 LayoutUnit maxContainerWidth = containingBlock->isLayoutView() ? containingB
lock->logicalWidth() : containingBlock->containingBlockLogicalWidthForContent(); |
| 698 // Sticky positioned element ignore any override logical width on the contai
ning block (as they don't call | 698 // Sticky positioned element ignore any override logical width on the contai
ning block (as they don't call |
| 699 // containingBlockLogicalWidthForContent). It's unclear whether this is tota
lly fine. | 699 // containingBlockLogicalWidthForContent). It's unclear whether this is tota
lly fine. |
| 700 // Compute the container-relative area within which the sticky element is al
lowed to move. | 700 // Compute the container-relative area within which the sticky element is al
lowed to move. |
| 701 LayoutUnit maxWidth = containingBlock->availableLogicalWidth(); | 701 LayoutUnit maxWidth = containingBlock->availableLogicalWidth(); |
| 702 | 702 |
| 703 // Map the containing block to the scroll ancestor without transforms. |
| 704 FloatRect scrollContainerRelativePaddingBoxRect(containingBlock->layoutOverf
lowRect()); |
| 705 if (containingBlock != scrollAncestor) { |
| 706 FloatQuad localQuad(FloatRect(containingBlock->paddingBoxRect())); |
| 707 TransformState transformState(TransformState::ApplyTransformDirection, l
ocalQuad.boundingBox().center(), localQuad); |
| 708 containingBlock->mapLocalToAncestor(scrollAncestor, transformState, Appl
yContainerFlip); |
| 709 transformState.flatten(); |
| 710 scrollContainerRelativePaddingBoxRect = transformState.lastPlanarQuad().
boundingBox(); |
| 711 |
| 712 // The sticky position constraint rects should be independent of the cur
rent scroll position, so after |
| 713 // mapping we add in the scroll position to get the container's position
within the ancestor scroller's |
| 714 // unscrolled layout overflow. |
| 715 FloatSize scrollOffset(scrollAncestor ? toFloatSize(scrollAncestor->getS
crollableArea()->adjustedScrollOffset()) : FloatSize()); |
| 716 scrollContainerRelativePaddingBoxRect.move(scrollOffset); |
| 717 } |
| 718 |
| 719 LayoutRect scrollContainerRelativeContainingBlockRect(scrollContainerRelativ
ePaddingBoxRect); |
| 703 // This is removing the padding of the containing block's overflow rect to g
et the flow | 720 // This is removing the padding of the containing block's overflow rect to g
et the flow |
| 704 // box rectangle and removing the margin of the sticky element to ensure tha
t space between | 721 // box rectangle and removing the margin of the sticky element to ensure tha
t space between |
| 705 // the sticky element and its containing flow box. It is an open issue wheth
er the margin | 722 // the sticky element and its containing flow box. It is an open issue wheth
er the margin |
| 706 // should collapse (See https://www.w3.org/TR/css-position-3/#sticky-pos). | 723 // should collapse (See https://www.w3.org/TR/css-position-3/#sticky-pos). |
| 707 containerContentRect.contractEdges( | 724 scrollContainerRelativeContainingBlockRect.contractEdges( |
| 708 minimumValueForLength(containingBlock->style()->paddingTop(), maxContain
erWidth) + minimumValueForLength(style()->marginTop(), maxWidth), | 725 minimumValueForLength(containingBlock->style()->paddingTop(), maxContain
erWidth) + minimumValueForLength(style()->marginTop(), maxWidth), |
| 709 minimumValueForLength(containingBlock->style()->paddingRight(), maxConta
inerWidth) + minimumValueForLength(style()->marginRight(), maxWidth), | 726 minimumValueForLength(containingBlock->style()->paddingRight(), maxConta
inerWidth) + minimumValueForLength(style()->marginRight(), maxWidth), |
| 710 minimumValueForLength(containingBlock->style()->paddingBottom(), maxCont
ainerWidth) + minimumValueForLength(style()->marginBottom(), maxWidth), | 727 minimumValueForLength(containingBlock->style()->paddingBottom(), maxCont
ainerWidth) + minimumValueForLength(style()->marginBottom(), maxWidth), |
| 711 minimumValueForLength(containingBlock->style()->paddingLeft(), maxContai
nerWidth) + minimumValueForLength(style()->marginLeft(), maxWidth)); | 728 minimumValueForLength(containingBlock->style()->paddingLeft(), maxContai
nerWidth) + minimumValueForLength(style()->marginLeft(), maxWidth)); |
| 712 | 729 |
| 713 // Map to the scroll ancestor. | 730 constraints.setScrollContainerRelativeContainingBlockRect(FloatRect(scrollCo
ntainerRelativeContainingBlockRect)); |
| 714 FloatRect scrollContainerRelativeContainingBlockRect(containingBlock->localT
oAncestorQuad(FloatRect(containerContentRect), scrollAncestor).boundingBox()); | |
| 715 FloatSize scrollOffset(scrollAncestor ? toFloatSize(scrollAncestor->getScrol
lableArea()->adjustedScrollOffset()) : FloatSize()); | |
| 716 | |
| 717 // The sticky position constraint rects should be independent of the current
scroll position, so after | |
| 718 // mapping we add in the scroll position to get the container's position wit
hin the ancestor scroller's | |
| 719 // unscrolled layout overflow. | |
| 720 if (containingBlock != scrollAncestor) | |
| 721 scrollContainerRelativeContainingBlockRect.move(scrollOffset); | |
| 722 constraints.setScrollContainerRelativeContainingBlockRect(scrollContainerRel
ativeContainingBlockRect); | |
| 723 | 731 |
| 724 FloatRect stickyBoxRect = isLayoutInline() | 732 FloatRect stickyBoxRect = isLayoutInline() |
| 725 ? FloatRect(toLayoutInline(this)->linesBoundingBox()) | 733 ? FloatRect(toLayoutInline(this)->linesBoundingBox()) |
| 726 : FloatRect(toLayoutBox(this)->frameRect()); | 734 : FloatRect(toLayoutBox(this)->frameRect()); |
| 727 FloatRect flippedStickyBoxRect = stickyBoxRect; | 735 FloatRect flippedStickyBoxRect = stickyBoxRect; |
| 728 containingBlock->flipForWritingMode(flippedStickyBoxRect); | 736 containingBlock->flipForWritingMode(flippedStickyBoxRect); |
| 729 FloatPoint stickyLocation = flippedStickyBoxRect.location() + skippedContain
ersOffset; | 737 FloatPoint stickyLocation = flippedStickyBoxRect.location() + skippedContain
ersOffset; |
| 730 | 738 |
| 731 // TODO(flackr): Unfortunate to call localToAncestorQuad again, but we can't
just offset from the previously computed rect if there are transforms. | 739 // The scrollContainerRelativePaddingBoxRect's position is the padding box s
o we need to remove the border when finding |
| 732 // Map to the scroll ancestor. | 740 // the position of the sticky box within the scroll ancestor if the containe
r is not our scroll ancestor. |
| 733 FloatRect scrollContainerRelativeContainerFrame = containingBlock->localToAn
cestorQuad(FloatRect(FloatPoint(), FloatSize(containingBlock->size())), scrollAn
cestor).boundingBox(); | 741 if (containingBlock != scrollAncestor) { |
| 734 // The sticky position constraint rects should be independent of the current
scroll position, so after | 742 FloatSize containerBorderOffset(containingBlock->borderLeft(), containin
gBlock->borderTop()); |
| 735 // mapping we add in the scroll position to get the container's position wit
hin the ancestor scroller's | 743 stickyLocation -= containerBorderOffset; |
| 736 // unscrolled layout overflow. | 744 } |
| 737 if (containingBlock != scrollAncestor) | 745 constraints.setScrollContainerRelativeStickyBoxRect(FloatRect(scrollContaine
rRelativePaddingBoxRect.location() + toFloatSize(stickyLocation), flippedStickyB
oxRect.size())); |
| 738 scrollContainerRelativeContainerFrame.move(scrollOffset); | |
| 739 | |
| 740 constraints.setScrollContainerRelativeStickyBoxRect(FloatRect(scrollContaine
rRelativeContainerFrame.location() + toFloatSize(stickyLocation), flippedStickyB
oxRect.size())); | |
| 741 | 746 |
| 742 // We skip the right or top sticky offset if there is not enough space to ho
nor both the left/right or top/bottom offsets. | 747 // We skip the right or top sticky offset if there is not enough space to ho
nor both the left/right or top/bottom offsets. |
| 743 LayoutUnit horizontalOffsets = minimumValueForLength(style()->right(), Layou
tUnit(constrainingSize.width())) + | 748 LayoutUnit horizontalOffsets = minimumValueForLength(style()->right(), Layou
tUnit(constrainingSize.width())) + |
| 744 minimumValueForLength(style()->left(), LayoutUnit(constrainingSize.width
())); | 749 minimumValueForLength(style()->left(), LayoutUnit(constrainingSize.width
())); |
| 745 bool skipRight = false; | 750 bool skipRight = false; |
| 746 bool skipLeft = false; | 751 bool skipLeft = false; |
| 747 if (!style()->left().isAuto() && !style()->right().isAuto()) { | 752 if (!style()->left().isAuto() && !style()->right().isAuto()) { |
| 748 if (horizontalOffsets > containerContentRect.width() | 753 if (horizontalOffsets > scrollContainerRelativeContainingBlockRect.width
() |
| 749 || horizontalOffsets + containerContentRect.width() > constrainingSi
ze.width()) { | 754 || horizontalOffsets + scrollContainerRelativeContainingBlockRect.wi
dth() > constrainingSize.width()) { |
| 750 skipRight = style()->isLeftToRightDirection(); | 755 skipRight = style()->isLeftToRightDirection(); |
| 751 skipLeft = !skipRight; | 756 skipLeft = !skipRight; |
| 752 } | 757 } |
| 753 } | 758 } |
| 754 | 759 |
| 755 if (!style()->left().isAuto() && !skipLeft) { | 760 if (!style()->left().isAuto() && !skipLeft) { |
| 756 constraints.setLeftOffset(minimumValueForLength(style()->left(), LayoutU
nit(constrainingSize.width()))); | 761 constraints.setLeftOffset(minimumValueForLength(style()->left(), LayoutU
nit(constrainingSize.width()))); |
| 757 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge
Left); | 762 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge
Left); |
| 758 } | 763 } |
| 759 | 764 |
| 760 if (!style()->right().isAuto() && !skipRight) { | 765 if (!style()->right().isAuto() && !skipRight) { |
| 761 constraints.setRightOffset(minimumValueForLength(style()->right(), Layou
tUnit(constrainingSize.width()))); | 766 constraints.setRightOffset(minimumValueForLength(style()->right(), Layou
tUnit(constrainingSize.width()))); |
| 762 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge
Right); | 767 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge
Right); |
| 763 } | 768 } |
| 764 | 769 |
| 765 bool skipBottom = false; | 770 bool skipBottom = false; |
| 766 // TODO(flackr): Exclude top or bottom edge offset depending on the writing
mode when related | 771 // TODO(flackr): Exclude top or bottom edge offset depending on the writing
mode when related |
| 767 // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style
/2014May/0286.html | 772 // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style
/2014May/0286.html |
| 768 LayoutUnit verticalOffsets = minimumValueForLength(style()->top(), LayoutUni
t(constrainingSize.height())) + | 773 LayoutUnit verticalOffsets = minimumValueForLength(style()->top(), LayoutUni
t(constrainingSize.height())) + |
| 769 minimumValueForLength(style()->bottom(), LayoutUnit(constrainingSize.hei
ght())); | 774 minimumValueForLength(style()->bottom(), LayoutUnit(constrainingSize.hei
ght())); |
| 770 if (!style()->top().isAuto() && !style()->bottom().isAuto()) { | 775 if (!style()->top().isAuto() && !style()->bottom().isAuto()) { |
| 771 if (verticalOffsets > containerContentRect.height() | 776 if (verticalOffsets > scrollContainerRelativeContainingBlockRect.height(
) |
| 772 || verticalOffsets + containerContentRect.height() > constrainingSiz
e.height()) { | 777 || verticalOffsets + scrollContainerRelativeContainingBlockRect.heig
ht() > constrainingSize.height()) { |
| 773 skipBottom = true; | 778 skipBottom = true; |
| 774 } | 779 } |
| 775 } | 780 } |
| 776 | 781 |
| 777 if (!style()->top().isAuto()) { | 782 if (!style()->top().isAuto()) { |
| 778 constraints.setTopOffset(minimumValueForLength(style()->top(), LayoutUni
t(constrainingSize.height()))); | 783 constraints.setTopOffset(minimumValueForLength(style()->top(), LayoutUni
t(constrainingSize.height()))); |
| 779 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge
Top); | 784 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge
Top); |
| 780 } | 785 } |
| 781 | 786 |
| 782 if (!style()->bottom().isAuto() && !skipBottom) { | 787 if (!style()->bottom().isAuto() && !skipBottom) { |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 if (rootElementStyle->hasBackground()) | 1188 if (rootElementStyle->hasBackground()) |
| 1184 return false; | 1189 return false; |
| 1185 | 1190 |
| 1186 if (node() != document().firstBodyElement()) | 1191 if (node() != document().firstBodyElement()) |
| 1187 return false; | 1192 return false; |
| 1188 | 1193 |
| 1189 return true; | 1194 return true; |
| 1190 } | 1195 } |
| 1191 | 1196 |
| 1192 } // namespace blink | 1197 } // namespace blink |
| OLD | NEW |