diff options
Diffstat (limited to 'components/script/dom')
7 files changed, 99 insertions, 24 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 4bea65388b6..93856508e6e 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -2881,6 +2881,42 @@ class PropertyArrays(): return define +class CGCollectJSONAttributesMethod(CGAbstractMethod): + """ + Generate the CollectJSONAttributes method for an interface descriptor + """ + def __init__(self, descriptor, toJSONMethod): + args = [Argument('SafeJSContext', 'cx'), + Argument('HandleObject', 'obj'), + Argument('*const %s' % descriptor.concreteType, 'this'), + Argument('&RootedGuard<*mut JSObject>', 'result')] + CGAbstractMethod.__init__(self, descriptor, 'CollectJSONAttributes', + 'bool', args, pub=True, unsafe=True) + self.toJSONMethod = toJSONMethod + + def definition_body(self): + ret = '' + interface = self.descriptor.interface + for m in interface.members: + if m.isAttr() and not m.isStatic() and m.type.isJSONType(): + name = m.identifier.name + ret += fill( + """ + rooted!(in(*cx) let mut temp = UndefinedValue()); + if !get_${name}(cx, obj, this, JSJitGetterCallArgs { _base: temp.handle_mut().into() }) { + return false; + } + if !JS_DefineProperty(*cx, result.handle().into(), + ${nameAsArray} as *const u8 as *const libc::c_char, + temp.handle(), JSPROP_ENUMERATE as u32) { + return false; + } + """, + name=name, nameAsArray=str_to_const_array(name)) + ret += 'return true;\n' + return CGGeneric(ret) + + class CGCreateInterfaceObjectsMethod(CGAbstractMethod): """ Generate the CreateInterfaceObjects method for an interface descriptor. @@ -3619,6 +3655,42 @@ class CGSpecializedMethod(CGAbstractExternMethod): return MakeNativeName(nativeName) +class CGDefaultToJSONMethod(CGSpecializedMethod): + def __init__(self, descriptor, method): + assert method.isDefaultToJSON() + CGSpecializedMethod.__init__(self, descriptor, method) + + def definition_body(self): + ret = dedent(""" + rooted!(in(*cx) let result = JS_NewPlainObject(*cx)); + if result.is_null() { + return false; + } + """) + + jsonDescriptors = [self.descriptor] + interface = self.descriptor.interface.parent + while interface: + descriptor = self.descriptor.getDescriptor(interface.identifier.name) + if descriptor.hasDefaultToJSON: + jsonDescriptors.append(descriptor) + interface = interface.parent + + form = """ + if !${parentclass}CollectJSONAttributes(cx, _obj, this, &result) { + return false; + } + """ + + # Iterate the array in reverse: oldest ancestor first + for descriptor in jsonDescriptors[:0:-1]: + ret += fill(form, parentclass=toBindingNamespace(descriptor.name) + "::") + ret += fill(form, parentclass="") + ret += ('(*args).rval().set(ObjectValue(*result));\n' + 'return true;\n') + return CGGeneric(ret) + + class CGStaticMethod(CGAbstractStaticBindingMethod): """ A class for generating the Rust code for an IDL static method. @@ -5665,7 +5737,8 @@ class CGInterfaceTrait(CGThing): for m in descriptor.interface.members: if (m.isMethod() and not m.isStatic() and not m.isMaplikeOrSetlikeOrIterableMethod() and - (not m.isIdentifierLess() or m.isStringifier())): + (not m.isIdentifierLess() or m.isStringifier()) and + not m.isDefaultToJSON()): name = CGSpecializedMethod.makeNativeName(descriptor, m) infallible = 'infallible' in descriptor.getExtendedAttributes(m) for idx, (rettype, arguments) in enumerate(m.signatures()): @@ -5856,7 +5929,9 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries 'js::jsapi::JS_HasProperty', 'js::jsapi::JS_HasPropertyById', 'js::rust::wrappers::JS_InitializePropertiesFromCompatibleNativeObject', + 'js::jsapi::JS_NewPlainObject', 'js::jsapi::JS_NewObject', + 'js::rust::RootedGuard', 'js::rust::wrappers::JS_NewObjectWithGivenProto', 'js::rust::wrappers::JS_NewObjectWithoutMetadata', 'js::rust::wrappers::ObjectIsDate', @@ -6055,6 +6130,7 @@ class CGDescriptor(CGThing): cgThings = [] + defaultToJSONMethod = None unscopableNames = [] for m in descriptor.interface.members: if (m.isMethod() and @@ -6062,7 +6138,9 @@ class CGDescriptor(CGThing): if m.getExtendedAttribute("Unscopable"): assert not m.isStatic() unscopableNames.append(m.identifier.name) - if m.isStatic(): + if m.isDefaultToJSON(): + defaultToJSONMethod = m + elif m.isStatic(): assert descriptor.interface.hasInterfaceObject() cgThings.append(CGStaticMethod(descriptor, m)) elif not descriptor.interface.isCallback(): @@ -6096,6 +6174,10 @@ class CGDescriptor(CGThing): if (not m.isStatic() and not descriptor.interface.isCallback()): cgThings.append(CGMemberJITInfo(descriptor, m)) + if defaultToJSONMethod: + cgThings.append(CGDefaultToJSONMethod(descriptor, defaultToJSONMethod)) + cgThings.append(CGMemberJITInfo(descriptor, defaultToJSONMethod)) + if descriptor.concrete: cgThings.append(CGClassFinalizeHook(descriptor)) cgThings.append(CGClassTraceHook(descriptor)) @@ -6113,6 +6195,9 @@ class CGDescriptor(CGThing): properties = PropertyArrays(descriptor) + if defaultToJSONMethod: + cgThings.append(CGCollectJSONAttributesMethod(descriptor, defaultToJSONMethod)) + if descriptor.concrete: if descriptor.proxy: # cgThings.append(CGProxyIsProxy(descriptor)) diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index 81f61a648f1..bde6e71bcfb 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -250,6 +250,8 @@ class Descriptor(DescriptorProvider): 'Stringifier': None, } + self.hasDefaultToJSON = False + def addOperation(operation, m): if not self.operations[operation]: self.operations[operation] = m @@ -259,6 +261,8 @@ class Descriptor(DescriptorProvider): for m in self.interface.members: if m.isMethod() and m.isStringifier(): addOperation('Stringifier', m) + if m.isMethod() and m.isDefaultToJSON(): + self.hasDefaultToJSON = True if self.concrete: iface = self.interface diff --git a/components/script/dom/rtcsessiondescription.rs b/components/script/dom/rtcsessiondescription.rs index 9aa46f56060..0ef79a321c6 100644 --- a/components/script/dom/rtcsessiondescription.rs +++ b/components/script/dom/rtcsessiondescription.rs @@ -14,12 +14,7 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; -use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::conversions::ToJSValConvertible; -use js::jsapi::JSObject; -use js::jsval::UndefinedValue; -use std::ptr::NonNull; #[dom_struct] pub struct RTCSessionDescription { @@ -71,18 +66,4 @@ impl RTCSessionDescriptionMethods for RTCSessionDescription { fn Sdp(&self) -> DOMString { self.sdp.clone() } - - #[allow(unsafe_code)] - /// https://w3c.github.io/webrtc-pc/#dom-rtcsessiondescription-tojson - fn ToJSON(&self, cx: JSContext) -> NonNull<JSObject> { - let init = RTCSessionDescriptionInit { - type_: self.ty, - sdp: self.sdp.clone(), - }; - unsafe { - rooted!(in(*cx) let mut jsval = UndefinedValue()); - init.to_jsval(*cx, jsval.handle_mut()); - NonNull::new(jsval.to_object()).unwrap() - } - } } diff --git a/components/script/dom/webidls/DOMMatrixReadOnly.webidl b/components/script/dom/webidls/DOMMatrixReadOnly.webidl index ea5d8caf8e5..317c2860707 100644 --- a/components/script/dom/webidls/DOMMatrixReadOnly.webidl +++ b/components/script/dom/webidls/DOMMatrixReadOnly.webidl @@ -81,7 +81,6 @@ interface DOMMatrixReadOnly { DOMPoint transformPoint(optional DOMPointInit point = {}); Float32Array toFloat32Array(); Float64Array toFloat64Array(); -// stringifier; -// serializer = { attribute }; - +// [Exposed=Window] stringifier; + [Default] object toJSON(); }; diff --git a/components/script/dom/webidls/DOMPointReadOnly.webidl b/components/script/dom/webidls/DOMPointReadOnly.webidl index 23643179333..071252c7690 100644 --- a/components/script/dom/webidls/DOMPointReadOnly.webidl +++ b/components/script/dom/webidls/DOMPointReadOnly.webidl @@ -20,4 +20,6 @@ interface DOMPointReadOnly { readonly attribute unrestricted double y; readonly attribute unrestricted double z; readonly attribute unrestricted double w; + + [Default] object toJSON(); }; diff --git a/components/script/dom/webidls/DOMQuad.webidl b/components/script/dom/webidls/DOMQuad.webidl index 8711dd44215..15f126cfea6 100644 --- a/components/script/dom/webidls/DOMQuad.webidl +++ b/components/script/dom/webidls/DOMQuad.webidl @@ -22,6 +22,8 @@ interface DOMQuad { [SameObject] readonly attribute DOMPoint p3; [SameObject] readonly attribute DOMPoint p4; [NewObject] DOMRect getBounds(); + + [Default] object toJSON(); }; dictionary DOMQuadInit { diff --git a/components/script/dom/webidls/DOMRectReadOnly.webidl b/components/script/dom/webidls/DOMRectReadOnly.webidl index 9464561bef4..58a8c87cd1c 100644 --- a/components/script/dom/webidls/DOMRectReadOnly.webidl +++ b/components/script/dom/webidls/DOMRectReadOnly.webidl @@ -17,6 +17,8 @@ interface DOMRectReadOnly { readonly attribute unrestricted double right; readonly attribute unrestricted double bottom; readonly attribute unrestricted double left; + + [Default] object toJSON(); }; // https://drafts.fxtf.org/geometry/#dictdef-domrectinit |