diff --git a/moli-renderer-v8/src/context_bootstrap/specs/registry.rs b/moli-renderer-v8/src/context_bootstrap/specs/registry.rs index 0f1d0f1aab..6e5e745ac4 100644 --- a/moli-renderer-v8/src/context_bootstrap/specs/registry.rs +++ b/moli-renderer-v8/src/context_bootstrap/specs/registry.rs @@ -560,6 +560,10 @@ const CONSTRUCTOR_SPECS_BEFORE_STREAMS: &[ConstructorSpec] = &[ interface: web_api_interfaces::ClipboardItem::DESCRIPTOR, kind: ConstructorKind::ClipboardItem, }, + ConstructorSpec { + interface: web_api_interfaces::MediaSession::DESCRIPTOR, + kind: ConstructorKind::Illegal, + }, ConstructorSpec { interface: web_api_interfaces::MediaCapabilities::DESCRIPTOR, kind: ConstructorKind::Illegal, diff --git a/moli-renderer-v8/src/script_vm/tests/media_session_interfaces.rs b/moli-renderer-v8/src/script_vm/tests/media_session_interfaces.rs new file mode 100644 index 0000000000..cfe8c4cb01 --- /dev/null +++ b/moli-renderer-v8/src/script_vm/tests/media_session_interfaces.rs @@ -0,0 +1,44 @@ +use super::*; + +#[test] +fn media_session_interfaces_preserve_native_inheritance_and_realm_contracts() { + for url in [ + "https://media-session-interfaces.test/", + "http://media-session-interfaces.test/", + "http://localhost/", + ] { + let mut vm = new_storage_page_task_executor_test_vm(url); + vm.eval("document.body.innerHTML = ''") + .unwrap(); + assert_eq!(vm.eval(r#"(() => { + const assert = (ok, message) => { if (!ok) throw Error(message); }; + { + const realms = [window, document.getElementById('child').contentWindow]; + for (const w of realms) { + for (const [name, parentName] of [["MediaSession","Object"]]) { + if (false && !w.isSecureContext) { + assert(!(name in w), name + ' hidden in an insecure realm'); + continue; + } + const C = w[name], parent = w[parentName]; + assert(typeof C === 'function' && C.name === name && C.length === 0, name + ' interface object'); + const descriptor = Object.getOwnPropertyDescriptor(w, name); + assert(descriptor.writable && descriptor.configurable && !descriptor.enumerable, name + ' global descriptor'); + assert(Object.getPrototypeOf(C.prototype) === parent.prototype, name + ' prototype inheritance'); + assert(Object.getPrototypeOf(C) === (parentName === 'Object' ? w.Function.prototype : parent), name + ' interface inheritance'); + assert(C.prototype.constructor === C, name + ' prototype constructor'); + const tag = Object.getOwnPropertyDescriptor(C.prototype, Symbol.toStringTag); + assert(tag.value === name && !tag.writable && !tag.enumerable && tag.configurable, name + ' tag'); + for (const call of [() => C(), () => new C()]) { + let error; + try { call(); } catch (caught) { error = caught; } + assert(error instanceof w.TypeError, name + ' rejects direct construction in the callee realm'); + if (w !== window) assert(!(error instanceof TypeError), name + ' foreign error realm'); + } + } + } + return true; + } +})()"#).unwrap(), "true", "{url}"); + } +} diff --git a/moli-renderer-v8/src/script_vm/tests/mod.rs b/moli-renderer-v8/src/script_vm/tests/mod.rs index c6babb3828..13053a25e6 100644 --- a/moli-renderer-v8/src/script_vm/tests/mod.rs +++ b/moli-renderer-v8/src/script_vm/tests/mod.rs @@ -2183,3 +2183,4 @@ mod intersection_target_order; mod observer_element_arguments; mod media_device_interfaces; +mod media_session_interfaces; diff --git a/moli-renderer-v8/src/web_api_interfaces.rs b/moli-renderer-v8/src/web_api_interfaces.rs index 5acca2d265..0621a9c301 100644 --- a/moli-renderer-v8/src/web_api_interfaces.rs +++ b/moli-renderer-v8/src/web_api_interfaces.rs @@ -294,6 +294,7 @@ interfaces! { MediaList; MediaQueryList: EventTarget; MediaQueryListEvent: Event; + MediaSession; MediaSource: EventTarget; MemoryInfo; MessageChannel;