SharedWorker: Add SharedWorker and SharedWorkerGlobalScope WebIDL interfaces (#44375)

Testing: covered by WPT test.
part of https://github.com/servo/servo/issues/7458

---------

Signed-off-by: Taym Haddadi <haddadi.taym@gmail.com>
This commit is contained in:
Taym Haddadi
2026-04-22 05:28:21 +02:00
committed by GitHub
parent d995e90976
commit bdbbe641eb
7 changed files with 202 additions and 0 deletions

View File

@@ -181,6 +181,8 @@ pub struct Preferences {
// feature: ServiceWorker | #36538 | Web/API/Service_Worker_API
pub dom_serviceworker_enabled: bool,
pub dom_serviceworker_timeout_seconds: i64,
// feature: SharedWorker | #7458 | Web/API/SharedWorker
pub dom_sharedworker_enabled: bool,
pub dom_servo_helpers_enabled: bool,
pub dom_servoparser_async_html_tokenizer_enabled: bool,
pub dom_testbinding_enabled: bool,
@@ -397,6 +399,7 @@ impl Preferences {
dom_storage_manager_api_enabled: false,
dom_serviceworker_enabled: false,
dom_serviceworker_timeout_seconds: 60,
dom_sharedworker_enabled: false,
dom_servo_helpers_enabled: false,
dom_servoparser_async_html_tokenizer_enabled: false,
dom_testbinding_enabled: false,

View File

@@ -11,6 +11,8 @@ pub(crate) mod serviceworkercontainer;
pub(crate) mod serviceworkerglobalscope;
#[expect(dead_code)]
pub(crate) mod serviceworkerregistration;
pub(crate) mod sharedworker;
pub(crate) mod sharedworkerglobalscope;
pub(crate) mod worker;
pub(crate) mod workerglobalscope;
pub(crate) mod workerlocation;

View File

@@ -0,0 +1,127 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use dom_struct::dom_struct;
use js::context::JSContext;
use js::rust::HandleObject;
use crate::dom::bindings::codegen::Bindings::SharedWorkerBinding::SharedWorkerMethods;
use crate::dom::bindings::codegen::UnionTypes::{
StringOrSharedWorkerOptions, TrustedScriptURLOrUSVString,
};
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto_and_cx;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::messageport::MessagePort;
use crate::dom::trustedtypes::trustedscripturl::TrustedScriptURL;
use crate::dom::window::Window;
use crate::script_runtime::CanGc;
/// <https://html.spec.whatwg.org/multipage/#shared-workers-and-the-sharedworker-interface>
#[dom_struct]
pub(crate) struct SharedWorker {
eventtarget: EventTarget,
/// The outside port returned to the creator's global.
port: Dom<MessagePort>,
}
impl SharedWorker {
fn new_inherited(port: &MessagePort) -> SharedWorker {
SharedWorker {
eventtarget: EventTarget::new_inherited(),
port: Dom::from_ref(port),
}
}
fn new(
global: &GlobalScope,
proto: Option<HandleObject>,
port: &MessagePort,
cx: &mut js::context::JSContext,
) -> DomRoot<SharedWorker> {
reflect_dom_object_with_proto_and_cx(
Box::new(SharedWorker::new_inherited(port)),
global,
proto,
cx,
)
}
}
impl SharedWorkerMethods<crate::DomTypeHolder> for SharedWorker {
/// <https://html.spec.whatwg.org/multipage/#dom-sharedworker>
fn Constructor(
cx: &mut JSContext,
window: &Window,
proto: Option<HandleObject>,
script_url: TrustedScriptURLOrUSVString,
options: StringOrSharedWorkerOptions,
) -> Fallible<DomRoot<SharedWorker>> {
let global = window.upcast::<GlobalScope>();
// Step 1. Let compliantScriptURL be the result of invoking the get trusted type
// compliant string algorithm with TrustedScriptURL, this's relevant global object,
// scriptURL, "SharedWorker constructor", and "script".
let compliant_script_url = TrustedScriptURL::get_trusted_type_compliant_string(
cx,
global,
script_url,
"SharedWorker constructor",
)?;
// Step 2. If options is a DOMString, set options to a new SharedWorkerOptions
// dictionary whose name member is set to the value of options and whose other
// members are set to their default values.
match options {
StringOrSharedWorkerOptions::String(name) => {
// TODO: The name will be used later.
let _worker_name = name;
},
StringOrSharedWorkerOptions::SharedWorkerOptions(_opts) => {
// TODO: Extract name from opts when implementing the registry phase.
},
}
// Step 3. Let outsideSettings be this's relevant settings object.
// (outsideSettings is `global` throughout.)
// Step 4. Let urlRecord be the result of encoding-parsing a URL given
// compliantScriptURL, relative to outsideSettings.
// Step 5. If urlRecord is failure, then throw a "SyntaxError" DOMException.
let Ok(_worker_url) = global.encoding_parse_a_url(&compliant_script_url.str()) else {
return Err(Error::Syntax(None));
};
// Step 6. Let outsidePort be a new MessagePort in outsideSettings's realm.
let outside_port = MessagePort::new(global, CanGc::from_cx(cx));
global.track_message_port(&outside_port, None);
// Step 7. Set this's port to outsidePort.
// (Stored via SharedWorker::new below.)
// TODO Step 8. Let callerIsSecureContext be true if outsideSettings is a secure
// context; otherwise, false.
// TODO Step 9. Let outsideStorageKey be the result of running obtain a storage key
// for non-storage purposes given outsideSettings.
// TODO Step 10. Let worker be this.
// TODO Step 11
Ok(SharedWorker::new(global, proto, &outside_port, cx))
}
/// <https://html.spec.whatwg.org/multipage/#dom-sharedworker-port>
fn Port(&self) -> DomRoot<MessagePort> {
// The port getter steps are to return this's port.
DomRoot::from_ref(&*self.port)
}
// <https://html.spec.whatwg.org/multipage/#handler-abstractworker-onerror>
event_handler!(error, GetOnerror, SetOnerror);
}

View File

@@ -0,0 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use dom_struct::dom_struct;
use crate::dom::bindings::codegen::Bindings::SharedWorkerGlobalScopeBinding::SharedWorkerGlobalScopeMethods;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::str::DOMString;
use crate::dom::workerglobalscope::WorkerGlobalScope;
// https://html.spec.whatwg.org/multipage/#the-sharedworkerglobalscope-interface
#[dom_struct]
pub(crate) struct SharedWorkerGlobalScope {
workerglobalscope: WorkerGlobalScope,
}
impl SharedWorkerGlobalScopeMethods<crate::DomTypeHolder> for SharedWorkerGlobalScope {
/// <https://html.spec.whatwg.org/multipage/#dom-sharedworkerglobalscope-name>
fn Name(&self) -> DOMString {
// The name getter steps are to return this's name.
// Its value represents the name that can be used to obtain a reference to the worker using the SharedWorker constructor.
self.workerglobalscope.worker_name()
}
/// <https://html.spec.whatwg.org/multipage/#dom-sharedworkerglobalscope-close>
fn Close(&self) {
// The close() method steps are to close a worker given this.
self.upcast::<WorkerGlobalScope>().close()
}
// <https://html.spec.whatwg.org/multipage/#handler-sharedworkerglobalscope-onconnect>
event_handler!(connect, GetOnconnect, SetOnconnect);
}

View File

@@ -937,6 +937,13 @@ DOMInterfaces = {
'register': False,
},
'SharedWorker': {
'cx': ['Constructor'],
},
'SharedWorkerGlobalScope': {
},
'Worker': {
'cx': ['Constructor', 'PostMessage', 'PostMessage_'],
},

View File

@@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#shared-workers-and-the-sharedworker-interface
[Pref="dom_sharedworker_enabled", Exposed=Window]
interface SharedWorker : EventTarget {
[Throws] constructor((TrustedScriptURL or USVString) scriptURL, optional (DOMString or SharedWorkerOptions) options = {});
readonly attribute MessagePort port;
};
SharedWorker includes AbstractWorker;
dictionary SharedWorkerOptions : WorkerOptions {
boolean extendedLifetime = false;
};

View File

@@ -0,0 +1,13 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#sharedworkerglobalscope
[Pref="dom_sharedworker_enabled", Global=(Worker,SharedWorker), Exposed=SharedWorker]
interface SharedWorkerGlobalScope : WorkerGlobalScope {
[Replaceable] readonly attribute DOMString name;
undefined close();
attribute EventHandler onconnect;
};