script: Support converting JS values to Rc<Promise> with FromJSValConvertible. (#36097)

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2025-03-25 10:08:45 -04:00 committed by GitHub
parent f65b697a5a
commit f717f6b848
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 27 additions and 4 deletions

4
Cargo.lock generated
View file

@ -4702,7 +4702,7 @@ dependencies = [
[[package]]
name = "mozjs"
version = "0.14.1"
source = "git+https://github.com/servo/mozjs#26c35182c1b2b7fb2fbfa93b82669533d92c3a60"
source = "git+https://github.com/servo/mozjs#39db84352d79ffa3e4fe756c8034af9def788f22"
dependencies = [
"bindgen 0.71.1",
"cc",
@ -4714,7 +4714,7 @@ dependencies = [
[[package]]
name = "mozjs_sys"
version = "0.128.9-0"
source = "git+https://github.com/servo/mozjs#26c35182c1b2b7fb2fbfa93b82669533d92c3a60"
source = "git+https://github.com/servo/mozjs#39db84352d79ffa3e4fe756c8034af9def788f22"
dependencies = [
"bindgen 0.71.1",
"cc",

View file

@ -15,7 +15,7 @@ use std::ptr;
use std::rc::Rc;
use dom_struct::dom_struct;
use js::conversions::ToJSValConvertible;
use js::conversions::{ConversionResult, FromJSValConvertibleRc, ToJSValConvertible};
use js::jsapi::{
AddRawValueRoot, CallArgs, GetFunctionNativeReserved, Heap, JS_ClearPendingException,
JS_GetFunctionObject, JS_NewFunction, JSAutoRealm, JSContext, JSObject,
@ -405,3 +405,24 @@ impl PromiseHelpers<crate::DomTypeHolder> for Promise {
Promise::new_resolved(global, cx, value, CanGc::note())
}
}
impl FromJSValConvertibleRc for Promise {
#[allow(unsafe_code)]
unsafe fn from_jsval(
cx: *mut JSContext,
value: HandleValue,
) -> Result<ConversionResult<Rc<Promise>>, ()> {
if value.get().is_null() {
return Ok(ConversionResult::Failure("null not allowed".into()));
}
if !value.get().is_object() {
return Ok(ConversionResult::Failure("not an object".into()));
}
rooted!(in(cx) let obj = value.get().to_object());
if !IsPromiseObject(obj.handle()) {
return Ok(ConversionResult::Failure("not a promise".into()));
}
let promise = Promise::new_with_js_promise(obj.handle(), SafeJSContext::from_ptr(cx));
Ok(ConversionResult::Success(promise))
}
}

View file

@ -910,6 +910,7 @@ impl TestBindingMethods<crate::DomTypeHolder> for TestBinding {
fn FuncControlledMethodDisabled(&self) {}
fn FuncControlledMethodEnabled(&self) {}
fn PassRecordPromise(&self, _: Record<DOMString, Rc<Promise>>) {}
fn PassRecord(&self, _: Record<DOMString, i32>) {}
fn PassRecordWithUSVStringKey(&self, _: Record<USVString, i32>) {}
fn PassRecordWithByteStringKey(&self, _: Record<ByteString, i32>) {}

View file

@ -490,7 +490,7 @@ DOMInterfaces = {
'Promise': {
'spiderMonkeyInterface': True,
'additionalTraits': ["crate::dom::promise::PromiseHelpers<Self>"]
'additionalTraits': ["crate::dom::promise::PromiseHelpers<Self>", "js::conversions::FromJSValConvertibleRc"]
},
'Range': {

View file

@ -479,6 +479,7 @@ interface TestBinding {
sequence<sequence<long>> returnSequenceSequence();
undefined passUnionSequenceSequence((long or sequence<sequence<long>>) seq);
undefined passRecordPromise(record<DOMString, Promise<undefined>> arg);
undefined passRecord(record<DOMString, long> arg);
undefined passRecordWithUSVStringKey(record<USVString, long> arg);
undefined passRecordWithByteStringKey(record<ByteString, long> arg);