diff --git a/components/script/dom/debuggerglobalscope.rs b/components/script/dom/debuggerglobalscope.rs
new file mode 100644
index 00000000000..9075060aab1
--- /dev/null
+++ b/components/script/dom/debuggerglobalscope.rs
@@ -0,0 +1,88 @@
+/* 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 std::sync::Arc;
+
+use base::id::PipelineId;
+use constellation_traits::ScriptToConstellationChan;
+use dom_struct::dom_struct;
+use js::jsval::UndefinedValue;
+use js::rust::Runtime;
+use net_traits::ResourceThreads;
+use profile_traits::{mem, time};
+use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
+
+use crate::dom::bindings::codegen::Bindings::DebuggerGlobalScopeBinding;
+use crate::dom::bindings::root::DomRoot;
+use crate::dom::globalscope::GlobalScope;
+#[cfg(feature = "testbinding")]
+#[cfg(feature = "webgpu")]
+use crate::dom::webgpu::identityhub::IdentityHub;
+use crate::script_module::ScriptFetchOptions;
+use crate::script_runtime::{CanGc, JSContext};
+
+#[dom_struct]
+/// Global scope for interacting with the devtools Debugger API.
+///
+///
+pub(crate) struct DebuggerGlobalScope {
+ global_scope: GlobalScope,
+}
+
+impl DebuggerGlobalScope {
+ /// Create a new heap-allocated `DebuggerGlobalScope`.
+ #[allow(unsafe_code)]
+ pub(crate) fn new(
+ runtime: &Runtime,
+ mem_profiler_chan: mem::ProfilerChan,
+ time_profiler_chan: time::ProfilerChan,
+ script_to_constellation_chan: ScriptToConstellationChan,
+ resource_threads: ResourceThreads,
+ #[cfg(feature = "webgpu")] gpu_id_hub: Arc,
+ ) -> DomRoot {
+ let global = Box::new(Self {
+ global_scope: GlobalScope::new_inherited(
+ PipelineId::new(), // ??? or TEST_PIPELINE_ID, but that seems worse
+ None, // ? if needed, see script_thread:745
+ mem_profiler_chan,
+ time_profiler_chan,
+ script_to_constellation_chan, // wrap it in a ScriptToConstellationChan
+ resource_threads,
+ MutableOrigin::new(ImmutableOrigin::new_opaque()),
+ ServoUrl::parse_with_base(None, "about:internal/debugger")
+ .expect("Guaranteed by argument"), // ???
+ None,
+ Default::default(),
+ gpu_id_hub,
+ None, // ? if needed, see script_thread:745
+ false,
+ ),
+ });
+
+ unsafe {
+ DebuggerGlobalScopeBinding::Wrap::(
+ JSContext::from_ptr(runtime.cx()),
+ global,
+ )
+ }
+ }
+
+ /// Get the JS context.
+ pub(crate) fn get_cx() -> JSContext {
+ GlobalScope::get_cx()
+ }
+
+ /// Evaluate a JS script in this global.
+ pub(crate) fn evaluate_js(&self, script: &str, can_gc: CanGc) -> bool {
+ debug!("Evaluating Dom in a worklet.");
+ rooted!(in (*GlobalScope::get_cx()) let mut rval = UndefinedValue());
+ self.global_scope.evaluate_js_on_global_with_result(
+ script,
+ rval.handle_mut(),
+ ScriptFetchOptions::default_classic_script(&self.global_scope),
+ self.global_scope.api_base_url(),
+ can_gc,
+ )
+ }
+}
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index 01ff74c7c49..b2ab674e29d 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -114,7 +114,7 @@ use crate::dom::reportingobserver::ReportingObserver;
use crate::dom::serviceworker::ServiceWorker;
use crate::dom::serviceworkerregistration::ServiceWorkerRegistration;
use crate::dom::trustedtypepolicyfactory::TrustedTypePolicyFactory;
-use crate::dom::types::MessageEvent;
+use crate::dom::types::{DebuggerGlobalScope, MessageEvent};
use crate::dom::underlyingsourcecontainer::UnderlyingSourceType;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::gpudevice::GPUDevice;
@@ -2530,6 +2530,9 @@ impl GlobalScope {
// https://drafts.css-houdini.org/worklets/#script-settings-for-worklets
return worklet.base_url();
}
+ if let Some(_debugger_global) = self.downcast::() {
+ return self.creation_url.clone();
+ }
unreachable!();
}
@@ -2545,6 +2548,9 @@ impl GlobalScope {
// TODO: is this the right URL to return?
return worklet.base_url();
}
+ if let Some(_debugger_global) = self.downcast::() {
+ return self.creation_url.clone();
+ }
unreachable!();
}
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 8190a0b1dda..3dabb64c11a 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -289,6 +289,7 @@ pub(crate) mod customevent;
pub(crate) mod datatransfer;
pub(crate) mod datatransferitem;
pub(crate) mod datatransferitemlist;
+pub(crate) mod debuggerglobalscope;
pub(crate) mod dedicatedworkerglobalscope;
pub(crate) mod defaultteereadrequest;
pub(crate) mod defaultteeunderlyingsource;
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 18bf170f1f3..939303ebeb8 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -133,6 +133,7 @@ use crate::dom::htmlslotelement::HTMLSlotElement;
use crate::dom::mutationobserver::MutationObserver;
use crate::dom::node::{Node, NodeTraits, ShadowIncluding};
use crate::dom::servoparser::{ParserContext, ServoParser};
+use crate::dom::types::DebuggerGlobalScope;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub;
use crate::dom::window::Window;
@@ -1004,6 +1005,23 @@ impl ScriptThread {
/// messages on its port.
pub(crate) fn start(&self, can_gc: CanGc) {
debug!("Starting script thread.");
+
+ let pipeline_id = PipelineId::new();
+ let script_to_constellation_chan = ScriptToConstellationChan {
+ sender: self.senders.pipeline_to_constellation_sender.clone(),
+ pipeline_id,
+ };
+ let debugger_global = DebuggerGlobalScope::new(
+ &self.js_runtime,
+ self.senders.memory_profiler_sender.clone(),
+ self.senders.time_profiler_sender.clone(),
+ script_to_constellation_chan,
+ self.resource_threads.clone(),
+ #[cfg(feature = "webgpu")]
+ self.gpu_id_hub.clone(),
+ );
+ debugger_global.evaluate_js("console.log('hello world')", can_gc);
+
while self.handle_msgs(can_gc) {
// Go on...
debug!("Running script thread.");
diff --git a/components/script_bindings/webidls/DebuggerGlobalScope.webidl b/components/script_bindings/webidls/DebuggerGlobalScope.webidl
new file mode 100644
index 00000000000..9035f7a40a2
--- /dev/null
+++ b/components/script_bindings/webidls/DebuggerGlobalScope.webidl
@@ -0,0 +1,7 @@
+/* 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/. */
+
+[Global=DebuggerGlobalScope, Exposed=DebuggerGlobalScope]
+interface DebuggerGlobalScope: GlobalScope {
+};
diff --git a/components/script_bindings/webidls/EventTarget.webidl b/components/script_bindings/webidls/EventTarget.webidl
index a8a63cc2b32..411fb962d32 100644
--- a/components/script_bindings/webidls/EventTarget.webidl
+++ b/components/script_bindings/webidls/EventTarget.webidl
@@ -5,7 +5,7 @@
* https://dom.spec.whatwg.org/#interface-eventtarget
*/
-[Exposed=(Window,Worker,Worklet,DissimilarOriginWindow)]
+[Exposed=(Window,Worker,Worklet,DissimilarOriginWindow,DebuggerGlobalScope)]
interface EventTarget {
[Throws] constructor();
undefined addEventListener(
diff --git a/components/script_bindings/webidls/GlobalScope.webidl b/components/script_bindings/webidls/GlobalScope.webidl
index 57206d13e6a..dfa44738781 100644
--- a/components/script_bindings/webidls/GlobalScope.webidl
+++ b/components/script_bindings/webidls/GlobalScope.webidl
@@ -5,6 +5,6 @@
// This interface is entirely internal to Servo, and should not be accessible to
// web pages.
-[Exposed=(Window,Worker,Worklet,DissimilarOriginWindow),
+[Exposed=(Window,Worker,Worklet,DissimilarOriginWindow,DebuggerGlobalScope),
Inline]
interface GlobalScope : EventTarget {};