1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/events/MouseEvent.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,485 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/dom/MouseEvent.h" 1.10 +#include "mozilla/MouseEvents.h" 1.11 +#include "nsContentUtils.h" 1.12 +#include "nsIContent.h" 1.13 +#include "prtime.h" 1.14 + 1.15 +namespace mozilla { 1.16 +namespace dom { 1.17 + 1.18 +MouseEvent::MouseEvent(EventTarget* aOwner, 1.19 + nsPresContext* aPresContext, 1.20 + WidgetMouseEventBase* aEvent) 1.21 + : UIEvent(aOwner, aPresContext, 1.22 + aEvent ? aEvent : new WidgetMouseEvent(false, 0, nullptr, 1.23 + WidgetMouseEvent::eReal)) 1.24 +{ 1.25 + // There's no way to make this class' ctor allocate an WidgetMouseScrollEvent. 1.26 + // It's not that important, though, since a scroll event is not a real 1.27 + // DOM event. 1.28 + 1.29 + WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent(); 1.30 + if (aEvent) { 1.31 + mEventIsInternal = false; 1.32 + } 1.33 + else { 1.34 + mEventIsInternal = true; 1.35 + mEvent->time = PR_Now(); 1.36 + mEvent->refPoint.x = mEvent->refPoint.y = 0; 1.37 + mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN; 1.38 + } 1.39 + 1.40 + if (mouseEvent) { 1.41 + MOZ_ASSERT(mouseEvent->reason != WidgetMouseEvent::eSynthesized, 1.42 + "Don't dispatch DOM events from synthesized mouse events"); 1.43 + mDetail = mouseEvent->clickCount; 1.44 + } 1.45 +} 1.46 + 1.47 +NS_IMPL_ADDREF_INHERITED(MouseEvent, UIEvent) 1.48 +NS_IMPL_RELEASE_INHERITED(MouseEvent, UIEvent) 1.49 + 1.50 +NS_INTERFACE_MAP_BEGIN(MouseEvent) 1.51 + NS_INTERFACE_MAP_ENTRY(nsIDOMMouseEvent) 1.52 +NS_INTERFACE_MAP_END_INHERITING(UIEvent) 1.53 + 1.54 +NS_IMETHODIMP 1.55 +MouseEvent::InitMouseEvent(const nsAString& aType, 1.56 + bool aCanBubble, 1.57 + bool aCancelable, 1.58 + nsIDOMWindow* aView, 1.59 + int32_t aDetail, 1.60 + int32_t aScreenX, 1.61 + int32_t aScreenY, 1.62 + int32_t aClientX, 1.63 + int32_t aClientY, 1.64 + bool aCtrlKey, 1.65 + bool aAltKey, 1.66 + bool aShiftKey, 1.67 + bool aMetaKey, 1.68 + uint16_t aButton, 1.69 + nsIDOMEventTarget* aRelatedTarget) 1.70 +{ 1.71 + nsresult rv = 1.72 + UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail); 1.73 + NS_ENSURE_SUCCESS(rv, rv); 1.74 + 1.75 + switch(mEvent->eventStructType) { 1.76 + case NS_MOUSE_EVENT: 1.77 + case NS_MOUSE_SCROLL_EVENT: 1.78 + case NS_WHEEL_EVENT: 1.79 + case NS_DRAG_EVENT: 1.80 + case NS_POINTER_EVENT: 1.81 + case NS_SIMPLE_GESTURE_EVENT: { 1.82 + WidgetMouseEventBase* mouseEventBase = mEvent->AsMouseEventBase(); 1.83 + mouseEventBase->relatedTarget = aRelatedTarget; 1.84 + mouseEventBase->button = aButton; 1.85 + mouseEventBase->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey); 1.86 + mClientPoint.x = aClientX; 1.87 + mClientPoint.y = aClientY; 1.88 + mouseEventBase->refPoint.x = aScreenX; 1.89 + mouseEventBase->refPoint.y = aScreenY; 1.90 + 1.91 + WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent(); 1.92 + if (mouseEvent) { 1.93 + mouseEvent->clickCount = aDetail; 1.94 + } 1.95 + break; 1.96 + } 1.97 + default: 1.98 + break; 1.99 + } 1.100 + 1.101 + return NS_OK; 1.102 +} 1.103 + 1.104 +nsresult 1.105 +MouseEvent::InitMouseEvent(const nsAString& aType, 1.106 + bool aCanBubble, 1.107 + bool aCancelable, 1.108 + nsIDOMWindow* aView, 1.109 + int32_t aDetail, 1.110 + int32_t aScreenX, 1.111 + int32_t aScreenY, 1.112 + int32_t aClientX, 1.113 + int32_t aClientY, 1.114 + int16_t aButton, 1.115 + nsIDOMEventTarget* aRelatedTarget, 1.116 + const nsAString& aModifiersList) 1.117 +{ 1.118 + Modifiers modifiers = ComputeModifierState(aModifiersList); 1.119 + 1.120 + nsresult rv = InitMouseEvent(aType, aCanBubble, aCancelable, aView, 1.121 + aDetail, aScreenX, aScreenY, aClientX, aClientY, 1.122 + (modifiers & MODIFIER_CONTROL) != 0, 1.123 + (modifiers & MODIFIER_ALT) != 0, 1.124 + (modifiers & MODIFIER_SHIFT) != 0, 1.125 + (modifiers & MODIFIER_META) != 0, 1.126 + aButton, aRelatedTarget); 1.127 + NS_ENSURE_SUCCESS(rv, rv); 1.128 + 1.129 + switch(mEvent->eventStructType) { 1.130 + case NS_MOUSE_EVENT: 1.131 + case NS_MOUSE_SCROLL_EVENT: 1.132 + case NS_WHEEL_EVENT: 1.133 + case NS_DRAG_EVENT: 1.134 + case NS_POINTER_EVENT: 1.135 + case NS_SIMPLE_GESTURE_EVENT: 1.136 + mEvent->AsInputEvent()->modifiers = modifiers; 1.137 + return NS_OK; 1.138 + default: 1.139 + MOZ_CRASH("There is no space to store the modifiers"); 1.140 + } 1.141 +} 1.142 + 1.143 +already_AddRefed<MouseEvent> 1.144 +MouseEvent::Constructor(const GlobalObject& aGlobal, 1.145 + const nsAString& aType, 1.146 + const MouseEventInit& aParam, 1.147 + ErrorResult& aRv) 1.148 +{ 1.149 + nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports()); 1.150 + nsRefPtr<MouseEvent> e = new MouseEvent(t, nullptr, nullptr); 1.151 + bool trusted = e->Init(t); 1.152 + e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable, 1.153 + aParam.mView, aParam.mDetail, aParam.mScreenX, 1.154 + aParam.mScreenY, aParam.mClientX, aParam.mClientY, 1.155 + aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey, 1.156 + aParam.mMetaKey, aParam.mButton, aParam.mRelatedTarget, 1.157 + aRv); 1.158 + e->SetTrusted(trusted); 1.159 + 1.160 + switch (e->mEvent->eventStructType) { 1.161 + case NS_MOUSE_EVENT: 1.162 + case NS_MOUSE_SCROLL_EVENT: 1.163 + case NS_WHEEL_EVENT: 1.164 + case NS_DRAG_EVENT: 1.165 + case NS_POINTER_EVENT: 1.166 + case NS_SIMPLE_GESTURE_EVENT: 1.167 + e->mEvent->AsMouseEventBase()->buttons = aParam.mButtons; 1.168 + break; 1.169 + default: 1.170 + break; 1.171 + } 1.172 + 1.173 + return e.forget(); 1.174 +} 1.175 + 1.176 +NS_IMETHODIMP 1.177 +MouseEvent::InitNSMouseEvent(const nsAString& aType, 1.178 + bool aCanBubble, 1.179 + bool aCancelable, 1.180 + nsIDOMWindow* aView, 1.181 + int32_t aDetail, 1.182 + int32_t aScreenX, 1.183 + int32_t aScreenY, 1.184 + int32_t aClientX, 1.185 + int32_t aClientY, 1.186 + bool aCtrlKey, 1.187 + bool aAltKey, 1.188 + bool aShiftKey, 1.189 + bool aMetaKey, 1.190 + uint16_t aButton, 1.191 + nsIDOMEventTarget* aRelatedTarget, 1.192 + float aPressure, 1.193 + uint16_t aInputSource) 1.194 +{ 1.195 + nsresult rv = MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, 1.196 + aView, aDetail, aScreenX, aScreenY, 1.197 + aClientX, aClientY, 1.198 + aCtrlKey, aAltKey, aShiftKey, 1.199 + aMetaKey, aButton, aRelatedTarget); 1.200 + NS_ENSURE_SUCCESS(rv, rv); 1.201 + 1.202 + WidgetMouseEventBase* mouseEventBase = mEvent->AsMouseEventBase(); 1.203 + mouseEventBase->pressure = aPressure; 1.204 + mouseEventBase->inputSource = aInputSource; 1.205 + return NS_OK; 1.206 +} 1.207 + 1.208 +NS_IMETHODIMP 1.209 +MouseEvent::GetButton(int16_t* aButton) 1.210 +{ 1.211 + NS_ENSURE_ARG_POINTER(aButton); 1.212 + *aButton = Button(); 1.213 + return NS_OK; 1.214 +} 1.215 + 1.216 +int16_t 1.217 +MouseEvent::Button() 1.218 +{ 1.219 + switch(mEvent->eventStructType) 1.220 + { 1.221 + case NS_MOUSE_EVENT: 1.222 + case NS_MOUSE_SCROLL_EVENT: 1.223 + case NS_WHEEL_EVENT: 1.224 + case NS_DRAG_EVENT: 1.225 + case NS_POINTER_EVENT: 1.226 + case NS_SIMPLE_GESTURE_EVENT: 1.227 + return mEvent->AsMouseEventBase()->button; 1.228 + default: 1.229 + NS_WARNING("Tried to get mouse button for non-mouse event!"); 1.230 + return WidgetMouseEvent::eLeftButton; 1.231 + } 1.232 +} 1.233 + 1.234 +NS_IMETHODIMP 1.235 +MouseEvent::GetButtons(uint16_t* aButtons) 1.236 +{ 1.237 + NS_ENSURE_ARG_POINTER(aButtons); 1.238 + *aButtons = Buttons(); 1.239 + return NS_OK; 1.240 +} 1.241 + 1.242 +uint16_t 1.243 +MouseEvent::Buttons() 1.244 +{ 1.245 + switch(mEvent->eventStructType) 1.246 + { 1.247 + case NS_MOUSE_EVENT: 1.248 + case NS_MOUSE_SCROLL_EVENT: 1.249 + case NS_WHEEL_EVENT: 1.250 + case NS_DRAG_EVENT: 1.251 + case NS_POINTER_EVENT: 1.252 + case NS_SIMPLE_GESTURE_EVENT: 1.253 + return mEvent->AsMouseEventBase()->buttons; 1.254 + default: 1.255 + MOZ_CRASH("Tried to get mouse buttons for non-mouse event!"); 1.256 + } 1.257 +} 1.258 + 1.259 +NS_IMETHODIMP 1.260 +MouseEvent::GetRelatedTarget(nsIDOMEventTarget** aRelatedTarget) 1.261 +{ 1.262 + NS_ENSURE_ARG_POINTER(aRelatedTarget); 1.263 + *aRelatedTarget = GetRelatedTarget().take(); 1.264 + return NS_OK; 1.265 +} 1.266 + 1.267 +already_AddRefed<EventTarget> 1.268 +MouseEvent::GetRelatedTarget() 1.269 +{ 1.270 + nsCOMPtr<EventTarget> relatedTarget; 1.271 + switch(mEvent->eventStructType) 1.272 + { 1.273 + case NS_MOUSE_EVENT: 1.274 + case NS_MOUSE_SCROLL_EVENT: 1.275 + case NS_WHEEL_EVENT: 1.276 + case NS_DRAG_EVENT: 1.277 + case NS_POINTER_EVENT: 1.278 + case NS_SIMPLE_GESTURE_EVENT: 1.279 + relatedTarget = 1.280 + do_QueryInterface(mEvent->AsMouseEventBase()->relatedTarget); 1.281 + break; 1.282 + default: 1.283 + break; 1.284 + } 1.285 + 1.286 + if (relatedTarget) { 1.287 + nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget); 1.288 + if (content && content->ChromeOnlyAccess() && 1.289 + !nsContentUtils::CanAccessNativeAnon()) { 1.290 + relatedTarget = do_QueryInterface(content->FindFirstNonChromeOnlyAccessContent()); 1.291 + } 1.292 + 1.293 + if (relatedTarget) { 1.294 + relatedTarget = relatedTarget->GetTargetForDOMEvent(); 1.295 + } 1.296 + return relatedTarget.forget(); 1.297 + } 1.298 + return nullptr; 1.299 +} 1.300 + 1.301 +NS_IMETHODIMP 1.302 +MouseEvent::GetMozMovementX(int32_t* aMovementX) 1.303 +{ 1.304 + NS_ENSURE_ARG_POINTER(aMovementX); 1.305 + *aMovementX = MozMovementX(); 1.306 + 1.307 + return NS_OK; 1.308 +} 1.309 + 1.310 +NS_IMETHODIMP 1.311 +MouseEvent::GetMozMovementY(int32_t* aMovementY) 1.312 +{ 1.313 + NS_ENSURE_ARG_POINTER(aMovementY); 1.314 + *aMovementY = MozMovementY(); 1.315 + 1.316 + return NS_OK; 1.317 +} 1.318 + 1.319 +NS_IMETHODIMP 1.320 +MouseEvent::GetScreenX(int32_t* aScreenX) 1.321 +{ 1.322 + NS_ENSURE_ARG_POINTER(aScreenX); 1.323 + *aScreenX = ScreenX(); 1.324 + return NS_OK; 1.325 +} 1.326 + 1.327 +int32_t 1.328 +MouseEvent::ScreenX() 1.329 +{ 1.330 + return Event::GetScreenCoords(mPresContext, mEvent, mEvent->refPoint).x; 1.331 +} 1.332 + 1.333 +NS_IMETHODIMP 1.334 +MouseEvent::GetScreenY(int32_t* aScreenY) 1.335 +{ 1.336 + NS_ENSURE_ARG_POINTER(aScreenY); 1.337 + *aScreenY = ScreenY(); 1.338 + return NS_OK; 1.339 +} 1.340 + 1.341 +int32_t 1.342 +MouseEvent::ScreenY() 1.343 +{ 1.344 + return Event::GetScreenCoords(mPresContext, mEvent, mEvent->refPoint).y; 1.345 +} 1.346 + 1.347 + 1.348 +NS_IMETHODIMP 1.349 +MouseEvent::GetClientX(int32_t* aClientX) 1.350 +{ 1.351 + NS_ENSURE_ARG_POINTER(aClientX); 1.352 + *aClientX = ClientX(); 1.353 + return NS_OK; 1.354 +} 1.355 + 1.356 +int32_t 1.357 +MouseEvent::ClientX() 1.358 +{ 1.359 + return Event::GetClientCoords(mPresContext, mEvent, mEvent->refPoint, 1.360 + mClientPoint).x; 1.361 +} 1.362 + 1.363 +NS_IMETHODIMP 1.364 +MouseEvent::GetClientY(int32_t* aClientY) 1.365 +{ 1.366 + NS_ENSURE_ARG_POINTER(aClientY); 1.367 + *aClientY = ClientY(); 1.368 + return NS_OK; 1.369 +} 1.370 + 1.371 +int32_t 1.372 +MouseEvent::ClientY() 1.373 +{ 1.374 + return Event::GetClientCoords(mPresContext, mEvent, mEvent->refPoint, 1.375 + mClientPoint).y; 1.376 +} 1.377 + 1.378 +bool 1.379 +MouseEvent::AltKey() 1.380 +{ 1.381 + return mEvent->AsInputEvent()->IsAlt(); 1.382 +} 1.383 + 1.384 +NS_IMETHODIMP 1.385 +MouseEvent::GetAltKey(bool* aIsDown) 1.386 +{ 1.387 + NS_ENSURE_ARG_POINTER(aIsDown); 1.388 + *aIsDown = AltKey(); 1.389 + return NS_OK; 1.390 +} 1.391 + 1.392 +bool 1.393 +MouseEvent::CtrlKey() 1.394 +{ 1.395 + return mEvent->AsInputEvent()->IsControl(); 1.396 +} 1.397 + 1.398 +NS_IMETHODIMP 1.399 +MouseEvent::GetCtrlKey(bool* aIsDown) 1.400 +{ 1.401 + NS_ENSURE_ARG_POINTER(aIsDown); 1.402 + *aIsDown = CtrlKey(); 1.403 + return NS_OK; 1.404 +} 1.405 + 1.406 +bool 1.407 +MouseEvent::ShiftKey() 1.408 +{ 1.409 + return mEvent->AsInputEvent()->IsShift(); 1.410 +} 1.411 + 1.412 +NS_IMETHODIMP 1.413 +MouseEvent::GetShiftKey(bool* aIsDown) 1.414 +{ 1.415 + NS_ENSURE_ARG_POINTER(aIsDown); 1.416 + *aIsDown = ShiftKey(); 1.417 + return NS_OK; 1.418 +} 1.419 + 1.420 +bool 1.421 +MouseEvent::MetaKey() 1.422 +{ 1.423 + return mEvent->AsInputEvent()->IsMeta(); 1.424 +} 1.425 + 1.426 +NS_IMETHODIMP 1.427 +MouseEvent::GetMetaKey(bool* aIsDown) 1.428 +{ 1.429 + NS_ENSURE_ARG_POINTER(aIsDown); 1.430 + *aIsDown = MetaKey(); 1.431 + return NS_OK; 1.432 +} 1.433 + 1.434 +NS_IMETHODIMP 1.435 +MouseEvent::GetModifierState(const nsAString& aKey, 1.436 + bool* aState) 1.437 +{ 1.438 + NS_ENSURE_ARG_POINTER(aState); 1.439 + 1.440 + *aState = GetModifierState(aKey); 1.441 + return NS_OK; 1.442 +} 1.443 + 1.444 +float 1.445 +MouseEvent::MozPressure() const 1.446 +{ 1.447 + return mEvent->AsMouseEventBase()->pressure; 1.448 +} 1.449 + 1.450 +NS_IMETHODIMP 1.451 +MouseEvent::GetMozPressure(float* aPressure) 1.452 +{ 1.453 + NS_ENSURE_ARG_POINTER(aPressure); 1.454 + *aPressure = MozPressure(); 1.455 + return NS_OK; 1.456 +} 1.457 + 1.458 +uint16_t 1.459 +MouseEvent::MozInputSource() const 1.460 +{ 1.461 + return mEvent->AsMouseEventBase()->inputSource; 1.462 +} 1.463 + 1.464 +NS_IMETHODIMP 1.465 +MouseEvent::GetMozInputSource(uint16_t* aInputSource) 1.466 +{ 1.467 + NS_ENSURE_ARG_POINTER(aInputSource); 1.468 + *aInputSource = MozInputSource(); 1.469 + return NS_OK; 1.470 +} 1.471 + 1.472 +} // namespace dom 1.473 +} // namespace mozilla 1.474 + 1.475 +using namespace mozilla; 1.476 +using namespace mozilla::dom; 1.477 + 1.478 +nsresult 1.479 +NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult, 1.480 + EventTarget* aOwner, 1.481 + nsPresContext* aPresContext, 1.482 + WidgetMouseEvent* aEvent) 1.483 +{ 1.484 + MouseEvent* it = new MouseEvent(aOwner, aPresContext, aEvent); 1.485 + NS_ADDREF(it); 1.486 + *aInstancePtrResult = static_cast<Event*>(it); 1.487 + return NS_OK; 1.488 +}