From 5cf439cce0115578d2b45164dd6c3a41714a4692 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 3 Oct 2021 12:39:56 +0200 Subject: [PATCH] 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. --- Userland/Libraries/LibWeb/DOM/Window.cpp | 19 ++++++++++--------- .../Libraries/LibWeb/HTML/EventLoop/Task.h | 1 + 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) { - // 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 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) 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 create(Source source, DOM::Document* document, Function steps)