Source/WebCore/ChangeLog

112011-04-04 Dimitri Glazkov <dglazkov@chromium.org>
22
 3 Reviewed by NOBODY (OOPS!).
 4
 5 Move MouseEvent-dispatching logic into MouseEventDispatchMediator.
 6 https://bugs.webkit.org/show_bug.cgi?id=57639
 7
 8 Refactoring, covered by existing tests.
 9
 10 * dom/Event.cpp:
 11 (WebCore::EventDispatchMediator::EventDispatchMediator): Added default
 12 constructor.
 13 (WebCore::EventDispatchMediator::setEvent): Added.
 14 * dom/Event.h: Tweaked decls.
 15 * dom/EventDispatcher.cpp:
 16 (WebCore::EventDispatcher::dispatchEvent): Moved useful assertion here
 17 from dispatchMouseEvent.
 18 (WebCore::EventDispatcher::node): Added.
 19 (WebCore::EventDispatcher::adjustRelatedTarget): Converted into a method.
 20 * dom/EventDispatcher.h: Adjusted decls.
 21 * dom/MouseEvent.cpp:
 22 (WebCore::MouseEventDispatchMediator::MouseEventDispatchMediator): Added.
 23 (WebCore::MouseEventDispatchMediator::event): Added.
 24 (WebCore::MouseEventDispatchMediator::dispatchEvent): Moved here the code from EventDispatcher::dispatchMouseEvent.
 25 * dom/MouseEvent.h:
 26 (WebCore::MouseEvent::create): Removed.
 27 (WebCore::MouseEvent::setRelatedTarget): Added.
 28 * dom/Node.cpp:
 29 (WebCore::Node::dispatchMouseEvent): Changed to use MouseEventDispatchMediator.
 30
 312011-04-04 Dimitri Glazkov <dglazkov@chromium.org>
 32
333 Reviewed by Adam Barth.
434
535 Introduce EventDispatchMediator abstraction, which encapsulate all

Source/WebCore/dom/Event.cpp

@@bool EventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
308308 return dispatcher->dispatchEvent(m_event.get());
309309}
310310
 311EventDispatchMediator::EventDispatchMediator()
 312{
 313}
 314
 315void EventDispatchMediator::setEvent(PassRefPtr<Event> event)
 316{
 317 m_event = event;
 318}
 319
311320Event* EventDispatchMediator::event() const
312321{
313322 return m_event.get();

Source/WebCore/dom/Event.h

@@public:
199199 virtual ~EventDispatchMediator();
200200
201201 virtual bool dispatchEvent(EventDispatcher*) const;
 202
 203protected:
 204 EventDispatchMediator();
 205
 206 void setEvent(PassRefPtr<Event>);
202207 Event* event() const;
 208
203209private:
204210 RefPtr<Event> m_event;
205211};

Source/WebCore/dom/EventDispatcher.cpp

@@static HashSet<Node*>* gNodesDispatchingSimulatedClicks = 0;
5555
5656bool EventDispatcher::dispatchEvent(Node* node, const EventDispatchMediator& mediator)
5757{
 58 ASSERT(!eventDispatchForbidden());
 59
5860 EventDispatcher dispatcher(node);
5961 return mediator.dispatchEvent(&dispatcher);
6062}
6163
 64Node* EventDispatcher::node() const
 65{
 66 return m_node.get();
 67}
 68
6269static EventTarget* findElementInstance(Node* referenceNode)
6370{
6471#if ENABLE(SVG)

@@void EventDispatcher::dispatchWheelEvent(Node* node, PlatformWheelEvent& event)
146153
147154// FIXME: Once https://bugs.webkit.org/show_bug.cgi?id=52963 lands, this should
148155// be greatly improved. See https://bugs.webkit.org/show_bug.cgi?id=54025.
149 static Node* pullOutOfShadow(Node* node)
 156PassRefPtr<EventTarget> EventDispatcher::adjustRelatedTarget(PassRefPtr<EventTarget> relatedTarget)
150157{
 158 if (!relatedTarget)
 159 return 0;
 160
 161 Node* node = relatedTarget->toNode();
 162 if (!node)
 163 return relatedTarget;
 164
151165 Node* outermostShadowBoundary = node;
152166 for (Node* n = node; n; n = n->parentOrHostNode()) {
153167 if (n->isShadowRoot())

@@doneWithDefault:
290304
291305 return !event->defaultPrevented();
292306}
293 bool EventDispatcher::dispatchMouseEvent(Node* node, const PlatformMouseEvent& event, const AtomicString& eventType,
294  int detail, Node* relatedTargetArg)
295 {
296  ASSERT(!eventDispatchForbidden());
297  ASSERT(event.eventType() == MouseEventMoved || event.button() != NoButton);
298 
299  if (node->disabled()) // Don't even send DOM events for disabled controls..
300  return true;
301 
302  if (eventType.isEmpty())
303  return false; // Shouldn't happen.
304 
305  EventDispatcher dispatcher(node);
306 
307  // Attempting to dispatch with a non-EventTarget relatedTarget causes the relatedTarget to be silently ignored.
308  RefPtr<Node> relatedTarget = pullOutOfShadow(relatedTargetArg);
309 
310  RefPtr<MouseEvent> mouseEvent = MouseEvent::create(eventType, node->document()->defaultView(), event, detail, relatedTarget);
311 
312  bool swallowEvent = false;
313 
314  dispatcher.dispatchEvent(mouseEvent);
315  bool defaultHandled = mouseEvent->defaultHandled();
316  bool defaultPrevented = mouseEvent->defaultPrevented();
317  if (defaultHandled || defaultPrevented)
318  swallowEvent = true;
319 
320  // Special case: If it's a double click event, we also send the dblclick event. This is not part
321  // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated
322  // as a separate event in other DOM-compliant browsers like Firefox, and so we do the same.
323  if (eventType == eventNames().clickEvent && detail == 2) {
324  RefPtr<Event> doubleClickEvent = MouseEvent::create(eventNames().dblclickEvent, node->document()->defaultView(), event, detail, relatedTarget);
325  if (defaultHandled)
326  doubleClickEvent->setDefaultHandled();
327  dispatcher.dispatchEvent(doubleClickEvent);
328  if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented())
329  swallowEvent = true;
330  }
331307
332  return swallowEvent;
333 }
334308
335309const EventContext* EventDispatcher::topEventContext()
336310{

Source/WebCore/dom/EventDispatcher.h

@@public:
5151 static bool dispatchEvent(Node*, const EventDispatchMediator&);
5252 static void dispatchScopedEvent(Node*, PassRefPtr<Event>);
5353
54  static bool dispatchMouseEvent(Node*, const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0);
5554 static void dispatchSimulatedClick(Node*, PassRefPtr<Event> underlyingEvent, bool sendMouseEvents, bool showPressedLook);
5655 static void dispatchWheelEvent(Node*, PlatformWheelEvent&);
5756
5857 bool dispatchEvent(PassRefPtr<Event>);
 58 PassRefPtr<EventTarget> adjustRelatedTarget(PassRefPtr<EventTarget>);
 59 Node* node() const;
 60
5961private:
6062 EventDispatcher(Node*);
6163

@@private:
6466 const EventContext* topEventContext();
6567 bool ancestorsInitialized() const;
6668
67  bool dispatchMouseEvent(const AtomicString& eventType, int button, int detail,
68  int pageX, int pageY, int screenX, int screenY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
69  bool isSimulated, Node* relatedTargetArg, PassRefPtr<Event> underlyingEvent);
70 
7169 Vector<EventContext> m_ancestors;
7270 RefPtr<Node> m_node;
7371 RefPtr<EventTarget> m_originalTarget;

Source/WebCore/dom/MouseEvent.cpp

2323#include "config.h"
2424#include "MouseEvent.h"
2525
 26#include "EventDispatcher.h"
 27#include "EventNames.h"
2628#include "Frame.h"
2729#include "FrameView.h"
28 #include "EventNames.h"
2930#include "PlatformMouseEvent.h"
3031
3132namespace WebCore {
3233
33 PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& eventType, PassRefPtr<AbstractView> view, const PlatformMouseEvent& event, int detail, PassRefPtr<Node> relatedTarget)
34 {
35  bool isCancelable = eventType != eventNames().mousemoveEvent;
36 
37  return MouseEvent::create(eventType, true, isCancelable, view,
38  detail, event.globalX(), event.globalY(), event.x(), event.y(),
39  event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), event.button(),
40  relatedTarget, 0, false);
41 }
42 
4334MouseEvent::MouseEvent()
4435 : m_button(0)
4536 , m_buttonDown(false)

@@SimulatedMouseEvent::SimulatedMouseEvent(const AtomicString& eventType, PassRefP
149140 setUnderlyingEvent(underlyingEvent);
150141}
151142
 143MouseEventDispatchMediator::MouseEventDispatchMediator(const AtomicString& eventType, PassRefPtr<AbstractView> view, const PlatformMouseEvent& event, int detail, PassRefPtr<Node> relatedTarget)
 144 : EventDispatchMediator()
 145{
 146 ASSERT(event.eventType() == MouseEventMoved || event.button() != NoButton);
 147
 148 bool isCancelable = eventType != eventNames().mousemoveEvent;
 149
 150 setEvent(MouseEvent::create(eventType, true, isCancelable, view,
 151 detail, event.globalX(), event.globalY(), event.x(), event.y(),
 152 event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), event.button(),
 153 relatedTarget, 0, false));
 154}
 155
 156MouseEvent* MouseEventDispatchMediator::event() const
 157{
 158 return static_cast<MouseEvent*>(EventDispatchMediator::event());
 159}
 160
 161bool MouseEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
 162{
 163 if (dispatcher->node()->disabled()) // Don't even send DOM events for disabled controls..
 164 return true;
 165
 166 if (event()->type().isEmpty())
 167 return false; // Shouldn't happen.
 168
 169 RefPtr<EventTarget> relatedTarget = dispatcher->adjustRelatedTarget(event()->relatedTarget());
 170 event()->setRelatedTarget(relatedTarget);
 171
 172 dispatcher->dispatchEvent(event());
 173 bool swallowEvent = event()->defaultHandled() || event()->defaultPrevented();
 174
 175 // Special case: If it's a double click event, we also send the dblclick event. This is not part
 176 // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated
 177 // as a separate event in other DOM-compliant browsers like Firefox, and so we do the same.
 178 if (event()->type() == eventNames().clickEvent && event()->detail() == 2) {
 179 RefPtr<MouseEvent> doubleClickEvent = MouseEvent::create();
 180 doubleClickEvent->initMouseEvent(eventNames().dblclickEvent, event()->bubbles(), event()->cancelable(), event()->view(),
 181 event()->detail(), event()->screenX(), event()->screenY(), event()->clientX(), event()->clientY(),
 182 event()->ctrlKey(), event()->altKey(), event()->shiftKey(), event()->metaKey(),
 183 event()->button(), relatedTarget);
 184 if (event()->defaultHandled())
 185 doubleClickEvent->setDefaultHandled();
 186 dispatcher->dispatchEvent(doubleClickEvent);
 187 if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented())
 188 swallowEvent = true;
 189 }
 190
 191 return swallowEvent;
 192}
 193
152194} // namespace WebCore

Source/WebCore/dom/MouseEvent.h

2929
3030namespace WebCore {
3131
 32class EventDispatcher;
3233class PlatformMouseEvent;
3334
3435 // Introduced in DOM Level 2

@@class PlatformMouseEvent;
4647 return adoptRef(new MouseEvent(type, canBubble, cancelable, view, detail, screenX, screenY, pageX, pageY,
4748 ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget, clipboard, isSimulated));
4849 }
49  static PassRefPtr<MouseEvent> create(const AtomicString& eventType, PassRefPtr<AbstractView>, const PlatformMouseEvent&, int detail, PassRefPtr<Node> relatedTarget);
50 
5150 virtual ~MouseEvent();
5251
5352 void initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,

@@class PlatformMouseEvent;
6059 unsigned short button() const { return m_button; }
6160 bool buttonDown() const { return m_buttonDown; }
6261 EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
 62 void setRelatedTarget(PassRefPtr<EventTarget> relatedTarget) { m_relatedTarget = relatedTarget; }
6363
6464 Clipboard* clipboard() const { return m_clipboard.get(); }
6565

@@private:
9696 SimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<AbstractView>, PassRefPtr<Event> underlyingEvent);
9797};
9898
 99class MouseEventDispatchMediator : public EventDispatchMediator {
 100public:
 101 MouseEventDispatchMediator(const AtomicString& eventType, PassRefPtr<AbstractView>, const PlatformMouseEvent&, int detail, PassRefPtr<Node> relatedTarget);
 102
 103private:
 104 MouseEvent* event() const;
 105
 106 virtual bool dispatchEvent(EventDispatcher*) const;
 107};
 108
99109} // namespace WebCore
100110
101111#endif // MouseEvent_h

Source/WebCore/dom/Node.cpp

@@bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& event)
26512651bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
26522652 int detail, Node* relatedTarget)
26532653{
2654  return EventDispatcher::dispatchMouseEvent(this, event, eventType, detail, relatedTarget);
 2654 return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator(eventType, document()->defaultView(), event, detail, relatedTarget));
26552655}
26562656
26572657void Node::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook)