mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #23500 - sreeise:exposed_binding_gen, r=jdm
Make bindings aware of exposed members/partial interfaces <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [ ] These changes fix #23332 <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23500) <!-- Reviewable:end -->
This commit is contained in:
commit
95b304b786
25 changed files with 151 additions and 78 deletions
|
@ -1513,7 +1513,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
|
|||
returnType)
|
||||
|
||||
|
||||
def MemberCondition(pref, func):
|
||||
def MemberCondition(pref, func, 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
|
||||
|
@ -1521,14 +1521,18 @@ def MemberCondition(pref, func):
|
|||
|
||||
pref: The name of the preference.
|
||||
func: The name of the function.
|
||||
exposed: One or more names of an exposed global.
|
||||
"""
|
||||
assert pref is None or isinstance(pref, 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:
|
||||
return 'Condition::Pref("%s")' % pref
|
||||
if 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"
|
||||
|
||||
|
||||
|
@ -1571,7 +1575,8 @@ class PropertyDefiner:
|
|||
PropertyDefiner.getStringAttr(interfaceMember,
|
||||
"Pref"),
|
||||
PropertyDefiner.getStringAttr(interfaceMember,
|
||||
"Func"))
|
||||
"Func"),
|
||||
interfaceMember.exposedSet())
|
||||
|
||||
def generateGuardedArray(self, array, name, specTemplate, specTerminator,
|
||||
specType, getCondition, getDataTuple):
|
||||
|
@ -1609,8 +1614,13 @@ class PropertyDefiner:
|
|||
if specTerminator:
|
||||
currentSpecs.append(specTerminator)
|
||||
specs.append("&[\n" + ",\n".join(currentSpecs) + "]\n")
|
||||
prefableSpecs.append(
|
||||
prefableTemplate % (cond, name + "_specs", len(specs) - 1))
|
||||
if isinstance(cond, list):
|
||||
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" +
|
||||
",\n".join(specs) + "\n" +
|
||||
|
@ -2640,8 +2650,8 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties):
|
|||
"""
|
||||
unforgeables = []
|
||||
|
||||
defineUnforgeableAttrs = "define_guarded_properties(cx, unforgeable_holder.handle(), %s);"
|
||||
defineUnforgeableMethods = "define_guarded_methods(cx, unforgeable_holder.handle(), %s);"
|
||||
defineUnforgeableAttrs = "define_guarded_properties(cx, unforgeable_holder.handle(), %s, global);"
|
||||
defineUnforgeableMethods = "define_guarded_methods(cx, unforgeable_holder.handle(), %s, global);"
|
||||
|
||||
unforgeableMembers = [
|
||||
(defineUnforgeableAttrs, properties.unforgeable_attrs),
|
||||
|
@ -2751,7 +2761,7 @@ class CGWrapGlobalMethod(CGAbstractMethod):
|
|||
("define_guarded_methods", self.properties.methods),
|
||||
("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]
|
||||
values["members"] = "\n".join(members)
|
||||
|
||||
|
@ -2966,6 +2976,7 @@ assert!(!prototype_proto.is_null());""" % getPrototypeProto)]
|
|||
code.append(CGGeneric("""
|
||||
rooted!(in(cx) let mut prototype = ptr::null_mut::<JSObject>());
|
||||
create_interface_prototype_object(cx,
|
||||
global.into(),
|
||||
prototype_proto.handle().into(),
|
||||
&PrototypeClass,
|
||||
%(methods)s,
|
||||
|
@ -7543,6 +7554,7 @@ impl %(base)s {
|
|||
for m in descriptor.interface.members:
|
||||
if PropertyDefiner.getStringAttr(m, 'Pref') or \
|
||||
PropertyDefiner.getStringAttr(m, 'Func') or \
|
||||
PropertyDefiner.getStringAttr(m, 'Exposed') or \
|
||||
(m.isMethod() and m.isIdentifierLess()):
|
||||
continue
|
||||
display = m.identifier.name + ('()' if m.isMethod() else '')
|
||||
|
|
|
@ -3723,6 +3723,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:
|
||||
|
@ -3756,12 +3757,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():
|
||||
|
|
|
@ -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():
|
|
@ -4,6 +4,7 @@ patch < debug.patch
|
|||
patch < callback-location.patch
|
||||
patch < union-typedef.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
|
||||
rm -r tests
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
//! 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::rust::HandleObject;
|
||||
use servo_config::prefs;
|
||||
|
@ -26,8 +28,13 @@ impl<T: Clone + Copy> Guard<T> {
|
|||
/// Expose the value if the 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) {
|
||||
pub unsafe fn expose(
|
||||
&self,
|
||||
cx: *mut JSContext,
|
||||
obj: HandleObject,
|
||||
global: HandleObject,
|
||||
) -> Option<T> {
|
||||
if self.condition.is_satisfied(cx, obj, global) {
|
||||
Some(self.value)
|
||||
} else {
|
||||
None
|
||||
|
@ -41,15 +48,23 @@ pub enum Condition {
|
|||
Func(unsafe fn(*mut JSContext, HandleObject) -> bool),
|
||||
/// The condition is satisfied if the preference is set.
|
||||
Pref(&'static str),
|
||||
// The condition is satisfied if the interface is exposed in the global.
|
||||
Exposed(InterfaceObjectMap::Globals),
|
||||
/// The condition is always satisfied.
|
||||
Satisfied,
|
||||
}
|
||||
|
||||
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 {
|
||||
Condition::Pref(name) => prefs::pref_map().get(name).as_bool().unwrap_or(false),
|
||||
Condition::Func(f) => f(cx, obj),
|
||||
Condition::Exposed(globals) => is_exposed_in(global, globals),
|
||||
Condition::Satisfied => true,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ pub unsafe fn create_callback_interface_object(
|
|||
assert!(!constants.is_empty());
|
||||
rval.set(JS_NewObject(cx, ptr::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_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.
|
||||
pub unsafe fn create_interface_prototype_object(
|
||||
cx: *mut JSContext,
|
||||
global: HandleObject,
|
||||
proto: HandleObject,
|
||||
class: &'static JSClass,
|
||||
regular_methods: &[Guard<&'static [JSFunctionSpec]>],
|
||||
|
@ -191,6 +192,7 @@ pub unsafe fn create_interface_prototype_object(
|
|||
) {
|
||||
create_object(
|
||||
cx,
|
||||
global,
|
||||
proto,
|
||||
class,
|
||||
regular_methods,
|
||||
|
@ -233,6 +235,7 @@ pub unsafe fn create_noncallback_interface_object(
|
|||
) {
|
||||
create_object(
|
||||
cx,
|
||||
global,
|
||||
proto,
|
||||
class.as_jsclass(),
|
||||
static_methods,
|
||||
|
@ -288,6 +291,7 @@ pub unsafe fn create_named_constructors(
|
|||
/// Create a new object with a unique type.
|
||||
pub unsafe fn create_object(
|
||||
cx: *mut JSContext,
|
||||
global: HandleObject,
|
||||
proto: HandleObject,
|
||||
class: &'static JSClass,
|
||||
methods: &[Guard<&'static [JSFunctionSpec]>],
|
||||
|
@ -297,9 +301,9 @@ pub unsafe fn create_object(
|
|||
) {
|
||||
rval.set(JS_NewObjectWithUniqueType(cx, class, proto));
|
||||
assert!(!rval.is_null());
|
||||
define_guarded_methods(cx, rval.handle(), methods);
|
||||
define_guarded_properties(cx, rval.handle(), properties);
|
||||
define_guarded_constants(cx, rval.handle(), constants);
|
||||
define_guarded_methods(cx, rval.handle(), methods, global);
|
||||
define_guarded_properties(cx, rval.handle(), properties, global);
|
||||
define_guarded_constants(cx, rval.handle(), constants, global);
|
||||
}
|
||||
|
||||
/// Conditionally define constants on an object.
|
||||
|
@ -307,9 +311,10 @@ pub unsafe fn define_guarded_constants(
|
|||
cx: *mut JSContext,
|
||||
obj: HandleObject,
|
||||
constants: &[Guard<&[ConstantSpec]>],
|
||||
global: HandleObject,
|
||||
) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -320,9 +325,10 @@ pub unsafe fn define_guarded_methods(
|
|||
cx: *mut JSContext,
|
||||
obj: HandleObject,
|
||||
methods: &[Guard<&'static [JSFunctionSpec]>],
|
||||
global: HandleObject,
|
||||
) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -333,9 +339,10 @@ pub unsafe fn define_guarded_properties(
|
|||
cx: *mut JSContext,
|
||||
obj: HandleObject,
|
||||
properties: &[Guard<&'static [JSPropertySpec]>],
|
||||
global: HandleObject,
|
||||
) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,6 @@ pub unsafe fn create_namespace_object(
|
|||
name: &[u8],
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -1087,6 +1087,18 @@ impl TestBindingMethods for TestBinding {
|
|||
fn IncumbentGlobal(&self) -> DomRoot<GlobalScope> {
|
||||
GlobalScope::incumbent().unwrap()
|
||||
}
|
||||
|
||||
fn SemiExposedBoolFromInterface(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn BoolFromSemiExposedPartialInterface(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn SemiExposedBoolFromPartialInterface(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl TestBinding {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
[
|
||||
ExceptionClass,
|
||||
Exposed=(Window,Worker),
|
||||
Exposed=(Window,Worker,Worklet,DissimilarOriginWindow),
|
||||
Constructor(optional DOMString message="", optional DOMString name="Error")
|
||||
]
|
||||
interface DOMException {
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
// way to enforce security policy.
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#location
|
||||
[Unforgeable, NoInterfaceObject] interface DissimilarOriginLocation {
|
||||
[Exposed=(Window,DissimilarOriginWindow), Unforgeable, NoInterfaceObject]
|
||||
interface DissimilarOriginLocation {
|
||||
[Throws] attribute USVString href;
|
||||
[Throws] void assign(USVString url);
|
||||
[Throws] void replace(USVString url);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// way to enforce security policy.
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#window
|
||||
[Global, NoInterfaceObject]
|
||||
[Global, Exposed=(Window,DissimilarOriginWindow), NoInterfaceObject]
|
||||
interface DissimilarOriginWindow : GlobalScope {
|
||||
[Unforgeable] readonly attribute WindowProxy window;
|
||||
[BinaryName="Self_", Replaceable] readonly attribute WindowProxy self;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* https://dom.spec.whatwg.org/#interface-eventtarget
|
||||
*/
|
||||
|
||||
[Constructor, Exposed=(Window,Worker,Worklet)]
|
||||
[Constructor, Exposed=(Window,Worker,Worklet,DissimilarOriginWindow)]
|
||||
interface EventTarget {
|
||||
void addEventListener(
|
||||
DOMString type,
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
// This interface is entirely internal to Servo, and should not be accessible to
|
||||
// web pages.
|
||||
|
||||
[Exposed=(Window,Worker,Worklet),
|
||||
[Exposed=(Window,Worker,Worklet,DissimilarOriginWindow),
|
||||
Inline]
|
||||
interface GlobalScope : EventTarget {};
|
||||
|
|
|
@ -556,6 +556,19 @@ interface TestBinding {
|
|||
|
||||
GlobalScope entryGlobal();
|
||||
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);
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#the-windowproxy-exotic-object
|
||||
[NoInterfaceObject]
|
||||
[Exposed=(Window,DissimilarOriginWindow), NoInterfaceObject]
|
||||
interface WindowProxy {};
|
||||
|
|
|
@ -689369,7 +689369,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"xhr/abort-after-send.any.js": [
|
||||
"41922c915a653ee96e949a3c8ce2aeeb4fd0630c",
|
||||
"0ffd8877f87f9255668409c1fc9e973d006e6ae9",
|
||||
"testharness"
|
||||
],
|
||||
"xhr/abort-after-stop.any.js": [
|
||||
|
|
|
@ -630,24 +630,6 @@
|
|||
[WorkerNavigator interface: self.navigator must not have property "taintEnabled"]
|
||||
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)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -30,24 +30,6 @@
|
|||
[WorkerNavigator interface: attribute onLine]
|
||||
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)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -12,9 +12,6 @@
|
|||
[Resource timing seems to work in workers]
|
||||
expected: FAIL
|
||||
|
||||
[performance.timing is not available in workers]
|
||||
expected: FAIL
|
||||
|
||||
[performance.toJSON is available in workers]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -18,12 +18,6 @@
|
|||
[idlharness]
|
||||
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]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
[responseXML-unavailable-in-worker.html]
|
||||
type: testharness
|
||||
[XMLHttpRequest's responseXML property should not be exposed in workers.]
|
||||
expected: FAIL
|
||||
|
|
@ -9735,6 +9735,9 @@
|
|||
"mozilla/webgl/tex_image_2d_simple_ref.html": [
|
||||
[]
|
||||
],
|
||||
"mozilla/worker_member_test.js": [
|
||||
[]
|
||||
],
|
||||
"mozilla/worklets/syntax_error.js": [
|
||||
[]
|
||||
],
|
||||
|
@ -18895,7 +18898,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"mozilla/interface_member_exposed.html": [
|
||||
"dd637cf92a894e4569e8fb0baf11eea6968033af",
|
||||
"f408f9c3dae4b78b49bf77b5ad32c0d5ee406f7e",
|
||||
"testharness"
|
||||
],
|
||||
"mozilla/interfaces.html": [
|
||||
|
@ -19594,6 +19597,10 @@
|
|||
"d5c75899eb546d7243d65b6f55e876c5008c6292",
|
||||
"testharness"
|
||||
],
|
||||
"mozilla/worker_member_test.js": [
|
||||
"abca5cd280ac07914cb21ee4968ac4d27e7feb68",
|
||||
"support"
|
||||
],
|
||||
"mozilla/worklets/syntax_error.js": [
|
||||
"4adade8939ce62eb5e83d73d4faf2261b264d809",
|
||||
"support"
|
||||
|
|
|
@ -43,4 +43,22 @@ for (var i = 0; i < staticMembers.length; i++) {
|
|||
test_member(name + 'Enabled', true, 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>
|
||||
|
|
3
tests/wpt/mozilla/tests/mozilla/worker_member_test.js
Normal file
3
tests/wpt/mozilla/tests/mozilla/worker_member_test.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
let member = location.search.slice(1);
|
||||
var binding = new TestBinding();
|
||||
postMessage(binding[member]);
|
|
@ -9,7 +9,9 @@
|
|||
client.addEventListener("readystatechange", test.step_func(function() {
|
||||
if(client.readyState == 4) {
|
||||
control_flag = true
|
||||
assert_equals(client.responseXML, null)
|
||||
if (self.GLOBAL.isWindow()) {
|
||||
assert_equals(client.responseXML, null)
|
||||
}
|
||||
assert_equals(client.responseText, "")
|
||||
assert_equals(client.status, 0)
|
||||
assert_equals(client.statusText, "")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue