Files
serenity/Userland/Libraries/LibWeb/HTML/SessionHistoryTraversalQueue.cpp
Andreas Kling 2c5f7ad8e4 LibWeb: Use a HashTable when querying SessionHistoryTraversalQueue
Instead of asking "do you have an entry not in this Vector", let's ask
"do you have an entry not in this HashTable".

(cherry picked from commit 861d46be3e69aeb1ca4a9e75029b4ce653bbcf47)
2024-11-17 13:47:42 -05:00

77 lines
2.5 KiB
C++

/*
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/HTML/Navigable.h>
#include <LibWeb/HTML/SessionHistoryTraversalQueue.h>
namespace Web::HTML {
JS_DEFINE_ALLOCATOR(SessionHistoryTraversalQueue);
JS_DEFINE_ALLOCATOR(SessionHistoryTraversalQueueEntry);
JS::NonnullGCPtr<SessionHistoryTraversalQueueEntry> SessionHistoryTraversalQueueEntry::create(JS::VM& vm, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps, JS::GCPtr<HTML::Navigable> target_navigable)
{
return vm.heap().allocate_without_realm<SessionHistoryTraversalQueueEntry>(steps, target_navigable);
}
void SessionHistoryTraversalQueueEntry::visit_edges(JS::Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_steps);
visitor.visit(m_target_navigable);
}
SessionHistoryTraversalQueue::SessionHistoryTraversalQueue()
{
m_timer = Core::Timer::create_single_shot(0, [this] {
if (m_is_task_running && m_queue.size() > 0) {
m_timer->start();
return;
}
while (m_queue.size() > 0) {
m_is_task_running = true;
auto entry = m_queue.take_first();
entry->execute_steps();
m_is_task_running = false;
}
});
}
void SessionHistoryTraversalQueue::visit_edges(JS::Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_queue);
}
void SessionHistoryTraversalQueue::append(JS::NonnullGCPtr<JS::HeapFunction<void()>> steps)
{
m_queue.append(SessionHistoryTraversalQueueEntry::create(vm(), steps, nullptr));
if (!m_timer->is_active()) {
m_timer->start();
}
}
void SessionHistoryTraversalQueue::append_sync(JS::NonnullGCPtr<JS::HeapFunction<void()>> steps, JS::GCPtr<Navigable> target_navigable)
{
m_queue.append(SessionHistoryTraversalQueueEntry::create(vm(), steps, target_navigable));
if (!m_timer->is_active()) {
m_timer->start();
}
}
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#sync-navigations-jump-queue
JS::GCPtr<SessionHistoryTraversalQueueEntry> SessionHistoryTraversalQueue::first_synchronous_navigation_steps_with_target_navigable_not_contained_in(HashTable<JS::NonnullGCPtr<Navigable>> const& set)
{
auto index = m_queue.find_first_index_if([&set](auto const& entry) -> bool {
return (entry->target_navigable() != nullptr) && !set.contains(*entry->target_navigable());
});
if (index.has_value())
return m_queue.take(*index);
return {};
}
}