1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-16 18:15:07 +00:00

LibWeb: Add a bare-bones HTML event loop with a task queue

This patch attaches a HTML::EventLoop to the main thread JS::VM used
for JavaScript bindings in the web engine.

The goal here is to model the various task scheduling mechanisms of the
HTML specification.
This commit is contained in:
Andreas Kling 2021-09-08 23:09:18 +02:00
parent b76456f0ed
commit ecb72f3b57
9 changed files with 180 additions and 1 deletions

View file

@ -13,7 +13,7 @@ JS::VM& main_thread_vm()
{
static RefPtr<JS::VM> vm;
if (!vm)
vm = JS::VM::create();
vm = JS::VM::create(make<WebEngineCustomData>());
return *vm;
}

View file

@ -7,9 +7,16 @@
#pragma once
#include <LibJS/Forward.h>
#include <LibWeb/HTML/EventLoop/EventLoop.h>
namespace Web::Bindings {
struct WebEngineCustomData final : public JS::VM::CustomData {
virtual ~WebEngineCustomData() override { }
HTML::EventLoop event_loop;
};
JS::VM& main_thread_vm();
}

View file

@ -71,6 +71,9 @@ set(SOURCES
HTML/BrowsingContextContainer.cpp
HTML/CanvasRenderingContext2D.cpp
HTML/DOMParser.cpp
HTML/EventLoop/EventLoop.cpp
HTML/EventLoop/Task.cpp
HTML/EventLoop/TaskQueue.cpp
HTML/EventNames.cpp
HTML/FormAssociatedElement.cpp
HTML/GlobalEventHandlers.cpp

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/VM.h>
#include <LibWeb/Bindings/MainThreadVM.h>
#include <LibWeb/HTML/EventLoop/EventLoop.h>
namespace Web::HTML {
EventLoop::EventLoop()
{
}
EventLoop::~EventLoop()
{
}
EventLoop& main_thread_event_loop()
{
return static_cast<Bindings::WebEngineCustomData*>(Bindings::main_thread_vm().custom_data())->event_loop;
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Function.h>
#include <LibWeb/HTML/EventLoop/TaskQueue.h>
namespace Web::HTML {
class EventLoop {
public:
EventLoop();
~EventLoop();
TaskQueue& task_queue() { return m_task_queue; }
TaskQueue const& task_queue() const { return m_task_queue; }
private:
TaskQueue m_task_queue;
};
EventLoop& main_thread_event_loop();
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/EventLoop/Task.h>
namespace Web::HTML {
Task::Task(DOM::Document* document, Function<void()> steps)
: m_steps(move(steps))
, m_document(document)
{
}
Task::~Task()
{
}
void Task::execute()
{
m_steps();
}
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Function.h>
#include <AK/NonnullOwnPtr.h>
#include <AK/RefPtr.h>
#include <LibWeb/Forward.h>
namespace Web::HTML {
class Task {
public:
static NonnullOwnPtr<Task> create(DOM::Document* document, Function<void()> steps)
{
return adopt_own(*new Task(document, move(steps)));
}
~Task();
void execute();
DOM::Document* document() { return m_document; }
DOM::Document const* document() const { return m_document; }
private:
Task(DOM::Document*, Function<void()> steps);
Function<void()> m_steps;
RefPtr<DOM::Document> m_document;
};
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/HTML/EventLoop/TaskQueue.h>
namespace Web::HTML {
TaskQueue::TaskQueue()
{
}
TaskQueue::~TaskQueue()
{
}
void TaskQueue::add(NonnullOwnPtr<Task> task)
{
m_tasks.enqueue(move(task));
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Queue.h>
#include <LibWeb/HTML/EventLoop/Task.h>
namespace Web::HTML {
class TaskQueue {
public:
TaskQueue();
~TaskQueue();
bool is_empty() const { return m_tasks.is_empty(); }
void add(NonnullOwnPtr<HTML::Task>);
OwnPtr<HTML::Task> take_first_runnable() { return m_tasks.dequeue(); }
private:
Queue<NonnullOwnPtr<HTML::Task>> m_tasks;
};
}