diff options
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 66 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/Configuration.py | 3 |
2 files changed, 65 insertions, 4 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 1ef2e0a4eb9..939fc05d581 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -1925,7 +1925,10 @@ class CGList(CGThing): """ def __init__(self, children, joiner=""): CGThing.__init__(self) - self.children = children + # Make a copy of the kids into a list, because if someone passes in a + # generator we won't be able to both declare and define ourselves, or + # define ourselves more than once! + self.children = list(children) self.joiner = joiner def append(self, child): @@ -1934,12 +1937,15 @@ class CGList(CGThing): def prepend(self, child): self.children.insert(0, child) - def join(self, generator): - return self.joiner.join(filter(lambda s: len(s) > 0, (child for child in generator))) + def join(self, iterable): + return self.joiner.join(s for s in iterable if len(s) > 0) def define(self): return self.join(child.define() for child in self.children if child is not None) + def __len__(self): + return len(self.children) + class CGIfElseWrapper(CGList): def __init__(self, condition, ifTrue, ifFalse): @@ -2145,6 +2151,49 @@ class CGAbstractMethod(CGThing): raise NotImplementedError # Override me! +class CGConstructorEnabled(CGAbstractMethod): + """ + A method for testing whether we should be exposing this interface + object or navigator property. This can perform various tests + depending on what conditions are specified on the interface. + """ + def __init__(self, descriptor): + CGAbstractMethod.__init__(self, descriptor, + 'ConstructorEnabled', 'bool', + [Argument("*mut JSContext", "aCx"), + Argument("HandleObject", "aObj")]) + + def definition_body(self): + body = CGList([], "\n") + + conditions = [] + iface = self.descriptor.interface + + pref = iface.getExtendedAttribute("Pref") + if pref: + assert isinstance(pref, list) and len(pref) == 1 + conditions.append('prefs::get_pref("%s").as_boolean().unwrap_or(false)' % pref[0]) + func = iface.getExtendedAttribute("Func") + if func: + assert isinstance(func, list) and len(func) == 1 + conditions.append("%s(aCx, aObj)" % func[0]) + # We should really have some conditions + assert len(body) or len(conditions) + + conditionsWrapper = "" + if len(conditions): + conditionsWrapper = CGWrapper(CGList((CGGeneric(cond) for cond in conditions), + " &&\n"), + pre="return ", + post=";\n", + reindent=True) + else: + conditionsWrapper = CGGeneric("return true;\n") + + body.append(conditionsWrapper) + return body + + def CreateBindingJSObject(descriptor, parent=None): create = "let raw = Box::into_raw(object);\nlet _rt = RootedTraceable::new(&*raw);\n" if descriptor.proxy: @@ -2684,15 +2733,21 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): return CGAbstractMethod.define(self) def definition_body(self): + def getCheck(desc): + if not desc.isExposedConditionally(): + return "" + else: + return "if !ConstructorEnabled(cx, global) { return; }" if self.descriptor.interface.isCallback(): function = "GetConstructorObject" else: function = "GetProtoObject" return CGGeneric("""\ assert!(!global.get().is_null()); +%s let mut proto = RootedObject::new(cx, ptr::null_mut()); %s(cx, global, proto.handle_mut()); -assert!(!proto.ptr.is_null());""" % function) +assert!(!proto.ptr.is_null());""" % (getCheck(self.descriptor), function)) def needCx(returnType, arguments, considerTypes): @@ -5003,6 +5058,8 @@ class CGDescriptor(CGThing): if descriptor.interface.hasInterfaceObject(): cgThings.append(CGDefineDOMInterfaceMethod(descriptor)) + if descriptor.isExposedConditionally(): + cgThings.append(CGConstructorEnabled(descriptor)) if descriptor.proxy: cgThings.append(CGDefineProxyHandler(descriptor)) @@ -5444,6 +5501,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::weakref::{DOM_WEAK_SLOT, WeakBox, WeakReferenceable}', 'mem::heap_size_of_raw_self_and_children', 'libc', + 'util::prefs', 'util::str::DOMString', 'std::borrow::ToOwned', 'std::cmp', diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index 99727f8acc0..9a1c5e2f4df 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -351,6 +351,9 @@ class Descriptor(DescriptorProvider): assert self.interface.hasInterfaceObject() return self.interface.isCallback() or self.hasDescendants() + def isExposedConditionally(self): + return self.interface.isExposedConditionally() + def isGlobal(self): """ Returns true if this is the primary interface for a global object |