Modified: trunk/LayoutTests/ChangeLog (266887 => 266888)
--- trunk/LayoutTests/ChangeLog 2020-09-10 19:56:07 UTC (rev 266887)
+++ trunk/LayoutTests/ChangeLog 2020-09-10 20:08:40 UTC (rev 266888)
@@ -1,3 +1,13 @@
+2020-09-10 Zalan Bujtas <[email protected]>
+
+ [LFC][IFC] Construct LineBox::InlineBoxes for nested inline level boxes when they overlap multiple lines
+ https://bugs.webkit.org/show_bug.cgi?id=216369
+
+ Reviewed by Antti Koivisto.
+
+ * fast/layoutformattingcontext/inline-box-overlaps-multiple-lines-expected.html: Added.
+ * fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html: Added.
+
2020-09-10 Wenson Hsieh <[email protected]>
REGRESSION (r257839): clickpay.com - password placeholder text cannot be replaced
Added: trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines-expected.html (0 => 266888)
--- trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines-expected.html (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines-expected.html 2020-09-10 20:08:40 UTC (rev 266888)
@@ -0,0 +1,8 @@
+<!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+div {
+ background: green;
+ font-size: 20px;
+}
+</style>
+<div>line break<br>this text's parent inline box starts at the previous line</div>
Added: trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html (0 => 266888)
--- trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html 2020-09-10 20:08:40 UTC (rev 266888)
@@ -0,0 +1,8 @@
+<!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+div {
+ background: green;
+ font-size: 20px;
+}
+</style>
+<div><span>line break<br>this text's parent inline box <span>starts at the previous line</span></span></div>
Modified: trunk/Source/WebCore/ChangeLog (266887 => 266888)
--- trunk/Source/WebCore/ChangeLog 2020-09-10 19:56:07 UTC (rev 266887)
+++ trunk/Source/WebCore/ChangeLog 2020-09-10 20:08:40 UTC (rev 266888)
@@ -1,3 +1,30 @@
+2020-09-10 Zalan Bujtas <[email protected]>
+
+ [LFC][IFC] Construct LineBox::InlineBoxes for nested inline level boxes when they overlap multiple lines
+ https://bugs.webkit.org/show_bug.cgi?id=216369
+
+ Reviewed by Antti Koivisto.
+
+ An inline box may not necessarily start on the current line:
+
+ <span id=outer>line break
+ <br>
+ this content's parent inline box('outer') <span id=inner>starts on the previous line</span>
+ </span>
+
+ We need to make sure that there's an LineBox::InlineBox for every inline box that's present on the current line.
+ (both 'outer' and 'inner' inline boxes have to have a corresponding LineBox::InlineBox here to be able to compute their geometry)
+ They normally get constructed when when we see a [container start] run, but when the nesting level > 1 at the start of the line,
+ we will not see those [container start] runs.
+ In such cases we need to create LineBox::InlineBoxes for the inline box ancestors.
+ We only have to do it on the first run as any subsequent inline content is either at the same/higher nesting level or
+ nested with a [container start] run.
+
+ Test: fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html
+
+ * layout/inlineformatting/InlineLineBox.cpp:
+ (WebCore::Layout::LineBox::constructInlineBoxes):
+
2020-09-10 Wenson Hsieh <[email protected]>
REGRESSION (r257839): clickpay.com - password placeholder text cannot be replaced
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp (266887 => 266888)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp 2020-09-10 19:56:07 UTC (rev 266887)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp 2020-09-10 20:08:40 UTC (rev 266888)
@@ -159,6 +159,33 @@
m_inlineBoxRectMap.set(&root(), &m_rootInlineBox);
};
constructRootInlineBox();
+ if (!runs.isEmpty()) {
+ // An inline box may not necessarily start on the current line:
+ // <span id=outer>line break<br>this content's parent inline box('outer') <span id=inner>starts on the previous line</span></span>
+ // We need to make sure that there's an LineBox::InlineBox for every inline box that's present on the current line.
+ // In nesting case we need to create LineBox::InlineBoxes for the inline box ancestors.
+ // We only have to do it on the first run as any subsequent inline content is either at the same/higher nesting level or
+ // nested with a [container start] run.
+ auto& firstRunParentInlineBox = runs[0].layoutBox().parent();
+ // If the parent is the root(), we can stop here. This is root inline box content, there's no nesting inline box from the previous line(s).
+ if (&firstRunParentInlineBox != &root()) {
+ auto* ancestor = &firstRunParentInlineBox;
+ Vector<const Box*> ancestorsWithoutInlineBoxes;
+ while (ancestor != &root()) {
+ ancestorsWithoutInlineBoxes.append(ancestor);
+ ancestor = &ancestor->parent();
+ }
+ // Construct the missing LineBox::InlineBoxes starting with the topmost ancestor.
+ for (auto* ancestor : WTF::makeReversedRange(ancestorsWithoutInlineBoxes)) {
+ auto& fontMetrics = ancestor->style().fontMetrics();
+ InlineLayoutUnit logicalHeight = fontMetrics.height();
+ auto inlineBoxRect = Display::InlineRect { { }, m_horizontalAlignmentOffset.valueOr(InlineLayoutUnit { }), logicalWidth(), logicalHeight };
+ auto inlineBox = makeUnique<InlineBox>(*ancestor, inlineBoxRect, fontMetrics.ascent(), fontMetrics.descent(), InlineBox::IsConsideredEmpty::No);
+ m_inlineBoxRectMap.set(ancestor, inlineBox.get());
+ m_inlineBoxList.append(WTFMove(inlineBox));
+ }
+ }
+ }
for (auto& run : runs) {
auto& inlineLevelBox = run.layoutBox();
@@ -196,8 +223,8 @@
auto& fontMetrics = inlineLevelBox.style().fontMetrics();
InlineLayoutUnit logicalHeight = fontMetrics.height();
InlineLayoutUnit baseline = fontMetrics.ascent();
- auto inlineBoxRect = Display::InlineRect { { }, inlineBoxLogicalLeft, initialWidth, logicalHeight };
- auto inlineBox = makeUnique<InlineBox>(inlineLevelBox, inlineBoxRect, baseline, logicalHeight - baseline, InlineBox::IsConsideredEmpty::Yes);
+ auto logicalRect = Display::InlineRect { { }, inlineBoxLogicalLeft, initialWidth, logicalHeight };
+ auto inlineBox = makeUnique<InlineBox>(inlineLevelBox, logicalRect, baseline, logicalHeight - baseline, InlineBox::IsConsideredEmpty::Yes);
m_inlineBoxRectMap.set(&inlineLevelBox, inlineBox.get());
m_inlineBoxList.append(WTFMove(inlineBox));
} else if (run.isContainerEnd()) {
@@ -204,8 +231,8 @@
// Adjust the logical width when the inline level container closes on this line.
auto& inlineBox = *m_inlineBoxRectMap.get(&inlineLevelBox);
inlineBox.setLogicalWidth(run.logicalRight() - inlineBox.logicalLeft());
- } else if ((run.isText() || run.isLineBreak())) {
- auto& containerBox = run.layoutBox().parent();
+ } else if (run.isText() || run.isLineBreak()) {
+ auto& containerBox = inlineLevelBox.parent();
&containerBox == &root() ? m_rootInlineBox.setIsNonEmpty() : m_inlineBoxRectMap.get(&containerBox)->setIsNonEmpty();
}
}