mirror of
https://github.com/servo/servo.git
synced 2025-08-13 01:15:34 +01:00
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:
parent
ff4971012f
commit
6471587fb4
11 changed files with 77 additions and 15 deletions
|
@ -42,7 +42,7 @@ use crate::dom::node::{Node, NodeTraits, ShadowIncluding};
|
|||
use crate::dom::types::HTMLElement;
|
||||
use crate::realms::enter_realm;
|
||||
use crate::script_module::ScriptFetchOptions;
|
||||
use crate::script_runtime::CanGc;
|
||||
use crate::script_runtime::{CanGc, IntroductionType};
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub(crate) fn handle_evaluate_js(
|
||||
|
@ -57,6 +57,8 @@ pub(crate) fn handle_evaluate_js(
|
|||
let _ac = enter_realm(global);
|
||||
rooted!(in(*cx) let mut rval = UndefinedValue());
|
||||
let source_code = SourceCode::Text(Rc::new(DOMString::from_string(eval)));
|
||||
// TODO: run code with SpiderMonkey Debugger API, like Firefox does
|
||||
// <https://searchfox.org/mozilla-central/rev/f6a806c38c459e0e0d797d264ca0e8ad46005105/devtools/server/actors/webconsole/eval-with-debugger.js#270>
|
||||
global.evaluate_script_on_global_with_result(
|
||||
&source_code,
|
||||
"<eval>",
|
||||
|
@ -65,7 +67,7 @@ pub(crate) fn handle_evaluate_js(
|
|||
ScriptFetchOptions::default_classic_script(global),
|
||||
global.api_base_url(),
|
||||
can_gc,
|
||||
None,
|
||||
Some(IntroductionType::DEBUGGER_EVAL),
|
||||
);
|
||||
|
||||
if rval.is_undefined() {
|
||||
|
|
|
@ -112,6 +112,7 @@ impl DebuggerGlobalScope {
|
|||
ScriptFetchOptions::default_classic_script(&self.global_scope),
|
||||
self.global_scope.api_base_url(),
|
||||
can_gc,
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -836,6 +836,7 @@ impl ModuleTree {
|
|||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
// FIXME: spec links in this function are all broken, so it’s unclear what this algorithm does
|
||||
/// <https://html.spec.whatwg.org/multipage/#fetch-the-descendants-of-a-module-script>
|
||||
fn fetch_module_descendants(
|
||||
&self,
|
||||
|
@ -929,6 +930,8 @@ impl ModuleTree {
|
|||
Some(parent_identity.clone()),
|
||||
false,
|
||||
None,
|
||||
// TODO: is this correct?
|
||||
Some(IntroductionType::IMPORTED_MODULE),
|
||||
can_gc,
|
||||
);
|
||||
}
|
||||
|
@ -1200,6 +1203,8 @@ struct ModuleContext {
|
|||
status: Result<(), NetworkError>,
|
||||
/// Timing object for this resource
|
||||
resource_timing: ResourceFetchTiming,
|
||||
/// `introductionType` value to set in the `CompileOptionsWrapper`.
|
||||
introduction_type: Option<&'static CStr>,
|
||||
}
|
||||
|
||||
impl FetchResponseListener for ModuleContext {
|
||||
|
@ -1336,7 +1341,7 @@ impl FetchResponseListener for ModuleContext {
|
|||
compiled_module.handle_mut(),
|
||||
false,
|
||||
CanGc::note(),
|
||||
None,
|
||||
self.introduction_type,
|
||||
);
|
||||
|
||||
match compiled_module_result {
|
||||
|
@ -1570,6 +1575,7 @@ fn fetch_an_import_module_script_graph(
|
|||
None,
|
||||
true,
|
||||
Some(dynamic_module),
|
||||
Some(IntroductionType::IMPORTED_MODULE),
|
||||
can_gc,
|
||||
);
|
||||
Ok(())
|
||||
|
@ -1675,6 +1681,7 @@ pub(crate) fn fetch_external_module_script(
|
|||
None,
|
||||
true,
|
||||
None,
|
||||
Some(IntroductionType::SRC_SCRIPT),
|
||||
can_gc,
|
||||
)
|
||||
}
|
||||
|
@ -1738,6 +1745,7 @@ fn fetch_single_module_script(
|
|||
parent_identity: Option<ModuleIdentity>,
|
||||
top_level_module_fetch: bool,
|
||||
dynamic_module: Option<RootedTraceableBox<DynamicModule>>,
|
||||
introduction_type: Option<&'static CStr>,
|
||||
can_gc: CanGc,
|
||||
) {
|
||||
{
|
||||
|
@ -1857,6 +1865,7 @@ fn fetch_single_module_script(
|
|||
options,
|
||||
status: Ok(()),
|
||||
resource_timing: ResourceFetchTiming::new(ResourceTimingType::Resource),
|
||||
introduction_type,
|
||||
}));
|
||||
|
||||
let network_listener = NetworkListener {
|
||||
|
|
|
@ -1255,6 +1255,13 @@ pub(crate) use script_bindings::script_runtime::CanGc;
|
|||
// TODO: squish `scriptElement` <https://searchfox.org/mozilla-central/rev/202069c4c5113a1a9052d84fa4679d4c1b22113e/devtools/server/actors/source.js#199-201>
|
||||
pub(crate) struct IntroductionType;
|
||||
impl IntroductionType {
|
||||
/// `introductionType` for code evaluated by debugger.
|
||||
/// This includes code run via the devtools repl, even if the thread is not paused.
|
||||
pub const DEBUGGER_EVAL: &CStr = c"debugger eval";
|
||||
|
||||
/// `introductionType` for code loaded by worklet.
|
||||
pub const WORKLET: &CStr = c"Worklet";
|
||||
|
||||
/// `introductionType` for code belonging to `<script src="file.js">` elements.
|
||||
/// This includes `<script type="module" src="...">`.
|
||||
pub const SRC_SCRIPT: &CStr = c"srcScript";
|
||||
|
@ -1263,6 +1270,23 @@ impl IntroductionType {
|
|||
/// This includes `<script type="module" src="...">`.
|
||||
pub const INLINE_SCRIPT: &CStr = c"inlineScript";
|
||||
|
||||
/// `introductionType` for code belonging to scripts that *would* be `"inlineScript"` except that they were not
|
||||
/// part of the initial file itself.
|
||||
/// For example, scripts created via:
|
||||
/// - `document.write("<script>code;</script>")`
|
||||
/// - `var s = document.createElement("script"); s.text = "code";`
|
||||
pub const INJECTED_SCRIPT: &CStr = c"injectedScript";
|
||||
|
||||
/// `introductionType` for code that was loaded indirectly by being imported by another script
|
||||
/// using ESM static or dynamic imports.
|
||||
pub const IMPORTED_MODULE: &CStr = c"importedModule";
|
||||
|
||||
/// `introductionType` for code presented in `javascript:` URLs.
|
||||
pub const JAVASCRIPT_URL: &CStr = c"javascriptURL";
|
||||
|
||||
/// `introductionType` for code passed to `setTimeout`/`setInterval` as a string.
|
||||
pub const DOM_TIMER: &CStr = c"domTimer";
|
||||
|
||||
/// `introductionType` for web workers.
|
||||
/// <https://searchfox.org/mozilla-central/rev/202069c4c5113a1a9052d84fa4679d4c1b22113e/devtools/docs/user/debugger-api/debugger.source/index.rst#96>
|
||||
pub const WORKER: &CStr = c"Worker";
|
||||
|
|
|
@ -154,7 +154,8 @@ use crate::navigation::{InProgressLoad, NavigationListener};
|
|||
use crate::realms::enter_realm;
|
||||
use crate::script_module::ScriptFetchOptions;
|
||||
use crate::script_runtime::{
|
||||
CanGc, JSContext, JSContextHelper, Runtime, ScriptThreadEventCategory, ThreadSafeJSContext,
|
||||
CanGc, IntroductionType, JSContext, JSContextHelper, Runtime, ScriptThreadEventCategory,
|
||||
ThreadSafeJSContext,
|
||||
};
|
||||
use crate::task_queue::TaskQueue;
|
||||
use crate::task_source::{SendableTaskSource, TaskSourceName};
|
||||
|
@ -3739,6 +3740,7 @@ impl ScriptThread {
|
|||
ScriptFetchOptions::default_classic_script(global_scope),
|
||||
global_scope.api_base_url(),
|
||||
can_gc,
|
||||
Some(IntroductionType::JAVASCRIPT_URL),
|
||||
);
|
||||
|
||||
load_data.js_eval_result = if jsval.get().is_string() {
|
||||
|
@ -4093,6 +4095,7 @@ impl ScriptThread {
|
|||
ScriptFetchOptions::default_classic_script(global_scope),
|
||||
global_scope.api_base_url(),
|
||||
can_gc,
|
||||
None, // No known `introductionType` for JS code from embedder
|
||||
);
|
||||
let result = match jsval_to_webdriver(
|
||||
context,
|
||||
|
|
|
@ -35,7 +35,7 @@ use crate::dom::testbinding::TestBindingCallback;
|
|||
use crate::dom::types::{Window, WorkerGlobalScope};
|
||||
use crate::dom::xmlhttprequest::XHRTimeoutCallback;
|
||||
use crate::script_module::ScriptFetchOptions;
|
||||
use crate::script_runtime::CanGc;
|
||||
use crate::script_runtime::{CanGc, IntroductionType};
|
||||
use crate::script_thread::ScriptThread;
|
||||
use crate::task_source::SendableTaskSource;
|
||||
|
||||
|
@ -562,6 +562,7 @@ impl JsTimerTask {
|
|||
ScriptFetchOptions::default_classic_script(&global),
|
||||
global.api_base_url(),
|
||||
can_gc,
|
||||
Some(IntroductionType::DOM_TIMER),
|
||||
);
|
||||
},
|
||||
InternalTimerCallback::FunctionTimerCallback(ref function, ref arguments) => {
|
||||
|
|
|
@ -529,6 +529,7 @@ pub(crate) fn handle_execute_script(
|
|||
ScriptFetchOptions::default_classic_script(global),
|
||||
global.api_base_url(),
|
||||
can_gc,
|
||||
None, // No known `introductionType` for JS code from WebDriver
|
||||
) {
|
||||
jsval_to_webdriver(cx, global, rval.handle(), realm, can_gc)
|
||||
} else {
|
||||
|
@ -570,6 +571,7 @@ pub(crate) fn handle_execute_async_script(
|
|||
ScriptFetchOptions::default_classic_script(global_scope),
|
||||
global_scope.api_base_url(),
|
||||
can_gc,
|
||||
None, // No known `introductionType` for JS code from WebDriver
|
||||
) {
|
||||
reply_sender.send(Err(WebDriverJSError::JSError)).unwrap();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue