mirror of
https://github.com/lexmount/moli.git
synced 2026-11-03 08:07:00 +00:00
feat(media): expose MediaSource handle and buffer interface shells
This commit is contained in:
@@ -64,6 +64,9 @@ pub(in crate::context_bootstrap) const WORKER_SHARED_INTERFACE_NAMES: &[&str] =
|
||||
"BroadcastChannel",
|
||||
"Notification",
|
||||
"ImageData",
|
||||
"MediaSourceHandle",
|
||||
"SourceBuffer",
|
||||
"SourceBufferList",
|
||||
"EncodedVideoChunk",
|
||||
"ImageBitmap",
|
||||
"ImageBitmapRenderingContext",
|
||||
@@ -168,6 +171,8 @@ const WINDOW_DEDICATED_AND_SHARED_WORKER_INTERFACE_NAMES: &[&str] = &[
|
||||
"XMLHttpRequest",
|
||||
];
|
||||
const DEDICATED_AND_SHARED_WORKER_INTERFACE_NAMES: &[&str] = &["FileReaderSync"];
|
||||
const WINDOW_AND_DEDICATED_WORKER_INTERFACE_NAMES: &[&str] =
|
||||
&["MediaSourceHandle", "SourceBuffer", "SourceBufferList"];
|
||||
|
||||
pub(in crate::context_bootstrap) const INDEXED_DB_INTERFACE_NAMES: &[&str] = &[
|
||||
"DOMStringList",
|
||||
@@ -446,6 +451,9 @@ fn exposure_for_name(name: &str) -> ExposureSet {
|
||||
_ if WINDOW_DEDICATED_AND_SHARED_WORKER_INTERFACE_NAMES.contains(&name) => {
|
||||
ExposureSet::WINDOW_DEDICATED_AND_SHARED_WORKER
|
||||
}
|
||||
_ if WINDOW_AND_DEDICATED_WORKER_INTERFACE_NAMES.contains(&name) => {
|
||||
ExposureSet::WINDOW_AND_DEDICATED_WORKER
|
||||
}
|
||||
_ if DEDICATED_AND_SHARED_WORKER_INTERFACE_NAMES.contains(&name) => {
|
||||
ExposureSet::DEDICATED_AND_SHARED_WORKER
|
||||
}
|
||||
|
||||
@@ -732,3 +732,40 @@ fn worker_rectangle_interfaces_share_native_state_and_inheritance() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn source_buffer_interfaces_are_exposed_only_to_window_and_dedicated_workers() {
|
||||
crate::ensure_v8_for_test();
|
||||
for (realm, expected) in [
|
||||
(super::RealmKind::DedicatedWorker, true),
|
||||
(super::RealmKind::SharedWorker, false),
|
||||
(super::RealmKind::ServiceWorker, false),
|
||||
] {
|
||||
let mut isolate = v8::Isolate::new(Default::default());
|
||||
let scope = pin!(v8::HandleScope::new(&mut isolate));
|
||||
let scope = &mut scope.init();
|
||||
let context = v8::Context::new(scope, Default::default());
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
let global = context.global(scope);
|
||||
crate::context_bootstrap::install_worker_lazy_exposed_interfaces(
|
||||
scope, global, realm, true,
|
||||
)
|
||||
.expect("worker interfaces");
|
||||
for name in ["MediaSourceHandle", "SourceBuffer", "SourceBufferList"] {
|
||||
assert_eq!(
|
||||
global.has_own_property(scope, v8str(scope, name).into()),
|
||||
Some(expected),
|
||||
"{realm:?}/{name}"
|
||||
);
|
||||
if expected {
|
||||
assert!(
|
||||
global
|
||||
.get(scope, v8str(scope, name).into())
|
||||
.unwrap()
|
||||
.is_function(),
|
||||
"{name} materialization"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1383,6 +1383,18 @@ const CONSTRUCTOR_SPECS_AFTER_STREAMS: &[ConstructorSpec] = &[
|
||||
interface: web_api_interfaces::MediaQueryList::DESCRIPTOR,
|
||||
kind: ConstructorKind::MediaQueryList,
|
||||
},
|
||||
ConstructorSpec {
|
||||
interface: web_api_interfaces::SourceBufferList::DESCRIPTOR,
|
||||
kind: ConstructorKind::Illegal,
|
||||
},
|
||||
ConstructorSpec {
|
||||
interface: web_api_interfaces::SourceBuffer::DESCRIPTOR,
|
||||
kind: ConstructorKind::Illegal,
|
||||
},
|
||||
ConstructorSpec {
|
||||
interface: web_api_interfaces::MediaSourceHandle::DESCRIPTOR,
|
||||
kind: ConstructorKind::Illegal,
|
||||
},
|
||||
ConstructorSpec {
|
||||
interface: web_api_interfaces::MediaSource::DESCRIPTOR,
|
||||
kind: ConstructorKind::MediaSource,
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn media_source_buffer_interface_exposure_interfaces_have_realm_local_constructors_and_exposure() {
|
||||
for url in [
|
||||
"https://interface-exposure.test/",
|
||||
"http://interface-exposure.test/",
|
||||
] {
|
||||
let mut vm = new_storage_test_vm(url);
|
||||
assert_eq!(vm.eval(r#"
|
||||
(() => {
|
||||
const assert = (ok, message) => { if (!ok) throw Error(message); };
|
||||
const names = ["MediaSourceHandle", "SourceBuffer", "SourceBufferList"];
|
||||
const parents = {"MediaSourceHandle": null, "SourceBuffer": "EventTarget", "SourceBufferList": "EventTarget"};
|
||||
if (!document.documentElement) document.appendChild(document.createElement('html'));
|
||||
if (!document.body) document.documentElement.appendChild(document.createElement('body'));
|
||||
const child = document.createElement('iframe');
|
||||
document.body.appendChild(child);
|
||||
const other = child.contentWindow;
|
||||
for (const realm of [window, other]) {
|
||||
for (const name of names) {
|
||||
const C = realm[name];
|
||||
assert(typeof C === 'function' && C.name === name && C.length === 0, name + ' constructor');
|
||||
assert(C.prototype.constructor === C, name + ' prototype identity');
|
||||
assert(Object.getPrototypeOf(C.prototype) === (parents[name] ? realm[parents[name]].prototype : realm.Object.prototype), name + ' prototype inheritance');
|
||||
assert(realm[name] === C, name + ' stable lazy materialization');
|
||||
for (const invoke of [() => C(), () => new C(), () => Reflect.construct(C, [], function Subclass() {})]) {
|
||||
let error;
|
||||
try { invoke(); } catch (caught) { error = caught; }
|
||||
assert(error instanceof realm.TypeError, name + ' rejects construction in callee realm');
|
||||
}
|
||||
assert(C !== (realm === window ? other[name] : window[name]), name + ' distinct realm constructors');
|
||||
}
|
||||
}
|
||||
return 'passed';
|
||||
})()
|
||||
"#).unwrap(), "passed", "{url}");
|
||||
}
|
||||
}
|
||||
@@ -2169,6 +2169,7 @@ mod http_fixture;
|
||||
mod iframe_load_delivery;
|
||||
mod media_owner_playback_interfaces;
|
||||
mod media_recorder_shell;
|
||||
mod media_source_buffer_interface_exposure_interfaces;
|
||||
mod performance_observer_contract;
|
||||
mod performance_receiver_consolidation;
|
||||
mod performance_timing_interface_exposure_interfaces;
|
||||
|
||||
@@ -325,6 +325,9 @@ interfaces! {
|
||||
MediaQueryListEvent: Event;
|
||||
MediaRecorder: EventTarget;
|
||||
MediaSession;
|
||||
MediaSourceHandle;
|
||||
SourceBuffer: EventTarget;
|
||||
SourceBufferList: EventTarget;
|
||||
MediaSource: EventTarget;
|
||||
MemoryInfo;
|
||||
MIDIPort: EventTarget;
|
||||
|
||||
Reference in New Issue
Block a user