diff options
author | Andreas Kling <kling@serenityos.org> | 2021-10-03 12:39:56 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-10-03 13:36:40 +0200 |
commit | 5cf439cce0115578d2b45164dd6c3a41714a4692 (patch) | |
tree | 5f3411d5262240bca6ba8c5549ab097ca5e2be93 /Userland/Libraries/LibWeb | |
parent | 9d170700478abb6145cf3fd811058092673423b7 (diff) | |
download | serenity-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.cpp | 19 | ||||
-rw-r--r-- | Userland/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& 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) |