OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2001 Peter Kelly (pmk@post.com) | |
3 * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de) | |
4 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | |
5 * Copyright (C) 2003, 2005, 2006, 2008 Apple Inc. All rights reserved. | |
6 * | |
7 * This library is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Library General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2 of the License, or (at your option) any later version. | |
11 * | |
12 * This library is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Library General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Library General Public License | |
18 * along with this library; see the file COPYING.LIB. If not, write to | |
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
20 * Boston, MA 02110-1301, USA. | |
21 */ | |
22 | |
23 #include "config.h" | |
24 #include "core/events/MouseEvent.h" | |
25 | |
26 #include "core/dom/Clipboard.h" | |
27 #include "core/events/EventDispatcher.h" | |
28 #include "core/events/EventNames.h" | |
29 #include "core/events/EventRetargeter.h" | |
30 #include "core/platform/PlatformMouseEvent.h" | |
31 | |
32 namespace WebCore { | |
33 | |
34 MouseEventInit::MouseEventInit() | |
35 : screenX(0) | |
36 , screenY(0) | |
37 , clientX(0) | |
38 , clientY(0) | |
39 , ctrlKey(false) | |
40 , altKey(false) | |
41 , shiftKey(false) | |
42 , metaKey(false) | |
43 , button(0) | |
44 , relatedTarget(0) | |
45 { | |
46 } | |
47 | |
48 PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& type, const MouseE
ventInit& initializer) | |
49 { | |
50 return adoptRef(new MouseEvent(type, initializer)); | |
51 } | |
52 | |
53 PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& eventType, PassRef
Ptr<AbstractView> view, const PlatformMouseEvent& event, int detail, PassRefPtr<
Node> relatedTarget) | |
54 { | |
55 ASSERT(event.type() == PlatformEvent::MouseMoved || event.button() != NoButt
on); | |
56 | |
57 bool isMouseEnterOrLeave = eventType == eventNames().mouseenterEvent || even
tType == eventNames().mouseleaveEvent; | |
58 bool isCancelable = !isMouseEnterOrLeave; | |
59 bool isBubbling = !isMouseEnterOrLeave; | |
60 | |
61 return MouseEvent::create(eventType, isBubbling, isCancelable, view, | |
62 detail, event.globalPosition().x(), event.globalPosition().y(), event.po
sition().x(), event.position().y(), | |
63 event.movementDelta().x(), event.movementDelta().y(), | |
64 event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), even
t.button(), | |
65 relatedTarget, 0, false); | |
66 } | |
67 | |
68 PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& type, bool canBubb
le, bool cancelable, PassRefPtr<AbstractView> view, | |
69 int detail, int screenX, int screenY, int pageX, int pageY, | |
70 int movementX, int movementY, | |
71 bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short butto
n, | |
72 PassRefPtr<EventTarget> relatedTarget) | |
73 | |
74 { | |
75 return MouseEvent::create(type, canBubble, cancelable, view, | |
76 detail, screenX, screenY, pageX, pageY, | |
77 movementX, movementY, | |
78 ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget, 0, false); | |
79 } | |
80 | |
81 PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& type, bool canBubb
le, bool cancelable, PassRefPtr<AbstractView> view, | |
82 int detail, int screenX, int screenY, int pageX, int pageY, | |
83 int movementX, int movementY, | |
84 bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short butto
n, | |
85 PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard> clipboard, bool
isSimulated) | |
86 { | |
87 return adoptRef(new MouseEvent(type, canBubble, cancelable, view, | |
88 detail, screenX, screenY, pageX, pageY, | |
89 movementX, movementY, | |
90 ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget, clipboard, is
Simulated)); | |
91 } | |
92 | |
93 MouseEvent::MouseEvent() | |
94 : m_button(0) | |
95 , m_buttonDown(false) | |
96 { | |
97 ScriptWrappable::init(this); | |
98 } | |
99 | |
100 MouseEvent::MouseEvent(const AtomicString& eventType, bool canBubble, bool cance
lable, PassRefPtr<AbstractView> view, | |
101 int detail, int screenX, int screenY, int pageX, int page
Y, | |
102 int movementX, int movementY, | |
103 bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, | |
104 unsigned short button, PassRefPtr<EventTarget> relatedTar
get, | |
105 PassRefPtr<Clipboard> clipboard, bool isSimulated) | |
106 : MouseRelatedEvent(eventType, canBubble, cancelable, view, detail, IntPoint
(screenX, screenY), | |
107 IntPoint(pageX, pageY), | |
108 IntPoint(movementX, movementY), | |
109 ctrlKey, altKey, shiftKey, metaKey, isSimulated) | |
110 , m_button(button == (unsigned short)-1 ? 0 : button) | |
111 , m_buttonDown(button != (unsigned short)-1) | |
112 , m_relatedTarget(relatedTarget) | |
113 , m_clipboard(clipboard) | |
114 { | |
115 ScriptWrappable::init(this); | |
116 } | |
117 | |
118 MouseEvent::MouseEvent(const AtomicString& eventType, const MouseEventInit& init
ializer) | |
119 : MouseRelatedEvent(eventType, initializer.bubbles, initializer.cancelable,
initializer.view, initializer.detail, IntPoint(initializer.screenX, initializer.
screenY), | |
120 IntPoint(0 /* pageX */, 0 /* pageY */), | |
121 IntPoint(0 /* movementX */, 0 /* movementY */), | |
122 initializer.ctrlKey, initializer.altKey, initializer.shiftKey, initializ
er.metaKey, false /* isSimulated */) | |
123 , m_button(initializer.button == (unsigned short)-1 ? 0 : initializer.button
) | |
124 , m_buttonDown(initializer.button != (unsigned short)-1) | |
125 , m_relatedTarget(initializer.relatedTarget) | |
126 , m_clipboard(0 /* clipboard */) | |
127 { | |
128 ScriptWrappable::init(this); | |
129 initCoordinates(IntPoint(initializer.clientX, initializer.clientY)); | |
130 } | |
131 | |
132 MouseEvent::~MouseEvent() | |
133 { | |
134 } | |
135 | |
136 void MouseEvent::initMouseEvent(const AtomicString& type, bool canBubble, bool c
ancelable, PassRefPtr<AbstractView> view, | |
137 int detail, int screenX, int screenY, int client
X, int clientY, | |
138 bool ctrlKey, bool altKey, bool shiftKey, bool m
etaKey, | |
139 unsigned short button, PassRefPtr<EventTarget> r
elatedTarget) | |
140 { | |
141 if (dispatched()) | |
142 return; | |
143 | |
144 initUIEvent(type, canBubble, cancelable, view, detail); | |
145 | |
146 m_screenLocation = IntPoint(screenX, screenY); | |
147 m_ctrlKey = ctrlKey; | |
148 m_altKey = altKey; | |
149 m_shiftKey = shiftKey; | |
150 m_metaKey = metaKey; | |
151 m_button = button == (unsigned short)-1 ? 0 : button; | |
152 m_buttonDown = button != (unsigned short)-1; | |
153 m_relatedTarget = relatedTarget; | |
154 | |
155 initCoordinates(IntPoint(clientX, clientY)); | |
156 | |
157 // FIXME: m_isSimulated is not set to false here. | |
158 // FIXME: m_clipboard is not set to 0 here. | |
159 } | |
160 | |
161 const AtomicString& MouseEvent::interfaceName() const | |
162 { | |
163 return eventNames().interfaceForMouseEvent; | |
164 } | |
165 | |
166 bool MouseEvent::isMouseEvent() const | |
167 { | |
168 return true; | |
169 } | |
170 | |
171 bool MouseEvent::isDragEvent() const | |
172 { | |
173 const AtomicString& t = type(); | |
174 return t == eventNames().dragenterEvent || t == eventNames().dragoverEvent |
| t == eventNames().dragleaveEvent || t == eventNames().dropEvent | |
175 || t == eventNames().dragstartEvent|| t == eventNames().dragEvent
|| t == eventNames().dragendEvent; | |
176 } | |
177 | |
178 int MouseEvent::which() const | |
179 { | |
180 // For the DOM, the return values for left, middle and right mouse buttons a
re 0, 1, 2, respectively. | |
181 // For the Netscape "which" property, the return values for left, middle and
right mouse buttons are 1, 2, 3, respectively. | |
182 // So we must add 1. | |
183 if (!m_buttonDown) | |
184 return 0; | |
185 return m_button + 1; | |
186 } | |
187 | |
188 Node* MouseEvent::toElement() const | |
189 { | |
190 // MSIE extension - "the object toward which the user is moving the mouse po
inter" | |
191 if (type() == eventNames().mouseoutEvent || type() == eventNames().mouseleav
eEvent) | |
192 return relatedTarget() ? relatedTarget()->toNode() : 0; | |
193 | |
194 return target() ? target()->toNode() : 0; | |
195 } | |
196 | |
197 Node* MouseEvent::fromElement() const | |
198 { | |
199 // MSIE extension - "object from which activation or the mouse pointer is ex
iting during the event" (huh?) | |
200 if (type() != eventNames().mouseoutEvent && type() != eventNames().mouseleav
eEvent) | |
201 return relatedTarget() ? relatedTarget()->toNode() : 0; | |
202 | |
203 return target() ? target()->toNode() : 0; | |
204 } | |
205 | |
206 PassRefPtr<SimulatedMouseEvent> SimulatedMouseEvent::create(const AtomicString&
eventType, PassRefPtr<AbstractView> view, PassRefPtr<Event> underlyingEvent) | |
207 { | |
208 return adoptRef(new SimulatedMouseEvent(eventType, view, underlyingEvent)); | |
209 } | |
210 | |
211 SimulatedMouseEvent::~SimulatedMouseEvent() | |
212 { | |
213 } | |
214 | |
215 SimulatedMouseEvent::SimulatedMouseEvent(const AtomicString& eventType, PassRefP
tr<AbstractView> view, PassRefPtr<Event> underlyingEvent) | |
216 : MouseEvent(eventType, true, true, view, 0, 0, 0, 0, 0, | |
217 0, 0, | |
218 false, false, false, false, 0, 0, 0, true) | |
219 { | |
220 if (UIEventWithKeyState* keyStateEvent = findEventWithKeyState(underlyingEve
nt.get())) { | |
221 m_ctrlKey = keyStateEvent->ctrlKey(); | |
222 m_altKey = keyStateEvent->altKey(); | |
223 m_shiftKey = keyStateEvent->shiftKey(); | |
224 m_metaKey = keyStateEvent->metaKey(); | |
225 } | |
226 setUnderlyingEvent(underlyingEvent); | |
227 | |
228 if (this->underlyingEvent() && this->underlyingEvent()->isMouseEvent()) { | |
229 MouseEvent* mouseEvent = toMouseEvent(this->underlyingEvent()); | |
230 m_screenLocation = mouseEvent->screenLocation(); | |
231 initCoordinates(mouseEvent->clientLocation()); | |
232 } | |
233 } | |
234 | |
235 PassRefPtr<MouseEventDispatchMediator> MouseEventDispatchMediator::create(PassRe
fPtr<MouseEvent> mouseEvent, MouseEventType mouseEventType) | |
236 { | |
237 return adoptRef(new MouseEventDispatchMediator(mouseEvent, mouseEventType)); | |
238 } | |
239 | |
240 MouseEventDispatchMediator::MouseEventDispatchMediator(PassRefPtr<MouseEvent> mo
useEvent, MouseEventType mouseEventType) | |
241 : EventDispatchMediator(mouseEvent), m_mouseEventType(mouseEventType) | |
242 { | |
243 } | |
244 | |
245 MouseEvent* MouseEventDispatchMediator::event() const | |
246 { | |
247 return toMouseEvent(EventDispatchMediator::event()); | |
248 } | |
249 | |
250 bool MouseEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) cons
t | |
251 { | |
252 if (isSyntheticMouseEvent()) { | |
253 EventRetargeter::adjustForMouseEvent(dispatcher->node(), *event()); | |
254 return dispatcher->dispatch(); | |
255 } | |
256 | |
257 if (isDisabledFormControl(dispatcher->node())) | |
258 return false; | |
259 | |
260 if (event()->type().isEmpty()) | |
261 return true; // Shouldn't happen. | |
262 | |
263 ASSERT(!event()->target() || event()->target() != event()->relatedTarget()); | |
264 | |
265 EventTarget* relatedTarget = event()->relatedTarget(); | |
266 EventRetargeter::adjustForMouseEvent(dispatcher->node(), *event()); | |
267 | |
268 dispatcher->dispatch(); | |
269 bool swallowEvent = event()->defaultHandled() || event()->defaultPrevented()
; | |
270 | |
271 if (event()->type() != eventNames().clickEvent || event()->detail() != 2) | |
272 return !swallowEvent; | |
273 | |
274 // Special case: If it's a double click event, we also send the dblclick eve
nt. This is not part | |
275 // of the DOM specs, but is used for compatibility with the ondblclick="" at
tribute. This is treated | |
276 // as a separate event in other DOM-compliant browsers like Firefox, and so
we do the same. | |
277 RefPtr<MouseEvent> doubleClickEvent = MouseEvent::create(); | |
278 doubleClickEvent->initMouseEvent(eventNames().dblclickEvent, event()->bubble
s(), event()->cancelable(), event()->view(), | |
279 event()->detail(), event()->screenX(), even
t()->screenY(), event()->clientX(), event()->clientY(), | |
280 event()->ctrlKey(), event()->altKey(), even
t()->shiftKey(), event()->metaKey(), | |
281 event()->button(), relatedTarget); | |
282 if (event()->defaultHandled()) | |
283 doubleClickEvent->setDefaultHandled(); | |
284 EventDispatcher::dispatchEvent(dispatcher->node(), MouseEventDispatchMediato
r::create(doubleClickEvent)); | |
285 if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented
()) | |
286 return false; | |
287 return !swallowEvent; | |
288 } | |
289 | |
290 } // namespace WebCore | |
OLD | NEW |