MouseEvent.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <LibGUI/Event.h>
  8. #include <LibWeb/Bindings/Intrinsics.h>
  9. #include <LibWeb/HTML/EventNames.h>
  10. #include <LibWeb/UIEvents/EventNames.h>
  11. #include <LibWeb/UIEvents/MouseEvent.h>
  12. namespace Web::UIEvents {
  13. MouseEvent::MouseEvent(JS::Realm& realm, FlyString const& event_name, MouseEventInit const& event_init)
  14. : UIEvent(realm, event_name, event_init)
  15. , m_offset_x(event_init.offset_x)
  16. , m_offset_y(event_init.offset_y)
  17. , m_client_x(event_init.client_x)
  18. , m_client_y(event_init.client_y)
  19. , m_page_x(event_init.page_x)
  20. , m_page_y(event_init.page_y)
  21. , m_button(event_init.button)
  22. , m_buttons(event_init.buttons)
  23. {
  24. set_event_characteristics();
  25. }
  26. MouseEvent::~MouseEvent() = default;
  27. JS::ThrowCompletionOr<void> MouseEvent::initialize(JS::Realm& realm)
  28. {
  29. MUST_OR_THROW_OOM(Base::initialize(realm));
  30. set_prototype(&Bindings::ensure_web_prototype<Bindings::MouseEventPrototype>(realm, "MouseEvent"));
  31. return {};
  32. }
  33. // https://www.w3.org/TR/uievents/#dom-mouseevent-button
  34. static i16 determine_button(unsigned mouse_button)
  35. {
  36. switch (mouse_button) {
  37. case GUI::MouseButton::Primary:
  38. return 0;
  39. case GUI::MouseButton::Middle:
  40. return 1;
  41. case GUI::MouseButton::Secondary:
  42. return 2;
  43. case GUI::MouseButton::Backward:
  44. return 3;
  45. case GUI::MouseButton::Forward:
  46. return 4;
  47. default:
  48. VERIFY_NOT_REACHED();
  49. }
  50. }
  51. WebIDL::ExceptionOr<JS::NonnullGCPtr<MouseEvent>> MouseEvent::create(JS::Realm& realm, FlyString const& event_name, MouseEventInit const& event_init)
  52. {
  53. return MUST_OR_THROW_OOM(realm.heap().allocate<MouseEvent>(realm, realm, event_name, event_init));
  54. }
  55. WebIDL::ExceptionOr<JS::NonnullGCPtr<MouseEvent>> MouseEvent::create_from_platform_event(JS::Realm& realm, FlyString const& event_name, CSSPixelPoint offset, CSSPixelPoint client_offset, CSSPixelPoint page_offset, unsigned buttons, unsigned mouse_button)
  56. {
  57. MouseEventInit event_init {};
  58. event_init.offset_x = static_cast<double>(offset.x().value());
  59. event_init.offset_y = static_cast<double>(offset.y().value());
  60. event_init.client_x = static_cast<double>(client_offset.x().value());
  61. event_init.client_y = static_cast<double>(client_offset.y().value());
  62. event_init.page_x = static_cast<double>(page_offset.x().value());
  63. event_init.page_y = static_cast<double>(page_offset.y().value());
  64. event_init.button = determine_button(mouse_button);
  65. event_init.buttons = buttons;
  66. return MouseEvent::create(realm, event_name, event_init);
  67. }
  68. void MouseEvent::set_event_characteristics()
  69. {
  70. if (type().is_one_of(EventNames::mousedown, EventNames::mousemove, EventNames::mouseout, EventNames::mouseover, EventNames::mouseup, HTML::EventNames::click)) {
  71. set_bubbles(true);
  72. set_cancelable(true);
  73. set_composed(true);
  74. }
  75. }
  76. }