diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp index f05a6d2f46..4065ef10fa 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 7437e21add..9020eeeb49 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&);