diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/dom')
22 files changed, 547 insertions, 951 deletions
diff --git a/src/3rdparty/webkit/WebCore/dom/ActiveDOMObject.h b/src/3rdparty/webkit/WebCore/dom/ActiveDOMObject.h index e58d3f9..73b52d5 100644 --- a/src/3rdparty/webkit/WebCore/dom/ActiveDOMObject.h +++ b/src/3rdparty/webkit/WebCore/dom/ActiveDOMObject.h @@ -53,9 +53,6 @@ namespace WebCore { virtual void resume(); virtual void stop(); - protected: - virtual ~ActiveDOMObject(); - template<class T> void setPendingActivity(T* thisObject) { ASSERT(thisObject == this); @@ -70,6 +67,9 @@ namespace WebCore { thisObject->deref(); } + protected: + virtual ~ActiveDOMObject(); + private: ScriptExecutionContext* m_scriptExecutionContext; unsigned m_pendingActivityCount; diff --git a/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp b/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp index 902b7ff..3c3dc37 100644 --- a/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp +++ b/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp @@ -187,10 +187,8 @@ void CharacterData::dispatchModifiedEvent(StringImpl* prevValue) { if (parentNode()) parentNode()->childrenChanged(); - if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER)) { - ExceptionCode ec; - dispatchMutationEvent(eventNames().DOMCharacterDataModifiedEvent, true, 0, prevValue, m_data, ec); - } + if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER)) + dispatchEvent(MutationEvent::create(eventNames().DOMCharacterDataModifiedEvent, true, 0, prevValue, m_data)); dispatchSubtreeModifiedEvent(); } diff --git a/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp b/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp index 1ec4eb3..7274b5d 100644 --- a/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp +++ b/src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp @@ -41,8 +41,8 @@ namespace WebCore { -static void dispatchChildInsertionEvents(Node*, ExceptionCode&); -static void dispatchChildRemovalEvents(Node*, ExceptionCode&); +static void dispatchChildInsertionEvents(Node*); +static void dispatchChildRemovalEvents(Node*); typedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue; static NodeCallbackQueue* s_postAttachCallbackQueue; @@ -144,7 +144,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce // Dispatch the mutation events. childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1); - dispatchChildInsertionEvents(child.get(), ec); + dispatchChildInsertionEvents(child.get()); // Add child to the rendering tree. if (attached() && !child->attached() && child->parent() == this) { @@ -255,7 +255,7 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce allowEventDispatch(); // Dispatch the mutation events - dispatchChildInsertionEvents(child.get(), ec); + dispatchChildInsertionEvents(child.get()); // Add child to the rendering tree if (attached() && !child->attached() && child->parent() == this) { @@ -287,7 +287,7 @@ static ExceptionCode willRemoveChild(Node *child) ExceptionCode ec = 0; // fire removed from document mutation events. - dispatchChildRemovalEvents(child, ec); + dispatchChildRemovalEvents(child); if (ec) return ec; @@ -480,7 +480,7 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo // Dispatch the mutation events childrenChanged(false, prev.get(), 0, 1); - dispatchChildInsertionEvents(child.get(), ec); + dispatchChildInsertionEvents(child.get()); // Add child to the rendering tree if (attached() && !child->attached() && child->parent() == this) { @@ -864,7 +864,7 @@ Node *ContainerNode::childNode(unsigned index) const return n; } -static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec) +static void dispatchChildInsertionEvents(Node* child) { ASSERT(!eventDispatchForbidden()); @@ -878,25 +878,17 @@ static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec) document->incDOMTreeVersion(); - if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER)) { - ec = 0; - c->dispatchMutationEvent(eventNames().DOMNodeInsertedEvent, true, c->parentNode(), String(), String(), ec); - if (ec) - return; - } + if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER)) + c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, c->parentNode())); // dispatch the DOMNodeInsertedIntoDocument event to all descendants if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) { - for (; c; c = c->traverseNextNode(child)) { - ec = 0; - c->dispatchMutationEvent(eventNames().DOMNodeInsertedIntoDocumentEvent, false, 0, String(), String(), ec); - if (ec) - return; - } + for (; c; c = c->traverseNextNode(child)) + c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false)); } } -static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec) +static void dispatchChildRemovalEvents(Node* child) { RefPtr<Node> c = child; RefPtr<Document> document = child->document(); @@ -907,21 +899,14 @@ static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec) document->incDOMTreeVersion(); // dispatch pre-removal mutation events - if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) { - ec = 0; - c->dispatchMutationEvent(eventNames().DOMNodeRemovedEvent, true, c->parentNode(), String(), String(), ec); - if (ec) - return; - } + if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) + c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode())); // dispatch the DOMNodeRemovedFromDocument event to all descendants - if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) - for (; c; c = c->traverseNextNode(child)) { - ec = 0; - c->dispatchMutationEvent(eventNames().DOMNodeRemovedFromDocumentEvent, false, 0, String(), String(), ec); - if (ec) - return; - } + if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) { + for (; c; c = c->traverseNextNode(child)) + c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false)); + } } -} +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/Document.cpp b/src/3rdparty/webkit/WebCore/dom/Document.cpp index 1b8afe7..5422bf0 100644 --- a/src/3rdparty/webkit/WebCore/dom/Document.cpp +++ b/src/3rdparty/webkit/WebCore/dom/Document.cpp @@ -174,6 +174,12 @@ #include "WMLNames.h" #endif +#if ENABLE(MATHML) +#include "MathMLElement.h" +#include "MathMLElementFactory.h" +#include "MathMLNames.h" +#endif + #if ENABLE(XHTMLMP) #include "HTMLNoScriptElement.h" #endif @@ -803,6 +809,10 @@ PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool cre else if (isWMLDocument()) e = WMLElementFactory::createWMLElement(QualifiedName(nullAtom, qName.localName(), WMLNames::wmlNamespaceURI), this, createdByParser); #endif +#if ENABLE(MATHML) + else if (qName.namespaceURI() == MathMLNames::mathmlNamespaceURI) + e = MathMLElementFactory::createMathMLElement(qName, this, createdByParser); +#endif if (!e) e = Element::create(qName, document()); @@ -1460,9 +1470,11 @@ void Document::detach() void Document::removeAllEventListeners() { + EventTarget::removeAllEventListeners(); + if (DOMWindow* domWindow = this->domWindow()) domWindow->removeAllEventListeners(); - for (Node* node = this; node; node = node->traverseNextNode()) + for (Node* node = firstChild(); node; node = node->traverseNextNode()) node->removeAllEventListeners(); } @@ -1705,8 +1717,8 @@ void Document::implicitClose() f->animation()->resumeAnimations(this); ImageLoader::dispatchPendingLoadEvents(); - dispatchLoadEvent(); - dispatchPageTransitionEvent(EventNames().pageshowEvent, false); + dispatchWindowLoadEvent(); + dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, false), this); if (f) f->loader()->handledOnloadEvents(); #ifdef INSTRUMENT_LAYOUT_SCHEDULING @@ -2163,7 +2175,7 @@ void Document::processHttpEquiv(const String& equiv, const String& content) FrameLoader* frameLoader = frame->loader(); if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url())) { frameLoader->stopAllLoaders(); - frameLoader->scheduleHTTPRedirection(0, blankURL()); + frameLoader->scheduleLocationChange(blankURL(), String()); } } } @@ -2636,7 +2648,7 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode) // Dispatch a change event for text fields or textareas that have been edited RenderObject* r = oldFocusedNode->renderer(); if (r && r->isTextControl() && toRenderTextControl(r)->isEdited()) { - oldFocusedNode->dispatchEvent(eventNames().changeEvent, true, false); + oldFocusedNode->dispatchEvent(Event::create(eventNames().changeEvent, true, false)); r = oldFocusedNode->renderer(); if (r && r->isTextControl()) toRenderTextControl(r)->setEdited(false); @@ -2863,26 +2875,16 @@ EventListener* Document::getWindowAttributeEventListener(const AtomicString& eve return domWindow->getAttributeEventListener(eventType); } -void Document::dispatchWindowEvent(PassRefPtr<Event> event) -{ - ASSERT(!eventDispatchForbidden()); - DOMWindow* domWindow = this->domWindow(); - if (!domWindow) - return; - ExceptionCode ec; - domWindow->dispatchEvent(event, ec); -} - -void Document::dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg) +void Document::dispatchWindowEvent(PassRefPtr<Event> event, PassRefPtr<EventTarget> target) { ASSERT(!eventDispatchForbidden()); DOMWindow* domWindow = this->domWindow(); if (!domWindow) return; - domWindow->dispatchEvent(eventType, canBubbleArg, cancelableArg); + domWindow->dispatchEvent(event, target); } -void Document::dispatchLoadEvent() +void Document::dispatchWindowLoadEvent() { ASSERT(!eventDispatchForbidden()); DOMWindow* domWindow = this->domWindow(); @@ -2891,15 +2893,6 @@ void Document::dispatchLoadEvent() domWindow->dispatchLoadEvent(); } -void Document::dispatchPageTransitionEvent(const AtomicString& eventType, bool persisted) -{ - ASSERT(!eventDispatchForbidden()); - DOMWindow* domWindow = this->domWindow(); - if (!domWindow) - return; - domWindow->dispatchPageTransitionEvent(eventType, persisted); -} - PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode& ec) { if (eventType == "Event" || eventType == "Events" || eventType == "HTMLEvents") @@ -4019,10 +4012,7 @@ CollectionCache* Document::nameCollectionInfo(CollectionType type, const AtomicS void Document::finishedParsing() { setParsing(false); - - ExceptionCode ec = 0; - dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false), ec); - + dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false)); if (Frame* f = frame()) f->loader()->finishedParsing(); } diff --git a/src/3rdparty/webkit/WebCore/dom/Document.h b/src/3rdparty/webkit/WebCore/dom/Document.h index bb247f3..454304b 100644 --- a/src/3rdparty/webkit/WebCore/dom/Document.h +++ b/src/3rdparty/webkit/WebCore/dom/Document.h @@ -200,6 +200,49 @@ public: // DOM methods & attributes for Document + DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); + DEFINE_ATTRIBUTE_EVENT_LISTENER(change); + DEFINE_ATTRIBUTE_EVENT_LISTENER(click); + DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drop); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drag); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend); + DEFINE_ATTRIBUTE_EVENT_LISTENER(input); + DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel); + DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll); + DEFINE_ATTRIBUTE_EVENT_LISTENER(select); + DEFINE_ATTRIBUTE_EVENT_LISTENER(submit); + + DEFINE_ATTRIBUTE_EVENT_LISTENER(blur); + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_ATTRIBUTE_EVENT_LISTENER(focus); + DEFINE_ATTRIBUTE_EVENT_LISTENER(load); + + // WebKit extensions + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(cut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(copy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(paste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(reset); + DEFINE_ATTRIBUTE_EVENT_LISTENER(search); + DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart); + DocumentType* doctype() const { return m_docType.get(); } DOMImplementation* implementation() const; @@ -547,10 +590,8 @@ public: // Helper functions for forwarding DOMWindow event related tasks to the DOMWindow if it exists. void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>); EventListener* getWindowAttributeEventListener(const AtomicString& eventType); - void dispatchWindowEvent(PassRefPtr<Event>); - void dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg); - void dispatchLoadEvent(); - void dispatchPageTransitionEvent(const AtomicString& eventType, bool persisted); + void dispatchWindowEvent(PassRefPtr<Event>, PassRefPtr<EventTarget> = 0); + void dispatchWindowLoadEvent(); PassRefPtr<Event> createEvent(const String& eventType, ExceptionCode&); @@ -812,7 +853,7 @@ public: void setDashboardRegions(const Vector<DashboardRegionValue>&); #endif - void removeAllEventListeners(); + virtual void removeAllEventListeners(); CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; } diff --git a/src/3rdparty/webkit/WebCore/dom/Element.h b/src/3rdparty/webkit/WebCore/dom/Element.h index e7a910c..4ecf932 100644 --- a/src/3rdparty/webkit/WebCore/dom/Element.h +++ b/src/3rdparty/webkit/WebCore/dom/Element.h @@ -44,6 +44,51 @@ public: static PassRefPtr<Element> create(const QualifiedName&, Document*); virtual ~Element(); + DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); + DEFINE_ATTRIBUTE_EVENT_LISTENER(change); + DEFINE_ATTRIBUTE_EVENT_LISTENER(click); + DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drop); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drag); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend); + DEFINE_ATTRIBUTE_EVENT_LISTENER(input); + DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel); + DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll); + DEFINE_ATTRIBUTE_EVENT_LISTENER(select); + DEFINE_ATTRIBUTE_EVENT_LISTENER(submit); + + // These 4 attribute event handler attributes are overrided by HTMLBodyElement + // and HTMLFrameSetElement to forward to the DOMWindow. + DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(blur); + DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(focus); + DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(load); + + // WebKit extensions + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(cut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(copy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(paste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(reset); + DEFINE_ATTRIBUTE_EVENT_LISTENER(search); + DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart); + const AtomicString& getIDAttribute() const; bool hasAttribute(const QualifiedName&) const; const AtomicString& getAttribute(const QualifiedName&) const; diff --git a/src/3rdparty/webkit/WebCore/dom/EventListener.h b/src/3rdparty/webkit/WebCore/dom/EventListener.h index 501c61d..6862f06 100644 --- a/src/3rdparty/webkit/WebCore/dom/EventListener.h +++ b/src/3rdparty/webkit/WebCore/dom/EventListener.h @@ -37,13 +37,14 @@ namespace WebCore { public: enum Type { JSEventListenerType, ImageEventListenerType, - InspectorDOMAgentType, + InspectorDOMAgentType, + InspectorDOMStorageResourceType, ObjCEventListenerType, ConditionEventListenerType }; virtual ~EventListener() { } virtual bool operator==(const EventListener&) = 0; - virtual void handleEvent(Event*, bool isWindowEvent = false) = 0; + virtual void handleEvent(Event*) = 0; // Return true to indicate that the error is handled. virtual bool reportError(const String& /*message*/, const String& /*url*/, int /*lineNumber*/) { return false; } virtual bool wasCreatedFromMarkup() const { return false; } @@ -68,10 +69,6 @@ namespace WebCore { Type m_type; }; -#if USE(JSC) - inline void markIfNotNull(JSC::MarkStack& markStack, EventListener* listener) { if (listener) listener->markJSFunction(markStack); } -#endif - } #endif diff --git a/src/3rdparty/webkit/WebCore/dom/EventNames.h b/src/3rdparty/webkit/WebCore/dom/EventNames.h index 382bbf7..0eb98ec 100644 --- a/src/3rdparty/webkit/WebCore/dom/EventNames.h +++ b/src/3rdparty/webkit/WebCore/dom/EventNames.h @@ -45,6 +45,7 @@ namespace WebCore { macro(copy) \ macro(cut) \ macro(dblclick) \ + macro(display) \ macro(downloading) \ macro(drag) \ macro(dragend) \ @@ -136,6 +137,8 @@ namespace WebCore { \ macro(webkitTransitionEnd) \ \ + macro(orientationchange) \ + \ // end of DOM_EVENT_NAMES_FOR_EACH class EventNames { diff --git a/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp b/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp index 652644f..d3b3f55 100644 --- a/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp +++ b/src/3rdparty/webkit/WebCore/dom/EventTarget.cpp @@ -34,11 +34,39 @@ #include "config.h" #include "EventTarget.h" +#include "Event.h" +#include "EventException.h" +#include <wtf/StdLibExtras.h> + +using namespace WTF; + namespace WebCore { #ifndef NDEBUG static int gEventDispatchForbidden = 0; -#endif + +void forbidEventDispatch() +{ + if (!isMainThread()) + return; + ++gEventDispatchForbidden; +} + +void allowEventDispatch() +{ + if (!isMainThread()) + return; + if (gEventDispatchForbidden > 0) + --gEventDispatchForbidden; +} + +bool eventDispatchForbidden() +{ + if (!isMainThread()) + return false; + return gEventDispatchForbidden > 0; +} +#endif // NDEBUG EventTarget::~EventTarget() { @@ -125,22 +153,153 @@ Notification* EventTarget::toNotification() } #endif -#ifndef NDEBUG -void forbidEventDispatch() +bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) { - ++gEventDispatchForbidden; + EventTargetData* d = ensureEventTargetData(); + + pair<EventListenerMap::iterator, bool> result = d->eventListenerMap.add(eventType, EventListenerVector()); + EventListenerVector& entry = result.first->second; + + RegisteredEventListener registeredListener(listener, useCapture); + if (!result.second) { // pre-existing entry + if (entry.find(registeredListener) != notFound) // duplicate listener + return false; + } + + entry.append(registeredListener); + return true; } -void allowEventDispatch() +bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) { - if (gEventDispatchForbidden > 0) - --gEventDispatchForbidden; + EventTargetData* d = eventTargetData(); + if (!d) + return false; + + EventListenerMap::iterator result = d->eventListenerMap.find(eventType); + if (result == d->eventListenerMap.end()) + return false; + EventListenerVector& entry = result->second; + + RegisteredEventListener registeredListener(listener, useCapture); + size_t index = entry.find(registeredListener); + if (index == notFound) + return false; + + entry.remove(index); + if (!entry.size()) + d->eventListenerMap.remove(result); + + // Notify firing events planning to invoke the listener at 'index' that + // they have one less listener to invoke. + for (size_t i = 0; i < d->firingEventEndIterators.size(); ++i) { + if (eventType == *d->firingEventEndIterators[i].eventType && index < *d->firingEventEndIterators[i].value) + --*d->firingEventEndIterators[i].value; + } + + return true; } -bool eventDispatchForbidden() +bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener) { - return gEventDispatchForbidden > 0; + clearAttributeEventListener(eventType); + if (!listener) + return false; + return addEventListener(eventType, listener, false); +} + +EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType) +{ + const EventListenerVector& entry = getEventListeners(eventType); + for (size_t i = 0; i < entry.size(); ++i) { + if (entry[i].listener->isAttribute()) + return entry[i].listener.get(); + } + return 0; +} + +bool EventTarget::clearAttributeEventListener(const AtomicString& eventType) +{ + EventListener* listener = getAttributeEventListener(eventType); + if (!listener) + return false; + return removeEventListener(eventType, listener, false); +} + +bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) +{ + if (!event || event->type().isEmpty()) { + ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; + return false; + } + return dispatchEvent(event); +} + +bool EventTarget::dispatchEvent(PassRefPtr<Event> event) +{ + event->setTarget(this); + event->setCurrentTarget(this); + event->setEventPhase(Event::AT_TARGET); + return fireEventListeners(event.get()); +} + +bool EventTarget::fireEventListeners(Event* event) +{ + ASSERT(!eventDispatchForbidden()); + ASSERT(event && !event->type().isEmpty()); + + EventTargetData* d = eventTargetData(); + if (!d) + return true; + + EventListenerMap::iterator result = d->eventListenerMap.find(event->type()); + if (result == d->eventListenerMap.end()) + return false; + EventListenerVector& entry = result->second; + + RefPtr<EventTarget> protect = this; + + size_t end = entry.size(); + d->firingEventEndIterators.append(FiringEventEndIterator(&event->type(), &end)); + for (size_t i = 0; i < end; ++i) { + RegisteredEventListener& registeredListener = entry[i]; + if (event->eventPhase() == Event::CAPTURING_PHASE && !registeredListener.useCapture) + continue; + if (event->eventPhase() == Event::BUBBLING_PHASE && registeredListener.useCapture) + continue; + // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling + // event listeners, even though that violates some versions of the DOM spec. + registeredListener.listener->handleEvent(event); + } + d->firingEventEndIterators.removeLast(); + + return !event->defaultPrevented(); +} + +const EventListenerVector& EventTarget::getEventListeners(const AtomicString& eventType) +{ + DEFINE_STATIC_LOCAL(EventListenerVector, emptyVector, ()); + + EventTargetData* d = eventTargetData(); + if (!d) + return emptyVector; + EventListenerMap::iterator it = d->eventListenerMap.find(eventType); + if (it == d->eventListenerMap.end()) + return emptyVector; + return it->second; +} + +void EventTarget::removeAllEventListeners() +{ + EventTargetData* d = eventTargetData(); + if (!d) + return; + d->eventListenerMap.clear(); + + // Notify firing events planning to invoke the listener at 'index' that + // they have one less listener to invoke. + for (size_t i = 0; i < d->firingEventEndIterators.size(); ++i) + *d->firingEventEndIterators[i].value = 0; } -#endif // NDEBUG -} // end namespace +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/EventTarget.h b/src/3rdparty/webkit/WebCore/dom/EventTarget.h index 6bcc3fb..4499328 100644 --- a/src/3rdparty/webkit/WebCore/dom/EventTarget.h +++ b/src/3rdparty/webkit/WebCore/dom/EventTarget.h @@ -32,6 +32,9 @@ #ifndef EventTarget_h #define EventTarget_h +#include "AtomicStringHash.h" +#include "EventNames.h" +#include "RegisteredEventListener.h" #include <wtf/Forward.h> namespace WebCore { @@ -58,8 +61,31 @@ namespace WebCore { typedef int ExceptionCode; + struct FiringEventEndIterator { + FiringEventEndIterator(const AtomicString* eventType, size_t* value) + : eventType(eventType) + , value(value) + { + } + + const AtomicString* eventType; + size_t* value; + }; + typedef Vector<FiringEventEndIterator, 1> FiringEventEndIteratorVector; + + typedef Vector<RegisteredEventListener, 1> EventListenerVector; + typedef HashMap<AtomicString, EventListenerVector> EventListenerMap; + + struct EventTargetData { + EventListenerMap eventListenerMap; + FiringEventEndIteratorVector firingEventEndIterators; + }; + class EventTarget { public: + void ref() { refEventTarget(); } + void deref() { derefEventTarget(); } + virtual EventSource* toEventSource(); virtual MessagePort* toMessagePort(); virtual Node* toNode(); @@ -90,36 +116,119 @@ namespace WebCore { virtual ScriptExecutionContext* scriptExecutionContext() const = 0; - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) = 0; - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) = 0; - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&) = 0; + virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); + virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); + virtual void removeAllEventListeners(); + virtual bool dispatchEvent(PassRefPtr<Event>); + bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); // DOM API - void ref() { refEventTarget(); } - void deref() { derefEventTarget(); } + // Used for legacy "onEvent" attribute APIs. + bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>); + bool clearAttributeEventListener(const AtomicString& eventType); + EventListener* getAttributeEventListener(const AtomicString& eventType); + + bool hasEventListeners(); + bool hasEventListeners(const AtomicString& eventType); + const EventListenerVector& getEventListeners(const AtomicString& eventType); - // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event - // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch. - virtual void* preDispatchEventHandler(Event*) { return 0; } - virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { } + bool fireEventListeners(Event*); + bool isFiringEventListeners(); + +#if USE(JSC) + void markEventListeners(JSC::MarkStack&); + void invalidateEventListeners(); +#endif protected: virtual ~EventTarget(); + + virtual EventTargetData* eventTargetData() = 0; + virtual EventTargetData* ensureEventTargetData() = 0; private: virtual void refEventTarget() = 0; virtual void derefEventTarget() = 0; }; - void forbidEventDispatch(); - void allowEventDispatch(); + #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \ + EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ + void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ + + #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \ + virtual EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ + virtual void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ + + #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \ + EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \ + void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \ + + #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \ + EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \ + void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \ + + #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \ + EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \ + void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \ #ifndef NDEBUG + void forbidEventDispatch(); + void allowEventDispatch(); bool eventDispatchForbidden(); #else inline void forbidEventDispatch() { } inline void allowEventDispatch() { } #endif -} +#if USE(JSC) + inline void EventTarget::markEventListeners(JSC::MarkStack& markStack) + { + EventTargetData* d = eventTargetData(); + if (!d) + return; + + EventListenerMap::iterator end = d->eventListenerMap.end(); + for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) { + EventListenerVector& entry = it->second; + for (size_t i = 0; i < entry.size(); ++i) + entry[i].listener->markJSFunction(markStack); + } + } + + inline void EventTarget::invalidateEventListeners() + { + EventTargetData* d = eventTargetData(); + if (!d) + return; + + d->eventListenerMap.clear(); + } + + inline bool EventTarget::isFiringEventListeners() + { + EventTargetData* d = eventTargetData(); + if (!d) + return false; + return d->firingEventEndIterators.size() != 0; + } + + inline bool EventTarget::hasEventListeners() + { + EventTargetData* d = eventTargetData(); + if (!d) + return false; + return !d->eventListenerMap.isEmpty(); + } + + inline bool EventTarget::hasEventListeners(const AtomicString& eventType) + { + EventTargetData* d = eventTargetData(); + if (!d) + return false; + return d->eventListenerMap.contains(eventType); + } #endif + +} // namespace WebCore + +#endif // EventTarget_h diff --git a/src/3rdparty/webkit/WebCore/dom/InputElement.cpp b/src/3rdparty/webkit/WebCore/dom/InputElement.cpp index 97793e2..96e31f4 100644 --- a/src/3rdparty/webkit/WebCore/dom/InputElement.cpp +++ b/src/3rdparty/webkit/WebCore/dom/InputElement.cpp @@ -34,7 +34,6 @@ #include "RenderTextControlSingleLine.h" #include "SelectionController.h" #include "TextIterator.h" -#include "TextBreakIterator.h" #if ENABLE(WML) #include "WMLInputElement.h" @@ -154,28 +153,10 @@ void InputElement::setValueFromRenderer(InputElementData& data, InputElement* in element->setFormControlValueMatchesRenderer(true); - // Fire the "input" DOM event - element->dispatchEvent(eventNames().inputEvent, true, false); + element->dispatchEvent(Event::create(eventNames().inputEvent, true, false)); notifyFormStateChanged(element); } -static int numCharactersInGraphemeClusters(StringImpl* s, int numGraphemeClusters) -{ - if (!s) - return 0; - - TextBreakIterator* it = characterBreakIterator(s->characters(), s->length()); - if (!it) - return 0; - - for (int i = 0; i < numGraphemeClusters; ++i) { - if (textBreakNext(it) == TextBreakDone) - return s->length(); - } - - return textBreakCurrent(it); -} - String InputElement::sanitizeValue(const InputElement* inputElement, const String& proposedValue) { return InputElement::sanitizeUserInputValue(inputElement, proposedValue, s_maximumLength); @@ -191,36 +172,15 @@ String InputElement::sanitizeUserInputValue(const InputElement* inputElement, co string.replace('\r', ' '); string.replace('\n', ' '); - StringImpl* s = string.impl(); - int newLength = numCharactersInGraphemeClusters(s, maxLength); - for (int i = 0; i < newLength; ++i) { - const UChar& current = (*s)[i]; + unsigned newLength = string.numCharactersInGraphemeClusters(maxLength); + for (unsigned i = 0; i < newLength; ++i) { + const UChar current = string[i]; if (current < ' ' && current != '\t') { newLength = i; break; } } - - if (newLength < static_cast<int>(string.length())) - return string.left(newLength); - - return string; -} - -static int numGraphemeClusters(StringImpl* s) -{ - if (!s) - return 0; - - TextBreakIterator* it = characterBreakIterator(s->characters(), s->length()); - if (!it) - return 0; - - int num = 0; - while (textBreakNext(it) != TextBreakDone) - ++num; - - return num; + return string.left(newLength); } void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputElement* inputElement, Element* element, Event* event) @@ -231,15 +191,16 @@ void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputEl // We use RenderTextControlSingleLine::text() instead of InputElement::value() // because they can be mismatched by sanitizeValue() in // RenderTextControlSingleLine::subtreeHasChanged() in some cases. - int oldLength = numGraphemeClusters(toRenderTextControlSingleLine(element->renderer())->text().impl()); + unsigned oldLength = toRenderTextControlSingleLine(element->renderer())->text().numGraphemeClusters(); // selection() may be a pre-edit text. - int selectionLength = numGraphemeClusters(plainText(element->document()->frame()->selection()->selection().toNormalizedRange().get()).impl()); + unsigned selectionLength = plainText(element->document()->frame()->selection()->selection().toNormalizedRange().get()).numGraphemeClusters(); ASSERT(oldLength >= selectionLength); // Selected characters will be removed by the next text event. - int baseLength = oldLength - selectionLength; - int appendableLength = data.maxLength() - baseLength; + unsigned baseLength = oldLength - selectionLength; + unsigned maxLength = static_cast<unsigned>(data.maxLength()); // maxLength() can never be negative. + unsigned appendableLength = maxLength > baseLength ? maxLength - baseLength : 0; // Truncate the inserted text to avoid violating the maxLength and other constraints. BeforeTextInsertedEvent* textEvent = static_cast<BeforeTextInsertedEvent*>(event); diff --git a/src/3rdparty/webkit/WebCore/dom/MessageEvent.h b/src/3rdparty/webkit/WebCore/dom/MessageEvent.h index 7d94689..555ed47 100644 --- a/src/3rdparty/webkit/WebCore/dom/MessageEvent.h +++ b/src/3rdparty/webkit/WebCore/dom/MessageEvent.h @@ -42,7 +42,7 @@ namespace WebCore { { return adoptRef(new MessageEvent); } - static PassRefPtr<MessageEvent> create(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray> ports) + static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const String& data = "", const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0) { return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports)); } diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp b/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp index bfd7932..50a0106 100644 --- a/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp +++ b/src/3rdparty/webkit/WebCore/dom/MessagePort.cpp @@ -169,13 +169,7 @@ void MessagePort::dispatchMessages() OwnPtr<MessagePortChannel::EventData> eventData; while (m_entangledChannel && m_entangledChannel->tryGetMessageFromRemote(eventData)) { OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*m_scriptExecutionContext, eventData->channels()); - RefPtr<Event> evt = MessageEvent::create(eventData->message(), "", "", 0, ports.release()); - - if (m_onMessageListener) { - evt->setTarget(this); - evt->setCurrentTarget(this); - m_onMessageListener->handleEvent(evt.get(), false); - } + RefPtr<Event> evt = MessageEvent::create(ports.release(), eventData->message()); ExceptionCode ec = 0; dispatchEvent(evt.release(), ec); @@ -183,63 +177,6 @@ void MessagePort::dispatchMessages() } } -void MessagePort::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) { - ListenerVector listeners; - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } else { - ListenerVector& listeners = iter->second; - for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) - return; - } - - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } -} - -void MessagePort::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) - return; - - ListenerVector& listeners = iter->second; - for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (**listenerIter == *eventListener) { - listeners.remove(listenerIter - listeners.begin()); - return; - } - } -} - -bool MessagePort::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) -{ - if (!event || event->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - ListenerVector listenersCopy = m_eventListeners.get(event->type()); - for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) { - event->setTarget(this); - event->setCurrentTarget(this); - listenerIter->get()->handleEvent(event.get(), false); - } - - return !event->defaultPrevented(); -} - -void MessagePort::setOnmessage(PassRefPtr<EventListener> eventListener) -{ - m_onMessageListener = eventListener; - start(); -} - bool MessagePort::hasPendingActivity() { // The spec says that entangled message ports should always be treated as if they have a strong reference. @@ -294,4 +231,14 @@ PassOwnPtr<MessagePortArray> MessagePort::entanglePorts(ScriptExecutionContext& return portArray; } +EventTargetData* MessagePort::eventTargetData() +{ + return &m_eventTargetData; +} + +EventTargetData* MessagePort::ensureEventTargetData() +{ + return &m_eventTargetData; +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePort.h b/src/3rdparty/webkit/WebCore/dom/MessagePort.h index d042bc1..e649d5d 100644 --- a/src/3rdparty/webkit/WebCore/dom/MessagePort.h +++ b/src/3rdparty/webkit/WebCore/dom/MessagePort.h @@ -29,9 +29,9 @@ #include "AtomicStringHash.h" #include "EventListener.h" +#include "EventNames.h" #include "EventTarget.h" #include "MessagePortChannel.h" - #include <wtf/HashMap.h> #include <wtf/OwnPtr.h> #include <wtf/PassOwnPtr.h> @@ -87,21 +87,17 @@ namespace WebCore { void dispatchMessages(); - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - - typedef Vector<RefPtr<EventListener> > ListenerVector; - typedef HashMap<AtomicString, ListenerVector> EventListenersMap; - EventListenersMap& eventListeners() { return m_eventListeners; } - using RefCounted<MessagePort>::ref; using RefCounted<MessagePort>::deref; bool hasPendingActivity(); - void setOnmessage(PassRefPtr<EventListener>); - EventListener* onmessage() const { return m_onMessageListener.get(); } + void setOnmessage(PassRefPtr<EventListener> listener) + { + setAttributeEventListener(eventNames().messageEvent, listener); + start(); + } + EventListener* onmessage() { return getAttributeEventListener(eventNames().messageEvent); } // Returns null if there is no entangled port, or if the entangled port is run by a different thread. // Returns null otherwise. @@ -114,16 +110,15 @@ namespace WebCore { virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); OwnPtr<MessagePortChannel> m_entangledChannel; bool m_started; ScriptExecutionContext* m_scriptExecutionContext; - - RefPtr<EventListener> m_onMessageListener; - - EventListenersMap m_eventListeners; + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/MessagePort.idl b/src/3rdparty/webkit/WebCore/dom/MessagePort.idl index 11ab757..a9149ec 100644 --- a/src/3rdparty/webkit/WebCore/dom/MessagePort.idl +++ b/src/3rdparty/webkit/WebCore/dom/MessagePort.idl @@ -28,6 +28,7 @@ module events { interface [ CustomMarkFunction, + EventTarget, GenerateConstructor, NoStaticTables ] MessagePort { diff --git a/src/3rdparty/webkit/WebCore/dom/MutationEvent.h b/src/3rdparty/webkit/WebCore/dom/MutationEvent.h index c5f2d1d..29b978c 100644 --- a/src/3rdparty/webkit/WebCore/dom/MutationEvent.h +++ b/src/3rdparty/webkit/WebCore/dom/MutationEvent.h @@ -41,10 +41,11 @@ namespace WebCore { { return adoptRef(new MutationEvent); } - static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode, - const String& prevValue, const String& newValue, const String& attrName, unsigned short attrChange) + + static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode = 0, + const String& prevValue = String(), const String& newValue = String(), const String& attrName = String(), unsigned short attrChange = 0) { - return adoptRef(new MutationEvent(type, canBubble, cancelable, relatedNode, prevValue, newValue, attrName, attrChange)); + return adoptRef(new MutationEvent(type, canBubble, false, relatedNode, prevValue, newValue, attrName, attrChange)); } void initMutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode, diff --git a/src/3rdparty/webkit/WebCore/dom/Node.cpp b/src/3rdparty/webkit/WebCore/dom/Node.cpp index a26dd04..2240dd8 100644 --- a/src/3rdparty/webkit/WebCore/dom/Node.cpp +++ b/src/3rdparty/webkit/WebCore/dom/Node.cpp @@ -2342,16 +2342,6 @@ ScriptExecutionContext* Node::scriptExecutionContext() const return document(); } -const RegisteredEventListenerVector& Node::eventListeners() const -{ - if (hasRareData()) { - if (RegisteredEventListenerVector* listeners = rareData()->listeners()) - return *listeners; - } - static const RegisteredEventListenerVector* emptyListenersVector = new RegisteredEventListenerVector; - return *emptyListenersVector; -} - void Node::insertedIntoDocument() { setInDocument(true); @@ -2399,69 +2389,45 @@ static inline void updateSVGElementInstancesAfterEventListenerChange(Node* refer #endif } -void Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) +bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) { + if (!EventTarget::addEventListener(eventType, listener, useCapture)) + return false; + if (Document* document = this->document()) document->addListenerTypeIfNeeded(eventType); - - RegisteredEventListenerVector& listeners = ensureRareData()->ensureListeners(); - - // Remove existing identical listener set with identical arguments. - // The DOM2 spec says that "duplicate instances are discarded" in this case. - removeEventListener(eventType, listener.get(), useCapture); - - listeners.append(RegisteredEventListener::create(eventType, listener, useCapture)); updateSVGElementInstancesAfterEventListenerChange(this); + return true; } -void Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) +bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) { - if (!hasRareData()) - return; - - RegisteredEventListenerVector* listeners = rareData()->listeners(); - if (!listeners) - return; - - size_t size = listeners->size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *listeners->at(i); - if (r.eventType() == eventType && r.useCapture() == useCapture && *r.listener() == *listener) { - r.setRemoved(true); - listeners->remove(i); + if (!EventTarget::removeEventListener(eventType, listener, useCapture)) + return false; - updateSVGElementInstancesAfterEventListenerChange(this); - return; - } - } + updateSVGElementInstancesAfterEventListenerChange(this); + return true; } -void Node::removeAllEventListenersSlowCase() +EventTargetData* Node::eventTargetData() { - ASSERT(hasRareData()); - - RegisteredEventListenerVector* listeners = rareData()->listeners(); - if (!listeners) - return; + return hasRareData() ? rareData()->eventTargetData() : 0; +} - size_t size = listeners->size(); - for (size_t i = 0; i < size; ++i) - listeners->at(i)->setRemoved(true); - listeners->clear(); +EventTargetData* Node::ensureEventTargetData() +{ + return ensureRareData()->ensureEventTargetData(); } -void Node::handleLocalEvents(Event* event, bool useCapture) +void Node::handleLocalEvents(Event* event) { + if (!hasRareData() || !rareData()->eventTargetData()) + return; + if (disabled() && event->isMouseEvent()) return; - RegisteredEventListenerVector listenersCopy = eventListeners(); - size_t size = listenersCopy.size(); - for (size_t i = 0; i < size; ++i) { - const RegisteredEventListener& r = *listenersCopy[i]; - if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed()) - r.listener()->handleEvent(event, false); - } + fireEventListeners(event); } #if ENABLE(SVG) @@ -2502,19 +2468,15 @@ static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNo return referenceNode; } -bool Node::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec) +bool Node::dispatchEvent(PassRefPtr<Event> prpEvent) { - RefPtr<Event> evt(e); - ASSERT(!eventDispatchForbidden()); - if (!evt || evt->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return false; - } + RefPtr<EventTarget> protect = this; + RefPtr<Event> event = prpEvent; - evt->setTarget(eventTargetRespectingSVGTargetRules(this)); + event->setTarget(eventTargetRespectingSVGTargetRules(this)); RefPtr<FrameView> view = document()->view(); - return dispatchGenericEvent(evt.release()); + return dispatchGenericEvent(event.release()); } bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent) @@ -2567,27 +2529,22 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent) if (targetForWindowEvents) { event->setCurrentTarget(targetForWindowEvents); - targetForWindowEvents->handleEvent(event.get(), true); + targetForWindowEvents->fireEventListeners(event.get()); if (event->propagationStopped()) goto doneDispatching; } for (size_t i = ancestors.size(); i; --i) { ContainerNode* ancestor = ancestors[i - 1].get(); event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor)); - ancestor->handleLocalEvents(event.get(), true); + ancestor->handleLocalEvents(event.get()); if (event->propagationStopped()) goto doneDispatching; } event->setEventPhase(Event::AT_TARGET); - // We do want capturing event listeners to be invoked here, even though - // that violates some versions of the DOM specification; Mozilla does it. event->setCurrentTarget(eventTargetRespectingSVGTargetRules(this)); - handleLocalEvents(event.get(), true); - if (event->propagationStopped()) - goto doneDispatching; - handleLocalEvents(event.get(), false); + handleLocalEvents(event.get()); if (event->propagationStopped()) goto doneDispatching; @@ -2599,13 +2556,13 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent) for (size_t i = 0; i < size; ++i) { ContainerNode* ancestor = ancestors[i].get(); event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor)); - ancestor->handleLocalEvents(event.get(), false); + ancestor->handleLocalEvents(event.get()); if (event->propagationStopped() || event->cancelBubble()) goto doneDispatching; } if (targetForWindowEvents) { event->setCurrentTarget(targetForWindowEvents); - targetForWindowEvents->handleEvent(event.get(), false); + targetForWindowEvents->fireEventListeners(event.get()); if (event->propagationStopped() || event->cancelBubble()) goto doneDispatching; } @@ -2663,8 +2620,7 @@ void Node::dispatchSubtreeModifiedEvent() if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER)) return; - ExceptionCode ec = 0; - dispatchMutationEvent(eventNames().DOMSubtreeModifiedEvent, true, 0, String(), String(), ec); + dispatchEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true)); } void Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent) @@ -2674,18 +2630,15 @@ void Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr bool cancelable = eventType == eventNames().DOMActivateEvent; - ExceptionCode ec = 0; - RefPtr<UIEvent> evt = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail); - evt->setUnderlyingEvent(underlyingEvent); - dispatchEvent(evt.release(), ec); + RefPtr<UIEvent> event = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail); + event->setUnderlyingEvent(underlyingEvent); + dispatchEvent(event.release()); } bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& key) { - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, document()->defaultView()); - bool r = dispatchEvent(keyboardEvent, ec); + bool r = dispatchEvent(keyboardEvent); // we want to return false if default is prevented (already taken care of) // or if the element is default-handled by the DOM. Otherwise we let it just @@ -2779,8 +2732,6 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det bool cancelable = eventType != eventNames().mousemoveEvent; - ExceptionCode ec = 0; - bool swallowEvent = false; // Attempting to dispatch with a non-EventTarget relatedTarget causes the relatedTarget to be silently ignored. @@ -2805,7 +2756,7 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det mouseEvent->setUnderlyingEvent(underlyingEvent.get()); mouseEvent->setAbsoluteLocation(IntPoint(pageX, pageY)); - dispatchEvent(mouseEvent, ec); + dispatchEvent(mouseEvent); bool defaultHandled = mouseEvent->defaultHandled(); bool defaultPrevented = mouseEvent->defaultPrevented(); if (defaultHandled || defaultPrevented) @@ -2823,7 +2774,7 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det doubleClickEvent->setUnderlyingEvent(underlyingEvent.get()); if (defaultHandled) doubleClickEvent->setDefaultHandled(); - dispatchEvent(doubleClickEvent, ec); + dispatchEvent(doubleClickEvent); if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented()) swallowEvent = true; } @@ -2860,98 +2811,18 @@ void Node::dispatchWheelEvent(PlatformWheelEvent& e) we->setAbsoluteLocation(IntPoint(pos.x(), pos.y())); - ExceptionCode ec = 0; - if (!dispatchEvent(we.release(), ec)) + if (!dispatchEvent(we.release())) e.accept(); } -void Node::dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime) -{ - ASSERT(!eventDispatchForbidden()); - - ExceptionCode ec = 0; - dispatchEvent(WebKitAnimationEvent::create(eventType, animationName, elapsedTime), ec); -} - -void Node::dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime) -{ - ASSERT(!eventDispatchForbidden()); - - ExceptionCode ec = 0; - dispatchEvent(WebKitTransitionEvent::create(eventType, propertyName, elapsedTime), ec); -} - -void Node::dispatchMutationEvent(const AtomicString& eventType, bool canBubble, PassRefPtr<Node> relatedNode, const String& prevValue, const String& newValue, ExceptionCode& ec) -{ - ASSERT(!eventDispatchForbidden()); - - dispatchEvent(MutationEvent::create(eventType, canBubble, false, relatedNode, prevValue, newValue, String(), 0), ec); -} - void Node::dispatchFocusEvent() { - dispatchEvent(eventNames().focusEvent, false, false); + dispatchEvent(Event::create(eventNames().focusEvent, false, false)); } void Node::dispatchBlurEvent() { - dispatchEvent(eventNames().blurEvent, false, false); -} - -bool Node::dispatchEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg) -{ - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; - return dispatchEvent(Event::create(eventType, canBubbleArg, cancelableArg), ec); -} - -void Node::dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg) -{ - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; - dispatchEvent(ProgressEvent::create(eventType, lengthComputableArg, loadedArg, totalArg), ec); -} - -void Node::clearAttributeEventListener(const AtomicString& eventType) -{ - if (!hasRareData()) - return; - - RegisteredEventListenerVector* listeners = rareData()->listeners(); - if (!listeners) - return; - - size_t size = listeners->size(); - for (size_t i = 0; i < size; ++i) { - RegisteredEventListener& r = *listeners->at(i); - if (r.eventType() != eventType || !r.listener()->isAttribute()) - continue; - - r.setRemoved(true); - listeners->remove(i); - - updateSVGElementInstancesAfterEventListenerChange(this); - return; - } -} - -void Node::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener) -{ - clearAttributeEventListener(eventType); - if (listener) - addEventListener(eventType, listener, false); -} - -EventListener* Node::getAttributeEventListener(const AtomicString& eventType) const -{ - const RegisteredEventListenerVector& listeners = eventListeners(); - size_t size = listeners.size(); - for (size_t i = 0; i < size; ++i) { - const RegisteredEventListener& r = *listeners[i]; - if (r.eventType() == eventType && r.listener()->isAttribute()) - return r.listener(); - } - return 0; + dispatchEvent(Event::create(eventNames().blurEvent, false, false)); } bool Node::disabled() const @@ -2984,396 +2855,6 @@ void Node::defaultEventHandler(Event* event) } } -EventListener* Node::onabort() const -{ - return getAttributeEventListener(eventNames().abortEvent); -} - -void Node::setOnabort(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().abortEvent, eventListener); -} - -EventListener* Node::onblur() const -{ - return getAttributeEventListener(eventNames().blurEvent); -} - -void Node::setOnblur(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().blurEvent, eventListener); -} - -EventListener* Node::onchange() const -{ - return getAttributeEventListener(eventNames().changeEvent); -} - -void Node::setOnchange(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().changeEvent, eventListener); -} - -EventListener* Node::onclick() const -{ - return getAttributeEventListener(eventNames().clickEvent); -} - -void Node::setOnclick(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().clickEvent, eventListener); -} - -EventListener* Node::oncontextmenu() const -{ - return getAttributeEventListener(eventNames().contextmenuEvent); -} - -void Node::setOncontextmenu(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().contextmenuEvent, eventListener); -} - -EventListener* Node::ondblclick() const -{ - return getAttributeEventListener(eventNames().dblclickEvent); -} - -void Node::setOndblclick(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dblclickEvent, eventListener); -} - -EventListener* Node::onerror() const -{ - return getAttributeEventListener(eventNames().errorEvent); -} - -void Node::setOnerror(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().errorEvent, eventListener); -} - -EventListener* Node::onfocus() const -{ - return getAttributeEventListener(eventNames().focusEvent); -} - -void Node::setOnfocus(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().focusEvent, eventListener); -} - -EventListener* Node::oninput() const -{ - return getAttributeEventListener(eventNames().inputEvent); -} - -void Node::setOninput(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().inputEvent, eventListener); -} - -EventListener* Node::oninvalid() const -{ - return getAttributeEventListener(eventNames().invalidEvent); -} - -void Node::setOninvalid(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().invalidEvent, eventListener); -} - -EventListener* Node::onkeydown() const -{ - return getAttributeEventListener(eventNames().keydownEvent); -} - -void Node::setOnkeydown(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().keydownEvent, eventListener); -} - -EventListener* Node::onkeypress() const -{ - return getAttributeEventListener(eventNames().keypressEvent); -} - -void Node::setOnkeypress(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().keypressEvent, eventListener); -} - -EventListener* Node::onkeyup() const -{ - return getAttributeEventListener(eventNames().keyupEvent); -} - -void Node::setOnkeyup(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().keyupEvent, eventListener); -} - -EventListener* Node::onload() const -{ - return getAttributeEventListener(eventNames().loadEvent); -} - -void Node::setOnload(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().loadEvent, eventListener); -} - -EventListener* Node::onmousedown() const -{ - return getAttributeEventListener(eventNames().mousedownEvent); -} - -void Node::setOnmousedown(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mousedownEvent, eventListener); -} - -EventListener* Node::onmousemove() const -{ - return getAttributeEventListener(eventNames().mousemoveEvent); -} - -void Node::setOnmousemove(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mousemoveEvent, eventListener); -} - -EventListener* Node::onmouseout() const -{ - return getAttributeEventListener(eventNames().mouseoutEvent); -} - -void Node::setOnmouseout(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mouseoutEvent, eventListener); -} - -EventListener* Node::onmouseover() const -{ - return getAttributeEventListener(eventNames().mouseoverEvent); -} - -void Node::setOnmouseover(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mouseoverEvent, eventListener); -} - -EventListener* Node::onmouseup() const -{ - return getAttributeEventListener(eventNames().mouseupEvent); -} - -void Node::setOnmouseup(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mouseupEvent, eventListener); -} - -EventListener* Node::onmousewheel() const -{ - return getAttributeEventListener(eventNames().mousewheelEvent); -} - -void Node::setOnmousewheel(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().mousewheelEvent, eventListener); -} - -EventListener* Node::ondragenter() const -{ - return getAttributeEventListener(eventNames().dragenterEvent); -} - -void Node::setOndragenter(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragenterEvent, eventListener); -} - -EventListener* Node::ondragover() const -{ - return getAttributeEventListener(eventNames().dragoverEvent); -} - -void Node::setOndragover(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragoverEvent, eventListener); -} - -EventListener* Node::ondragleave() const -{ - return getAttributeEventListener(eventNames().dragleaveEvent); -} - -void Node::setOndragleave(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragleaveEvent, eventListener); -} - -EventListener* Node::ondrop() const -{ - return getAttributeEventListener(eventNames().dropEvent); -} - -void Node::setOndrop(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dropEvent, eventListener); -} - -EventListener* Node::ondragstart() const -{ - return getAttributeEventListener(eventNames().dragstartEvent); -} - -void Node::setOndragstart(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragstartEvent, eventListener); -} - -EventListener* Node::ondrag() const -{ - return getAttributeEventListener(eventNames().dragEvent); -} - -void Node::setOndrag(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragEvent, eventListener); -} - -EventListener* Node::ondragend() const -{ - return getAttributeEventListener(eventNames().dragendEvent); -} - -void Node::setOndragend(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().dragendEvent, eventListener); -} - -EventListener* Node::onscroll() const -{ - return getAttributeEventListener(eventNames().scrollEvent); -} - -void Node::setOnscroll(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().scrollEvent, eventListener); -} - -EventListener* Node::onselect() const -{ - return getAttributeEventListener(eventNames().selectEvent); -} - -void Node::setOnselect(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().selectEvent, eventListener); -} - -EventListener* Node::onsubmit() const -{ - return getAttributeEventListener(eventNames().submitEvent); -} - -void Node::setOnsubmit(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().submitEvent, eventListener); -} - -EventListener* Node::onbeforecut() const -{ - return getAttributeEventListener(eventNames().beforecutEvent); -} - -void Node::setOnbeforecut(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().beforecutEvent, eventListener); -} - -EventListener* Node::oncut() const -{ - return getAttributeEventListener(eventNames().cutEvent); -} - -void Node::setOncut(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().cutEvent, eventListener); -} - -EventListener* Node::onbeforecopy() const -{ - return getAttributeEventListener(eventNames().beforecopyEvent); -} - -void Node::setOnbeforecopy(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().beforecopyEvent, eventListener); -} - -EventListener* Node::oncopy() const -{ - return getAttributeEventListener(eventNames().copyEvent); -} - -void Node::setOncopy(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().copyEvent, eventListener); -} - -EventListener* Node::onbeforepaste() const -{ - return getAttributeEventListener(eventNames().beforepasteEvent); -} - -void Node::setOnbeforepaste(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().beforepasteEvent, eventListener); -} - -EventListener* Node::onpaste() const -{ - return getAttributeEventListener(eventNames().pasteEvent); -} - -void Node::setOnpaste(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().pasteEvent, eventListener); -} - -EventListener* Node::onreset() const -{ - return getAttributeEventListener(eventNames().resetEvent); -} - -void Node::setOnreset(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().resetEvent, eventListener); -} - -EventListener* Node::onsearch() const -{ - return getAttributeEventListener(eventNames().searchEvent); -} - -void Node::setOnsearch(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().searchEvent, eventListener); -} - -EventListener* Node::onselectstart() const -{ - return getAttributeEventListener(eventNames().selectstartEvent); -} - -void Node::setOnselectstart(PassRefPtr<EventListener> eventListener) -{ - setAttributeEventListener(eventNames().selectstartEvent, eventListener); -} - } // namespace WebCore #ifndef NDEBUG diff --git a/src/3rdparty/webkit/WebCore/dom/Node.h b/src/3rdparty/webkit/WebCore/dom/Node.h index af1e73b..f3bebc6 100644 --- a/src/3rdparty/webkit/WebCore/dom/Node.h +++ b/src/3rdparty/webkit/WebCore/dom/Node.h @@ -183,6 +183,13 @@ public: static bool isWMLElement() { return false; } #endif +#if ENABLE(MATHML) + virtual bool isMathMLElement() const { return false; } +#else + static bool isMathMLElement() { return false; } +#endif + + virtual bool isMediaControlElement() const { return false; } virtual bool isStyledElement() const { return false; } virtual bool isFrameOwnerElement() const { return false; } @@ -505,19 +512,19 @@ public: virtual ScriptExecutionContext* scriptExecutionContext() const; - // Used for standard DOM addEventListener / removeEventListener APIs. - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); + virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); + virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - // Used for legacy "onEvent" property APIs. - void setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>); - void clearAttributeEventListener(const AtomicString& eventType); - EventListener* getAttributeEventListener(const AtomicString& eventType) const; + // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event + // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch. + virtual void* preDispatchEventHandler(Event*) { return 0; } + virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { } - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - bool dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable); + using EventTarget::dispatchEvent; + virtual bool dispatchEvent(PassRefPtr<Event>); - void removeAllEventListeners() { if (hasRareData()) removeAllEventListenersSlowCase(); } + bool dispatchGenericEvent(PassRefPtr<Event>); + virtual void handleLocalEvents(Event*); void dispatchSubtreeModifiedEvent(); void dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent); @@ -531,14 +538,6 @@ public: bool isSimulated, Node* relatedTarget, PassRefPtr<Event> underlyingEvent); void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent); void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true); - void dispatchProgressEvent(const AtomicString& eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg); - void dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime); - void dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime); - void dispatchMutationEvent(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode, const String& prevValue, const String& newValue, ExceptionCode&); - - bool dispatchGenericEvent(PassRefPtr<Event>); - - virtual void handleLocalEvents(Event*, bool useCapture); virtual void dispatchFocusEvent(); virtual void dispatchBlurEvent(); @@ -554,95 +553,12 @@ public: */ virtual bool disabled() const; - const RegisteredEventListenerVector& eventListeners() const; - - // These 4 attribute event handler attributes are overrided by HTMLBodyElement - // and HTMLFrameSetElement to forward to the DOMWindow. - virtual EventListener* onblur() const; - virtual void setOnblur(PassRefPtr<EventListener>); - virtual EventListener* onerror() const; - virtual void setOnerror(PassRefPtr<EventListener>); - virtual EventListener* onfocus() const; - virtual void setOnfocus(PassRefPtr<EventListener>); - virtual EventListener* onload() const; - virtual void setOnload(PassRefPtr<EventListener>); - - EventListener* onabort() const; - void setOnabort(PassRefPtr<EventListener>); - EventListener* onchange() const; - void setOnchange(PassRefPtr<EventListener>); - EventListener* onclick() const; - void setOnclick(PassRefPtr<EventListener>); - EventListener* oncontextmenu() const; - void setOncontextmenu(PassRefPtr<EventListener>); - EventListener* ondblclick() const; - void setOndblclick(PassRefPtr<EventListener>); - EventListener* ondragenter() const; - void setOndragenter(PassRefPtr<EventListener>); - EventListener* ondragover() const; - void setOndragover(PassRefPtr<EventListener>); - EventListener* ondragleave() const; - void setOndragleave(PassRefPtr<EventListener>); - EventListener* ondrop() const; - void setOndrop(PassRefPtr<EventListener>); - EventListener* ondragstart() const; - void setOndragstart(PassRefPtr<EventListener>); - EventListener* ondrag() const; - void setOndrag(PassRefPtr<EventListener>); - EventListener* ondragend() const; - void setOndragend(PassRefPtr<EventListener>); - EventListener* oninput() const; - void setOninput(PassRefPtr<EventListener>); - EventListener* oninvalid() const; - void setOninvalid(PassRefPtr<EventListener>); - EventListener* onkeydown() const; - void setOnkeydown(PassRefPtr<EventListener>); - EventListener* onkeypress() const; - void setOnkeypress(PassRefPtr<EventListener>); - EventListener* onkeyup() const; - void setOnkeyup(PassRefPtr<EventListener>); - EventListener* onmousedown() const; - void setOnmousedown(PassRefPtr<EventListener>); - EventListener* onmousemove() const; - void setOnmousemove(PassRefPtr<EventListener>); - EventListener* onmouseout() const; - void setOnmouseout(PassRefPtr<EventListener>); - EventListener* onmouseover() const; - void setOnmouseover(PassRefPtr<EventListener>); - EventListener* onmouseup() const; - void setOnmouseup(PassRefPtr<EventListener>); - EventListener* onmousewheel() const; - void setOnmousewheel(PassRefPtr<EventListener>); - EventListener* onscroll() const; - void setOnscroll(PassRefPtr<EventListener>); - EventListener* onselect() const; - void setOnselect(PassRefPtr<EventListener>); - EventListener* onsubmit() const; - void setOnsubmit(PassRefPtr<EventListener>); - - // WebKit extensions - EventListener* onbeforecut() const; - void setOnbeforecut(PassRefPtr<EventListener>); - EventListener* oncut() const; - void setOncut(PassRefPtr<EventListener>); - EventListener* onbeforecopy() const; - void setOnbeforecopy(PassRefPtr<EventListener>); - EventListener* oncopy() const; - void setOncopy(PassRefPtr<EventListener>); - EventListener* onbeforepaste() const; - void setOnbeforepaste(PassRefPtr<EventListener>); - EventListener* onpaste() const; - void setOnpaste(PassRefPtr<EventListener>); - EventListener* onreset() const; - void setOnreset(PassRefPtr<EventListener>); - EventListener* onsearch() const; - void setOnsearch(PassRefPtr<EventListener>); - EventListener* onselectstart() const; - void setOnselectstart(PassRefPtr<EventListener>); - using TreeShared<Node>::ref; using TreeShared<Node>::deref; + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); + protected: // CreateElementZeroRefCount is deprecated and can be removed once we convert all element // classes to start with a reference count of 1. diff --git a/src/3rdparty/webkit/WebCore/dom/Node.idl b/src/3rdparty/webkit/WebCore/dom/Node.idl index 1e31aea..45ea132 100644 --- a/src/3rdparty/webkit/WebCore/dom/Node.idl +++ b/src/3rdparty/webkit/WebCore/dom/Node.idl @@ -24,6 +24,7 @@ module core { CustomMarkFunction, CustomPushEventHandlerScope, CustomToJS, + EventTarget, GenerateConstructor, GenerateNativeConverter, InlineGetOwnPropertySlot, diff --git a/src/3rdparty/webkit/WebCore/dom/NodeRareData.h b/src/3rdparty/webkit/WebCore/dom/NodeRareData.h index 7740344..8b9e1bf 100644 --- a/src/3rdparty/webkit/WebCore/dom/NodeRareData.h +++ b/src/3rdparty/webkit/WebCore/dom/NodeRareData.h @@ -93,12 +93,12 @@ public: void setTabIndexExplicitly(short index) { m_tabIndex = index; m_tabIndexWasSetExplicitly = true; } bool tabIndexSetExplicitly() const { return m_tabIndexWasSetExplicitly; } - RegisteredEventListenerVector* listeners() { return m_eventListeners.get(); } - RegisteredEventListenerVector& ensureListeners() + EventTargetData* eventTargetData() { return m_eventTargetData.get(); } + EventTargetData* ensureEventTargetData() { - if (!m_eventListeners) - m_eventListeners.set(new RegisteredEventListenerVector); - return *m_eventListeners; + if (!m_eventTargetData) + m_eventTargetData.set(new EventTargetData); + return m_eventTargetData.get(); } bool isFocused() const { return m_isFocused; } @@ -111,7 +111,7 @@ protected: private: OwnPtr<NodeListsNodeData> m_nodeLists; - OwnPtr<RegisteredEventListenerVector > m_eventListeners; + OwnPtr<EventTargetData> m_eventTargetData; short m_tabIndex; bool m_tabIndexWasSetExplicitly : 1; bool m_isFocused : 1; diff --git a/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.cpp b/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.cpp index f257e56..e8bc594 100644 --- a/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.cpp +++ b/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.cpp @@ -27,12 +27,4 @@ namespace WebCore { -RegisteredEventListener::RegisteredEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) - : m_eventType(eventType) - , m_listener(listener) - , m_useCapture(useCapture) - , m_removed(false) -{ -} - } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h b/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h index 034f6c3..88d2279 100644 --- a/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h +++ b/src/3rdparty/webkit/WebCore/dom/RegisteredEventListener.h @@ -29,47 +29,21 @@ namespace WebCore { - class RegisteredEventListener : public RefCounted<RegisteredEventListener> { - public: - static PassRefPtr<RegisteredEventListener> create(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) + struct RegisteredEventListener { + RegisteredEventListener(PassRefPtr<EventListener> listener, bool useCapture) + : listener(listener) + , useCapture(useCapture) { - return adoptRef(new RegisteredEventListener(eventType, listener, useCapture)); } - const AtomicString& eventType() const { return m_eventType; } - EventListener* listener() const { return m_listener.get(); } - bool useCapture() const { return m_useCapture; } - - bool removed() const { return m_removed; } - void setRemoved(bool removed) { m_removed = removed; } - - private: - RegisteredEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - - AtomicString m_eventType; - RefPtr<EventListener> m_listener; - bool m_useCapture; - bool m_removed; + RefPtr<EventListener> listener; + bool useCapture; }; - - typedef Vector<RefPtr<RegisteredEventListener> > RegisteredEventListenerVector; - -#if USE(JSC) - inline void markEventListeners(JSC::MarkStack& markStack, const RegisteredEventListenerVector& listeners) - { - for (size_t i = 0; i < listeners.size(); ++i) - listeners[i]->listener()->markJSFunction(markStack); - } - - inline void invalidateEventListeners(const RegisteredEventListenerVector& listeners) + + inline bool operator==(const RegisteredEventListener& a, const RegisteredEventListener& b) { - // For efficiency's sake, we just set the "removed" bit, instead of - // actually removing the event listener. The node that owns these - // listeners is about to be deleted, anyway. - for (size_t i = 0; i < listeners.size(); ++i) - listeners[i]->setRemoved(true); + return *a.listener == *b.listener && a.useCapture == b.useCapture; } -#endif } // namespace WebCore |