diff --git a/Tests/LibWeb/Text/expected/DOM/AbortSignal-any-crash.txt b/Tests/LibWeb/Text/expected/DOM/AbortSignal-any-crash.txt
new file mode 100644
index 00000000000..47a5310842d
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/DOM/AbortSignal-any-crash.txt
@@ -0,0 +1 @@
+PASS (didn't crash)
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/input/DOM/AbortSignal-any-crash.html b/Tests/LibWeb/Text/input/DOM/AbortSignal-any-crash.html
new file mode 100644
index 00000000000..1204b6200d7
--- /dev/null
+++ b/Tests/LibWeb/Text/input/DOM/AbortSignal-any-crash.html
@@ -0,0 +1,11 @@
+
+
+
diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp
index d333b9611a0..26234e4b522 100644
--- a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp
+++ b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2021, Luke Wilde
- * Copyright (c) 2024, Tim Ledbetter
+ * Copyright (c) 2024, Tim Ledbetter
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -58,21 +58,42 @@ void AbortSignal::signal_abort(JS::Value reason)
else
m_abort_reason = WebIDL::AbortError::create(realm(), "Aborted without reason"_fly_string).ptr();
- // 3. For each algorithm in signal’s abort algorithms: run algorithm.
- for (auto& algorithm : m_abort_algorithms)
- algorithm->function()();
+ // 3. Let dependentSignalsToAbort be a new list.
+ Vector> dependent_signals_to_abort;
- // 4. Empty signal’s abort algorithms.
- m_abort_algorithms.clear();
+ // 4. For each dependentSignal of signal’s dependent signals:
+ for (auto const& dependent_signal : m_dependent_signals) {
+ // 1. If dependentSignal is not aborted, then:
+ if (!dependent_signal->aborted()) {
+ // 1. Set dependentSignal’s abort reason to signal’s abort reason.
+ dependent_signal->set_reason(m_abort_reason);
- // 5. Fire an event named abort at signal.
- auto abort_event = Event::create(realm(), HTML::EventNames::abort);
- abort_event->set_is_trusted(true);
- dispatch_event(abort_event);
+ // 2. Append dependentSignal to dependentSignalsToAbort.
+ dependent_signals_to_abort.append(*dependent_signal);
+ }
+ }
- // 6. For each dependentSignal of signal’s dependent signals, signal abort on dependentSignal with signal’s abort reason.
- for (auto const& dependent_signal : m_dependent_signals)
- dependent_signal->signal_abort(reason);
+ // https://dom.spec.whatwg.org/#run-the-abort-steps
+ auto run_the_abort_steps = [](auto& signal) {
+ // 1. For each algorithm in signal’s abort algorithms: run algorithm.
+ for (auto& algorithm : signal.m_abort_algorithms)
+ algorithm->function()();
+
+ // 2. Empty signal’s abort algorithms.
+ signal.m_abort_algorithms.clear();
+
+ // 3. Fire an event named abort at signal.
+ auto abort_event = Event::create(signal.realm(), HTML::EventNames::abort);
+ abort_event->set_is_trusted(true);
+ signal.dispatch_event(abort_event);
+ };
+
+ // 5. Run the abort steps for signal.
+ run_the_abort_steps(*this);
+
+ // 6. For each dependentSignal of dependentSignalsToAbort, run the abort steps for dependentSignal.
+ for (auto const& dependent_signal : dependent_signals_to_abort)
+ run_the_abort_steps(*dependent_signal);
}
void AbortSignal::set_onabort(WebIDL::CallbackType* event_handler)