mirror of
https://github.com/servo/servo.git
synced 2025-06-04 07:35:36 +00:00
dom: implement signal abort on controller and signal (#37192)
Part of https://github.com/servo/servo/issues/34866 Implement signal abort, and part of running abort steps. Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
This commit is contained in:
parent
9959bc4e0f
commit
8a808f89fd
3 changed files with 101 additions and 9 deletions
|
@ -3,24 +3,33 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use js::jsapi::Value;
|
||||
use js::rust::{Handle, HandleObject};
|
||||
use js::rust::{HandleObject, HandleValue};
|
||||
|
||||
use crate::dom::abortsignal::AbortSignal;
|
||||
use crate::dom::bindings::codegen::Bindings::AbortControllerBinding::AbortControllerMethods;
|
||||
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::script_runtime::{CanGc, JSContext};
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortcontroller>
|
||||
#[dom_struct]
|
||||
pub(crate) struct AbortController {
|
||||
reflector_: Reflector,
|
||||
|
||||
/// An AbortController object has an associated signal (an AbortSignal object).
|
||||
signal: Dom<AbortSignal>,
|
||||
}
|
||||
|
||||
impl AbortController {
|
||||
/// <https://dom.spec.whatwg.org/#dom-abortcontroller-abortcontroller>
|
||||
fn new_inherited() -> AbortController {
|
||||
// The new AbortController() constructor steps are:
|
||||
// Let signal be a new AbortSignal object.
|
||||
// Set this’s signal to signal.
|
||||
AbortController {
|
||||
reflector_: Reflector::new(),
|
||||
signal: Dom::from_ref(&AbortSignal::new_inherited()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +45,12 @@ impl AbortController {
|
|||
can_gc,
|
||||
)
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortcontroller-signal-abort>
|
||||
fn signal_abort(&self, cx: JSContext, reason: HandleValue, can_gc: CanGc) {
|
||||
// signal abort on controller’s signal with reason if it is given.
|
||||
self.signal.signal_abort(cx, reason, can_gc);
|
||||
}
|
||||
}
|
||||
|
||||
impl AbortControllerMethods<crate::DomTypeHolder> for AbortController {
|
||||
|
@ -49,5 +64,9 @@ impl AbortControllerMethods<crate::DomTypeHolder> for AbortController {
|
|||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#dom-abortcontroller-abort>
|
||||
fn Abort(&self, _cx: JSContext, _reason: Handle<'_, Value>) {}
|
||||
fn Abort(&self, cx: JSContext, reason: HandleValue, can_gc: CanGc) {
|
||||
// The abort(reason) method steps are
|
||||
// to signal abort on this with reason if it is given.
|
||||
self.signal_abort(cx, reason, can_gc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,18 +2,37 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use js::jsapi::Heap;
|
||||
use js::jsval::JSVal;
|
||||
use js::rust::{HandleObject, MutableHandleValue};
|
||||
use js::jsval::{JSVal, UndefinedValue};
|
||||
use js::rust::{HandleObject, HandleValue, MutableHandleValue};
|
||||
use script_bindings::inheritance::Castable;
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::AbortSignalBinding::AbortSignalMethods;
|
||||
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
|
||||
use crate::dom::bindings::error::{Error, ErrorToJsval};
|
||||
use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object_with_proto};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::script_runtime::{CanGc, JSContext};
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortcontroller-api-integration>
|
||||
/// TODO: implement algorithms at call point,
|
||||
/// in order to integrate the abort signal with its various use cases.
|
||||
#[derive(JSTraceable, MallocSizeOf)]
|
||||
#[allow(dead_code)]
|
||||
enum AbortAlgorithm {
|
||||
/// <https://dom.spec.whatwg.org/#add-an-event-listener>
|
||||
DomEventLister,
|
||||
/// <https://streams.spec.whatwg.org/#readable-stream-pipe-to>
|
||||
StreamPiping,
|
||||
/// <https://fetch.spec.whatwg.org/#dom-global-fetch>
|
||||
Fetch,
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortsignal>
|
||||
#[dom_struct]
|
||||
pub(crate) struct AbortSignal {
|
||||
|
@ -22,14 +41,17 @@ pub(crate) struct AbortSignal {
|
|||
/// <https://dom.spec.whatwg.org/#abortsignal-abort-reason>
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
abort_reason: Heap<JSVal>,
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortsignal-abort-algorithms>
|
||||
abort_algorithms: RefCell<Vec<AbortAlgorithm>>,
|
||||
}
|
||||
|
||||
impl AbortSignal {
|
||||
#[allow(dead_code)]
|
||||
fn new_inherited() -> AbortSignal {
|
||||
pub(crate) fn new_inherited() -> AbortSignal {
|
||||
AbortSignal {
|
||||
eventtarget: EventTarget::new_inherited(),
|
||||
abort_reason: Default::default(),
|
||||
abort_algorithms: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,6 +68,53 @@ impl AbortSignal {
|
|||
can_gc,
|
||||
)
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortsignal-signal-abort>
|
||||
pub(crate) fn signal_abort(&self, cx: JSContext, reason: HandleValue, can_gc: CanGc) {
|
||||
// If signal is aborted, then return.
|
||||
if self.Aborted() {
|
||||
return;
|
||||
}
|
||||
|
||||
let abort_reason = reason.get();
|
||||
|
||||
// Set signal’s abort reason to reason if it is given;
|
||||
if !abort_reason.is_undefined() {
|
||||
self.abort_reason.set(abort_reason);
|
||||
} else {
|
||||
// otherwise to a new "AbortError" DOMException.
|
||||
rooted!(in(*cx) let mut rooted_error = UndefinedValue());
|
||||
Error::Abort.to_jsval(cx, &self.global(), rooted_error.handle_mut(), can_gc);
|
||||
self.abort_reason.set(rooted_error.get())
|
||||
}
|
||||
|
||||
// Let dependentSignalsToAbort be a new list.
|
||||
// For each dependentSignal of signal’s dependent signals:
|
||||
// TODO: #36936
|
||||
|
||||
// Run the abort steps for signal.
|
||||
self.run_the_abort_steps(can_gc);
|
||||
|
||||
// For each dependentSignal of dependentSignalsToAbort, run the abort steps for dependentSignal.
|
||||
// TODO: #36936
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#run-the-abort-steps>
|
||||
fn run_the_abort_steps(&self, can_gc: CanGc) {
|
||||
// For each algorithm of signal’s abort algorithms: run algorithm.
|
||||
let algos = mem::take(&mut *self.abort_algorithms.borrow_mut());
|
||||
for _algo in algos {
|
||||
// TODO: match on variant and implement algo steps.
|
||||
// See the various items of #34866
|
||||
}
|
||||
|
||||
// Empty signal’s abort algorithms.
|
||||
// Done above with `take`.
|
||||
|
||||
// Fire an event named abort at signal.
|
||||
self.upcast::<EventTarget>()
|
||||
.fire_event(atom!("abort"), can_gc);
|
||||
}
|
||||
}
|
||||
|
||||
impl AbortSignalMethods<crate::DomTypeHolder> for AbortSignal {
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
|
||||
DOMInterfaces = {
|
||||
|
||||
'AbortController': {
|
||||
'canGc':['Abort'],
|
||||
},
|
||||
|
||||
'AbstractRange': {
|
||||
'weakReferenceable': True,
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue