mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 12:23:15 +00:00
LibWeb: Implement AbortSignal.timeout()
This method returns a signal that will automatically abort after a given number of milliseconds.
This commit is contained in:
parent
3c288c96e6
commit
ae42c6ed80
2
Tests/LibWeb/Text/expected/abortsignal-timeout.txt
Normal file
2
Tests/LibWeb/Text/expected/abortsignal-timeout.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
Time passed before abort event fired is at least 10 milliseconds: true
|
||||
Reason type: TimeoutError
|
15
Tests/LibWeb/Text/input/abortsignal-timeout.html
Normal file
15
Tests/LibWeb/Text/input/abortsignal-timeout.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<script src="include.js"></script>
|
||||
<script>
|
||||
asyncTest(done => {
|
||||
const timeout_milliseconds = 10;
|
||||
const test_start_time = performance.now();
|
||||
const signal = AbortSignal.timeout(timeout_milliseconds);
|
||||
signal.onabort = () => {
|
||||
const abort_event_time = performance.now();
|
||||
const time_taken_milliseconds = abort_event_time - test_start_time;
|
||||
println(`Time passed before abort event fired is at least ${timeout_milliseconds} milliseconds: ${time_taken_milliseconds >= timeout_milliseconds}`);
|
||||
println(`Reason type: ${signal.reason.name}`);
|
||||
done();
|
||||
};
|
||||
});
|
||||
</script>
|
|
@ -9,6 +9,8 @@
|
|||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/EventDispatcher.h>
|
||||
#include <LibWeb/HTML/EventHandler.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
|
@ -132,4 +134,30 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<AbortSignal>> AbortSignal::abort(JS::VM& vm
|
|||
return signal;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-abortsignal-timeout
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<AbortSignal>> AbortSignal::timeout(JS::VM& vm, WebIDL::UnsignedLongLong milliseconds)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let signal be a new AbortSignal object.
|
||||
auto signal = TRY(construct_impl(realm));
|
||||
|
||||
// 2. Let global be signal’s relevant global object.
|
||||
auto& global = HTML::relevant_global_object(signal);
|
||||
auto* window_or_worker = dynamic_cast<HTML::WindowOrWorkerGlobalScopeMixin*>(&global);
|
||||
VERIFY(window_or_worker);
|
||||
|
||||
// 3. Run steps after a timeout given global, "AbortSignal-timeout", milliseconds, and the following step:
|
||||
window_or_worker->run_steps_after_a_timeout(milliseconds, [&realm, &global, strong_signal = JS::make_handle(signal)]() {
|
||||
// 1. Queue a global task on the timer task source given global to signal abort given signal and a new "TimeoutError" DOMException.
|
||||
HTML::queue_global_task(HTML::Task::Source::TimerTask, global, [&realm, &strong_signal]() mutable {
|
||||
auto reason = WebIDL::TimeoutError::create(realm, "Signal timed out"_fly_string);
|
||||
strong_signal->signal_abort(reason);
|
||||
});
|
||||
});
|
||||
|
||||
// 4. Return signal.
|
||||
return signal;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <LibJS/Heap/HeapFunction.h>
|
||||
#include <LibWeb/DOM/EventTarget.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/WebIDL/Types.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
|
@ -44,6 +45,7 @@ public:
|
|||
void follow(JS::NonnullGCPtr<AbortSignal> parent_signal);
|
||||
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<AbortSignal>> abort(JS::VM&, JS::Value reason);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<AbortSignal>> timeout(JS::VM&, Web::WebIDL::UnsignedLongLong milliseconds);
|
||||
|
||||
private:
|
||||
explicit AbortSignal(JS::Realm&);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
[Exposed=(Window,Worker), CustomVisit]
|
||||
interface AbortSignal : EventTarget {
|
||||
[NewObject] static AbortSignal abort(optional any reason);
|
||||
// FIXME: [Exposed=(Window,Worker), NewObject] static AbortSignal timeout([EnforceRange] unsigned long long milliseconds);
|
||||
[Exposed=(Window,Worker), NewObject] static AbortSignal timeout([EnforceRange] unsigned long long milliseconds);
|
||||
// FIXME: [NewObject] static AbortSignal _any(sequence<AbortSignal> signals);
|
||||
|
||||
readonly attribute boolean aborted;
|
||||
|
|
Loading…
Reference in a new issue