diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/dom/EventTargetNode.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/dom/EventTargetNode.cpp | 1166 |
1 files changed, 0 insertions, 1166 deletions
diff --git a/src/3rdparty/webkit/WebCore/dom/EventTargetNode.cpp b/src/3rdparty/webkit/WebCore/dom/EventTargetNode.cpp deleted file mode 100644 index 8553da7..0000000 --- a/src/3rdparty/webkit/WebCore/dom/EventTargetNode.cpp +++ /dev/null @@ -1,1166 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2001 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "EventTargetNode.h" - -#include "Document.h" -#include "EventException.h" -#include "EventHandler.h" -#include "EventListener.h" -#include "EventNames.h" -#include "Frame.h" -#include "FrameView.h" -#include "KeyboardEvent.h" -#include "MouseEvent.h" -#include "MutationEvent.h" -#include "NodeRareData.h" -#include "Page.h" -#include "PlatformMouseEvent.h" -#include "PlatformWheelEvent.h" -#include "ProgressEvent.h" -#include "RegisteredEventListener.h" -#include "ScriptController.h" -#include "TextEvent.h" -#include "WebKitAnimationEvent.h" -#include "WebKitTransitionEvent.h" -#include "WheelEvent.h" -#include <wtf/HashSet.h> - -#if ENABLE(DOM_STORAGE) -#include "StorageEvent.h" -#endif - -#if ENABLE(SVG) -#include "SVGElementInstance.h" -#include "SVGUseElement.h" -#endif - -namespace WebCore { - -static HashSet<EventTargetNode*>* gNodesDispatchingSimulatedClicks = 0; - -EventTargetNode::EventTargetNode(Document* doc, bool isElement, bool isContainer) - : Node(doc, isElement, isContainer) -{ -} - -EventTargetNode::~EventTargetNode() -{ - if (!eventListeners().isEmpty() && !inDocument()) - document()->unregisterDisconnectedNodeWithEventListeners(this); -} - -ScriptExecutionContext* EventTargetNode::scriptExecutionContext() const -{ - return document(); -} - -const RegisteredEventListenerVector& EventTargetNode::eventListeners() const -{ - if (hasRareData()) { - if (RegisteredEventListenerVector* listeners = rareData()->listeners()) - return *listeners; - } - static const RegisteredEventListenerVector* emptyListenersVector = new RegisteredEventListenerVector; - return *emptyListenersVector; -} - -void EventTargetNode::insertedIntoDocument() -{ - if (!eventListeners().isEmpty()) - document()->unregisterDisconnectedNodeWithEventListeners(this); - - Node::insertedIntoDocument(); -} - -void EventTargetNode::removedFromDocument() -{ - if (!eventListeners().isEmpty()) - document()->registerDisconnectedNodeWithEventListeners(this); - - Node::removedFromDocument(); -} - -void EventTargetNode::willMoveToNewOwnerDocument() -{ - if (!eventListeners().isEmpty()) - document()->unregisterDisconnectedNodeWithEventListeners(this); - - Node::willMoveToNewOwnerDocument(); -} - -void EventTargetNode::didMoveToNewOwnerDocument() -{ - if (!eventListeners().isEmpty()) - document()->registerDisconnectedNodeWithEventListeners(this); - - Node::didMoveToNewOwnerDocument(); -} - -static inline void updateSVGElementInstancesAfterEventListenerChange(EventTargetNode* referenceNode) -{ - ASSERT(referenceNode); - -#if ENABLE(SVG) - if (!referenceNode->isSVGElement()) - return; - - // Elements living inside a <use> shadow tree, never cause any updates! - if (referenceNode->shadowTreeRootNode()) - return; - - // We're possibly (a child of) an element that is referenced by a <use> client - // If an event listeners changes on a referenced element, update all instances. - for (Node* node = referenceNode; node; node = node->parentNode()) { - if (!node->hasID() || !node->isSVGElement()) - continue; - - SVGElementInstance::invalidateAllInstancesOfElement(static_cast<SVGElement*>(node)); - break; - } -#endif -} - -void EventTargetNode::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) -{ - Document* document = this->document(); - if (!document->attached()) - return; - - 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); - - // adding the first one - if (listeners.isEmpty() && !inDocument()) - document->registerDisconnectedNodeWithEventListeners(this); - - listeners.append(RegisteredEventListener::create(eventType, listener, useCapture)); - updateSVGElementInstancesAfterEventListenerChange(this); -} - -void EventTargetNode::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.listener() == listener && r.useCapture() == useCapture) { - r.setRemoved(true); - listeners->remove(i); - - // removed last - if (listeners->isEmpty() && !inDocument()) - document()->unregisterDisconnectedNodeWithEventListeners(this); - - updateSVGElementInstancesAfterEventListenerChange(this); - return; - } - } -} - -void EventTargetNode::removeAllEventListeners() -{ - if (!hasRareData()) - return; - - RegisteredEventListenerVector* listeners = rareData()->listeners(); - if (!listeners) - return; - - size_t size = listeners->size(); - for (size_t i = 0; i < size; ++i) - listeners->at(i)->setRemoved(true); - listeners->clear(); -} - -void EventTargetNode::handleLocalEvents(Event* event, bool useCapture) -{ - 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); - } -} - -#if ENABLE(SVG) -static inline SVGElementInstance* eventTargetAsSVGElementInstance(EventTargetNode* referenceNode) -{ - ASSERT(referenceNode); - if (!referenceNode->isSVGElement()) - return 0; - - // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included - // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects - for (Node* n = referenceNode; n; n = n->parentNode()) { - if (!n->isShadowNode() || !n->isSVGElement()) - continue; - - Node* shadowTreeParentElement = n->shadowParentNode(); - ASSERT(shadowTreeParentElement->hasTagName(SVGNames::useTag)); - - if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode)) - return instance; - } - - return 0; -} -#endif - -static inline EventTarget* eventTargetRespectingSVGTargetRules(EventTargetNode* referenceNode) -{ - ASSERT(referenceNode); - -#if ENABLE(SVG) - if (SVGElementInstance* instance = eventTargetAsSVGElementInstance(referenceNode)) { - ASSERT(instance->shadowTreeElement() == referenceNode); - return instance; - } -#endif - - return referenceNode; -} - -bool EventTargetNode::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec) -{ - RefPtr<Event> evt(e); - ASSERT(!eventDispatchForbidden()); - if (!evt || evt->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return false; - } - - evt->setTarget(eventTargetRespectingSVGTargetRules(this)); - - RefPtr<FrameView> view = document()->view(); - return dispatchGenericEvent(evt.release(), ec); -} - -bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> prpEvent, ExceptionCode& ec) -{ - RefPtr<Event> event(prpEvent); - - ASSERT(!eventDispatchForbidden()); - ASSERT(event->target()); - ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null. - - // Make a vector of ancestors to send the event to. - // If the node is not in a document just send the event to it. - // Be sure to ref all of nodes since event handlers could result in the last reference going away. - RefPtr<EventTargetNode> thisNode(this); - Vector<RefPtr<ContainerNode> > ancestors; - if (inDocument()) { - for (ContainerNode* ancestor = eventParentNode(); ancestor; ancestor = ancestor->eventParentNode()) { -#if ENABLE(SVG) - // Skip <use> shadow tree elements. - if (ancestor->isSVGElement() && ancestor->isShadowNode()) - continue; -#endif - ancestors.append(ancestor); - } - } - - // Set up a pointer to indicate whether to dispatch window events. - // We don't dispatch load events to the window. That quirk was originally - // added because Mozilla doesn't propagate load events to the window object. - Document* documentForWindowEvents = 0; - if (event->type() != eventNames().loadEvent) { - EventTargetNode* topLevelContainer = ancestors.isEmpty() ? this : ancestors.last().get(); - if (topLevelContainer->isDocumentNode()) - documentForWindowEvents = static_cast<Document*>(topLevelContainer); - } - - // Give the target node a chance to do some work before DOM event handlers get a crack. - void* data = preDispatchEventHandler(event.get()); - if (event->propagationStopped()) - goto doneDispatching; - - // Trigger capturing event handlers, starting at the top and working our way down. - event->setEventPhase(Event::CAPTURING_PHASE); - - if (documentForWindowEvents) { - event->setCurrentTarget(documentForWindowEvents); - documentForWindowEvents->handleWindowEvent(event.get(), true); - 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); - 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); - if (event->propagationStopped()) - goto doneDispatching; - - if (event->bubbles() && !event->cancelBubble()) { - // Trigger bubbling event handlers, starting at the bottom and working our way up. - event->setEventPhase(Event::BUBBLING_PHASE); - - size_t size = ancestors.size(); - for (size_t i = 0; i < size; ++i) { - ContainerNode* ancestor = ancestors[i].get(); - event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor)); - ancestor->handleLocalEvents(event.get(), false); - if (event->propagationStopped() || event->cancelBubble()) - goto doneDispatching; - } - if (documentForWindowEvents) { - event->setCurrentTarget(documentForWindowEvents); - documentForWindowEvents->handleWindowEvent(event.get(), false); - if (event->propagationStopped() || event->cancelBubble()) - goto doneDispatching; - } - } - -doneDispatching: - event->setCurrentTarget(0); - event->setEventPhase(0); - - // Pass the data from the preDispatchEventHandler to the postDispatchEventHandler. - postDispatchEventHandler(event.get(), data); - - // Call default event handlers. While the DOM does have a concept of preventing - // default handling, the detail of which handlers are called is an internal - // implementation detail and not part of the DOM. - if (!event->defaultPrevented() && !event->defaultHandled()) { - // Non-bubbling events call only one default event handler, the one for the target. - defaultEventHandler(event.get()); - ASSERT(!event->defaultPrevented()); - if (event->defaultHandled()) - goto doneWithDefault; - // For bubbling events, call default event handlers on the same targets in the - // same order as the bubbling phase. - if (event->bubbles()) { - size_t size = ancestors.size(); - for (size_t i = 0; i < size; ++i) { - ContainerNode* ancestor = ancestors[i].get(); - ancestor->defaultEventHandler(event.get()); - ASSERT(!event->defaultPrevented()); - if (event->defaultHandled()) - goto doneWithDefault; - } - } - } - -doneWithDefault: - Document::updateDocumentsRendering(); - - return !event->defaultPrevented(); -} - -bool EventTargetNode::dispatchSubtreeModifiedEvent() -{ - ASSERT(!eventDispatchForbidden()); - - document()->incDOMTreeVersion(); - - notifyNodeListsAttributeChanged(); // FIXME: Can do better some day. Really only care about the name attribute changing. - - if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER)) - return false; - ExceptionCode ec = 0; - return dispatchEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true, false, 0, String(), String(), String(), 0), ec); -} - -void EventTargetNode::dispatchWindowEvent(PassRefPtr<Event> e) -{ - ASSERT(!eventDispatchForbidden()); - RefPtr<Event> evt(e); - RefPtr<Document> doc = document(); - evt->setTarget(doc); - doc->handleWindowEvent(evt.get(), true); - doc->handleWindowEvent(evt.get(), false); -} - -void EventTargetNode::dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg) -{ - ASSERT(!eventDispatchForbidden()); - RefPtr<Document> doc = document(); - dispatchWindowEvent(Event::create(eventType, canBubbleArg, cancelableArg)); - - if (eventType == eventNames().loadEvent) { - // For onload events, send a separate load event to the enclosing frame only. - // This is a DOM extension and is independent of bubbling/capturing rules of - // the DOM. - Element* ownerElement = doc->ownerElement(); - if (ownerElement) { - RefPtr<Event> ownerEvent = Event::create(eventType, false, cancelableArg); - ownerEvent->setTarget(ownerElement); - ExceptionCode ec = 0; - ownerElement->dispatchGenericEvent(ownerEvent.release(), ec); - } - } -} - -bool EventTargetNode::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent) -{ - ASSERT(!eventDispatchForbidden()); - ASSERT(eventType == eventNames().DOMFocusInEvent || eventType == eventNames().DOMFocusOutEvent || eventType == eventNames().DOMActivateEvent); - - bool cancelable = eventType == eventNames().DOMActivateEvent; - - ExceptionCode ec = 0; - RefPtr<UIEvent> evt = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail); - evt->setUnderlyingEvent(underlyingEvent); - return dispatchEvent(evt.release(), ec); -} - -bool EventTargetNode::dispatchKeyEvent(const PlatformKeyboardEvent& key) -{ - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; - RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, document()->defaultView()); - bool r = dispatchEvent(keyboardEvent, ec); - - // 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 - // let it get handled by AppKit - if (keyboardEvent->defaultHandled()) - r = false; - - return r; -} - -bool EventTargetNode::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType, - int detail, Node* relatedTarget) -{ - ASSERT(!eventDispatchForbidden()); - - IntPoint contentsPos; - if (FrameView* view = document()->view()) - contentsPos = view->windowToContents(event.pos()); - - short button = event.button(); - - ASSERT(event.eventType() == MouseEventMoved || button != NoButton); - - return dispatchMouseEvent(eventType, button, detail, - contentsPos.x(), contentsPos.y(), event.globalX(), event.globalY(), - event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), - false, relatedTarget); -} - -void EventTargetNode::dispatchSimulatedMouseEvent(const AtomicString& eventType, - PassRefPtr<Event> underlyingEvent) -{ - ASSERT(!eventDispatchForbidden()); - - bool ctrlKey = false; - bool altKey = false; - bool shiftKey = false; - bool metaKey = false; - if (UIEventWithKeyState* keyStateEvent = findEventWithKeyState(underlyingEvent.get())) { - ctrlKey = keyStateEvent->ctrlKey(); - altKey = keyStateEvent->altKey(); - shiftKey = keyStateEvent->shiftKey(); - metaKey = keyStateEvent->metaKey(); - } - - // Like Gecko, we just pass 0 for everything when we make a fake mouse event. - // Internet Explorer instead gives the current mouse position and state. - dispatchMouseEvent(eventType, 0, 0, 0, 0, 0, 0, - ctrlKey, altKey, shiftKey, metaKey, true, 0, underlyingEvent); -} - -void EventTargetNode::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook) -{ - if (!gNodesDispatchingSimulatedClicks) - gNodesDispatchingSimulatedClicks = new HashSet<EventTargetNode*>; - else if (gNodesDispatchingSimulatedClicks->contains(this)) - return; - - gNodesDispatchingSimulatedClicks->add(this); - - // send mousedown and mouseup before the click, if requested - if (sendMouseEvents) - dispatchSimulatedMouseEvent(eventNames().mousedownEvent, event.get()); - setActive(true, showPressedLook); - if (sendMouseEvents) - dispatchSimulatedMouseEvent(eventNames().mouseupEvent, event.get()); - setActive(false); - - // always send click - dispatchSimulatedMouseEvent(eventNames().clickEvent, event); - - gNodesDispatchingSimulatedClicks->remove(this); -} - -bool EventTargetNode::dispatchMouseEvent(const AtomicString& eventType, int button, int detail, - int pageX, int pageY, int screenX, int screenY, - bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, - bool isSimulated, Node* relatedTargetArg, PassRefPtr<Event> underlyingEvent) -{ - ASSERT(!eventDispatchForbidden()); - if (disabled()) // Don't even send DOM events for disabled controls.. - return true; - - if (eventType.isEmpty()) - return false; // Shouldn't happen. - - // Dispatching the first event can easily result in this node being destroyed. - // Since we dispatch up to three events here, we need to make sure we're referenced - // so the pointer will be good for the two subsequent ones. - RefPtr<Node> protect(this); - - 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. - RefPtr<EventTargetNode> relatedTarget = (relatedTargetArg && relatedTargetArg->isEventTargetNode()) - ? static_cast<EventTargetNode*>(relatedTargetArg) : 0; - - if (Frame* frame = document()->frame()) { - float pageZoom = frame->pageZoomFactor(); - if (pageZoom != 1.0f) { - // Adjust our pageX and pageY to account for the page zoom. - pageX = lroundf(pageX / pageZoom); - pageY = lroundf(pageY / pageZoom); - } - } - - RefPtr<Event> mouseEvent = MouseEvent::create(eventType, - true, cancelable, document()->defaultView(), - detail, screenX, screenY, pageX, pageY, - ctrlKey, altKey, shiftKey, metaKey, button, - relatedTarget, 0, isSimulated); - mouseEvent->setUnderlyingEvent(underlyingEvent.get()); - - dispatchEvent(mouseEvent, ec); - bool defaultHandled = mouseEvent->defaultHandled(); - bool defaultPrevented = mouseEvent->defaultPrevented(); - if (defaultHandled || defaultPrevented) - swallowEvent = true; - - // Special case: If it's a double click event, we also send the dblclick event. This is not part - // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated - // as a separate event in other DOM-compliant browsers like Firefox, and so we do the same. - if (eventType == eventNames().clickEvent && detail == 2) { - RefPtr<Event> doubleClickEvent = MouseEvent::create(eventNames().dblclickEvent, - true, cancelable, document()->defaultView(), - detail, screenX, screenY, pageX, pageY, - ctrlKey, altKey, shiftKey, metaKey, button, - relatedTarget, 0, isSimulated); - doubleClickEvent->setUnderlyingEvent(underlyingEvent.get()); - if (defaultHandled) - doubleClickEvent->setDefaultHandled(); - dispatchEvent(doubleClickEvent, ec); - if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented()) - swallowEvent = true; - } - - return swallowEvent; -} - -void EventTargetNode::dispatchWheelEvent(PlatformWheelEvent& e) -{ - ASSERT(!eventDispatchForbidden()); - if (e.deltaX() == 0 && e.deltaY() == 0) - return; - - FrameView* view = document()->view(); - if (!view) - return; - - IntPoint pos = view->windowToContents(e.pos()); - - // Convert the deltas from pixels to lines if we have a pixel scroll event. - float deltaX = e.deltaX(); - float deltaY = e.deltaY(); - - // FIXME: Should we do anything with a ScrollByPageWheelEvent here? - // It will be treated like a line scroll of 1 right now. - if (e.granularity() == ScrollByPixelWheelEvent) { - deltaX /= cMouseWheelPixelsPerLineStep; - deltaY /= cMouseWheelPixelsPerLineStep; - } - - RefPtr<WheelEvent> we = WheelEvent::create(e.deltaX(), e.deltaY(), - document()->defaultView(), e.globalX(), e.globalY(), pos.x(), pos.y(), - e.ctrlKey(), e.altKey(), e.shiftKey(), e.metaKey()); - ExceptionCode ec = 0; - if (!dispatchEvent(we.release(), ec)) - e.accept(); -} - -bool EventTargetNode::dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime) -{ - ASSERT(!eventDispatchForbidden()); - - ExceptionCode ec = 0; - return dispatchEvent(WebKitAnimationEvent::create(eventType, animationName, elapsedTime), ec); -} - -bool EventTargetNode::dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime) -{ - ASSERT(!eventDispatchForbidden()); - - ExceptionCode ec = 0; - return dispatchEvent(WebKitTransitionEvent::create(eventType, propertyName, elapsedTime), ec); -} - -void EventTargetNode::dispatchFocusEvent() -{ - dispatchEventForType(eventNames().focusEvent, false, false); -} - -void EventTargetNode::dispatchBlurEvent() -{ - dispatchEventForType(eventNames().blurEvent, false, false); -} - -bool EventTargetNode::dispatchEventForType(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg) -{ - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; - return dispatchEvent(Event::create(eventType, canBubbleArg, cancelableArg), ec); -} - -bool EventTargetNode::dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg) -{ - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; - return dispatchEvent(ProgressEvent::create(eventType, lengthComputableArg, loadedArg, totalArg), ec); -} - -void EventTargetNode::dispatchStorageEvent(const AtomicString &eventType, const String& key, const String& oldValue, const String& newValue, Frame* source) -{ -#if ENABLE(DOM_STORAGE) - ASSERT(!eventDispatchForbidden()); - ExceptionCode ec = 0; - dispatchEvent(StorageEvent::create(eventType, key, oldValue, newValue, source->document()->documentURI(), source->domWindow()), ec); -#endif -} - -void EventTargetNode::removeInlineEventListenerForType(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()->isInline()) - continue; - - r.setRemoved(true); - listeners->remove(i); - - // removed last - if (listeners->isEmpty() && !inDocument()) - document()->unregisterDisconnectedNodeWithEventListeners(this); - - updateSVGElementInstancesAfterEventListenerChange(this); - return; - } -} - -void EventTargetNode::setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener> listener) -{ - // In case we are the only one holding a reference to it, we don't want removeInlineEventListenerForType to destroy it. - removeInlineEventListenerForType(eventType); - if (listener) - addEventListener(eventType, listener, false); -} - -void EventTargetNode::setInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute* attr) -{ - setInlineEventListenerForType(eventType, document()->createEventListener(attr->localName().string(), attr->value(), this)); -} - -EventListener* EventTargetNode::inlineEventListenerForType(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()->isInline()) - return r.listener(); - } - return 0; -} - -bool EventTargetNode::disabled() const -{ - return false; -} - -void EventTargetNode::defaultEventHandler(Event* event) -{ - if (event->target() != this) - return; - const AtomicString& eventType = event->type(); - if (eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent) { - if (event->isKeyboardEvent()) - if (Frame* frame = document()->frame()) - frame->eventHandler()->defaultKeyboardEventHandler(static_cast<KeyboardEvent*>(event)); - } else if (eventType == eventNames().clickEvent) { - int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0; - dispatchUIEvent(eventNames().DOMActivateEvent, detail, event); - } else if (eventType == eventNames().contextmenuEvent) { - if (Frame* frame = document()->frame()) - if (Page* page = frame->page()) - page->contextMenuController()->handleContextMenuEvent(event); - } else if (eventType == eventNames().textInputEvent) { - if (event->isTextEvent()) - if (Frame* frame = document()->frame()) - frame->eventHandler()->defaultTextInputEventHandler(static_cast<TextEvent*>(event)); - } -} - -EventListener* EventTargetNode::onabort() const -{ - return inlineEventListenerForType(eventNames().abortEvent); -} - -void EventTargetNode::setOnabort(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().abortEvent, eventListener); -} - -EventListener* EventTargetNode::onblur() const -{ - return inlineEventListenerForType(eventNames().blurEvent); -} - -void EventTargetNode::setOnblur(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().blurEvent, eventListener); -} - -EventListener* EventTargetNode::onchange() const -{ - return inlineEventListenerForType(eventNames().changeEvent); -} - -void EventTargetNode::setOnchange(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().changeEvent, eventListener); -} - -EventListener* EventTargetNode::onclick() const -{ - return inlineEventListenerForType(eventNames().clickEvent); -} - -void EventTargetNode::setOnclick(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().clickEvent, eventListener); -} - -EventListener* EventTargetNode::oncontextmenu() const -{ - return inlineEventListenerForType(eventNames().contextmenuEvent); -} - -void EventTargetNode::setOncontextmenu(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().contextmenuEvent, eventListener); -} - -EventListener* EventTargetNode::ondblclick() const -{ - return inlineEventListenerForType(eventNames().dblclickEvent); -} - -void EventTargetNode::setOndblclick(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().dblclickEvent, eventListener); -} - -EventListener* EventTargetNode::onerror() const -{ - return inlineEventListenerForType(eventNames().errorEvent); -} - -void EventTargetNode::setOnerror(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().errorEvent, eventListener); -} - -EventListener* EventTargetNode::onfocus() const -{ - return inlineEventListenerForType(eventNames().focusEvent); -} - -void EventTargetNode::setOnfocus(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().focusEvent, eventListener); -} - -EventListener* EventTargetNode::oninput() const -{ - return inlineEventListenerForType(eventNames().inputEvent); -} - -void EventTargetNode::setOninput(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().inputEvent, eventListener); -} - -EventListener* EventTargetNode::onkeydown() const -{ - return inlineEventListenerForType(eventNames().keydownEvent); -} - -void EventTargetNode::setOnkeydown(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().keydownEvent, eventListener); -} - -EventListener* EventTargetNode::onkeypress() const -{ - return inlineEventListenerForType(eventNames().keypressEvent); -} - -void EventTargetNode::setOnkeypress(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().keypressEvent, eventListener); -} - -EventListener* EventTargetNode::onkeyup() const -{ - return inlineEventListenerForType(eventNames().keyupEvent); -} - -void EventTargetNode::setOnkeyup(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().keyupEvent, eventListener); -} - -EventListener* EventTargetNode::onload() const -{ - return inlineEventListenerForType(eventNames().loadEvent); -} - -void EventTargetNode::setOnload(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().loadEvent, eventListener); -} - -EventListener* EventTargetNode::onmousedown() const -{ - return inlineEventListenerForType(eventNames().mousedownEvent); -} - -void EventTargetNode::setOnmousedown(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().mousedownEvent, eventListener); -} - -EventListener* EventTargetNode::onmousemove() const -{ - return inlineEventListenerForType(eventNames().mousemoveEvent); -} - -void EventTargetNode::setOnmousemove(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().mousemoveEvent, eventListener); -} - -EventListener* EventTargetNode::onmouseout() const -{ - return inlineEventListenerForType(eventNames().mouseoutEvent); -} - -void EventTargetNode::setOnmouseout(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().mouseoutEvent, eventListener); -} - -EventListener* EventTargetNode::onmouseover() const -{ - return inlineEventListenerForType(eventNames().mouseoverEvent); -} - -void EventTargetNode::setOnmouseover(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().mouseoverEvent, eventListener); -} - -EventListener* EventTargetNode::onmouseup() const -{ - return inlineEventListenerForType(eventNames().mouseupEvent); -} - -void EventTargetNode::setOnmouseup(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().mouseupEvent, eventListener); -} - -EventListener* EventTargetNode::onmousewheel() const -{ - return inlineEventListenerForType(eventNames().mousewheelEvent); -} - -void EventTargetNode::setOnmousewheel(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().mousewheelEvent, eventListener); -} - -EventListener* EventTargetNode::onbeforecut() const -{ - return inlineEventListenerForType(eventNames().beforecutEvent); -} - -void EventTargetNode::setOnbeforecut(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().beforecutEvent, eventListener); -} - -EventListener* EventTargetNode::oncut() const -{ - return inlineEventListenerForType(eventNames().cutEvent); -} - -void EventTargetNode::setOncut(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().cutEvent, eventListener); -} - -EventListener* EventTargetNode::onbeforecopy() const -{ - return inlineEventListenerForType(eventNames().beforecopyEvent); -} - -void EventTargetNode::setOnbeforecopy(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().beforecopyEvent, eventListener); -} - -EventListener* EventTargetNode::oncopy() const -{ - return inlineEventListenerForType(eventNames().copyEvent); -} - -void EventTargetNode::setOncopy(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().copyEvent, eventListener); -} - -EventListener* EventTargetNode::onbeforepaste() const -{ - return inlineEventListenerForType(eventNames().beforepasteEvent); -} - -void EventTargetNode::setOnbeforepaste(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().beforepasteEvent, eventListener); -} - -EventListener* EventTargetNode::onpaste() const -{ - return inlineEventListenerForType(eventNames().pasteEvent); -} - -void EventTargetNode::setOnpaste(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().pasteEvent, eventListener); -} - -EventListener* EventTargetNode::ondragenter() const -{ - return inlineEventListenerForType(eventNames().dragenterEvent); -} - -void EventTargetNode::setOndragenter(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().dragenterEvent, eventListener); -} - -EventListener* EventTargetNode::ondragover() const -{ - return inlineEventListenerForType(eventNames().dragoverEvent); -} - -void EventTargetNode::setOndragover(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().dragoverEvent, eventListener); -} - -EventListener* EventTargetNode::ondragleave() const -{ - return inlineEventListenerForType(eventNames().dragleaveEvent); -} - -void EventTargetNode::setOndragleave(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().dragleaveEvent, eventListener); -} - -EventListener* EventTargetNode::ondrop() const -{ - return inlineEventListenerForType(eventNames().dropEvent); -} - -void EventTargetNode::setOndrop(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().dropEvent, eventListener); -} - -EventListener* EventTargetNode::ondragstart() const -{ - return inlineEventListenerForType(eventNames().dragstartEvent); -} - -void EventTargetNode::setOndragstart(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().dragstartEvent, eventListener); -} - -EventListener* EventTargetNode::ondrag() const -{ - return inlineEventListenerForType(eventNames().dragEvent); -} - -void EventTargetNode::setOndrag(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().dragEvent, eventListener); -} - -EventListener* EventTargetNode::ondragend() const -{ - return inlineEventListenerForType(eventNames().dragendEvent); -} - -void EventTargetNode::setOndragend(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().dragendEvent, eventListener); -} - -EventListener* EventTargetNode::onreset() const -{ - return inlineEventListenerForType(eventNames().resetEvent); -} - -void EventTargetNode::setOnreset(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().resetEvent, eventListener); -} - -EventListener* EventTargetNode::onresize() const -{ - return inlineEventListenerForType(eventNames().resizeEvent); -} - -void EventTargetNode::setOnresize(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().resizeEvent, eventListener); -} - -EventListener* EventTargetNode::onscroll() const -{ - return inlineEventListenerForType(eventNames().scrollEvent); -} - -void EventTargetNode::setOnscroll(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().scrollEvent, eventListener); -} - -EventListener* EventTargetNode::onsearch() const -{ - return inlineEventListenerForType(eventNames().searchEvent); -} - -void EventTargetNode::setOnsearch(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().searchEvent, eventListener); -} - -EventListener* EventTargetNode::onselect() const -{ - return inlineEventListenerForType(eventNames().selectEvent); -} - -void EventTargetNode::setOnselect(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().selectEvent, eventListener); -} - -EventListener* EventTargetNode::onselectstart() const -{ - return inlineEventListenerForType(eventNames().selectstartEvent); -} - -void EventTargetNode::setOnselectstart(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().selectstartEvent, eventListener); -} - -EventListener* EventTargetNode::onsubmit() const -{ - return inlineEventListenerForType(eventNames().submitEvent); -} - -void EventTargetNode::setOnsubmit(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().submitEvent, eventListener); -} - -EventListener* EventTargetNode::onunload() const -{ - return inlineEventListenerForType(eventNames().unloadEvent); -} - -void EventTargetNode::setOnunload(PassRefPtr<EventListener> eventListener) -{ - setInlineEventListenerForType(eventNames().unloadEvent, eventListener); -} - -} // namespace WebCore |