Source/WebCore/ChangeLog

 12011-03-28 Dimitri Glazkov <dglazkov@chromium.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 Move more events to EventDispatcher.
 6 https://bugs.webkit.org/show_bug.cgi?id=57247
 7
 8 No new tests. (OOPS!)
 9
 10 * dom/EventDispatcher.cpp:
 11 (WebCore::eventTargetRespectingSVGTargetRules): Made a static function,
 12 since it's not used anywhere outside of the EventDispatcher.
 13 (WebCore::EventDispatcher::dispatchScopedEvent): Moved from Node.cpp.
 14 (WebCore::EventDispatcher::dispatchKeyEvent): Ditto.
 15 (WebCore::EventDispatcher::dispatchWheelEvent): Ditto.
 16 (WebCore::EventDispatcher::dispatchEvent): Changed to use eventTargetRespectingSVGTargetRules
 17 as a static function.
 18 * dom/EventDispatcher.h: Updated decls.
 19 * dom/Node.cpp:
 20 (WebCore::Node::dispatchScopedEvent): Replaced with calling EventDispatcher.
 21 (WebCore::Node::dispatchKeyEvent): Ditto.
 22 (WebCore::Node::dispatchWheelEvent): Ditto.
 23
1242011-03-28 David Kilzer <ddkilzer@apple.com>
225
326 <http://webkit.org/b/57239> Use forward class declaration instead of including header

Source/WebCore/dom/EventDispatcher.cpp

3131#include "EventTarget.h"
3232#include "FrameView.h"
3333#include "InspectorInstrumentation.h"
 34#include "KeyboardEvent.h"
3435#include "MouseEvent.h"
3536#include "Node.h"
 37#include "PlatformWheelEvent.h"
 38#include "ScopedEventQueue.h"
3639
3740#if ENABLE(SVG)
3841#include "SVGElementInstance.h"

4245
4346#include "UIEvent.h"
4447#include "UIEventWithKeyState.h"
 48#include "WheelEvent.h"
4549#include "WindowEventContext.h"
4650
4751#include <wtf/RefPtr.h>

@@bool EventDispatcher::dispatchEvent(Node* node, PassRefPtr<Event> event)
5660 return dispatcher.dispatchEvent(event);
5761}
5862
 63inline static EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNode)
 64{
 65 ASSERT(referenceNode);
 66
 67#if ENABLE(SVG)
 68 if (!referenceNode->isSVGElement())
 69 return referenceNode;
 70
 71 // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
 72 // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects
 73 for (Node* n = referenceNode; n; n = n->parentNode()) {
 74 if (!n->isShadowRoot() || !n->isSVGElement())
 75 continue;
 76
 77 Element* shadowTreeParentElement = n->shadowHost();
 78 ASSERT(shadowTreeParentElement->hasTagName(SVGNames::useTag));
 79
 80 if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode))
 81 return instance;
 82 }
 83#endif
 84
 85 return referenceNode;
 86}
 87
 88void EventDispatcher::dispatchScopedEvent(Node* node, PassRefPtr<Event> event)
 89{
 90 // We need to set the target here because it can go away by the time we actually fire the event.
 91 event->setTarget(eventTargetRespectingSVGTargetRules(node));
 92
 93 ScopedEventQueue::instance()->enqueueEvent(event);
 94}
 95
 96bool EventDispatcher::dispatchKeyEvent(Node* node, const PlatformKeyboardEvent& key)
 97{
 98 EventDispatcher dispatcher(node);
 99
 100 RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, node->document()->defaultView());
 101 bool r = dispatcher.dispatchEvent(keyboardEvent);
 102
 103 // We want to return false if default is prevented (already taken care of)
 104 // or if the element is default-handled by the DOM. Otherwise we let it just
 105 // let it get handled by AppKit.
 106 if (keyboardEvent->defaultHandled())
 107 r = false;
 108
 109 return r;
 110}
 111
59112bool EventDispatcher::dispatchMouseEvent(Node* node, const PlatformMouseEvent& event, const AtomicString& eventType,
60113 int detail, Node* relatedTarget)
61114{

@@void EventDispatcher::dispatchSimulatedClick(Node* node, PassRefPtr<Event> event
101154 gNodesDispatchingSimulatedClicks->remove(node);
102155}
103156
 157void EventDispatcher::dispatchWheelEvent(Node* node, PlatformWheelEvent& e)
 158{
 159 ASSERT(!eventDispatchForbidden());
 160 if (!(e.deltaX() || e.deltaY()))
 161 return;
 162
 163 EventDispatcher dispatcher(node);
 164
 165 if (!dispatcher.m_view)
 166 return;
 167
 168 IntPoint pos = dispatcher.m_view->windowToContents(e.pos());
 169
 170 int adjustedPageX = pos.x();
 171 int adjustedPageY = pos.y();
 172 if (Frame* frame = node->document()->frame()) {
 173 float pageZoom = frame->pageZoomFactor();
 174 if (pageZoom != 1.0f) {
 175 // Adjust our pageX and pageY to account for the page zoom.
 176 adjustedPageX = lroundf(pos.x() / pageZoom);
 177 adjustedPageY = lroundf(pos.y() / pageZoom);
 178 }
 179 }
 180
 181 WheelEvent::Granularity granularity;
 182 switch (e.granularity()) {
 183 case ScrollByPageWheelEvent:
 184 granularity = WheelEvent::Page;
 185 break;
 186 case ScrollByPixelWheelEvent:
 187 default:
 188 granularity = WheelEvent::Pixel;
 189 break;
 190 }
 191
 192 RefPtr<WheelEvent> we = WheelEvent::create(e.wheelTicksX(), e.wheelTicksY(), e.deltaX(), e.deltaY(), granularity,
 193 node->document()->defaultView(), e.globalX(), e.globalY(), adjustedPageX, adjustedPageY,
 194 e.ctrlKey(), e.altKey(), e.shiftKey(), e.metaKey());
 195
 196 we->setAbsoluteLocation(IntPoint(pos.x(), pos.y()));
 197
 198 if (!dispatcher.dispatchEvent(we) || we->defaultHandled())
 199 e.accept();
 200
 201 we.release();
 202}
 203
104204// FIXME: Once https://bugs.webkit.org/show_bug.cgi?id=52963 lands, this should
105205// be greatly improved. See https://bugs.webkit.org/show_bug.cgi?id=54025.
106206static Node* pullOutOfShadow(Node* node)

@@static Node* pullOutOfShadow(Node* node)
113213 return outermostShadowBoundary;
114214}
115215
116 EventTarget* EventDispatcher::eventTargetRespectingSVGTargetRules(Node* referenceNode)
117 {
118  ASSERT(referenceNode);
119 
120 #if ENABLE(SVG)
121  if (!referenceNode->isSVGElement())
122  return referenceNode;
123 
124  // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
125  // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects
126  for (Node* n = referenceNode; n; n = n->parentNode()) {
127  if (!n->isShadowRoot() || !n->isSVGElement())
128  continue;
129 
130  Element* shadowTreeParentElement = n->shadowHost();
131  ASSERT(shadowTreeParentElement->hasTagName(SVGNames::useTag));
132 
133  if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode))
134  return instance;
135  }
136 #endif
137 
138  return referenceNode;
139 }
140 
141216EventDispatcher::EventDispatcher(Node* node)
142217 : m_node(node)
143218{

@@bool EventDispatcher::dispatchEvent(PassRefPtr<Event> prpEvent)
216291
217292 event->setEventPhase(Event::AT_TARGET);
218293 event->setTarget(originalTarget.get());
219  event->setCurrentTarget(EventDispatcher::eventTargetRespectingSVGTargetRules(m_node.get()));
 294 event->setCurrentTarget(eventTargetRespectingSVGTargetRules(m_node.get()));
220295 m_node->handleLocalEvents(event.get());
221296 if (event->propagationStopped())
222297 goto doneDispatching;

Source/WebCore/dom/EventDispatcher.h

@@class EventContext;
3636class EventTarget;
3737class FrameView;
3838class Node;
 39class PlatformKeyboardEvent;
3940class PlatformMouseEvent;
 41class PlatformWheelEvent;
4042
4143enum EventDispatchBehavior {
4244 RetargetEvent,

@@enum EventDispatchBehavior {
4749class EventDispatcher {
4850public:
4951 static bool dispatchEvent(Node*, PassRefPtr<Event>);
 52 static void dispatchScopedEvent(Node*, PassRefPtr<Event>);
 53
 54 static bool dispatchKeyEvent(Node*, const PlatformKeyboardEvent&);
5055 static bool dispatchMouseEvent(Node*, const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0);
5156 static void dispatchSimulatedClick(Node*, PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
52 
53  static EventTarget* eventTargetRespectingSVGTargetRules(Node*);
 57 static void dispatchWheelEvent(Node*, PlatformWheelEvent&);
5458
5559private:
5660 EventDispatcher(Node*);

Source/WebCore/dom/Node.cpp

@@void Node::handleLocalEvents(Event* event)
26022602
26032603void Node::dispatchScopedEvent(PassRefPtr<Event> event)
26042604{
2605  // We need to set the target here because it can go away by the time we actually fire the event.
2606  event->setTarget(EventDispatcher::eventTargetRespectingSVGTargetRules(this));
2607 
2608  ScopedEventQueue::instance()->enqueueEvent(event);
 2605 EventDispatcher::dispatchScopedEvent(this, event);
26092606}
26102607
26112608bool Node::dispatchEvent(PassRefPtr<Event> event)

@@void Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr
26422639
26432640bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& key)
26442641{
2645  RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, document()->defaultView());
2646  bool r = dispatchEvent(keyboardEvent);
2647 
2648  // we want to return false if default is prevented (already taken care of)
2649  // or if the element is default-handled by the DOM. Otherwise we let it just
2650  // let it get handled by AppKit
2651  if (keyboardEvent->defaultHandled())
2652  r = false;
2653 
2654  return r;
 2642 return EventDispatcher::dispatchKeyEvent(this, key);
26552643}
26562644
26572645bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,

@@void Node::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents,
26672655
26682656void Node::dispatchWheelEvent(PlatformWheelEvent& e)
26692657{
2670  ASSERT(!eventDispatchForbidden());
2671  if (e.deltaX() == 0 && e.deltaY() == 0)
2672  return;
2673 
2674  FrameView* view = document()->view();
2675  if (!view)
2676  return;
2677 
2678  IntPoint pos = view->windowToContents(e.pos());
2679 
2680  int adjustedPageX = pos.x();
2681  int adjustedPageY = pos.y();
2682  if (Frame* frame = document()->frame()) {
2683  float pageZoom = frame->pageZoomFactor();
2684  if (pageZoom != 1.0f) {
2685  // Adjust our pageX and pageY to account for the page zoom.
2686  adjustedPageX = lroundf(pos.x() / pageZoom);
2687  adjustedPageY = lroundf(pos.y() / pageZoom);
2688  }
2689  }
2690 
2691  WheelEvent::Granularity granularity;
2692  switch (e.granularity()) {
2693  case ScrollByPageWheelEvent:
2694  granularity = WheelEvent::Page;
2695  break;
2696  case ScrollByPixelWheelEvent:
2697  default:
2698  granularity = WheelEvent::Pixel;
2699  break;
2700  }
2701 
2702  RefPtr<WheelEvent> we = WheelEvent::create(e.wheelTicksX(), e.wheelTicksY(), e.deltaX(), e.deltaY(), granularity,
2703  document()->defaultView(), e.globalX(), e.globalY(), adjustedPageX, adjustedPageY,
2704  e.ctrlKey(), e.altKey(), e.shiftKey(), e.metaKey());
2705 
2706  we->setAbsoluteLocation(IntPoint(pos.x(), pos.y()));
2707 
2708  if (!dispatchEvent(we) || we->defaultHandled())
2709  e.accept();
2710 
2711  we.release();
 2658 EventDispatcher::dispatchWheelEvent(this, e);
27122659}
27132660
27142661void Node::dispatchFocusEvent()