Title: [223898] trunk
Revision
223898
Author
an...@apple.com
Date
2017-10-24 10:50:19 -0700 (Tue, 24 Oct 2017)

Log Message

Create inline wrappers for before/after pseudo elements that have display:contents
https://bugs.webkit.org/show_bug.cgi?id=178722

Reviewed by Ryosuke Niwa.

Source/WebCore:

We can handle before and after pseudo elements with display:contents by giving them
inline renderers with style inherited from display:contents style. This removes
need for complicated logic for this case and handles everything correctly.

This is a better approach and replaces the one taken in bug 178584.
It also fixes two display:contents WPTs.

* dom/PseudoElement.h:

    There is no need to track content renderers separately anymore. They always descendants of
    pseudo element's renderer (which is an inline wrapper in case of display:contents).

* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::copyContentFrom):
* rendering/style/RenderStyle.h:
* style/RenderTreeUpdaterGeneratedContent.cpp:
(WebCore::createContentRenderers):
(WebCore::updateStyleForContentRenderers):
(WebCore::RenderTreeUpdater::GeneratedContent::updatePseudoElement):
(WebCore::removeAndDestroyContentRenderers): Deleted.

    Since content renderers are now always descendants of the pseudo renderer
    there is no need for a separate destruction path.

* style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::resolvePseudoStyle):

    Create ElementUpdate with a style that will produce an inline wrapper.

LayoutTests:

* TestExpectations:

Enable

imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-before-after-first-letter-001.html and
imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-before-after-001.html

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (223897 => 223898)


--- trunk/LayoutTests/ChangeLog	2017-10-24 17:38:44 UTC (rev 223897)
+++ trunk/LayoutTests/ChangeLog	2017-10-24 17:50:19 UTC (rev 223898)
@@ -1,3 +1,17 @@
+2017-10-24  Antti Koivisto  <an...@apple.com>
+
+        Create inline wrappers for before/after pseudo elements that have display:contents
+        https://bugs.webkit.org/show_bug.cgi?id=178722
+
+        Reviewed by Ryosuke Niwa.
+
+        * TestExpectations:
+
+        Enable
+
+        imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-before-after-first-letter-001.html and
+        imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-before-after-001.html
+
 2017-10-24  Per Arne Vollan  <pvol...@apple.com>
 
         Mark fast/css-generated-content/details-summary-before-after.html as failing on Windows.

Modified: trunk/LayoutTests/TestExpectations (223897 => 223898)


--- trunk/LayoutTests/TestExpectations	2017-10-24 17:38:44 UTC (rev 223897)
+++ trunk/LayoutTests/TestExpectations	2017-10-24 17:50:19 UTC (rev 223898)
@@ -1267,8 +1267,6 @@
 ########################################
 ### START OF display: contents failures
 
-webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-before-after-first-letter-001.html [ ImageOnlyFailure ]
-webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-before-after-001.html [ ImageOnlyFailure ]
 webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-table-002-none.html [ ImageOnlyFailure ]
 webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-flex-003.html [ ImageOnlyFailure ]
 webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-table-001-inline.html [ ImageOnlyFailure ]

Modified: trunk/Source/WebCore/ChangeLog (223897 => 223898)


--- trunk/Source/WebCore/ChangeLog	2017-10-24 17:38:44 UTC (rev 223897)
+++ trunk/Source/WebCore/ChangeLog	2017-10-24 17:50:19 UTC (rev 223898)
@@ -1,3 +1,39 @@
+2017-10-24  Antti Koivisto  <an...@apple.com>
+
+        Create inline wrappers for before/after pseudo elements that have display:contents
+        https://bugs.webkit.org/show_bug.cgi?id=178722
+
+        Reviewed by Ryosuke Niwa.
+
+        We can handle before and after pseudo elements with display:contents by giving them
+        inline renderers with style inherited from display:contents style. This removes
+        need for complicated logic for this case and handles everything correctly.
+
+        This is a better approach and replaces the one taken in bug 178584.
+        It also fixes two display:contents WPTs.
+
+        * dom/PseudoElement.h:
+
+            There is no need to track content renderers separately anymore. They always descendants of
+            pseudo element's renderer (which is an inline wrapper in case of display:contents).
+
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::copyContentFrom):
+        * rendering/style/RenderStyle.h:
+        * style/RenderTreeUpdaterGeneratedContent.cpp:
+        (WebCore::createContentRenderers):
+        (WebCore::updateStyleForContentRenderers):
+        (WebCore::RenderTreeUpdater::GeneratedContent::updatePseudoElement):
+        (WebCore::removeAndDestroyContentRenderers): Deleted.
+
+            Since content renderers are now always descendants of the pseudo renderer
+            there is no need for a separate destruction path.
+
+        * style/StyleTreeResolver.cpp:
+        (WebCore::Style::TreeResolver::resolvePseudoStyle):
+
+            Create ElementUpdate with a style that will produce an inline wrapper.
+
 2017-10-24  Wenson Hsieh  <wenson_hs...@apple.com>
 
         [iOS] MediaPlayer::isAvailable() takes ~150 ms during web process initialization

Modified: trunk/Source/WebCore/dom/PseudoElement.h (223897 => 223898)


--- trunk/Source/WebCore/dom/PseudoElement.h	2017-10-24 17:38:44 UTC (rev 223897)
+++ trunk/Source/WebCore/dom/PseudoElement.h	2017-10-24 17:50:19 UTC (rev 223898)
@@ -44,8 +44,6 @@
     bool canStartSelection() const override { return false; }
     bool canContainRangeEndPoint() const override { return false; }
 
-    auto& contentRenderers() { return m_contentRenderers; }
-
     static String pseudoElementNameForEvents(PseudoId);
 
 private:
@@ -55,7 +53,6 @@
 
     Element* m_hostElement;
     PseudoId m_pseudoId;
-    Vector<WeakPtr<RenderObject>> m_contentRenderers;
 };
 
 const QualifiedName& pseudoElementTagName();

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (223897 => 223898)


--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2017-10-24 17:38:44 UTC (rev 223897)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2017-10-24 17:50:19 UTC (rev 223898)
@@ -352,6 +352,13 @@
     ASSERT(zoom() == initialZoom());
 }
 
+void RenderStyle::copyContentFrom(const RenderStyle& other)
+{
+    if (!other.m_rareNonInheritedData->content)
+        return;
+    m_rareNonInheritedData.access().content = other.m_rareNonInheritedData->content->clone();
+}
+
 bool RenderStyle::operator==(const RenderStyle& other) const
 {
     // compare everything except the pseudoStyle pointer

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (223897 => 223898)


--- trunk/Source/WebCore/rendering/style/RenderStyle.h	2017-10-24 17:38:44 UTC (rev 223897)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h	2017-10-24 17:50:19 UTC (rev 223898)
@@ -159,6 +159,7 @@
 
     void inheritFrom(const RenderStyle& inheritParent);
     void copyNonInheritedFrom(const RenderStyle&);
+    void copyContentFrom(const RenderStyle&);
 
     ContentPosition resolvedJustifyContentPosition(const StyleContentAlignmentData& normalValueBehavior) const;
     ContentDistributionType resolvedJustifyContentDistribution(const StyleContentAlignmentData& normalValueBehavior) const;

Modified: trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.cpp (223897 => 223898)


--- trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.cpp	2017-10-24 17:38:44 UTC (rev 223897)
+++ trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.cpp	2017-10-24 17:50:19 UTC (rev 223898)
@@ -69,41 +69,27 @@
     ASSERT(!lastQuote);
 }
 
-static void createContentRenderers(PseudoElement& pseudoElement, const RenderStyle& style, RenderTreePosition& renderTreePosition)
+static void createContentRenderers(RenderElement& pseudoRenderer, const RenderStyle& style)
 {
     ASSERT(style.contentData());
 
     for (const ContentData* content = style.contentData(); content; content = content->next()) {
-        auto child = content->createContentRenderer(renderTreePosition.parent().document(), style);
-        pseudoElement.contentRenderers().append(makeWeakPtr(*child));
-        if (renderTreePosition.parent().isChildAllowed(*child, style))
-            renderTreePosition.insert(WTFMove(child));
+        auto child = content->createContentRenderer(pseudoRenderer.document(), style);
+        if (pseudoRenderer.isChildAllowed(*child, style))
+            pseudoRenderer.addChild(WTFMove(child));
     }
 }
 
-static void updateStyleForContentRenderers(PseudoElement& pseudoElement, const RenderStyle& style)
+static void updateStyleForContentRenderers(RenderElement& pseudoRenderer, const RenderStyle& style)
 {
-    for (auto& contentRenderer : pseudoElement.contentRenderers()) {
-        if (!contentRenderer)
-            continue;
+    for (auto& contentRenderer : descendantsOfType<RenderElement>(pseudoRenderer)) {
         // We only manage the style for the generated content which must be images or text.
-        if (!is<RenderImage>(*contentRenderer) && !is<RenderQuote>(*contentRenderer))
+        if (!is<RenderImage>(contentRenderer) && !is<RenderQuote>(contentRenderer))
             continue;
-        auto createdStyle = RenderStyle::createStyleInheritingFromPseudoStyle(style);
-        downcast<RenderElement>(*contentRenderer).setStyle(WTFMove(createdStyle));
+        contentRenderer.setStyle(RenderStyle::createStyleInheritingFromPseudoStyle(style));
     }
 }
 
-static void removeAndDestroyContentRenderers(PseudoElement& pseudoElement)
-{
-    for (auto& contentRenderer : pseudoElement.contentRenderers()) {
-        if (!contentRenderer)
-            continue;
-        contentRenderer->removeFromParentAndDestroy();
-    }
-    pseudoElement.contentRenderers().clear();
-}
-
 void RenderTreeUpdater::GeneratedContent::updatePseudoElement(Element& current, const std::optional<Style::ElementUpdate>& update, PseudoId pseudoId)
 {
     PseudoElement* pseudoElement = pseudoId == BEFORE ? current.beforePseudoElement() : current.afterPseudoElement();
@@ -113,8 +99,6 @@
 
     if (!needsPseudoElement(update)) {
         if (pseudoElement) {
-            removeAndDestroyContentRenderers(*pseudoElement);
-
             if (pseudoId == BEFORE)
                 current.clearBeforePseudoElement();
             else
@@ -142,29 +126,20 @@
     m_updater.updateElementRenderer(*pseudoElement, *update);
 
     auto* pseudoElementRenderer = pseudoElement->renderer();
-    if (!pseudoElementRenderer && update->style->display() != CONTENTS)
+    if (!pseudoElementRenderer)
         return;
 
-    auto renderTreePosition = pseudoElementRenderer ? RenderTreePosition(*pseudoElementRenderer) : m_updater.renderTreePosition();
+    if (update->change == Style::Detach)
+        createContentRenderers(*pseudoElementRenderer, *update->style);
+    else
+        updateStyleForContentRenderers(*pseudoElementRenderer, *update->style);
 
-    if (update->change == Style::Detach) {
-        removeAndDestroyContentRenderers(*pseudoElement);
-
-        if (pseudoElementRenderer)
-            renderTreePosition.moveToLastChild();
-        else
-            renderTreePosition.computeNextSibling(*pseudoElement);
-
-        createContentRenderers(*pseudoElement, *update->style, renderTreePosition);
-    } else
-        updateStyleForContentRenderers(*pseudoElement, *update->style);
-
     if (m_updater.renderView().hasQuotesNeedingUpdate()) {
-        for (auto& child : descendantsOfType<RenderQuote>(renderTreePosition.parent()))
+        for (auto& child : descendantsOfType<RenderQuote>(*pseudoElementRenderer))
             updateQuotesUpTo(&child);
     }
-    if (is<RenderListItem>(renderTreePosition.parent()))
-        ListItem::updateMarker(downcast<RenderListItem>(renderTreePosition.parent()));
+    if (is<RenderListItem>(*pseudoElementRenderer))
+        ListItem::updateMarker(downcast<RenderListItem>(*pseudoElementRenderer));
 }
 
 bool RenderTreeUpdater::GeneratedContent::needsPseudoElement(const std::optional<Style::ElementUpdate>& update)

Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (223897 => 223898)


--- trunk/Source/WebCore/style/StyleTreeResolver.cpp	2017-10-24 17:38:44 UTC (rev 223897)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp	2017-10-24 17:50:19 UTC (rev 223898)
@@ -246,6 +246,15 @@
             element.setAfterPseudoElement(WTFMove(newPseudoElement));
     }
 
+    if (pseudoStyle->display() == CONTENTS) {
+        // For display:contents we create an inline wrapper that inherits its style from the display:contents style.
+        auto contentsStyle = RenderStyle::createPtr();
+        contentsStyle->setStyleType(pseudoId);
+        contentsStyle->inheritFrom(*pseudoStyle);
+        contentsStyle->copyContentFrom(*pseudoStyle);
+        pseudoStyle = WTFMove(contentsStyle);
+    }
+
     return createAnimatedElementUpdate(WTFMove(pseudoStyle), *pseudoElement, elementUpdate.change);
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to