/* * Copyright (c) 2023, Andrew Kaster * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Web::HTML { // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigateeventinit struct NavigateEventInit : public DOM::EventInit { Bindings::NavigationType navigation_type = Bindings::NavigationType::Push; JS::GCPtr destination; bool can_intercept = false; bool user_initiated = false; bool hash_change = false; JS::GCPtr signal; JS::GCPtr form_data = nullptr; Optional download_request = {}; Optional info; bool has_ua_visual_transition = false; }; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigationintercepthandler using NavigationInterceptHandler = JS::NonnullGCPtr; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigationinterceptoptions struct NavigationInterceptOptions { JS::GCPtr handler; Optional focus_reset; Optional scroll; }; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigateevent class NavigateEvent : public DOM::Event { WEB_PLATFORM_OBJECT(NavigateEvent, DOM::Event); JS_DECLARE_ALLOCATOR(NavigateEvent); public: // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-interception-state enum class InterceptionState { None, Intercepted, Committed, Scrolled, Finished }; [[nodiscard]] static JS::NonnullGCPtr construct_impl(JS::Realm&, FlyString const& event_name, NavigateEventInit const&); // The navigationType, destination, canIntercept, userInitiated, hashChange, signal, formData, // downloadRequest, info, and hasUAVisualTransition attributes must return the values they are initialized to. Bindings::NavigationType navigation_type() const { return m_navigation_type; } JS::NonnullGCPtr destination() const { return m_destination; } bool can_intercept() const { return m_can_intercept; } bool user_initiated() const { return m_user_initiated; } bool hash_change() const { return m_hash_change; } JS::NonnullGCPtr signal() const { return m_signal; } JS::GCPtr form_data() const { return m_form_data; } Optional download_request() const { return m_download_request; } JS::Value info() const { return m_info; } bool has_ua_visual_transition() const { return m_has_ua_visual_transition; } WebIDL::ExceptionOr intercept(NavigationInterceptOptions const&); WebIDL::ExceptionOr scroll(); virtual ~NavigateEvent() override; JS::NonnullGCPtr abort_controller() const { return *m_abort_controller; } InterceptionState interception_state() const { return m_interception_state; } Vector const& navigation_handler_list() const { return m_navigation_handler_list; } Optional classic_history_api_state() const { return m_classic_history_api_state; } void set_abort_controller(JS::NonnullGCPtr c) { m_abort_controller = c; } void set_interception_state(InterceptionState s) { m_interception_state = s; } void set_classic_history_api_state(Optional r) { m_classic_history_api_state = move(r); } void finish(bool did_fulfill); private: NavigateEvent(JS::Realm&, FlyString const& event_name, NavigateEventInit const& event_init); virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; WebIDL::ExceptionOr perform_shared_checks(); void process_scroll_behavior(); void potentially_process_scroll_behavior(); void potentially_reset_the_focus(); // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-interception-state InterceptionState m_interception_state = InterceptionState::None; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-navigation-handler-list Vector m_navigation_handler_list; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-focusreset Optional m_focus_reset_behavior = {}; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-scroll Optional m_scroll_behavior = {}; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-abort-controller JS::GCPtr m_abort_controller = { nullptr }; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-classic-history-api-state Optional m_classic_history_api_state = {}; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-navigationtype Bindings::NavigationType m_navigation_type = { Bindings::NavigationType::Push }; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-destination JS::NonnullGCPtr m_destination; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-canintercept bool m_can_intercept = { false }; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-userinitiated bool m_user_initiated = { false }; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-hashchange bool m_hash_change = { false }; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-signal JS::NonnullGCPtr m_signal; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-formdata JS::GCPtr m_form_data; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-downloadrequest Optional m_download_request; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-info JS::Value m_info; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-hasuavisualtransition bool m_has_ua_visual_transition { false }; }; } namespace AK { template<> struct Formatter : Formatter { ErrorOr format(FormatBuilder& builder, Web::Bindings::NavigationScrollBehavior const& value) { return Formatter::format(builder, Web::Bindings::idl_enum_to_string(value)); } }; template<> struct Formatter : Formatter { ErrorOr format(FormatBuilder& builder, Web::Bindings::NavigationFocusReset const& value) { return Formatter::format(builder, Web::Bindings::idl_enum_to_string(value)); } }; }