mirror of
				https://github.com/LadybirdBrowser/ladybird.git
				synced 2025-10-27 02:20:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			76 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			76 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, Function<void()> steps, JS::GCPtr<HTML::Navigable> target_navigable)
 | |
| {
 | |
|     return vm.heap().allocate_without_realm<SessionHistoryTraversalQueueEntry>(JS::create_heap_function(vm.heap(), move(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(Function<void()> steps)
 | |
| {
 | |
|     m_queue.append(SessionHistoryTraversalQueueEntry::create(vm(), move(steps), nullptr));
 | |
|     if (!m_timer->is_active()) {
 | |
|         m_timer->start();
 | |
|     }
 | |
| }
 | |
| 
 | |
| void SessionHistoryTraversalQueue::append_sync(Function<void()> steps, JS::GCPtr<Navigable> target_navigable)
 | |
| {
 | |
|     m_queue.append(SessionHistoryTraversalQueueEntry::create(vm(), move(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(Vector<JS::GCPtr<Navigable>> const& list)
 | |
| {
 | |
|     auto index = m_queue.find_first_index_if([&list](auto const& entry) -> bool {
 | |
|         return (entry->target_navigable() != nullptr) && !list.contains_slow(entry->target_navigable());
 | |
|     });
 | |
|     if (index.has_value())
 | |
|         return m_queue.take(*index);
 | |
|     return {};
 | |
| }
 | |
| 
 | |
| }
 |