Change bindings generation to make Exposed annotation aware of members/partial interfaces

This commit is contained in:
sreeise 2019-05-28 03:23:47 -04:00
parent 2b84348372
commit 871239a3e3
25 changed files with 151 additions and 78 deletions

View file

@ -1513,7 +1513,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
returnType) returnType)
def MemberCondition(pref, func): def MemberCondition(pref, func, exposed):
""" """
A string representing the condition for a member to actually be exposed. A string representing the condition for a member to actually be exposed.
Any of the arguments can be None. If not None, they should have the Any of the arguments can be None. If not None, they should have the
@ -1521,14 +1521,18 @@ def MemberCondition(pref, func):
pref: The name of the preference. pref: The name of the preference.
func: The name of the function. func: The name of the function.
exposed: One or more names of an exposed global.
""" """
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 assert exposed is None or isinstance(exposed, set)
assert func is None or pref is None or exposed is None
if pref: if pref:
return 'Condition::Pref("%s")' % pref return 'Condition::Pref("%s")' % pref
if func: if func:
return 'Condition::Func(%s)' % func return 'Condition::Func(%s)' % func
if exposed:
return ["Condition::Exposed(InterfaceObjectMap::Globals::%s)" % camel_to_upper_snake(i) for i in exposed]
return "Condition::Satisfied" return "Condition::Satisfied"
@ -1571,7 +1575,8 @@ class PropertyDefiner:
PropertyDefiner.getStringAttr(interfaceMember, PropertyDefiner.getStringAttr(interfaceMember,
"Pref"), "Pref"),
PropertyDefiner.getStringAttr(interfaceMember, PropertyDefiner.getStringAttr(interfaceMember,
"Func")) "Func"),
interfaceMember.exposedSet())
def generateGuardedArray(self, array, name, specTemplate, specTerminator, def generateGuardedArray(self, array, name, specTemplate, specTerminator,
specType, getCondition, getDataTuple): specType, getCondition, getDataTuple):
@ -1609,8 +1614,13 @@ class PropertyDefiner:
if specTerminator: if specTerminator:
currentSpecs.append(specTerminator) currentSpecs.append(specTerminator)
specs.append("&[\n" + ",\n".join(currentSpecs) + "]\n") specs.append("&[\n" + ",\n".join(currentSpecs) + "]\n")
prefableSpecs.append( if isinstance(cond, list):
prefableTemplate % (cond, name + "_specs", len(specs) - 1)) for i in cond:
prefableSpecs.append(
prefableTemplate % (i, name + "_specs", len(specs) - 1))
else:
prefableSpecs.append(
prefableTemplate % (cond, name + "_specs", len(specs) - 1))
specsArray = ("const %s_specs: &'static [&'static[%s]] = &[\n" + specsArray = ("const %s_specs: &'static [&'static[%s]] = &[\n" +
",\n".join(specs) + "\n" + ",\n".join(specs) + "\n" +
@ -2640,8 +2650,8 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties):
""" """
unforgeables = [] unforgeables = []
defineUnforgeableAttrs = "define_guarded_properties(cx, unforgeable_holder.handle(), %s);" defineUnforgeableAttrs = "define_guarded_properties(cx, unforgeable_holder.handle(), %s, global);"
defineUnforgeableMethods = "define_guarded_methods(cx, unforgeable_holder.handle(), %s);" defineUnforgeableMethods = "define_guarded_methods(cx, unforgeable_holder.handle(), %s, global);"
unforgeableMembers = [ unforgeableMembers = [
(defineUnforgeableAttrs, properties.unforgeable_attrs), (defineUnforgeableAttrs, properties.unforgeable_attrs),
@ -2751,7 +2761,7 @@ class CGWrapGlobalMethod(CGAbstractMethod):
("define_guarded_methods", self.properties.methods), ("define_guarded_methods", self.properties.methods),
("define_guarded_constants", self.properties.consts) ("define_guarded_constants", self.properties.consts)
] ]
members = ["%s(cx, obj.handle(), %s);" % (function, array.variableName()) members = ["%s(cx, obj.handle(), %s, obj.handle());" % (function, array.variableName())
for (function, array) in pairs if array.length() > 0] for (function, array) in pairs if array.length() > 0]
values["members"] = "\n".join(members) values["members"] = "\n".join(members)
@ -2966,6 +2976,7 @@ assert!(!prototype_proto.is_null());""" % getPrototypeProto)]
code.append(CGGeneric(""" code.append(CGGeneric("""
rooted!(in(cx) let mut prototype = ptr::null_mut::<JSObject>()); rooted!(in(cx) let mut prototype = ptr::null_mut::<JSObject>());
create_interface_prototype_object(cx, create_interface_prototype_object(cx,
global.into(),
prototype_proto.handle().into(), prototype_proto.handle().into(),
&PrototypeClass, &PrototypeClass,
%(methods)s, %(methods)s,
@ -7543,6 +7554,7 @@ impl %(base)s {
for m in descriptor.interface.members: for m in descriptor.interface.members:
if PropertyDefiner.getStringAttr(m, 'Pref') or \ if PropertyDefiner.getStringAttr(m, 'Pref') or \
PropertyDefiner.getStringAttr(m, 'Func') or \ PropertyDefiner.getStringAttr(m, 'Func') or \
PropertyDefiner.getStringAttr(m, 'Exposed') or \
(m.isMethod() and m.isIdentifierLess()): (m.isMethod() and m.isIdentifierLess()):
continue continue
display = m.identifier.name + ('()' if m.isMethod() else '') display = m.identifier.name + ('()' if m.isMethod() else '')

View file

@ -3723,6 +3723,7 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
IDLObjectWithIdentifier.__init__(self, location, None, identifier) IDLObjectWithIdentifier.__init__(self, location, None, identifier)
IDLExposureMixins.__init__(self, location) IDLExposureMixins.__init__(self, location)
self.tag = tag self.tag = tag
self.exposed = set()
if extendedAttrDict is None: if extendedAttrDict is None:
self._extendedAttrDict = {} self._extendedAttrDict = {}
else: else:
@ -3756,12 +3757,16 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
def getExtendedAttribute(self, name): def getExtendedAttribute(self, name):
return self._extendedAttrDict.get(name, None) return self._extendedAttrDict.get(name, None)
def exposedSet(self):
return self.exposed
def finish(self, scope): def finish(self, scope):
# We better be exposed _somewhere_. # We better be exposed _somewhere_.
if (len(self._exposureGlobalNames) == 0): if (len(self._exposureGlobalNames) == 0):
print(self.identifier.name) print(self.identifier.name)
assert len(self._exposureGlobalNames) != 0 assert len(self._exposureGlobalNames) != 0
IDLExposureMixins.finish(self, scope) IDLExposureMixins.finish(self, scope)
globalNameSetToExposureSet(scope, self._exposureGlobalNames, self.exposed)
def validate(self): def validate(self):
if self.isAttr() or self.isMethod(): if self.isAttr() or self.isMethod():

View file

@ -0,0 +1,27 @@
--- WebIDL.py
+++ WebIDL.py
@@ -3653,6 +3653,7 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
IDLExposureMixins.__init__(self, location)
self.tag = tag
+ self.exposed = set()
if extendedAttrDict is None:
self._extendedAttrDict = {}
else:
@@ -3686,12 +3687,16 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
def getExtendedAttribute(self, name):
return self._extendedAttrDict.get(name, None)
+ def exposedSet(self):
+ return self.exposed
+
def finish(self, scope):
# We better be exposed _somewhere_.
if (len(self._exposureGlobalNames) == 0):
print self.identifier.name
assert len(self._exposureGlobalNames) != 0
IDLExposureMixins.finish(self, scope)
+ globalNameSetToExposureSet(scope, self._exposureGlobalNames, self.exposed)
def validate(self):
if self.isAttr() or self.isMethod():

View file

@ -4,6 +4,7 @@ patch < debug.patch
patch < callback-location.patch patch < callback-location.patch
patch < union-typedef.patch patch < union-typedef.patch
patch < inline.patch patch < inline.patch
patch < exposed-globals.patch
wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz
rm -r tests rm -r tests

View file

@ -4,6 +4,8 @@
//! Machinery to conditionally expose things. //! Machinery to conditionally expose things.
use crate::dom::bindings::codegen::InterfaceObjectMap;
use crate::dom::bindings::interface::is_exposed_in;
use js::jsapi::JSContext; use js::jsapi::JSContext;
use js::rust::HandleObject; use js::rust::HandleObject;
use servo_config::prefs; use servo_config::prefs;
@ -26,8 +28,13 @@ impl<T: Clone + Copy> Guard<T> {
/// Expose the value if the condition is satisfied. /// Expose the value if the condition is satisfied.
/// ///
/// The passed handle is the object on which the value may be exposed. /// 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> { pub unsafe fn expose(
if self.condition.is_satisfied(cx, obj) { &self,
cx: *mut JSContext,
obj: HandleObject,
global: HandleObject,
) -> Option<T> {
if self.condition.is_satisfied(cx, obj, global) {
Some(self.value) Some(self.value)
} else { } else {
None None
@ -41,15 +48,23 @@ pub enum Condition {
Func(unsafe fn(*mut JSContext, HandleObject) -> bool), 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 satisfied if the interface is exposed in the global.
Exposed(InterfaceObjectMap::Globals),
/// The condition is always satisfied. /// The condition is always satisfied.
Satisfied, Satisfied,
} }
impl Condition { impl Condition {
unsafe fn is_satisfied(&self, cx: *mut JSContext, obj: HandleObject) -> bool { unsafe fn is_satisfied(
&self,
cx: *mut JSContext,
obj: HandleObject,
global: HandleObject,
) -> bool {
match *self { match *self {
Condition::Pref(name) => prefs::pref_map().get(name).as_bool().unwrap_or(false), Condition::Pref(name) => prefs::pref_map().get(name).as_bool().unwrap_or(false),
Condition::Func(f) => f(cx, obj), Condition::Func(f) => f(cx, obj),
Condition::Exposed(globals) => is_exposed_in(global, globals),
Condition::Satisfied => true, Condition::Satisfied => true,
} }
} }

View file

@ -173,7 +173,7 @@ pub unsafe fn create_callback_interface_object(
assert!(!constants.is_empty()); assert!(!constants.is_empty());
rval.set(JS_NewObject(cx, ptr::null())); rval.set(JS_NewObject(cx, ptr::null()));
assert!(!rval.is_null()); assert!(!rval.is_null());
define_guarded_constants(cx, rval.handle(), constants); define_guarded_constants(cx, rval.handle(), constants, global);
define_name(cx, rval.handle(), name); define_name(cx, rval.handle(), name);
define_on_global_object(cx, global, name, rval.handle()); define_on_global_object(cx, global, name, rval.handle());
} }
@ -181,6 +181,7 @@ pub unsafe fn create_callback_interface_object(
/// Create the interface prototype object of a non-callback interface. /// Create the interface prototype object of a non-callback interface.
pub unsafe fn create_interface_prototype_object( pub unsafe fn create_interface_prototype_object(
cx: *mut JSContext, cx: *mut JSContext,
global: HandleObject,
proto: HandleObject, proto: HandleObject,
class: &'static JSClass, class: &'static JSClass,
regular_methods: &[Guard<&'static [JSFunctionSpec]>], regular_methods: &[Guard<&'static [JSFunctionSpec]>],
@ -191,6 +192,7 @@ pub unsafe fn create_interface_prototype_object(
) { ) {
create_object( create_object(
cx, cx,
global,
proto, proto,
class, class,
regular_methods, regular_methods,
@ -233,6 +235,7 @@ pub unsafe fn create_noncallback_interface_object(
) { ) {
create_object( create_object(
cx, cx,
global,
proto, proto,
class.as_jsclass(), class.as_jsclass(),
static_methods, static_methods,
@ -288,6 +291,7 @@ pub unsafe fn create_named_constructors(
/// Create a new object with a unique type. /// Create a new object with a unique type.
pub unsafe fn create_object( pub unsafe fn create_object(
cx: *mut JSContext, cx: *mut JSContext,
global: HandleObject,
proto: HandleObject, proto: HandleObject,
class: &'static JSClass, class: &'static JSClass,
methods: &[Guard<&'static [JSFunctionSpec]>], methods: &[Guard<&'static [JSFunctionSpec]>],
@ -297,9 +301,9 @@ pub unsafe fn create_object(
) { ) {
rval.set(JS_NewObjectWithUniqueType(cx, class, proto)); rval.set(JS_NewObjectWithUniqueType(cx, class, proto));
assert!(!rval.is_null()); assert!(!rval.is_null());
define_guarded_methods(cx, rval.handle(), methods); define_guarded_methods(cx, rval.handle(), methods, global);
define_guarded_properties(cx, rval.handle(), properties); define_guarded_properties(cx, rval.handle(), properties, global);
define_guarded_constants(cx, rval.handle(), constants); define_guarded_constants(cx, rval.handle(), constants, global);
} }
/// Conditionally define constants on an object. /// Conditionally define constants on an object.
@ -307,9 +311,10 @@ pub unsafe fn define_guarded_constants(
cx: *mut JSContext, cx: *mut JSContext,
obj: HandleObject, obj: HandleObject,
constants: &[Guard<&[ConstantSpec]>], constants: &[Guard<&[ConstantSpec]>],
global: HandleObject,
) { ) {
for guard in constants { for guard in constants {
if let Some(specs) = guard.expose(cx, obj) { if let Some(specs) = guard.expose(cx, obj, global) {
define_constants(cx, obj, specs); define_constants(cx, obj, specs);
} }
} }
@ -320,9 +325,10 @@ pub unsafe fn define_guarded_methods(
cx: *mut JSContext, cx: *mut JSContext,
obj: HandleObject, obj: HandleObject,
methods: &[Guard<&'static [JSFunctionSpec]>], methods: &[Guard<&'static [JSFunctionSpec]>],
global: HandleObject,
) { ) {
for guard in methods { for guard in methods {
if let Some(specs) = guard.expose(cx, obj) { if let Some(specs) = guard.expose(cx, obj, global) {
define_methods(cx, obj, specs).unwrap(); define_methods(cx, obj, specs).unwrap();
} }
} }
@ -333,9 +339,10 @@ pub unsafe fn define_guarded_properties(
cx: *mut JSContext, cx: *mut JSContext,
obj: HandleObject, obj: HandleObject,
properties: &[Guard<&'static [JSPropertySpec]>], properties: &[Guard<&'static [JSPropertySpec]>],
global: HandleObject,
) { ) {
for guard in properties { for guard in properties {
if let Some(specs) = guard.expose(cx, obj) { if let Some(specs) = guard.expose(cx, obj, global) {
define_properties(cx, obj, specs).unwrap(); define_properties(cx, obj, specs).unwrap();
} }
} }

View file

@ -37,6 +37,6 @@ pub unsafe fn create_namespace_object(
name: &[u8], name: &[u8],
rval: MutableHandleObject, rval: MutableHandleObject,
) { ) {
create_object(cx, proto, &class.0, methods, &[], &[], rval); create_object(cx, global, proto, &class.0, methods, &[], &[], rval);
define_on_global_object(cx, global, name, rval.handle()); define_on_global_object(cx, global, name, rval.handle());
} }

View file

@ -1087,6 +1087,18 @@ impl TestBindingMethods for TestBinding {
fn IncumbentGlobal(&self) -> DomRoot<GlobalScope> { fn IncumbentGlobal(&self) -> DomRoot<GlobalScope> {
GlobalScope::incumbent().unwrap() GlobalScope::incumbent().unwrap()
} }
fn SemiExposedBoolFromInterface(&self) -> bool {
true
}
fn BoolFromSemiExposedPartialInterface(&self) -> bool {
true
}
fn SemiExposedBoolFromPartialInterface(&self) -> bool {
true
}
} }
impl TestBinding { impl TestBinding {

View file

@ -9,7 +9,7 @@
[ [
ExceptionClass, ExceptionClass,
Exposed=(Window,Worker), Exposed=(Window,Worker,Worklet,DissimilarOriginWindow),
Constructor(optional DOMString message="", optional DOMString name="Error") Constructor(optional DOMString message="", optional DOMString name="Error")
] ]
interface DOMException { interface DOMException {

View file

@ -14,7 +14,8 @@
// way to enforce security policy. // way to enforce security policy.
// https://html.spec.whatwg.org/multipage/#location // https://html.spec.whatwg.org/multipage/#location
[Unforgeable, NoInterfaceObject] interface DissimilarOriginLocation { [Exposed=(Window,DissimilarOriginWindow), Unforgeable, NoInterfaceObject]
interface DissimilarOriginLocation {
[Throws] attribute USVString href; [Throws] attribute USVString href;
[Throws] void assign(USVString url); [Throws] void assign(USVString url);
[Throws] void replace(USVString url); [Throws] void replace(USVString url);

View file

@ -13,7 +13,7 @@
// way to enforce security policy. // way to enforce security policy.
// https://html.spec.whatwg.org/multipage/#window // https://html.spec.whatwg.org/multipage/#window
[Global, NoInterfaceObject] [Global, Exposed=(Window,DissimilarOriginWindow), NoInterfaceObject]
interface DissimilarOriginWindow : GlobalScope { interface DissimilarOriginWindow : GlobalScope {
[Unforgeable] readonly attribute WindowProxy window; [Unforgeable] readonly attribute WindowProxy window;
[BinaryName="Self_", Replaceable] readonly attribute WindowProxy self; [BinaryName="Self_", Replaceable] readonly attribute WindowProxy self;

View file

@ -5,7 +5,7 @@
* https://dom.spec.whatwg.org/#interface-eventtarget * https://dom.spec.whatwg.org/#interface-eventtarget
*/ */
[Constructor, Exposed=(Window,Worker,Worklet)] [Constructor, Exposed=(Window,Worker,Worklet,DissimilarOriginWindow)]
interface EventTarget { interface EventTarget {
void addEventListener( void addEventListener(
DOMString type, DOMString type,

View file

@ -5,6 +5,6 @@
// This interface is entirely internal to Servo, and should not be accessible to // This interface is entirely internal to Servo, and should not be accessible to
// web pages. // web pages.
[Exposed=(Window,Worker,Worklet), [Exposed=(Window,Worker,Worklet,DissimilarOriginWindow),
Inline] Inline]
interface GlobalScope : EventTarget {}; interface GlobalScope : EventTarget {};

View file

@ -556,6 +556,19 @@ interface TestBinding {
GlobalScope entryGlobal(); GlobalScope entryGlobal();
GlobalScope incumbentGlobal(); GlobalScope incumbentGlobal();
[Exposed=(Window)]
readonly attribute boolean semiExposedBoolFromInterface;
};
[Exposed=(Window)]
partial interface TestBinding {
readonly attribute boolean boolFromSemiExposedPartialInterface;
};
partial interface TestBinding {
[Exposed=(Window)]
readonly attribute boolean semiExposedBoolFromPartialInterface;
}; };
callback SimpleCallback = void(any value); callback SimpleCallback = void(any value);

View file

@ -3,5 +3,5 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#the-windowproxy-exotic-object // https://html.spec.whatwg.org/multipage/#the-windowproxy-exotic-object
[NoInterfaceObject] [Exposed=(Window,DissimilarOriginWindow), NoInterfaceObject]
interface WindowProxy {}; interface WindowProxy {};

View file

@ -689238,7 +689238,7 @@
"testharness" "testharness"
], ],
"xhr/abort-after-send.any.js": [ "xhr/abort-after-send.any.js": [
"41922c915a653ee96e949a3c8ce2aeeb4fd0630c", "0ffd8877f87f9255668409c1fc9e973d006e6ae9",
"testharness" "testharness"
], ],
"xhr/abort-after-stop.any.js": [ "xhr/abort-after-stop.any.js": [

View file

@ -630,24 +630,6 @@
[WorkerNavigator interface: self.navigator must not have property "taintEnabled"] [WorkerNavigator interface: self.navigator must not have property "taintEnabled"]
expected: FAIL expected: FAIL
[WorkerNavigator interface: self.navigator must not have property "vendor"]
expected: FAIL
[WorkerNavigator interface: self.navigator must not have property "vendorSub"]
expected: FAIL
[WorkerNavigator interface: self.navigator must not have property "productSub"]
expected: FAIL
[WorkerNavigator interface: member vendor]
expected: FAIL
[WorkerNavigator interface: member vendorSub]
expected: FAIL
[WorkerNavigator interface: member productSub]
expected: FAIL
[OffscreenCanvasRenderingContext2D interface: operation arc(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, boolean)] [OffscreenCanvasRenderingContext2D interface: operation arc(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, boolean)]
expected: FAIL expected: FAIL

View file

@ -30,24 +30,6 @@
[WorkerNavigator interface: attribute onLine] [WorkerNavigator interface: attribute onLine]
expected: FAIL expected: FAIL
[WorkerNavigator interface: member productSub]
expected: FAIL
[WorkerNavigator interface: member vendor]
expected: FAIL
[WorkerNavigator interface: member vendorSub]
expected: FAIL
[WorkerNavigator interface: self.navigator must not have property "productSub"]
expected: FAIL
[WorkerNavigator interface: self.navigator must not have property "vendor"]
expected: FAIL
[WorkerNavigator interface: self.navigator must not have property "vendorSub"]
expected: FAIL
[WorkerNavigator interface: self.navigator must inherit property "languages" with the proper type (7)] [WorkerNavigator interface: self.navigator must inherit property "languages" with the proper type (7)]
expected: FAIL expected: FAIL

View file

@ -12,9 +12,6 @@
[Resource timing seems to work in workers] [Resource timing seems to work in workers]
expected: FAIL expected: FAIL
[performance.timing is not available in workers]
expected: FAIL
[performance.toJSON is available in workers] [performance.toJSON is available in workers]
expected: FAIL expected: FAIL

View file

@ -18,12 +18,6 @@
[idlharness] [idlharness]
expected: FAIL expected: FAIL
[XMLHttpRequest interface: new XMLHttpRequest() must not have property "responseXML"]
expected: FAIL
[XMLHttpRequest interface: member responseXML]
expected: FAIL
[Testing Symbol.iterator property of iterable interface FormData] [Testing Symbol.iterator property of iterable interface FormData]
expected: FAIL expected: FAIL

View file

@ -1,5 +0,0 @@
[responseXML-unavailable-in-worker.html]
type: testharness
[XMLHttpRequest's responseXML property should not be exposed in workers.]
expected: FAIL

View file

@ -9735,6 +9735,9 @@
"mozilla/webgl/tex_image_2d_simple_ref.html": [ "mozilla/webgl/tex_image_2d_simple_ref.html": [
[] []
], ],
"mozilla/worker_member_test.js": [
[]
],
"mozilla/worklets/syntax_error.js": [ "mozilla/worklets/syntax_error.js": [
[] []
], ],
@ -18895,7 +18898,7 @@
"testharness" "testharness"
], ],
"mozilla/interface_member_exposed.html": [ "mozilla/interface_member_exposed.html": [
"dd637cf92a894e4569e8fb0baf11eea6968033af", "f408f9c3dae4b78b49bf77b5ad32c0d5ee406f7e",
"testharness" "testharness"
], ],
"mozilla/interfaces.html": [ "mozilla/interfaces.html": [
@ -19594,6 +19597,10 @@
"d5c75899eb546d7243d65b6f55e876c5008c6292", "d5c75899eb546d7243d65b6f55e876c5008c6292",
"testharness" "testharness"
], ],
"mozilla/worker_member_test.js": [
"abca5cd280ac07914cb21ee4968ac4d27e7feb68",
"support"
],
"mozilla/worklets/syntax_error.js": [ "mozilla/worklets/syntax_error.js": [
"4adade8939ce62eb5e83d73d4faf2261b264d809", "4adade8939ce62eb5e83d73d4faf2261b264d809",
"support" "support"

View file

@ -43,4 +43,22 @@ for (var i = 0; i < staticMembers.length; i++) {
test_member(name + 'Enabled', true, function(o) { return o; }); test_member(name + 'Enabled', true, function(o) { return o; });
test_member(name + 'Disabled', false, function(o) { return o; }); test_member(name + 'Disabled', false, function(o) { return o; });
} }
members = [
'semiExposedBoolFromInterface',
'boolFromSemiExposedPartialInterface',
'semiExposedBoolFromPartialInterface',
];
for (const member of members) {
var interface = new TestBinding();
async_test(function(t) {
assert_true(member in interface);
assert_true(interface[member]);
let w = new Worker("worker_member_test.js?" + member);
w.onmessage = t.step_func(function(e) {
assert_equals(e.data, undefined);
t.done();
});
}, member);
}
</script> </script>

View file

@ -0,0 +1,3 @@
let member = location.search.slice(1);
var binding = new TestBinding();
postMessage(binding[member]);

View file

@ -9,7 +9,9 @@
client.addEventListener("readystatechange", test.step_func(function() { client.addEventListener("readystatechange", test.step_func(function() {
if(client.readyState == 4) { if(client.readyState == 4) {
control_flag = true control_flag = true
assert_equals(client.responseXML, null) if (self.GLOBAL.isWindow()) {
assert_equals(client.responseXML, null)
}
assert_equals(client.responseText, "") assert_equals(client.responseText, "")
assert_equals(client.status, 0) assert_equals(client.status, 0)
assert_equals(client.statusText, "") assert_equals(client.statusText, "")