Revert "script: implement AbortController (#31361)" (#32243)

This reverts commit 7fce850cff.
This commit is contained in:
Samson 2024-05-07 08:23:14 +02:00 committed by GitHub
parent 45f2433d76
commit 8bc49299c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
86 changed files with 1193 additions and 517 deletions

View file

@ -1,59 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 dom_struct::dom_struct;
use js::jsapi::Value;
use js::rust::{Handle, HandleObject};
use crate::dom::abortsignal::AbortSignal;
use crate::dom::bindings::codegen::Bindings::AbortControllerBinding::AbortControllerMethods;
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::globalscope::GlobalScope;
use crate::script_runtime::JSContext;
#[dom_struct]
pub struct AbortController {
reflector_: Reflector,
signal: Dom<AbortSignal>,
}
impl AbortController {
pub fn new_inherited(signal: &AbortSignal) -> AbortController {
AbortController {
reflector_: Reflector::new(),
signal: Dom::from_ref(signal),
}
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
) -> DomRoot<AbortController> {
reflect_dom_object_with_proto(
Box::new(AbortController::new_inherited(&AbortSignal::new(global))),
global,
proto,
)
}
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
) -> DomRoot<AbortController> {
AbortController::new_with_proto(global, proto)
}
}
impl AbortControllerMethods for AbortController {
/// <https://dom.spec.whatwg.org/#dom-abortcontroller-signal>
fn Signal(&self) -> DomRoot<AbortSignal> {
DomRoot::from_ref(&self.signal)
}
/// <https://dom.spec.whatwg.org/#dom-abortcontroller-abort>
fn Abort(&self, _cx: JSContext, reason: Handle<'_, Value>) {
self.signal.signal_abort(reason);
}
}

View file

@ -1,139 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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::rc::Rc;
use dom_struct::dom_struct;
use js::conversions::ToJSValConvertible;
use js::jsapi::{ExceptionStackBehavior, Heap, JS_IsExceptionPending};
use js::jsval::{JSVal, UndefinedValue};
use js::rust::wrappers::JS_SetPendingException;
use js::rust::HandleValue;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::AbortSignalBinding::AbortSignalMethods;
use crate::dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
use crate::dom::bindings::codegen::Bindings::EventTargetBinding::EventListenerOptions;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::domexception::DOMErrorName;
use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::types::DOMException;
use crate::script_runtime::JSContext;
#[derive(JSTraceable, MallocSizeOf)]
pub enum AbortAlgorithm {
RemoveEventListener(
DomRoot<EventTarget>,
DOMString,
#[ignore_malloc_size_of = "Rc"] Rc<EventListener>,
#[ignore_malloc_size_of = "generated"] EventListenerOptions,
),
}
impl AbortAlgorithm {
fn exec(self) {
match self {
Self::RemoveEventListener(target, ty, listener, options) => {
target.remove_event_listener(ty, Some(listener), options)
},
}
}
}
#[dom_struct]
pub struct AbortSignal {
event_target: EventTarget,
#[ignore_malloc_size_of = "Defined in rust-mozjs"]
reason: Heap<JSVal>,
abort_algorithms: DomRefCell<Vec<AbortAlgorithm>>,
}
impl AbortSignal {
pub fn new_inherited() -> Self {
Self {
event_target: EventTarget::new_inherited(),
reason: Heap::default(),
abort_algorithms: DomRefCell::default(),
}
}
pub fn new(global: &GlobalScope) -> DomRoot<Self> {
reflect_dom_object(Box::new(Self::new_inherited()), global)
}
/// <https://dom.spec.whatwg.org/#abortsignal-add>
pub fn add_abort_algorithm(&self, alg: AbortAlgorithm) {
if !self.Aborted() {
self.abort_algorithms.borrow_mut().push(alg);
}
}
/// <https://dom.spec.whatwg.org/#abortsignal-signal-abort>
#[allow(unsafe_code)]
pub fn signal_abort(&self, reason: HandleValue) {
// 1. If signal is aborted, then return.
if self.Aborted() {
return;
}
// 2. Set signals abort reason to reason if it is given; otherwise to a new "AbortError" DOMException.
let cx = *GlobalScope::get_cx();
rooted!(in(cx) let mut new_reason = UndefinedValue());
let reason = if reason.is_undefined() {
let exception = DOMException::new(&self.global(), DOMErrorName::AbortError);
unsafe {
exception.to_jsval(cx, new_reason.handle_mut());
};
new_reason.handle()
} else {
reason
};
self.reason.set(reason.get());
// 3. For each algorithm of signals abort algorithms: run algorithm.
// 4. Empty signals abort algorithms.
for algorithm in self.abort_algorithms.borrow_mut().drain(..) {
algorithm.exec();
}
// 5. Fire an event named abort at signal.
let event = Event::new(
&self.global(),
atom!("abort"),
EventBubbles::DoesNotBubble,
EventCancelable::Cancelable,
);
event.fire(self.upcast());
// 6. For each dependentSignal of signals dependent signals,
// signal abort on dependentSignal with signals abort reason.
// TODO
}
}
impl AbortSignalMethods for AbortSignal {
// https://dom.spec.whatwg.org/#dom-abortsignal-onabort
event_handler!(Abort, GetOnabort, SetOnabort);
/// <https://dom.spec.whatwg.org/#dom-abortsignal-aborted>
fn Aborted(&self) -> bool {
!self.reason.get().is_undefined()
}
/// <https://dom.spec.whatwg.org/#dom-abortsignal-reason>
fn Reason(&self, _cx: JSContext) -> JSVal {
self.reason.get()
}
#[allow(unsafe_code)]
/// <https://dom.spec.whatwg.org/#dom-abortsignal-throwifaborted>
fn ThrowIfAborted(&self) {
let reason = self.reason.get();
if !reason.is_undefined() {
let cx = *GlobalScope::get_cx();
unsafe {
assert!(!JS_IsExceptionPending(cx));
rooted!(in(cx) let mut thrown = UndefinedValue());
reason.to_jsval(cx, thrown.handle_mut());
JS_SetPendingException(cx, thrown.handle(), ExceptionStackBehavior::Capture);
}
}
}
}

View file

@ -2167,8 +2167,7 @@ class CGImports(CGWrapper):
"""
Generates the appropriate import/use statements.
"""
def __init__(self, child, descriptors, callbacks, dictionaries, enums, typedefs, imports, config,
current_name=None):
def __init__(self, child, descriptors, callbacks, dictionaries, enums, typedefs, imports, config):
"""
Adds a set of imports.
"""
@ -2270,8 +2269,7 @@ class CGImports(CGWrapper):
parentName = descriptor.getParentName()
while parentName:
descriptor = descriptorProvider.getDescriptor(parentName)
if current_name != descriptor.ifaceName:
extras += [descriptor.path, descriptor.bindingPath]
extras += [descriptor.path, descriptor.bindingPath]
parentName = descriptor.getParentName()
elif t.isType() and t.isRecord():
extras += ['crate::dom::bindings::record::Record']
@ -6892,7 +6890,7 @@ class CGBindingRoot(CGThing):
DomRoot codegen class for binding generation. Instantiate the class, and call
declare or define to generate header or cpp code (respectively).
"""
def __init__(self, config, prefix, webIDLFile, name):
def __init__(self, config, prefix, webIDLFile):
descriptors = config.getDescriptors(webIDLFile=webIDLFile,
hasInterfaceObject=True)
# We also want descriptors that have an interface prototype object
@ -6960,7 +6958,7 @@ class CGBindingRoot(CGThing):
# These are the global imports (outside of the generated module)
curr = CGImports(curr, descriptors=callbackDescriptors, callbacks=mainCallbacks,
dictionaries=dictionaries, enums=enums, typedefs=typedefs,
imports=['crate::dom::bindings::import::base::*'], config=config, current_name=name)
imports=['crate::dom::bindings::import::base::*'], config=config)
# Add the auto-generated comment.
curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT + ALLOWED_WARNINGS)

View file

@ -232,7 +232,6 @@ class Descriptor(DescriptorProvider):
self.register = desc.get('register', True)
self.path = desc.get('path', pathDefault)
self.inRealmMethods = [name for name in desc.get('inRealms', [])]
self.ifaceName = ifaceName
self.bindingPath = f"crate::dom::bindings::codegen::Bindings::{ifaceName}Binding::{ifaceName}_Binding"
self.outerObjectHook = desc.get('outerObjectHook', 'None')
self.proxy = False

View file

@ -52,9 +52,8 @@ def main():
for webidl in webidls:
filename = os.path.join(webidls_dir, webidl)
name = webidl[:-len(".webidl")]
prefix = "Bindings/%sBinding" % name
module = CGBindingRoot(config, prefix, filename, name).define()
prefix = "Bindings/%sBinding" % webidl[:-len(".webidl")]
module = CGBindingRoot(config, prefix, filename).define()
if module:
with open(os.path.join(out_dir, prefix + ".rs"), "wb") as f:
f.write(module.encode("utf-8"))

View file

@ -23,7 +23,6 @@ use servo_atoms::Atom;
use servo_url::ServoUrl;
use super::bindings::trace::HashMapTracedValues;
use crate::dom::abortsignal::AbortAlgorithm;
use crate::dom::beforeunloadevent::BeforeUnloadEvent;
use crate::dom::bindings::callback::{CallbackContainer, CallbackFunction, ExceptionHandling};
use crate::dom::bindings::cell::DomRefCell;
@ -705,7 +704,7 @@ impl EventTarget {
None => return,
};
let mut handlers = self.handlers.borrow_mut();
let entry = match handlers.entry(Atom::from(ty.clone())) {
let entry = match handlers.entry(Atom::from(ty)) {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(EventListeners(vec![])),
};
@ -717,20 +716,12 @@ impl EventTarget {
};
let new_entry = EventListenerEntry {
phase,
listener: EventListenerType::Additive(Rc::clone(&listener)),
listener: EventListenerType::Additive(listener),
once: options.once,
};
if !entry.contains(&new_entry) {
entry.push(new_entry);
}
if let Some(signal) = options.signal {
signal.add_abort_algorithm(AbortAlgorithm::RemoveEventListener(
DomRoot::from_ref(&self),
ty,
listener,
options.parent,
));
};
}
// https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
@ -810,7 +801,6 @@ impl From<AddEventListenerOptionsOrBoolean> for AddEventListenerOptions {
AddEventListenerOptionsOrBoolean::Boolean(capture) => Self {
parent: EventListenerOptions { capture },
once: false,
signal: None,
},
}
}

View file

@ -100,7 +100,6 @@ impl MediaQueryListMethods for MediaQueryList {
AddEventListenerOptions {
parent: EventListenerOptions { capture: false },
once: false,
signal: None,
},
);
}

View file

@ -209,8 +209,6 @@ pub mod types {
include!(concat!(env!("OUT_DIR"), "/InterfaceTypes.rs"));
}
pub mod abortcontroller;
pub mod abortsignal;
pub mod abstractrange;
pub mod abstractworker;
pub mod abstractworkerglobalscope;

View file

@ -1,13 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
// https://dom.spec.whatwg.org/#interface-abortcontroller
[Exposed=*]
interface AbortController {
constructor();
[SameObject] readonly attribute AbortSignal signal;
undefined abort(optional any reason);
};

View file

@ -1,17 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
// https://dom.spec.whatwg.org/#interface-AbortSignal
[Exposed=*]
interface AbortSignal : EventTarget {
// [NewObject] static AbortSignal abort(optional any reason);
// [Exposed=(Window,Worker), NewObject] static AbortSignal timeout([EnforceRange] unsigned long long milliseconds);
// [NewObject] static AbortSignal _any(sequence<AbortSignal> signals);
readonly attribute boolean aborted;
readonly attribute any reason;
undefined throwIfAborted();
attribute EventHandler onabort;
};

View file

@ -31,5 +31,4 @@ dictionary EventListenerOptions {
dictionary AddEventListenerOptions : EventListenerOptions {
// boolean passive = false;
boolean once = false;
AbortSignal signal;
};