Changeset 232065 in webkit
- Timestamp:
- May 22, 2018 8:06:27 AM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r232064 r232065 1 2018-05-22 Zalan Bujtas <zalan@apple.com> 2 3 [LFC] Implement positioning for non-replaced out-of-flow elements. 4 https://bugs.webkit.org/show_bug.cgi?id=185858 5 6 Reviewed by Antti Koivisto. 7 8 In certain cases, the out-of-flow element's final position depends on the element's size. 9 Call computeOutOfFlowPosition() after width/height are resolved. 10 11 * layout/FormattingContext.cpp: 12 (WebCore::Layout::FormattingContext::computeOutOfFlowPosition const): 13 (WebCore::Layout::FormattingContext::layoutOutOfFlowDescendants const): 14 (WebCore::Layout::FormattingContext::computeOutOfFlowNonReplacedPosition const): 15 (WebCore::Layout::FormattingContext::computeOutOfFlowReplacedPosition const): 16 * layout/FormattingContext.h: 17 1 18 2018-05-22 Olivier Blin <olivier.blin@softathome.com> 2 19 -
trunk/Source/WebCore/layout/FormattingContext.cpp
r232042 r232065 58 58 } 59 59 60 void FormattingContext::computeOutOfFlowPosition(const Box&, Display::Box&) const 61 { 60 void FormattingContext::computeOutOfFlowPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const 61 { 62 if (!layoutBox.replaced()) { 63 computeOutOfFlowNonReplacedPosition(layoutContext, layoutBox, displayBox); 64 return; 65 } 66 computeOutOfFlowReplacedPosition(layoutContext, layoutBox, displayBox); 62 67 } 63 68 … … 148 153 auto& displayBox = layoutContext.createDisplayBox(layoutBox); 149 154 150 computeOutOfFlowPosition(layoutBox, displayBox); 155 // The term "static position" (of an element) refers, roughly, to the position an element would have had in the normal flow. 156 // More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge 157 // of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static' and 158 // its specified 'float' had been 'none' and its specified 'clear' had been 'none'. 159 computeStaticPosition(layoutContext, layoutBox, displayBox); 151 160 computeOutOfFlowWidth(layoutContext, layoutBox, displayBox); 152 161 … … 156 165 157 166 computeOutOfFlowHeight(layoutContext, layoutBox, displayBox); 167 computeOutOfFlowPosition(layoutContext, layoutBox, displayBox); 158 168 } 159 169 } … … 439 449 } 440 450 451 void FormattingContext::computeOutOfFlowNonReplacedPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const 452 { 453 // 10.3.7 Absolutely positioned, non-replaced elements (left/right) 454 // 10.6.4 Absolutely positioned, non-replaced elements (top/bottom) 455 456 // At this point we've the size computed. 457 auto size = displayBox.size(); 458 auto& style = layoutBox.style(); 459 460 // 10.6.4 Absolutely positioned, non-replaced elements 461 auto top = style.logicalTop(); 462 auto bottom = style.logicalBottom(); 463 auto containingBlockHeight = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->height(); 464 465 // 'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' 466 // = height of containing block 467 // 468 // 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7, 469 // set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top' 470 // 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for 471 // 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom' 472 // 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7, set 'auto' 473 // values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom' 474 // 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top' 475 // 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', then 'auto' values for 'margin-top' and 'margin-bottom' are set to 0 and solve for 'height' 476 // 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom' 477 LayoutUnit computedTopValue; 478 if (top.isAuto() && !bottom.isAuto()) { 479 // #1 #4 480 auto marginTop = displayBox.marginTop(); 481 auto marginBottom = displayBox.marginBottom(); 482 483 auto paddingTop = displayBox.paddingTop(); 484 auto paddingBottom = displayBox.paddingBottom(); 485 486 auto borderTop = displayBox.borderTop(); 487 auto borderBottom = displayBox.borderBottom(); 488 489 computedTopValue = containingBlockHeight - (marginTop + borderTop + paddingTop + size.height() + paddingBottom + borderBottom + marginBottom + bottom.value()); 490 } else if (top.isAuto() && bottom.isAuto()) { 491 // #2 492 // Already computed as part of the computeStaticPosition(); 493 computedTopValue = displayBox.top(); 494 } else { 495 // #3 #5 #6 have top != auto 496 computedTopValue = valueForLength(top, containingBlockHeight); 497 } 498 499 displayBox.setTop(computedTopValue); 500 501 // 10.3.7 Absolutely positioned, non-replaced elements 502 auto left = style.logicalLeft(); 503 auto right = style.logicalRight(); 504 auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width(); 505 506 // 'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' 507 // = width of containing block 508 // 509 // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. 510 // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static 511 // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. 512 513 // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' 514 // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position 515 // containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. 516 // Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). 517 // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' 518 // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' 519 // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' 520 // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' 521 LayoutUnit computedLeftValue; 522 if (left.isAuto() && !right.isAuto()) { 523 // #1 #4 524 auto marginLeft = displayBox.marginLeft(); 525 auto marginRight = displayBox.marginRight(); 526 527 auto paddingLeft = displayBox.paddingLeft(); 528 auto paddingRight = displayBox.paddingRight(); 529 530 auto borderLeft = displayBox.borderLeft(); 531 auto borderRight = displayBox.borderRight(); 532 533 computedLeftValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + size.width() + paddingRight + borderRight + marginRight + right.value()); 534 } else if (left.isAuto() && right.isAuto()) { 535 // #2 536 // FIXME: rtl 537 computedLeftValue = displayBox.left(); 538 } else { 539 // #3 #5 #6 have left != auto 540 computedLeftValue = valueForLength(left, containingBlockWidth); 541 } 542 543 displayBox.setLeft(computedLeftValue); 544 } 545 546 void FormattingContext::computeOutOfFlowReplacedPosition(LayoutContext&, const Box&, Display::Box&) const 547 { 548 549 } 550 441 551 LayoutUnit FormattingContext::shrinkToFitWidth(LayoutContext&, const Box&) const 442 552 { … … 477 587 } 478 588 #endif 589 479 590 } 480 591 } -
trunk/Source/WebCore/layout/FormattingContext.h
r232042 r232065 67 67 virtual void computeStaticPosition(LayoutContext&, const Box&, Display::Box&) const; 68 68 virtual void computeInFlowPositionedPosition(const Box&, Display::Box&) const; 69 virtual void computeOutOfFlowPosition( const Box&, Display::Box&) const;69 virtual void computeOutOfFlowPosition(LayoutContext&, const Box&, Display::Box&) const; 70 70 71 71 virtual void computeWidth(LayoutContext&, const Box&, Display::Box&) const; … … 101 101 void computeOutOfFlowReplacedWidth(LayoutContext&, const Box&, Display::Box&) const; 102 102 103 void computeOutOfFlowNonReplacedPosition(LayoutContext&, const Box&, Display::Box&) const; 104 void computeOutOfFlowReplacedPosition(LayoutContext&, const Box&, Display::Box&) const; 105 103 106 void computeFloatingNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const; 104 107 void computeFloatingNonReplacedWidth(LayoutContext&, const Box&, Display::Box&) const;
Note: See TracChangeset
for help on using the changeset viewer.