WebKit Bugzilla
Attachment 348262 Details for
Bug 169718
: Changes to slot children should trigger slotchange
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP2
wip169718b.patch (text/plain), 24.57 KB, created by
Ryosuke Niwa
on 2018-08-27 21:24:04 PDT
(
hide
)
Description:
WIP2
Filename:
MIME Type:
Creator:
Ryosuke Niwa
Created:
2018-08-27 21:24:04 PDT
Size:
24.57 KB
patch
obsolete
>Index: Source/WebCore/dom/Element.cpp >=================================================================== >--- Source/WebCore/dom/Element.cpp (revision 235334) >+++ Source/WebCore/dom/Element.cpp (working copy) >@@ -1727,7 +1727,7 @@ > > if (parentNode() == &parentOfInsertedTree) { > if (auto* shadowRoot = parentNode()->shadowRoot()) >- shadowRoot->hostChildElementDidChange(*this); >+ shadowRoot->didInsertHostChildElement(*this); > } > > if (!parentOfInsertedTree.isInTreeScope()) >@@ -1829,7 +1829,7 @@ > > if (!parentNode()) { > if (auto* shadowRoot = oldParentOfRemovedTree.shadowRoot()) >- shadowRoot->hostChildElementDidChange(*this); >+ shadowRoot->didRemoveHostChildElement(*this); > } > > clearBeforePseudoElement(); >@@ -2178,16 +2178,18 @@ > switch (change.type) { > case ElementInserted: > case ElementRemoved: >- // For elements, we notify shadowRoot in Element::insertedInto and Element::removedFrom. >+ // For elements, we notify shadowRoot in Element::insertedIntoAncestor and Element::removedFromAncestor. > break; > case AllChildrenRemoved: >- case AllChildrenReplaced: > shadowRoot->didRemoveAllChildrenOfShadowHost(); > break; >+ case AllChildrenReplaced: >+ shadowRoot->didReplaceAllChildrenOfShadowHost(); >+ break; > case TextInserted: > case TextRemoved: > case TextChanged: >- shadowRoot->didChangeDefaultSlot(); >+ shadowRoot->didMutateTextChildOfShadowHost(); > break; > case NonContentsChildInserted: > case NonContentsChildRemoved: >Index: Source/WebCore/dom/ShadowRoot.cpp >=================================================================== >--- Source/WebCore/dom/ShadowRoot.cpp (revision 235334) >+++ Source/WebCore/dom/ShadowRoot.cpp (working copy) >@@ -183,6 +183,7 @@ > > void ShadowRoot::addSlotElementByName(const AtomicString& name, HTMLSlotElement& slot) > { >+ ASSERT(&slot.rootNode() == this); > if (!m_slotAssignment) > m_slotAssignment = std::make_unique<SlotAssignment>(); > >@@ -194,6 +195,12 @@ > return m_slotAssignment->removeSlotElementByName(name, slot, *this); > } > >+void ShadowRoot::slotFallbackDidChange(HTMLSlotElement& slot) >+{ >+ ASSERT(&slot.rootNode() == this); >+ return m_slotAssignment->slotFallbackDidChange(slot, *this); >+} >+ > const Vector<Node*>* ShadowRoot::assignedNodesForSlot(const HTMLSlotElement& slot) > { > if (!m_slotAssignment) >Index: Source/WebCore/dom/ShadowRoot.h >=================================================================== >--- Source/WebCore/dom/ShadowRoot.h (revision 235334) >+++ Source/WebCore/dom/ShadowRoot.h (working copy) >@@ -74,10 +74,13 @@ > > void addSlotElementByName(const AtomicString&, HTMLSlotElement&); > void removeSlotElementByName(const AtomicString&, HTMLSlotElement&); >+ void slotFallbackDidChange(HTMLSlotElement&); > > void didRemoveAllChildrenOfShadowHost(); >- void didChangeDefaultSlot(); >- void hostChildElementDidChange(const Element&); >+ void didReplaceAllChildrenOfShadowHost(); >+ void didMutateTextChildOfShadowHost(); >+ void didInsertHostChildElement(const Element&); >+ void didRemoveHostChildElement(const Element&); > void hostChildElementDidChangeSlotAttribute(Element&, const AtomicString& oldValue, const AtomicString& newValue); > > const Vector<Node*>* assignedNodesForSlot(const HTMLSlotElement&); >@@ -107,7 +110,6 @@ > Element* m_host { nullptr }; > > std::unique_ptr<Style::Scope> m_styleScope; >- > std::unique_ptr<SlotAssignment> m_slotAssignment; > }; > >Index: Source/WebCore/dom/SlotAssignment.cpp >=================================================================== >--- Source/WebCore/dom/SlotAssignment.cpp (revision 235334) >+++ Source/WebCore/dom/SlotAssignment.cpp (working copy) >@@ -87,14 +87,14 @@ > auto& slotInfo = *addResult.iterator->value; > > if (!slotInfo.hasSlotElements()) >- slotInfo.element = &slotElement; >+ slotInfo.slotElement = &slotElement; > else { >- slotInfo.element = nullptr; >+ slotInfo.slotElement = nullptr; > #ifndef NDEBUG > m_needsToResolveSlotElements = true; > #endif > } >- slotInfo.elementCount++; >+ slotInfo.slotCount++; > } > > void SlotAssignment::removeSlotElementByName(const AtomicString& name, HTMLSlotElement& slotElement, ShadowRoot& shadowRoot) >@@ -113,62 +113,130 @@ > auto& slotInfo = *it->value; > RELEASE_ASSERT(slotInfo.hasSlotElements()); > >- slotInfo.elementCount--; >- if (slotInfo.element == &slotElement) { >- slotInfo.element = nullptr; >+ slotInfo.slotCount--; >+ if (slotInfo.slotElement == &slotElement) { >+ slotInfo.slotElement = nullptr; > #ifndef NDEBUG > m_needsToResolveSlotElements = true; > #endif > } >- ASSERT(slotInfo.element || m_needsToResolveSlotElements); >+ ASSERT(slotInfo.slotElement || m_needsToResolveSlotElements); > } > >-void SlotAssignment::didChangeSlot(const AtomicString& slotAttrValue, ShadowRoot& shadowRoot) >+void SlotAssignment::slotFallbackDidChange(HTMLSlotElement& slotElement, ShadowRoot& shadowRoot) > { >- auto& slotName = slotNameFromAttributeValue(slotAttrValue); >- auto it = m_slots.find(slotName); >- if (it == m_slots.end()) >- return; >- >- it->value->assignedNodes.clear(); >- m_slotAssignmentsIsValid = false; >+ ASSERT(slotElement.containingShadowRoot() == &shadowRoot); >+ const AtomicString& slotName = slotNameFromAttributeValue(slotElement.attributeWithoutSynchronization(nameAttr)); > >- RefPtr<HTMLSlotElement> slotElement = findFirstSlotElement(*it->value, shadowRoot); >- if (!slotElement) >+ if (slotHasAssignedNodes(slotName, shadowRoot)) > return; > >+ m_slotAssignmentsIsValid = false; > shadowRoot.host()->invalidateStyleAndRenderersForSubtree(); > > if (shadowRoot.mode() == ShadowRootMode::UserAgent) > return; > >- slotElement->enqueueSlotChangeEvent(); >+ slotElement.enqueueSlotChangeEvent(); > } > >-void SlotAssignment::hostChildElementDidChange(const Element& childElement, ShadowRoot& shadowRoot) >+static bool containsTextNodeAsChild(ContainerNode& container) > { >- didChangeSlot(childElement.attributeWithoutSynchronization(slotAttr), shadowRoot); >+ for (Node* child = container.firstChild(); child; child = child->nextSibling()) { >+ if (is<Text>(child)) >+ return true; >+ } >+ return false; > } > >+bool SlotAssignment::slotHasAssignedNodes(const AtomicString& slotName, ShadowRoot& shadowRoot) >+{ >+ auto* slotInfo = m_slots.get(slotName); >+ RELEASE_ASSERT(slotInfo); >+ >+ if (!slotInfo->assignedElementCount) { >+ // assignSlots had never been called after SlotAssignment was created. >+ // FIXME: Simply update assignedElementCount instead of doing the full blown assignments. >+ assignSlots(shadowRoot); >+ } >+ >+ if (*slotInfo->assignedElementCount) >+ return true; >+ >+ if (m_slotAssignmentsIsValid && slotInfo->assignedNodes.size()) >+ return true; >+ >+ if (slotName != defaultSlotName()) >+ return false; >+ >+ ASSERT(shadowRoot.host()); >+ if (m_defaultSlotState == DefaultSlotState::Unknown) >+ m_defaultSlotState = containsTextNodeAsChild(*shadowRoot.host()) ? DefaultSlotState::ContainsText : DefaultSlotState::DoesNotContainText; >+ ASSERT((m_defaultSlotState == DefaultSlotState::ContainsText) == containsTextNodeAsChild(*shadowRoot.host())); >+ >+ return m_defaultSlotState == DefaultSlotState::ContainsText; >+} >+ >+auto SlotAssignment::didChangeSlot(const AtomicString& slotName, ShadowRoot& shadowRoot) -> SlotInfo* >+{ >+ auto* slotInfo = m_slots.get(slotName); >+ if (!slotInfo) >+ return nullptr; >+ >+ slotInfo->assignedNodes.clear(); >+ m_slotAssignmentsIsValid = false; >+ >+ if (auto* slotElement = findFirstSlotElement(*slotInfo, shadowRoot)) { >+ shadowRoot.host()->invalidateStyleAndRenderersForSubtree(); >+ if (shadowRoot.mode() != ShadowRootMode::UserAgent) >+ slotElement->enqueueSlotChangeEvent(); >+ } >+ >+ return slotInfo; >+} >+ >+void SlotAssignment::didInsertHostChildElement(const Element& childElement, ShadowRoot& shadowRoot) >+{ >+ if (auto* slotInfo = didChangeSlot(slotNameFromSlotAttribute(childElement), shadowRoot)) >+ slotInfo->didInsertElement(); >+} >+ >+void SlotAssignment::didRemoveHostChildElement(const Element& childElement, ShadowRoot& shadowRoot) >+{ >+ if (auto* slotInfo = didChangeSlot(slotNameFromSlotAttribute(childElement), shadowRoot)) >+ slotInfo->didRemoveElement(); >+} >+ >+void SlotAssignment::hostChildElementDidChangeSlotAttribute(Element& childElement, const AtomicString& oldValue, const AtomicString& newValue, ShadowRoot& shadowRoot) >+{ >+ if (auto* slotInfo = didChangeSlot(slotNameFromAttributeValue(oldValue), shadowRoot)) >+ slotInfo->didRemoveElement(); >+ if (auto* slotInfo = didChangeSlot(slotNameFromAttributeValue(newValue), shadowRoot)) >+ slotInfo->didInsertElement(); >+ RenderTreeUpdater::tearDownRenderers(childElement); >+} >+ >+void SlotAssignment::hostChildElementDidChange(const Element&, ShadowRoot&) >+{ } >+ > const Vector<Node*>* SlotAssignment::assignedNodesForSlot(const HTMLSlotElement& slotElement, ShadowRoot& shadowRoot) > { > ASSERT(slotElement.containingShadowRoot() == &shadowRoot); > const AtomicString& slotName = slotNameFromAttributeValue(slotElement.attributeWithoutSynchronization(nameAttr)); >- auto it = m_slots.find(slotName); >- RELEASE_ASSERT(it != m_slots.end()); >+ auto* slotInfo = m_slots.get(slotName); >+ RELEASE_ASSERT(slotInfo); > >- auto& slotInfo = *it->value; > if (!m_slotAssignmentsIsValid) > assignSlots(shadowRoot); > >- if (!slotInfo.assignedNodes.size()) >+ if (!slotInfo->assignedNodes.size()) > return nullptr; > >- RELEASE_ASSERT(slotInfo.hasSlotElements()); >- if (slotInfo.hasDuplicatedSlotElements() && findFirstSlotElement(slotInfo, shadowRoot) != &slotElement) >+ RELEASE_ASSERT(slotInfo->hasSlotElements()); >+ if (slotInfo->hasDuplicatedSlotElements() && findFirstSlotElement(*slotInfo, shadowRoot) != &slotElement) > return nullptr; > >- return &slotInfo.assignedNodes; >+ return &slotInfo->assignedNodes; > } > > const AtomicString& SlotAssignment::slotNameForHostChild(const Node& child) const >@@ -182,11 +250,11 @@ > resolveAllSlotElements(shadowRoot); > > #ifndef NDEBUG >- ASSERT(!slotInfo.element || m_slotElementsForConsistencyCheck.contains(slotInfo.element)); >- ASSERT(!!slotInfo.element == !!slotInfo.elementCount); >+ ASSERT(!slotInfo.slotElement || m_slotElementsForConsistencyCheck.contains(slotInfo.slotElement)); >+ ASSERT(!!slotInfo.slotElement == !!slotInfo.slotCount); > #endif > >- return slotInfo.element; >+ return slotInfo.slotElement; > } > > void SlotAssignment::resolveAllSlotElements(ShadowRoot& shadowRoot) >@@ -198,7 +266,7 @@ > > // FIXME: It's inefficient to reset all values. We should be able to void this in common case. > for (auto& entry : m_slots) >- entry.value->element = nullptr; >+ entry.value->slotElement = nullptr; > > unsigned slotCount = m_slots.size(); > for (auto& slotElement : descendantsOfType<HTMLSlotElement>(shadowRoot)) { >@@ -208,11 +276,11 @@ > RELEASE_ASSERT(it != m_slots.end()); > > SlotInfo& slotInfo = *it->value; >- bool hasSeenSlotWithSameName = !!slotInfo.element; >+ bool hasSeenSlotWithSameName = !!slotInfo.slotElement; > if (hasSeenSlotWithSameName) > continue; > >- slotInfo.element = &slotElement; >+ slotInfo.slotElement = &slotElement; > slotCount--; > if (!slotCount) > break; >@@ -224,15 +292,19 @@ > ASSERT(!m_slotAssignmentsIsValid); > m_slotAssignmentsIsValid = true; > >- for (auto& entry : m_slots) >- entry.value->assignedNodes.shrink(0); >+ for (auto& slotInfo : m_slots.values()) { >+ slotInfo->assignedNodes.shrink(0); >+ slotInfo->assignedElementCount = 0; >+ } > > auto& host = *shadowRoot.host(); > for (auto* child = host.firstChild(); child; child = child->nextSibling()) { >- if (!is<Text>(*child) && !is<Element>(*child)) >- continue; >- auto slotName = slotNameForHostChild(*child); >- assignToSlot(*child, slotName); >+ if (is<Text>(*child)) { >+ if (auto* slotInfo = m_slots.get(defaultSlotName())) >+ slotInfo->assignedNodes.append(child); >+ } >+ if (is<Element>(*child)) >+ assignElementToSlot(downcast<Element>(*child), slotNameForHostChild(*child)); > } > > for (auto& entry : m_slots) >@@ -239,18 +311,26 @@ > entry.value->assignedNodes.shrinkToFit(); > } > >-void SlotAssignment::assignToSlot(Node& child, const AtomicString& slotName) >+void SlotAssignment::assignElementToSlot(Element& child, const AtomicString& slotName) > { > ASSERT(!slotName.isNull()); > if (slotName == defaultSlotName()) { >- auto defaultSlotEntry = m_slots.find(defaultSlotName()); >- if (defaultSlotEntry != m_slots.end()) >- defaultSlotEntry->value->assignedNodes.append(&child); >+ auto* slotInfo = m_slots.get(defaultSlotName()); >+ if (!slotInfo) >+ return; >+ slotInfo->assignedNodes.append(&child); >+ ++(*slotInfo->assignedElementCount); > return; > } > >- auto addResult = m_slots.add(slotName, std::make_unique<SlotInfo>()); >- addResult.iterator->value->assignedNodes.append(&child); >+ auto addResult = m_slots.ensure(slotName, [] { >+ auto slotInfo = std::make_unique<SlotInfo>(); >+ slotInfo->assignedElementCount = { 0 }; >+ return slotInfo; >+ }); >+ auto& slotInfo = *addResult.iterator->value; >+ slotInfo.assignedNodes.append(&child); >+ ++(*slotInfo.assignedElementCount); > } > > } >Index: Source/WebCore/dom/SlotAssignment.h >=================================================================== >--- Source/WebCore/dom/SlotAssignment.h (revision 235334) >+++ Source/WebCore/dom/SlotAssignment.h (working copy) >@@ -49,10 +49,30 @@ > > HTMLSlotElement* findAssignedSlot(const Node&, ShadowRoot&); > >+ void didRemoveAllChildrenOfShadowHost(ShadowRoot& shadowRoot) >+ { >+ m_defaultSlotState = DefaultSlotState::DoesNotContainText; >+ didChangeSlot(defaultSlotName(), shadowRoot); >+ } >+ void didReplaceAllChildrenOfShadowHost(ShadowRoot& shadowRoot) >+ { >+ m_defaultSlotState = DefaultSlotState::Unknown; >+ didChangeSlot(defaultSlotName(), shadowRoot); >+ } >+ void didMutateTextChildOfShadowHost(ShadowRoot& shadowRoot) >+ { >+ m_defaultSlotState = DefaultSlotState::Unknown; >+ didChangeSlot(defaultSlotName(), shadowRoot); >+ } >+ >+ virtual void didInsertHostChildElement(const Element&, ShadowRoot&); >+ virtual void didRemoveHostChildElement(const Element&, ShadowRoot&); >+ virtual void hostChildElementDidChangeSlotAttribute(Element&, const AtomicString&, const AtomicString&, ShadowRoot&); >+ > void addSlotElementByName(const AtomicString&, HTMLSlotElement&, ShadowRoot&); > void removeSlotElementByName(const AtomicString&, HTMLSlotElement&, ShadowRoot&); >+ void slotFallbackDidChange(HTMLSlotElement&, ShadowRoot&); > >- void didChangeSlot(const AtomicString&, ShadowRoot&); > void enqueueSlotChangeEvent(const AtomicString&, ShadowRoot&); > > const Vector<Node*>* assignedNodesForSlot(const HTMLSlotElement&, ShadowRoot&); >@@ -59,25 +79,46 @@ > > virtual void hostChildElementDidChange(const Element&, ShadowRoot&); > >-private: >+protected: > struct SlotInfo { > WTF_MAKE_FAST_ALLOCATED; > public: >- SlotInfo() { } >+ explicit SlotInfo() { } > SlotInfo(HTMLSlotElement& slotElement) >- : element(&slotElement) >- , elementCount(1) >+ : slotElement(&slotElement) >+ , slotCount(1) > { } > >- bool hasSlotElements() { return !!elementCount; } >- bool hasDuplicatedSlotElements() { return elementCount > 1; } >- bool shouldResolveSlotElement() { return !element && elementCount; } >+ bool hasSlotElements() { return !!slotCount; } >+ bool hasDuplicatedSlotElements() { return slotCount > 1; } >+ bool shouldResolveSlotElement() { return !slotElement && slotCount; } > >- HTMLSlotElement* element { nullptr }; >- unsigned elementCount { 0 }; >+ void didInsertElement() >+ { >+ if (assignedElementCount) >+ ++(*assignedElementCount); >+ } >+ void didRemoveElement() >+ { >+ if (assignedElementCount) { >+ ASSERT(*assignedElementCount); >+ --(*assignedElementCount); >+ } >+ } >+ >+ HTMLSlotElement* slotElement { nullptr }; >+ unsigned slotCount { 0 }; >+ std::optional<unsigned> assignedElementCount; > Vector<Node*> assignedNodes; > }; >- >+ >+ SlotInfo* didChangeSlot(const AtomicString&, ShadowRoot&); >+ >+private: >+ enum class DefaultSlotState { Unknown, ContainsText, DoesNotContainText }; >+ >+ bool slotHasAssignedNodes(const AtomicString&, ShadowRoot&); >+ > virtual const AtomicString& slotNameForHostChild(const Node&) const; > > HTMLSlotElement* findFirstSlotElement(SlotInfo&, ShadowRoot&); >@@ -84,7 +125,7 @@ > void resolveAllSlotElements(ShadowRoot&); > > void assignSlots(ShadowRoot&); >- void assignToSlot(Node& child, const AtomicString& slotName); >+ void assignElementToSlot(Element&, const AtomicString& slotName); > > HashMap<AtomicString, std::unique_ptr<SlotInfo>> m_slots; > >@@ -94,33 +135,43 @@ > #endif > > bool m_slotAssignmentsIsValid { false }; >+ DefaultSlotState m_defaultSlotState { DefaultSlotState::Unknown }; > }; > > inline void ShadowRoot::didRemoveAllChildrenOfShadowHost() > { > if (m_slotAssignment) // FIXME: This is incorrect when there were no elements or text nodes removed. >- m_slotAssignment->didChangeSlot(nullAtom(), *this); >+ m_slotAssignment->didRemoveAllChildrenOfShadowHost(*this); > } > >-inline void ShadowRoot::didChangeDefaultSlot() >+inline void ShadowRoot::didReplaceAllChildrenOfShadowHost() > { >+ if (m_slotAssignment) // FIXME: This is incorrect when there were no elements or text nodes removed. >+ m_slotAssignment->didReplaceAllChildrenOfShadowHost(*this); >+} >+ >+inline void ShadowRoot::didMutateTextChildOfShadowHost() >+{ > if (m_slotAssignment) >- m_slotAssignment->didChangeSlot(nullAtom(), *this); >+ m_slotAssignment->didMutateTextChildOfShadowHost(*this); > } > >-inline void ShadowRoot::hostChildElementDidChange(const Element& childElement) >+inline void ShadowRoot::didInsertHostChildElement(const Element& childElement) > { > if (m_slotAssignment) >- m_slotAssignment->hostChildElementDidChange(childElement, *this); >+ m_slotAssignment->didInsertHostChildElement(childElement, *this); > } > >-inline void ShadowRoot::hostChildElementDidChangeSlotAttribute(Element& element, const AtomicString& oldValue, const AtomicString& newValue) >+inline void ShadowRoot::didRemoveHostChildElement(const Element& childElement) > { >- if (!m_slotAssignment) >- return; >- m_slotAssignment->didChangeSlot(oldValue, *this); >- m_slotAssignment->didChangeSlot(newValue, *this); >- RenderTreeUpdater::tearDownRenderers(element); >+ if (m_slotAssignment) >+ m_slotAssignment->didRemoveHostChildElement(childElement, *this); > } > >+inline void ShadowRoot::hostChildElementDidChangeSlotAttribute(Element& childElement, const AtomicString& oldValue, const AtomicString& newValue) >+{ >+ if (m_slotAssignment) >+ m_slotAssignment->hostChildElementDidChangeSlotAttribute(childElement, oldValue, newValue, *this); >+} >+ > } // namespace WebCore >Index: Source/WebCore/html/HTMLDetailsElement.cpp >=================================================================== >--- Source/WebCore/html/HTMLDetailsElement.cpp (revision 235334) >+++ Source/WebCore/html/HTMLDetailsElement.cpp (working copy) >@@ -57,20 +57,29 @@ > > class DetailsSlotAssignment final : public SlotAssignment { > private: >- void hostChildElementDidChange(const Element&, ShadowRoot&) override; >+ void didInsertHostChildElement(const Element& childElement, ShadowRoot& shadowRoot) override >+ { >+ if (auto* slotInfo = didChangeSlot(slotNameForHostChild(childElement), shadowRoot)) >+ slotInfo->didInsertElement(); >+ } >+ >+ void didRemoveHostChildElement(const Element&, ShadowRoot& shadowRoot) override >+ { >+ // We don't know whether this element, if it was a summary, was the first element. >+ if (auto* slotInfo = didChangeSlot(summarySlotName(), shadowRoot)) >+ slotInfo->assignedElementCount = std::nullopt; >+ if (auto* slotInfo = didChangeSlot(SlotAssignment::defaultSlotName(), shadowRoot)) >+ slotInfo->assignedElementCount = std::nullopt; >+ } >+ >+ void hostChildElementDidChangeSlotAttribute(Element&, const AtomicString&, const AtomicString&, ShadowRoot&) override >+ { >+ // details & summar elements ignore slot attribute in the contents. >+ } >+ > const AtomicString& slotNameForHostChild(const Node&) const override; > }; > >-void DetailsSlotAssignment::hostChildElementDidChange(const Element& childElement, ShadowRoot& shadowRoot) >-{ >- if (is<HTMLSummaryElement>(childElement)) { >- // Don't check whether this is the first summary element >- // since we don't know the answer when this function is called inside Element::removedFrom. >- didChangeSlot(summarySlotName(), shadowRoot); >- } else >- didChangeSlot(SlotAssignment::defaultSlotName(), shadowRoot); >-} >- > const AtomicString& DetailsSlotAssignment::slotNameForHostChild(const Node& child) const > { > auto& parent = *child.parentNode(); >Index: Source/WebCore/html/HTMLSlotElement.cpp >=================================================================== >--- Source/WebCore/html/HTMLSlotElement.cpp (revision 235334) >+++ Source/WebCore/html/HTMLSlotElement.cpp (working copy) >@@ -57,7 +57,7 @@ > ASSERT_UNUSED(insertionResult, insertionResult == InsertedIntoAncestorResult::Done); > > if (insertionType.treeScopeChanged && isInShadowTree()) { >- if (auto shadowRoot = containingShadowRoot()) >+ if (auto* shadowRoot = containingShadowRoot()) > shadowRoot->addSlotElementByName(attributeWithoutSynchronization(nameAttr), *this); > } > >@@ -75,6 +75,16 @@ > HTMLElement::removedFromAncestor(removalType, oldParentOfRemovedTree); > } > >+void HTMLSlotElement::childrenChanged(const ChildChange& childChange) >+{ >+ HTMLElement::childrenChanged(childChange); >+ >+ if (isInShadowTree()) { >+ if (auto* shadowRoot = containingShadowRoot()) >+ shadowRoot->slotFallbackDidChange(*this); >+ } >+} >+ > void HTMLSlotElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason reason) > { > HTMLElement::attributeChanged(name, oldValue, newValue, reason); >Index: Source/WebCore/html/HTMLSlotElement.h >=================================================================== >--- Source/WebCore/html/HTMLSlotElement.h (revision 235334) >+++ Source/WebCore/html/HTMLSlotElement.h (working copy) >@@ -51,6 +51,7 @@ > > InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) final; > void removedFromAncestor(RemovalType, ContainerNode&) final; >+ void childrenChanged(const ChildChange&) final; > void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason) final; > > bool m_inSignalSlotList { false }; >Index: Source/WebCore/html/HTMLSummaryElement.cpp >=================================================================== >--- Source/WebCore/html/HTMLSummaryElement.cpp (revision 235334) >+++ Source/WebCore/html/HTMLSummaryElement.cpp (working copy) >@@ -42,11 +42,23 @@ > > class SummarySlotElement final : public SlotAssignment { > private: >- void hostChildElementDidChange(const Element&, ShadowRoot& shadowRoot) override >+ void didInsertHostChildElement(const Element&, ShadowRoot& shadowRoot) override > { >- didChangeSlot(SlotAssignment::defaultSlotName(), shadowRoot); >+ if (auto* slotInfo = didChangeSlot(SlotAssignment::defaultSlotName(), shadowRoot)) >+ slotInfo->didInsertElement(); > } > >+ void didRemoveHostChildElement(const Element&, ShadowRoot& shadowRoot) override >+ { >+ if (auto* slotInfo = didChangeSlot(SlotAssignment::defaultSlotName(), shadowRoot)) >+ slotInfo->didRemoveElement(); >+ } >+ >+ void hostChildElementDidChangeSlotAttribute(Element&, const AtomicString&, const AtomicString&, ShadowRoot&) override >+ { >+ // details & summar elements ignore slot attribute in the contents. >+ } >+ > const AtomicString& slotNameForHostChild(const Node&) const override { return SlotAssignment::defaultSlotName(); } > }; >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 169718
:
348058
|
348262
|
348266
|
348276
|
348364
|
348374
|
348382
|
348390