mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:28:10 +00:00
LibWeb: Add NavigateEvent, the main event of the Navigation API
This event is the star of the show, and the main way that web content can react to either programmatic or user-initiated navigation. All of the fun algorithms will have to come later though.
This commit is contained in:
parent
5374fbfbcf
commit
d1aea87889
9 changed files with 408 additions and 0 deletions
148
Userland/Libraries/LibWeb/HTML/NavigateEvent.h
Normal file
148
Userland/Libraries/LibWeb/HTML/NavigateEvent.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/NavigateEventPrototype.h>
|
||||
#include <LibWeb/DOM/Event.h>
|
||||
#include <LibWeb/HTML/NavigationType.h>
|
||||
#include <LibWeb/HTML/StructuredSerialize.h>
|
||||
|
||||
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<NavigationDestination> destination;
|
||||
bool can_intercept = false;
|
||||
bool user_initiated = false;
|
||||
bool hash_change = false;
|
||||
JS::GCPtr<DOM::AbortSignal> signal;
|
||||
JS::GCPtr<XHR::FormData> form_data = nullptr;
|
||||
Optional<String> download_request = {};
|
||||
JS::Value info;
|
||||
bool has_ua_visual_transition = false;
|
||||
};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigationintercepthandler
|
||||
using NavigationInterceptHandler = JS::NonnullGCPtr<WebIDL::CallbackType>;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigationinterceptoptions
|
||||
struct NavigationInterceptOptions {
|
||||
JS::GCPtr<WebIDL::CallbackType> handler;
|
||||
Bindings::NavigationFocusReset focus_reset;
|
||||
Bindings::NavigationScrollBehavior scroll;
|
||||
};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigateevent
|
||||
class NavigateEvent : public DOM::Event {
|
||||
WEB_PLATFORM_OBJECT(NavigateEvent, DOM::Event);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static JS::NonnullGCPtr<NavigateEvent> 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<NavigationDestination> 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<DOM::AbortSignal> signal() const { return m_signal; }
|
||||
JS::GCPtr<XHR::FormData> form_data() const { return m_form_data; }
|
||||
Optional<String> 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<void> intercept(Optional<NavigationInterceptOptions> const& = {});
|
||||
WebIDL::ExceptionOr<void> scroll();
|
||||
|
||||
virtual ~NavigateEvent() override;
|
||||
|
||||
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<void> perform_shared_checks();
|
||||
void process_scroll_behavior();
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-interception-state
|
||||
enum class InterceptionState {
|
||||
None,
|
||||
Intercepted,
|
||||
Committed,
|
||||
Scrolled,
|
||||
Finished
|
||||
};
|
||||
InterceptionState m_interception_state = InterceptionState::None;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-navigation-handler-list
|
||||
Vector<NavigationInterceptHandler> m_navigation_handler_list;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-focusreset
|
||||
Optional<Bindings::NavigationFocusReset> m_focus_reset_behavior = {};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-scroll
|
||||
Optional<Bindings::NavigationScrollBehavior> m_scroll_behavior = {};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-abort-controller
|
||||
JS::GCPtr<DOM::AbortController> m_abort_controller = { nullptr };
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigateevent-classic-history-api-state
|
||||
Optional<SerializationRecord> 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<NavigationDestination> 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<DOM::AbortSignal> m_signal;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-formdata
|
||||
JS::GCPtr<XHR::FormData> m_form_data;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigateevent-downloadrequest
|
||||
Optional<String> 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<Web::Bindings::NavigationScrollBehavior> : Formatter<StringView> {
|
||||
ErrorOr<void> format(FormatBuilder& builder, Web::Bindings::NavigationScrollBehavior const& value)
|
||||
{
|
||||
return Formatter<StringView>::format(builder, Web::Bindings::idl_enum_to_string(value));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Formatter<Web::Bindings::NavigationFocusReset> : Formatter<StringView> {
|
||||
ErrorOr<void> format(FormatBuilder& builder, Web::Bindings::NavigationFocusReset const& value)
|
||||
{
|
||||
return Formatter<StringView>::format(builder, Web::Bindings::idl_enum_to_string(value));
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue