1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 23:27:36 +00:00

LibWeb: Add SessionHistoryTraversalQueue

This commit is contained in:
Aliaksandr Kalenik 2023-07-25 01:22:57 +02:00 committed by Andreas Kling
parent 6d866dc5ba
commit 08788072c1
5 changed files with 134 additions and 80 deletions

View file

@ -939,7 +939,8 @@ WebIDL::ExceptionOr<void> Navigable::navigate(
// for historyEntry, given navigable, "navigate", sourceSnapshotParams, // for historyEntry, given navigable, "navigate", sourceSnapshotParams,
// targetSnapshotParams, navigationId, navigationParams, cspNavigationType, with allowPOST // targetSnapshotParams, navigationId, navigationParams, cspNavigationType, with allowPOST
// set to true and completionSteps set to the following step: // set to true and completionSteps set to the following step:
populate_session_history_entry_document(history_entry, navigation_params, navigation_id, source_snapshot_params, [this, history_entry, history_handling] { populate_session_history_entry_document(history_entry, navigation_params, navigation_id, source_snapshot_params, [this, history_entry, history_handling, navigation_id] {
traversable_navigable()->append_session_history_traversal_steps([this, history_entry, history_handling, navigation_id] {
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#finalize-a-cross-document-navigation // https://html.spec.whatwg.org/multipage/browsing-the-web.html#finalize-a-cross-document-navigation
// 1. FIXME: Assert: this is running on navigable's traversable navigable's session history traversal queue. // 1. FIXME: Assert: this is running on navigable's traversable navigable's session history traversal queue.
@ -972,6 +973,7 @@ WebIDL::ExceptionOr<void> Navigable::navigate(
// 9. If entryToReplace is null, then: // 9. If entryToReplace is null, then:
if (entry_to_replace == nullptr) { if (entry_to_replace == nullptr) {
// FIXME: 1. Clear the forward session history of traversable. // FIXME: 1. Clear the forward session history of traversable.
traversable->clear_the_forward_session_history();
// 2. Set targetStep to traversable's current session history step + 1. // 2. Set targetStep to traversable's current session history step + 1.
target_step = traversable->current_session_history_step() + 1; target_step = traversable->current_session_history_step() + 1;
@ -994,6 +996,7 @@ WebIDL::ExceptionOr<void> Navigable::navigate(
// 10. Apply the history step targetStep to traversable. // 10. Apply the history step targetStep to traversable.
traversable->apply_the_history_step(target_step); traversable->apply_the_history_step(target_step);
});
}).release_value_but_fixme_should_propagate_errors(); }).release_value_but_fixme_should_propagate_errors();
}); });
@ -1022,10 +1025,11 @@ void Navigable::reload()
// 2. Let traversable be navigable's traversable navigable. // 2. Let traversable be navigable's traversable navigable.
auto traversable = traversable_navigable(); auto traversable = traversable_navigable();
// FIXME: 3. Append the following session history traversal steps to traversable: // 3. Append the following session history traversal steps to traversable:
traversable->append_session_history_traversal_steps([traversable] {
// 1. Apply pending history changes to traversable with true. // 1. Apply pending history changes to traversable with true.
traversable->apply_pending_history_changes(); traversable->apply_pending_history_changes();
});
} }
} }

View file

@ -102,8 +102,8 @@ WebIDL::ExceptionOr<void> NavigableContainer::create_new_child_navigable()
// 11. Let traversable be parentNavigable's traversable navigable. // 11. Let traversable be parentNavigable's traversable navigable.
auto traversable = parent_navigable->traversable_navigable(); auto traversable = parent_navigable->traversable_navigable();
// FIXME: 12. Append the following session history traversal steps to traversable: // 12. Append the following session history traversal steps to traversable:
traversable->append_session_history_traversal_steps([traversable, navigable, parent_navigable, history_entry] {
// 1. Let parentDocState be parentNavigable's active session history entry's document state. // 1. Let parentDocState be parentNavigable's active session history entry's document state.
auto parent_doc_state = parent_navigable->active_session_history_entry()->document_state; auto parent_doc_state = parent_navigable->active_session_history_entry()->document_state;
@ -126,6 +126,7 @@ WebIDL::ExceptionOr<void> NavigableContainer::create_new_child_navigable()
parent_doc_state->nested_histories().append(move(nested_history)); parent_doc_state->nested_histories().append(move(nested_history));
// FIXME: 6. Update for navigable creation/destruction given traversable // FIXME: 6. Update for navigable creation/destruction given traversable
});
return {}; return {};
} }
@ -342,10 +343,11 @@ void NavigableContainer::destroy_the_child_navigable()
// 7. Let traversable be container's node navigable's traversable navigable. // 7. Let traversable be container's node navigable's traversable navigable.
auto traversable = this->navigable()->traversable_navigable(); auto traversable = this->navigable()->traversable_navigable();
// FIXME: 8. Append the following session history traversal steps to traversable: // 8. Append the following session history traversal steps to traversable:
traversable->append_session_history_traversal_steps([traversable] {
// 1. Apply pending history changes to traversable. // 1. Apply pending history changes to traversable.
traversable->apply_pending_history_changes(); traversable->apply_pending_history_changes();
});
} }
} }

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibCore/Timer.h>
namespace Web::HTML {
// https://html.spec.whatwg.org/multipage/document-sequences.html#tn-session-history-traversal-queue
class SessionHistoryTraversalQueue {
public:
SessionHistoryTraversalQueue()
{
m_timer = Core::Timer::create_single_shot(0, [this] {
while (m_queue.size() > 0) {
auto steps = m_queue.take_first();
steps();
}
}).release_value_but_fixme_should_propagate_errors();
}
void append(JS::SafeFunction<void()> steps)
{
m_queue.append(move(steps));
if (!m_timer->is_active()) {
m_timer->start();
}
}
private:
Vector<JS::SafeFunction<void()>> m_queue;
RefPtr<Core::Timer> m_timer;
};
}

View file

@ -479,7 +479,7 @@ void TraversableNavigable::traverse_the_history_by_delta(int delta)
// FIXME: 2. If sourceDocument is given, then: // FIXME: 2. If sourceDocument is given, then:
// 3. Append the following session history traversal steps to traversable: // 3. Append the following session history traversal steps to traversable:
append_session_history_traversal_steps([this, delta] {
// 1. Let allSteps be the result of getting all used history steps for traversable. // 1. Let allSteps be the result of getting all used history steps for traversable.
auto all_steps = get_all_used_history_steps(); auto all_steps = get_all_used_history_steps();
@ -497,6 +497,7 @@ void TraversableNavigable::traverse_the_history_by_delta(int delta)
// 5. Apply the history step allSteps[targetStepIndex] to traversable, with checkForUserCancelation set to true, // 5. Apply the history step allSteps[targetStepIndex] to traversable, with checkForUserCancelation set to true,
// sourceSnapshotParams set to sourceSnapshotParams, and initiatorToCheck set to initiatorToCheck. // sourceSnapshotParams set to sourceSnapshotParams, and initiatorToCheck set to initiatorToCheck.
apply_the_history_step(all_steps[target_step_index]); apply_the_history_step(all_steps[target_step_index]);
});
} }
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#apply-pending-history-changes // https://html.spec.whatwg.org/multipage/browsing-the-web.html#apply-pending-history-changes

View file

@ -8,6 +8,7 @@
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibWeb/HTML/Navigable.h> #include <LibWeb/HTML/Navigable.h>
#include <LibWeb/HTML/SessionHistoryTraversalQueue.h>
#include <LibWeb/HTML/VisibilityState.h> #include <LibWeb/HTML/VisibilityState.h>
namespace Web::HTML { namespace Web::HTML {
@ -47,6 +48,11 @@ public:
void destroy_top_level_traversable(); void destroy_top_level_traversable();
void append_session_history_traversal_steps(JS::SafeFunction<void()> steps)
{
m_session_history_traversal_queue.append(move(steps));
}
private: private:
TraversableNavigable(); TraversableNavigable();
@ -65,6 +71,8 @@ private:
// https://html.spec.whatwg.org/multipage/document-sequences.html#system-visibility-state // https://html.spec.whatwg.org/multipage/document-sequences.html#system-visibility-state
VisibilityState m_system_visibility_state { VisibilityState::Visible }; VisibilityState m_system_visibility_state { VisibilityState::Visible };
SessionHistoryTraversalQueue m_session_history_traversal_queue;
}; };
} }