소스 검색

LibWeb: Add support for AbortSignal.reason

Luke Wilde 3 년 전
부모
커밋
64040c136e

+ 3 - 2
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);
 }
 
 }

+ 1 - 1
Userland/Libraries/LibWeb/DOM/AbortController.h

@@ -39,7 +39,7 @@ public:
     // https://dom.spec.whatwg.org/#dom-abortcontroller-signal
     NonnullRefPtr<AbortSignal> signal() const { return m_signal; }
 
-    void abort();
+    void abort(JS::Value reason);
 
 private:
     AbortController(Document& document);

+ 1 - 1
Userland/Libraries/LibWeb/DOM/AbortController.idl

@@ -4,5 +4,5 @@ interface AbortController {
 
     [SameObject] readonly attribute AbortSignal signal;
 
-    undefined abort();
+    undefined abort(optional any reason);
 };

+ 21 - 4
Userland/Libraries/LibWeb/DOM/AbortSignal.cpp

@@ -5,6 +5,8 @@
  */
 
 #include <LibWeb/Bindings/AbortSignalWrapper.h>
+#include <LibWeb/Bindings/DOMExceptionWrapper.h>
+#include <LibWeb/Bindings/Wrapper.h>
 #include <LibWeb/DOM/AbortSignal.h>
 #include <LibWeb/DOM/Document.h>
 #include <LibWeb/DOM/EventDispatcher.h>
@@ -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<void()> 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);
+}
+
 }

+ 11 - 4
Userland/Libraries/LibWeb/DOM/AbortSignal.h

@@ -42,13 +42,19 @@ public:
     void add_abort_algorithm(Function<void()>);
 
     // 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.

+ 3 - 2
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;
 };