/* * 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 * * 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 #if ENABLE(DOM_STORAGE) #include "StorageEvent.h" #endif #if ENABLE(SVG) #include "SVGElementInstance.h" #include "SVGUseElement.h" #endif namespace WebCore { static HashSet* 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 shadow tree, never cause any updates! if (referenceNode->shadowTreeRootNode()) return; // We're possibly (a child of) an element that is referenced by a 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(node)); break; } #endif } void EventTargetNode::addEventListener(const AtomicString& eventType, PassRefPtr 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(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 e, ExceptionCode& ec) { RefPtr evt(e); ASSERT(!eventDispatchForbidden()); if (!evt || evt->type().isEmpty()) { ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; return false; } evt->setTarget(eventTargetRespectingSVGTargetRules(this)); RefPtr view = document()->view(); return dispatchGenericEvent(evt.release(), ec); } bool EventTargetNode::dispatchGenericEvent(PassRefPtr prpEvent, ExceptionCode& ec) { RefPtr 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 thisNode(this); Vector > ancestors; if (inDocument()) { for (ContainerNode* ancestor = eventParentNode(); ancestor; ancestor = ancestor->eventParentNode()) { #if ENABLE(SVG) // Skip 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(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 e) { ASSERT(!eventDispatchForbidden()); RefPtr evt(e); RefPtr 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 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 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 underlyingEvent) { ASSERT(!eventDispatchForbidden()); ASSERT(eventType == eventNames().DOMFocusInEvent || eventType == eventNames().DOMFocusOutEvent || eventType == eventNames().DOMActivateEvent); bool cancelable = eventType == eventNames().DOMActivateEvent; ExceptionCode ec = 0; RefPtr 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::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 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, bool sendMouseEvents, bool showPressedLook) { if (!gNodesDispatchingSimulatedClicks) gNodesDispatchingSimulatedClicks = new HashSet; 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 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 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 relatedTarget = (relatedTargetArg && relatedTargetArg->isEventTargetNode()) ? static_cast(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 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 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 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 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(event)); } else if (eventType == eventNames().clickEvent) { int detail = event->isUIEvent() ? static_cast(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(event)); } } EventListener* EventTargetNode::onabort() const { return inlineEventListenerForType(eventNames().abortEvent); } void EventTargetNode::setOnabort(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().abortEvent, eventListener); } EventListener* EventTargetNode::onblur() const { return inlineEventListenerForType(eventNames().blurEvent); } void EventTargetNode::setOnblur(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().blurEvent, eventListener); } EventListener* EventTargetNode::onchange() const { return inlineEventListenerForType(eventNames().changeEvent); } void EventTargetNode::setOnchange(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().changeEvent, eventListener); } EventListener* EventTargetNode::onclick() const { return inlineEventListenerForType(eventNames().clickEvent); } void EventTargetNode::setOnclick(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().clickEvent, eventListener); } EventListener* EventTargetNode::oncontextmenu() const { return inlineEventListenerForType(eventNames().contextmenuEvent); } void EventTargetNode::setOncontextmenu(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().contextmenuEvent, eventListener); } EventListener* EventTargetNode::ondblclick() const { return inlineEventListenerForType(eventNames().dblclickEvent); } void EventTargetNode::setOndblclick(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().dblclickEvent, eventListener); } EventListener* EventTargetNode::onerror() const { return inlineEventListenerForType(eventNames().errorEvent); } void EventTargetNode::setOnerror(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().errorEvent, eventListener); } EventListener* EventTargetNode::onfocus() const { return inlineEventListenerForType(eventNames().focusEvent); } void EventTargetNode::setOnfocus(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().focusEvent, eventListener); } EventListener* EventTargetNode::oninput() const { return inlineEventListenerForType(eventNames().inputEvent); } void EventTargetNode::setOninput(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().inputEvent, eventListener); } EventListener* EventTargetNode::onkeydown() const { return inlineEventListenerForType(eventNames().keydownEvent); } void EventTargetNode::setOnkeydown(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().keydownEvent, eventListener); } EventListener* EventTargetNode::onkeypress() const { return inlineEventListenerForType(eventNames().keypressEvent); } void EventTargetNode::setOnkeypress(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().keypressEvent, eventListener); } EventListener* EventTargetNode::onkeyup() const { return inlineEventListenerForType(eventNames().keyupEvent); } void EventTargetNode::setOnkeyup(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().keyupEvent, eventListener); } EventListener* EventTargetNode::onload() const { return inlineEventListenerForType(eventNames().loadEvent); } void EventTargetNode::setOnload(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().loadEvent, eventListener); } EventListener* EventTargetNode::onmousedown() const { return inlineEventListenerForType(eventNames().mousedownEvent); } void EventTargetNode::setOnmousedown(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().mousedownEvent, eventListener); } EventListener* EventTargetNode::onmousemove() const { return inlineEventListenerForType(eventNames().mousemoveEvent); } void EventTargetNode::setOnmousemove(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().mousemoveEvent, eventListener); } EventListener* EventTargetNode::onmouseout() const { return inlineEventListenerForType(eventNames().mouseoutEvent); } void EventTargetNode::setOnmouseout(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().mouseoutEvent, eventListener); } EventListener* EventTargetNode::onmouseover() const { return inlineEventListenerForType(eventNames().mouseoverEvent); } void EventTargetNode::setOnmouseover(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().mouseoverEvent, eventListener); } EventListener* EventTargetNode::onmouseup() const { return inlineEventListenerForType(eventNames().mouseupEvent); } void EventTargetNode::setOnmouseup(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().mouseupEvent, eventListener); } EventListener* EventTargetNode::onmousewheel() const { return inlineEventListenerForType(eventNames().mousewheelEvent); } void EventTargetNode::setOnmousewheel(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().mousewheelEvent, eventListener); } EventListener* EventTargetNode::onbeforecut() const { return inlineEventListenerForType(eventNames().beforecutEvent); } void EventTargetNode::setOnbeforecut(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().beforecutEvent, eventListener); } EventListener* EventTargetNode::oncut() const { return inlineEventListenerForType(eventNames().cutEvent); } void EventTargetNode::setOncut(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().cutEvent, eventListener); } EventListener* EventTargetNode::onbeforecopy() const { return inlineEventListenerForType(eventNames().beforecopyEvent); } void EventTargetNode::setOnbeforecopy(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().beforecopyEvent, eventListener); } EventListener* EventTargetNode::oncopy() const { return inlineEventListenerForType(eventNames().copyEvent); } void EventTargetNode::setOncopy(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().copyEvent, eventListener); } EventListener* EventTargetNode::onbeforepaste() const { return inlineEventListenerForType(eventNames().beforepasteEvent); } void EventTargetNode::setOnbeforepaste(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().beforepasteEvent, eventListener); } EventListener* EventTargetNode::onpaste() const { return inlineEventListenerForType(eventNames().pasteEvent); } void EventTargetNode::setOnpaste(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().pasteEvent, eventListener); } EventListener* EventTargetNode::ondragenter() const { return inlineEventListenerForType(eventNames().dragenterEvent); } void EventTargetNode::setOndragenter(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().dragenterEvent, eventListener); } EventListener* EventTargetNode::ondragover() const { return inlineEventListenerForType(eventNames().dragoverEvent); } void EventTargetNode::setOndragover(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().dragoverEvent, eventListener); } EventListener* EventTargetNode::ondragleave() const { return inlineEventListenerForType(eventNames().dragleaveEvent); } void EventTargetNode::setOndragleave(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().dragleaveEvent, eventListener); } EventListener* EventTargetNode::ondrop() const { return inlineEventListenerForType(eventNames().dropEvent); } void EventTargetNode::setOndrop(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().dropEvent, eventListener); } EventListener* EventTargetNode::ondragstart() const { return inlineEventListenerForType(eventNames().dragstartEvent); } void EventTargetNode::setOndragstart(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().dragstartEvent, eventListener); } EventListener* EventTargetNode::ondrag() const { return inlineEventListenerForType(eventNames().dragEvent); } void EventTargetNode::setOndrag(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().dragEvent, eventListener); } EventListener* EventTargetNode::ondragend() const { return inlineEventListenerForType(eventNames().dragendEvent); } void EventTargetNode::setOndragend(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().dragendEvent, eventListener); } EventListener* EventTargetNode::onreset() const { return inlineEventListenerForType(eventNames().resetEvent); } void EventTargetNode::setOnreset(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().resetEvent, eventListener); } EventListener* EventTargetNode::onresize() const { return inlineEventListenerForType(eventNames().resizeEvent); } void EventTargetNode::setOnresize(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().resizeEvent, eventListener); } EventListener* EventTargetNode::onscroll() const { return inlineEventListenerForType(eventNames().scrollEvent); } void EventTargetNode::setOnscroll(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().scrollEvent, eventListener); } EventListener* EventTargetNode::onsearch() const { return inlineEventListenerForType(eventNames().searchEvent); } void EventTargetNode::setOnsearch(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().searchEvent, eventListener); } EventListener* EventTargetNode::onselect() const { return inlineEventListenerForType(eventNames().selectEvent); } void EventTargetNode::setOnselect(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().selectEvent, eventListener); } EventListener* EventTargetNode::onselectstart() const { return inlineEventListenerForType(eventNames().selectstartEvent); } void EventTargetNode::setOnselectstart(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().selectstartEvent, eventListener); } EventListener* EventTargetNode::onsubmit() const { return inlineEventListenerForType(eventNames().submitEvent); } void EventTargetNode::setOnsubmit(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().submitEvent, eventListener); } EventListener* EventTargetNode::onunload() const { return inlineEventListenerForType(eventNames().unloadEvent); } void EventTargetNode::setOnunload(PassRefPtr eventListener) { setInlineEventListenerForType(eventNames().unloadEvent, eventListener); } } // namespace WebCore