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.
This commit is contained in:
Andreas Kling 2021-10-03 12:39:56 +02:00
commit 5cf439cce0
Notes: sideshowbarker 2024-07-18 03:09:16 +09:00
2 changed files with 11 additions and 9 deletions

View file

@ -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>)

View file

@ -25,6 +25,7 @@ public:
IdleTask,
PostedMessage,
Microtask,
TimerTask,
};
static NonnullOwnPtr<Task> create(Source source, DOM::Document* document, Function<void()> steps)