diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index d2d090f83502..dd6d535e5ec8 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -2834,8 +2834,19 @@ def definition_body(self): else: proto_properties = properties + code.append(CGGeneric(""" rooted!(in(cx) let mut prototype = ptr::null_mut::()); +""")) + + if self.descriptor.hasNamedPropertiesObject(): + assert self.descriptor.isGlobal() + assert not self.haveUnscopables + code.append(CGGeneric(""" +dom::types::%s::CreateNamedPropertiesObject(cx, prototype.handle_mut()); +""" % name)) + else: + code.append(CGGeneric(""" create_interface_prototype_object(cx, prototype_proto.handle(), &PrototypeClass, @@ -2844,6 +2855,9 @@ def definition_body(self): %(consts)s, %(unscopables)s, prototype.handle_mut()); +""" % proto_properties)) + + code.append(CGGeneric(""" assert!(!prototype.is_null()); assert!((*cache)[PrototypeList::ID::%(id)s as usize].is_null()); (*cache)[PrototypeList::ID::%(id)s as usize] = prototype.get(); @@ -4899,8 +4913,7 @@ def getBody(self): CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" + "}\n") - namedGetter = self.descriptor.operations['NamedGetter'] - if namedGetter: + if self.descriptor.operations['NamedGetter']: attrs = [] if not self.descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties"): attrs.append("JSPROP_ENUMERATE") @@ -5152,11 +5165,10 @@ def getBody(self): else: indexed = "" - namedGetter = self.descriptor.operations['NamedGetter'] condition = "RUST_JSID_IS_STRING(id) || RUST_JSID_IS_INT(id)" if indexedGetter: condition = "index.is_none() && (%s)" % condition - if namedGetter: + if self.descriptor.operations['NamedGetter']: named = """\ if %s { let mut has_on_proto = false; @@ -5237,8 +5249,7 @@ def getBody(self): else: getIndexedOrExpando = getFromExpando + "\n" - namedGetter = self.descriptor.operations['NamedGetter'] - if namedGetter: + if self.descriptor.operations['NamedGetter']: condition = "RUST_JSID_IS_STRING(id) || RUST_JSID_IS_INT(id)" # From step 1: # If O supports indexed properties and P is an array index, then: @@ -5526,7 +5537,7 @@ def members(): rettype = "ErrorResult" yield name, attribute_arguments(typeNeedsCx(m.type, False), m.type), rettype - if descriptor.proxy: + if descriptor.proxy or descriptor.hasNamedPropertiesObject(): for name, operation in descriptor.operations.iteritems(): if not operation or operation.isStringifier(): continue @@ -5561,6 +5572,12 @@ def contains_unsafe_arg(arguments): return reduce((lambda x, y: x or y[1] == '*mut JSContext'), arguments, False) methods = [] + + if descriptor.hasNamedPropertiesObject(): + methods.append(CGGeneric(""" +unsafe fn CreateNamedPropertiesObject(cx: *mut JSContext, proto: MutableHandleObject); +""")) + for name, arguments, rettype in members(): arguments = list(arguments) methods.append(CGGeneric("%sfn %s(&self%s) -> %s;\n" % ( @@ -5859,6 +5876,7 @@ def reexportedName(name): cgThings = [] unscopableNames = [] + for m in descriptor.interface.members: if (m.isMethod() and (not m.isIdentifierLess() or m == descriptor.operations["Stringifier"])): @@ -5896,7 +5914,7 @@ def reexportedName(name): elif m.getExtendedAttribute("Replaceable"): cgThings.append(CGSpecializedReplaceableSetter(descriptor, m)) - if (not m.isStatic() and not descriptor.interface.isCallback()): + if not m.isStatic() and not descriptor.interface.isCallback(): cgThings.append(CGMemberJITInfo(descriptor, m)) if descriptor.concrete: diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index 0ab27151bb6e..17aa0efde2e7 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -267,8 +267,10 @@ def addOperation(operation, m): continue def addIndexedOrNamedOperation(operation, m): - self.proxy = True + if not self.isGlobal(): + self.proxy = True if m.isIndexed(): + assert not self.isGlobal() operation = 'Indexed' + operation else: assert m.isNamed() @@ -355,6 +357,15 @@ def binaryNameFor(self, name): def internalNameFor(self, name): return self._internalNames.get(name, name) + def hasNamedPropertiesObject(self): + if self.interface.isExternal(): + return False + + return self.isGlobal() and self.supportsNamedProperties() + + def supportsNamedProperties(self): + return self.operations['NamedGetter'] is not None + def getExtendedAttributes(self, member, getter=False, setter=False): def maybeAppendInfallibleToAttrs(attrs, throws): if throws is None: diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 436d4e71d1a8..66adea442eec 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -368,6 +368,56 @@ pub struct Document { throw_on_dynamic_markup_insertion_counter: Cell, } +// https://html.spec.whatwg.org/multipage/#dom-document-nameditem-filter +fn filter_by_name(name: &Atom, element: &Element) -> bool { + // TODO: Handle ,