script: Set correct introductionType values in more places (#38550)

to use the [SpiderMonkey Debugger
API](https://firefox-source-docs.mozilla.org/js/Debugger/) as the single
source of truth about scripts and their sources for devtools purposes
(servo/servo#38334), we need to keep track of whether scripts come from
an actual file or from things like setTimeout(), because for some
[introductionType](https://firefox-source-docs.mozilla.org/js/Debugger/Debugger.Source.html#introductiontype)
[values](https://firefox-source-docs.mozilla.org/devtools-user/debugger-api/debugger.source/#accessor-properties-of-the-debugger-source-prototype-object),
we want to disregard the script unless it has a [`//# sourceURL=`
override](https://tc39.es/ecma426/#sec-linking-eval)
([displayURL](https://firefox-source-docs.mozilla.org/js/Debugger/Debugger.Source.html#displayurl)).

this patch builds on #38363, setting the correct introductionType value
in several more cases.

Testing: will undergo many automated tests in #38334
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-09 13:05:54 +08:00 committed by GitHub
parent ff4971012f
commit 6471587fb4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 77 additions and 15 deletions

View file

@ -112,6 +112,7 @@ impl DebuggerGlobalScope {
ScriptFetchOptions::default_classic_script(&self.global_scope),
self.global_scope.api_base_url(),
can_gc,
None,
)
}

View file

@ -2759,6 +2759,7 @@ impl GlobalScope {
fetch_options: ScriptFetchOptions,
script_base_url: ServoUrl,
can_gc: CanGc,
introduction_type: Option<&'static CStr>,
) -> bool {
let source_code = SourceCode::Text(Rc::new(DOMString::from_string((*code).to_string())));
self.evaluate_script_on_global_with_result(
@ -2769,7 +2770,7 @@ impl GlobalScope {
fetch_options,
script_base_url,
can_gc,
None,
introduction_type,
)
}

View file

@ -213,6 +213,11 @@ pub(crate) struct HTMLScriptElement {
/// <https://w3c.github.io/trusted-types/dist/spec/#htmlscriptelement-script-text>
script_text: DomRefCell<DOMString>,
/// `introductionType` value to set in the `CompileOptionsWrapper`, overriding the usual
/// `srcScript` or `inlineScript` that this script would normally use.
#[no_trace]
introduction_type_override: Cell<Option<&'static CStr>>,
}
impl HTMLScriptElement {
@ -232,6 +237,7 @@ impl HTMLScriptElement {
preparation_time_document: MutNullableDom::new(None),
line_number: creator.return_line_number(),
script_text: DomRefCell::new(DOMString::new()),
introduction_type_override: Cell::new(None),
}
}
@ -688,7 +694,10 @@ impl HTMLScriptElement {
}
/// <https://html.spec.whatwg.org/multipage/#prepare-the-script-element>
pub(crate) fn prepare(&self, can_gc: CanGc) {
pub(crate) fn prepare(&self, introduction_type_override: Option<&'static CStr>, can_gc: CanGc) {
self.introduction_type_override
.set(introduction_type_override);
// Step 1. If el's already started is true, then return.
if self.already_started.get() {
return;
@ -1165,7 +1174,14 @@ impl HTMLScriptElement {
// Step 6.
let document = self.owner_document();
let old_script = document.GetCurrentScript();
let introduction_type = (!script.external).then_some(IntroductionType::INLINE_SCRIPT);
let introduction_type =
self.introduction_type_override
.get()
.unwrap_or(if script.external {
IntroductionType::SRC_SCRIPT
} else {
IntroductionType::INLINE_SCRIPT
});
match script.type_ {
ScriptType::Classic => {
@ -1174,7 +1190,7 @@ impl HTMLScriptElement {
} else {
document.set_current_script(Some(self))
}
self.run_a_classic_script(&script, can_gc, introduction_type);
self.run_a_classic_script(&script, can_gc, Some(introduction_type));
document.set_current_script(old_script.as_deref());
},
ScriptType::Module => {
@ -1428,7 +1444,7 @@ impl VirtualMethods for HTMLScriptElement {
if *attr.local_name() == local_name!("src") {
if let AttributeMutation::Set(_) = mutation {
if !self.parser_inserted.get() && self.upcast::<Node>().is_connected() {
self.prepare(can_gc);
self.prepare(Some(IntroductionType::INJECTED_SCRIPT), can_gc);
}
}
}
@ -1447,7 +1463,7 @@ impl VirtualMethods for HTMLScriptElement {
// running any scripts until the DOM tree is safe for interactions.
self.owner_document().add_delayed_task(
task!(ScriptPrepare: |script: DomRoot<HTMLScriptElement>| {
script.prepare(CanGc::note());
script.prepare(Some(IntroductionType::INJECTED_SCRIPT), CanGc::note());
}),
);
}
@ -1460,7 +1476,7 @@ impl VirtualMethods for HTMLScriptElement {
}
if self.upcast::<Node>().is_connected() && !self.parser_inserted.get() {
self.prepare(CanGc::note());
self.prepare(Some(IntroductionType::INJECTED_SCRIPT), CanGc::note());
}
}

View file

@ -76,7 +76,7 @@ use crate::dom::text::Text;
use crate::dom::virtualmethods::vtable_for;
use crate::network_listener::PreInvoke;
use crate::realms::enter_realm;
use crate::script_runtime::CanGc;
use crate::script_runtime::{CanGc, IntroductionType};
use crate::script_thread::ScriptThread;
mod async_html;
@ -682,7 +682,9 @@ impl ServoParser {
self.script_nesting_level.set(script_nesting_level + 1);
script.set_initial_script_text();
script.prepare(can_gc);
let introduction_type_override =
(script_nesting_level > 0).then_some(IntroductionType::INJECTED_SCRIPT);
script.prepare(introduction_type_override, can_gc);
self.script_nesting_level.set(script_nesting_level);
if self.document.has_pending_parsing_blocking_script() {

View file

@ -34,7 +34,7 @@ use crate::dom::worklet::WorkletExecutor;
use crate::messaging::MainThreadScriptMsg;
use crate::realms::enter_realm;
use crate::script_module::ScriptFetchOptions;
use crate::script_runtime::{CanGc, JSContext};
use crate::script_runtime::{CanGc, IntroductionType, JSContext};
#[dom_struct]
/// <https://drafts.css-houdini.org/worklets/#workletglobalscope>
@ -133,6 +133,7 @@ impl WorkletGlobalScope {
ScriptFetchOptions::default_classic_script(&self.globalscope),
self.globalscope.api_base_url(),
can_gc,
Some(IntroductionType::WORKLET),
)
}