Changeset 223898 in webkit


Ignore:
Timestamp:
Oct 24, 2017 10:50:19 AM (7 years ago)
Author:
Antti Koivisto
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:

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

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r223888 r223898  
     12017-10-24  Antti Koivisto  <antti@apple.com>
     2
     3        Create inline wrappers for before/after pseudo elements that have display:contents
     4        https://bugs.webkit.org/show_bug.cgi?id=178722
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        * TestExpectations:
     9
     10        Enable
     11
     12        imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-before-after-first-letter-001.html and
     13        imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-before-after-001.html
     14
    1152017-10-24  Per Arne Vollan  <pvollan@apple.com>
    216
  • trunk/LayoutTests/TestExpectations

    r223895 r223898  
    12681268### START OF display: contents failures
    12691269
    1270 webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-before-after-first-letter-001.html [ ImageOnlyFailure ]
    1271 webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-before-after-001.html [ ImageOnlyFailure ]
    12721270webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-table-002-none.html [ ImageOnlyFailure ]
    12731271webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-flex-003.html [ ImageOnlyFailure ]
  • trunk/Source/WebCore/ChangeLog

    r223897 r223898  
     12017-10-24  Antti Koivisto  <antti@apple.com>
     2
     3        Create inline wrappers for before/after pseudo elements that have display:contents
     4        https://bugs.webkit.org/show_bug.cgi?id=178722
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        We can handle before and after pseudo elements with display:contents by giving them
     9        inline renderers with style inherited from display:contents style. This removes
     10        need for complicated logic for this case and handles everything correctly.
     11
     12        This is a better approach and replaces the one taken in bug 178584.
     13        It also fixes two display:contents WPTs.
     14
     15        * dom/PseudoElement.h:
     16
     17            There is no need to track content renderers separately anymore. They always descendants of
     18            pseudo element's renderer (which is an inline wrapper in case of display:contents).
     19
     20        * rendering/style/RenderStyle.cpp:
     21        (WebCore::RenderStyle::copyContentFrom):
     22        * rendering/style/RenderStyle.h:
     23        * style/RenderTreeUpdaterGeneratedContent.cpp:
     24        (WebCore::createContentRenderers):
     25        (WebCore::updateStyleForContentRenderers):
     26        (WebCore::RenderTreeUpdater::GeneratedContent::updatePseudoElement):
     27        (WebCore::removeAndDestroyContentRenderers): Deleted.
     28
     29            Since content renderers are now always descendants of the pseudo renderer
     30            there is no need for a separate destruction path.
     31
     32        * style/StyleTreeResolver.cpp:
     33        (WebCore::Style::TreeResolver::resolvePseudoStyle):
     34
     35            Create ElementUpdate with a style that will produce an inline wrapper.
     36
    1372017-10-24  Wenson Hsieh  <wenson_hsieh@apple.com>
    238
  • trunk/Source/WebCore/dom/PseudoElement.h

    r223810 r223898  
    4545    bool canContainRangeEndPoint() const override { return false; }
    4646
    47     auto& contentRenderers() { return m_contentRenderers; }
    48 
    4947    static String pseudoElementNameForEvents(PseudoId);
    5048
     
    5654    Element* m_hostElement;
    5755    PseudoId m_pseudoId;
    58     Vector<WeakPtr<RenderObject>> m_contentRenderers;
    5956};
    6057
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r222441 r223898  
    351351
    352352    ASSERT(zoom() == initialZoom());
     353}
     354
     355void RenderStyle::copyContentFrom(const RenderStyle& other)
     356{
     357    if (!other.m_rareNonInheritedData->content)
     358        return;
     359    m_rareNonInheritedData.access().content = other.m_rareNonInheritedData->content->clone();
    353360}
    354361
  • trunk/Source/WebCore/rendering/style/RenderStyle.h

    r222441 r223898  
    160160    void inheritFrom(const RenderStyle& inheritParent);
    161161    void copyNonInheritedFrom(const RenderStyle&);
     162    void copyContentFrom(const RenderStyle&);
    162163
    163164    ContentPosition resolvedJustifyContentPosition(const StyleContentAlignmentData& normalValueBehavior) const;
  • trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.cpp

    r223810 r223898  
    7070}
    7171
    72 static void createContentRenderers(PseudoElement& pseudoElement, const RenderStyle& style, RenderTreePosition& renderTreePosition)
     72static void createContentRenderers(RenderElement& pseudoRenderer, const RenderStyle& style)
    7373{
    7474    ASSERT(style.contentData());
    7575
    7676    for (const ContentData* content = style.contentData(); content; content = content->next()) {
    77         auto child = content->createContentRenderer(renderTreePosition.parent().document(), style);
    78         pseudoElement.contentRenderers().append(makeWeakPtr(*child));
    79         if (renderTreePosition.parent().isChildAllowed(*child, style))
    80             renderTreePosition.insert(WTFMove(child));
     77        auto child = content->createContentRenderer(pseudoRenderer.document(), style);
     78        if (pseudoRenderer.isChildAllowed(*child, style))
     79            pseudoRenderer.addChild(WTFMove(child));
    8180    }
    8281}
    8382
    84 static void updateStyleForContentRenderers(PseudoElement& pseudoElement, const RenderStyle& style)
     83static void updateStyleForContentRenderers(RenderElement& pseudoRenderer, const RenderStyle& style)
    8584{
    86     for (auto& contentRenderer : pseudoElement.contentRenderers()) {
    87         if (!contentRenderer)
     85    for (auto& contentRenderer : descendantsOfType<RenderElement>(pseudoRenderer)) {
     86        // We only manage the style for the generated content which must be images or text.
     87        if (!is<RenderImage>(contentRenderer) && !is<RenderQuote>(contentRenderer))
    8888            continue;
    89         // We only manage the style for the generated content which must be images or text.
    90         if (!is<RenderImage>(*contentRenderer) && !is<RenderQuote>(*contentRenderer))
    91             continue;
    92         auto createdStyle = RenderStyle::createStyleInheritingFromPseudoStyle(style);
    93         downcast<RenderElement>(*contentRenderer).setStyle(WTFMove(createdStyle));
     89        contentRenderer.setStyle(RenderStyle::createStyleInheritingFromPseudoStyle(style));
    9490    }
    95 }
    96 
    97 static void removeAndDestroyContentRenderers(PseudoElement& pseudoElement)
    98 {
    99     for (auto& contentRenderer : pseudoElement.contentRenderers()) {
    100         if (!contentRenderer)
    101             continue;
    102         contentRenderer->removeFromParentAndDestroy();
    103     }
    104     pseudoElement.contentRenderers().clear();
    10591}
    10692
     
    114100    if (!needsPseudoElement(update)) {
    115101        if (pseudoElement) {
    116             removeAndDestroyContentRenderers(*pseudoElement);
    117 
    118102            if (pseudoId == BEFORE)
    119103                current.clearBeforePseudoElement();
     
    143127
    144128    auto* pseudoElementRenderer = pseudoElement->renderer();
    145     if (!pseudoElementRenderer && update->style->display() != CONTENTS)
     129    if (!pseudoElementRenderer)
    146130        return;
    147131
    148     auto renderTreePosition = pseudoElementRenderer ? RenderTreePosition(*pseudoElementRenderer) : m_updater.renderTreePosition();
    149 
    150     if (update->change == Style::Detach) {
    151         removeAndDestroyContentRenderers(*pseudoElement);
    152 
    153         if (pseudoElementRenderer)
    154             renderTreePosition.moveToLastChild();
    155         else
    156             renderTreePosition.computeNextSibling(*pseudoElement);
    157 
    158         createContentRenderers(*pseudoElement, *update->style, renderTreePosition);
    159     } else
    160         updateStyleForContentRenderers(*pseudoElement, *update->style);
     132    if (update->change == Style::Detach)
     133        createContentRenderers(*pseudoElementRenderer, *update->style);
     134    else
     135        updateStyleForContentRenderers(*pseudoElementRenderer, *update->style);
    161136
    162137    if (m_updater.renderView().hasQuotesNeedingUpdate()) {
    163         for (auto& child : descendantsOfType<RenderQuote>(renderTreePosition.parent()))
     138        for (auto& child : descendantsOfType<RenderQuote>(*pseudoElementRenderer))
    164139            updateQuotesUpTo(&child);
    165140    }
    166     if (is<RenderListItem>(renderTreePosition.parent()))
    167         ListItem::updateMarker(downcast<RenderListItem>(renderTreePosition.parent()));
     141    if (is<RenderListItem>(*pseudoElementRenderer))
     142        ListItem::updateMarker(downcast<RenderListItem>(*pseudoElementRenderer));
    168143}
    169144
  • trunk/Source/WebCore/style/StyleTreeResolver.cpp

    r223748 r223898  
    247247    }
    248248
     249    if (pseudoStyle->display() == CONTENTS) {
     250        // For display:contents we create an inline wrapper that inherits its style from the display:contents style.
     251        auto contentsStyle = RenderStyle::createPtr();
     252        contentsStyle->setStyleType(pseudoId);
     253        contentsStyle->inheritFrom(*pseudoStyle);
     254        contentsStyle->copyContentFrom(*pseudoStyle);
     255        pseudoStyle = WTFMove(contentsStyle);
     256    }
     257
    249258    return createAnimatedElementUpdate(WTFMove(pseudoStyle), *pseudoElement, elementUpdate.change);
    250259}
Note: See TracChangeset for help on using the changeset viewer.