From b10ff6d304580f9ae5f7cff6500c177aa258ea41 Mon Sep 17 00:00:00 2001 From: ldm0 Date: Fri, 2 Oct 2026 15:06:33 +0800 Subject: [PATCH] feat(media): expose native media stream track interface objects --- .../src/context_bootstrap/specs/registry.rs | 8 ++++ .../tests/media_stream_track_interfaces.rs | 44 +++++++++++++++++++ moli-renderer-v8/src/script_vm/tests/mod.rs | 1 + moli-renderer-v8/src/web_api_interfaces.rs | 2 + 4 files changed, 55 insertions(+) create mode 100644 moli-renderer-v8/src/script_vm/tests/media_stream_track_interfaces.rs diff --git a/moli-renderer-v8/src/context_bootstrap/specs/registry.rs b/moli-renderer-v8/src/context_bootstrap/specs/registry.rs index 0f1d0f1aab..428ccb8924 100644 --- a/moli-renderer-v8/src/context_bootstrap/specs/registry.rs +++ b/moli-renderer-v8/src/context_bootstrap/specs/registry.rs @@ -548,6 +548,14 @@ const CONSTRUCTOR_SPECS_BEFORE_STREAMS: &[ConstructorSpec] = &[ interface: web_api_interfaces::InputDeviceInfo::DESCRIPTOR, kind: ConstructorKind::Illegal, }, + ConstructorSpec { + interface: web_api_interfaces::MediaStreamTrack::DESCRIPTOR, + kind: ConstructorKind::Illegal, + }, + ConstructorSpec { + interface: web_api_interfaces::CanvasCaptureMediaStreamTrack::DESCRIPTOR, + kind: ConstructorKind::Illegal, + }, ConstructorSpec { interface: web_api_interfaces::MediaDevices::DESCRIPTOR, kind: ConstructorKind::Illegal, diff --git a/moli-renderer-v8/src/script_vm/tests/media_stream_track_interfaces.rs b/moli-renderer-v8/src/script_vm/tests/media_stream_track_interfaces.rs new file mode 100644 index 0000000000..5a799d6a99 --- /dev/null +++ b/moli-renderer-v8/src/script_vm/tests/media_stream_track_interfaces.rs @@ -0,0 +1,44 @@ +use super::*; + +#[test] +fn media_stream_track_interfaces_preserve_native_inheritance_and_realm_contracts() { + for url in [ + "https://media-stream-track-interfaces.test/", + "http://media-stream-track-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 [["MediaStreamTrack","EventTarget"],["CanvasCaptureMediaStreamTrack","MediaStreamTrack"]]) { + 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..4f36c67b6b 100644 --- a/moli-renderer-v8/src/script_vm/tests/mod.rs +++ b/moli-renderer-v8/src/script_vm/tests/mod.rs @@ -2144,6 +2144,7 @@ mod element_click; mod event_receivers; mod headers_list; mod http_fixture; +mod media_stream_track_interfaces; mod audio_event_interfaces; mod import_meta; diff --git a/moli-renderer-v8/src/web_api_interfaces.rs b/moli-renderer-v8/src/web_api_interfaces.rs index 5acca2d265..86de6f2d7c 100644 --- a/moli-renderer-v8/src/web_api_interfaces.rs +++ b/moli-renderer-v8/src/web_api_interfaces.rs @@ -289,6 +289,8 @@ interfaces! { MediaCapabilities; MediaDeviceInfo; InputDeviceInfo: MediaDeviceInfo; + MediaStreamTrack: EventTarget; + CanvasCaptureMediaStreamTrack: MediaStreamTrack; MediaDevices: EventTarget; MediaError; MediaList;