Diff
Modified: trunk/Source/WebCore/ChangeLog (281574 => 281575)
--- trunk/Source/WebCore/ChangeLog 2021-08-25 19:40:21 UTC (rev 281574)
+++ trunk/Source/WebCore/ChangeLog 2021-08-25 19:50:35 UTC (rev 281575)
@@ -1,3 +1,44 @@
+2021-08-25 Alan Bujtas <[email protected]>
+
+ [LFC][IFC] Line spanning inline boxes should also be in the run list
+ https://bugs.webkit.org/show_bug.cgi?id=228059
+ <rdar://problem/81077420>
+
+ Reviewed by Antti Koivisto.
+
+ Consider the following case:
+ <div><span>first line text<br>second line text<br>third line text</span></div>
+
+ Here is the list of runs we generate for the content above:
+
+ [inline box][first line text][hard linebreak][second line text][hard linebreak][third line text]
+
+ This list does not include the spanning inline boxes, i.e. the missing inline box on the second and the third line.
+ The integration code then looks inside the LineBox to find these spanning inline boxes (see createDisplayNonRootInlineBoxes)
+
+ In this patch we start including such spanning inline boxes in the run list.
+ [inline box][first line text][hard linebreak][inline box][second line text][hard linebreak][inline box][third line text]
+
+ This is also in preparation for making LineBox completely internal to the layout code.
+
+ * layout/formattingContexts/inline/InlineFormattingContext.cpp:
+ (WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
+ * layout/formattingContexts/inline/InlineLineRun.h:
+ (WebCore::Layout::LineRun::isText const):
+ (WebCore::Layout::LineRun::isLineBreak const):
+ (WebCore::Layout::LineRun::isAtomicInlineLevelBox const):
+ (WebCore::Layout::LineRun::isInlineBox const):
+ (WebCore::Layout::LineRun::isRootInlineBox const):
+ (WebCore::Layout::LineRun::type const):
+ (WebCore::Layout::LineRun::hasContent const):
+ (WebCore::Layout::LineRun::isLineSpanning const):
+ (WebCore::Layout::LineRun::LineRun):
+ * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+ (WebCore::LayoutIntegration::InlineContentBuilder::build const):
+ (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLineRuns const):
+ (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayNonRootInlineBoxes const): Deleted.
+ * layout/integration/LayoutIntegrationInlineContentBuilder.h:
+
2021-08-25 Sonia Singla <[email protected]>
Add onsecuritypolicyviolation on GlobalEventHandlers
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp (281574 => 281575)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp 2021-08-25 19:40:21 UTC (rev 281574)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp 2021-08-25 19:50:35 UTC (rev 281575)
@@ -605,6 +605,9 @@
return lineBoxLogicalRect;
}
+ // Spanning inline boxes start at the very beginning of the line.
+ // FIXME: Offset it with the run for the root inline box, when we start constructing runs for them.
+ auto lineSpanningInlineBoxIndex = formattingState.lineRuns().size();
HashSet<const Box*> inlineBoxStartSet;
auto constructLineRunsAndUpdateBoxGeometry = [&] {
// Create the inline runs on the current line. This is mostly text and atomic inline runs.
@@ -612,7 +615,7 @@
// FIXME: We should not need to construct a line run for <br>.
auto& layoutBox = lineRun.layoutBox();
if (lineRun.isText()) {
- formattingState.addLineRun({ lineIndex, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
+ formattingState.addLineRun({ lineIndex, LineRun::Type::Text, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
continue;
}
if (lineRun.isLineBreak()) {
@@ -619,7 +622,7 @@
if (layoutBox.isLineBreakBox()) {
// Only hard linebreaks have associated layout boxes.
auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox);
- formattingState.addLineRun({ lineIndex, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
+ formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreak, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
lineBreakBoxRect.moveBy(lineBoxLogicalRect.topLeft());
@@ -626,7 +629,7 @@
boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height()));
} else
- formattingState.addLineRun({ lineIndex, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
+ formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreak, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
continue;
}
if (lineRun.isBox()) {
@@ -633,7 +636,7 @@
ASSERT(layoutBox.isAtomicInlineLevelBox());
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
auto logicalBorderBox = lineBox.logicalBorderBoxForAtomicInlineLevelBox(layoutBox, boxGeometry);
- formattingState.addLineRun({ lineIndex, layoutBox, logicalBorderBox, lineRun.expansion(), { } });
+ formattingState.addLineRun({ lineIndex, LineRun::Type::AtomicInlineLevelBox, layoutBox, logicalBorderBox, lineRun.expansion(), { } });
auto borderBoxLogicalTopLeft = logicalBorderBox.topLeft();
// Note that inline boxes are relative to the line and their top position can be negative.
@@ -647,7 +650,7 @@
if (lineRun.isInlineBoxStart()) {
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
auto inlineBoxLogicalRect = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
- formattingState.addLineRun({ lineIndex, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { } });
+ formattingState.addLineRun({ lineIndex, LineRun::Type::InlineBox, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
inlineBoxStartSet.add(&layoutBox);
continue;
}
@@ -682,6 +685,8 @@
continue;
}
// Middle or end of the inline box. Let's stretch the box as needed.
+ formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::InlineBox, layoutBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
+
auto enclosingBorderBoxRect = BoxGeometry::borderBoxRect(boxGeometry);
enclosingBorderBoxRect.expandToContain(logicalRect);
boxGeometry.setLogicalLeft(enclosingBorderBoxRect.left());
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h (281574 => 281575)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h 2021-08-25 19:40:21 UTC (rev 281574)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h 2021-08-25 19:50:35 UTC (rev 281575)
@@ -59,9 +59,27 @@
String m_contentString;
};
+ enum class Type {
+ Text,
+ LineBreak,
+ AtomicInlineLevelBox,
+ InlineBox,
+ RootInlineBox,
+ GenericInlineLevelBox
+ };
struct Expansion;
- LineRun(size_t lineIndex, const Box&, const InlineRect&, Expansion, std::optional<Text> = std::nullopt);
+ LineRun(size_t lineIndex, Type, const Box&, const InlineRect&, Expansion, std::optional<Text> = std::nullopt, bool hasContent = true, bool isLineSpanning = false);
+ bool isText() const { return m_type == Type::Text; }
+ bool isLineBreak() const { return m_type == Type::LineBreak; }
+ bool isAtomicInlineLevelBox() const { return m_type == Type::AtomicInlineLevelBox; }
+ bool isInlineBox() const { return m_type == Type::InlineBox || isRootInlineBox(); }
+ bool isRootInlineBox() const { return m_type == Type::RootInlineBox; }
+ Type type() const { return m_type; }
+
+ bool hasContent() const { return m_hasContent; }
+ bool isLineSpanning() const { return m_isLineSpanning; }
+
const InlineRect& logicalRect() const { return m_logicalRect; }
InlineLayoutUnit logicalTop() const { return logicalRect().top(); }
@@ -87,16 +105,23 @@
private:
const size_t m_lineIndex;
+ const Type m_type;
WeakPtr<const Layout::Box> m_layoutBox;
InlineRect m_logicalRect;
+ bool m_hasContent { true };
+ // FIXME: This is temporary until after iterators can skip over line spanning/root inline boxes.
+ bool m_isLineSpanning { false };
Expansion m_expansion;
std::optional<Text> m_text;
};
-inline LineRun::LineRun(size_t lineIndex, const Layout::Box& layoutBox, const InlineRect& logicalRect, Expansion expansion, std::optional<Text> text)
+inline LineRun::LineRun(size_t lineIndex, Type type, const Layout::Box& layoutBox, const InlineRect& logicalRect, Expansion expansion, std::optional<Text> text, bool hasContent, bool isLineSpanning)
: m_lineIndex(lineIndex)
+ , m_type(type)
, m_layoutBox(makeWeakPtr(layoutBox))
, m_logicalRect(logicalRect)
+ , m_hasContent(hasContent)
+ , m_isLineSpanning(isLineSpanning)
, m_expansion(expansion)
, m_text(text)
{
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (281574 => 281575)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp 2021-08-25 19:40:21 UTC (rev 281574)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp 2021-08-25 19:50:35 UTC (rev 281575)
@@ -166,7 +166,6 @@
{
auto lineLevelVisualAdjustmentsForRuns = computeLineLevelVisualAdjustmentsForRuns(inlineFormattingState);
createDisplayLineRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns(), inlineContent, lineLevelVisualAdjustmentsForRuns);
- createDisplayNonRootInlineBoxes(inlineFormattingState, inlineContent);
createDisplayLines(inlineFormattingState.lines(), inlineContent, lineLevelVisualAdjustmentsForRuns);
}
@@ -245,7 +244,20 @@
runRect.setY(roundToInt(runRect.y()));
// FIXME: Add support for non-text ink overflow.
// FIXME: Add support for cases when the run is after ellipsis.
- inlineContent.runs.append({ lineIndex, layoutBox, runRect, runRect, { }, { } });
+ if (lineRun.isInlineBox()) {
+ auto lineRunRect = lineRun.logicalRect();
+ lineRunRect.moveBy(lineBoxLogicalRect.topLeft());
+ auto hasScrollableContent = [&] {
+ // In standards mode, inline boxes always start with an imaginary strut.
+ return m_layoutState.inStandardsMode() || lineRun.hasContent() || geometry.horizontalBorder() || (geometry.horizontalPadding() && geometry.horizontalPadding().value());
+ };
+ inlineContent.nonRootInlineBoxes.append({ lineIndex, layoutBox, lineRunRect, hasScrollableContent() });
+ if (!lineRun.isLineSpanning()) {
+ // FIXME: Run iterators with (text)runs spanning over multiple lines expect no "in-between" runs (e.g. line spanning or root inline boxes).
+ inlineContent.runs.append({ lineIndex, layoutBox, runRect, runRect, { }, { } });
+ }
+ } else
+ inlineContent.runs.append({ lineIndex, layoutBox, runRect, runRect, { }, { } });
};
auto createDisplayTextRunForRange = [&](auto& lineRun, auto startOffset, auto endOffset) {
@@ -368,32 +380,7 @@
}
}
-void InlineContentBuilder::createDisplayNonRootInlineBoxes(const Layout::InlineFormattingState& inlineFormattingState, InlineContent& inlineContent) const
-{
- for (size_t lineIndex = 0; lineIndex < inlineFormattingState.lineBoxes().size(); ++lineIndex) {
- auto& lineBox = inlineFormattingState.lineBoxes()[lineIndex];
- if (!lineBox.hasInlineBox())
- continue;
-
- auto lineBoxLogicalRect = inlineFormattingState.lines()[lineIndex].lineBoxLogicalRect();
- for (auto& inlineLevelBox : lineBox.nonRootInlineLevelBoxes()) {
- if (!inlineLevelBox.isInlineBox())
- continue;
- auto& layoutBox = inlineLevelBox.layoutBox();
- auto& boxGeometry = m_layoutState.geometryForBox(layoutBox);
- auto inlineBoxRect = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
- inlineBoxRect.moveBy(lineBoxLogicalRect.topLeft());
-
- auto hasScrollableContent = [&] {
- // In standards mode, inline boxes always start with an imaginary strut.
- return m_layoutState.inStandardsMode() || inlineLevelBox.hasContent() || boxGeometry.horizontalBorder() || (boxGeometry.horizontalPadding() && boxGeometry.horizontalPadding().value());
- };
- inlineContent.nonRootInlineBoxes.append({ lineIndex, layoutBox, inlineBoxRect, hasScrollableContent() });
- }
- }
}
-
}
-}
#endif
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h (281574 => 281575)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h 2021-08-25 19:40:21 UTC (rev 281574)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h 2021-08-25 19:50:35 UTC (rev 281575)
@@ -52,7 +52,6 @@
LineLevelVisualAdjustmentsForRunsList computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineFormattingState&) const;
void createDisplayLineRuns(const Layout::InlineLines&, const Layout::InlineLineRuns&, InlineContent&, const LineLevelVisualAdjustmentsForRunsList&) const;
void createDisplayLines(const Layout::InlineLines&, InlineContent&, const LineLevelVisualAdjustmentsForRunsList&) const;
- void createDisplayNonRootInlineBoxes(const Layout::InlineFormattingState&, InlineContent&) const;
const Layout::LayoutState& m_layoutState;
const RenderBlockFlow& m_blockFlow;