Changeset 198115 in webkit
- Timestamp:
- Mar 14, 2016 5:02:21 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r198096 r198115 1 2016-03-14 Ryosuke Niwa <rniwa@webkit.org> 2 3 Add slotchange event 4 https://bugs.webkit.org/show_bug.cgi?id=155424 5 <rdar://problem/24997534> 6 7 Reviewed by Antti Koivisto. 8 9 Added a W3C style testharness.js test. 10 11 * fast/shadow-dom/ShadowRoot-interface-expected.txt: 12 * fast/shadow-dom/ShadowRoot-interface.html: Don't import testharness.css from svn.webkit.org. 13 * fast/shadow-dom/slotchange-event-expected.txt: Added. 14 * fast/shadow-dom/slotchange-event.html: Added. 15 1 16 2016-03-13 Darin Adler <darin@apple.com> 2 17 -
trunk/LayoutTests/fast/shadow-dom/ShadowRoot-interface-expected.txt
r189841 r198115 1 Blocked access to external URL https://svn.webkit.org/repository/webkit/trunk/LayoutTests/resources/testharness.css2 1 3 2 PASS Check the existence of ShadowRoot interface -
trunk/LayoutTests/fast/shadow-dom/ShadowRoot-interface.html
r189841 r198115 8 8 <script src="../../resources/testharness.js"></script> 9 9 <script src="../../resources/testharnessreport.js"></script> 10 <link rel='stylesheet' href=' https://svn.webkit.org/repository/webkit/trunk/LayoutTests/resources/testharness.css'>10 <link rel='stylesheet' href='../../resources/testharness.css'> 11 11 </head> 12 12 <body> -
trunk/Source/WebCore/ChangeLog
r198102 r198115 1 2016-03-14 Ryosuke Niwa <rniwa@webkit.org> 2 3 Add slotchange event 4 https://bugs.webkit.org/show_bug.cgi?id=155424 5 <rdar://problem/24997534> 6 7 Reviewed by Antti Koivisto. 8 9 Added `slotchange` event as discussed on https://github.com/w3c/webcomponents/issues/288. 10 11 While the exact semantics of it could still evolve over time, this patch implements as 12 an asynchronous event that fires on a slot element whenever its distributed nodes change 13 (flattened assigned nodes): 14 http://w3c.github.io/webcomponents/spec/shadow/#dfn-distributed-nodes 15 16 Since inserting or removing an element from a shadow host could needs to enqueue this event 17 on the right slot element, this patch moves the invalidation point of element removals and 18 insertions from Element::childrenChanged to Element::insertedInto and Element::removedFrom. 19 Text nodes are still invalidated at Element::childrenChanged for performance reasons 20 since it could only appear within a default slot element. 21 22 Because this more fine-grained invalidation needs to be overridden by HTMLDetailsElement, 23 we now subclass SlotAssignment in HTMLDetailsElement instead of passing in a std::function. 24 25 Test: fast/shadow-dom/slotchange-event.html 26 27 * dom/Document.cpp: 28 (WebCore::Document::enqueueSlotchangeEvent): Added. 29 * dom/Document.h: 30 * dom/Element.cpp: 31 (WebCore::Element::attributeChanged): Call hostChildElementDidChangeSlotAttr. 32 (WebCore::Element::insertedInto): Call hostChildElementDidChange. 33 (WebCore::Element::removedFrom): Ditto. 34 (WebCore::Element::childrenChanged): Don't invalidate the slots on ElementInserted and 35 ElementRemoved since they're now done in Element::insertedInto and Element::removedFrom. 36 * dom/Event.cpp: 37 (WebCore::Event::scoped): slotchange event is scoped. 38 * dom/EventNames.h: Added eventNames().slotchange. 39 * dom/ShadowRoot.cpp: 40 (WebCore::ShadowRoot::invalidateSlotAssignments): Deleted. 41 (WebCore::ShadowRoot::invalidateDefaultSlotAssignments): Deleted. 42 * dom/ShadowRoot.h: 43 (ShadowRoot): Added more fine-grained invalidators, mirroring changes to SlotAssignment. 44 * dom/SlotAssignment.cpp: 45 (WebCore::SlotAssignment::SlotAssignment): Removed a variant that takes SlotNameFunction 46 since HTMLDetailsElement now subclasses SlotAssignment. 47 (WebCore::SlotAssignment::~SlotAssignment): Added now that the class is virtual. 48 (WebCore::recursivelyFireSlotChangeEvent): Added. 49 (WebCore::SlotAssignment::didChangeSlot): Added. Invalidates the style tree only if there 50 is a corresponding slot element, and fires slotchange event. When the slot element we found 51 in this shadow tree is assigned to a slot element inside an inner shadow tree, recursively 52 fire slotchange event on each such inner slots. 53 (WebCore::SlotAssignment::hostChildElementDidChange): Added. Update the matching slot when 54 an element is inserted or removed under a shadow host. 55 (WebCore::SlotAssignment::assignedNodesForSlot): Removed the superfluous early exit to an 56 release assert since addSlotElementByName should always create a SlotInfo for each element. 57 (WebCore::SlotAssignment::slotNameForHostChild): Added. This is the equivalent of old 58 m_slotNameFunction which DetailsSlotAssignment overrides. 59 (WebCore::SlotAssignment::invalidateDefaultSlot): Deleted. 60 (WebCore::SlotAssignment::findFirstSlotElement): Added an assertion. slotInfo.element must 61 be nullptr if elementCount is 0, and elementCount must be 0 if slotInfo.element is nullptr 62 after calling resolveAllSlotElements, which traverses the entire shadow tree to find all 63 slot elements. 64 (WebCore::SlotAssignment::assignSlots): 65 * dom/SlotAssignment.h: Implemented inline functions of ShadowRoot here to avoid including 66 SlotAssignment.h in ShadowRoot.h. Not inlining them results in extra function calls for all 67 builtin elements with shadow root without slot elements, which impacts performance. 68 (WebCore::ShadowRoot::didRemoveAllChildrenOfShadowHost): Added. 69 (WebCore::ShadowRoot::didChangeDefaultSlot): Added. 70 (WebCore::ShadowRoot::hostChildElementDidChange): Added. 71 (WebCore::ShadowRoot::hostChildElementDidChangeSlotAttribute): Added. 72 (WebCore::ShadowRoot::innerSlotDidChange): 73 * html/HTMLDetailsElement.cpp: 74 (WebCore::DetailsSlotAssignment): Added. Subclasses SlotAssignment to override 75 hostChildElementDidChange and slotNameForHostChild. 76 (WebCore::DetailsSlotAssignment::hostChildElementDidChange): Added. We don't check if this 77 is the first summary element since we don't know the answer when this function is called 78 inside Element::removedFrom. 79 (WebCore::DetailsSlotAssignment::slotNameForHostChild): Renamed from slotNameFunction. Also 80 removed the code to return nullAtom when details element is not open as that messes up new 81 fine-grained invalidation. Insert/remove the slot element in parseAttribute instead. 82 (WebCore::HTMLDetailsElement::didAddUserAgentShadowRoot): Don't insert the slot element for 83 the summary since the details element is not open now. 84 (WebCore::HTMLDetailsElement::parseAttribute): Remove and insert the slot element for the 85 summary here instead of changing the behavior of slotNameForHostChild. 86 * html/HTMLDetailsElement.h: 87 * html/HTMLSlotElement.cpp: 88 (WebCore::HTMLSlotElement::enqueueSlotChangeEvent): Added. Enqueues a new slotchange event 89 if we haven't done so for this element yet. 90 (WebCore::HTMLSlotElement::dispatchEvent): Added. Clear m_hasEnqueuedSlotChangeEvent when 91 dispatching a slotchange event so that a subsequent call to enqueueSlotChangeEvent would 92 enqueue a new event. Note scripts call EventTarget::dispatchEventForBindings instead. 93 * html/HTMLSlotElement.h: 94 1 95 2016-03-14 Youenn Fablet <youenn.fablet@crf.canon.fr> 2 96 -
trunk/Source/WebCore/dom/Document.cpp
r197917 r198115 4173 4173 } 4174 4174 4175 void Document::enqueueSlotchangeEvent(Ref<Event>&& event) 4176 { 4177 m_eventQueue.enqueueEvent(WTFMove(event)); 4178 } 4179 4175 4180 RefPtr<Event> Document::createEvent(const String& type, ExceptionCode& ec) 4176 4181 { -
trunk/Source/WebCore/dom/Document.h
r197887 r198115 1089 1089 void enqueueDocumentEvent(Ref<Event>&&); 1090 1090 void enqueueOverflowEvent(Ref<Event>&&); 1091 void enqueueSlotchangeEvent(Ref<Event>&&); 1091 1092 void enqueuePageshowEvent(PageshowEventPersistence); 1092 1093 void enqueueHashchangeEvent(const String& oldURL, const String& newURL); -
trunk/Source/WebCore/dom/Element.cpp
r197764 r198115 84 84 #include "Settings.h" 85 85 #include "SimulatedClick.h" 86 #include "SlotAssignment.h" 86 87 #include "StyleProperties.h" 87 88 #include "StyleResolver.h" … … 1255 1256 if (auto* parent = parentElement()) { 1256 1257 if (auto* shadowRoot = parent->shadowRoot()) 1257 shadowRoot-> invalidateSlotAssignments();1258 shadowRoot->hostChildElementDidChangeSlotAttribute(oldValue, newValue); 1258 1259 } 1259 1260 } … … 1497 1498 #endif 1498 1499 1500 if (parentNode() == &insertionPoint) { 1501 if (auto* shadowRoot = parentNode()->shadowRoot()) 1502 shadowRoot->hostChildElementDidChange(*this); 1503 } 1504 1499 1505 if (!insertionPoint.isInTreeScope()) 1500 1506 return InsertionDone; … … 1574 1580 updateLabel(*oldScope, fastGetAttribute(forAttr), nullAtom); 1575 1581 } 1582 } 1583 1584 if (!parentNode()) { 1585 if (auto* shadowRoot = insertionPoint.shadowRoot()) 1586 shadowRoot->hostChildElementDidChange(*this); 1576 1587 } 1577 1588 … … 1833 1844 case ElementInserted: 1834 1845 case ElementRemoved: 1846 // For elements, we notify shadowRoot in Element::insertedInto and Element::removedFrom. 1847 break; 1835 1848 case AllChildrenRemoved: 1836 shadowRoot-> invalidateSlotAssignments();1849 shadowRoot->didRemoveAllChildrenOfShadowHost(); 1837 1850 break; 1838 1851 case TextInserted: 1839 1852 case TextRemoved: 1840 1853 case TextChanged: 1841 shadowRoot-> invalidateDefaultSlotAssignments();1854 shadowRoot->didChangeDefaultSlot(); 1842 1855 break; 1843 1856 case NonContentsChildChanged: -
trunk/Source/WebCore/dom/Event.cpp
r198056 r198115 104 104 || m_type == eventNames().scrollEvent 105 105 || m_type == eventNames().selectEvent 106 || m_type == eventNames().selectstartEvent; 106 || m_type == eventNames().selectstartEvent 107 || m_type == eventNames().slotchangeEvent; 107 108 } 108 109 -
trunk/Source/WebCore/dom/EventNames.h
r197790 r198115 196 196 macro(show) \ 197 197 macro(signalingstatechange) \ 198 macro(slotchange) \ 198 199 macro(soundend) \ 199 200 macro(soundstart) \ -
trunk/Source/WebCore/dom/ShadowRoot.cpp
r198090 r198115 202 202 } 203 203 204 void ShadowRoot::invalidateSlotAssignments()205 {206 if (m_slotAssignment)207 m_slotAssignment->invalidate(*this);208 }209 210 void ShadowRoot::invalidateDefaultSlotAssignments()211 {212 if (m_slotAssignment)213 m_slotAssignment->invalidateDefaultSlot(*this);214 }215 216 204 const Vector<Node*>* ShadowRoot::assignedNodesForSlot(const HTMLSlotElement& slot) 217 205 { -
trunk/Source/WebCore/dom/ShadowRoot.h
r197887 r198115 92 92 void removeSlotElementByName(const AtomicString&, HTMLSlotElement&); 93 93 94 void invalidateSlotAssignments(); 95 void invalidateDefaultSlotAssignments(); 94 void didRemoveAllChildrenOfShadowHost(); 95 void didChangeDefaultSlot(); 96 void hostChildElementDidChange(const Element&); 97 void hostChildElementDidChangeSlotAttribute(const AtomicString& oldValue, const AtomicString& newValue); 98 void innerSlotDidChange(const AtomicString&); 96 99 97 100 const Vector<Node*>* assignedNodesForSlot(const HTMLSlotElement&); -
trunk/Source/WebCore/dom/SlotAssignment.cpp
r198090 r198115 51 51 52 52 SlotAssignment::SlotAssignment() 53 : m_slotNameFunction(slotNameFromSlotAttribute) 54 { 55 } 56 57 SlotAssignment::SlotAssignment(SlotNameFunction function) 58 : m_slotNameFunction(WTFMove(function)) 53 { 54 } 55 56 SlotAssignment::~SlotAssignment() 59 57 { 60 58 } … … 65 63 return nullptr; 66 64 67 auto slotName = m_slotNameFunction(node); 68 if (!slotName) 69 return nullptr; 70 65 auto slotName = slotNameForHostChild(node); 71 66 auto it = m_slots.find(slotName); 72 67 if (it == m_slots.end()) … … 134 129 } 135 130 131 static void recursivelyFireSlotChangeEvent(HTMLSlotElement& slotElement) 132 { 133 slotElement.enqueueSlotChangeEvent(); 134 135 auto* slotParent = slotElement.parentElement(); 136 if (!slotParent) 137 return; 138 139 auto* shadowRootOfSlotParent = slotParent->shadowRoot(); 140 if (!shadowRootOfSlotParent) 141 return; 142 143 shadowRootOfSlotParent->innerSlotDidChange(slotElement.fastGetAttribute(slotAttr)); 144 } 145 146 void SlotAssignment::didChangeSlot(const AtomicString& slotAttrValue, ChangeType changeType, ShadowRoot& shadowRoot) 147 { 148 auto& slotName = slotNameFromAttributeValue(slotAttrValue); 149 auto it = m_slots.find(slotName); 150 if (it == m_slots.end()) 151 return; 152 153 HTMLSlotElement* slotElement = findFirstSlotElement(*it->value, shadowRoot); 154 if (!slotElement) 155 return; 156 157 if (changeType == ChangeType::DirectChild) { 158 shadowRoot.host()->setNeedsStyleRecalc(ReconstructRenderTree); 159 m_slotAssignmentsIsValid = false; 160 } 161 162 if (shadowRoot.type() == ShadowRoot::Type::UserAgent) 163 return; 164 165 recursivelyFireSlotChangeEvent(*slotElement); 166 } 167 168 void SlotAssignment::hostChildElementDidChange(const Element& childElement, ShadowRoot& shadowRoot) 169 { 170 didChangeSlot(childElement.fastGetAttribute(slotAttr), ChangeType::DirectChild, shadowRoot); 171 } 172 136 173 const Vector<Node*>* SlotAssignment::assignedNodesForSlot(const HTMLSlotElement& slotElement, ShadowRoot& shadowRoot) 137 174 { 175 ASSERT(slotElement.containingShadowRoot() == &shadowRoot); 176 const AtomicString& slotName = slotNameFromAttributeValue(slotElement.fastGetAttribute(nameAttr)); 177 auto it = m_slots.find(slotName); 178 RELEASE_ASSERT(it != m_slots.end()); 179 180 auto& slotInfo = *it->value; 138 181 if (!m_slotAssignmentsIsValid) 139 182 assignSlots(shadowRoot); 140 183 141 const AtomicString& slotName = slotNameFromAttributeValue(slotElement.fastGetAttribute(nameAttr));142 auto it = m_slots.find(slotName);143 if (it == m_slots.end())144 return nullptr;145 146 auto& slotInfo = *it->value;147 148 184 if (!slotInfo.assignedNodes.size()) 149 185 return nullptr; … … 156 192 } 157 193 158 void SlotAssignment::invalidate(ShadowRoot& shadowRoot) 159 { 160 // FIXME: We should be able to do a targeted reconstruction. 161 shadowRoot.host()->setNeedsStyleRecalc(ReconstructRenderTree); 162 m_slotAssignmentsIsValid = false; 163 } 164 165 void SlotAssignment::invalidateDefaultSlot(ShadowRoot& shadowRoot) 166 { 167 auto it = m_slots.find(defaultSlotName()); 168 if (it != m_slots.end() && it->value->elementCount) 169 invalidate(shadowRoot); // FIXME: We should be able to reconstruct only under the default slot. 194 const AtomicString& SlotAssignment::slotNameForHostChild(const Node& child) const 195 { 196 return slotNameFromSlotAttribute(child); 170 197 } 171 198 … … 177 204 #ifndef NDEBUG 178 205 ASSERT(!slotInfo.element || m_slotElementsForConsistencyCheck.contains(slotInfo.element)); 206 ASSERT(!!slotInfo.element == !!slotInfo.elementCount); 179 207 #endif 180 208 … … 224 252 if (!is<Text>(*child) && !is<Element>(*child)) 225 253 continue; 226 auto slotName = m_slotNameFunction(*child); 227 if (!slotName) 228 continue; 254 auto slotName = slotNameForHostChild(*child); 229 255 assignToSlot(*child, slotName); 230 256 } -
trunk/Source/WebCore/dom/SlotAssignment.h
r190840 r198115 29 29 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 30 30 31 #include "ShadowRoot.h" 31 32 #include <wtf/HashMap.h> 32 33 #include <wtf/HashSet.h> … … 37 38 namespace WebCore { 38 39 40 class Element; 39 41 class HTMLSlotElement; 40 42 class Node; 41 class ShadowRoot;42 43 43 44 class SlotAssignment { 44 45 WTF_MAKE_NONCOPYABLE(SlotAssignment); 45 46 public: 46 using SlotNameFunction = std::function<AtomicString (const Node& child)>;47 48 47 SlotAssignment(); 49 SlotAssignment(SlotNameFunction); 50 ~SlotAssignment() { } 48 virtual ~SlotAssignment(); 51 49 52 50 static const AtomicString& defaultSlotName() { return emptyAtom; } … … 57 55 void removeSlotElementByName(const AtomicString&, HTMLSlotElement&, ShadowRoot&); 58 56 57 enum class ChangeType { DirectChild, InnerSlot }; 58 void didChangeSlot(const AtomicString&, ChangeType, ShadowRoot&); 59 void enqueueSlotChangeEvent(const AtomicString&, ShadowRoot&); 60 59 61 const Vector<Node*>* assignedNodesForSlot(const HTMLSlotElement&, ShadowRoot&); 60 62 61 void invalidate(ShadowRoot&); 62 void invalidateDefaultSlot(ShadowRoot&); 63 virtual void hostChildElementDidChange(const Element&, ShadowRoot&); 63 64 64 65 private: … … 78 79 Vector<Node*> assignedNodes; 79 80 }; 81 82 virtual const AtomicString& slotNameForHostChild(const Node&) const; 80 83 81 84 HTMLSlotElement* findFirstSlotElement(SlotInfo&, ShadowRoot&); … … 84 87 void assignSlots(ShadowRoot&); 85 88 void assignToSlot(Node& child, const AtomicString& slotName); 86 87 SlotNameFunction m_slotNameFunction;88 89 89 90 HashMap<AtomicString, std::unique_ptr<SlotInfo>> m_slots; … … 97 98 }; 98 99 100 inline void ShadowRoot::didRemoveAllChildrenOfShadowHost() 101 { 102 if (m_slotAssignment) // FIXME: This is incorrect when there were no elements or text nodes removed. 103 m_slotAssignment->didChangeSlot(nullAtom, SlotAssignment::ChangeType::DirectChild, *this); 104 } 105 106 inline void ShadowRoot::didChangeDefaultSlot() 107 { 108 if (m_slotAssignment) 109 m_slotAssignment->didChangeSlot(nullAtom, SlotAssignment::ChangeType::DirectChild, *this); 110 } 111 112 inline void ShadowRoot::hostChildElementDidChange(const Element& childElement) 113 { 114 if (m_slotAssignment) 115 m_slotAssignment->hostChildElementDidChange(childElement, *this); 116 } 117 118 inline void ShadowRoot::hostChildElementDidChangeSlotAttribute(const AtomicString& oldValue, const AtomicString& newValue) 119 { 120 if (m_slotAssignment) { 121 m_slotAssignment->didChangeSlot(oldValue, SlotAssignment::ChangeType::DirectChild, *this); 122 m_slotAssignment->didChangeSlot(newValue, SlotAssignment::ChangeType::DirectChild, *this); 123 } 124 } 125 126 inline void ShadowRoot::innerSlotDidChange(const AtomicString& name) 127 { 128 if (m_slotAssignment) 129 m_slotAssignment->didChangeSlot(name, SlotAssignment::ChangeType::InnerSlot, *this); 130 } 131 99 132 } 100 133 -
trunk/Source/WebCore/html/HTMLDetailsElement.cpp
r198090 r198115 45 45 } 46 46 47 static AtomicString slotNameFunction(const Node& child) 47 class DetailsSlotAssignment final : public SlotAssignment { 48 private: 49 void hostChildElementDidChange(const Element&, ShadowRoot&) override; 50 const AtomicString& slotNameForHostChild(const Node&) const override; 51 }; 52 53 void DetailsSlotAssignment::hostChildElementDidChange(const Element& childElement, ShadowRoot& shadowRoot) 54 { 55 if (is<HTMLSummaryElement>(childElement)) { 56 // Don't check whether this is the first summary element 57 // since we don't know the answer when this function is called inside Element::removedFrom. 58 didChangeSlot(summarySlotName(), ChangeType::DirectChild, shadowRoot); 59 } else 60 didChangeSlot(SlotAssignment::defaultSlotName(), ChangeType::DirectChild, shadowRoot); 61 } 62 63 const AtomicString& DetailsSlotAssignment::slotNameForHostChild(const Node& child) const 48 64 { 49 65 auto& parent = *child.parentNode(); … … 56 72 return summarySlotName(); 57 73 } 58 // Everything else is assigned to the default slot if details is open. 59 if (details.isOpen()) 60 return SlotAssignment::defaultSlotName(); 61 62 // Otherwise don't render the content. 63 return nullAtom; 64 }; 74 return SlotAssignment::defaultSlotName(); 75 } 65 76 66 77 Ref<HTMLDetailsElement> HTMLDetailsElement::create(const QualifiedName& tagName, Document& document) 67 78 { 68 79 auto details = adoptRef(*new HTMLDetailsElement(tagName, document)); 69 details->addShadowRoot(ShadowRoot::create(document, std::make_unique< SlotAssignment>(slotNameFunction)));80 details->addShadowRoot(ShadowRoot::create(document, std::make_unique<DetailsSlotAssignment>())); 70 81 return details; 71 82 } … … 95 106 root->appendChild(WTFMove(summarySlot)); 96 107 97 autodefaultSlot = HTMLSlotElement::create(slotTag, document());98 root->appendChild(WTFMove(defaultSlot));108 m_defaultSlot = HTMLSlotElement::create(slotTag, document()); 109 ASSERT(!m_isOpen); 99 110 } 100 111 … … 118 129 bool oldValue = m_isOpen; 119 130 m_isOpen = !value.isNull(); 120 if (oldValue != m_isOpen) 121 shadowRoot()->invalidateSlotAssignments(); 131 if (oldValue != m_isOpen) { 132 auto* root = shadowRoot(); 133 ASSERT(root); 134 if (m_isOpen) 135 root->appendChild(*m_defaultSlot); 136 else 137 root->removeChild(*m_defaultSlot); 138 } 122 139 } else 123 140 HTMLElement::parseAttribute(name, value); -
trunk/Source/WebCore/html/HTMLDetailsElement.h
r197566 r198115 48 48 HTMLSlotElement* m_summarySlot { nullptr }; 49 49 HTMLSummaryElement* m_defaultSummary { nullptr }; 50 RefPtr<HTMLSlotElement> m_defaultSlot; 50 51 }; 51 52 -
trunk/Source/WebCore/html/HTMLSlotElement.cpp
r190845 r198115 30 30 31 31 #include "ElementChildIterator.h" 32 #include "Event.h" 33 #include "EventNames.h" 32 34 #include "HTMLNames.h" 33 35 #include "ShadowRoot.h" … … 98 100 } 99 101 102 void HTMLSlotElement::enqueueSlotChangeEvent() 103 { 104 if (m_hasEnqueuedSlotChangeEvent) 105 return; 106 107 bool bubbles = false; 108 bool cancelable = false; 109 auto event = Event::create(eventNames().slotchangeEvent, bubbles, cancelable); 110 event->setTarget(this); 111 document().enqueueSlotchangeEvent(WTFMove(event)); 112 113 m_hasEnqueuedSlotChangeEvent = true; 114 } 115 116 bool HTMLSlotElement::dispatchEvent(Event& event) 117 { 118 if (event.type() == eventNames().slotchangeEvent) 119 m_hasEnqueuedSlotChangeEvent = false; 120 return HTMLElement::dispatchEvent(event); 121 } 122 100 123 } 101 124 -
trunk/Source/WebCore/html/HTMLSlotElement.h
r197563 r198115 40 40 const Vector<Node*>* assignedNodes() const; 41 41 42 void enqueueSlotChangeEvent(); 43 42 44 private: 43 45 HTMLSlotElement(const QualifiedName&, Document&); … … 46 48 void removedFrom(ContainerNode&) override; 47 49 void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason) override; 50 51 bool dispatchEvent(Event&) override; 52 53 bool m_hasEnqueuedSlotChangeEvent { false }; 48 54 }; 49 55
Note: See TracChangeset
for help on using the changeset viewer.