devtools: Create source actors from Debugger API notifications (#38334)

currently our devtools impl creates source actors in script, when
executing scripts in HTMLScriptElement or DedicatedWorkerGlobalScope.
this approach is cumbersome, and it means that many pathways to running
scripts are missed, such as imported ES modules.

with the [SpiderMonkey Debugger
API](https://firefox-source-docs.mozilla.org/js/Debugger/), we can pick
up all of the scripts and all of their sources without any extra code,
as long as we tell it about every global we create (#38333, #38551).
this patch adds a [Debugger#onNewScript()
hook](https://firefox-source-docs.mozilla.org/js/Debugger/Debugger.html#onnewscript-script-global)
to the debugger script, which calls
DebuggerGlobalScope#notifyNewSource() to notify our script system when a
new script runs. if the source is relevant to the file tree in the
Sources tab, script tells devtools to create a source actor.

Testing: adds several new automated devtools tests
Fixes: part of #36027

Signed-off-by: Delan Azabani <dazabani@igalia.com>
Co-authored-by: atbrakhi <atbrakhi@igalia.com>
This commit is contained in:
shuppy 2025-08-11 14:04:51 +08:00 committed by GitHub
parent de73d4a25c
commit 4784668fa9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 522 additions and 118 deletions

View file

@ -56,6 +56,9 @@ pub struct SourceActor {
pub content: Option<String>,
pub content_type: Option<String>,
// TODO: use it in #37667, then remove this allow
#[allow(unused)]
pub spidermonkey_id: u32,
/// `introductionType` in SpiderMonkey `CompileOptionsWrapper`.
pub introduction_type: String,
}
@ -96,6 +99,7 @@ impl SourceActor {
url: ServoUrl,
content: Option<String>,
content_type: Option<String>,
spidermonkey_id: u32,
introduction_type: String,
) -> SourceActor {
SourceActor {
@ -104,6 +108,7 @@ impl SourceActor {
content,
content_type,
is_black_boxed: false,
spidermonkey_id,
introduction_type,
}
}
@ -114,6 +119,7 @@ impl SourceActor {
url: ServoUrl,
content: Option<String>,
content_type: Option<String>,
spidermonkey_id: u32,
introduction_type: String,
) -> &SourceActor {
let source_actor_name = actors.new_name("source");
@ -123,6 +129,7 @@ impl SourceActor {
url,
content,
content_type,
spidermonkey_id,
introduction_type,
);
actors.register(Box::new(source_actor));
@ -160,6 +167,10 @@ impl Actor for SourceActor {
let reply = SourceContentReply {
from: self.name(),
content_type: self.content_type.clone(),
// TODO: if needed, fetch the page again, in the same way as in the original request.
// Fetch it from cache, even if the original request was non-idempotent (e.g. POST).
// If we cant fetch it from cache, we should probably give up, because with a real
// fetch, the server could return a different response.
// TODO: do we want to wait instead of giving up immediately, in cases where the content could
// become available later (e.g. after a fetch)?
source: self