diff options
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 33 | ||||
-rw-r--r-- | components/script/dom/bindings/interface.rs | 48 | ||||
-rw-r--r-- | components/script/dom/webidls/ChildNode.webidl | 7 | ||||
-rw-r--r-- | components/script/dom/webidls/ParentNode.webidl | 4 |
4 files changed, 72 insertions, 20 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 0caeddb3dfa..c356a7d066c 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -2494,12 +2494,13 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): properties should be a PropertyArrays instance. """ - def __init__(self, descriptor, properties): + def __init__(self, descriptor, properties, haveUnscopables): args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'global'), Argument('*mut ProtoOrIfaceArray', 'cache')] CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args, unsafe=True) self.properties = properties + self.haveUnscopables = haveUnscopables def definition_body(self): name = self.descriptor.interface.identifier.name @@ -2530,7 +2531,10 @@ let mut prototype_proto = RootedObject::new(cx, ptr::null_mut()); %s; assert!(!prototype_proto.ptr.is_null());""" % getPrototypeProto)] - properties = {"id": name} + properties = { + "id": name, + "unscopables": "unscopable_names" if self.haveUnscopables else "&[]" + } for arrayName in self.properties.arrayNames(): array = getattr(self.properties, arrayName) if array.length(): @@ -2546,6 +2550,7 @@ create_interface_prototype_object(cx, %(methods)s, %(attrs)s, %(consts)s, + %(unscopables)s, prototype.handle_mut()); assert!(!prototype.ptr.is_null()); assert!((*cache)[PrototypeList::ID::%(id)s as usize].is_null()); @@ -5058,9 +5063,13 @@ class CGDescriptor(CGThing): descriptor.shouldHaveGetConstructorObjectMethod()): cgThings.append(CGGetConstructorObjectMethod(descriptor)) + unscopableNames = [] for m in descriptor.interface.members: if (m.isMethod() and (not m.isIdentifierLess() or m == descriptor.operations["Stringifier"])): + if m.getExtendedAttribute("Unscopable"): + assert not m.isStatic() + unscopableNames.append(m.identifier.name) if m.isStatic(): assert descriptor.interface.hasInterfaceObject() cgThings.append(CGStaticMethod(descriptor, m)) @@ -5072,7 +5081,9 @@ class CGDescriptor(CGThing): raise TypeError("Stringifier attributes not supported yet. " "See https://github.com/servo/servo/issues/7590\n" "%s" % m.location) - + if m.getExtendedAttribute("Unscopable"): + assert not m.isStatic() + unscopableNames.append(m.identifier.name) if m.isStatic(): assert descriptor.interface.hasInterfaceObject() cgThings.append(CGStaticGetter(descriptor, m)) @@ -5106,10 +5117,6 @@ class CGDescriptor(CGThing): if not descriptor.interface.isCallback(): cgThings.append(CGPrototypeJSClass(descriptor)) - properties = PropertyArrays(descriptor) - cgThings.append(CGGeneric(str(properties))) - cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties)) - # If there are no constant members, don't make a module for constants constMembers = [m for m in descriptor.interface.members if m.isConst()] if constMembers: @@ -5156,13 +5163,25 @@ class CGDescriptor(CGThing): cgThings.append(CGWrapMethod(descriptor)) + haveUnscopables = False if not descriptor.interface.isCallback(): + if unscopableNames: + haveUnscopables = True + cgThings.append( + CGList([CGGeneric("const unscopable_names: &'static [&'static [u8]] = &["), + CGIndenter(CGList([CGGeneric(str_to_const_array(name)) for + name in unscopableNames], ",\n")), + CGGeneric("];\n")], "\n")) if descriptor.concrete or descriptor.hasDescendants(): cgThings.append(CGIDLInterface(descriptor)) cgThings.append(CGInterfaceTrait(descriptor)) if descriptor.weakReferenceable: cgThings.append(CGWeakReferenceableTrait(descriptor)) + properties = PropertyArrays(descriptor) + cgThings.append(CGGeneric(str(properties))) + cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties, haveUnscopables)) + cgThings = CGList(cgThings, "\n") # self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name), # cgThings), diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index 590e57ba8e0..500f262f3af 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -9,16 +9,18 @@ use dom::bindings::conversions::get_dom_class; use dom::bindings::guard::Guard; use dom::bindings::utils::get_proto_or_iface_array; use js::error::throw_type_error; -use js::glue::UncheckedUnwrapObject; +use js::glue::{RUST_SYMBOL_TO_JSID, UncheckedUnwrapObject}; use js::jsapi::{Class, ClassExtension, ClassSpec, GetGlobalForObjectCrossCompartment}; -use js::jsapi::{HandleObject, HandleValue, JSClass, JSContext, JSFunctionSpec}; -use js::jsapi::{JSNative, JSFUN_CONSTRUCTOR, JSPROP_ENUMERATE, JSPROP_PERMANENT, JSPROP_READONLY}; -use js::jsapi::{JSPROP_RESOLVING, JSPropertySpec, JSString, JS_AtomizeAndPinString}; -use js::jsapi::{JS_DefineProperty, JS_DefineProperty1, JS_DefineProperty2, JS_DefineProperty4}; +use js::jsapi::{GetWellKnownSymbol, HandleObject, HandleValue, JSClass, JSContext}; +use js::jsapi::{JSFunctionSpec, JSNative, JSFUN_CONSTRUCTOR, JSPROP_ENUMERATE}; +use js::jsapi::{JSPROP_PERMANENT, JSPROP_READONLY, JSPROP_RESOLVING, JSPropertySpec}; +use js::jsapi::{JSString, JS_AtomizeAndPinString, JS_DefineProperty, JS_DefineProperty1}; +use js::jsapi::{JS_DefineProperty2, JS_DefineProperty4, JS_DefinePropertyById3}; use js::jsapi::{JS_GetClass, JS_GetFunctionObject, JS_GetPrototype, JS_LinkConstructorAndPrototype}; -use js::jsapi::{JS_NewFunction, JS_NewObject, JS_NewObjectWithUniqueType, JS_NewStringCopyN}; -use js::jsapi::{MutableHandleObject, MutableHandleValue, ObjectOps, RootedObject, RootedString}; -use js::jsapi::{RootedValue, Value}; +use js::jsapi::{JS_NewFunction, JS_NewObject, JS_NewObjectWithUniqueType}; +use js::jsapi::{JS_NewPlainObject, JS_NewStringCopyN, MutableHandleObject}; +use js::jsapi::{MutableHandleValue, ObjectOps, RootedId, RootedObject}; +use js::jsapi::{RootedString, RootedValue, SymbolCode, TrueHandleValue, Value}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value}; use js::rust::{define_methods, define_properties}; use libc; @@ -236,8 +238,22 @@ pub unsafe fn create_interface_prototype_object( regular_methods: &[Guard<&'static [JSFunctionSpec]>], regular_properties: &[Guard<&'static [JSPropertySpec]>], constants: &[Guard<&[ConstantSpec]>], + unscopable_names: &[&[u8]], rval: MutableHandleObject) { create_object(cx, proto, class, regular_methods, regular_properties, constants, rval); + + if !unscopable_names.is_empty() { + let mut unscopable_obj = RootedObject::new(cx, ptr::null_mut()); + create_unscopable_object(cx, unscopable_names, unscopable_obj.handle_mut()); + + let unscopable_symbol = GetWellKnownSymbol(cx, SymbolCode::unscopables); + assert!(!unscopable_symbol.is_null()); + + let unscopable_id = RootedId::new(cx, RUST_SYMBOL_TO_JSID(unscopable_symbol)); + assert!(JS_DefinePropertyById3( + cx, rval.handle(), unscopable_id.handle(), unscopable_obj.handle(), + JSPROP_READONLY, None, None)) + } } /// Create and define the interface object of a non-callback interface. @@ -375,6 +391,22 @@ unsafe fn create_object( } } +unsafe fn create_unscopable_object( + cx: *mut JSContext, + names: &[&[u8]], + rval: MutableHandleObject) { + assert!(!names.is_empty()); + assert!(rval.is_null()); + rval.set(JS_NewPlainObject(cx)); + assert!(!rval.ptr.is_null()); + for &name in names { + assert!(*name.last().unwrap() == b'\0'); + assert!(JS_DefineProperty( + cx, rval.handle(), name.as_ptr() as *const libc::c_char, TrueHandleValue, + JSPROP_READONLY, None, None)); + } +} + /// Conditionally define methods on an object. pub unsafe fn define_guarded_methods( cx: *mut JSContext, diff --git a/components/script/dom/webidls/ChildNode.webidl b/components/script/dom/webidls/ChildNode.webidl index 1506ec17c21..ca642048d11 100644 --- a/components/script/dom/webidls/ChildNode.webidl +++ b/components/script/dom/webidls/ChildNode.webidl @@ -8,12 +8,13 @@ [NoInterfaceObject] interface ChildNode { - [Throws] + [Throws, Unscopable] void before((Node or DOMString)... nodes); - [Throws] + [Throws, Unscopable] void after((Node or DOMString)... nodes); - [Throws] + [Throws, Unscopable] void replaceWith((Node or DOMString)... nodes); + [Unscopable] void remove(); }; diff --git a/components/script/dom/webidls/ParentNode.webidl b/components/script/dom/webidls/ParentNode.webidl index 667dcc4671d..84da03e3643 100644 --- a/components/script/dom/webidls/ParentNode.webidl +++ b/components/script/dom/webidls/ParentNode.webidl @@ -17,9 +17,9 @@ interface ParentNode { [Pure] readonly attribute unsigned long childElementCount; - [Throws] + [Throws, Unscopable] void prepend((Node or DOMString)... nodes); - [Throws] + [Throws, Unscopable] void append((Node or DOMString)... nodes); [Pure, Throws] |