diff --git a/Userland/Libraries/LibWeb/DOM/AbortController.cpp b/Userland/Libraries/LibWeb/DOM/AbortController.cpp index 4f3450c4a8..2723894900 100644 --- a/Userland/Libraries/LibWeb/DOM/AbortController.cpp +++ b/Userland/Libraries/LibWeb/DOM/AbortController.cpp @@ -20,9 +20,10 @@ AbortController::~AbortController() } // https://dom.spec.whatwg.org/#dom-abortcontroller-abort -void AbortController::abort() +void AbortController::abort(JS::Value reason) { - m_signal->signal_abort(); + // The abort(reason) method steps are to signal abort on this’s signal with reason if it is given. + m_signal->signal_abort(reason); } } diff --git a/Userland/Libraries/LibWeb/DOM/AbortController.h b/Userland/Libraries/LibWeb/DOM/AbortController.h index c8b4a15866..d07146e8cd 100644 --- a/Userland/Libraries/LibWeb/DOM/AbortController.h +++ b/Userland/Libraries/LibWeb/DOM/AbortController.h @@ -39,7 +39,7 @@ public: // https://dom.spec.whatwg.org/#dom-abortcontroller-signal NonnullRefPtr signal() const { return m_signal; } - void abort(); + void abort(JS::Value reason); private: AbortController(Document& document); diff --git a/Userland/Libraries/LibWeb/DOM/AbortController.idl b/Userland/Libraries/LibWeb/DOM/AbortController.idl index 4877c9295e..162c3e9dc1 100644 --- a/Userland/Libraries/LibWeb/DOM/AbortController.idl +++ b/Userland/Libraries/LibWeb/DOM/AbortController.idl @@ -4,5 +4,5 @@ interface AbortController { [SameObject] readonly attribute AbortSignal signal; - undefined abort(); + undefined abort(optional any reason); }; diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp index 94845e93a7..f86bd74c57 100644 --- a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp +++ b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include #include @@ -29,25 +31,35 @@ JS::Object* AbortSignal::create_wrapper(JS::GlobalObject& global_object) // https://dom.spec.whatwg.org/#abortsignal-add void AbortSignal::add_abort_algorithm(Function abort_algorithm) { - if (m_aborted) + // 1. If signal is aborted, then return. + if (aborted()) return; + // 2. Append algorithm to signal’s abort algorithms. m_abort_algorithms.append(move(abort_algorithm)); } // https://dom.spec.whatwg.org/#abortsignal-signal-abort -void AbortSignal::signal_abort() +void AbortSignal::signal_abort(JS::Value reason) { - if (m_aborted) + // 1. If signal is aborted, then return. + if (aborted()) return; - m_aborted = true; + // 2. Set signal’s abort reason to reason if it is given; otherwise to a new "AbortError" DOMException. + if (!reason.is_undefined()) + m_abort_reason = reason; + else + m_abort_reason = wrap(wrapper()->global_object(), AbortError::create("Aborted without reason")); + // 3. For each algorithm in signal’s abort algorithms: run algorithm. for (auto& algorithm : m_abort_algorithms) algorithm(); + // 4. Empty signal’s abort algorithms. m_abort_algorithms.clear(); + // 5. Fire an event named abort at signal. dispatch_event(Event::create(HTML::EventNames::abort)); } @@ -61,4 +73,9 @@ HTML::EventHandler AbortSignal::onabort() return event_handler_attribute(HTML::EventNames::abort); } +void AbortSignal::visit_edges(JS::Cell::Visitor& visitor) +{ + visitor.visit(m_abort_reason); +} + } diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.h b/Userland/Libraries/LibWeb/DOM/AbortSignal.h index c3ecfe0dcb..fbbb83bb5c 100644 --- a/Userland/Libraries/LibWeb/DOM/AbortSignal.h +++ b/Userland/Libraries/LibWeb/DOM/AbortSignal.h @@ -42,13 +42,19 @@ public: void add_abort_algorithm(Function); // https://dom.spec.whatwg.org/#dom-abortsignal-aborted - bool aborted() const { return m_aborted; } + // An AbortSignal object is aborted when its abort reason is not undefined. + bool aborted() const { return !m_abort_reason.is_undefined(); } - void signal_abort(); + void signal_abort(JS::Value reason); void set_onabort(HTML::EventHandler); HTML::EventHandler onabort(); + // https://dom.spec.whatwg.org/#dom-abortsignal-reason + JS::Value reason() const { return m_abort_reason; } + + void visit_edges(JS::Cell::Visitor&); + // ^EventTarget virtual void ref_event_target() override { ref(); } virtual void unref_event_target() override { unref(); } @@ -57,8 +63,9 @@ public: private: AbortSignal(Document& document); - // https://dom.spec.whatwg.org/#abortsignal-aborted-flag - bool m_aborted { false }; + // https://dom.spec.whatwg.org/#abortsignal-abort-reason + // An AbortSignal object has an associated abort reason, which is a JavaScript value. It is undefined unless specified otherwise. + JS::Value m_abort_reason { JS::js_undefined() }; // https://dom.spec.whatwg.org/#abortsignal-abort-algorithms // FIXME: This should be a set. diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.idl b/Userland/Libraries/LibWeb/DOM/AbortSignal.idl index 4fda402027..d28ef8a5d5 100644 --- a/Userland/Libraries/LibWeb/DOM/AbortSignal.idl +++ b/Userland/Libraries/LibWeb/DOM/AbortSignal.idl @@ -1,8 +1,9 @@ -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), CustomVisit] interface AbortSignal : EventTarget { - // FIXME: [NewObject] static AbortSignal abort(); + // FIXME: [NewObject] static AbortSignal abort(optional any reason); readonly attribute boolean aborted; + readonly attribute any reason; attribute EventHandler onabort; };