From 699ead09399dd060795efcdff5d6211cb6e7df84 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Sat, 23 Sep 2023 22:59:27 +0200 Subject: [PATCH] LibWeb: Start fleshing out update document for history step application --- Userland/Libraries/LibWeb/DOM/Document.cpp | 33 +++++++++++++++++++ Userland/Libraries/LibWeb/DOM/Document.h | 5 +++ Userland/Libraries/LibWeb/HTML/Navigable.cpp | 20 +++++++---- .../LibWeb/HTML/TraversableNavigable.cpp | 14 ++++---- .../LibWeb/HTML/TraversableNavigable.h | 4 +-- 5 files changed, 62 insertions(+), 14 deletions(-) diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index abd3bb2c56..c41249c9be 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -3489,4 +3489,37 @@ Painting::ViewportPaintable* Document::paintable() return static_cast(Node::paintable()); } +// https://html.spec.whatwg.org/multipage/browsing-the-web.html#update-document-for-history-step-application +void Document::update_for_history_step_application(JS::NonnullGCPtr entry, bool do_not_reactive, size_t script_history_length, size_t script_history_index) +{ + // 1. Let documentIsNew be true if document's latest entry is null; otherwise false. + auto document_is_new = !m_latest_entry; + + // 2. Let documentsEntryChanged be true if document's latest entry is not entry; otherwise false. + auto documents_entry_changed = m_latest_entry != entry; + + // 3. Set document's history object's index to scriptHistoryIndex. + history()->m_index = script_history_index; + + // 4. Set document's history object's length to scriptHistoryLength. + history()->m_length = script_history_length; + + // 5. If documentsEntryChanged is true, then: + if (documents_entry_changed) { + // FIXME: Implement this. + } + + // 6. If documentIsNew is true, then: + if (document_is_new) { + // FIXME: 1. Try to scroll to the fragment for document. + // FIXME: 2. At this point scripts may run for the newly-created document document. + } + + // 7. Otherwise, if documentsEntryChanged is false and doNotReactivate is false, then: + if (!documents_entry_changed && !do_not_reactive) { + // FIXME: 1. Assert: entriesForNavigationAPI is given. + // FIXME: 2. Reactivate document given entry and entriesForNavigationAPI. + } +} + } diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index e4a0bcdb97..1fb3507960 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -531,6 +531,8 @@ public: HTML::SourceSnapshotParams snapshot_source_snapshot_params() const; + void update_for_history_step_application(JS::NonnullGCPtr, bool do_not_reactive, size_t script_history_length, size_t script_history_index); + protected: virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; @@ -730,6 +732,9 @@ private: RefPtr m_active_refresh_timer; bool m_temporary_document_for_fragment_parsing { false }; + + // https://html.spec.whatwg.org/multipage/browsing-the-web.html#latest-entry + JS::GCPtr m_latest_entry; }; template<> diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp index c276b339d8..fd8573f135 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp @@ -1330,23 +1330,31 @@ WebIDL::ExceptionOr Navigable::navigate_to_a_fragment(AK::URL const& url, // 7. Let entryToReplace be navigable's active session history entry if historyHandling is "replace", otherwise null. auto entry_to_replace = history_handling == HistoryHandlingBehavior::Replace ? active_session_history_entry() : nullptr; - // FIXME: 8. Let history be navigable's active document's history object. + // 8. Let history be navigable's active document's history object. + auto history = active_document()->history(); - // FIXME: 9. Let scriptHistoryIndex be history's index. + // 9. Let scriptHistoryIndex be history's index. + auto script_history_index = history->m_index; - // FIXME: 10. Let scriptHistoryIndex be history's index. + // 10. Let scriptHistoryLength be history's length. + auto script_history_length = history->m_length; // 11. If historyHandling is "push", then: if (history_handling == HistoryHandlingBehavior::Push) { // FIXME: 1. Set history's state to null. - // FIXME: 2. Increment scriptHistoryIndex. - // FIXME: 3. Set scriptHistoryLength to scriptHistoryIndex + 1. + + // 2. Increment scriptHistoryIndex. + script_history_index++; + + // 3. Set scriptHistoryLength to scriptHistoryIndex + 1. + script_history_length = script_history_index + 1; } // 12. Set navigable's active session history entry to historyEntry. m_active_session_history_entry = history_entry; - // FIXME: 13. Update document for history step application given navigable's active document, historyEntry, true, scriptHistoryIndex, and scriptHistoryLength. + // 13. Update document for history step application given navigable's active document, historyEntry, true, scriptHistoryIndex, and scriptHistoryLength. + active_document()->update_for_history_step_application(*history_entry, true, script_history_length, script_history_index); // FIXME: 14. Update the navigation API entries for a same-document navigation given navigation, historyEntry, and historyHandling. diff --git a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp index bf4c866c95..3bd2066f8a 100644 --- a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp @@ -407,14 +407,14 @@ void TraversableNavigable::apply_the_history_step(int step, Optionalset_ongoing_navigation({}); // 8. Let (scriptHistoryLength, scriptHistoryIndex) be the result of getting the history object length and index given traversable and targetStep. - auto [script_history_length, script_history_index] = get_the_history_object_length_and_index(target_step); - (void)script_history_length; - (void)script_history_index; + auto history_object_length_and_index = get_the_history_object_length_and_index(target_step); + auto script_history_length = history_object_length_and_index.script_history_length; + auto script_history_index = history_object_length_and_index.script_history_index; // FIXME: 9. Append navigable to navigablesThatMustWaitBeforeHandlingSyncNavigation. // 10. Queue a global task on the navigation and traversal task source given navigable's active window to run the steps: - queue_global_task(Task::Source::NavigationAndTraversal, *navigable->active_window(), [&, target_entry, navigable, displayed_document, update_only = changing_navigable_continuation.update_only] { + queue_global_task(Task::Source::NavigationAndTraversal, *navigable->active_window(), [&, target_entry, navigable, displayed_document, update_only = changing_navigable_continuation.update_only, script_history_length, script_history_index] { // NOTE: This check is not in the spec but we should not continue navigation if navigable has been destroyed. if (navigable->has_been_destroyed()) return; @@ -439,8 +439,10 @@ void TraversableNavigable::apply_the_history_step(int step, Optionaldocument_state->document()->update_for_history_step_application(*target_entry, update_only, script_history_length, script_history_index); // 4. Increment completedChangeJobs. completed_change_jobs++; diff --git a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h index 7a442cece8..f835192448 100644 --- a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h +++ b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h @@ -34,8 +34,8 @@ public: void set_system_visibility_state(VisibilityState); struct HistoryObjectLengthAndIndex { - size_t script_history_length; - size_t script_history_index; + u64 script_history_length; + u64 script_history_index; }; HistoryObjectLengthAndIndex get_the_history_object_length_and_index(int) const;