⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 271481 in webkit


Ignore:
Timestamp:
Jan 14, 2021, 6:30:19 AM (6 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC][Quirk] Let's adopt a less quirky behavior for line breaks on non-empty lines
https://bugs.webkit.org/show_bug.cgi?id=220252

Reviewed by Antti Koivisto.

WebKit has this quirk behavior where <br> stretches the line box vertically only when the line is empty.
e.g.

<div><span><br></span></div>
We make the line as tall as the <br> is but

<div>some content<span style="font-size: 200px;"><br></span></div>
does not produce a ~200px tall line.

However when horizontal padding/border added, the line suddenly becomes ~200px tall:
<div>some content<span style="font-size: 200px; padding: 1px;"><br></span></div>

Removing this quirk makes the inlineLevelBoxAffectsLineBox logic simpler since we don't have to check against
whether the line is considered empty and the result is aligned with Chrome's behavior.
(This is in preparation for getting rid of the is-considered-empty concept for line/line box.)

  • layout/inlineformatting/InlineFormattingContextGeometry.cpp:

(WebCore::Layout::LineBoxBuilder::constructInlineLevelBoxes):

  • layout/inlineformatting/InlineFormattingContextQuirks.cpp:

(WebCore::Layout::InlineFormattingContext::Quirks::inlineLevelBoxAffectsLineBox const):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r271480 r271481  
     12021-01-14  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC][Quirk] Let's adopt a less quirky behavior for line breaks on non-empty lines
     4        https://bugs.webkit.org/show_bug.cgi?id=220252
     5
     6        Reviewed by Antti Koivisto.
     7
     8        WebKit has this quirk behavior where <br> stretches the line box vertically only when the line is empty.
     9        e.g.
     10
     11        <div><span><br></span></div>
     12        We make the line as tall as the <br> is but
     13
     14        <div>some content<span style="font-size: 200px;"><br></span></div>
     15        does not produce a ~200px tall line.
     16
     17        However when horizontal padding/border added, the line suddenly becomes ~200px tall:
     18        <div>some content<span style="font-size: 200px; padding: 1px;"><br></span></div>
     19
     20        Removing this quirk makes the inlineLevelBoxAffectsLineBox logic simpler since we don't have to check against
     21        whether the line is considered empty and the result is aligned with Chrome's behavior.
     22        (This is in preparation for getting rid of the is-considered-empty concept for line/line box.)
     23
     24        * layout/inlineformatting/InlineFormattingContextGeometry.cpp:
     25        (WebCore::Layout::LineBoxBuilder::constructInlineLevelBoxes):
     26        * layout/inlineformatting/InlineFormattingContextQuirks.cpp:
     27        (WebCore::Layout::InlineFormattingContext::Quirks::inlineLevelBoxAffectsLineBox const):
     28
    1292021-01-14  Martin Robinson  <mrobinson@igalia.com>
    230
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp

    r271415 r271481  
    4545bool InlineFormattingContext::Quirks::inlineLevelBoxAffectsLineBox(const LineBox::InlineLevelBox& inlineLevelBox, const LineBox& lineBox) const
    4646{
     47    if (inlineLevelBox.isLineBreakBox()) {
     48        if (layoutState().inNoQuirksMode())
     49            return true;
     50        // In quirks mode linebreak boxes (<br>) affect the line box when they are inside a non-root inline box (<span></span>) or when
     51        // the line has no other inline level box/root inlinebox has no content.
     52        auto& parentInlineBox = lineBox.inlineLevelBoxForLayoutBox(inlineLevelBox.layoutBox().parent());
     53        if (!parentInlineBox.isRootInlineBox())
     54            return true;
     55        return !parentInlineBox.hasContent() && lineBox.nonRootInlineLevelBoxes().size() == 1;
     56    }
    4757    if (inlineLevelBox.isInlineBox()) {
    4858        // Inline boxes (e.g. root inline box or <span>) affects line boxes either through the strut or actual content.
     
    5868        auto inlineBoxHasImaginaryStrut = layoutState().inNoQuirksMode();
    5969        return inlineBoxHasImaginaryStrut && !lineBox.isConsideredEmpty();
    60     }
    61     if (inlineLevelBox.isLineBreakBox()) {
    62         // <br> in non-standard mode stretches the line box only when the line is empty.
    63         // e.g. <div><span><br></span></div> will stretch but <div>this will not stretch to 200px<span style="font-size: 200px;"><br></span></div>
    64         return layoutState().inNoQuirksMode() ? true : lineBox.isConsideredEmpty();
    6570    }
    6671    if (inlineLevelBox.isAtomicInlineLevelBox()) {
  • trunk/Source/WebCore/rendering/InlineFlowBox.cpp

    r271284 r271481  
    138138                // FIXME: This isn't ideal. We only turn off because current layout test results expect the <br> to be 0-height on the baseline.
    139139                // Other than making a zillion tests have to regenerate results, there's no reason to ditch the optimization here.
    140                 shouldClearDescendantsHaveSameLineHeightAndBaseline = child->renderer().isBR();
     140                auto childIsHardLinebreak = child->renderer().isBR();
     141                shouldClearDescendantsHaveSameLineHeightAndBaseline = childIsHardLinebreak;
     142                m_hasHardLinebreak = m_hasHardLinebreak || childIsHardLinebreak;
    141143            } else {
    142144                auto& childFlowBox = downcast<InlineFlowBox>(*child);
     
    596598            if (maxPositionBottom < boxHeight)
    597599                maxPositionBottom = boxHeight;
    598         } else if (!inlineFlowBox || strictMode || inlineFlowBox->hasTextChildren() || (inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && inlineFlowBox->hasTextDescendants())
    599                    || inlineFlowBox->renderer().hasInlineDirectionBordersOrPadding()) {
     600        } else if (strictMode
     601            || !inlineFlowBox
     602            || inlineFlowBox->hasTextChildren()
     603            || (inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && inlineFlowBox->hasTextDescendants())
     604            || inlineFlowBox->renderer().hasInlineDirectionBordersOrPadding()
     605            || inlineFlowBox->hasHardLinebreak()) {
    600606            // Note that these values can be negative.  Even though we only affect the maxAscent and maxDescent values
    601607            // if our box (excluding line-height) was above (for ascent) or below (for descent) the root baseline, once you factor in line-height
  • trunk/Source/WebCore/rendering/InlineFlowBox.h

    r256196 r271481  
    4545        , m_includeLogicalLeftEdge(false)
    4646        , m_includeLogicalRightEdge(false)
     47        , m_hasHardLinebreak(false)
    4748        , m_descendantsHaveSameLineHeightAndBaseline(true)
    4849        , m_baselineType(AlphabeticBaseline)
     
    209210    bool hasTextChildren() const { return m_hasTextChildren; }
    210211    bool hasTextDescendants() const { return m_hasTextDescendants; }
     212    bool hasHardLinebreak() const { return m_hasHardLinebreak; }
    211213    void setHasTextChildren() { m_hasTextChildren = true; setHasTextDescendants(); }
    212214    void setHasTextDescendants() { m_hasTextDescendants = true; }
     
    313315    unsigned m_hasTextChildren : 1;
    314316    unsigned m_hasTextDescendants : 1;
     317    unsigned m_hasHardLinebreak : 1;
    315318    unsigned m_descendantsHaveSameLineHeightAndBaseline : 1;
    316319
  • trunk/Source/WebCore/rendering/RenderInline.cpp

    r270220 r271481  
    213213    auto* parentStyle = &parent()->style();
    214214    RenderInline* parentRenderInline = is<RenderInline>(*parent()) ? downcast<RenderInline>(parent()) : nullptr;
     215    auto hasHardLineBreakChildOnly = firstChild() && firstChild() == lastChild() && firstChild()->isBR();
    215216    bool checkFonts = document().inNoQuirksMode();
    216217    bool alwaysCreateLineBoxes = (parentRenderInline && parentRenderInline->alwaysCreateLineBoxes())
     
    219220        || style().textEmphasisMark() != TextEmphasisMark::None
    220221        || (checkFonts && (!parentStyle->fontCascade().fontMetrics().hasIdenticalAscentDescentAndLineGap(style().fontCascade().fontMetrics())
    221         || parentStyle->lineHeight() != style().lineHeight()));
     222        || parentStyle->lineHeight() != style().lineHeight()))
     223        || hasHardLineBreakChildOnly;
    222224
    223225    if (!alwaysCreateLineBoxes && checkFonts && view().usesFirstLineRules()) {
Note: See TracChangeset for help on using the changeset viewer.