Changeset 190840 in webkit
- Timestamp:
- Oct 10, 2015, 11:16:37 AM (10 years ago)
- Location:
- trunk
- Files:
-
- 27 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r190838 r190840 1 2015-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 1 14 2015-10-10 Andreas Kling <akling@apple.com> 2 15 -
trunk/LayoutTests/TestExpectations
r190836 r190840 673 673 674 674 webkit.org/b/148695 fast/shadow-dom [ Failure ImageOnlyFailure ] 675 webkit.org/b/149997 fast/html/details-replace-text.html [ Failure ] 675 676 676 677 # 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 11 11 RenderBlock (anonymous) at (0,18) size 784x23 12 12 RenderTextControl {INPUT} at (2,2) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)] 13 RenderText {#text} at (0,0) size 0x014 RenderText {#text} at (0,0) size 0x015 13 layer at (13,31) size 139x13 16 14 RenderBlock {DIV} at (3,3) size 140x13 -
trunk/LayoutTests/platform/mac/fast/css-generated-content/details-summary-before-after-expected.txt
r177774 r190840 25 25 text run at (0,0) width 30: "after" 26 26 RenderBlock (anonymous) at (1,77) size 782x18 27 RenderText {#text} at (0,0) size 0x0 27 28 RenderText {#text} at (0,0) size 50x18 28 29 text run at (0,0) width 50: "Details " -
trunk/LayoutTests/platform/mac/fast/html/details-add-child-2-expected.txt
r177774 r190840 13 13 RenderText {#text} at (0,0) size 144x18 14 14 text run at (0,0) width 144: "should have bold test" 15 RenderText {#text} at (0,0) size 0x016 RenderText {#text} at (0,0) size 0x0 -
trunk/LayoutTests/platform/mac/fast/html/details-open2-expected.txt
r177774 r190840 11 11 RenderBlock (anonymous) at (0,18) size 784x23 12 12 RenderTextControl {INPUT} at (2,2) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)] 13 RenderText {#text} at (0,0) size 0x014 RenderText {#text} at (0,0) size 0x015 13 layer at (13,31) size 130x13 16 14 RenderBlock {DIV} at (3,3) size 131x13 -
trunk/LayoutTests/platform/mac/fast/html/details-remove-summary-1-and-click-expected.txt
r177774 r190840 9 9 RenderText {#text} at (16,0) size 47x18 10 10 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 body11 caret: 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 9 9 RenderText {#text} at (16,0) size 47x18 10 10 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 body11 caret: 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 1501 1501 dom/SelectorQuery.cpp 1502 1502 dom/ShadowRoot.cpp 1503 dom/SlotAssignment.cpp 1503 1504 dom/SpaceSplitString.cpp 1504 1505 dom/StaticNodeList.cpp … … 1701 1702 html/HTMLScriptElement.cpp 1702 1703 html/HTMLSelectElement.cpp 1704 html/HTMLSlotElement.cpp 1703 1705 html/HTMLSourceElement.cpp 1704 1706 html/HTMLSpanElement.cpp -
trunk/Source/WebCore/ChangeLog
r190838 r190840 1 2015-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 1 128 2015-10-10 Andreas Kling <akling@apple.com> 2 129 -
trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
r190723 r190840 14900 14900 </ClCompile> 14901 14901 <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"> 14902 14916 <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> 14903 14917 <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> … … 22050 22064 <ClInclude Include="..\dom\SecurityOriginPolicy.h" /> 22051 22065 <ClInclude Include="..\dom\SelectorQuery.h" /> 22066 <ClInclude Include="..\dom\SlotAssignment.h" /> 22052 22067 <ClInclude Include="..\dom\SimulatedClickOptions.h" /> 22053 22068 <ClInclude Include="..\dom\SpaceSplitString.h" /> -
trunk/Source/WebCore/dom/DOMAllInOne.cpp
r190281 r190840 139 139 #include "SelectorQuery.cpp" 140 140 #include "ShadowRoot.cpp" 141 #include "SlotAssignment.cpp" 141 142 #include "SpaceSplitString.cpp" 142 143 #include "StaticNodeList.cpp" -
trunk/Source/WebCore/dom/Element.cpp
r190138 r190840 1861 1861 1862 1862 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) 1866 1864 switch (change.type) { 1867 1865 case ElementInserted: -
trunk/Source/WebCore/dom/EventDispatcher.cpp
r190340 r190840 33 33 #include "HTMLMediaElement.h" 34 34 #include "HTMLSlotElement.h" 35 #include "InsertionPoint.h"36 35 #include "InspectorInstrumentation.h" 37 36 #include "MouseEvent.h" … … 404 403 : m_event(event) 405 404 { 406 #if ENABLE(SHADOW_DOM) 405 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 407 406 Vector<EventTarget*, 16> targetStack; 408 407 #endif … … 434 433 if (!parent) 435 434 return; 436 #if ENABLE(SHADOW_DOM) 435 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 437 436 if (ShadowRoot* shadowRootOfParent = parent->shadowRoot()) { 438 437 if (auto* assignedSlot = shadowRootOfParent->findAssignedSlot(*node)) { … … 449 448 ShadowRoot& shadowRoot = downcast<ShadowRoot>(*node); 450 449 // 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) 452 451 if (!targetStack.isEmpty()) { 453 452 // 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 32 32 #include "CSSStyleSheet.h" 33 33 #include "ElementTraversal.h" 34 #include "InsertionPoint.h"35 34 #include "RenderElement.h" 36 35 #include "RuntimeEnabledFeatures.h" … … 46 45 void* authorStyleSheets; 47 46 void* host; 48 #if ENABLE(SHADOW_DOM) 47 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 49 48 void* slotAssignment; 50 49 #endif … … 56 55 : DocumentFragment(document, CreateShadowRoot) 57 56 , TreeScope(*this, document) 58 , m_resetStyleInheritance(false)59 57 , m_type(type) 60 , m_host(nullptr) 61 { 62 } 58 { 59 } 60 61 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 62 63 ShadowRoot::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 63 72 64 73 ShadowRoot::~ShadowRoot() … … 176 185 } 177 186 178 #if ENABLE(SHADOW_DOM) 187 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 179 188 180 189 HTMLSlotElement* ShadowRoot::findAssignedSlot(const Node& node) 181 190 { 182 if (!m_slotAssignment s)191 if (!m_slotAssignment) 183 192 return nullptr; 184 return m_slotAssignment s->findAssignedSlot(node, *this);193 return m_slotAssignment->findAssignedSlot(node, *this); 185 194 } 186 195 187 196 void ShadowRoot::addSlotElementByName(const AtomicString& name, HTMLSlotElement& slot) 188 197 { 189 if (!m_slotAssignment s)190 m_slotAssignment s= std::make_unique<SlotAssignment>();191 192 return m_slotAssignment s->addSlotElementByName(name, slot, *this);198 if (!m_slotAssignment) 199 m_slotAssignment = std::make_unique<SlotAssignment>(); 200 201 return m_slotAssignment->addSlotElementByName(name, slot, *this); 193 202 } 194 203 195 204 void ShadowRoot::removeSlotElementByName(const AtomicString& name, HTMLSlotElement& slot) 196 205 { 197 return m_slotAssignment s->removeSlotElementByName(name, slot, *this);206 return m_slotAssignment->removeSlotElementByName(name, slot, *this); 198 207 } 199 208 200 209 void ShadowRoot::invalidateSlotAssignments() 201 210 { 202 if (m_slotAssignment s)203 m_slotAssignment s->invalidate(*this);211 if (m_slotAssignment) 212 m_slotAssignment->invalidate(*this); 204 213 } 205 214 206 215 void ShadowRoot::invalidateDefaultSlotAssignments() 207 216 { 208 if (m_slotAssignment s)209 m_slotAssignment s->invalidateDefaultSlot(*this);217 if (m_slotAssignment) 218 m_slotAssignment->invalidateDefaultSlot(*this); 210 219 } 211 220 212 221 const Vector<Node*>* ShadowRoot::assignedNodesForSlot(const HTMLSlotElement& slot) 213 222 { 214 if (!m_slotAssignment s)223 if (!m_slotAssignment) 215 224 return nullptr; 216 return m_slotAssignment s->assignedNodesForSlot(slot, *this);225 return m_slotAssignment->assignedNodesForSlot(slot, *this); 217 226 } 218 227 -
trunk/Source/WebCore/dom/ShadowRoot.h
r190256 r190840 55 55 } 56 56 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 57 64 virtual ~ShadowRoot(); 58 65 … … 82 89 virtual ContentDistributor* distributor() { return nullptr; } 83 90 84 #if ENABLE(SHADOW_DOM) 91 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 85 92 HTMLSlotElement* findAssignedSlot(const Node&); 86 93 … … 97 104 ShadowRoot(Document&, Type); 98 105 106 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 107 ShadowRoot(Document&, std::unique_ptr<SlotAssignment>&&); 108 #endif 109 99 110 // FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834 100 111 bool isOrphan() const { return !m_host; } … … 105 116 virtual Ref<Node> cloneNodeInternal(Document&, CloningOperation) override; 106 117 107 bool m_resetStyleInheritance ;108 Type m_type ;118 bool m_resetStyleInheritance { false }; 119 Type m_type { Type::UserAgent }; 109 120 110 Element* m_host ;121 Element* m_host { nullptr }; 111 122 112 123 std::unique_ptr<StyleResolver> m_styleResolver; 113 124 std::unique_ptr<AuthorStyleSheets> m_authorStyleSheets; 114 125 115 #if ENABLE(SHADOW_DOM) 116 std::unique_ptr<SlotAssignment> m_slotAssignment s;126 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 127 std::unique_ptr<SlotAssignment> m_slotAssignment; 117 128 #endif 118 129 }; -
trunk/Source/WebCore/dom/SlotAssignment.cpp
r190323 r190840 27 27 #include "SlotAssignment.h" 28 28 29 #if ENABLE(SHADOW_DOM) 29 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 30 30 31 31 #include "HTMLSlotElement.h" 32 #include "ShadowRoot.h" 32 33 #include "TypedElementDescendantIterator.h" 33 34 … … 36 37 using namespace HTMLNames; 37 38 38 static const AtomicString& treatNullAsEmpty(const AtomicString& name) 39 { 40 return name == nullAtom ? emptyAtom : name; 39 static const AtomicString& slotNameFromAttributeValue(const AtomicString& value) 40 { 41 return value == nullAtom ? SlotAssignment::defaultSlotName() : value; 42 } 43 44 static 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 51 SlotAssignment::SlotAssignment() 52 : m_slotNameFunction(slotNameFromSlotAttribute) 53 { 54 } 55 56 SlotAssignment::SlotAssignment(SlotNameFunction function) 57 : m_slotNameFunction(WTF::move(function)) 58 { 41 59 } 42 60 43 61 HTMLSlotElement* SlotAssignment::findAssignedSlot(const Node& node, ShadowRoot& shadowRoot) 44 62 { 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); 48 71 if (it == m_slots.end()) 49 72 return nullptr; … … 62 85 shadowRoot.host()->setNeedsStyleRecalc(ReconstructRenderTree); 63 86 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>()); 66 89 if (addResult.isNewEntry) { 67 90 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. 69 92 m_slotAssignmentsIsValid = false; 70 93 return; … … 94 117 host->setNeedsStyleRecalc(ReconstructRenderTree); 95 118 96 auto it = m_slots.find( treatNullAsEmpty(name));119 auto it = m_slots.find(slotNameFromAttributeValue(name)); 97 120 RELEASE_ASSERT(it != m_slots.end()); 98 121 … … 115 138 assignSlots(shadowRoot); 116 139 117 const AtomicString& slotName = slot Element.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); 119 142 if (it == m_slots.end()) 120 143 return nullptr; … … 141 164 void SlotAssignment::invalidateDefaultSlot(ShadowRoot& shadowRoot) 142 165 { 143 auto it = m_slots.find( emptyAtom);166 auto it = m_slots.find(defaultSlotName()); 144 167 if (it != m_slots.end() && it->value->elementCount) 145 168 invalidate(shadowRoot); // FIXME: We should be able to reconstruct only under the default slot. … … 171 194 unsigned slotCount = m_slots.size(); 172 195 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); 176 199 RELEASE_ASSERT(it != m_slots.end()); 177 200 … … 193 216 m_slotAssignmentsIsValid = true; 194 217 195 auto* host = shadowRoot.host();196 RELEASE_ASSERT(host);197 198 218 for (auto& entry : m_slots) 199 219 entry.value->assignedNodes.shrink(0); 200 220 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); 213 227 } 214 228 … … 217 231 } 218 232 219 } 220 221 #endif 222 233 void 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 27 27 #define SlotAssignment_h 28 28 29 #if ENABLE(SHADOW_DOM) 29 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 30 30 31 31 #include <wtf/HashMap.h> … … 44 44 WTF_MAKE_NONCOPYABLE(SlotAssignment); 45 45 public: 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; } 47 53 48 54 HTMLSlotElement* findAssignedSlot(const Node&, ShadowRoot&); … … 75 81 HTMLSlotElement* findFirstSlotElement(SlotInfo&, ShadowRoot&); 76 82 void resolveAllSlotElements(ShadowRoot&); 83 77 84 void assignSlots(ShadowRoot&); 85 void assignToSlot(Node& child, const AtomicString& slotName); 86 87 SlotNameFunction m_slotNameFunction; 78 88 79 89 HashMap<AtomicString, std::unique_ptr<SlotInfo>> m_slots; -
trunk/Source/WebCore/html/HTMLDetailsElement.cpp
r189824 r190840 24 24 #if ENABLE(DETAILS_ELEMENT) 25 25 #include "AXObjectCache.h" 26 #include "ContentDistributor.h"27 26 #include "ElementIterator.h" 27 #include "HTMLSlotElement.h" 28 28 #include "HTMLSummaryElement.h" 29 #include "InsertionPoint.h"30 29 #include "LocalizedStrings.h" 31 30 #include "MouseEvent.h" 32 31 #include "RenderBlockFlow.h" 32 #include "ShadowRoot.h" 33 #include "SlotAssignment.h" 33 34 #include "Text.h" 34 35 … … 37 38 using namespace HTMLNames; 38 39 39 static const AtomicString& summary QuerySelector()40 static const AtomicString& summarySlotName() 40 41 { 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; 66 44 } 67 45 68 class DetailsSummaryElement final : public InsertionPoint { 69 public: 70 static Ref<DetailsSummaryElement> create(Document&); 46 static AtomicString slotNameFunction(const Node& child) 47 { 48 auto& parent = *child.parentNode(); 49 ASSERT(is<HTMLDetailsElement>(parent)); 50 auto& details = downcast<HTMLDetailsElement>(parent); 71 51 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(); 76 56 } 57 // Everything else is assigned to the default slot if details is open. 58 if (details.isOpen()) 59 return SlotAssignment::defaultSlotName(); 77 60 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; 90 63 }; 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 }101 64 102 65 Ref<HTMLDetailsElement> HTMLDetailsElement::create(const QualifiedName& tagName, Document& document) 103 66 { 104 Ref<HTMLDetailsElement>details = adoptRef(*new HTMLDetailsElement(tagName, document));105 details->addShadowRoot(ShadowRoot WithInsertionPoints::create(document));67 auto details = adoptRef(*new HTMLDetailsElement(tagName, document)); 68 details->addShadowRoot(ShadowRoot::create(document, std::make_unique<SlotAssignment>(slotNameFunction))); 106 69 return details; 107 70 } … … 109 72 HTMLDetailsElement::HTMLDetailsElement(const QualifiedName& tagName, Document& document) 110 73 : HTMLElement(tagName, document) 111 , m_isOpen(false)112 74 { 113 75 ASSERT(hasTagName(detailsTag)); … … 121 83 void HTMLDetailsElement::didAddUserAgentShadowRoot(ShadowRoot* root) 122 84 { 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)); 125 98 } 126 99 127 const Element* HTMLDetailsElement::findMainSummary() const100 bool HTMLDetailsElement::isActiveSummary(const HTMLSummaryElement& summary) const 128 101 { 129 if ( auto summary = childrenOfType<HTMLSummaryElement>(*this).first())130 return summary;102 if (!m_summarySlot->assignedNodes()) 103 return &summary == m_defaultSummary; 131 104 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; 133 109 } 134 110 … … 139 115 m_isOpen = !value.isNull(); 140 116 if (oldValue != m_isOpen) 141 s etNeedsStyleRecalc(ReconstructRenderTree);117 shadowRoot()->invalidateSlotAssignments(); 142 118 } else 143 119 HTMLElement::parseAttribute(name, value); 144 120 } 145 121 146 bool HTMLDetailsElement::childShouldCreateRenderer(const Node& child) const147 {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 }162 122 163 123 void HTMLDetailsElement::toggleOpen() -
trunk/Source/WebCore/html/HTMLDetailsElement.h
r189841 r190840 26 26 namespace WebCore { 27 27 28 class HTMLSlotElement; 29 28 30 class HTMLDetailsElement final : public HTMLElement { 29 31 public: … … 31 33 void toggleOpen(); 32 34 33 const Element* findMainSummary() const;34 35 bool isOpen() const { return m_isOpen; } 36 bool isActiveSummary(const HTMLSummaryElement&) const; 35 37 36 38 private: … … 38 40 39 41 virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override; 40 virtual bool childShouldCreateRenderer(const Node&) const override;41 42 virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; 42 43 … … 44 45 virtual bool canHaveUserAgentShadowRoot() const override final { return true; } 45 46 46 bool m_isOpen; 47 bool m_isOpen { false }; 48 HTMLSlotElement* m_summarySlot { nullptr }; 49 HTMLSummaryElement* m_defaultSummary { nullptr }; 47 50 }; 48 51 -
trunk/Source/WebCore/html/HTMLSlotElement.cpp
r190093 r190840 26 26 #include "config.h" 27 27 #include "HTMLSlotElement.h" 28 29 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 28 30 29 31 #include "ElementChildIterator.h" … … 96 98 97 99 } 100 101 #endif -
trunk/Source/WebCore/html/HTMLSlotElement.h
r190093 r190840 27 27 #define HTMLSlotElement_h 28 28 29 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 30 29 31 #include "HTMLElement.h" 30 32 #include "InsertionPoint.h" … … 50 52 51 53 #endif 54 #endif -
trunk/Source/WebCore/html/HTMLSummaryElement.cpp
r189824 r190840 26 26 #include "HTMLDetailsElement.h" 27 27 #include "HTMLFormControlElement.h" 28 #include " InsertionPoint.h"28 #include "HTMLSlotElement.h" 29 29 #include "KeyboardEvent.h" 30 30 #include "MouseEvent.h" … … 32 32 #include "PlatformMouseEvent.h" 33 33 #include "RenderBlockFlow.h" 34 #include "ShadowRoot.h" 34 35 35 36 namespace WebCore { … … 37 38 using namespace HTMLNames; 38 39 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 55 40 Ref<HTMLSummaryElement> HTMLSummaryElement::create(const QualifiedName& tagName, Document& document) 56 41 { 57 42 Ref<HTMLSummaryElement> summary = adoptRef(*new HTMLSummaryElement(tagName, document)); 58 summary->addShadowRoot(ShadowRoot WithInsertionPoints::create(document));43 summary->addShadowRoot(ShadowRoot::create(document, ShadowRoot::Type::UserAgent)); 59 44 return summary; 60 45 } … … 71 56 } 72 57 73 bool HTMLSummaryElement::childShouldCreateRenderer(const Node& child) const74 {75 if (child.isPseudoElement())76 return HTMLElement::childShouldCreateRenderer(child);77 78 return hasShadowRootOrActiveInsertionPointParent(child) && HTMLElement::childShouldCreateRenderer(child);79 }80 81 58 void HTMLSummaryElement::didAddUserAgentShadowRoot(ShadowRoot* root) 82 59 { 83 60 root->appendChild(DetailsMarkerControl::create(document()), ASSERT_NO_EXCEPTION); 84 root->appendChild( SummaryContentElement::create(document()), ASSERT_NO_EXCEPTION);61 root->appendChild(HTMLSlotElement::create(slotTag, document())); 85 62 } 86 63 87 64 HTMLDetailsElement* HTMLSummaryElement::detailsElement() const 88 65 { 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; 93 74 } 94 75 95 bool HTMLSummaryElement::is MainSummary() const76 bool HTMLSummaryElement::isActiveSummary() const 96 77 { 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); 101 82 } 102 83 … … 115 96 bool HTMLSummaryElement::supportsFocus() const 116 97 { 117 return is MainSummary();98 return isActiveSummary(); 118 99 } 119 100 120 101 void HTMLSummaryElement::defaultEventHandler(Event* event) 121 102 { 122 if (is MainSummary() && renderer()) {103 if (isActiveSummary() && renderer()) { 123 104 if (event->type() == eventNames().DOMActivateEvent && !isClickableControl(event->target()->toNode())) { 124 105 if (HTMLDetailsElement* details = detailsElement()) … … 161 142 bool HTMLSummaryElement::willRespondToMouseClickEvents() 162 143 { 163 if (is MainSummary() && renderer())144 if (isActiveSummary() && renderer()) 164 145 return true; 165 146 -
trunk/Source/WebCore/html/HTMLSummaryElement.h
r189841 r190840 32 32 static Ref<HTMLSummaryElement> create(const QualifiedName&, Document&); 33 33 34 bool is MainSummary() const;34 bool isActiveSummary() const; 35 35 virtual bool willRespondToMouseClickEvents() override; 36 36 … … 39 39 40 40 virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override; 41 virtual bool childShouldCreateRenderer(const Node&) const override;42 41 virtual void defaultEventHandler(Event*) override; 43 42 -
trunk/Source/WebCore/html/shadow/DetailsMarkerControl.cpp
r183160 r190840 58 58 bool DetailsMarkerControl::rendererIsNeeded(const RenderStyle& style) 59 59 { 60 return downcast<HTMLSummaryElement>(shadowHost())->is MainSummary() && HTMLDivElement::rendererIsNeeded(style);60 return downcast<HTMLSummaryElement>(shadowHost())->isActiveSummary() && HTMLDivElement::rendererIsNeeded(style); 61 61 } 62 62 -
trunk/Source/WebCore/style/RenderTreePosition.cpp
r190585 r190840 38 38 ASSERT(!node.renderer()); 39 39 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 42 48 return; 43 49 } -
trunk/Source/WebCore/style/StyleResolveTree.cpp
r190430 r190840 35 35 #include "FlowThreadController.h" 36 36 #include "HTMLSlotElement.h" 37 #include "InsertionPoint.h"38 37 #include "InspectorInstrumentation.h" 39 38 #include "LoaderStrategy.h" … … 223 222 static void invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(Node& current) 224 223 { 225 if (is<InsertionPoint>(current))226 return; 224 // FIXME: This needs to traverse in composed tree order. 225 227 226 // This function finds sibling text renderers where the results of textRendererIsNeeded may have changed as a result of 228 227 // the current node gaining or losing the renderer. This can only affect white space text nodes. … … 358 357 } 359 358 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 386 359 static void attachShadowRoot(ShadowRoot& shadowRoot) 387 360 { … … 471 444 } 472 445 473 #if ENABLE(SHADOW_DOM) 446 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 474 447 static void attachSlotAssignees(HTMLSlotElement& slot, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition) 475 448 { … … 481 454 attachRenderTree(downcast<Element>(*child), inheritedStyle, renderTreePosition, nullptr); 482 455 } 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 491 459 slot.clearNeedsStyleRecalc(); 492 460 slot.clearChildNeedsStyleRecalc(); … … 499 467 WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates; 500 468 501 #if ENABLE(SHADOW_DOM) 469 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 502 470 if (is<HTMLSlotElement>(current)) { 503 471 attachSlotAssignees(downcast<HTMLSlotElement>(current), inheritedStyle, renderTreePosition); … … 505 473 } 506 474 #endif 507 if (is<InsertionPoint>(current)) {508 attachDistributedChildren(downcast<InsertionPoint>(current), inheritedStyle, renderTreePosition);509 current.clearNeedsStyleRecalc();510 current.clearChildNeedsStyleRecalc();511 return;512 }513 475 514 476 if (current.hasCustomStyleResolveCallbacks()) … … 530 492 parentPusher.push(); 531 493 532 bool skipChildren = shadowRoot && shadowRoot->type() != ShadowRoot::Type::UserAgent;494 bool skipChildren = shadowRoot; 533 495 if (!skipChildren) 534 496 attachChildren(current, renderer->style(), childRenderTreePosition); … … 548 510 if (current.hasCustomStyleResolveCallbacks()) 549 511 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 }562 512 } 563 513 … … 578 528 } 579 529 580 #if ENABLE(SHADOW_DOM) 530 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 581 531 static void detachSlotAssignees(HTMLSlotElement& slot, DetachType detachType) 582 532 { … … 589 539 detachRenderTree(downcast<Element>(*child), detachType); 590 540 } 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 599 544 slot.clearNeedsStyleRecalc(); 600 545 slot.clearChildNeedsStyleRecalc(); … … 616 561 current.clearHoverAndActiveStatusBeforeDetachingRenderer(); 617 562 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)) 622 565 detachSlotAssignees(downcast<HTMLSlotElement>(current), detachType); 623 566 #endif … … 857 800 } 858 801 859 #if ENABLE(SHADOW_DOM) 802 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 860 803 static void resolveSlotAssignees(HTMLSlotElement& slot, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Change change) 861 804 { … … 884 827 ASSERT(change != Detach); 885 828 886 #if ENABLE(SHADOW_DOM) 829 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 887 830 if (is<HTMLSlotElement>(current)) { 888 831 resolveSlotAssignees(downcast<HTMLSlotElement>(current), inheritedStyle, renderTreePosition, change); … … 890 833 } 891 834 #endif 892 if (is<InsertionPoint>(current)) {893 current.clearNeedsStyleRecalc();894 current.clearChildNeedsStyleRecalc();895 return;896 }897 835 898 836 if (current.hasCustomStyleResolveCallbacks()) { … … 921 859 updateBeforeOrAfterPseudoElement(current, change, BEFORE, childRenderTreePosition); 922 860 923 bool skipChildren = shadowRoot && shadowRoot->type() != ShadowRoot::Type::UserAgent;861 bool skipChildren = shadowRoot; 924 862 if (!skipChildren) 925 863 resolveChildren(current, renderer->style(), change, childRenderTreePosition);
Note:
See TracChangeset
for help on using the changeset viewer.