- a/Source/WebCore/ChangeLog +58 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2019-01-04  Zalan Bujtas  <zalan@apple.com>
2
3
        [LFC] VerticalMargin should only have the used values.
4
        https://bugs.webkit.org/show_bug.cgi?id=193168
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Split VerticalMargin into ComputedVerticalMargin and UsedVerticalMargin.
9
        ComputedVerticalMargin holds the computed (optional) values while UsedVerticalMargin holds both the
10
        collapsed (optional) and the non-collapsed values.
11
12
        * layout/FormattingContext.cpp:
13
        (WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
14
        * layout/FormattingContext.h:
15
        * layout/FormattingContextGeometry.cpp:
16
        (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
17
        (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
18
        (WebCore::Layout::FormattingContext::Geometry::complicatedCases):
19
        (WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
20
        (WebCore::Layout::FormattingContext::Geometry::inlineReplacedWidthAndMargin):
21
        (WebCore::Layout::FormattingContext::Geometry::computedVerticalMargin):
22
        (WebCore::Layout::FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue): Deleted.
23
        * layout/FormattingContextQuirks.cpp:
24
        (WebCore::Layout::FormattingContext::Quirks::heightValueOfNearestContainingBlockWithFixedHeight):
25
        * layout/LayoutUnits.h:
26
        * layout/MarginTypes.h:
27
        (WebCore::Layout::UsedVerticalMargin::before const):
28
        (WebCore::Layout::UsedVerticalMargin::after const):
29
        (WebCore::Layout::UsedVerticalMargin::nonCollapsedValues const):
30
        (WebCore::Layout::UsedVerticalMargin::collapsedValues const):
31
        (WebCore::Layout::UsedVerticalMargin::hasCollapsedValues const):
32
        (WebCore::Layout::UsedVerticalMargin::setCollapsedValues):
33
        (WebCore::Layout::UsedVerticalMargin::UsedVerticalMargin):
34
        (WebCore::Layout::VerticalMargin::nonCollapsedValues const): Deleted.
35
        (WebCore::Layout::VerticalMargin::collapsedValues const): Deleted.
36
        (WebCore::Layout::VerticalMargin::setCollapsedValues): Deleted.
37
        (WebCore::Layout::VerticalMargin::VerticalMargin): Deleted.
38
        (WebCore::Layout::VerticalMargin::usedValues const): Deleted.
39
        * layout/blockformatting/BlockFormattingContext.cpp:
40
        (WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):
41
        * layout/blockformatting/BlockFormattingContextGeometry.cpp:
42
        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
43
        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
44
        * layout/blockformatting/BlockFormattingContextQuirks.cpp:
45
        (WebCore::Layout::BlockFormattingContext::Quirks::stretchedHeight):
46
        * layout/blockformatting/BlockMarginCollapse.cpp:
47
        (WebCore::Layout::BlockFormattingContext::Geometry::MarginCollapse::computedNonCollapsedMarginBefore):
48
        (WebCore::Layout::BlockFormattingContext::Geometry::MarginCollapse::computedNonCollapsedMarginAfter):
49
        * layout/displaytree/DisplayBox.h:
50
        (WebCore::Display::Box::setVerticalMargin):
51
        (WebCore::Display::Box::verticalMargin const):
52
        (WebCore::Display::Box::marginBefore const):
53
        (WebCore::Display::Box::marginAfter const):
54
        * layout/floats/FloatingContext.cpp:
55
        (WebCore::Layout::FloatingContext::verticalPositionWithClearance const):
56
        * layout/inlineformatting/InlineFormattingContext.cpp:
57
        (WebCore::Layout::InlineFormattingContext::computeHeightAndMargin const):
58
1
2019-01-04  Zalan Bujtas  <zalan@apple.com>
59
2019-01-04  Zalan Bujtas  <zalan@apple.com>
2
60
3
        [LFC] ComputedHorizontalMargin should have optional members
61
        [LFC] ComputedHorizontalMargin should have optional members
- a/Source/WebCore/layout/FormattingContext.cpp -3 / +3 lines
Lines 116-126 void FormattingContext::computeOutOfFlowVerticalGeometry(const Box& layoutBox) c a/Source/WebCore/layout/FormattingContext.cpp_sec1
116
116
117
    auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
117
    auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
118
    // Margins of absolutely positioned boxes do not collapse
118
    // Margins of absolutely positioned boxes do not collapse
119
    ASSERT(!verticalGeometry.heightAndMargin.margin.collapsedValues());
119
    ASSERT(!verticalGeometry.heightAndMargin.usedMargin.hasCollapsedValues());
120
    auto nonCollapsedVerticalMargin = verticalGeometry.heightAndMargin.margin.nonCollapsedValues();
120
    auto nonCollapsedVerticalMargin = verticalGeometry.heightAndMargin.usedMargin.nonCollapsedValues();
121
    displayBox.setTop(verticalGeometry.top + nonCollapsedVerticalMargin.before);
121
    displayBox.setTop(verticalGeometry.top + nonCollapsedVerticalMargin.before);
122
    displayBox.setContentBoxHeight(verticalGeometry.heightAndMargin.height);
122
    displayBox.setContentBoxHeight(verticalGeometry.heightAndMargin.height);
123
    displayBox.setVerticalMargin(verticalGeometry.heightAndMargin.margin);
123
    displayBox.setVerticalMargin(verticalGeometry.heightAndMargin.usedMargin);
124
}
124
}
125
125
126
void FormattingContext::computeBorderAndPadding(const Box& layoutBox) const
126
void FormattingContext::computeBorderAndPadding(const Box& layoutBox) const
- a/Source/WebCore/layout/FormattingContext.h -1 / +1 lines
Lines 97-103 protected: a/Source/WebCore/layout/FormattingContext.h_sec1
97
        static Optional<Edges> computedPadding(const LayoutState&, const Box&);
97
        static Optional<Edges> computedPadding(const LayoutState&, const Box&);
98
98
99
        static ComputedHorizontalMargin computedHorizontalMargin(const LayoutState&, const Box&);
99
        static ComputedHorizontalMargin computedHorizontalMargin(const LayoutState&, const Box&);
100
        static VerticalMargin::ComputedValues computedNonCollapsedVerticalMarginValue(const LayoutState&, const Box&);
100
        static ComputedVerticalMargin computedVerticalMargin(const LayoutState&, const Box&);
101
101
102
        static Optional<LayoutUnit> computedValueIfNotAuto(const Length& geometryProperty, LayoutUnit containingBlockWidth);
102
        static Optional<LayoutUnit> computedValueIfNotAuto(const Length& geometryProperty, LayoutUnit containingBlockWidth);
103
        static Optional<LayoutUnit> fixedValue(const Length& geometryProperty);
103
        static Optional<LayoutUnit> fixedValue(const Length& geometryProperty);
- a/Source/WebCore/layout/FormattingContextGeometry.cpp -77 / +54 lines
Lines 280-289 VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeomet a/Source/WebCore/layout/FormattingContextGeometry.cpp_sec1
280
    auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
280
    auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
281
    auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
281
    auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
282
    auto height = usedHeight ? usedHeight.value() : computedHeightValue(layoutState, layoutBox, HeightType::Normal);
282
    auto height = usedHeight ? usedHeight.value() : computedHeightValue(layoutState, layoutBox, HeightType::Normal);
283
    auto computedMarginBefore = computedValueIfNotAuto(style.marginBefore(), containingBlockWidth);
283
    auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutState, layoutBox);
284
    auto computedMarginAfter = computedValueIfNotAuto(style.marginAfter(), containingBlockWidth);
284
    UsedVerticalMargin::NonCollapsedValues usedVerticalMargin; 
285
    auto usedMarginBefore = computedMarginBefore;
286
    auto usedMarginAfter = computedMarginAfter;
287
    auto paddingTop = displayBox.paddingTop().valueOr(0);
285
    auto paddingTop = displayBox.paddingTop().valueOr(0);
288
    auto paddingBottom = displayBox.paddingBottom().valueOr(0);
286
    auto paddingBottom = displayBox.paddingBottom().valueOr(0);
289
    auto borderTop = displayBox.borderTop();
287
    auto borderTop = displayBox.borderTop();
Lines 293-364 VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeomet a/Source/WebCore/layout/FormattingContextGeometry.cpp_sec2
293
        top = staticVerticalPositionForOutOfFlowPositioned(layoutState, layoutBox);
291
        top = staticVerticalPositionForOutOfFlowPositioned(layoutState, layoutBox);
294
292
295
    if (top && height && bottom) {
293
    if (top && height && bottom) {
296
        if (!usedMarginBefore && !usedMarginAfter) {
294
        if (!computedVerticalMargin.before && !computedVerticalMargin.after) {
297
            auto marginBeforeAndAfter = containingBlockHeight - (*top + borderTop + paddingTop + *height + paddingBottom + borderBottom + *bottom);
295
            auto marginBeforeAndAfter = containingBlockHeight - (*top + borderTop + paddingTop + *height + paddingBottom + borderBottom + *bottom);
298
            usedMarginBefore = usedMarginAfter = marginBeforeAndAfter / 2;
296
            usedVerticalMargin = { marginBeforeAndAfter / 2, marginBeforeAndAfter / 2 };
299
        } else if (!usedMarginBefore)
297
        } else if (!computedVerticalMargin.before) {
300
            usedMarginBefore = containingBlockHeight - (*top + borderTop + paddingTop + *height + paddingBottom + borderBottom + *usedMarginAfter + *bottom);
298
            usedVerticalMargin.after = *computedVerticalMargin.after;
301
        else
299
            usedVerticalMargin.before = containingBlockHeight - (*top + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom);
302
            usedMarginAfter = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + *height + paddingBottom + borderBottom + *bottom);
300
        } else {
301
            usedVerticalMargin.before = *computedVerticalMargin.before;
302
            usedVerticalMargin.after = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + *bottom);
303
        }
303
        // Over-constrained?
304
        // Over-constrained?
304
        auto boxHeight = *top + *usedMarginBefore + borderTop + paddingTop + *height + paddingBottom + borderBottom + *usedMarginAfter + *bottom;
305
        auto boxHeight = *top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom;
305
        if (boxHeight > containingBlockHeight)
306
        if (boxHeight > containingBlockHeight)
306
            bottom = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + *height + paddingBottom + borderBottom + *usedMarginAfter); 
307
            bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after); 
307
    }
308
    }
308
309
309
    if (!top && !height && bottom) {
310
    if (!top && !height && bottom) {
310
        // #1
311
        // #1
311
        height = contentHeightForFormattingContextRoot(layoutState, layoutBox);
312
        height = contentHeightForFormattingContextRoot(layoutState, layoutBox);
312
        usedMarginBefore = usedMarginBefore.valueOr(0);
313
        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
313
        usedMarginAfter = usedMarginAfter.valueOr(0);
314
        top = containingBlockHeight - (usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom); 
314
        top = containingBlockHeight - (*usedMarginBefore + borderTop + paddingTop + *height + paddingBottom + borderBottom + *usedMarginAfter + *bottom); 
315
    }
315
    }
316
316
317
    if (!top && !bottom && height) {
317
    if (!top && !bottom && height) {
318
        // #2
318
        // #2
319
        top = staticVerticalPositionForOutOfFlowPositioned(layoutState, layoutBox);
319
        top = staticVerticalPositionForOutOfFlowPositioned(layoutState, layoutBox);
320
        usedMarginBefore = usedMarginBefore.valueOr(0);
320
        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
321
        usedMarginAfter = usedMarginAfter.valueOr(0);
321
        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after); 
322
        bottom = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + *height + paddingBottom + borderBottom + *usedMarginAfter); 
323
    }
322
    }
324
323
325
    if (!height && !bottom && top) {
324
    if (!height && !bottom && top) {
326
        // #3
325
        // #3
327
        height = contentHeightForFormattingContextRoot(layoutState, layoutBox);
326
        height = contentHeightForFormattingContextRoot(layoutState, layoutBox);
328
        usedMarginBefore = usedMarginBefore.valueOr(0);
327
        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
329
        usedMarginAfter = usedMarginAfter.valueOr(0);
328
        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after); 
330
        bottom = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + *height + paddingBottom + borderBottom + *usedMarginAfter); 
331
    }
329
    }
332
330
333
    if (!top && height && bottom) {
331
    if (!top && height && bottom) {
334
        // #4
332
        // #4
335
        usedMarginBefore = usedMarginBefore.valueOr(0);
333
        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
336
        usedMarginAfter = usedMarginAfter.valueOr(0);
334
        top = containingBlockHeight - (usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom); 
337
        top = containingBlockHeight - (*usedMarginBefore + borderTop + paddingTop + *height + paddingBottom + borderBottom + *usedMarginAfter + *bottom); 
338
    }
335
    }
339
336
340
    if (!height && top && bottom) {
337
    if (!height && top && bottom) {
341
        // #5
338
        // #5
342
        usedMarginBefore = usedMarginBefore.valueOr(0);
339
        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
343
        usedMarginAfter = usedMarginAfter.valueOr(0);
340
        height = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom); 
344
        height = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + paddingBottom + borderBottom + *usedMarginAfter + *bottom); 
345
    }
341
    }
346
342
347
    if (!bottom && top && height) {
343
    if (!bottom && top && height) {
348
        // #6
344
        // #6
349
        usedMarginBefore = usedMarginBefore.valueOr(0);
345
        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
350
        usedMarginAfter = usedMarginAfter.valueOr(0);
346
        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after); 
351
        bottom = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + *height + paddingBottom + borderBottom + *usedMarginAfter); 
352
    }
347
    }
353
348
354
    ASSERT(top);
349
    ASSERT(top);
355
    ASSERT(bottom);
350
    ASSERT(bottom);
356
    ASSERT(height);
351
    ASSERT(height);
357
    ASSERT(usedMarginBefore);
358
    ASSERT(usedMarginAfter);
359
352
360
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow non-replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << *height << "px) margin(" << *usedMarginBefore << "px, "  << *usedMarginAfter << "px) layoutBox(" << &layoutBox << ")");
353
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow non-replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << *height << "px) margin(" << usedVerticalMargin.before << "px, "  << usedVerticalMargin.after << "px) layoutBox(" << &layoutBox << ")");
361
    return { *top, *bottom, { *height, { { *usedMarginBefore, *usedMarginAfter }, { } } } };
354
    return { *top, *bottom, { *height, { usedVerticalMargin, { } } } };
362
}
355
}
363
356
364
HorizontalGeometry FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry(LayoutState& layoutState, const Box& layoutBox, Optional<LayoutUnit> usedWidth)
357
HorizontalGeometry FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry(LayoutState& layoutState, const Box& layoutBox, Optional<LayoutUnit> usedWidth)
Lines 523-532 VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry( a/Source/WebCore/layout/FormattingContextGeometry.cpp_sec3
523
    auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
516
    auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
524
    auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
517
    auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
525
    auto height = inlineReplacedHeightAndMargin(layoutState, layoutBox, usedHeight).height;
518
    auto height = inlineReplacedHeightAndMargin(layoutState, layoutBox, usedHeight).height;
526
    auto computedMarginBefore = computedValueIfNotAuto(style.marginBefore(), containingBlockWidth);
519
    auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutState, layoutBox);
527
    auto computedMarginAfter = computedValueIfNotAuto(style.marginAfter(), containingBlockWidth);
520
    UsedVerticalMargin::NonCollapsedValues usedVerticalMargin; 
528
    auto usedMarginBefore = computedMarginBefore;
529
    auto usedMarginAfter = computedMarginAfter;
530
    auto paddingTop = displayBox.paddingTop().valueOr(0);
521
    auto paddingTop = displayBox.paddingTop().valueOr(0);
531
    auto paddingBottom = displayBox.paddingBottom().valueOr(0);
522
    auto paddingBottom = displayBox.paddingBottom().valueOr(0);
532
    auto borderTop = displayBox.borderTop();
523
    auto borderTop = displayBox.borderTop();
Lines 539-574 VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry( a/Source/WebCore/layout/FormattingContextGeometry.cpp_sec4
539
530
540
    if (!bottom) {
531
    if (!bottom) {
541
        // #2
532
        // #2
542
        usedMarginBefore = usedMarginBefore.valueOr(0);
533
        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
543
        usedMarginAfter = usedMarginAfter.valueOr(0);
544
    }
534
    }
545
535
546
    if (!usedMarginBefore && !usedMarginAfter) {
536
    if (!computedVerticalMargin.before && !computedVerticalMargin.after) {
547
        // #3
537
        // #3
548
        auto marginBeforeAndAfter = containingBlockHeight - (*top + borderTop + paddingTop + height + paddingBottom + borderBottom + *bottom);
538
        auto marginBeforeAndAfter = containingBlockHeight - (*top + borderTop + paddingTop + height + paddingBottom + borderBottom + *bottom);
549
        usedMarginBefore = usedMarginAfter = marginBeforeAndAfter / 2;
539
        usedVerticalMargin = { marginBeforeAndAfter / 2, marginBeforeAndAfter / 2 };
550
    }
540
    }
551
541
552
    // #4
542
    // #4
553
    if (!top)
543
    if (!top)
554
        top = containingBlockHeight - (*usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter + *bottom);
544
        top = containingBlockHeight - (usedVerticalMargin.before + borderTop + paddingTop + height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom);
555
545
556
    if (!bottom)
546
    if (!bottom)
557
        bottom = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter);
547
        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + height + paddingBottom + borderBottom + usedVerticalMargin.after);
558
548
559
    if (!usedMarginBefore)
549
    if (!computedVerticalMargin.before)
560
        usedMarginBefore = containingBlockHeight - (*top + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter + *bottom);
550
        usedVerticalMargin.before = containingBlockHeight - (*top + borderTop + paddingTop + height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom);
561
551
562
    if (!usedMarginAfter)
552
    if (!computedVerticalMargin.after)
563
        usedMarginAfter = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *bottom);
553
        usedVerticalMargin.after = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + height + paddingBottom + borderBottom + *bottom);
564
554
565
    // #5
555
    // #5
566
    auto boxHeight = *top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter + *bottom;
556
    auto boxHeight = *top + usedVerticalMargin.before + borderTop + paddingTop + height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom;
567
    if (boxHeight > containingBlockHeight)
557
    if (boxHeight > containingBlockHeight)
568
        bottom = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter); 
558
        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + height + paddingBottom + borderBottom + usedVerticalMargin.after); 
569
559
570
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << height << "px) margin(" << *usedMarginBefore << "px, "  << *usedMarginAfter << "px) layoutBox(" << &layoutBox << ")");
560
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << height << "px) margin(" << usedVerticalMargin.before << "px, "  << usedVerticalMargin.after << "px) layoutBox(" << &layoutBox << ")");
571
    return { *top, *bottom, { height, { { *usedMarginBefore, *usedMarginAfter }, { } } } };
561
    return { *top, *bottom, { height, { usedVerticalMargin, { } } } };
572
}
562
}
573
563
574
HorizontalGeometry FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry(const LayoutState& layoutState, const Box& layoutBox, Optional<LayoutUnit> usedWidth)
564
HorizontalGeometry FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry(const LayoutState& layoutState, const Box& layoutBox, Optional<LayoutUnit> usedWidth)
Lines 679-697 HeightAndMargin FormattingContext::Geometry::complicatedCases(const LayoutState& a/Source/WebCore/layout/FormattingContextGeometry.cpp_sec5
679
    // 1. If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.
669
    // 1. If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.
680
    // 2. If 'height' is 'auto', the height depends on the element's descendants per 10.6.7.
670
    // 2. If 'height' is 'auto', the height depends on the element's descendants per 10.6.7.
681
671
682
    auto& style = layoutBox.style();
683
    auto& containingBlock = *layoutBox.containingBlock();
684
    auto& containingBlockDisplayBox = layoutState.displayBoxForLayoutBox(containingBlock);
685
    auto containingBlockWidth = containingBlockDisplayBox.contentBoxWidth();
686
687
    auto height = usedHeight ? usedHeight.value() : computedHeightValue(layoutState, layoutBox, HeightType::Normal);
672
    auto height = usedHeight ? usedHeight.value() : computedHeightValue(layoutState, layoutBox, HeightType::Normal);
688
    auto computedMarginBefore = computedValueIfNotAuto(style.marginBefore(), containingBlockWidth);
673
    auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutState, layoutBox);
689
    auto computedMarginAfter = computedValueIfNotAuto(style.marginAfter(), containingBlockWidth);
690
691
    // #1
674
    // #1
692
    auto usedMarginBefore = computedMarginBefore.valueOr(0);
675
    auto usedVerticalMargin = UsedVerticalMargin::NonCollapsedValues { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) }; 
693
    auto usedMarginAfter = computedMarginAfter.valueOr(0);
694
695
    // #2
676
    // #2
696
    if (!height) {
677
    if (!height) {
697
        ASSERT(isHeightAuto(layoutBox));
678
        ASSERT(isHeightAuto(layoutBox));
Lines 700-707 HeightAndMargin FormattingContext::Geometry::complicatedCases(const LayoutState& a/Source/WebCore/layout/FormattingContextGeometry.cpp_sec6
700
681
701
    ASSERT(height);
682
    ASSERT(height);
702
683
703
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating non-replaced -> height(" << *height << "px) margin(" << usedMarginBefore << "px, " << usedMarginAfter << "px) -> layoutBox(" << &layoutBox << ")");
684
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating non-replaced -> height(" << *height << "px) margin(" << usedVerticalMargin.before << "px, " << usedVerticalMargin.after << "px) -> layoutBox(" << &layoutBox << ")");
704
    return HeightAndMargin { *height, { { usedMarginBefore, usedMarginAfter }, { } } };
685
    return HeightAndMargin { *height, { usedVerticalMargin, { } } };
705
}
686
}
706
687
707
WidthAndMargin FormattingContext::Geometry::floatingNonReplacedWidthAndMargin(LayoutState& layoutState, const Box& layoutBox, Optional<LayoutUnit> usedWidth)
688
WidthAndMargin FormattingContext::Geometry::floatingNonReplacedWidthAndMargin(LayoutState& layoutState, const Box& layoutBox, Optional<LayoutUnit> usedWidth)
Lines 802-809 HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const a/Source/WebCore/layout/FormattingContextGeometry.cpp_sec7
802
    //    the height of the largest rectangle that has a 2:1 ratio, has a height not greater than 150px, and has a width not greater than the device width.
783
    //    the height of the largest rectangle that has a 2:1 ratio, has a height not greater than 150px, and has a width not greater than the device width.
803
784
804
    // #1
785
    // #1
805
    auto margin = computedNonCollapsedVerticalMarginValue(layoutState, layoutBox);
786
    auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutState, layoutBox);
806
787
    auto usedVerticalMargin = UsedVerticalMargin::NonCollapsedValues { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
807
    auto& style = layoutBox.style();
788
    auto& style = layoutBox.style();
808
    auto replaced = layoutBox.replaced();
789
    auto replaced = layoutBox.replaced();
809
790
Lines 828-835 HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const a/Source/WebCore/layout/FormattingContextGeometry.cpp_sec8
828
809
829
    ASSERT(height);
810
    ASSERT(height);
830
811
831
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow replaced -> height(" << *height << "px) margin(" << margin.before << "px, " << margin.after << "px) -> layoutBox(" << &layoutBox << ")");
812
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow replaced -> height(" << *height << "px) margin(" << usedVerticalMargin.before << "px, " << usedVerticalMargin.after << "px) -> layoutBox(" << &layoutBox << ")");
832
    return { *height, { margin, { } } };
813
    return { *height, { usedVerticalMargin, { } } };
833
}
814
}
834
815
835
WidthAndMargin FormattingContext::Geometry::inlineReplacedWidthAndMargin(const LayoutState& layoutState, const Box& layoutBox,
816
WidthAndMargin FormattingContext::Geometry::inlineReplacedWidthAndMargin(const LayoutState& layoutState, const Box& layoutBox,
Lines 857-864 WidthAndMargin FormattingContext::Geometry::inlineReplacedWidthAndMargin(const L a/Source/WebCore/layout/FormattingContextGeometry.cpp_sec9
857
    //    If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
838
    //    If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
858
839
859
    auto& style = layoutBox.style();
840
    auto& style = layoutBox.style();
860
    auto& containingBlockDisplayBox = layoutState.displayBoxForLayoutBox(*layoutBox.containingBlock());
841
    auto& containingBlock = *layoutBox.containingBlock();
861
    auto containingBlockWidth = containingBlockDisplayBox.width();
842
    auto containingBlockWidth = layoutState.displayBoxForLayoutBox(containingBlock).contentBoxWidth();
862
    auto computedHorizontalMargin = Geometry::computedHorizontalMargin(layoutState, layoutBox);
843
    auto computedHorizontalMargin = Geometry::computedHorizontalMargin(layoutState, layoutBox);
863
844
864
    auto usedMarginStart = [&] {
845
    auto usedMarginStart = [&] {
Lines 1008-1023 ComputedHorizontalMargin FormattingContext::Geometry::computedHorizontalMargin(c a/Source/WebCore/layout/FormattingContextGeometry.cpp_sec10
1008
    return { computedValueIfNotAuto(style.marginStart(), containingBlockWidth), computedValueIfNotAuto(style.marginEnd(), containingBlockWidth) };
989
    return { computedValueIfNotAuto(style.marginStart(), containingBlockWidth), computedValueIfNotAuto(style.marginEnd(), containingBlockWidth) };
1009
}
990
}
1010
991
1011
VerticalMargin::ComputedValues FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue(const LayoutState& layoutState, const Box& layoutBox)
992
ComputedVerticalMargin FormattingContext::Geometry::computedVerticalMargin(const LayoutState& layoutState, const Box& layoutBox)
1012
{
993
{
1013
    auto& style = layoutBox.style();
994
    auto& style = layoutBox.style();
1014
    auto containingBlockWidth = layoutState.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
995
    auto containingBlockWidth = layoutState.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
1015
996
1016
    auto usedMarginBefore = computedValueIfNotAuto(style.marginBefore(), containingBlockWidth).valueOr(0_lu);
997
    return { computedValueIfNotAuto(style.marginBefore(), containingBlockWidth), computedValueIfNotAuto(style.marginAfter(), containingBlockWidth) };
1017
    auto usedMarginAfter = computedValueIfNotAuto(style.marginAfter(), containingBlockWidth).valueOr(0_lu);
1018
1019
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Margin] -> non collapsed vertical -> margin(" << usedMarginBefore << "px, " << usedMarginAfter << "px) -> layoutBox: " << &layoutBox);
1020
    return { usedMarginBefore, usedMarginAfter };
1021
}
998
}
1022
999
1023
}
1000
}
- a/Source/WebCore/layout/FormattingContextQuirks.cpp -2 / +2 lines
Lines 51-60 LayoutUnit FormattingContext::Quirks::heightValueOfNearestContainingBlockWithFix a/Source/WebCore/layout/FormattingContextQuirks.cpp_sec1
51
        if (containingBlock->isBodyBox() || containingBlock->isDocumentBox()) {
51
        if (containingBlock->isBodyBox() || containingBlock->isDocumentBox()) {
52
            auto& displayBox = layoutState.displayBoxForLayoutBox(*containingBlock);
52
            auto& displayBox = layoutState.displayBoxForLayoutBox(*containingBlock);
53
53
54
            auto verticalMargin = FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue(layoutState, *containingBlock);
54
            auto verticalMargin = Geometry::computedVerticalMargin(layoutState, *containingBlock);
55
            auto verticalPadding = displayBox.paddingTop().valueOr(0) + displayBox.paddingBottom().valueOr(0);
55
            auto verticalPadding = displayBox.paddingTop().valueOr(0) + displayBox.paddingBottom().valueOr(0);
56
            auto verticalBorder = displayBox.borderTop() + displayBox.borderBottom();
56
            auto verticalBorder = displayBox.borderTop() + displayBox.borderBottom();
57
            bodyAndDocumentVerticalMarginPaddingAndBorder += verticalMargin.before + verticalMargin.after + verticalPadding + verticalBorder;
57
            bodyAndDocumentVerticalMarginPaddingAndBorder += verticalMargin.before.valueOr(0) + verticalMargin.after.valueOr(0) + verticalPadding + verticalBorder;
58
        }
58
        }
59
59
60
        containingBlock = containingBlock->containingBlock();
60
        containingBlock = containingBlock->containingBlock();
- a/Source/WebCore/layout/LayoutUnits.h -1 / +1 lines
Lines 109-115 struct WidthAndMargin { a/Source/WebCore/layout/LayoutUnits.h_sec1
109
109
110
struct HeightAndMargin {
110
struct HeightAndMargin {
111
    LayoutUnit height;
111
    LayoutUnit height;
112
    VerticalMargin margin;
112
    UsedVerticalMargin usedMargin;
113
};
113
};
114
114
115
struct HorizontalGeometry {
115
struct HorizontalGeometry {
- a/Source/WebCore/layout/MarginTypes.h -23 / +23 lines
Lines 32-59 a/Source/WebCore/layout/MarginTypes.h_sec1
32
namespace WebCore {
32
namespace WebCore {
33
namespace Layout {
33
namespace Layout {
34
34
35
struct VerticalMargin {
35
struct ComputedVerticalMargin {
36
    struct ComputedValues {
36
    Optional<LayoutUnit> before;
37
    Optional<LayoutUnit> after;
38
};
39
40
struct UsedVerticalMargin {
41
    LayoutUnit before() const { return m_collapsedValues.before.valueOr(m_nonCollapsedValues.before); }
42
    LayoutUnit after() const { return m_collapsedValues.after.valueOr(m_nonCollapsedValues.after); }
43
44
    struct NonCollapsedValues {
37
        LayoutUnit before;
45
        LayoutUnit before;
38
        LayoutUnit after;
46
        LayoutUnit after;
39
    };
47
    };
40
    ComputedValues usedValues() const;
48
    NonCollapsedValues nonCollapsedValues() const { return m_nonCollapsedValues; }
41
    ComputedValues nonCollapsedValues() const { return m_nonCollapsed; }
49
42
    
43
    struct CollapsedValues {
50
    struct CollapsedValues {
44
        Optional<LayoutUnit> before;
51
        Optional<LayoutUnit> before;
45
        Optional<LayoutUnit> after;
52
        Optional<LayoutUnit> after;
46
    };
53
    };
47
    Optional<CollapsedValues> collapsedValues() const { return m_collapsed; }
54
    CollapsedValues collapsedValues() const { return m_collapsedValues; }
48
    void setCollapsedValues(CollapsedValues collapsedValues) { m_collapsed = collapsedValues; }
55
    bool hasCollapsedValues() const { return m_collapsedValues.before || m_collapsedValues.after; }
56
    void setCollapsedValues(CollapsedValues collapsedValues) { m_collapsedValues = collapsedValues; }
49
57
50
    VerticalMargin(ComputedValues nonCollapsed, Optional<CollapsedValues>);
58
    UsedVerticalMargin(NonCollapsedValues, CollapsedValues);
51
59
52
    VerticalMargin() = default;
60
    UsedVerticalMargin() = default;
53
    ~VerticalMargin() = default;
61
    ~UsedVerticalMargin() = default;
54
private:
62
private:
55
    ComputedValues m_nonCollapsed;
63
    NonCollapsedValues m_nonCollapsedValues;
56
    Optional<CollapsedValues> m_collapsed;
64
    CollapsedValues m_collapsedValues;
57
};
65
};
58
66
59
struct ComputedHorizontalMargin {
67
struct ComputedHorizontalMargin {
Lines 75-92 struct PositiveAndNegativeVerticalMargin { a/Source/WebCore/layout/MarginTypes.h_sec2
75
    Values after;
83
    Values after;
76
};
84
};
77
85
78
inline VerticalMargin::VerticalMargin(VerticalMargin::ComputedValues nonCollapsed, Optional<VerticalMargin::CollapsedValues> collapsed)
86
inline UsedVerticalMargin::UsedVerticalMargin(UsedVerticalMargin::NonCollapsedValues nonCollapsedValues, UsedVerticalMargin::CollapsedValues collapsedValues)
79
    : m_nonCollapsed(nonCollapsed)
87
    : m_nonCollapsedValues(nonCollapsedValues)
80
    , m_collapsed(collapsed)
88
    , m_collapsedValues(collapsedValues)
81
{
82
}
83
84
inline VerticalMargin::ComputedValues VerticalMargin::usedValues() const
85
{
89
{
86
    if (!m_collapsed)
87
        return m_nonCollapsed;
88
    return { m_collapsed->before.valueOr(m_nonCollapsed.before),
89
        m_collapsed->after.valueOr(m_nonCollapsed.after) };
90
}
90
}
91
91
92
}
92
}
- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp -4 / +4 lines
Lines 358-364 void BlockFormattingContext::computeHeightAndMargin(const Box& layoutBox) const a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp_sec1
358
            auto maxHeightAndMargin = compute(maxHeight);
358
            auto maxHeightAndMargin = compute(maxHeight);
359
            // Used height should remain the same.
359
            // Used height should remain the same.
360
            ASSERT((layoutState.inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || maxHeightAndMargin.height == *maxHeight);
360
            ASSERT((layoutState.inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || maxHeightAndMargin.height == *maxHeight);
361
            heightAndMargin = { *maxHeight, maxHeightAndMargin.margin };
361
            heightAndMargin = { *maxHeight, maxHeightAndMargin.usedMargin };
362
        }
362
        }
363
    }
363
    }
364
364
Lines 367-383 void BlockFormattingContext::computeHeightAndMargin(const Box& layoutBox) const a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp_sec2
367
            auto minHeightAndMargin = compute(minHeight);
367
            auto minHeightAndMargin = compute(minHeight);
368
            // Used height should remain the same.
368
            // Used height should remain the same.
369
            ASSERT((layoutState.inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || minHeightAndMargin.height == *minHeight);
369
            ASSERT((layoutState.inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || minHeightAndMargin.height == *minHeight);
370
            heightAndMargin = { *minHeight, minHeightAndMargin.margin };
370
            heightAndMargin = { *minHeight, minHeightAndMargin.usedMargin };
371
        }
371
        }
372
    }
372
    }
373
373
374
    auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
374
    auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
375
    displayBox.setContentBoxHeight(heightAndMargin.height);
375
    displayBox.setContentBoxHeight(heightAndMargin.height);
376
    displayBox.setVerticalMargin(heightAndMargin.margin);
376
    displayBox.setVerticalMargin(heightAndMargin.usedMargin);
377
377
378
    // If this box has already been moved by the estimated vertical margin, no need to move it again.
378
    // If this box has already been moved by the estimated vertical margin, no need to move it again.
379
    if (layoutBox.isFloatingPositioned() || !displayBox.estimatedMarginBefore())
379
    if (layoutBox.isFloatingPositioned() || !displayBox.estimatedMarginBefore())
380
        displayBox.moveVertically(heightAndMargin.margin.usedValues().before);
380
        displayBox.moveVertically(heightAndMargin.usedMargin.before());
381
}
381
}
382
382
383
FormattingContext::InstrinsicWidthConstraints BlockFormattingContext::instrinsicWidthConstraints() const
383
FormattingContext::InstrinsicWidthConstraints BlockFormattingContext::instrinsicWidthConstraints() const
- a/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp -8 / +5 lines
Lines 57-69 HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMarg a/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp_sec1
57
        // Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored,
57
        // Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored,
58
        // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
58
        // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
59
59
60
        auto& style = layoutBox.style();
61
        auto containingBlockWidth = layoutState.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
62
        auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
60
        auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
63
61
        auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutState, layoutBox);
64
        auto nonCollapsedMargin = VerticalMargin::ComputedValues { computedValueIfNotAuto(style.marginBefore(), containingBlockWidth).valueOr(0),
62
        auto nonCollapsedMargin = UsedVerticalMargin::NonCollapsedValues { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) }; 
65
            computedValueIfNotAuto(style.marginAfter(), containingBlockWidth).valueOr(0) }; 
63
        auto collapsedMargin = UsedVerticalMargin::CollapsedValues { MarginCollapse::marginBefore(layoutState, layoutBox), MarginCollapse::marginAfter(layoutState, layoutBox) };
66
        auto collapsedMargin = VerticalMargin::CollapsedValues { MarginCollapse::marginBefore(layoutState, layoutBox), MarginCollapse::marginAfter(layoutState, layoutBox) };
67
        auto borderAndPaddingTop = displayBox.borderTop() + displayBox.paddingTop().valueOr(0);
64
        auto borderAndPaddingTop = displayBox.borderTop() + displayBox.paddingTop().valueOr(0);
68
65
69
        auto height = usedHeight ? usedHeight.value() : computedHeightValue(layoutState, layoutBox, HeightType::Normal);
66
        auto height = usedHeight ? usedHeight.value() : computedHeightValue(layoutState, layoutBox, HeightType::Normal);
Lines 104-110 HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMarg a/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp_sec2
104
101
105
    auto heightAndMargin = compute();
102
    auto heightAndMargin = compute();
106
103
107
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow non-replaced -> height(" << heightAndMargin.height << "px) margin(" << heightAndMargin.margin.usedValues().before << "px, " << heightAndMargin.margin.usedValues().after << "px) -> layoutBox(" << &layoutBox << ")");
104
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow non-replaced -> height(" << heightAndMargin.height << "px) margin(" << heightAndMargin.usedMargin.before() << "px, " << heightAndMargin.usedMargin.after() << "px) -> layoutBox(" << &layoutBox << ")");
108
    return heightAndMargin;
105
    return heightAndMargin;
109
}
106
}
110
107
Lines 263-269 HeightAndMargin BlockFormattingContext::Geometry::inFlowHeightAndMargin(const La a/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp_sec3
263
260
264
    heightAndMargin = Quirks::stretchedHeight(layoutState, layoutBox, heightAndMargin);
261
    heightAndMargin = Quirks::stretchedHeight(layoutState, layoutBox, heightAndMargin);
265
262
266
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow non-replaced -> streched to viewport -> height(" << heightAndMargin.height << "px) margin(" << heightAndMargin.margin.usedValues().before << "px, " << heightAndMargin.margin.usedValues().after << "px) -> layoutBox(" << &layoutBox << ")");
263
    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow non-replaced -> streched to viewport -> height(" << heightAndMargin.height << "px) margin(" << heightAndMargin.usedMargin.before() << "px, " << heightAndMargin.usedMargin.after() << "px) -> layoutBox(" << &layoutBox << ")");
267
    return heightAndMargin;
264
    return heightAndMargin;
268
}
265
}
269
266
- a/Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp -5 / +9 lines
Lines 80-89 HeightAndMargin BlockFormattingContext::Quirks::stretchedHeight(const LayoutStat a/Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp_sec1
80
80
81
    LayoutUnit totalVerticalMargin;
81
    LayoutUnit totalVerticalMargin;
82
    if (layoutBox.isDocumentBox()) {
82
    if (layoutBox.isDocumentBox()) {
83
        auto verticalMargin = heightAndMargin.margin.usedValues();
83
        auto verticalMargin = heightAndMargin.usedMargin;
84
        // Document box's margins do not collapse.
84
        // Document box's margins do not collapse.
85
        ASSERT(!heightAndMargin.margin.collapsedValues());
85
        ASSERT(!verticalMargin.hasCollapsedValues());
86
        totalVerticalMargin = verticalMargin.before + verticalMargin.after;
86
        totalVerticalMargin = verticalMargin.before() + verticalMargin.after();
87
    } else if (layoutBox.isBodyBox()) {
87
    } else if (layoutBox.isBodyBox()) {
88
        // Here is the quirky part for body box:
88
        // Here is the quirky part for body box:
89
        // Stretch the body using the initial containing block's height and shrink it with document box's margin/border/padding.
89
        // Stretch the body using the initial containing block's height and shrink it with document box's margin/border/padding.
Lines 93-100 HeightAndMargin BlockFormattingContext::Quirks::stretchedHeight(const LayoutStat a/Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp_sec2
93
93
94
        // This quirk happens when the body height is 0 which means its vertical margins collapse through (top and bottom margins are adjoining).
94
        // This quirk happens when the body height is 0 which means its vertical margins collapse through (top and bottom margins are adjoining).
95
        // However now that we stretch the body they don't collapse through anymore, so we need to use the non-collapsed values instead.
95
        // However now that we stretch the body they don't collapse through anymore, so we need to use the non-collapsed values instead.
96
        auto bodyBoxVerticalMargin = heightAndMargin.height ? heightAndMargin.margin.usedValues() : heightAndMargin.margin.nonCollapsedValues();
96
        if (heightAndMargin.height)
97
        totalVerticalMargin = bodyBoxVerticalMargin.before + bodyBoxVerticalMargin.after;
97
            totalVerticalMargin = heightAndMargin.usedMargin.before() + heightAndMargin.usedMargin.after();
98
        else {
99
            auto nonCollapsedValues = heightAndMargin.usedMargin.nonCollapsedValues();
100
            totalVerticalMargin = nonCollapsedValues.before + nonCollapsedValues.after;
101
        }
98
    }
102
    }
99
103
100
    // Stretch but never overstretch with the margins.
104
    // Stretch but never overstretch with the margins.
- a/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp -2 / +2 lines
Lines 107-120 LayoutUnit BlockFormattingContext::Geometry::MarginCollapse::computedNonCollapse a/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp_sec1
107
{
107
{
108
    ASSERT(layoutBox.isBlockLevelBox());
108
    ASSERT(layoutBox.isBlockLevelBox());
109
109
110
    return computedNonCollapsedVerticalMarginValue(layoutState, layoutBox).before;
110
    return computedVerticalMargin(layoutState, layoutBox).before.valueOr(0);
111
}
111
}
112
112
113
LayoutUnit BlockFormattingContext::Geometry::MarginCollapse::computedNonCollapsedMarginAfter(const LayoutState& layoutState, const Box& layoutBox)
113
LayoutUnit BlockFormattingContext::Geometry::MarginCollapse::computedNonCollapsedMarginAfter(const LayoutState& layoutState, const Box& layoutBox)
114
{
114
{
115
    ASSERT(layoutBox.isBlockLevelBox());
115
    ASSERT(layoutBox.isBlockLevelBox());
116
116
117
    return computedNonCollapsedVerticalMarginValue(layoutState, layoutBox).after;
117
    return computedVerticalMargin(layoutState, layoutBox).after.valueOr(0);
118
}
118
}
119
119
120
LayoutUnit BlockFormattingContext::Geometry::MarginCollapse::nonCollapsedMarginBefore(const LayoutState& layoutState, const Box& layoutBox)
120
LayoutUnit BlockFormattingContext::Geometry::MarginCollapse::nonCollapsedMarginBefore(const LayoutState& layoutState, const Box& layoutBox)
- a/Source/WebCore/layout/displaytree/DisplayBox.h -8 / +8 lines
Lines 138-144 public: a/Source/WebCore/layout/displaytree/DisplayBox.h_sec1
138
    Rect rect() const { return { top(), left(), width(), height() }; }
138
    Rect rect() const { return { top(), left(), width(), height() }; }
139
    Rect rectWithMargin() const { return { top() - marginBefore(), left() - marginStart(), marginStart() + width() + marginEnd(), marginBefore() + height() + marginAfter() }; }
139
    Rect rectWithMargin() const { return { top() - marginBefore(), left() - marginStart(), marginStart() + width() + marginEnd(), marginBefore() + height() + marginAfter() }; }
140
140
141
    Layout::VerticalMargin verticalMargin() const;
141
    Layout::UsedVerticalMargin verticalMargin() const;
142
    LayoutUnit marginBefore() const;
142
    LayoutUnit marginBefore() const;
143
    LayoutUnit marginStart() const;
143
    LayoutUnit marginStart() const;
144
    LayoutUnit marginAfter() const;
144
    LayoutUnit marginAfter() const;
Lines 192-198 private: a/Source/WebCore/layout/displaytree/DisplayBox.h_sec2
192
    void setContentBoxWidth(LayoutUnit);
192
    void setContentBoxWidth(LayoutUnit);
193
193
194
    void setHorizontalMargin(Layout::UsedHorizontalMargin);
194
    void setHorizontalMargin(Layout::UsedHorizontalMargin);
195
    void setVerticalMargin(Layout::VerticalMargin);
195
    void setVerticalMargin(Layout::UsedVerticalMargin);
196
    void setHorizontalComputedMargin(Layout::ComputedHorizontalMargin);
196
    void setHorizontalComputedMargin(Layout::ComputedHorizontalMargin);
197
    void setEstimatedMarginBefore(LayoutUnit marginBefore) { m_estimatedMarginBefore = marginBefore; }
197
    void setEstimatedMarginBefore(LayoutUnit marginBefore) { m_estimatedMarginBefore = marginBefore; }
198
198
Lines 225-231 private: a/Source/WebCore/layout/displaytree/DisplayBox.h_sec3
225
    LayoutUnit m_contentHeight;
225
    LayoutUnit m_contentHeight;
226
226
227
    Layout::UsedHorizontalMargin m_horizontalMargin;
227
    Layout::UsedHorizontalMargin m_horizontalMargin;
228
    Layout::VerticalMargin m_verticalMargin;
228
    Layout::UsedVerticalMargin m_verticalMargin;
229
    Layout::ComputedHorizontalMargin m_horizontalComputedMargin;
229
    Layout::ComputedHorizontalMargin m_horizontalComputedMargin;
230
    Optional<LayoutUnit> m_estimatedMarginBefore;
230
    Optional<LayoutUnit> m_estimatedMarginBefore;
231
231
Lines 515-527 inline void Box::setHorizontalMargin(Layout::UsedHorizontalMargin margin) a/Source/WebCore/layout/displaytree/DisplayBox.h_sec4
515
    m_horizontalMargin = margin;
515
    m_horizontalMargin = margin;
516
}
516
}
517
517
518
inline void Box::setVerticalMargin(Layout::VerticalMargin margin)
518
inline void Box::setVerticalMargin(Layout::UsedVerticalMargin margin)
519
{
519
{
520
#if !ASSERT_DISABLED
520
#if !ASSERT_DISABLED
521
    setHasValidVerticalMargin();
521
    setHasValidVerticalMargin();
522
    setHasValidVerticalNonCollapsedMargin();
522
    setHasValidVerticalNonCollapsedMargin();
523
#endif
523
#endif
524
    ASSERT(!m_estimatedMarginBefore || *m_estimatedMarginBefore == margin.usedValues().before);
524
    ASSERT(!m_estimatedMarginBefore || *m_estimatedMarginBefore == margin.before());
525
    m_verticalMargin = margin;
525
    m_verticalMargin = margin;
526
}
526
}
527
527
Lines 549-555 inline void Box::setPadding(Optional<Layout::Edges> padding) a/Source/WebCore/layout/displaytree/DisplayBox.h_sec5
549
    m_padding = padding;
549
    m_padding = padding;
550
}
550
}
551
551
552
inline Layout::VerticalMargin Box::verticalMargin() const
552
inline Layout::UsedVerticalMargin Box::verticalMargin() const
553
{
553
{
554
    ASSERT(m_hasValidVerticalMargin);
554
    ASSERT(m_hasValidVerticalMargin);
555
    return m_verticalMargin;
555
    return m_verticalMargin;
Lines 558-564 inline Layout::VerticalMargin Box::verticalMargin() const a/Source/WebCore/layout/displaytree/DisplayBox.h_sec6
558
inline LayoutUnit Box::marginBefore() const
558
inline LayoutUnit Box::marginBefore() const
559
{
559
{
560
    ASSERT(m_hasValidVerticalMargin);
560
    ASSERT(m_hasValidVerticalMargin);
561
    return m_verticalMargin.usedValues().before;
561
    return m_verticalMargin.before();
562
}
562
}
563
563
564
inline LayoutUnit Box::marginStart() const
564
inline LayoutUnit Box::marginStart() const
Lines 570-576 inline LayoutUnit Box::marginStart() const a/Source/WebCore/layout/displaytree/DisplayBox.h_sec7
570
inline LayoutUnit Box::marginAfter() const
570
inline LayoutUnit Box::marginAfter() const
571
{
571
{
572
    ASSERT(m_hasValidVerticalMargin);
572
    ASSERT(m_hasValidVerticalMargin);
573
    return m_verticalMargin.usedValues().after;
573
    return m_verticalMargin.after();
574
}
574
}
575
575
576
inline LayoutUnit Box::marginEnd() const
576
inline LayoutUnit Box::marginEnd() const
- a/Source/WebCore/layout/floats/FloatingContext.cpp -4 / +4 lines
Lines 193-206 Optional<Position> FloatingContext::verticalPositionWithClearance(const Box& lay a/Source/WebCore/layout/floats/FloatingContext.cpp_sec1
193
193
194
            // Reset previous bottom and current top margins to non-collapsing.
194
            // Reset previous bottom and current top margins to non-collapsing.
195
            auto previousVerticalMargin = previousInFlowDisplayBox.verticalMargin();
195
            auto previousVerticalMargin = previousInFlowDisplayBox.verticalMargin();
196
            if (previousVerticalMargin.collapsedValues() && previousVerticalMargin.collapsedValues()->after) {
196
            if (previousVerticalMargin.collapsedValues().after) {
197
                previousVerticalMargin.setCollapsedValues({ previousVerticalMargin.collapsedValues()->before, { } });
197
                previousVerticalMargin.setCollapsedValues({ previousVerticalMargin.collapsedValues().before, { } });
198
                previousInFlowDisplayBox.setVerticalMargin(previousVerticalMargin);
198
                previousInFlowDisplayBox.setVerticalMargin(previousVerticalMargin);
199
            }
199
            }
200
            // FIXME: check if collapsing through has anything to do with this.
200
            // FIXME: check if collapsing through has anything to do with this.
201
            auto verticalMargin = displayBox.verticalMargin();
201
            auto verticalMargin = displayBox.verticalMargin();
202
            if (verticalMargin.collapsedValues() && verticalMargin.collapsedValues()->before) {
202
            if (verticalMargin.collapsedValues().before) {
203
                verticalMargin.setCollapsedValues({ { }, verticalMargin.collapsedValues()->after });
203
                verticalMargin.setCollapsedValues({ { }, verticalMargin.collapsedValues().after });
204
                displayBox.setVerticalMargin(verticalMargin);
204
                displayBox.setVerticalMargin(verticalMargin);
205
            }
205
            }
206
206
- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp -1 / +1 lines
Lines 362-368 void InlineFormattingContext::computeHeightAndMargin(const Box& layoutBox) const a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp_sec1
362
362
363
    auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
363
    auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
364
    displayBox.setContentBoxHeight(heightAndMargin.height);
364
    displayBox.setContentBoxHeight(heightAndMargin.height);
365
    displayBox.setVerticalMargin(heightAndMargin.margin);
365
    displayBox.setVerticalMargin(heightAndMargin.usedMargin);
366
}
366
}
367
367
368
void InlineFormattingContext::layoutFormattingContextRoot(const Box& root) const
368
void InlineFormattingContext::layoutFormattingContextRoot(const Box& root) const

Return to Bug 193168