aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py29
-rw-r--r--components/script/dom/bindings/utils.rs24
2 files changed, 50 insertions, 3 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index d44db4078b4..9f965a9c7e8 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1165,6 +1165,15 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
return CGGeneric("*mut JSObject")
if returnType.isSequence():
raise TypeError("We don't support sequence return values")
+ if returnType.isDictionary():
+ nullable = returnType.nullable()
+ dictName = returnType.inner.name if nullable else returnType.name
+ result = CGGeneric(dictName)
+ if typeNeedsRooting(returnType, descriptorProvider):
+ raise TypeError("We don't support rootable dictionaries return values")
+ if nullable:
+ result = CGWrapper(result, pre="Option<", post=">")
+ return result
raise TypeError("Don't know how to declare return value for %s" %
returnType)
@@ -4517,7 +4526,14 @@ class CGDictionary(CGThing):
conversion = self.getMemberConversion(memberInfo)
return CGGeneric("%s: %s,\n" % (name, conversion.define()))
+ def memberInsert(memberInfo):
+ member, _ = memberInfo
+ name = self.makeMemberName(member.identifier.name)
+ insertion = ("set_dictionary_property(cx, obj, \"%s\", &mut self.%s.to_jsval(cx)).unwrap();" % (name, name))
+ return CGGeneric("%s\n" % insertion)
+
memberInits = CGList([memberInit(m) for m in self.memberInfo])
+ memberInserts = CGList([memberInsert(m) for m in self.memberInfo])
return string.Template(
"impl ${selfName} {\n"
@@ -4538,10 +4554,19 @@ class CGDictionary(CGThing):
"${initMembers}"
" })\n"
" }\n"
- "}").substitute({
+ "}\n"
+ "\n"
+ "impl ToJSValConvertible for ${selfName} {\n"
+ " fn to_jsval(&self, cx: *mut JSContext) -> JSVal {\n"
+ " let obj = unsafe { JS_NewObject(cx, 0 as *const JSClass, 0 as *const JSObject, 0 as *const JSObject) };\n"
+ "${insertMembers}"
+ " ObjectOrNullValue(obj)\n"
+ " }\n"
+ "}\n").substitute({
"selfName": self.makeClassName(d),
"initParent": CGIndenter(CGGeneric(initParent), indentLevel=12).define(),
"initMembers": CGIndenter(memberInits, indentLevel=12).define(),
+ "insertMembers": CGIndenter(memberInserts, indentLevel=8).define(),
})
@staticmethod
@@ -4590,6 +4615,7 @@ class CGDictionary(CGThing):
return CGGeneric(conversion)
+
@staticmethod
def makeIdName(name):
return name + "_id"
@@ -4750,6 +4776,7 @@ class CGBindingRoot(CGThing):
'dom::bindings::utils::{Reflectable}',
'dom::bindings::utils::throwing_constructor',
'dom::bindings::utils::get_dictionary_property',
+ 'dom::bindings::utils::set_dictionary_property',
'dom::bindings::utils::{NativeProperties, NativePropertyHooks}',
'dom::bindings::utils::ConstantVal::{IntVal, UintVal}',
'dom::bindings::utils::NonNullJSNative',
diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs
index 612cba46f35..f53451352cc 100644
--- a/components/script/dom/bindings/utils.rs
+++ b/components/script/dom/bindings/utils.rs
@@ -29,7 +29,7 @@ use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype, JS_GetStringCharsAn
use js::jsapi::JSHandleObject;
use js::jsapi::JS_GetFunctionObject;
use js::jsapi::{JS_HasPropertyById, JS_GetPrototype};
-use js::jsapi::{JS_GetProperty, JS_HasProperty};
+use js::jsapi::{JS_GetProperty, JS_HasProperty, JS_SetProperty};
use js::jsapi::{JS_DefineFunctions, JS_DefineProperty};
use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass};
@@ -510,7 +510,6 @@ pub fn is_platform_object(obj: *mut JSObject) -> bool {
pub fn get_dictionary_property(cx: *mut JSContext,
object: *mut JSObject,
property: &str) -> Result<Option<JSVal>, ()> {
- use std::ffi::CString;
fn has_property(cx: *mut JSContext, object: *mut JSObject, property: &CString,
found: &mut JSBool) -> bool {
unsafe {
@@ -546,6 +545,27 @@ pub fn get_dictionary_property(cx: *mut JSContext,
Ok(Some(value))
}
+/// Set the property with name `property` from `object`.
+/// Returns `Err(())` on JSAPI failure, or null object,
+/// and Ok(()) otherwise
+pub fn set_dictionary_property(cx: *mut JSContext,
+ object: *mut JSObject,
+ property: &str,
+ value: &mut JSVal) -> Result<(), ()> {
+ if object.is_null() {
+ return Err(());
+ }
+
+ let property = CString::new(property).unwrap();
+ unsafe {
+ if JS_SetProperty(cx, object, property.as_ptr(), value) == 0 {
+ return Err(());
+ }
+ }
+
+ Ok(())
+}
+
/// Returns whether `proxy` has a property `id` on its prototype.
pub fn has_property_on_prototype(cx: *mut JSContext, proxy: *mut JSObject,
id: jsid) -> bool {