Implement [Func]

This commit is contained in:
Anthony Ramine 2016-05-21 00:09:06 +02:00
parent 0d04acd50f
commit e179cb02ff
6 changed files with 58 additions and 8 deletions

View file

@ -1334,8 +1334,11 @@ def MemberCondition(pref, func):
""" """
assert pref is None or isinstance(pref, str) assert pref is None or isinstance(pref, str)
assert func is None or isinstance(func, str) assert func is None or isinstance(func, str)
assert func is None or pref is None
if pref: if pref:
return 'Condition::Pref("%s")' % pref return 'Condition::Pref("%s")' % pref
if func:
return 'Condition::Func(%s)' % func
return "Condition::Satisfied" return "Condition::Satisfied"

View file

@ -4,6 +4,7 @@
//! Machinery to conditionally expose things. //! Machinery to conditionally expose things.
use js::jsapi::{HandleObject, JSContext};
use util::prefs::get_pref; use util::prefs::get_pref;
/// A container with a condition. /// A container with a condition.
@ -22,8 +23,10 @@ impl<T: Clone + Copy> Guard<T> {
} }
/// Expose the value if the condition is satisfied. /// Expose the value if the condition is satisfied.
pub fn expose(&self) -> Option<T> { ///
if self.condition.is_satisfied() { /// The passed handle is the object on which the value may be exposed.
pub unsafe fn expose(&self, cx: *mut JSContext, obj: HandleObject) -> Option<T> {
if self.condition.is_satisfied(cx, obj) {
Some(self.value) Some(self.value)
} else { } else {
None None
@ -33,6 +36,8 @@ impl<T: Clone + Copy> Guard<T> {
/// A condition to expose things. /// A condition to expose things.
pub enum Condition { pub enum Condition {
/// The condition is satisfied if the function returns true.
Func(unsafe fn(*mut JSContext, HandleObject) -> bool),
/// The condition is satisfied if the preference is set. /// The condition is satisfied if the preference is set.
Pref(&'static str), Pref(&'static str),
/// The condition is always satisfied. /// The condition is always satisfied.
@ -40,9 +45,10 @@ pub enum Condition {
} }
impl Condition { impl Condition {
fn is_satisfied(&self) -> bool { unsafe fn is_satisfied(&self, cx: *mut JSContext, obj: HandleObject) -> bool {
match *self { match *self {
Condition::Pref(name) => get_pref(name).as_boolean().unwrap_or(false), Condition::Pref(name) => get_pref(name).as_boolean().unwrap_or(false),
Condition::Func(f) => f(cx, obj),
Condition::Satisfied => true, Condition::Satisfied => true,
} }
} }

View file

@ -220,7 +220,7 @@ pub unsafe fn create_callback_interface_object(
rval.set(JS_NewObject(cx, ptr::null())); rval.set(JS_NewObject(cx, ptr::null()));
assert!(!rval.ptr.is_null()); assert!(!rval.ptr.is_null());
for guard in constants { for guard in constants {
if let Some(specs) = guard.expose() { if let Some(specs) = guard.expose(cx, rval.handle()) {
define_constants(cx, rval.handle(), specs); define_constants(cx, rval.handle(), specs);
} }
} }
@ -369,7 +369,7 @@ unsafe fn create_object(
define_guarded_methods(cx, rval.handle(), methods); define_guarded_methods(cx, rval.handle(), methods);
define_guarded_properties(cx, rval.handle(), properties); define_guarded_properties(cx, rval.handle(), properties);
for guard in constants { for guard in constants {
if let Some(specs) = guard.expose() { if let Some(specs) = guard.expose(cx, rval.handle()) {
define_constants(cx, rval.handle(), specs); define_constants(cx, rval.handle(), specs);
} }
} }
@ -381,7 +381,7 @@ pub unsafe fn define_guarded_methods(
obj: HandleObject, obj: HandleObject,
methods: &[Guard<&'static [JSFunctionSpec]>]) { methods: &[Guard<&'static [JSFunctionSpec]>]) {
for guard in methods { for guard in methods {
if let Some(specs) = guard.expose() { if let Some(specs) = guard.expose(cx, obj) {
define_methods(cx, obj, specs).unwrap(); define_methods(cx, obj, specs).unwrap();
} }
} }
@ -393,7 +393,7 @@ pub unsafe fn define_guarded_properties(
obj: HandleObject, obj: HandleObject,
properties: &[Guard<&'static [JSPropertySpec]>]) { properties: &[Guard<&'static [JSPropertySpec]>]) {
for guard in properties { for guard in properties {
if let Some(specs) = guard.expose() { if let Some(specs) = guard.expose(cx, obj) {
define_properties(cx, obj, specs).unwrap(); define_properties(cx, obj, specs).unwrap();
} }
} }

View file

@ -24,7 +24,7 @@ use dom::bindings::str::{ByteString, DOMString, USVString};
use dom::bindings::weakref::MutableWeakRef; use dom::bindings::weakref::MutableWeakRef;
use dom::blob::{Blob, DataSlice}; use dom::blob::{Blob, DataSlice};
use dom::url::URL; use dom::url::URL;
use js::jsapi::{HandleValue, JSContext, JSObject}; use js::jsapi::{HandleObject, HandleValue, JSContext, JSObject};
use js::jsval::{JSVal, NullValue}; use js::jsval::{JSVal, NullValue};
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::ptr; use std::ptr;
@ -567,6 +567,10 @@ impl TestBindingMethods for TestBinding {
fn PrefControlledAttributeEnabled(&self) -> bool { false } fn PrefControlledAttributeEnabled(&self) -> bool { false }
fn PrefControlledMethodDisabled(&self) {} fn PrefControlledMethodDisabled(&self) {}
fn PrefControlledMethodEnabled(&self) {} fn PrefControlledMethodEnabled(&self) {}
fn FuncControlledAttributeDisabled(&self) -> bool { false }
fn FuncControlledAttributeEnabled(&self) -> bool { false }
fn FuncControlledMethodDisabled(&self) {}
fn FuncControlledMethodEnabled(&self) {}
} }
impl TestBinding { impl TestBinding {
@ -577,4 +581,14 @@ impl TestBinding {
pub fn PrefControlledStaticAttributeEnabled(_: GlobalRef) -> bool { false } pub fn PrefControlledStaticAttributeEnabled(_: GlobalRef) -> bool { false }
pub fn PrefControlledStaticMethodDisabled(_: GlobalRef) {} pub fn PrefControlledStaticMethodDisabled(_: GlobalRef) {}
pub fn PrefControlledStaticMethodEnabled(_: GlobalRef) {} pub fn PrefControlledStaticMethodEnabled(_: GlobalRef) {}
pub fn FuncControlledStaticAttributeDisabled(_: GlobalRef) -> bool { false }
pub fn FuncControlledStaticAttributeEnabled(_: GlobalRef) -> bool { false }
pub fn FuncControlledStaticMethodDisabled(_: GlobalRef) {}
pub fn FuncControlledStaticMethodEnabled(_: GlobalRef) {}
}
#[allow(unsafe_code)]
impl TestBinding {
pub unsafe fn condition_satisfied(_: *mut JSContext, _: HandleObject) -> bool { true }
pub unsafe fn condition_unsatisfied(_: *mut JSContext, _: HandleObject) -> bool { false }
} }

View file

@ -433,4 +433,26 @@ interface TestBinding {
static void prefControlledStaticMethodEnabled(); static void prefControlledStaticMethodEnabled();
[Pref="dom.testbinding.prefcontrolled2.enabled"] [Pref="dom.testbinding.prefcontrolled2.enabled"]
const unsigned short prefControlledConstEnabled = 0; const unsigned short prefControlledConstEnabled = 0;
[Func="TestBinding::condition_unsatisfied"]
readonly attribute boolean funcControlledAttributeDisabled;
[Func="TestBinding::condition_unsatisfied"]
static readonly attribute boolean funcControlledStaticAttributeDisabled;
[Func="TestBinding::condition_unsatisfied"]
void funcControlledMethodDisabled();
[Func="TestBinding::condition_unsatisfied"]
static void funcControlledStaticMethodDisabled();
[Func="TestBinding::condition_unsatisfied"]
const unsigned short funcControlledConstDisabled = 0;
[Func="TestBinding::condition_satisfied"]
readonly attribute boolean funcControlledAttributeEnabled;
[Func="TestBinding::condition_satisfied"]
static readonly attribute boolean funcControlledStaticAttributeEnabled;
[Func="TestBinding::condition_satisfied"]
void funcControlledMethodEnabled();
[Func="TestBinding::condition_satisfied"]
static void funcControlledStaticMethodEnabled();
[Func="TestBinding::condition_satisfied"]
const unsigned short funcControlledConstEnabled = 0;
}; };

View file

@ -19,10 +19,15 @@ function test_member(name, enabled, target) {
} }
var members = [ var members = [
'funcControlledAttribute',
'funcControlledMethod',
'prefControlledAttribute', 'prefControlledAttribute',
'prefControlledMethod' 'prefControlledMethod'
]; ];
var staticMembers = [ var staticMembers = [
'funcControlledStaticAttribute',
'funcControlledStaticMethod',
'funcControlledConst',
'prefControlledStaticAttribute', 'prefControlledStaticAttribute',
'prefControlledStaticMethod', 'prefControlledStaticMethod',
'prefControlledConst' 'prefControlledConst'