mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Support controlling the visibility of WebIDL interfaces via the Pref annotation.
This commit is contained in:
parent
224bcd7057
commit
bb47f72f25
2 changed files with 65 additions and 4 deletions
|
@ -1925,7 +1925,10 @@ class CGList(CGThing):
|
||||||
"""
|
"""
|
||||||
def __init__(self, children, joiner=""):
|
def __init__(self, children, joiner=""):
|
||||||
CGThing.__init__(self)
|
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
|
self.joiner = joiner
|
||||||
|
|
||||||
def append(self, child):
|
def append(self, child):
|
||||||
|
@ -1934,12 +1937,15 @@ class CGList(CGThing):
|
||||||
def prepend(self, child):
|
def prepend(self, child):
|
||||||
self.children.insert(0, child)
|
self.children.insert(0, child)
|
||||||
|
|
||||||
def join(self, generator):
|
def join(self, iterable):
|
||||||
return self.joiner.join(filter(lambda s: len(s) > 0, (child for child in generator)))
|
return self.joiner.join(s for s in iterable if len(s) > 0)
|
||||||
|
|
||||||
def define(self):
|
def define(self):
|
||||||
return self.join(child.define() for child in self.children if child is not None)
|
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):
|
class CGIfElseWrapper(CGList):
|
||||||
def __init__(self, condition, ifTrue, ifFalse):
|
def __init__(self, condition, ifTrue, ifFalse):
|
||||||
|
@ -2145,6 +2151,49 @@ class CGAbstractMethod(CGThing):
|
||||||
raise NotImplementedError # Override me!
|
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):
|
def CreateBindingJSObject(descriptor, parent=None):
|
||||||
create = "let raw = Box::into_raw(object);\nlet _rt = RootedTraceable::new(&*raw);\n"
|
create = "let raw = Box::into_raw(object);\nlet _rt = RootedTraceable::new(&*raw);\n"
|
||||||
if descriptor.proxy:
|
if descriptor.proxy:
|
||||||
|
@ -2684,15 +2733,21 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
||||||
return CGAbstractMethod.define(self)
|
return CGAbstractMethod.define(self)
|
||||||
|
|
||||||
def definition_body(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():
|
if self.descriptor.interface.isCallback():
|
||||||
function = "GetConstructorObject"
|
function = "GetConstructorObject"
|
||||||
else:
|
else:
|
||||||
function = "GetProtoObject"
|
function = "GetProtoObject"
|
||||||
return CGGeneric("""\
|
return CGGeneric("""\
|
||||||
assert!(!global.get().is_null());
|
assert!(!global.get().is_null());
|
||||||
|
%s
|
||||||
let mut proto = RootedObject::new(cx, ptr::null_mut());
|
let mut proto = RootedObject::new(cx, ptr::null_mut());
|
||||||
%s(cx, global, proto.handle_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):
|
def needCx(returnType, arguments, considerTypes):
|
||||||
|
@ -5003,6 +5058,8 @@ class CGDescriptor(CGThing):
|
||||||
|
|
||||||
if descriptor.interface.hasInterfaceObject():
|
if descriptor.interface.hasInterfaceObject():
|
||||||
cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
|
cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
|
||||||
|
if descriptor.isExposedConditionally():
|
||||||
|
cgThings.append(CGConstructorEnabled(descriptor))
|
||||||
|
|
||||||
if descriptor.proxy:
|
if descriptor.proxy:
|
||||||
cgThings.append(CGDefineProxyHandler(descriptor))
|
cgThings.append(CGDefineProxyHandler(descriptor))
|
||||||
|
@ -5444,6 +5501,7 @@ class CGBindingRoot(CGThing):
|
||||||
'dom::bindings::weakref::{DOM_WEAK_SLOT, WeakBox, WeakReferenceable}',
|
'dom::bindings::weakref::{DOM_WEAK_SLOT, WeakBox, WeakReferenceable}',
|
||||||
'mem::heap_size_of_raw_self_and_children',
|
'mem::heap_size_of_raw_self_and_children',
|
||||||
'libc',
|
'libc',
|
||||||
|
'util::prefs',
|
||||||
'util::str::DOMString',
|
'util::str::DOMString',
|
||||||
'std::borrow::ToOwned',
|
'std::borrow::ToOwned',
|
||||||
'std::cmp',
|
'std::cmp',
|
||||||
|
|
|
@ -351,6 +351,9 @@ class Descriptor(DescriptorProvider):
|
||||||
assert self.interface.hasInterfaceObject()
|
assert self.interface.hasInterfaceObject()
|
||||||
return self.interface.isCallback() or self.hasDescendants()
|
return self.interface.isCallback() or self.hasDescendants()
|
||||||
|
|
||||||
|
def isExposedConditionally(self):
|
||||||
|
return self.interface.isExposedConditionally()
|
||||||
|
|
||||||
def isGlobal(self):
|
def isGlobal(self):
|
||||||
"""
|
"""
|
||||||
Returns true if this is the primary interface for a global object
|
Returns true if this is the primary interface for a global object
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue