From 67bc3629a9b053050f5f4271f6cb01ad3694e721 Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Fri, 22 Sep 2023 19:18:50 -0600 Subject: [PATCH] LibWeb: Implement fire a push/replace/reload navigate event --- Userland/Libraries/LibWeb/HTML/Navigation.cpp | 42 +++++++++++++++++++ Userland/Libraries/LibWeb/HTML/Navigation.h | 8 ++++ 2 files changed, 50 insertions(+) diff --git a/Userland/Libraries/LibWeb/HTML/Navigation.cpp b/Userland/Libraries/LibWeb/HTML/Navigation.cpp index 942cbb8b26..2f7e535cfe 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigation.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigation.cpp @@ -1252,4 +1252,46 @@ bool Navigation::fire_a_traverse_navigate_event(JS::NonnullGCPtr&> form_data_entry_list, + Optional navigation_api_state, + Optional classic_history_api_state) +{ + auto& realm = relevant_realm(*this); + auto& vm = this->vm(); + + // This fulfills the entry requirement: an optional serialized state navigationAPIState (default StructuredSerializeForStorage(null)) + if (!navigation_api_state.has_value()) + navigation_api_state = MUST(structured_serialize_for_storage(vm, JS::js_null())); + + // 1. Let event be the result of creating an event given NavigateEvent, in navigation's relevant realm. + // 2. Set event's classic history API state to classicHistoryAPIState. + // AD-HOC: These are handled in the inner algorithm + + // 3. Let destination be a new NavigationDestination created in navigation's relevant realm. + auto destination = NavigationDestination::create(realm); + + // 4. Set destination's URL to destinationURL. + destination->set_url(destination_url); + + // 5. Set destination's entry to null. + destination->set_entry(nullptr); + + // 6. Set destination's state to navigationAPIState. + destination->set_state(*navigation_api_state); + + // 7. Set destination's is same document to isSameDocument. + destination->set_is_same_document(is_same_document); + + // 8. Return the result of performing the inner navigate event firing algorithm given navigation, + // navigationType, event, destination, userInvolvement, formDataEntryList, and null. + // AD-HOC: We don't pass the event, but we do pass the classic_history_api state at the end to be set later + return inner_navigate_event_firing_algorithm(navigation_type, destination, user_involvement, move(form_data_entry_list), {}, move(classic_history_api_state)); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/Navigation.h b/Userland/Libraries/LibWeb/HTML/Navigation.h index 709ac53c14..d39f08e7f2 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigation.h +++ b/Userland/Libraries/LibWeb/HTML/Navigation.h @@ -110,6 +110,14 @@ public: i64 get_the_navigation_api_entry_index(SessionHistoryEntry const&) const; void abort_the_ongoing_navigation(Optional> error = {}); bool fire_a_traverse_navigate_event(JS::NonnullGCPtr destination_she, UserNavigationInvolvement = UserNavigationInvolvement::None); + bool fire_a_push_replace_reload_navigate_event( + Bindings::NavigationType, + AK::URL destination_url, + bool is_same_document, + UserNavigationInvolvement = UserNavigationInvolvement::None, + Optional&> form_data_entry_list = {}, + Optional navigation_api_state = {}, + Optional classic_history_api_state = {}); virtual ~Navigation() override;