MouseEvent.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "mozilla/dom/MouseEvent.h"
  6. #include "mozilla/MouseEvents.h"
  7. #include "nsContentUtils.h"
  8. #include "nsIContent.h"
  9. #include "prtime.h"
  10. namespace mozilla {
  11. namespace dom {
  12. MouseEvent::MouseEvent(EventTarget* aOwner,
  13. nsPresContext* aPresContext,
  14. WidgetMouseEventBase* aEvent)
  15. : UIEvent(aOwner, aPresContext,
  16. aEvent ? aEvent :
  17. new WidgetMouseEvent(false, eVoidEvent, nullptr,
  18. WidgetMouseEvent::eReal))
  19. {
  20. // There's no way to make this class' ctor allocate an WidgetMouseScrollEvent.
  21. // It's not that important, though, since a scroll event is not a real
  22. // DOM event.
  23. WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent();
  24. if (aEvent) {
  25. mEventIsInternal = false;
  26. }
  27. else {
  28. mEventIsInternal = true;
  29. mEvent->mTime = PR_Now();
  30. mEvent->mRefPoint = LayoutDeviceIntPoint(0, 0);
  31. mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
  32. }
  33. if (mouseEvent) {
  34. MOZ_ASSERT(mouseEvent->mReason != WidgetMouseEvent::eSynthesized,
  35. "Don't dispatch DOM events from synthesized mouse events");
  36. mDetail = mouseEvent->mClickCount;
  37. }
  38. }
  39. NS_IMPL_ADDREF_INHERITED(MouseEvent, UIEvent)
  40. NS_IMPL_RELEASE_INHERITED(MouseEvent, UIEvent)
  41. NS_INTERFACE_MAP_BEGIN(MouseEvent)
  42. NS_INTERFACE_MAP_ENTRY(nsIDOMMouseEvent)
  43. NS_INTERFACE_MAP_END_INHERITING(UIEvent)
  44. void
  45. MouseEvent::InitMouseEvent(const nsAString& aType,
  46. bool aCanBubble,
  47. bool aCancelable,
  48. nsGlobalWindow* aView,
  49. int32_t aDetail,
  50. int32_t aScreenX,
  51. int32_t aScreenY,
  52. int32_t aClientX,
  53. int32_t aClientY,
  54. bool aCtrlKey,
  55. bool aAltKey,
  56. bool aShiftKey,
  57. bool aMetaKey,
  58. uint16_t aButton,
  59. EventTarget* aRelatedTarget)
  60. {
  61. NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
  62. UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
  63. switch(mEvent->mClass) {
  64. case eMouseEventClass:
  65. case eMouseScrollEventClass:
  66. case eWheelEventClass:
  67. case eDragEventClass:
  68. case ePointerEventClass:
  69. case eSimpleGestureEventClass: {
  70. WidgetMouseEventBase* mouseEventBase = mEvent->AsMouseEventBase();
  71. mouseEventBase->mRelatedTarget = aRelatedTarget;
  72. mouseEventBase->button = aButton;
  73. mouseEventBase->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
  74. mClientPoint.x = aClientX;
  75. mClientPoint.y = aClientY;
  76. mouseEventBase->mRefPoint.x = aScreenX;
  77. mouseEventBase->mRefPoint.y = aScreenY;
  78. WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent();
  79. if (mouseEvent) {
  80. mouseEvent->mClickCount = aDetail;
  81. }
  82. break;
  83. }
  84. default:
  85. break;
  86. }
  87. }
  88. NS_IMETHODIMP
  89. MouseEvent::InitMouseEvent(const nsAString& aType,
  90. bool aCanBubble,
  91. bool aCancelable,
  92. mozIDOMWindow* aView,
  93. int32_t aDetail,
  94. int32_t aScreenX,
  95. int32_t aScreenY,
  96. int32_t aClientX,
  97. int32_t aClientY,
  98. bool aCtrlKey,
  99. bool aAltKey,
  100. bool aShiftKey,
  101. bool aMetaKey,
  102. uint16_t aButton,
  103. nsIDOMEventTarget* aRelatedTarget)
  104. {
  105. MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable,
  106. nsGlobalWindow::Cast(aView), aDetail,
  107. aScreenX, aScreenY,
  108. aClientX, aClientY,
  109. aCtrlKey, aAltKey, aShiftKey,
  110. aMetaKey, aButton,
  111. static_cast<EventTarget *>(aRelatedTarget));
  112. return NS_OK;
  113. }
  114. void
  115. MouseEvent::InitMouseEvent(const nsAString& aType,
  116. bool aCanBubble,
  117. bool aCancelable,
  118. nsGlobalWindow* aView,
  119. int32_t aDetail,
  120. int32_t aScreenX,
  121. int32_t aScreenY,
  122. int32_t aClientX,
  123. int32_t aClientY,
  124. int16_t aButton,
  125. EventTarget* aRelatedTarget,
  126. const nsAString& aModifiersList)
  127. {
  128. NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
  129. Modifiers modifiers = ComputeModifierState(aModifiersList);
  130. InitMouseEvent(aType, aCanBubble, aCancelable, aView, aDetail,
  131. aScreenX, aScreenY, aClientX, aClientY,
  132. (modifiers & MODIFIER_CONTROL) != 0,
  133. (modifiers & MODIFIER_ALT) != 0,
  134. (modifiers & MODIFIER_SHIFT) != 0,
  135. (modifiers & MODIFIER_META) != 0,
  136. aButton, aRelatedTarget);
  137. switch(mEvent->mClass) {
  138. case eMouseEventClass:
  139. case eMouseScrollEventClass:
  140. case eWheelEventClass:
  141. case eDragEventClass:
  142. case ePointerEventClass:
  143. case eSimpleGestureEventClass:
  144. mEvent->AsInputEvent()->mModifiers = modifiers;
  145. return;
  146. default:
  147. MOZ_CRASH("There is no space to store the modifiers");
  148. }
  149. }
  150. void
  151. MouseEvent::InitializeExtraMouseEventDictionaryMembers(const MouseEventInit& aParam)
  152. {
  153. InitModifiers(aParam);
  154. mEvent->AsMouseEventBase()->buttons = aParam.mButtons;
  155. mMovementPoint.x = aParam.mMovementX;
  156. mMovementPoint.y = aParam.mMovementY;
  157. }
  158. already_AddRefed<MouseEvent>
  159. MouseEvent::Constructor(const GlobalObject& aGlobal,
  160. const nsAString& aType,
  161. const MouseEventInit& aParam,
  162. ErrorResult& aRv)
  163. {
  164. nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
  165. RefPtr<MouseEvent> e = new MouseEvent(t, nullptr, nullptr);
  166. bool trusted = e->Init(t);
  167. e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable,
  168. aParam.mView, aParam.mDetail, aParam.mScreenX,
  169. aParam.mScreenY, aParam.mClientX, aParam.mClientY,
  170. aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey,
  171. aParam.mMetaKey, aParam.mButton, aParam.mRelatedTarget);
  172. e->InitializeExtraMouseEventDictionaryMembers(aParam);
  173. e->SetTrusted(trusted);
  174. e->SetComposed(aParam.mComposed);
  175. return e.forget();
  176. }
  177. void
  178. MouseEvent::InitNSMouseEvent(const nsAString& aType,
  179. bool aCanBubble,
  180. bool aCancelable,
  181. nsGlobalWindow* aView,
  182. int32_t aDetail,
  183. int32_t aScreenX,
  184. int32_t aScreenY,
  185. int32_t aClientX,
  186. int32_t aClientY,
  187. bool aCtrlKey,
  188. bool aAltKey,
  189. bool aShiftKey,
  190. bool aMetaKey,
  191. uint16_t aButton,
  192. EventTarget* aRelatedTarget,
  193. float aPressure,
  194. uint16_t aInputSource)
  195. {
  196. NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
  197. MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable,
  198. aView, aDetail, aScreenX, aScreenY,
  199. aClientX, aClientY,
  200. aCtrlKey, aAltKey, aShiftKey,
  201. aMetaKey, aButton, aRelatedTarget);
  202. WidgetMouseEventBase* mouseEventBase = mEvent->AsMouseEventBase();
  203. mouseEventBase->pressure = aPressure;
  204. mouseEventBase->inputSource = aInputSource;
  205. }
  206. NS_IMETHODIMP
  207. MouseEvent::GetButton(int16_t* aButton)
  208. {
  209. NS_ENSURE_ARG_POINTER(aButton);
  210. *aButton = Button();
  211. return NS_OK;
  212. }
  213. int16_t
  214. MouseEvent::Button()
  215. {
  216. switch(mEvent->mClass) {
  217. case eMouseEventClass:
  218. case eMouseScrollEventClass:
  219. case eWheelEventClass:
  220. case eDragEventClass:
  221. case ePointerEventClass:
  222. case eSimpleGestureEventClass:
  223. return mEvent->AsMouseEventBase()->button;
  224. default:
  225. NS_WARNING("Tried to get mouse button for non-mouse event!");
  226. return WidgetMouseEvent::eLeftButton;
  227. }
  228. }
  229. NS_IMETHODIMP
  230. MouseEvent::GetButtons(uint16_t* aButtons)
  231. {
  232. NS_ENSURE_ARG_POINTER(aButtons);
  233. *aButtons = Buttons();
  234. return NS_OK;
  235. }
  236. uint16_t
  237. MouseEvent::Buttons()
  238. {
  239. switch(mEvent->mClass) {
  240. case eMouseEventClass:
  241. case eMouseScrollEventClass:
  242. case eWheelEventClass:
  243. case eDragEventClass:
  244. case ePointerEventClass:
  245. case eSimpleGestureEventClass:
  246. return mEvent->AsMouseEventBase()->buttons;
  247. default:
  248. MOZ_CRASH("Tried to get mouse buttons for non-mouse event!");
  249. }
  250. }
  251. NS_IMETHODIMP
  252. MouseEvent::GetRelatedTarget(nsIDOMEventTarget** aRelatedTarget)
  253. {
  254. NS_ENSURE_ARG_POINTER(aRelatedTarget);
  255. *aRelatedTarget = GetRelatedTarget().take();
  256. return NS_OK;
  257. }
  258. already_AddRefed<EventTarget>
  259. MouseEvent::GetRelatedTarget()
  260. {
  261. nsCOMPtr<EventTarget> relatedTarget;
  262. switch(mEvent->mClass) {
  263. case eMouseEventClass:
  264. case eMouseScrollEventClass:
  265. case eWheelEventClass:
  266. case eDragEventClass:
  267. case ePointerEventClass:
  268. case eSimpleGestureEventClass:
  269. relatedTarget = mEvent->AsMouseEventBase()->mRelatedTarget;
  270. break;
  271. default:
  272. break;
  273. }
  274. if (relatedTarget) {
  275. nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget);
  276. nsCOMPtr<nsIContent> currentTarget =
  277. do_QueryInterface(mEvent->mCurrentTarget);
  278. nsIContent* shadowRelatedTarget = GetShadowRelatedTarget(currentTarget, content);
  279. if (shadowRelatedTarget) {
  280. relatedTarget = shadowRelatedTarget;
  281. }
  282. if (content && content->ChromeOnlyAccess() &&
  283. !nsContentUtils::CanAccessNativeAnon()) {
  284. relatedTarget = do_QueryInterface(content->FindFirstNonChromeOnlyAccessContent());
  285. }
  286. if (relatedTarget) {
  287. relatedTarget = relatedTarget->GetTargetForDOMEvent();
  288. }
  289. return relatedTarget.forget();
  290. }
  291. return nullptr;
  292. }
  293. void
  294. MouseEvent::GetRegion(nsAString& aRegion)
  295. {
  296. SetDOMStringToNull(aRegion);
  297. WidgetMouseEventBase* mouseEventBase = mEvent->AsMouseEventBase();
  298. if (mouseEventBase) {
  299. aRegion = mouseEventBase->region;
  300. }
  301. }
  302. NS_IMETHODIMP
  303. MouseEvent::GetMozMovementX(int32_t* aMovementX)
  304. {
  305. NS_ENSURE_ARG_POINTER(aMovementX);
  306. *aMovementX = MovementX();
  307. return NS_OK;
  308. }
  309. NS_IMETHODIMP
  310. MouseEvent::GetMozMovementY(int32_t* aMovementY)
  311. {
  312. NS_ENSURE_ARG_POINTER(aMovementY);
  313. *aMovementY = MovementY();
  314. return NS_OK;
  315. }
  316. NS_IMETHODIMP
  317. MouseEvent::GetScreenX(int32_t* aScreenX)
  318. {
  319. NS_ENSURE_ARG_POINTER(aScreenX);
  320. *aScreenX = ScreenX();
  321. return NS_OK;
  322. }
  323. int32_t
  324. MouseEvent::ScreenX()
  325. {
  326. return Event::GetScreenCoords(mPresContext, mEvent, mEvent->mRefPoint).x;
  327. }
  328. NS_IMETHODIMP
  329. MouseEvent::GetScreenY(int32_t* aScreenY)
  330. {
  331. NS_ENSURE_ARG_POINTER(aScreenY);
  332. *aScreenY = ScreenY();
  333. return NS_OK;
  334. }
  335. int32_t
  336. MouseEvent::ScreenY()
  337. {
  338. return Event::GetScreenCoords(mPresContext, mEvent, mEvent->mRefPoint).y;
  339. }
  340. NS_IMETHODIMP
  341. MouseEvent::GetClientX(int32_t* aClientX)
  342. {
  343. NS_ENSURE_ARG_POINTER(aClientX);
  344. *aClientX = ClientX();
  345. return NS_OK;
  346. }
  347. int32_t
  348. MouseEvent::ClientX()
  349. {
  350. return Event::GetClientCoords(mPresContext, mEvent, mEvent->mRefPoint,
  351. mClientPoint).x;
  352. }
  353. NS_IMETHODIMP
  354. MouseEvent::GetClientY(int32_t* aClientY)
  355. {
  356. NS_ENSURE_ARG_POINTER(aClientY);
  357. *aClientY = ClientY();
  358. return NS_OK;
  359. }
  360. int32_t
  361. MouseEvent::ClientY()
  362. {
  363. return Event::GetClientCoords(mPresContext, mEvent, mEvent->mRefPoint,
  364. mClientPoint).y;
  365. }
  366. int32_t
  367. MouseEvent::OffsetX()
  368. {
  369. return Event::GetOffsetCoords(mPresContext, mEvent, mEvent->mRefPoint,
  370. mClientPoint).x;
  371. }
  372. int32_t
  373. MouseEvent::OffsetY()
  374. {
  375. return Event::GetOffsetCoords(mPresContext, mEvent, mEvent->mRefPoint,
  376. mClientPoint).y;
  377. }
  378. bool
  379. MouseEvent::AltKey()
  380. {
  381. return mEvent->AsInputEvent()->IsAlt();
  382. }
  383. NS_IMETHODIMP
  384. MouseEvent::GetAltKey(bool* aIsDown)
  385. {
  386. NS_ENSURE_ARG_POINTER(aIsDown);
  387. *aIsDown = AltKey();
  388. return NS_OK;
  389. }
  390. bool
  391. MouseEvent::CtrlKey()
  392. {
  393. return mEvent->AsInputEvent()->IsControl();
  394. }
  395. NS_IMETHODIMP
  396. MouseEvent::GetCtrlKey(bool* aIsDown)
  397. {
  398. NS_ENSURE_ARG_POINTER(aIsDown);
  399. *aIsDown = CtrlKey();
  400. return NS_OK;
  401. }
  402. bool
  403. MouseEvent::ShiftKey()
  404. {
  405. return mEvent->AsInputEvent()->IsShift();
  406. }
  407. NS_IMETHODIMP
  408. MouseEvent::GetShiftKey(bool* aIsDown)
  409. {
  410. NS_ENSURE_ARG_POINTER(aIsDown);
  411. *aIsDown = ShiftKey();
  412. return NS_OK;
  413. }
  414. bool
  415. MouseEvent::MetaKey()
  416. {
  417. return mEvent->AsInputEvent()->IsMeta();
  418. }
  419. NS_IMETHODIMP
  420. MouseEvent::GetMetaKey(bool* aIsDown)
  421. {
  422. NS_ENSURE_ARG_POINTER(aIsDown);
  423. *aIsDown = MetaKey();
  424. return NS_OK;
  425. }
  426. NS_IMETHODIMP
  427. MouseEvent::GetModifierState(const nsAString& aKey,
  428. bool* aState)
  429. {
  430. NS_ENSURE_ARG_POINTER(aState);
  431. *aState = GetModifierState(aKey);
  432. return NS_OK;
  433. }
  434. float
  435. MouseEvent::MozPressure() const
  436. {
  437. return mEvent->AsMouseEventBase()->pressure;
  438. }
  439. NS_IMETHODIMP
  440. MouseEvent::GetMozPressure(float* aPressure)
  441. {
  442. NS_ENSURE_ARG_POINTER(aPressure);
  443. *aPressure = MozPressure();
  444. return NS_OK;
  445. }
  446. bool
  447. MouseEvent::HitCluster() const
  448. {
  449. return mEvent->AsMouseEventBase()->hitCluster;
  450. }
  451. uint16_t
  452. MouseEvent::MozInputSource() const
  453. {
  454. return mEvent->AsMouseEventBase()->inputSource;
  455. }
  456. NS_IMETHODIMP
  457. MouseEvent::GetMozInputSource(uint16_t* aInputSource)
  458. {
  459. NS_ENSURE_ARG_POINTER(aInputSource);
  460. *aInputSource = MozInputSource();
  461. return NS_OK;
  462. }
  463. } // namespace dom
  464. } // namespace mozilla
  465. using namespace mozilla;
  466. using namespace mozilla::dom;
  467. already_AddRefed<MouseEvent>
  468. NS_NewDOMMouseEvent(EventTarget* aOwner,
  469. nsPresContext* aPresContext,
  470. WidgetMouseEvent* aEvent)
  471. {
  472. RefPtr<MouseEvent> it = new MouseEvent(aOwner, aPresContext, aEvent);
  473. return it.forget();
  474. }