Diff
Modified: trunk/LayoutTests/ChangeLog (290866 => 290867)
--- trunk/LayoutTests/ChangeLog 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/LayoutTests/ChangeLog 2022-03-05 16:57:58 UTC (rev 290867)
@@ -1,3 +1,13 @@
+2022-03-05 Antti Koivisto <an...@apple.com>
+
+ Resolve ::first-line style eagerly
+ https://bugs.webkit.org/show_bug.cgi?id=237362
+
+ Reviewed by Alan Bujtas.
+
+ * TestExpectations:
+ * platform/mac/fast/forms/input-baseline-expected.txt:
+
2022-03-05 Youenn Fablet <you...@apple.com>
Implement remote-inbound-rtp packetsLost
Modified: trunk/LayoutTests/TestExpectations (290866 => 290867)
--- trunk/LayoutTests/TestExpectations 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/LayoutTests/TestExpectations 2022-03-05 16:57:58 UTC (rev 290867)
@@ -4412,11 +4412,7 @@
webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/first-letter-exclude-inline-child-marker.html [ ImageOnlyFailure ]
webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/first-letter-exclude-inline-marker.html [ ImageOnlyFailure ]
webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/first-letter-list-item-dynamic-001.html [ ImageOnlyFailure ]
-webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/first-line-change-inline-color.html [ ImageOnlyFailure ]
-webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/first-line-change-inline-color-nested.html [ ImageOnlyFailure ]
webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/first-line-opacity-001.html [ ImageOnlyFailure ]
-webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/first-line-with-before-after.html [ ImageOnlyFailure ]
-webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/first-line-with-out-of-flow.html [ ImageOnlyFailure ]
webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/grammar-error-001.html [ ImageOnlyFailure ]
webkit.org/b/204163 imported/w3c/web-platform-tests/css/css-pseudo/marker-content-002.html [ ImageOnlyFailure ]
webkit.org/b/204163 imported/w3c/web-platform-tests/css/css-pseudo/marker-content-003.html [ ImageOnlyFailure ]
@@ -4443,7 +4439,6 @@
webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/marker-unicode-bidi-default.html [ ImageOnlyFailure ]
webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/marker-unicode-bidi-normal.html [ ImageOnlyFailure ]
webkit.org/b/214461 imported/w3c/web-platform-tests/css/css-pseudo/spelling-error-001.html [ ImageOnlyFailure ]
-webkit.org/b/230964 imported/w3c/web-platform-tests/css/css-pseudo/first-line-and-placeholder.html [ ImageOnlyFailure ]
webkit.org/b/214462 imported/w3c/web-platform-tests/css/css-scoping/host-context-specificity-001.html [ ImageOnlyFailure ]
webkit.org/b/214462 imported/w3c/web-platform-tests/css/css-scoping/host-context-specificity-002.html [ ImageOnlyFailure ]
@@ -4910,10 +4905,7 @@
webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/first-letter-punctuation-dynamic.html [ ImageOnlyFailure ]
webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/first-letter-skip-empty-span-nested.html [ ImageOnlyFailure ]
webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/first-letter-skip-empty-span.html [ ImageOnlyFailure ]
-webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/first-line-with-inline-block-before.html [ ImageOnlyFailure ]
webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/first-line-with-inline-block.html [ ImageOnlyFailure ]
-webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/first-line-with-out-of-flow-and-nested-div.html [ ImageOnlyFailure ]
-webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/first-line-with-out-of-flow-and-nested-span.html [ ImageOnlyFailure ]
webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/grammar-spelling-errors-001.html [ ImageOnlyFailure ]
webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/grammar-spelling-errors-002.html [ ImageOnlyFailure ]
webkit.org/b/230004 imported/w3c/web-platform-tests/css/css-pseudo/highlight-painting-001.html [ ImageOnlyFailure ]
Modified: trunk/LayoutTests/platform/gtk/fast/forms/input-baseline-expected.txt (290866 => 290867)
--- trunk/LayoutTests/platform/gtk/fast/forms/input-baseline-expected.txt 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/LayoutTests/platform/gtk/fast/forms/input-baseline-expected.txt 2022-03-05 16:57:58 UTC (rev 290867)
@@ -12,10 +12,10 @@
text run at (196,41) width 420: "This text should line up with the bottom of the text in the text field."
RenderBR {BR} at (616,41) size 0x17
RenderBR {BR} at (0,64) size 0x17
- RenderTextControl {INPUT} at (2,84) size 192x130 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
- RenderText {#text} at (196,172) size 420x17
- text run at (196,172) width 420: "This text should line up with the bottom of the text in the text field."
+ RenderTextControl {INPUT} at (2,84) size 192x24 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+ RenderText {#text} at (196,87) size 420x17
+ text run at (196,87) width 420: "This text should line up with the bottom of the text in the text field."
layer at (13,49) size 186x18
RenderBlock {DIV} at (3,3) size 186x18
-layer at (13,95) size 186x124
- RenderBlock {DIV} at (3,3) size 186x124
+layer at (13,95) size 186x18
+ RenderBlock {DIV} at (3,3) size 186x18
Modified: trunk/LayoutTests/platform/mac/fast/forms/input-baseline-expected.txt (290866 => 290867)
--- trunk/LayoutTests/platform/mac/fast/forms/input-baseline-expected.txt 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/LayoutTests/platform/mac/fast/forms/input-baseline-expected.txt 2022-03-05 16:57:58 UTC (rev 290867)
@@ -12,10 +12,10 @@
text run at (150,38) width 431: "This text should line up with the bottom of the text in the text field."
RenderBR {BR} at (580,38) size 1x18
RenderBR {BR} at (0,59) size 0x18
- RenderTextControl {INPUT} at (2,79) size 147x132 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
- RenderText {#text} at (150,171) size 431x18
- text run at (150,171) width 431: "This text should line up with the bottom of the text in the text field."
+ RenderTextControl {INPUT} at (2,79) size 147x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+ RenderText {#text} at (150,79) size 431x18
+ text run at (150,79) width 431: "This text should line up with the bottom of the text in the text field."
layer at (13,49) size 141x13
RenderBlock {DIV} at (3,3) size 141x13
-layer at (13,90) size 141x126
- RenderBlock {DIV} at (3,3) size 141x126
+layer at (13,90) size 141x13
+ RenderBlock {DIV} at (3,3) size 141x13
Modified: trunk/Source/WebCore/ChangeLog (290866 => 290867)
--- trunk/Source/WebCore/ChangeLog 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/ChangeLog 2022-03-05 16:57:58 UTC (rev 290867)
@@ -1,3 +1,58 @@
+2022-03-05 Antti Koivisto <an...@apple.com>
+
+ Resolve ::first-line style eagerly
+ https://bugs.webkit.org/show_bug.cgi?id=237362
+
+ Reviewed by Alan Bujtas.
+
+ Compute ::first-line style during style resolution instead of lazily in render tree.
+ This fixes bugs and clarifies the architecture in ways that a helpful for features like
+ container queries.
+
+ As a side effect it also makes ::first-line style animatable.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::firstLineBlock const): Deleted.
+ * rendering/RenderBlock.h:
+ * rendering/RenderElement.cpp:
+ (WebCore::RenderElement::RenderElement):
+ (WebCore::RenderElement::firstLineStyle const):
+ (WebCore::RenderElement::styleWillChange):
+ (WebCore::RenderElement::computeFirstLineStyle const): Deleted.
+ (WebCore::RenderElement::invalidateCachedFirstLineStyle): Deleted.
+ * rendering/RenderElement.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::firstLineBlock const): Deleted.
+ * rendering/RenderObject.h:
+ * rendering/RenderRubyRun.cpp:
+ (WebCore::RenderRubyRun::firstLineBlock const): Deleted.
+ * rendering/RenderRubyRun.h:
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::firstLineBlock const): Deleted.
+ * rendering/RenderTable.h:
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::findByDisplayContentsInlineWrapperCandidate): Deleted.
+ * rendering/RenderText.h:
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::getCachedPseudoStyle const):
+ * rendering/style/RenderStyle.h:
+ (WebCore::generatesBox):
+ * rendering/svg/RenderSVGText.cpp:
+ (WebCore::RenderSVGText::firstLineBlock const): Deleted.
+ * rendering/svg/RenderSVGText.h:
+ * rendering/updating/RenderTreeUpdaterGeneratedContent.cpp:
+ (WebCore::RenderTreeUpdater::GeneratedContent::updatePseudoElement):
+ * style/StyleTreeResolver.cpp:
+ (WebCore::Style::TreeResolver::resolveElement):
+ (WebCore::Style::TreeResolver::resolvePseudoElement):
+ (WebCore::Style::TreeResolver::resolveInheritedFirstLinePseudoElement):
+ (WebCore::Style::TreeResolver::makeResolutionContextForInheritedFirstLine):
+ (WebCore::Style::TreeResolver::boxGeneratingParent const const):
+ (WebCore::Style::TreeResolver::parentBoxStyle const):
+ (WebCore::Style::TreeResolver::resolveComposedTree):
+ (WebCore::Style::TreeResolver::resolvePseudoStyle): Deleted.
+ * style/StyleTreeResolver.h:
+
2022-03-05 Alan Bujtas <za...@apple.com>
[LFC][Integration] RenderInline should use ADD_REASONS_AND_RETURN_IF_NEEDED
Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderBlock.cpp 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp 2022-03-05 16:57:58 UTC (rev 290867)
@@ -2571,27 +2571,6 @@
return renderElement.isRenderBlockFlow() || renderElement.isRenderButton();
}
-RenderBlock* RenderBlock::firstLineBlock() const
-{
- RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
- bool hasPseudo = false;
- while (true) {
- hasPseudo = firstLineBlock->style().hasPseudoStyle(PseudoId::FirstLine);
- if (hasPseudo)
- break;
- RenderElement* parentBlock = firstLineBlock->parent();
- if (firstLineBlock->isReplacedOrInlineBlock() || firstLineBlock->isFloating()
- || !parentBlock || parentBlock->firstChild() != firstLineBlock || !isRenderBlockFlowOrRenderButton(*parentBlock))
- break;
- firstLineBlock = downcast<RenderBlock>(parentBlock);
- }
-
- if (!hasPseudo)
- return nullptr;
-
- return firstLineBlock;
-}
-
static inline RenderBlock* findFirstLetterBlock(RenderBlock* start)
{
RenderBlock* firstLetterBlock = start;
Modified: trunk/Source/WebCore/rendering/RenderBlock.h (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderBlock.h 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderBlock.h 2022-03-05 16:57:58 UTC (rev 290867)
@@ -383,9 +383,6 @@
// Adjust from painting offsets to the local coords of this renderer
void offsetForContents(LayoutPoint&) const;
- // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
- // children.
- RenderBlock* firstLineBlock() const override;
enum FieldsetFindLegendOption { FieldsetIgnoreFloatingOrOutOfFlow, FieldsetIncludeFloatingOrOutOfFlow };
RenderBox* findFieldsetLegend(FieldsetFindLegendOption = FieldsetIgnoreFloatingOrOutOfFlow) const;
Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderElement.cpp 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp 2022-03-05 16:57:58 UTC (rev 290867)
@@ -117,7 +117,6 @@
, m_hasContinuationChainNode(false)
, m_isContinuation(false)
, m_isFirstLetter(false)
- , m_hasValidCachedFirstLineStyle(false)
, m_renderBlockHasMarginBeforeQuirk(false)
, m_renderBlockHasMarginAfterQuirk(false)
, m_renderBlockShouldForceRelayoutChildren(false)
@@ -224,62 +223,21 @@
return nullptr;
}
-std::unique_ptr<RenderStyle> RenderElement::computeFirstLineStyle() const
-{
- ASSERT(view().usesFirstLineRules());
-
- RenderElement& rendererForFirstLineStyle = isBeforeOrAfterContent() ? *parent() : const_cast<RenderElement&>(*this);
-
- if (rendererForFirstLineStyle.isRenderBlockFlow() || rendererForFirstLineStyle.isRenderButton()) {
- RenderBlock* firstLineBlock = rendererForFirstLineStyle.firstLineBlock();
- if (!firstLineBlock)
- return nullptr;
- auto* firstLineStyle = firstLineBlock->getCachedPseudoStyle(PseudoId::FirstLine, &style());
- if (!firstLineStyle)
- return nullptr;
- return RenderStyle::clonePtr(*firstLineStyle);
- }
-
- if (!rendererForFirstLineStyle.isRenderInline())
- return nullptr;
-
- auto& parentStyle = rendererForFirstLineStyle.parent()->firstLineStyle();
- if (&parentStyle == &rendererForFirstLineStyle.parent()->style())
- return nullptr;
-
- if (rendererForFirstLineStyle.isAnonymous()) {
- auto* textRendererWithDisplayContentsParent = RenderText::findByDisplayContentsInlineWrapperCandidate(rendererForFirstLineStyle);
- if (!textRendererWithDisplayContentsParent)
- return nullptr;
- auto* composedTreeParentElement = textRendererWithDisplayContentsParent->textNode()->parentElementInComposedTree();
- if (!composedTreeParentElement)
- return nullptr;
-
- auto style = composedTreeParentElement->styleResolver().styleForElement(*composedTreeParentElement, { &parentStyle }).renderStyle;
- ASSERT(style->display() == DisplayType::Contents);
-
- // We act as if there was an unstyled <span> around the text node. Only styling happens via inheritance.
- auto firstLineStyle = RenderStyle::createPtr();
- firstLineStyle->inheritFrom(*style);
- return firstLineStyle;
- }
-
- return rendererForFirstLineStyle.element()->styleResolver().styleForElement(*element(), { &parentStyle }).renderStyle;
-}
-
const RenderStyle& RenderElement::firstLineStyle() const
{
- if (!view().usesFirstLineRules())
+ // FIXME: It would be better to just set anonymous block first-line styles correctly.
+ if (isAnonymousBlock()) {
+ if (!previousInFlowSibling()) {
+ if (auto* firstLineStyle = parent()->style().getCachedPseudoStyle(PseudoId::FirstLine))
+ return *firstLineStyle;
+ }
return style();
-
- if (!m_hasValidCachedFirstLineStyle) {
- auto firstLineStyle = computeFirstLineStyle();
- if (firstLineStyle || hasRareData())
- const_cast<RenderElement&>(*this).ensureRareData().cachedFirstLineStyle = WTFMove(firstLineStyle);
- m_hasValidCachedFirstLineStyle = true;
}
- return (hasRareData() && rareData().cachedFirstLineStyle) ? *rareData().cachedFirstLineStyle : style();
+ if (auto* firstLineStyle = style().getCachedPseudoStyle(PseudoId::FirstLine))
+ return *firstLineStyle;
+
+ return style();
}
StyleDifference RenderElement::adjustStyleDifference(StyleDifference diff, OptionSet<StyleDifferenceContextSensitiveProperty> contextSensitiveProperties) const
@@ -805,16 +763,6 @@
return renderer && renderer->hasBackground();
}
-void RenderElement::invalidateCachedFirstLineStyle()
-{
- if (!m_hasValidCachedFirstLineStyle)
- return;
- m_hasValidCachedFirstLineStyle = false;
- // Invalidate the subtree as descendant's first line style may depend on ancestor's.
- for (auto& descendant : descendantsOfType<RenderElement>(*this))
- descendant.m_hasValidCachedFirstLineStyle = false;
-}
-
void RenderElement::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
ASSERT(settings().shouldAllowUserInstalledFonts() || newStyle.fontDescription().shouldAllowUserInstalledFonts() == AllowUserInstalledFonts::No);
@@ -885,9 +833,6 @@
clearPositionedState();
}
- if (newStyle.hasPseudoStyle(PseudoId::FirstLine) || oldStyle->hasPseudoStyle(PseudoId::FirstLine))
- invalidateCachedFirstLineStyle();
-
setHorizontalWritingMode(true);
setHasVisibleBoxDecorations(false);
setHasNonVisibleOverflow(false);
Modified: trunk/Source/WebCore/rendering/RenderElement.h (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderElement.h 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderElement.h 2022-03-05 16:57:58 UTC (rev 290867)
@@ -351,8 +351,6 @@
void updateShapeImage(const ShapeValue*, const ShapeValue*);
StyleDifference adjustStyleDifference(StyleDifference, OptionSet<StyleDifferenceContextSensitiveProperty>) const;
- std::unique_ptr<RenderStyle> computeFirstLineStyle() const;
- void invalidateCachedFirstLineStyle();
bool canDestroyDecodedData() final { return !isVisibleInViewport(); }
VisibleInViewportState imageFrameAvailable(CachedImage&, ImageAnimatingState, const IntRect* changeRect) final;
@@ -381,7 +379,6 @@
unsigned m_hasContinuationChainNode : 1;
unsigned m_isContinuation : 1;
unsigned m_isFirstLetter : 1;
- mutable unsigned m_hasValidCachedFirstLineStyle : 1;
unsigned m_renderBlockHasMarginBeforeQuirk : 1;
unsigned m_renderBlockHasMarginAfterQuirk : 1;
Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderObject.cpp 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp 2022-03-05 16:57:58 UTC (rev 290867)
@@ -491,11 +491,6 @@
return document().documentElement() ? document().documentElement()->renderBox() : nullptr;
}
-RenderBlock* RenderObject::firstLineBlock() const
-{
- return nullptr;
-}
-
static inline bool objectIsRelayoutBoundary(const RenderElement* object)
{
// FIXME: In future it may be possible to broaden these conditions in order to improve performance.
Modified: trunk/Source/WebCore/rendering/RenderObject.h (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderObject.h 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderObject.h 2022-03-05 16:57:58 UTC (rev 290867)
@@ -173,9 +173,6 @@
// Creates a scope where this object will assert on calls to setNeedsLayout().
class SetLayoutNeededForbiddenScope;
-
- // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline children.
- virtual RenderBlock* firstLineBlock() const;
// RenderObject tree manipulation
//////////////////////////////////////////
@@ -946,7 +943,6 @@
ADD_BOOLEAN_BITFIELD(paintContainmentApplies, PaintContainmentApplies);
// From RenderElement
- std::unique_ptr<RenderStyle> cachedFirstLineStyle;
std::unique_ptr<ReferencedSVGResources> referencedSVGResources;
WeakPtr<RenderBlockFlow> backdropRenderer;
};
Modified: trunk/Source/WebCore/rendering/RenderRubyRun.cpp (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderRubyRun.cpp 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderRubyRun.cpp 2022-03-05 16:57:58 UTC (rev 290867)
@@ -85,11 +85,6 @@
return child && child->isRubyBase() ? static_cast<RenderRubyBase*>(child) : nullptr;
}
-RenderBlock* RenderRubyRun::firstLineBlock() const
-{
- return nullptr;
-}
-
bool RenderRubyRun::isChildAllowed(const RenderObject& child, const RenderStyle&) const
{
return child.isInline() || child.isRubyText();
Modified: trunk/Source/WebCore/rendering/RenderRubyRun.h (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderRubyRun.h 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderRubyRun.h 2022-03-05 16:57:58 UTC (rev 290867)
@@ -57,8 +57,6 @@
bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
- RenderBlock* firstLineBlock() const override;
-
void getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, float& startOverhang, float& endOverhang) const;
static RenderPtr<RenderRubyRun> staticCreateRubyRun(const RenderObject* parentRuby);
Modified: trunk/Source/WebCore/rendering/RenderTable.cpp (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderTable.cpp 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderTable.cpp 2022-03-05 16:57:58 UTC (rev 290867)
@@ -1486,11 +1486,6 @@
return cell->section()->primaryCellAt(cell->rowIndex(), effCol);
}
-RenderBlock* RenderTable::firstLineBlock() const
-{
- return nullptr;
-}
-
LayoutUnit RenderTable::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
return valueOrCompute(firstLineBaseline(), [&] {
Modified: trunk/Source/WebCore/rendering/RenderTable.h (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderTable.h 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderTable.h 2022-03-05 16:57:58 UTC (rev 290867)
@@ -307,8 +307,6 @@
void invalidateCachedColumns();
void invalidateCachedColumnOffsets();
-
- RenderBlock* firstLineBlock() const final;
void updateLogicalWidth() final;
Modified: trunk/Source/WebCore/rendering/RenderText.cpp (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderText.cpp 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderText.cpp 2022-03-05 16:57:58 UTC (rev 290867)
@@ -1821,18 +1821,4 @@
m_hasInlineWrapperForDisplayContents = true;
}
-RenderText* RenderText::findByDisplayContentsInlineWrapperCandidate(RenderElement& renderer)
-{
- auto* firstChild = renderer.firstChild();
- if (!is<RenderText>(firstChild))
- return nullptr;
- auto& textRenderer = downcast<RenderText>(*firstChild);
- if (textRenderer.inlineWrapperForDisplayContents() != &renderer)
- return nullptr;
- ASSERT(textRenderer.textNode());
- ASSERT(renderer.firstChild() == renderer.lastChild());
- return &textRenderer;
-
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderText.h (290866 => 290867)
--- trunk/Source/WebCore/rendering/RenderText.h 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/RenderText.h 2022-03-05 16:57:58 UTC (rev 290867)
@@ -181,8 +181,6 @@
RenderInline* inlineWrapperForDisplayContents();
void setInlineWrapperForDisplayContents(RenderInline*);
- static RenderText* findByDisplayContentsInlineWrapperCandidate(RenderElement&);
-
template <typename MeasureTextCallback>
static float measureTextConsideringPossibleTrailingSpace(bool currentCharacterIsSpace, unsigned startIndex, unsigned wordLength, WordTrailingSpace&, HashSet<const Font*>& fallbackFonts, MeasureTextCallback&&);
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (290866 => 290867)
--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2022-03-05 16:57:58 UTC (rev 290867)
@@ -405,9 +405,6 @@
if (!m_cachedPseudoStyles || !m_cachedPseudoStyles->size())
return nullptr;
- if (styleType() != PseudoId::None)
- return nullptr;
-
for (auto& pseudoStyle : *m_cachedPseudoStyles) {
if (pseudoStyle->styleType() == pid)
return pseudoStyle.get();
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (290866 => 290867)
--- trunk/Source/WebCore/rendering/style/RenderStyle.h 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h 2022-03-05 16:57:58 UTC (rev 290867)
@@ -2477,4 +2477,9 @@
return style && style->display() != DisplayType::None && style->contentData();
}
+inline bool generatesBox(const RenderStyle& style)
+{
+ return style.display() != DisplayType::None && style.display() != DisplayType::Contents;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp (290866 => 290867)
--- trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp 2022-03-05 16:57:58 UTC (rev 290867)
@@ -488,11 +488,4 @@
return repaintRect;
}
-// Fix for <rdar://problem/8048875>. We should not render :first-line CSS Style
-// in a SVG text element context.
-RenderBlock* RenderSVGText::firstLineBlock() const
-{
- return 0;
}
-
-}
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGText.h (290866 => 290867)
--- trunk/Source/WebCore/rendering/svg/RenderSVGText.h 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGText.h 2022-03-05 16:57:58 UTC (rev 290867)
@@ -81,8 +81,6 @@
const AffineTransform& localToParentTransform() const override { return m_localTransform; }
AffineTransform localTransform() const override { return m_localTransform; }
- RenderBlock* firstLineBlock() const override;
-
bool shouldHandleSubtreeMutations() const;
bool m_needsReordering : 1;
Modified: trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp (290866 => 290867)
--- trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp 2022-03-05 16:57:58 UTC (rev 290867)
@@ -147,10 +147,11 @@
Style::ElementUpdate contentsUpdate { WTFMove(contentsStyle), styleChange, elementUpdate.recompositeLayer };
m_updater.updateElementRenderer(*pseudoElement, WTFMove(contentsUpdate));
- pseudoElement->storeDisplayContentsStyle(RenderStyle::clonePtr(*updateStyle));
+ auto pseudoElementUpdateStyle = RenderStyle::cloneIncludingPseudoElements(*updateStyle);
+ pseudoElement->storeDisplayContentsStyle(makeUnique<RenderStyle>(WTFMove(pseudoElementUpdateStyle)));
} else {
- auto pseudoElementUpdateStyle = RenderStyle::clonePtr(*updateStyle);
- Style::ElementUpdate pseudoElementUpdate { WTFMove(pseudoElementUpdateStyle), styleChange, elementUpdate.recompositeLayer };
+ auto pseudoElementUpdateStyle = RenderStyle::cloneIncludingPseudoElements(*updateStyle);
+ Style::ElementUpdate pseudoElementUpdate { makeUnique<RenderStyle>(WTFMove(pseudoElementUpdateStyle)), styleChange, elementUpdate.recompositeLayer };
m_updater.updateElementRenderer(*pseudoElement, WTFMove(pseudoElementUpdate));
ASSERT(!pseudoElement->hasDisplayContents());
}
Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (290866 => 290867)
--- trunk/Source/WebCore/style/StyleTreeResolver.cpp 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp 2022-03-05 16:57:58 UTC (rev 290867)
@@ -35,6 +35,7 @@
#include "HTMLInputElement.h"
#include "HTMLMeterElement.h"
#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
#include "HTMLProgressElement.h"
#include "HTMLSlotElement.h"
#include "LoaderStrategy.h"
@@ -250,15 +251,19 @@
}
auto resolveAndAddPseudoElementStyle = [&](PseudoId pseudoId) {
- auto pseudoElementUpdate = resolvePseudoStyle(element, update, pseudoId);
+ auto pseudoElementUpdate = resolvePseudoElement(element, pseudoId, update);
if (!pseudoElementUpdate)
- return;
+ return Change::None;
if (pseudoElementUpdate->change != Change::None)
update.change = std::max(update.change, Change::NonInherited);
if (pseudoElementUpdate->recompositeLayer)
update.recompositeLayer = true;
update.style->addCachedPseudoStyle(WTFMove(pseudoElementUpdate->style));
+ return pseudoElementUpdate->change;
};
+
+ if (resolveAndAddPseudoElementStyle(PseudoId::FirstLine) != Change::None)
+ descendantsToResolve = DescendantsToResolve::All;
resolveAndAddPseudoElementStyle(PseudoId::Marker);
resolveAndAddPseudoElementStyle(PseudoId::Before);
@@ -278,17 +283,44 @@
return { WTFMove(update), descendantsToResolve };
}
-std::optional<ElementUpdate> TreeResolver::resolvePseudoStyle(Element& element, const ElementUpdate& elementUpdate, PseudoId pseudoId)
+inline bool supportsFirstLinePseudoElement(const RenderStyle& style)
{
+ auto display = style.display();
+ return display == DisplayType::Block
+ || display == DisplayType::ListItem
+ || display == DisplayType::InlineBlock
+ || display == DisplayType::TableCell
+ || display == DisplayType::TableCaption
+ || display == DisplayType::FlowRoot;
+};
+
+std::optional<ElementUpdate> TreeResolver::resolvePseudoElement(Element& element, PseudoId pseudoId, const ElementUpdate& elementUpdate)
+{
if (pseudoId == PseudoId::Backdrop && !element.isInTopLayer())
return { };
if (pseudoId == PseudoId::Marker && elementUpdate.style->display() != DisplayType::ListItem)
return { };
+ if (pseudoId == PseudoId::FirstLine && !scope().resolver->usesFirstLineRules())
+ return { };
if (elementUpdate.style->display() == DisplayType::None)
return { };
- if (!elementUpdate.style->hasPseudoStyle(pseudoId))
+
+ if (!elementUpdate.style->hasPseudoStyle(pseudoId)) {
+ if (pseudoId == PseudoId::FirstLine) {
+ auto firstLineStyle = resolveInheritedFirstLinePseudoElement(element, elementUpdate);
+ if (!firstLineStyle)
+ return { };
+
+ auto* oldStyle = element.renderOrDisplayContentsStyle(PseudoId::FirstLine);
+ auto change = oldStyle ? determineChange(*oldStyle, *firstLineStyle) : Change::Renderer;
+ return ElementUpdate { WTFMove(firstLineStyle), change };
+ }
return { };
+ }
+ if (pseudoId == PseudoId::FirstLine && !supportsFirstLinePseudoElement(*elementUpdate.style))
+ return { };
+
auto resolutionContext = makeResolutionContextForPseudoElement(elementUpdate);
auto pseudoStyle = scope().resolver->pseudoStyleForElement(element, { pseudoId }, resolutionContext);
@@ -295,13 +327,89 @@
if (!pseudoStyle)
return { };
+ // FIXME: This test shouldn't be needed.
bool hasAnimations = pseudoStyle->hasAnimationsOrTransitions() || element.hasKeyframeEffects(pseudoId);
- if (!pseudoElementRendererIsNeeded(pseudoStyle.get()) && !hasAnimations)
+ if (pseudoId != PseudoId::FirstLine && !pseudoElementRendererIsNeeded(pseudoStyle.get()) && !hasAnimations)
return { };
- return createAnimatedElementUpdate(WTFMove(pseudoStyle), { element, pseudoId }, elementUpdate.change, resolutionContext);
+ auto animatedUpdate = createAnimatedElementUpdate(WTFMove(pseudoStyle), { element, pseudoId }, elementUpdate.change, resolutionContext);
+
+ if (pseudoId == PseudoId::Before || pseudoId == PseudoId::After) {
+ // ::first-line can inherit to ::before/::after
+ auto firstLineContext = makeResolutionContextForInheritedFirstLine(elementUpdate, *elementUpdate.style);
+ if (firstLineContext) {
+ auto firstLineStyle = scope().resolver->pseudoStyleForElement(element, { pseudoId }, *firstLineContext);
+ firstLineStyle->setStyleType(PseudoId::FirstLine);
+ animatedUpdate.style->addCachedPseudoStyle(WTFMove(firstLineStyle));
+ }
+ }
+
+ return animatedUpdate;
}
+std::unique_ptr<RenderStyle> TreeResolver::resolveInheritedFirstLinePseudoElement(Element& element, const ElementUpdate& elementUpdate)
+{
+ if (elementUpdate.style->display() == DisplayType::Inline) {
+ auto* parent = boxGeneratingParent();
+ if (!parent)
+ return { };
+
+ auto resolutionContext = makeResolutionContextForInheritedFirstLine(elementUpdate, parent->style);
+ if (!resolutionContext)
+ return { };
+
+ auto elementStyle = scope().resolver->styleForElement(element, *resolutionContext);
+ auto firstLineStyle = WTFMove(elementStyle.renderStyle);
+ firstLineStyle->setStyleType(PseudoId::FirstLine);
+
+ return firstLineStyle;
+ }
+
+ auto isChildInBlockFormattingContext = [](const RenderStyle& style) {
+ // FIXME: Incomplete. There should be shared code with layout for this.
+ if (style.display() != DisplayType::Block)
+ return false;
+ if (style.hasOutOfFlowPosition())
+ return false;
+ if (style.floating() != Float::None)
+ return false;
+ if (style.overflowX() != Overflow::Visible || style.overflowY() != Overflow::Visible)
+ return false;
+ return true;
+ };
+
+ auto firstLineElementForBlock = [&]() -> Element* {
+ if (!isChildInBlockFormattingContext(*elementUpdate.style))
+ return nullptr;
+
+ // ::first-line is only propagated to the first block.
+ if (parent().resolvedFirstBoxGeneratingChild)
+ return nullptr;
+
+ for (auto& parent : makeReversedRange(m_parentStack)) {
+ if (parent.style.display() == DisplayType::Contents)
+ continue;
+ if (!supportsFirstLinePseudoElement(parent.style))
+ return nullptr;
+ if (parent.style.hasPseudoStyle(PseudoId::FirstLine))
+ return parent.element;
+ if (!isChildInBlockFormattingContext(parent.style))
+ return nullptr;
+ }
+ return nullptr;
+ };
+
+ auto firstLineElement = firstLineElementForBlock();
+ if (!firstLineElement)
+ return { };
+
+ auto resolutionContext = makeResolutionContextForPseudoElement(elementUpdate);
+ // Can't use the cached state since the element being resolved is not the current one.
+ resolutionContext.selectorMatchingState = nullptr;
+
+ return scope().resolver->pseudoStyleForElement(*firstLineElement, { PseudoId::FirstLine }, resolutionContext);
+}
+
ResolutionContext TreeResolver::makeResolutionContext()
{
return {
@@ -322,20 +430,43 @@
};
}
-const RenderStyle* TreeResolver::parentBoxStyle() const
+std::optional<ResolutionContext> TreeResolver::makeResolutionContextForInheritedFirstLine(const ElementUpdate& elementUpdate, const RenderStyle& inheritStyle)
{
+ if (!scope().resolver->usesFirstLineRules())
+ return { };
+
+ auto parentFirstLineStyle = inheritStyle.getCachedPseudoStyle(PseudoId::FirstLine);
+ if (!parentFirstLineStyle)
+ return { };
+
+ // First line style for inlines is made by inheriting from parent first line style.
+ return ResolutionContext {
+ parentFirstLineStyle,
+ parentBoxStyleForPseudoElement(elementUpdate),
+ m_documentElementStyle.get(),
+ &scope().selectorMatchingState
+ };
+}
+
+auto TreeResolver::boxGeneratingParent() const -> const Parent*
+{
// 'display: contents' doesn't generate boxes.
- for (auto i = m_parentStack.size(); i--;) {
- auto& parent = m_parentStack[i];
+ for (auto& parent : makeReversedRange(m_parentStack)) {
if (parent.style.display() == DisplayType::None)
return nullptr;
if (parent.style.display() != DisplayType::Contents)
- return &parent.style;
+ return &parent;
}
ASSERT_NOT_REACHED();
return nullptr;
}
+const RenderStyle* TreeResolver::parentBoxStyle() const
+{
+ auto* parent = boxGeneratingParent();
+ return parent ? &parent->style : nullptr;
+}
+
const RenderStyle* TreeResolver::parentBoxStyleForPseudoElement(const ElementUpdate& elementUpdate) const
{
switch (elementUpdate.style->display()) {
@@ -556,6 +687,9 @@
m_update->addText(text, parent.element, WTFMove(textUpdate));
}
+ if (!text.data().isAllSpecialCharacters<isHTMLSpace>())
+ parent.resolvedFirstBoxGeneratingChild = true;
+
text.setHasValidStyle();
it.traverseNextSkippingChildren();
continue;
@@ -610,6 +744,9 @@
if (!m_didSeePendingStylesheet)
m_didSeePendingStylesheet = hasLoadingStylesheet(m_document.styleScope(), element, !shouldIterateChildren);
+ if (style && generatesBox(*style))
+ parent.resolvedFirstBoxGeneratingChild = true;
+
if (!shouldIterateChildren) {
it.traverseNextSkippingChildren();
continue;
Modified: trunk/Source/WebCore/style/StyleTreeResolver.h (290866 => 290867)
--- trunk/Source/WebCore/style/StyleTreeResolver.h 2022-03-05 16:26:41 UTC (rev 290866)
+++ trunk/Source/WebCore/style/StyleTreeResolver.h 2022-03-05 16:57:58 UTC (rev 290867)
@@ -69,7 +69,8 @@
std::pair<ElementUpdate, DescendantsToResolve> resolveElement(Element&);
static ElementUpdate createAnimatedElementUpdate(std::unique_ptr<RenderStyle>, const Styleable&, Change, const ResolutionContext&);
- std::optional<ElementUpdate> resolvePseudoStyle(Element&, const ElementUpdate&, PseudoId);
+ std::optional<ElementUpdate> resolvePseudoElement(Element&, PseudoId, const ElementUpdate&);
+ std::unique_ptr<RenderStyle> resolveInheritedFirstLinePseudoElement(Element&, const ElementUpdate&);
struct Scope : RefCounted<Scope> {
WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(TreeResolverScope);
@@ -90,6 +91,7 @@
Change change { Change::None };
DescendantsToResolve descendantsToResolve { DescendantsToResolve::None };
bool didPushScope { false };
+ bool resolvedFirstBoxGeneratingChild { false };
Parent(Document&);
Parent(Element&, const RenderStyle&, Change, DescendantsToResolve);
@@ -112,6 +114,8 @@
ResolutionContext makeResolutionContext();
ResolutionContext makeResolutionContextForPseudoElement(const ElementUpdate&);
+ std::optional<ResolutionContext> makeResolutionContextForInheritedFirstLine(const ElementUpdate&, const RenderStyle& inheritStyle);
+ const Parent* boxGeneratingParent() const;
const RenderStyle* parentBoxStyle() const;
const RenderStyle* parentBoxStyleForPseudoElement(const ElementUpdate&) const;