NavigateEvent.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <LibWeb/Bindings/NavigateEventPrototype.h>
  8. #include <LibWeb/DOM/Event.h>
  9. #include <LibWeb/HTML/NavigationType.h>
  10. #include <LibWeb/HTML/StructuredSerialize.h>
  11. namespace Web::HTML {
  12. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigateeventinit
  13. struct NavigateEventInit : public DOM::EventInit {
  14. Bindings::NavigationType navigation_type = Bindings::NavigationType::Push;
  15. JS::GCPtr<NavigationDestination> destination;
  16. bool can_intercept = false;
  17. bool user_initiated = false;
  18. bool hash_change = false;
  19. JS::GCPtr<DOM::AbortSignal> signal;
  20. JS::GCPtr<XHR::FormData> form_data = nullptr;
  21. Optional<String> download_request = {};
  22. Optional<JS::Value> info;
  23. bool has_ua_visual_transition = false;
  24. };
  25. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigationintercepthandler
  26. using NavigationInterceptHandler = JS::NonnullGCPtr<WebIDL::CallbackType>;
  27. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigationinterceptoptions
  28. struct NavigationInterceptOptions {
  29. JS::GCPtr<WebIDL::CallbackType> handler;
  30. Optional<Bindings::NavigationFocusReset> focus_reset;
  31. Optional<Bindings::NavigationScrollBehavior> scroll;
  32. };
  33. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigateevent
  34. class NavigateEvent : public DOM::Event {
  35. WEB_PLATFORM_OBJECT(NavigateEvent, DOM::Event);
  36. JS_DECLARE_ALLOCATOR(NavigateEvent);
  37. public:
  38. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-interception-state
  39. enum class InterceptionState {
  40. None,
  41. Intercepted,
  42. Committed,
  43. Scrolled,
  44. Finished
  45. };
  46. [[nodiscard]] static JS::NonnullGCPtr<NavigateEvent> construct_impl(JS::Realm&, FlyString const& event_name, NavigateEventInit const&);
  47. // The navigationType, destination, canIntercept, userInitiated, hashChange, signal, formData,
  48. // downloadRequest, info, and hasUAVisualTransition attributes must return the values they are initialized to.
  49. Bindings::NavigationType navigation_type() const { return m_navigation_type; }
  50. JS::NonnullGCPtr<NavigationDestination> destination() const { return m_destination; }
  51. bool can_intercept() const { return m_can_intercept; }
  52. bool user_initiated() const { return m_user_initiated; }
  53. bool hash_change() const { return m_hash_change; }
  54. JS::NonnullGCPtr<DOM::AbortSignal> signal() const { return m_signal; }
  55. JS::GCPtr<XHR::FormData> form_data() const { return m_form_data; }
  56. Optional<String> download_request() const { return m_download_request; }
  57. JS::Value info() const { return m_info; }
  58. bool has_ua_visual_transition() const { return m_has_ua_visual_transition; }
  59. WebIDL::ExceptionOr<void> intercept(NavigationInterceptOptions const&);
  60. WebIDL::ExceptionOr<void> scroll();
  61. virtual ~NavigateEvent() override;
  62. JS::NonnullGCPtr<DOM::AbortController> abort_controller() const { return *m_abort_controller; }
  63. InterceptionState interception_state() const { return m_interception_state; }
  64. Vector<NavigationInterceptHandler> const& navigation_handler_list() const { return m_navigation_handler_list; }
  65. Optional<SerializationRecord> classic_history_api_state() const { return m_classic_history_api_state; }
  66. void set_abort_controller(JS::NonnullGCPtr<DOM::AbortController> c) { m_abort_controller = c; }
  67. void set_interception_state(InterceptionState s) { m_interception_state = s; }
  68. void set_classic_history_api_state(Optional<SerializationRecord> r) { m_classic_history_api_state = move(r); }
  69. void finish(bool did_fulfill);
  70. private:
  71. NavigateEvent(JS::Realm&, FlyString const& event_name, NavigateEventInit const& event_init);
  72. virtual void initialize(JS::Realm&) override;
  73. virtual void visit_edges(Cell::Visitor&) override;
  74. WebIDL::ExceptionOr<void> perform_shared_checks();
  75. void process_scroll_behavior();
  76. void potentially_process_scroll_behavior();
  77. void potentially_reset_the_focus();
  78. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-interception-state
  79. InterceptionState m_interception_state = InterceptionState::None;
  80. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-navigation-handler-list
  81. Vector<NavigationInterceptHandler> m_navigation_handler_list;
  82. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-focusreset
  83. Optional<Bindings::NavigationFocusReset> m_focus_reset_behavior = {};
  84. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-scroll
  85. Optional<Bindings::NavigationScrollBehavior> m_scroll_behavior = {};
  86. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-abort-controller
  87. JS::GCPtr<DOM::AbortController> m_abort_controller = { nullptr };
  88. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-classic-history-api-state
  89. Optional<SerializationRecord> m_classic_history_api_state = {};
  90. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-navigationtype
  91. Bindings::NavigationType m_navigation_type = { Bindings::NavigationType::Push };
  92. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-destination
  93. JS::NonnullGCPtr<NavigationDestination> m_destination;
  94. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-canintercept
  95. bool m_can_intercept = { false };
  96. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-userinitiated
  97. bool m_user_initiated = { false };
  98. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-hashchange
  99. bool m_hash_change = { false };
  100. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-signal
  101. JS::NonnullGCPtr<DOM::AbortSignal> m_signal;
  102. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-formdata
  103. JS::GCPtr<XHR::FormData> m_form_data;
  104. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-downloadrequest
  105. Optional<String> m_download_request;
  106. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-info
  107. JS::Value m_info;
  108. // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-hasuavisualtransition
  109. bool m_has_ua_visual_transition { false };
  110. };
  111. }
  112. namespace AK {
  113. template<>
  114. struct Formatter<Web::Bindings::NavigationScrollBehavior> : Formatter<StringView> {
  115. ErrorOr<void> format(FormatBuilder& builder, Web::Bindings::NavigationScrollBehavior const& value)
  116. {
  117. return Formatter<StringView>::format(builder, Web::Bindings::idl_enum_to_string(value));
  118. }
  119. };
  120. template<>
  121. struct Formatter<Web::Bindings::NavigationFocusReset> : Formatter<StringView> {
  122. ErrorOr<void> format(FormatBuilder& builder, Web::Bindings::NavigationFocusReset const& value)
  123. {
  124. return Formatter<StringView>::format(builder, Web::Bindings::idl_enum_to_string(value));
  125. }
  126. };
  127. }