1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:47:36 +00:00

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
parent 9d17070047
commit 5cf439cce0
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>)