summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-10-03 12:39:56 +0200
committerAndreas Kling <kling@serenityos.org>2021-10-03 13:36:40 +0200
commit5cf439cce0115578d2b45164dd6c3a41714a4692 (patch)
tree5f3411d5262240bca6ba8c5549ab097ca5e2be93 /Userland/Libraries/LibWeb
parent9d170700478abb6145cf3fd811058092673423b7 (diff)
downloadserenity-5cf439cce0115578d2b45164dd6c3a41714a4692.zip
LibWeb: Run setTimeout() and setInterval() callbacks as HTML tasks
We now invoke DOM timer callbacks via HTML tasks. This brings callback sequencing closer to the spec, although there are still many imperfections in this area.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/DOM/Window.cpp19
-rw-r--r--Userland/Libraries/LibWeb/HTML/EventLoop/Task.h1
2 files changed, 11 insertions, 9 deletions
diff --git a/Userland/Libraries/LibWeb/DOM/Window.cpp b/Userland/Libraries/LibWeb/DOM/Window.cpp
index 4983e85ced..45e544f140 100644
--- a/Userland/Libraries/LibWeb/DOM/Window.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Window.cpp
@@ -146,20 +146,21 @@ i32 Window::set_timeout(JS::FunctionObject& callback, i32 interval)
void Window::timer_did_fire(Badge<Timer>, Timer& timer)
{
- // We should not be here if there's no JS wrapper for the Window object.
- VERIFY(wrapper());
- auto& vm = wrapper()->vm();
-
- // NOTE: This protector pointer keeps the timer alive until the end of this function no matter what.
- NonnullRefPtr protector(timer);
+ NonnullRefPtr<Timer> strong_timer { timer };
if (timer.type() == Timer::Type::Timeout) {
m_timers.remove(timer.id());
}
- [[maybe_unused]] auto rc = vm.call(timer.callback(), wrapper());
- if (vm.exception())
- vm.clear_exception();
+ HTML::queue_global_task(HTML::Task::Source::TimerTask, associated_document(), [this, strong_this = NonnullRefPtr(*this), strong_timer = NonnullRefPtr(timer)]() mutable {
+ // We should not be here if there's no JS wrapper for the Window object.
+ VERIFY(wrapper());
+ auto& vm = wrapper()->vm();
+
+ [[maybe_unused]] auto rc = vm.call(strong_timer->callback(), wrapper());
+ if (vm.exception())
+ vm.clear_exception();
+ });
}
i32 Window::allocate_timer_id(Badge<Timer>)
diff --git a/Userland/Libraries/LibWeb/HTML/EventLoop/Task.h b/Userland/Libraries/LibWeb/HTML/EventLoop/Task.h
index 36d9f30c5a..9b9402f3cc 100644
--- a/Userland/Libraries/LibWeb/HTML/EventLoop/Task.h
+++ b/Userland/Libraries/LibWeb/HTML/EventLoop/Task.h
@@ -25,6 +25,7 @@ public:
IdleTask,
PostedMessage,
Microtask,
+ TimerTask,
};
static NonnullOwnPtr<Task> create(Source source, DOM::Document* document, Function<void()> steps)