From dce6327ae701ac9b77aec69198f140a812f90581 Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Wed, 26 Oct 2022 18:15:46 +0100 Subject: [PATCH] LibWeb: Add the ability for an AbortSignal to follow another Following another abort signal basically means to make an abort signal abort when another abort signal is aborted, unless the following signal is already aborted. --- Userland/Libraries/LibWeb/DOM/AbortSignal.cpp | 23 +++++++++++++++++++ Userland/Libraries/LibWeb/DOM/AbortSignal.h | 2 ++ 2 files changed, 25 insertions(+) diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp index f05a6d2f46a..4065ef10fac 100644 --- a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp +++ b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp @@ -84,4 +84,27 @@ void AbortSignal::visit_edges(JS::Cell::Visitor& visitor) visitor.visit(m_abort_reason); } +// https://dom.spec.whatwg.org/#abortsignal-follow +void AbortSignal::follow(JS::NonnullGCPtr parent_signal) +{ + // A followingSignal (an AbortSignal) is made to follow a parentSignal (an AbortSignal) by running these steps: + + // 1. If followingSignal is aborted, then return. + if (aborted()) + return; + + // 2. If parentSignal is aborted, then signal abort on followingSignal with parentSignal’s abort reason. + if (parent_signal->aborted()) { + signal_abort(parent_signal->reason()); + return; + } + + // 3. Otherwise, add the following abort steps to parentSignal: + // NOTE: `this` and `parent_signal` are protected by AbortSignal using JS::SafeFunction. + parent_signal->add_abort_algorithm([this, parent_signal]() mutable { + // 1. Signal abort on followingSignal with parentSignal’s abort reason. + signal_abort(parent_signal->reason()); + }); +} + } diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.h b/Userland/Libraries/LibWeb/DOM/AbortSignal.h index 7437e21add5..9020eeeb492 100644 --- a/Userland/Libraries/LibWeb/DOM/AbortSignal.h +++ b/Userland/Libraries/LibWeb/DOM/AbortSignal.h @@ -38,6 +38,8 @@ public: JS::ThrowCompletionOr throw_if_aborted() const; + void follow(JS::NonnullGCPtr parent_signal); + private: explicit AbortSignal(JS::Realm&);