Changeset 199154 in webkit


Ignore:
Timestamp:
Apr 7, 2016 3:29:15 AM (8 years ago)
Author:
Antti Koivisto
Message:

Shadow DOM: Implement display: contents for slots
https://bugs.webkit.org/show_bug.cgi?id=149439
<rdar://problem/22731922>

Reviewed by Ryosuke Niwa.

Source/WebCore:

This patch adds support for value 'contents' of the 'display' property for <slot> elements only. The value is ignored
for other elements for now. With this display value the element does not generate a box for itself but its descendants
generate them normally.

Slots already have implicit "display: contents". With this patch the value comes from the user agent stylesheet and can
be overriden by the author.

  • css/CSSParser.cpp:

(WebCore::isValidKeywordPropertyAndValue):

  • css/CSSPrimitiveValueMappings.h:

(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):

  • css/CSSValueKeywords.in:

Suport parsing display: contents.

  • css/StyleResolver.cpp:

(WebCore::equivalentBlockDisplay):
(WebCore::StyleResolver::adjustRenderStyle):

Disallow for non-slots for now.

  • css/html.css:

(slot):

Add "slot { display: contents }" to the UA sheet.

  • dom/Element.cpp:

(WebCore::Element::resolveStyle):
(WebCore::Element::hasDisplayContents):
(WebCore::Element::setHasDisplayContents):

Add a rare data bit for elements with display:contents (as we don't save the RenderStyle for them).

(WebCore::Element::rendererIsNeeded):

Don't need renderer for display:contents.

(WebCore::Element::createElementRenderer):

  • dom/Element.h:

(WebCore::Element::isVisibleInViewportChanged):

  • dom/ElementAndTextDescendantIterator.h:

(WebCore::ElementAndTextDescendantIterator::operator!):
(WebCore::ElementAndTextDescendantIterator::operator bool):
(WebCore::ElementAndTextDescendantIterator::ElementAndTextDescendantIterator):
(WebCore::ElementAndTextDescendantIterator::operator==):
(WebCore::ElementAndTextDescendantIterator::operator!=):

Support initializing ElementAndTextDescendantIterator with root==current so that m_current is not nulled.
This is needed for ComposedTreeIterator to be initialized correctly when root is a slot and the current node
is a slotted node. The case happens in RenderTreePosition::previousSiblingRenderer when slot display is overriden
to something else than 'contents'.

  • dom/ElementRareData.h:

(WebCore::ElementRareData::hasDisplayContents):
(WebCore::ElementRareData::setHasDisplayContents):
(WebCore::ElementRareData::ElementRareData):

  • rendering/RenderElement.cpp:

(WebCore::RenderElement::createFor):

  • rendering/style/RenderStyleConstants.h:
  • style/RenderTreePosition.cpp:

(WebCore::RenderTreePosition::nextSiblingRenderer):

Test for dynamic display:contents.

  • style/RenderTreeUpdater.cpp:

(WebCore::findRenderingRoot):
(WebCore::RenderTreeUpdater::updateRenderTree):
(WebCore::RenderTreeUpdater::updateElementRenderer):

Test for dynamic display:contents.

  • style/StyleTreeResolver.cpp:

(WebCore::Style::affectsRenderedSubtree):

No need for special case.

(WebCore::Style::TreeResolver::resolveComposedTree):

Test for dynamic display:contents.

LayoutTests:

  • platform/mac/TestExpectations:

Enable fast/shadow-dom/css-scoping-shadow-slot-display-override.html, the test for overriding slot display value.

Location:
trunk
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r199153 r199154  
     12016-04-07  Antti Koivisto  <antti@apple.com>
     2
     3        Shadow DOM: Implement display: contents for slots
     4        https://bugs.webkit.org/show_bug.cgi?id=149439
     5        <rdar://problem/22731922>
     6
     7        Reviewed by Ryosuke Niwa.
     8
     9        * platform/mac/TestExpectations:
     10
     11        Enable fast/shadow-dom/css-scoping-shadow-slot-display-override.html, the test for overriding slot display value.
     12
    1132016-04-07  Sergio Villar Senin  <svillar@igalia.com>
    214
     
    224236        * fast/block/float/float-moves-between-lines-expected.txt: Added.
    225237        * fast/block/float/float-moves-between-lines.html: Added.
    226 
    227 2016-04-06  Antti Koivisto  <antti@apple.com>
    228 
    229         Shadow DOM: Implement display: contents for slots
    230         https://bugs.webkit.org/show_bug.cgi?id=149439
    231         <rdar://problem/22731922>
    232 
    233         Reviewed by Ryosuke Niwa.
    234 
    235         * platform/mac/TestExpectations:
    236 
    237         Enable fast/shadow-dom/css-scoping-shadow-slot-display-override.html, the test for overriding slot display value.
    238238
    2392392016-04-06  Antti Koivisto  <antti@apple.com>
  • trunk/LayoutTests/platform/mac/TestExpectations

    r199152 r199154  
    12301230webkit.org/b/148695 fast/shadow-dom [ Pass ]
    12311231webkit.org/b/149440 fast/shadow-dom/css-scoping-shadow-host-functional-rule.html [ ImageOnlyFailure ]
    1232 webkit.org/b/149441 fast/shadow-dom/css-scoping-shadow-slot-display-override.html [ ImageOnlyFailure ]
    12331232
    12341233# Touch events is not enabled on Mac
  • trunk/Source/WebCore/ChangeLog

    r199153 r199154  
     12016-04-07  Antti Koivisto  <antti@apple.com>
     2
     3        Shadow DOM: Implement display: contents for slots
     4        https://bugs.webkit.org/show_bug.cgi?id=149439
     5        <rdar://problem/22731922>
     6
     7        Reviewed by Ryosuke Niwa.
     8
     9        This patch adds support for value 'contents' of the 'display' property for <slot> elements only. The value is ignored
     10        for other elements for now. With this display value the element does not generate a box for itself but its descendants
     11        generate them normally.
     12
     13        Slots already have implicit "display: contents". With this patch the value comes from the user agent stylesheet and can
     14        be overriden by the author.
     15
     16        * css/CSSParser.cpp:
     17        (WebCore::isValidKeywordPropertyAndValue):
     18        * css/CSSPrimitiveValueMappings.h:
     19        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
     20        * css/CSSValueKeywords.in:
     21
     22            Suport parsing display: contents.
     23
     24        * css/StyleResolver.cpp:
     25        (WebCore::equivalentBlockDisplay):
     26        (WebCore::StyleResolver::adjustRenderStyle):
     27
     28            Disallow for non-slots for now.
     29
     30        * css/html.css:
     31        (slot):
     32
     33            Add "slot { display: contents }" to the UA sheet.
     34
     35        * dom/Element.cpp:
     36        (WebCore::Element::resolveStyle):
     37        (WebCore::Element::hasDisplayContents):
     38        (WebCore::Element::setHasDisplayContents):
     39
     40            Add a rare data bit for elements with display:contents (as we don't save the RenderStyle for them).
     41
     42        (WebCore::Element::rendererIsNeeded):
     43
     44            Don't need renderer for display:contents.
     45
     46        (WebCore::Element::createElementRenderer):
     47        * dom/Element.h:
     48        (WebCore::Element::isVisibleInViewportChanged):
     49        * dom/ElementAndTextDescendantIterator.h:
     50        (WebCore::ElementAndTextDescendantIterator::operator!):
     51        (WebCore::ElementAndTextDescendantIterator::operator bool):
     52        (WebCore::ElementAndTextDescendantIterator::ElementAndTextDescendantIterator):
     53        (WebCore::ElementAndTextDescendantIterator::operator==):
     54        (WebCore::ElementAndTextDescendantIterator::operator!=):
     55
     56            Support initializing ElementAndTextDescendantIterator with root==current so that m_current is not nulled.
     57            This is needed for ComposedTreeIterator to be initialized correctly when root is a slot and the current node
     58            is a slotted node. The case happens in RenderTreePosition::previousSiblingRenderer when slot display is overriden
     59            to something else than 'contents'.
     60
     61        * dom/ElementRareData.h:
     62        (WebCore::ElementRareData::hasDisplayContents):
     63        (WebCore::ElementRareData::setHasDisplayContents):
     64        (WebCore::ElementRareData::ElementRareData):
     65        * rendering/RenderElement.cpp:
     66        (WebCore::RenderElement::createFor):
     67        * rendering/style/RenderStyleConstants.h:
     68        * style/RenderTreePosition.cpp:
     69        (WebCore::RenderTreePosition::nextSiblingRenderer):
     70
     71            Test for dynamic display:contents.
     72
     73        * style/RenderTreeUpdater.cpp:
     74        (WebCore::findRenderingRoot):
     75        (WebCore::RenderTreeUpdater::updateRenderTree):
     76        (WebCore::RenderTreeUpdater::updateElementRenderer):
     77
     78            Test for dynamic display:contents.
     79
     80        * style/StyleTreeResolver.cpp:
     81        (WebCore::Style::affectsRenderedSubtree):
     82
     83            No need for special case.
     84
     85        (WebCore::Style::TreeResolver::resolveComposedTree):
     86
     87            Test for dynamic display:contents.
     88
    1892016-04-07  Sergio Villar Senin  <svillar@igalia.com>
    290
  • trunk/Source/WebCore/css/CSSParser.cpp

    r199152 r199154  
    670670        // inline-table | table-row-group | table-header-group | table-footer-group | table-row |
    671671        // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none | inherit
    672         // flex | -webkit-flex | inline-flex | -webkit-inline-flex | -webkit-grid | -webkit-inline-grid
    673         if ((valueID >= CSSValueInline && valueID <= CSSValueWebkitInlineFlex) || valueID == CSSValueNone)
     672        // flex | -webkit-flex | inline-flex | -webkit-inline-flex | -webkit-grid | -webkit-inline-grid | contents
     673        if ((valueID >= CSSValueInline && valueID <= CSSValueContents) || valueID == CSSValueNone)
    674674            return true;
    675675#if ENABLE(CSS_GRID_LAYOUT)
  • trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h

    r199152 r199154  
    13881388    case NONE:
    13891389        m_value.valueID = CSSValueNone;
     1390        break;
     1391    case CONTENTS:
     1392        m_value.valueID = CSSValueContents;
    13901393        break;
    13911394    }
  • trunk/Source/WebCore/css/CSSValueKeywords.in

    r199152 r199154  
    418418inline-flex
    419419-webkit-inline-flex
     420contents
    420421-webkit-grid
    421422-webkit-inline-grid
     
    11851186// will-change
    11861187scroll-position
    1187 contents
     1188//contents
    11881189
    11891190#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r199152 r199154  
    724724    case TABLE_CELL:
    725725    case TABLE_CAPTION:
     726    case CONTENTS:
    726727        return BLOCK;
    727728    case NONE:
     
    766767
    767768    if (style.display() != NONE) {
     769        if (style.display() == CONTENTS) {
     770            // FIXME: Enable for all elements.
     771            bool elementSupportsDisplayContents = false;
     772#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
     773            elementSupportsDisplayContents = is<HTMLSlotElement>(e);
     774#endif
     775            if (!elementSupportsDisplayContents)
     776                style.setDisplay(INLINE);
     777        }
    768778        // If we have a <td> that specifies a float property, in quirks mode we just drop the float
    769779        // property.
  • trunk/Source/WebCore/css/html.css

    r199152 r199154  
    12241224}
    12251225
     1226slot {
     1227    display: contents;
     1228}
     1229
    12261230#if defined(WTF_PLATFORM_IOS) && WTF_PLATFORM_IOS
    12271231applet, embed, object, img {
  • trunk/Source/WebCore/dom/Element.cpp

    r199152 r199154  
    13761376}
    13771377
     1378bool Element::hasDisplayContents() const
     1379{
     1380    return hasRareData() && elementRareData()->hasDisplayContents();
     1381}
     1382
     1383void Element::setHasDisplayContents(bool value)
     1384{
     1385    if (hasDisplayContents() == value)
     1386        return;
     1387    ensureElementRareData().setHasDisplayContents(value);
     1388}
     1389
    13781390// Returns true is the given attribute is an event handler.
    13791391// We consider an event handler any attribute that begins with "on".
     
    14791491bool Element::rendererIsNeeded(const RenderStyle& style)
    14801492{
    1481     return style.display() != NONE;
     1493    return style.display() != NONE && style.display() != CONTENTS;
    14821494}
    14831495
  • trunk/Source/WebCore/dom/Element.h

    r199152 r199154  
    502502    ElementStyle resolveStyle(RenderStyle* parentStyle);
    503503
     504    bool hasDisplayContents() const;
     505    void setHasDisplayContents(bool);
     506
    504507    virtual void isVisibleInViewportChanged() { }
    505508
  • trunk/Source/WebCore/dom/ElementAndTextDescendantIterator.h

    r199152 r199154  
    5151    bool operator!=(const ElementAndTextDescendantIterator& other) const;
    5252
    53     bool operator!() const { return !m_current; }
    54     explicit operator bool() const { return m_current; }
     53    bool operator!() const { return !m_depth; }
     54    explicit operator bool() const { return m_depth; }
    5555
    5656    void dropAssertions();
     
    116116
    117117inline ElementAndTextDescendantIterator::ElementAndTextDescendantIterator(ContainerNode& root, Node* current)
    118     : m_current(current != &root ? current : nullptr)
     118    : m_current(current)
    119119#if !ASSERT_DISABLED
    120120    , m_assertions(m_current)
     
    124124        return;
    125125    ASSERT(isElementOrText(*m_current));
     126    if (m_current == &root)
     127        return;
    126128
    127129    Vector<Node*, 20> ancestorStack;
     
    286288{
    287289    ASSERT(!m_assertions.domTreeHasMutated());
    288     return m_current == other.m_current;
     290    return m_current == other.m_current || (!m_depth && !other.m_depth);
    289291}
    290292
  • trunk/Source/WebCore/dom/ElementRareData.h

    r199152 r199154  
    107107    bool hasPendingResources() const { return m_hasPendingResources; }
    108108    void setHasPendingResources(bool has) { m_hasPendingResources = has; }
     109
     110    bool hasDisplayContents() const { return m_hasDisplayContents; }
     111    void setHasDisplayContents(bool value) { m_hasDisplayContents = value; }
    109112
    110113private:
     
    127130    unsigned m_childrenAffectedByBackwardPositionalRules : 1;
    128131    unsigned m_childrenAffectedByPropertyBasedBackwardPositionalRules : 1;
     132    unsigned m_hasDisplayContents : 1;
    129133
    130134    RegionOversetState m_regionOversetState;
     
    167171    , m_childrenAffectedByBackwardPositionalRules(false)
    168172    , m_childrenAffectedByPropertyBasedBackwardPositionalRules(false)
     173    , m_hasDisplayContents(false)
    169174    , m_regionOversetState(RegionUndefined)
    170175    , m_minimumSizeForResizing(defaultMinimumSizeForResizing())
     
    194199{
    195200    m_computedStyle = nullptr;
     201    m_hasDisplayContents = false;
    196202    setStyleAffectedByEmpty(false);
    197203    setChildIndex(0);
  • trunk/Source/WebCore/html/HTMLSlotElement.h

    r199152 r199154  
    5454};
    5555
    56 // Slots have implicit display:contents until it is supported for reals.
    57 inline bool hasImplicitDisplayContents(const Element& element) { return is<HTMLSlotElement>(element); }
    58 
    59 }
    60 
    61 #else
    62 
    63 namespace WebCore {
    64 
    65 inline bool hasImplicitDisplayContents(const Element&) { return false; }
    66 
    6756}
    6857
  • trunk/Source/WebCore/rendering/RenderElement.cpp

    r199152 r199154  
    162162    switch (style.get().display()) {
    163163    case NONE:
     164    case CONTENTS:
    164165        return nullptr;
    165166    case INLINE:
  • trunk/Source/WebCore/rendering/style/RenderStyleConstants.h

    r199152 r199154  
    564564    TABLE_CAPTION, BOX, INLINE_BOX,
    565565    FLEX, WEBKIT_FLEX, INLINE_FLEX, WEBKIT_INLINE_FLEX,
     566    CONTENTS,
    566567#if ENABLE(CSS_GRID_LAYOUT)
    567568    GRID, INLINE_GRID,
  • trunk/Source/WebCore/style/RenderTreePosition.cpp

    r199152 r199154  
    9090    while (it != end) {
    9191        auto& node = *it;
    92         bool hasDisplayContents = is<Element>(node) && hasImplicitDisplayContents(downcast<Element>(node));
     92        bool hasDisplayContents = is<Element>(node) && downcast<Element>(node).hasDisplayContents();
    9393        if (hasDisplayContents) {
    9494            it.traverseNext();
  • trunk/Source/WebCore/style/RenderTreeUpdater.cpp

    r199152 r199154  
    6969        if (ancestor.renderer())
    7070            return &ancestor;
    71         if (!hasImplicitDisplayContents(ancestor))
     71        if (!ancestor.hasDisplayContents())
    7272            return nullptr;
    7373    }
     
    152152        updateElementRenderer(element, *elementUpdate);
    153153
    154         bool mayHaveRenderedDescendants = element.renderer() || (hasImplicitDisplayContents(element) && shouldCreateRenderer(element, renderTreePosition().parent()));
     154        bool mayHaveRenderedDescendants = element.renderer() || (element.hasDisplayContents() && shouldCreateRenderer(element, renderTreePosition().parent()));
    155155        if (!mayHaveRenderedDescendants) {
    156156            it.traverseNextSkippingChildren();
     
    245245        tearDownRenderers(element, TeardownType::KeepHoverAndActive);
    246246
    247     bool shouldCreateNewRenderer = !element.renderer() && update.style && !hasImplicitDisplayContents(element);
     247    bool hasDisplayContest = update.style && update.style->display() == CONTENTS;
     248    element.setHasDisplayContents(hasDisplayContest);
     249
     250    bool shouldCreateNewRenderer = !element.renderer() && update.style && !hasDisplayContest;
    248251    if (shouldCreateNewRenderer) {
    249252        if (element.hasCustomStyleResolveCallbacks())
  • trunk/Source/WebCore/style/StyleTreeResolver.cpp

    r199152 r199154  
    173173    if (newStyle.display() != NONE)
    174174        return true;
    175     // FIXME: Make 'contents' an actual display property value.
    176     if (hasImplicitDisplayContents(element))
    177         return true;
    178175    if (element.rendererIsNeeded(newStyle))
    179176        return true;
     
    377374        update.style = element.renderStyle();
    378375
    379         bool shouldResolve = parent.change >= Inherit || element.needsStyleRecalc() || shouldResolveForPseudoElement || affectedByPreviousSibling || hasImplicitDisplayContents(element);
     376        bool shouldResolve = parent.change >= Inherit || element.needsStyleRecalc() || shouldResolveForPseudoElement || affectedByPreviousSibling || element.hasDisplayContents();
    380377        if (shouldResolve) {
    381378#if PLATFORM(IOS)
Note: See TracChangeset for help on using the changeset viewer.