Changeset 190840 in webkit


Ignore:
Timestamp:
Oct 10, 2015, 11:16:37 AM (10 years ago)
Author:
Antti Koivisto
Message:

Rewrite HTMLDetailsElement using HTMLSlotElement
https://bugs.webkit.org/show_bug.cgi?id=149698

Reviewed by Andreas Kling.

Source/WebCore:

Use the modern Shadow DOM to implement <details> element. After this the legacy InsertionPoint and
related code can be removed.

Based on a patch by Ryosuke.

  • dom/Element.cpp:

(WebCore::Element::childrenChanged):

  • dom/EventDispatcher.cpp:

(WebCore::EventPath::EventPath):

  • dom/ShadowRoot.cpp:

(WebCore::ShadowRoot::ShadowRoot):
(WebCore::ShadowRoot::~ShadowRoot):
(WebCore::ShadowRoot::removeAllEventListeners):
(WebCore::ShadowRoot::findAssignedSlot):
(WebCore::ShadowRoot::addSlotElementByName):
(WebCore::ShadowRoot::removeSlotElementByName):
(WebCore::ShadowRoot::invalidateSlotAssignments):
(WebCore::ShadowRoot::invalidateDefaultSlotAssignments):
(WebCore::ShadowRoot::assignedNodesForSlot):

  • dom/ShadowRoot.h:

(WebCore::ShadowRoot::create):
(WebCore::ShadowRoot::distributor):
(WebCore::ShadowRoot::isOrphan):

  • dom/SlotAssignment.cpp:

(WebCore::slotNameFromAttributeValue):

Rename for clarity.

(WebCore::slotNameFromSlotAttribute):

SlotAssignment can now be specialized by providing function that maps from node to slot name.
This is the default function that gets the name from the slot attribute.

(WebCore::SlotAssignment::SlotAssignment):
(WebCore::SlotAssignment::findAssignedSlot):

Use the name mapping function.
Ensure that the slots are assigned.

(WebCore::SlotAssignment::addSlotElementByName):
(WebCore::SlotAssignment::removeSlotElementByName):
(WebCore::SlotAssignment::assignedNodesForSlot):
(WebCore::SlotAssignment::invalidate):
(WebCore::SlotAssignment::invalidateDefaultSlot):
(WebCore::SlotAssignment::resolveAllSlotElements):
(WebCore::SlotAssignment::assignSlots):

Use the name mapping function.

(WebCore::SlotAssignment::assignToSlot):

Factor into function.

(WebCore::treatNullAsEmpty): Deleted.

  • dom/SlotAssignment.h:

(WebCore::SlotAssignment::~SlotAssignment):
(WebCore::SlotAssignment::defaultSlotName):

Add static getter for emptyAtom for clarity.

(WebCore::SlotAssignment::SlotAssignment): Deleted.

  • html/HTMLDetailsElement.cpp:

(WebCore::summarySlotName):
(WebCore::slotNameFunction):

Slot name function for <details>. It assigns the first <summary> child to the summary slot and others
to the default content slot if the element is open.

(WebCore::HTMLDetailsElement::create):
(WebCore::HTMLDetailsElement::didAddUserAgentShadowRoot):
(WebCore::HTMLDetailsElement::isActiveSummary):
(WebCore::HTMLDetailsElement::parseAttribute):
(WebCore::HTMLDetailsElement::toggleOpen):
(WebCore::summaryQuerySelector): Deleted.
(WebCore::DetailsContentElement::create): Deleted.
(WebCore::DetailsSummaryElement::create): Deleted.
(WebCore::HTMLDetailsElement::findMainSummary): Deleted.
(WebCore::HTMLDetailsElement::childShouldCreateRenderer): Deleted.

  • html/HTMLDetailsElement.h:
  • html/HTMLSummaryElement.cpp:

(WebCore::HTMLSummaryElement::create):
(WebCore::HTMLSummaryElement::createElementRenderer):
(WebCore::HTMLSummaryElement::didAddUserAgentShadowRoot):
(WebCore::HTMLSummaryElement::detailsElement):
(WebCore::HTMLSummaryElement::isActiveSummary):
(WebCore::isClickableControl):
(WebCore::HTMLSummaryElement::supportsFocus):
(WebCore::HTMLSummaryElement::defaultEventHandler):
(WebCore::HTMLSummaryElement::willRespondToMouseClickEvents):
(WebCore::SummaryContentElement::create): Deleted.
(WebCore::HTMLSummaryElement::childShouldCreateRenderer): Deleted.
(WebCore::HTMLSummaryElement::isMainSummary): Deleted.

  • html/HTMLSummaryElement.h:
  • html/shadow/DetailsMarkerControl.cpp:

(WebCore::DetailsMarkerControl::rendererIsNeeded):

  • style/RenderTreePosition.cpp:

(WebCore::RenderTreePosition::computeNextSibling):

Skip the verification assert for shadow host children. Getting this right requires
better shadow-aware traversal code.

  • style/StyleResolveTree.cpp:

(WebCore::Style::invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded):
(WebCore::Style::attachChildren):
(WebCore::Style::attachShadowRoot):
(WebCore::Style::attachBeforeOrAfterPseudoElementIfNeeded):
(WebCore::Style::attachSlotAssignees):
(WebCore::Style::attachRenderTree):
(WebCore::Style::detachChildren):
(WebCore::Style::detachShadowRoot):
(WebCore::Style::detachSlotAssignees):
(WebCore::Style::detachRenderTree):
(WebCore::Style::resolveChildren):
(WebCore::Style::resolveSlotAssignees):
(WebCore::Style::resolveTree):
(WebCore::Style::attachDistributedChildren): Deleted.
(WebCore::Style::detachDistributedChildren): Deleted.

Remove InsertionPoint related code paths.

LayoutTests:

  • TestExpectations:
  • platform/mac/fast/html/details-add-child-2-expected.txt:
  • platform/mac/fast/html/details-open2-expected.txt:
  • platform/mac/fast/html/details-remove-summary-1-and-click-expected.txt:
  • platform/mac/fast/html/details-remove-summary-4-and-click-expected.txt:
Location:
trunk
Files:
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r190838 r190840  
     12015-10-10  Antti Koivisto  <antti@apple.com>
     2
     3        Rewrite HTMLDetailsElement using HTMLSlotElement
     4        https://bugs.webkit.org/show_bug.cgi?id=149698
     5
     6        Reviewed by Andreas Kling.
     7
     8        * TestExpectations:
     9        * platform/mac/fast/html/details-add-child-2-expected.txt:
     10        * platform/mac/fast/html/details-open2-expected.txt:
     11        * platform/mac/fast/html/details-remove-summary-1-and-click-expected.txt:
     12        * platform/mac/fast/html/details-remove-summary-4-and-click-expected.txt:
     13
    1142015-10-10  Andreas Kling  <akling@apple.com>
    215
  • trunk/LayoutTests/TestExpectations

    r190836 r190840  
    673673
    674674webkit.org/b/148695 fast/shadow-dom [ Failure ImageOnlyFailure ]
     675webkit.org/b/149997 fast/html/details-replace-text.html [ Failure ]
    675676
    676677# Marks as flaky (see also https://bugs.webkit.org/show_bug.cgi?id=132388)
  • trunk/LayoutTests/platform/mac-mavericks/fast/html/details-open2-expected.txt

    r177774 r190840  
    1111        RenderBlock (anonymous) at (0,18) size 784x23
    1212          RenderTextControl {INPUT} at (2,2) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
    13           RenderText {#text} at (0,0) size 0x0
    14           RenderText {#text} at (0,0) size 0x0
    1513layer at (13,31) size 139x13
    1614  RenderBlock {DIV} at (3,3) size 140x13
  • trunk/LayoutTests/platform/mac/fast/css-generated-content/details-summary-before-after-expected.txt

    r177774 r190840  
    2525                text run at (0,0) width 30: "after"
    2626        RenderBlock (anonymous) at (1,77) size 782x18
     27          RenderText {#text} at (0,0) size 0x0
    2728          RenderText {#text} at (0,0) size 50x18
    2829            text run at (0,0) width 50: "Details "
  • trunk/LayoutTests/platform/mac/fast/html/details-add-child-2-expected.txt

    r177774 r190840  
    1313            RenderText {#text} at (0,0) size 144x18
    1414              text run at (0,0) width 144: "should have bold test"
    15           RenderText {#text} at (0,0) size 0x0
    16           RenderText {#text} at (0,0) size 0x0
  • trunk/LayoutTests/platform/mac/fast/html/details-open2-expected.txt

    r177774 r190840  
    1111        RenderBlock (anonymous) at (0,18) size 784x23
    1212          RenderTextControl {INPUT} at (2,2) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
    13           RenderText {#text} at (0,0) size 0x0
    14           RenderText {#text} at (0,0) size 0x0
    1513layer at (13,31) size 130x13
    1614  RenderBlock {DIV} at (3,3) size 131x13
  • trunk/LayoutTests/platform/mac/fast/html/details-remove-summary-1-and-click-expected.txt

    r177774 r190840  
    99          RenderText {#text} at (16,0) size 47x18
    1010            text run at (16,0) width 47: "Details"
    11 caret: position 0 of child 0 {DIV} of {#document-fragment} of child 0 {SUMMARY} of child 0 {WEBKITSHADOWCONTENT} of {#document-fragment} of child 1 {DETAILS} of body
     11caret: position 0 of child 0 {DIV} of {#document-fragment} of child 0 {SUMMARY} of child 0 {SLOT} of {#document-fragment} of child 1 {DETAILS} of body
  • trunk/LayoutTests/platform/mac/fast/html/details-remove-summary-4-and-click-expected.txt

    r177774 r190840  
    99          RenderText {#text} at (16,0) size 47x18
    1010            text run at (16,0) width 47: "Details"
    11 caret: position 0 of child 0 {DIV} of {#document-fragment} of child 0 {SUMMARY} of child 0 {WEBKITSHADOWCONTENT} of {#document-fragment} of child 1 {DETAILS} of body
     11caret: position 0 of child 0 {DIV} of {#document-fragment} of child 0 {SUMMARY} of child 0 {SLOT} of {#document-fragment} of child 1 {DETAILS} of body
  • trunk/Source/WebCore/CMakeLists.txt

    r190794 r190840  
    15011501    dom/SelectorQuery.cpp
    15021502    dom/ShadowRoot.cpp
     1503    dom/SlotAssignment.cpp
    15031504    dom/SpaceSplitString.cpp
    15041505    dom/StaticNodeList.cpp
     
    17011702    html/HTMLScriptElement.cpp
    17021703    html/HTMLSelectElement.cpp
     1704    html/HTMLSlotElement.cpp
    17031705    html/HTMLSourceElement.cpp
    17041706    html/HTMLSpanElement.cpp
  • trunk/Source/WebCore/ChangeLog

    r190838 r190840  
     12015-10-10  Antti Koivisto  <antti@apple.com>
     2
     3        Rewrite HTMLDetailsElement using HTMLSlotElement
     4        https://bugs.webkit.org/show_bug.cgi?id=149698
     5
     6        Reviewed by Andreas Kling.
     7
     8        Use the modern Shadow DOM to implement <details> element. After this the legacy InsertionPoint and
     9        related code can be removed.
     10
     11        Based on a patch by Ryosuke.
     12
     13        * dom/Element.cpp:
     14        (WebCore::Element::childrenChanged):
     15        * dom/EventDispatcher.cpp:
     16        (WebCore::EventPath::EventPath):
     17        * dom/ShadowRoot.cpp:
     18        (WebCore::ShadowRoot::ShadowRoot):
     19        (WebCore::ShadowRoot::~ShadowRoot):
     20        (WebCore::ShadowRoot::removeAllEventListeners):
     21        (WebCore::ShadowRoot::findAssignedSlot):
     22        (WebCore::ShadowRoot::addSlotElementByName):
     23        (WebCore::ShadowRoot::removeSlotElementByName):
     24        (WebCore::ShadowRoot::invalidateSlotAssignments):
     25        (WebCore::ShadowRoot::invalidateDefaultSlotAssignments):
     26        (WebCore::ShadowRoot::assignedNodesForSlot):
     27        * dom/ShadowRoot.h:
     28        (WebCore::ShadowRoot::create):
     29        (WebCore::ShadowRoot::distributor):
     30        (WebCore::ShadowRoot::isOrphan):
     31        * dom/SlotAssignment.cpp:
     32        (WebCore::slotNameFromAttributeValue):
     33
     34            Rename for clarity.
     35
     36        (WebCore::slotNameFromSlotAttribute):
     37
     38            SlotAssignment can now be specialized by providing function that maps from node to slot name.
     39            This is the default function that gets the name from the slot attribute.
     40
     41        (WebCore::SlotAssignment::SlotAssignment):
     42        (WebCore::SlotAssignment::findAssignedSlot):
     43
     44            Use the name mapping function.
     45            Ensure that the slots are assigned.
     46
     47        (WebCore::SlotAssignment::addSlotElementByName):
     48        (WebCore::SlotAssignment::removeSlotElementByName):
     49        (WebCore::SlotAssignment::assignedNodesForSlot):
     50        (WebCore::SlotAssignment::invalidate):
     51        (WebCore::SlotAssignment::invalidateDefaultSlot):
     52        (WebCore::SlotAssignment::resolveAllSlotElements):
     53        (WebCore::SlotAssignment::assignSlots):
     54
     55            Use the name mapping function.
     56
     57        (WebCore::SlotAssignment::assignToSlot):
     58
     59            Factor into function.
     60
     61        (WebCore::treatNullAsEmpty): Deleted.
     62        * dom/SlotAssignment.h:
     63        (WebCore::SlotAssignment::~SlotAssignment):
     64        (WebCore::SlotAssignment::defaultSlotName):
     65
     66            Add static getter for emptyAtom for clarity.
     67
     68        (WebCore::SlotAssignment::SlotAssignment): Deleted.
     69        * html/HTMLDetailsElement.cpp:
     70        (WebCore::summarySlotName):
     71        (WebCore::slotNameFunction):
     72
     73            Slot name function for <details>. It assigns the first <summary> child to the summary slot and others
     74            to the default content slot if the element is open.
     75
     76        (WebCore::HTMLDetailsElement::create):
     77        (WebCore::HTMLDetailsElement::didAddUserAgentShadowRoot):
     78        (WebCore::HTMLDetailsElement::isActiveSummary):
     79        (WebCore::HTMLDetailsElement::parseAttribute):
     80        (WebCore::HTMLDetailsElement::toggleOpen):
     81        (WebCore::summaryQuerySelector): Deleted.
     82        (WebCore::DetailsContentElement::create): Deleted.
     83        (WebCore::DetailsSummaryElement::create): Deleted.
     84        (WebCore::HTMLDetailsElement::findMainSummary): Deleted.
     85        (WebCore::HTMLDetailsElement::childShouldCreateRenderer): Deleted.
     86        * html/HTMLDetailsElement.h:
     87        * html/HTMLSummaryElement.cpp:
     88        (WebCore::HTMLSummaryElement::create):
     89        (WebCore::HTMLSummaryElement::createElementRenderer):
     90        (WebCore::HTMLSummaryElement::didAddUserAgentShadowRoot):
     91        (WebCore::HTMLSummaryElement::detailsElement):
     92        (WebCore::HTMLSummaryElement::isActiveSummary):
     93        (WebCore::isClickableControl):
     94        (WebCore::HTMLSummaryElement::supportsFocus):
     95        (WebCore::HTMLSummaryElement::defaultEventHandler):
     96        (WebCore::HTMLSummaryElement::willRespondToMouseClickEvents):
     97        (WebCore::SummaryContentElement::create): Deleted.
     98        (WebCore::HTMLSummaryElement::childShouldCreateRenderer): Deleted.
     99        (WebCore::HTMLSummaryElement::isMainSummary): Deleted.
     100        * html/HTMLSummaryElement.h:
     101        * html/shadow/DetailsMarkerControl.cpp:
     102        (WebCore::DetailsMarkerControl::rendererIsNeeded):
     103        * style/RenderTreePosition.cpp:
     104        (WebCore::RenderTreePosition::computeNextSibling):
     105
     106            Skip the verification assert for shadow host children. Getting this right requires
     107            better shadow-aware traversal code.
     108
     109        * style/StyleResolveTree.cpp:
     110        (WebCore::Style::invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded):
     111        (WebCore::Style::attachChildren):
     112        (WebCore::Style::attachShadowRoot):
     113        (WebCore::Style::attachBeforeOrAfterPseudoElementIfNeeded):
     114        (WebCore::Style::attachSlotAssignees):
     115        (WebCore::Style::attachRenderTree):
     116        (WebCore::Style::detachChildren):
     117        (WebCore::Style::detachShadowRoot):
     118        (WebCore::Style::detachSlotAssignees):
     119        (WebCore::Style::detachRenderTree):
     120        (WebCore::Style::resolveChildren):
     121        (WebCore::Style::resolveSlotAssignees):
     122        (WebCore::Style::resolveTree):
     123        (WebCore::Style::attachDistributedChildren): Deleted.
     124        (WebCore::Style::detachDistributedChildren): Deleted.
     125
     126            Remove InsertionPoint related code paths.
     127
    11282015-10-10  Andreas Kling  <akling@apple.com>
    2129
  • trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj

    r190723 r190840  
    1490014900    </ClCompile>
    1490114901    <ClCompile Include="..\dom\SelectorQuery.cpp">
     14902      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
     14903      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
     14904      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
     14905      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">true</ExcludedFromBuild>
     14906      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">true</ExcludedFromBuild>
     14907      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">true</ExcludedFromBuild>
     14908      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
     14909      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     14910      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
     14911      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">true</ExcludedFromBuild>
     14912      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
     14913      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
     14914    </ClCompile>
     14915    <ClCompile Include="..\dom\SlotAssignment.cpp">
    1490214916      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
    1490314917      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
     
    2205022064    <ClInclude Include="..\dom\SecurityOriginPolicy.h" />
    2205122065    <ClInclude Include="..\dom\SelectorQuery.h" />
     22066    <ClInclude Include="..\dom\SlotAssignment.h" />
    2205222067    <ClInclude Include="..\dom\SimulatedClickOptions.h" />
    2205322068    <ClInclude Include="..\dom\SpaceSplitString.h" />
  • trunk/Source/WebCore/dom/DOMAllInOne.cpp

    r190281 r190840  
    139139#include "SelectorQuery.cpp"
    140140#include "ShadowRoot.cpp"
     141#include "SlotAssignment.cpp"
    141142#include "SpaceSplitString.cpp"
    142143#include "StaticNodeList.cpp"
  • trunk/Source/WebCore/dom/Element.cpp

    r190138 r190840  
    18611861
    18621862    if (ShadowRoot* shadowRoot = this->shadowRoot()) {
    1863         if (auto* distributor = shadowRoot->distributor())
    1864             distributor->invalidateDistribution(this);
    1865 #if ENABLE(SHADOW_DOM)
     1863#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    18661864        switch (change.type) {
    18671865        case ElementInserted:
  • trunk/Source/WebCore/dom/EventDispatcher.cpp

    r190340 r190840  
    3333#include "HTMLMediaElement.h"
    3434#include "HTMLSlotElement.h"
    35 #include "InsertionPoint.h"
    3635#include "InspectorInstrumentation.h"
    3736#include "MouseEvent.h"
     
    404403    : m_event(event)
    405404{
    406 #if ENABLE(SHADOW_DOM)
     405#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    407406    Vector<EventTarget*, 16> targetStack;
    408407#endif
     
    434433            if (!parent)
    435434                return;
    436 #if ENABLE(SHADOW_DOM)
     435#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    437436            if (ShadowRoot* shadowRootOfParent = parent->shadowRoot()) {
    438437                if (auto* assignedSlot = shadowRootOfParent->findAssignedSlot(*node)) {
     
    449448        ShadowRoot& shadowRoot = downcast<ShadowRoot>(*node);
    450449        // At a shadow root. Continue dispatching the event at the shadow host.
    451 #if ENABLE(SHADOW_DOM)
     450#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    452451        if (!targetStack.isEmpty()) {
    453452            // Move target back to a descendant of the shadow host if the event did not originate in this shadow tree or its inner shadow trees.
  • trunk/Source/WebCore/dom/ShadowRoot.cpp

    r190347 r190840  
    3232#include "CSSStyleSheet.h"
    3333#include "ElementTraversal.h"
    34 #include "InsertionPoint.h"
    3534#include "RenderElement.h"
    3635#include "RuntimeEnabledFeatures.h"
     
    4645    void* authorStyleSheets;
    4746    void* host;
    48 #if ENABLE(SHADOW_DOM)
     47#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    4948    void* slotAssignment;
    5049#endif
     
    5655    : DocumentFragment(document, CreateShadowRoot)
    5756    , TreeScope(*this, document)
    58     , m_resetStyleInheritance(false)
    5957    , m_type(type)
    60     , m_host(nullptr)
    61 {
    62 }
     58{
     59}
     60
     61#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
     62
     63ShadowRoot::ShadowRoot(Document& document, std::unique_ptr<SlotAssignment>&& slotAssignment)
     64    : DocumentFragment(document, CreateShadowRoot)
     65    , TreeScope(*this, document)
     66    , m_type(Type::UserAgent)
     67    , m_slotAssignment(WTF::move(slotAssignment))
     68{
     69}
     70
     71#endif
    6372
    6473ShadowRoot::~ShadowRoot()
     
    176185}
    177186
    178 #if ENABLE(SHADOW_DOM)
     187#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    179188
    180189HTMLSlotElement* ShadowRoot::findAssignedSlot(const Node& node)
    181190{
    182     if (!m_slotAssignments)
     191    if (!m_slotAssignment)
    183192        return nullptr;
    184     return m_slotAssignments->findAssignedSlot(node, *this);
     193    return m_slotAssignment->findAssignedSlot(node, *this);
    185194}
    186195
    187196void ShadowRoot::addSlotElementByName(const AtomicString& name, HTMLSlotElement& slot)
    188197{
    189     if (!m_slotAssignments)
    190         m_slotAssignments = std::make_unique<SlotAssignment>();
    191 
    192     return m_slotAssignments->addSlotElementByName(name, slot, *this);
     198    if (!m_slotAssignment)
     199        m_slotAssignment = std::make_unique<SlotAssignment>();
     200
     201    return m_slotAssignment->addSlotElementByName(name, slot, *this);
    193202}
    194203
    195204void ShadowRoot::removeSlotElementByName(const AtomicString& name, HTMLSlotElement& slot)
    196205{
    197     return m_slotAssignments->removeSlotElementByName(name, slot, *this);
     206    return m_slotAssignment->removeSlotElementByName(name, slot, *this);
    198207}
    199208
    200209void ShadowRoot::invalidateSlotAssignments()
    201210{
    202     if (m_slotAssignments)
    203         m_slotAssignments->invalidate(*this);
     211    if (m_slotAssignment)
     212        m_slotAssignment->invalidate(*this);
    204213}
    205214
    206215void ShadowRoot::invalidateDefaultSlotAssignments()
    207216{
    208     if (m_slotAssignments)
    209         m_slotAssignments->invalidateDefaultSlot(*this);
     217    if (m_slotAssignment)
     218        m_slotAssignment->invalidateDefaultSlot(*this);
    210219}
    211220
    212221const Vector<Node*>* ShadowRoot::assignedNodesForSlot(const HTMLSlotElement& slot)
    213222{
    214     if (!m_slotAssignments)
     223    if (!m_slotAssignment)
    215224        return nullptr;
    216     return m_slotAssignments->assignedNodesForSlot(slot, *this);
     225    return m_slotAssignment->assignedNodesForSlot(slot, *this);
    217226}
    218227
  • trunk/Source/WebCore/dom/ShadowRoot.h

    r190256 r190840  
    5555    }
    5656
     57#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
     58    static Ref<ShadowRoot> create(Document& document, std::unique_ptr<SlotAssignment>&& assignment)
     59    {
     60        return adoptRef(*new ShadowRoot(document, WTF::move(assignment)));
     61    }
     62#endif
     63
    5764    virtual ~ShadowRoot();
    5865
     
    8289    virtual ContentDistributor* distributor() { return nullptr; }
    8390
    84 #if ENABLE(SHADOW_DOM)
     91#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    8592    HTMLSlotElement* findAssignedSlot(const Node&);
    8693
     
    97104    ShadowRoot(Document&, Type);
    98105
     106#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
     107    ShadowRoot(Document&, std::unique_ptr<SlotAssignment>&&);
     108#endif
     109
    99110    // FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
    100111    bool isOrphan() const { return !m_host; }
     
    105116    virtual Ref<Node> cloneNodeInternal(Document&, CloningOperation) override;
    106117
    107     bool m_resetStyleInheritance;
    108     Type m_type;
     118    bool m_resetStyleInheritance { false };
     119    Type m_type { Type::UserAgent };
    109120
    110     Element* m_host;
     121    Element* m_host { nullptr };
    111122
    112123    std::unique_ptr<StyleResolver> m_styleResolver;
    113124    std::unique_ptr<AuthorStyleSheets> m_authorStyleSheets;
    114125
    115 #if ENABLE(SHADOW_DOM)
    116     std::unique_ptr<SlotAssignment> m_slotAssignments;
     126#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
     127    std::unique_ptr<SlotAssignment> m_slotAssignment;
    117128#endif
    118129};
  • trunk/Source/WebCore/dom/SlotAssignment.cpp

    r190323 r190840  
    2727#include "SlotAssignment.h"
    2828
    29 #if ENABLE(SHADOW_DOM)
     29#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    3030
    3131#include "HTMLSlotElement.h"
     32#include "ShadowRoot.h"
    3233#include "TypedElementDescendantIterator.h"
    3334
     
    3637using namespace HTMLNames;
    3738
    38 static const AtomicString& treatNullAsEmpty(const AtomicString& name)
    39 {
    40     return name == nullAtom ? emptyAtom : name;
     39static const AtomicString& slotNameFromAttributeValue(const AtomicString& value)
     40{
     41    return value == nullAtom ? SlotAssignment::defaultSlotName() : value;
     42}
     43
     44static const AtomicString& slotNameFromSlotAttribute(const Node& child)
     45{
     46    if (!is<Element>(child))
     47        return SlotAssignment::defaultSlotName();
     48    return slotNameFromAttributeValue(downcast<Element>(child).fastGetAttribute(slotAttr));
     49}
     50
     51SlotAssignment::SlotAssignment()
     52    : m_slotNameFunction(slotNameFromSlotAttribute)
     53{
     54}
     55
     56SlotAssignment::SlotAssignment(SlotNameFunction function)
     57    : m_slotNameFunction(WTF::move(function))
     58{
    4159}
    4260
    4361HTMLSlotElement* SlotAssignment::findAssignedSlot(const Node& node, ShadowRoot& shadowRoot)
    4462{
    45     const AtomicString& name = is<Element>(node) ? downcast<Element>(node).fastGetAttribute(slotAttr) : emptyAtom;
    46 
    47     auto it = m_slots.find(treatNullAsEmpty(name));
     63    if (!m_slotAssignmentsIsValid)
     64        assignSlots(shadowRoot);
     65
     66    auto slotName = m_slotNameFunction(node);
     67    if (!slotName)
     68        return nullptr;
     69
     70    auto it = m_slots.find(slotName);
    4871    if (it == m_slots.end())
    4972        return nullptr;
     
    6285    shadowRoot.host()->setNeedsStyleRecalc(ReconstructRenderTree);
    6386
    64     const AtomicString& key = treatNullAsEmpty(name);
    65     auto addResult = m_slots.add(key, std::unique_ptr<SlotInfo>());
     87    const AtomicString& slotName = slotNameFromAttributeValue(name);
     88    auto addResult = m_slots.add(slotName, std::unique_ptr<SlotInfo>());
    6689    if (addResult.isNewEntry) {
    6790        addResult.iterator->value = std::make_unique<SlotInfo>(slotElement);
    68         if (key == emptyAtom) // Because assignSlots doesn't collect nodes assgined to the default slot as an optimzation.
     91        if (slotName == defaultSlotName()) // Because assignSlots doesn't collect nodes assigned to the default slot as an optimzation.
    6992            m_slotAssignmentsIsValid = false;
    7093        return;
     
    94117        host->setNeedsStyleRecalc(ReconstructRenderTree);
    95118
    96     auto it = m_slots.find(treatNullAsEmpty(name));
     119    auto it = m_slots.find(slotNameFromAttributeValue(name));
    97120    RELEASE_ASSERT(it != m_slots.end());
    98121
     
    115138        assignSlots(shadowRoot);
    116139
    117     const AtomicString& slotName = slotElement.fastGetAttribute(nameAttr);
    118     auto it = m_slots.find(treatNullAsEmpty(slotName));
     140    const AtomicString& slotName = slotNameFromAttributeValue(slotElement.fastGetAttribute(nameAttr));
     141    auto it = m_slots.find(slotName);
    119142    if (it == m_slots.end())
    120143        return nullptr;
     
    141164void SlotAssignment::invalidateDefaultSlot(ShadowRoot& shadowRoot)
    142165{
    143     auto it = m_slots.find(emptyAtom);
     166    auto it = m_slots.find(defaultSlotName());
    144167    if (it != m_slots.end() && it->value->elementCount)
    145168        invalidate(shadowRoot); // FIXME: We should be able to reconstruct only under the default slot.
     
    171194    unsigned slotCount = m_slots.size();
    172195    for (auto& slotElement : descendantsOfType<HTMLSlotElement>(shadowRoot)) {
    173         const AtomicString& slotName = slotElement.fastGetAttribute(nameAttr);
    174 
    175         auto it = m_slots.find(treatNullAsEmpty(slotName));
     196        auto& slotName = slotNameFromAttributeValue(slotElement.fastGetAttribute(nameAttr));
     197
     198        auto it = m_slots.find(slotName);
    176199        RELEASE_ASSERT(it != m_slots.end());
    177200
     
    193216    m_slotAssignmentsIsValid = true;
    194217
    195     auto* host = shadowRoot.host();
    196     RELEASE_ASSERT(host);
    197 
    198218    for (auto& entry : m_slots)
    199219        entry.value->assignedNodes.shrink(0);
    200220
    201     for (Node* child = host->firstChild(); child; child = child->nextSibling()) {
    202         if (is<Element>(child)) {
    203             auto& slotName = downcast<Element>(*child).fastGetAttribute(slotAttr);
    204             if (!slotName.isNull()) {
    205                 auto addResult = m_slots.add(treatNullAsEmpty(slotName), std::make_unique<SlotInfo>());
    206                 addResult.iterator->value->assignedNodes.append(child);
    207                 continue;
    208             }
    209         }
    210         auto defaultSlotEntry = m_slots.find(emptyAtom);
    211         if (defaultSlotEntry != m_slots.end())
    212             defaultSlotEntry->value->assignedNodes.append(child);
     221    auto& host = *shadowRoot.host();
     222    for (auto* child = host.firstChild(); child; child = child->nextSibling()) {
     223        auto slotName = m_slotNameFunction(*child);
     224        if (!slotName)
     225            continue;
     226        assignToSlot(*child, slotName);
    213227    }
    214228
     
    217231}
    218232
    219 }
    220 
    221 #endif
    222 
     233void SlotAssignment::assignToSlot(Node& child, const AtomicString& slotName)
     234{
     235    ASSERT(!slotName.isNull());
     236    if (slotName == defaultSlotName()) {
     237        auto defaultSlotEntry = m_slots.find(defaultSlotName());
     238        if (defaultSlotEntry != m_slots.end())
     239            defaultSlotEntry->value->assignedNodes.append(&child);
     240        return;
     241    }
     242
     243    auto addResult = m_slots.add(slotName, std::make_unique<SlotInfo>());
     244    addResult.iterator->value->assignedNodes.append(&child);
     245}
     246
     247}
     248
     249#endif
     250
  • trunk/Source/WebCore/dom/SlotAssignment.h

    r190323 r190840  
    2727#define SlotAssignment_h
    2828
    29 #if ENABLE(SHADOW_DOM)
     29#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    3030
    3131#include <wtf/HashMap.h>
     
    4444    WTF_MAKE_NONCOPYABLE(SlotAssignment);
    4545public:
    46     SlotAssignment() { }
     46    using SlotNameFunction = std::function<AtomicString (const Node& child)>;
     47
     48    SlotAssignment();
     49    SlotAssignment(SlotNameFunction);
     50    ~SlotAssignment() { }
     51
     52    static const AtomicString& defaultSlotName() { return emptyAtom; }
    4753
    4854    HTMLSlotElement* findAssignedSlot(const Node&, ShadowRoot&);
     
    7581    HTMLSlotElement* findFirstSlotElement(SlotInfo&, ShadowRoot&);
    7682    void resolveAllSlotElements(ShadowRoot&);
     83
    7784    void assignSlots(ShadowRoot&);
     85    void assignToSlot(Node& child, const AtomicString& slotName);
     86
     87    SlotNameFunction m_slotNameFunction;
    7888
    7989    HashMap<AtomicString, std::unique_ptr<SlotInfo>> m_slots;
  • trunk/Source/WebCore/html/HTMLDetailsElement.cpp

    r189824 r190840  
    2424#if ENABLE(DETAILS_ELEMENT)
    2525#include "AXObjectCache.h"
    26 #include "ContentDistributor.h"
    2726#include "ElementIterator.h"
     27#include "HTMLSlotElement.h"
    2828#include "HTMLSummaryElement.h"
    29 #include "InsertionPoint.h"
    3029#include "LocalizedStrings.h"
    3130#include "MouseEvent.h"
    3231#include "RenderBlockFlow.h"
     32#include "ShadowRoot.h"
     33#include "SlotAssignment.h"
    3334#include "Text.h"
    3435
     
    3738using namespace HTMLNames;
    3839
    39 static const AtomicString& summaryQuerySelector()
     40static const AtomicString& summarySlotName()
    4041{
    41     DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, selector, ("summary:first-of-type", AtomicString::ConstructFromLiteral));
    42     return selector;
    43 };
    44 
    45 class DetailsContentElement final : public InsertionPoint {
    46 public:
    47     static Ref<DetailsContentElement> create(Document&);
    48 
    49 private:
    50     DetailsContentElement(Document& document)
    51         : InsertionPoint(webkitShadowContentTag, document)
    52     {
    53     }
    54 
    55     virtual MatchType matchTypeFor(Node* node) const override
    56     {
    57         if (node->isElementNode() && node == node->parentNode()->querySelector(summaryQuerySelector(), ASSERT_NO_EXCEPTION))
    58             return NeverMatches;
    59         return AlwaysMatches;
    60     }
    61 };
    62 
    63 Ref<DetailsContentElement> DetailsContentElement::create(Document& document)
    64 {
    65     return adoptRef(*new DetailsContentElement(document));
     42    static NeverDestroyed<AtomicString> summarySlot("summarySlot");
     43    return summarySlot;
    6644}
    6745
    68 class DetailsSummaryElement final : public InsertionPoint {
    69 public:
    70     static Ref<DetailsSummaryElement> create(Document&);
     46static AtomicString slotNameFunction(const Node& child)
     47{
     48    auto& parent = *child.parentNode();
     49    ASSERT(is<HTMLDetailsElement>(parent));
     50    auto& details = downcast<HTMLDetailsElement>(parent);
    7151
    72     Element* fallbackSummary()
    73     {
    74         ASSERT(firstChild() && firstChild()->hasTagName(summaryTag));
    75         return downcast<Element>(firstChild());
     52    // The first summary child gets assigned to the summary slot.
     53    if (is<HTMLSummaryElement>(child)) {
     54        if (&child == childrenOfType<HTMLSummaryElement>(details).first())
     55            return summarySlotName();
    7656    }
     57    // Everything else is assigned to the default slot if details is open.
     58    if (details.isOpen())
     59        return SlotAssignment::defaultSlotName();
    7760
    78 private:
    79     DetailsSummaryElement(Document& document)
    80         : InsertionPoint(webkitShadowContentTag, document)
    81     {
    82     }
    83 
    84     virtual MatchType matchTypeFor(Node* node) const override
    85     {
    86         if (node->isElementNode() && node == node->parentNode()->querySelector(summaryQuerySelector(), ASSERT_NO_EXCEPTION))
    87             return AlwaysMatches;
    88         return NeverMatches;
    89     }
     61    // Otherwise don't render the content.
     62    return nullAtom;
    9063};
    91 
    92 Ref<DetailsSummaryElement> DetailsSummaryElement::create(Document& document)
    93 {
    94     Ref<HTMLSummaryElement> summary = HTMLSummaryElement::create(summaryTag, document);
    95     summary->appendChild(Text::create(document, defaultDetailsSummaryText()), ASSERT_NO_EXCEPTION);
    96 
    97     Ref<DetailsSummaryElement> detailsSummary = adoptRef(*new DetailsSummaryElement(document));
    98     detailsSummary->appendChild(WTF::move(summary));
    99     return detailsSummary;
    100 }
    10164
    10265Ref<HTMLDetailsElement> HTMLDetailsElement::create(const QualifiedName& tagName, Document& document)
    10366{
    104     Ref<HTMLDetailsElement> details = adoptRef(*new HTMLDetailsElement(tagName, document));
    105     details->addShadowRoot(ShadowRootWithInsertionPoints::create(document));
     67    auto details = adoptRef(*new HTMLDetailsElement(tagName, document));
     68    details->addShadowRoot(ShadowRoot::create(document, std::make_unique<SlotAssignment>(slotNameFunction)));
    10669    return details;
    10770}
     
    10972HTMLDetailsElement::HTMLDetailsElement(const QualifiedName& tagName, Document& document)
    11073    : HTMLElement(tagName, document)
    111     , m_isOpen(false)
    11274{
    11375    ASSERT(hasTagName(detailsTag));
     
    12183void HTMLDetailsElement::didAddUserAgentShadowRoot(ShadowRoot* root)
    12284{
    123     root->appendChild(DetailsSummaryElement::create(document()), ASSERT_NO_EXCEPTION);
    124     root->appendChild(DetailsContentElement::create(document()), ASSERT_NO_EXCEPTION);
     85    auto summarySlot = HTMLSlotElement::create(slotTag, document());
     86    summarySlot->setAttribute(nameAttr, summarySlotName());
     87    m_summarySlot = summarySlot.ptr();
     88
     89    auto defaultSummary = HTMLSummaryElement::create(summaryTag, document());
     90    defaultSummary->appendChild(Text::create(document(), defaultDetailsSummaryText()), ASSERT_NO_EXCEPTION);
     91    m_defaultSummary = defaultSummary.ptr();
     92
     93    summarySlot->appendChild(WTF::move(defaultSummary));
     94    root->appendChild(WTF::move(summarySlot));
     95
     96    auto defaultSlot = HTMLSlotElement::create(slotTag, document());
     97    root->appendChild(WTF::move(defaultSlot));
    12598}
    12699
    127 const Element* HTMLDetailsElement::findMainSummary() const
     100bool HTMLDetailsElement::isActiveSummary(const HTMLSummaryElement& summary) const
    128101{
    129     if (auto summary = childrenOfType<HTMLSummaryElement>(*this).first())
    130         return summary;
     102    if (!m_summarySlot->assignedNodes())
     103        return &summary == m_defaultSummary;
    131104
    132     return static_cast<DetailsSummaryElement*>(userAgentShadowRoot()->firstChild())->fallbackSummary();
     105    auto* slot = shadowRoot()->findAssignedSlot(summary);
     106    if (!slot)
     107        return false;
     108    return slot == m_summarySlot;
    133109}
    134110
     
    139115        m_isOpen = !value.isNull();
    140116        if (oldValue != m_isOpen)
    141             setNeedsStyleRecalc(ReconstructRenderTree);
     117            shadowRoot()->invalidateSlotAssignments();
    142118    } else
    143119        HTMLElement::parseAttribute(name, value);
    144120}
    145121
    146 bool HTMLDetailsElement::childShouldCreateRenderer(const Node& child) const
    147 {
    148     if (child.isPseudoElement())
    149         return HTMLElement::childShouldCreateRenderer(child);
    150 
    151     if (!hasShadowRootOrActiveInsertionPointParent(child))
    152         return false;
    153 
    154     if (m_isOpen)
    155         return HTMLElement::childShouldCreateRenderer(child);
    156 
    157     if (!child.hasTagName(summaryTag))
    158         return false;
    159 
    160     return &child == findMainSummary() && HTMLElement::childShouldCreateRenderer(child);
    161 }
    162122
    163123void HTMLDetailsElement::toggleOpen()
  • trunk/Source/WebCore/html/HTMLDetailsElement.h

    r189841 r190840  
    2626namespace WebCore {
    2727
     28class HTMLSlotElement;
     29
    2830class HTMLDetailsElement final : public HTMLElement {
    2931public:
     
    3133    void toggleOpen();
    3234
    33     const Element* findMainSummary() const;
    3435    bool isOpen() const { return m_isOpen; }
     36    bool isActiveSummary(const HTMLSummaryElement&) const;
    3537   
    3638private:
     
    3840
    3941    virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
    40     virtual bool childShouldCreateRenderer(const Node&) const override;
    4142    virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
    4243
     
    4445    virtual bool canHaveUserAgentShadowRoot() const override final { return true; }
    4546
    46     bool m_isOpen;
     47    bool m_isOpen { false };
     48    HTMLSlotElement* m_summarySlot { nullptr };
     49    HTMLSummaryElement* m_defaultSummary { nullptr };
    4750};
    4851
  • trunk/Source/WebCore/html/HTMLSlotElement.cpp

    r190093 r190840  
    2626#include "config.h"
    2727#include "HTMLSlotElement.h"
     28
     29#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    2830
    2931#include "ElementChildIterator.h"
     
    9698
    9799}
     100
     101#endif
  • trunk/Source/WebCore/html/HTMLSlotElement.h

    r190093 r190840  
    2727#define HTMLSlotElement_h
    2828
     29#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
     30
    2931#include "HTMLElement.h"
    3032#include "InsertionPoint.h"
     
    5052
    5153#endif
     54#endif
  • trunk/Source/WebCore/html/HTMLSummaryElement.cpp

    r189824 r190840  
    2626#include "HTMLDetailsElement.h"
    2727#include "HTMLFormControlElement.h"
    28 #include "InsertionPoint.h"
     28#include "HTMLSlotElement.h"
    2929#include "KeyboardEvent.h"
    3030#include "MouseEvent.h"
     
    3232#include "PlatformMouseEvent.h"
    3333#include "RenderBlockFlow.h"
     34#include "ShadowRoot.h"
    3435
    3536namespace WebCore {
     
    3738using namespace HTMLNames;
    3839
    39 class SummaryContentElement final : public InsertionPoint {
    40 public:
    41     static Ref<SummaryContentElement> create(Document&);
    42 
    43 private:
    44     SummaryContentElement(Document& document)
    45         : InsertionPoint(webkitShadowContentTag, document)
    46     {
    47     }
    48 };
    49 
    50 Ref<SummaryContentElement> SummaryContentElement::create(Document& document)
    51 {
    52     return adoptRef(*new SummaryContentElement(document));
    53 }
    54 
    5540Ref<HTMLSummaryElement> HTMLSummaryElement::create(const QualifiedName& tagName, Document& document)
    5641{
    5742    Ref<HTMLSummaryElement> summary = adoptRef(*new HTMLSummaryElement(tagName, document));
    58     summary->addShadowRoot(ShadowRootWithInsertionPoints::create(document));
     43    summary->addShadowRoot(ShadowRoot::create(document, ShadowRoot::Type::UserAgent));
    5944    return summary;
    6045}
     
    7156}
    7257
    73 bool HTMLSummaryElement::childShouldCreateRenderer(const Node& child) const
    74 {
    75     if (child.isPseudoElement())
    76         return HTMLElement::childShouldCreateRenderer(child);
    77 
    78     return hasShadowRootOrActiveInsertionPointParent(child) && HTMLElement::childShouldCreateRenderer(child);
    79 }
    80 
    8158void HTMLSummaryElement::didAddUserAgentShadowRoot(ShadowRoot* root)
    8259{
    8360    root->appendChild(DetailsMarkerControl::create(document()), ASSERT_NO_EXCEPTION);
    84     root->appendChild(SummaryContentElement::create(document()), ASSERT_NO_EXCEPTION);
     61    root->appendChild(HTMLSlotElement::create(slotTag, document()));
    8562}
    8663
    8764HTMLDetailsElement* HTMLSummaryElement::detailsElement() const
    8865{
    89     Node* mayDetails = NodeRenderingTraversal::parent(this);
    90     if (!mayDetails || !mayDetails->hasTagName(detailsTag))
    91         return nullptr;
    92     return downcast<HTMLDetailsElement>(mayDetails);
     66    auto* parent = parentElement();
     67    if (parent && is<HTMLDetailsElement>(*parent))
     68        return downcast<HTMLDetailsElement>(parent);
     69    // Fallback summary element is in the shadow tree.
     70    auto* host = shadowHost();
     71    if (host && is<HTMLDetailsElement>(*host))
     72        return downcast<HTMLDetailsElement>(host);
     73    return nullptr;
    9374}
    9475
    95 bool HTMLSummaryElement::isMainSummary() const
     76bool HTMLSummaryElement::isActiveSummary() const
    9677{
    97     if (HTMLDetailsElement* details = detailsElement())
    98         return details->findMainSummary() == this;
    99 
    100     return false;
     78    HTMLDetailsElement* details = detailsElement();
     79    if (!details)
     80        return false;
     81    return details->isActiveSummary(*this);
    10182}
    10283
     
    11596bool HTMLSummaryElement::supportsFocus() const
    11697{
    117     return isMainSummary();
     98    return isActiveSummary();
    11899}
    119100
    120101void HTMLSummaryElement::defaultEventHandler(Event* event)
    121102{
    122     if (isMainSummary() && renderer()) {
     103    if (isActiveSummary() && renderer()) {
    123104        if (event->type() == eventNames().DOMActivateEvent && !isClickableControl(event->target()->toNode())) {
    124105            if (HTMLDetailsElement* details = detailsElement())
     
    161142bool HTMLSummaryElement::willRespondToMouseClickEvents()
    162143{
    163     if (isMainSummary() && renderer())
     144    if (isActiveSummary() && renderer())
    164145        return true;
    165146
  • trunk/Source/WebCore/html/HTMLSummaryElement.h

    r189841 r190840  
    3232    static Ref<HTMLSummaryElement> create(const QualifiedName&, Document&);
    3333
    34     bool isMainSummary() const;
     34    bool isActiveSummary() const;
    3535    virtual bool willRespondToMouseClickEvents() override;
    3636
     
    3939
    4040    virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
    41     virtual bool childShouldCreateRenderer(const Node&) const override;
    4241    virtual void defaultEventHandler(Event*) override;
    4342
  • trunk/Source/WebCore/html/shadow/DetailsMarkerControl.cpp

    r183160 r190840  
    5858bool DetailsMarkerControl::rendererIsNeeded(const RenderStyle& style)
    5959{
    60     return downcast<HTMLSummaryElement>(shadowHost())->isMainSummary() && HTMLDivElement::rendererIsNeeded(style);
     60    return downcast<HTMLSummaryElement>(shadowHost())->isActiveSummary() && HTMLDivElement::rendererIsNeeded(style);
    6161}
    6262
  • trunk/Source/WebCore/style/RenderTreePosition.cpp

    r190585 r190840  
    3838    ASSERT(!node.renderer());
    3939    if (m_hasValidNextSibling) {
    40         // Stop validating at some point so the assert doesn't make us O(N^2) on debug builds.
    41         ASSERT(m_parent.isRenderView() || ++m_assertionLimitCounter > 20 || nextSiblingRenderer(node, m_parent) == m_nextSibling);
     40#if !ASSERT_DISABLED
     41        const unsigned oNSquaredAvoidanceLimit = 20;
     42        bool skipAssert = m_parent.isRenderView() || ++m_assertionLimitCounter > oNSquaredAvoidanceLimit;
     43        // FIXME: Traversal needs to know about slots and this needs be removed.
     44        skipAssert = skipAssert || (node.parentElement() && node.parentElement()->shadowRoot());
     45
     46        ASSERT(skipAssert || nextSiblingRenderer(node, m_parent) == m_nextSibling);
     47#endif
    4248        return;
    4349    }
  • trunk/Source/WebCore/style/StyleResolveTree.cpp

    r190430 r190840  
    3535#include "FlowThreadController.h"
    3636#include "HTMLSlotElement.h"
    37 #include "InsertionPoint.h"
    3837#include "InspectorInstrumentation.h"
    3938#include "LoaderStrategy.h"
     
    223222static void invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(Node& current)
    224223{
    225     if (is<InsertionPoint>(current))
    226         return;
     224    // FIXME: This needs to traverse in composed tree order.
     225
    227226    // This function finds sibling text renderers where the results of textRendererIsNeeded may have changed as a result of
    228227    // the current node gaining or losing the renderer. This can only affect white space text nodes.
     
    358357}
    359358
    360 static void attachDistributedChildren(InsertionPoint& insertionPoint, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition)
    361 {
    362     if (ShadowRoot* shadowRoot = insertionPoint.containingShadowRoot())
    363         ContentDistributor::ensureDistribution(shadowRoot);
    364 
    365     for (Node* current = insertionPoint.firstDistributed(); current; current = insertionPoint.nextDistributedTo(current)) {
    366         if (current->renderer())
    367             renderTreePosition.invalidateNextSibling(*current->renderer());
    368         if (is<Text>(*current)) {
    369             if (current->renderer())
    370                 continue;
    371             attachTextRenderer(downcast<Text>(*current), renderTreePosition);
    372             continue;
    373         }
    374         if (is<Element>(*current)) {
    375             Element& currentElement = downcast<Element>(*current);
    376             if (currentElement.renderer())
    377                 detachRenderTree(currentElement);
    378             attachRenderTree(currentElement, inheritedStyle, renderTreePosition, nullptr);
    379         }
    380     }
    381     // Use actual children as fallback content.
    382     if (!insertionPoint.hasDistribution())
    383         attachChildren(insertionPoint, inheritedStyle, renderTreePosition);
    384 }
    385 
    386359static void attachShadowRoot(ShadowRoot& shadowRoot)
    387360{
     
    471444}
    472445
    473 #if ENABLE(SHADOW_DOM)
     446#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    474447static void attachSlotAssignees(HTMLSlotElement& slot, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition)
    475448{
     
    481454                attachRenderTree(downcast<Element>(*child), inheritedStyle, renderTreePosition, nullptr);
    482455        }
    483     } else {
    484         for (Node* child = slot.firstChild(); child; child = child->nextSibling()) {
    485             if (is<Text>(*child))
    486                 attachTextRenderer(downcast<Text>(*child), renderTreePosition);
    487             else if (is<Element>(*child))
    488                 attachRenderTree(downcast<Element>(*child), inheritedStyle, renderTreePosition, nullptr);
    489         }
    490     }
     456    } else
     457        attachChildren(slot, inheritedStyle, renderTreePosition);
     458
    491459    slot.clearNeedsStyleRecalc();
    492460    slot.clearChildNeedsStyleRecalc();
     
    499467    WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
    500468
    501 #if ENABLE(SHADOW_DOM)
     469#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    502470    if (is<HTMLSlotElement>(current)) {
    503471        attachSlotAssignees(downcast<HTMLSlotElement>(current), inheritedStyle, renderTreePosition);
     
    505473    }
    506474#endif
    507     if (is<InsertionPoint>(current)) {
    508         attachDistributedChildren(downcast<InsertionPoint>(current), inheritedStyle, renderTreePosition);
    509         current.clearNeedsStyleRecalc();
    510         current.clearChildNeedsStyleRecalc();
    511         return;
    512     }
    513475
    514476    if (current.hasCustomStyleResolveCallbacks())
     
    530492            parentPusher.push();
    531493
    532         bool skipChildren = shadowRoot && shadowRoot->type() != ShadowRoot::Type::UserAgent;
     494        bool skipChildren = shadowRoot;
    533495        if (!skipChildren)
    534496            attachChildren(current, renderer->style(), childRenderTreePosition);
     
    548510    if (current.hasCustomStyleResolveCallbacks())
    549511        current.didAttachRenderers();
    550 }
    551 
    552 static void detachDistributedChildren(InsertionPoint& insertionPoint)
    553 {
    554     for (Node* current = insertionPoint.firstDistributed(); current; current = insertionPoint.nextDistributedTo(current)) {
    555         if (is<Text>(*current)) {
    556             detachTextRenderer(downcast<Text>(*current));
    557             continue;
    558         }
    559         if (is<Element>(*current))
    560             detachRenderTree(downcast<Element>(*current));
    561     }
    562512}
    563513
     
    578528}
    579529
    580 #if ENABLE(SHADOW_DOM)
     530#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    581531static void detachSlotAssignees(HTMLSlotElement& slot, DetachType detachType)
    582532{
     
    589539                detachRenderTree(downcast<Element>(*child), detachType);
    590540        }
    591     } else {
    592         for (Node* child = slot.firstChild(); child; child = child->nextSibling()) {
    593             if (is<Text>(*child))
    594                 detachTextRenderer(downcast<Text>(*child));
    595             else if (is<Element>(*child))
    596                 detachRenderTree(downcast<Element>(*child), detachType);
    597         }
    598     }
     541    } else
     542        detachChildren(slot, detachType);
     543
    599544    slot.clearNeedsStyleRecalc();
    600545    slot.clearChildNeedsStyleRecalc();
     
    616561        current.clearHoverAndActiveStatusBeforeDetachingRenderer();
    617562
    618     if (is<InsertionPoint>(current))
    619         detachDistributedChildren(downcast<InsertionPoint>(current));
    620 #if ENABLE(SHADOW_DOM)
    621     else if (is<HTMLSlotElement>(current))
     563#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
     564    if (is<HTMLSlotElement>(current))
    622565        detachSlotAssignees(downcast<HTMLSlotElement>(current), detachType);
    623566#endif
     
    857800}
    858801
    859 #if ENABLE(SHADOW_DOM)
     802#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    860803static void resolveSlotAssignees(HTMLSlotElement& slot, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Change change)
    861804{
     
    884827    ASSERT(change != Detach);
    885828
    886 #if ENABLE(SHADOW_DOM)
     829#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
    887830    if (is<HTMLSlotElement>(current)) {
    888831        resolveSlotAssignees(downcast<HTMLSlotElement>(current), inheritedStyle, renderTreePosition, change);
     
    890833    }
    891834#endif
    892     if (is<InsertionPoint>(current)) {
    893         current.clearNeedsStyleRecalc();
    894         current.clearChildNeedsStyleRecalc();
    895         return;
    896     }
    897835
    898836    if (current.hasCustomStyleResolveCallbacks()) {
     
    921859        updateBeforeOrAfterPseudoElement(current, change, BEFORE, childRenderTreePosition);
    922860
    923         bool skipChildren = shadowRoot && shadowRoot->type() != ShadowRoot::Type::UserAgent;
     861        bool skipChildren = shadowRoot;
    924862        if (!skipChildren)
    925863            resolveChildren(current, renderer->style(), change, childRenderTreePosition);
Note: See TracChangeset for help on using the changeset viewer.