Changeset 238077 in webkit
- Timestamp:
- Nov 11, 2018 1:29:12 PM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r238075 r238077 1 2018-11-11 Zalan Bujtas <zalan@apple.com> 2 3 [LFC][BFC] In-flow positioned logic is really formatting context dependent. 4 https://bugs.webkit.org/show_bug.cgi?id=191512 5 6 Reviewed by Simon Fraser. 7 8 Move block formatting context specific code from FormattingContext to BlockFormattingContext. 9 10 * layout/FormattingContext.cpp: 11 (WebCore::Layout::FormattingContext::placeInFlowPositionedChildren const): Deleted. 12 * layout/FormattingContext.h: 13 * layout/FormattingContextGeometry.cpp: 14 (WebCore::Layout::FormattingContext::Geometry::inFlowPositionedPositionOffset): 15 * layout/blockformatting/BlockFormattingContext.cpp: 16 (WebCore::Layout::BlockFormattingContext::placeInFlowPositionedChildren const): 17 (WebCore::Layout::BlockFormattingContext::computeInFlowPositionedPosition const): Deleted. 18 * layout/blockformatting/BlockFormattingContext.h: 19 * layout/blockformatting/BlockFormattingContextGeometry.cpp: 20 (WebCore::Layout::BlockFormattingContext::Geometry::inFlowPositionedPosition): Deleted. 21 * layout/inlineformatting/InlineFormattingContext.cpp: 22 (WebCore::Layout::InlineFormattingContext::computeInFlowPositionedPosition const): Deleted. 23 * layout/inlineformatting/InlineFormattingContext.h: 24 1 25 2018-11-11 Myles C. Maxfield <mmaxfield@apple.com> 2 26 -
trunk/Source/WebCore/layout/FormattingContext.cpp
r237729 r238077 131 131 } 132 132 133 void FormattingContext::placeInFlowPositionedChildren(const Container& container) const134 {135 // If this container also establishes a formatting context, then positioning already has happend in that the formatting context.136 if (container.establishesFormattingContext() && &container != &root())137 return;138 139 LOG_WITH_STREAM(FormattingContextLayout, stream << "Start: move in-flow positioned children -> parent: " << &container);140 for (auto& layoutBox : childrenOfType<Box>(container)) {141 if (!layoutBox.isInFlowPositioned())142 continue;143 computeInFlowPositionedPosition(layoutBox);144 }145 LOG_WITH_STREAM(FormattingContextLayout, stream << "End: move in-flow positioned children -> parent: " << &container);146 }147 148 133 void FormattingContext::layoutOutOfFlowDescendants(const Box& layoutBox) const 149 134 { -
trunk/Source/WebCore/layout/FormattingContext.h
r237782 r238077 71 71 72 72 virtual void computeStaticPosition(const Box&) const = 0; 73 virtual void computeInFlowPositionedPosition(const Box&) const = 0;74 73 75 74 void computeBorderAndPadding(const Box&) const; 76 77 void placeInFlowPositionedChildren(const Container&) const;78 75 79 76 #ifndef NDEBUG … … 93 90 static WidthAndMargin inlineReplacedWidthAndMargin(const LayoutState&, const Box&, std::optional<LayoutUnit> usedWidth = { }, 94 91 std::optional<LayoutUnit> precomputedMarginLeft = { }, std::optional<LayoutUnit> precomputedMarginRight = { }); 92 93 static LayoutSize inFlowPositionedPositionOffset(const LayoutState&, const Box&); 95 94 96 95 static HeightAndMargin complicatedCases(const LayoutState&, const Box&, std::optional<LayoutUnit> usedHeight = { }); -
trunk/Source/WebCore/layout/FormattingContextGeometry.cpp
r237783 r238077 948 948 } 949 949 950 LayoutSize FormattingContext::Geometry::inFlowPositionedPositionOffset(const LayoutState& layoutState, const Box& layoutBox) 951 { 952 ASSERT(layoutBox.isInFlowPositioned()); 953 954 // 9.4.3 Relative positioning 955 // 956 // The 'top' and 'bottom' properties move relatively positioned element(s) up or down without changing their size. 957 // Top' moves the boxes down, and 'bottom' moves them up. Since boxes are not split or stretched as a result of 'top' or 'bottom', the used values are always: top = -bottom. 958 // 959 // 1. If both are 'auto', their used values are both '0'. 960 // 2. If one of them is 'auto', it becomes the negative of the other. 961 // 3. If neither is 'auto', 'bottom' is ignored (i.e., the used value of 'bottom' will be minus the value of 'top'). 962 963 auto& style = layoutBox.style(); 964 auto& containingBlock = *layoutBox.containingBlock(); 965 auto containingBlockWidth = layoutState.displayBoxForLayoutBox(containingBlock).contentBoxWidth(); 966 967 auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth); 968 auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth); 969 970 if (!top && !bottom) { 971 // #1 972 top = bottom = { 0 }; 973 } else if (!top) { 974 // #2 975 top = -*bottom; 976 } else if (!bottom) { 977 // #3 978 bottom = -*top; 979 } else { 980 // #4 981 bottom = std::nullopt; 982 } 983 984 // For relatively positioned elements, 'left' and 'right' move the box(es) horizontally, without changing their size. 985 // 'Left' moves the boxes to the right, and 'right' moves them to the left. 986 // Since boxes are not split or stretched as a result of 'left' or 'right', the used values are always: left = -right. 987 // 988 // 1. If both 'left' and 'right' are 'auto' (their initial values), the used values are '0' (i.e., the boxes stay in their original position). 989 // 2. If 'left' is 'auto', its used value is minus the value of 'right' (i.e., the boxes move to the left by the value of 'right'). 990 // 3. If 'right' is specified as 'auto', its used value is minus the value of 'left'. 991 // 4. If neither 'left' nor 'right' is 'auto', the position is over-constrained, and one of them has to be ignored. 992 // If the 'direction' property of the containing block is 'ltr', the value of 'left' wins and 'right' becomes -'left'. 993 // If 'direction' of the containing block is 'rtl', 'right' wins and 'left' is ignored. 994 995 auto left = computedValueIfNotAuto(style.logicalLeft(), containingBlockWidth); 996 auto right = computedValueIfNotAuto(style.logicalRight(), containingBlockWidth); 997 998 if (!left && !right) { 999 // #1 1000 left = right = { 0 }; 1001 } else if (!left) { 1002 // #2 1003 left = -*right; 1004 } else if (!right) { 1005 // #3 1006 right = -*left; 1007 } else { 1008 // #4 1009 auto isLeftToRightDirection = containingBlock.style().isLeftToRightDirection(); 1010 if (isLeftToRightDirection) 1011 right = -*left; 1012 else 1013 left = std::nullopt; 1014 } 1015 1016 ASSERT(!bottom || *top == -*bottom); 1017 ASSERT(!left || *left == -*right); 1018 1019 auto topPositionOffset = *top; 1020 auto leftPositionOffset = left.value_or(-*right); 1021 1022 LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position] -> positioned inflow -> top offset(" << topPositionOffset << "px) left offset(" << leftPositionOffset << "px) layoutBox(" << &layoutBox << ")"); 1023 return { leftPositionOffset, topPositionOffset }; 1024 } 1025 950 1026 Edges FormattingContext::Geometry::computedBorder(const LayoutState&, const Box& layoutBox) 951 1027 { -
trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp
r237730 r238077 155 155 } 156 156 157 void BlockFormattingContext::placeInFlowPositionedChildren(const Container& container) const 158 { 159 LOG_WITH_STREAM(FormattingContextLayout, stream << "Start: move in-flow positioned children -> parent: " << &container); 160 for (auto& layoutBox : childrenOfType<Box>(container)) { 161 if (!layoutBox.isInFlowPositioned()) 162 continue; 163 164 auto computeInFlowPositionedPosition = [&](auto& layoutBox) { 165 auto& layoutState = this->layoutState(); 166 auto positionOffset = Geometry::inFlowPositionedPositionOffset(layoutState, layoutBox); 167 168 auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox); 169 auto topLeft = displayBox.topLeft(); 170 171 topLeft.move(positionOffset); 172 173 displayBox.setTopLeft(topLeft); 174 }; 175 176 computeInFlowPositionedPosition(layoutBox); 177 } 178 LOG_WITH_STREAM(FormattingContextLayout, stream << "End: move in-flow positioned children -> parent: " << &container); 179 } 180 157 181 void BlockFormattingContext::computeStaticPosition(const Box& layoutBox) const 158 182 { … … 275 299 } 276 300 277 void BlockFormattingContext::computeInFlowPositionedPosition(const Box& layoutBox) const278 {279 auto& layoutState = this->layoutState();280 layoutState.displayBoxForLayoutBox(layoutBox).setTopLeft(Geometry::inFlowPositionedPosition(layoutState, layoutBox));281 }282 283 301 void BlockFormattingContext::computeWidthAndMargin(const Box& layoutBox) const 284 302 { -
trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h
r237729 r238077 52 52 private: 53 53 void layoutFormattingContextRoot(FloatingContext&, const Box&) const; 54 void placeInFlowPositionedChildren(const Container&) const; 54 55 55 56 void computeWidthAndMargin(const Box&) const; … … 61 62 void computeVerticalPositionForFloatClear(const FloatingContext&, const Box&) const; 62 63 63 void computeInFlowPositionedPosition(const Box&) const override;64 64 void computeEstimatedMarginTopForAncestors(const Box&) const; 65 65 void computeEstimatedMarginTop(const Box&) const; … … 76 76 77 77 static Position staticPosition(const LayoutState&, const Box&); 78 static Position inFlowPositionedPosition(const LayoutState&, const Box&);79 78 80 79 static bool instrinsicWidthConstraintsNeedChildrenWidth(const Box&); -
trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp
r237782 r238077 288 288 } 289 289 290 Position BlockFormattingContext::Geometry::inFlowPositionedPosition(const LayoutState& layoutState, const Box& layoutBox)291 {292 ASSERT(layoutBox.isInFlowPositioned());293 294 // 9.4.3 Relative positioning295 //296 // The 'top' and 'bottom' properties move relatively positioned element(s) up or down without changing their size.297 // Top' moves the boxes down, and 'bottom' moves them up. Since boxes are not split or stretched as a result of 'top' or 'bottom', the used values are always: top = -bottom.298 //299 // 1. If both are 'auto', their used values are both '0'.300 // 2. If one of them is 'auto', it becomes the negative of the other.301 // 3. If neither is 'auto', 'bottom' is ignored (i.e., the used value of 'bottom' will be minus the value of 'top').302 303 auto& style = layoutBox.style();304 auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);305 auto& containingBlock = *layoutBox.containingBlock();306 auto containingBlockWidth = layoutState.displayBoxForLayoutBox(containingBlock).contentBoxWidth();307 308 auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);309 auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);310 311 if (!top && !bottom) {312 // #1313 top = bottom = { 0 };314 } else if (!top) {315 // #2316 top = -*bottom;317 } else if (!bottom) {318 // #3319 bottom = -*top;320 } else {321 // #4322 bottom = std::nullopt;323 }324 325 // For relatively positioned elements, 'left' and 'right' move the box(es) horizontally, without changing their size.326 // 'Left' moves the boxes to the right, and 'right' moves them to the left.327 // Since boxes are not split or stretched as a result of 'left' or 'right', the used values are always: left = -right.328 //329 // 1. If both 'left' and 'right' are 'auto' (their initial values), the used values are '0' (i.e., the boxes stay in their original position).330 // 2. If 'left' is 'auto', its used value is minus the value of 'right' (i.e., the boxes move to the left by the value of 'right').331 // 3. If 'right' is specified as 'auto', its used value is minus the value of 'left'.332 // 4. If neither 'left' nor 'right' is 'auto', the position is over-constrained, and one of them has to be ignored.333 // If the 'direction' property of the containing block is 'ltr', the value of 'left' wins and 'right' becomes -'left'.334 // If 'direction' of the containing block is 'rtl', 'right' wins and 'left' is ignored.335 336 auto left = computedValueIfNotAuto(style.logicalLeft(), containingBlockWidth);337 auto right = computedValueIfNotAuto(style.logicalRight(), containingBlockWidth);338 339 if (!left && !right) {340 // #1341 left = right = { 0 };342 } else if (!left) {343 // #2344 left = -*right;345 } else if (!right) {346 // #3347 right = -*left;348 } else {349 // #4350 auto isLeftToRightDirection = containingBlock.style().isLeftToRightDirection();351 if (isLeftToRightDirection)352 right = -*left;353 else354 left = std::nullopt;355 }356 357 ASSERT(!bottom || *top == -*bottom);358 ASSERT(!left || *left == -*right);359 360 auto newTopPosition = displayBox.top() + *top;361 auto newLeftPosition = displayBox.left() + left.value_or(-*right);362 363 LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position] -> positioned inflow -> top(" << newTopPosition << "px) left(" << newLeftPosition << "px) layoutBox(" << &layoutBox << ")");364 return { newLeftPosition, newTopPosition };365 }366 367 290 HeightAndMargin BlockFormattingContext::Geometry::inFlowHeightAndMargin(const LayoutState& layoutState, const Box& layoutBox, std::optional<LayoutUnit> usedHeight) 368 291 { -
trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
r238028 r238077 285 285 } 286 286 287 void InlineFormattingContext::computeInFlowPositionedPosition(const Box&) const288 {289 }290 291 287 void InlineFormattingContext::collectInlineContent(InlineRunProvider& inlineRunProvider) const 292 288 { -
trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h
r238028 r238077 119 119 void computeFloatPosition(const FloatingContext&, Line&, const Box&) const; 120 120 void computeStaticPosition(const Box&) const override; 121 void computeInFlowPositionedPosition(const Box&) const override;122 121 123 122 void collectInlineContent(InlineRunProvider&) const;
Note: See TracChangeset
for help on using the changeset viewer.