mirror of
https://github.com/servo/servo.git
synced 2025-07-31 19:20:22 +01:00
This patch adds support for listing scripts in the Sources panel. Classic scripts, both external and inline, are implemented, but worker scripts and imported module scripts are not yet implemented. For example: ```html <!-- sources.html --> <!doctype html><meta charset=utf-8> <script src="classic.js"></script> <script> console.log("inline classic"); new Worker("worker.js"); </script> <script type="module"> import module from "./module.js"; console.log("inline module"); </script> <script src="https://servo.org/js/load-table.js"></script> ``` ```js // classic.js console.log("external classic"); ``` ```js // worker.js console.log("external classic worker"); ``` ```js // module.js export default 1; console.log("external module"); ```  --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes partially implement #36027 <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes require tests, but they are blocked on #36325 Signed-off-by: Delan Azabani <dazabani@igalia.com> Co-authored-by: atbrakhi <atbrakhi@igalia.com>
167 lines
4.6 KiB
Rust
167 lines
4.6 KiB
Rust
/* 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::cell::{Ref, RefCell};
|
|
use std::collections::BTreeSet;
|
|
use std::net::TcpStream;
|
|
|
|
use serde::Serialize;
|
|
use serde_json::{Map, Value};
|
|
use servo_url::ServoUrl;
|
|
|
|
use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
|
|
use crate::protocol::JsonPacketStream;
|
|
use crate::{EmptyReplyMsg, StreamId};
|
|
|
|
#[derive(Serialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
struct ThreadAttached {
|
|
from: String,
|
|
#[serde(rename = "type")]
|
|
type_: String,
|
|
actor: String,
|
|
frame: u32,
|
|
error: u32,
|
|
recording_endpoint: u32,
|
|
execution_point: u32,
|
|
popped_frames: Vec<PoppedFrameMsg>,
|
|
why: WhyMsg,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
enum PoppedFrameMsg {}
|
|
|
|
#[derive(Serialize)]
|
|
struct WhyMsg {
|
|
#[serde(rename = "type")]
|
|
type_: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
struct ThreadResumedReply {
|
|
from: String,
|
|
#[serde(rename = "type")]
|
|
type_: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
struct ThreadInterruptedReply {
|
|
from: String,
|
|
#[serde(rename = "type")]
|
|
type_: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
struct SourcesReply {
|
|
from: String,
|
|
sources: Vec<Source>,
|
|
}
|
|
|
|
#[derive(Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct Source {
|
|
pub actor: String,
|
|
/// URL of the script, or URL of the page for inline scripts.
|
|
pub url: String,
|
|
pub is_black_boxed: bool,
|
|
}
|
|
|
|
pub struct ThreadActor {
|
|
name: String,
|
|
source_urls: RefCell<BTreeSet<Source>>,
|
|
}
|
|
|
|
impl ThreadActor {
|
|
pub fn new(name: String) -> ThreadActor {
|
|
ThreadActor {
|
|
name,
|
|
source_urls: RefCell::new(BTreeSet::default()),
|
|
}
|
|
}
|
|
|
|
pub fn add_source(&self, url: ServoUrl) {
|
|
self.source_urls.borrow_mut().insert(Source {
|
|
actor: self.name.clone(),
|
|
url: url.to_string(),
|
|
is_black_boxed: false,
|
|
});
|
|
}
|
|
|
|
pub fn sources(&self) -> Ref<BTreeSet<Source>> {
|
|
self.source_urls.borrow()
|
|
}
|
|
}
|
|
|
|
impl Actor for ThreadActor {
|
|
fn name(&self) -> String {
|
|
self.name.clone()
|
|
}
|
|
|
|
fn handle_message(
|
|
&self,
|
|
registry: &ActorRegistry,
|
|
msg_type: &str,
|
|
_msg: &Map<String, Value>,
|
|
stream: &mut TcpStream,
|
|
_id: StreamId,
|
|
) -> Result<ActorMessageStatus, ()> {
|
|
Ok(match msg_type {
|
|
"attach" => {
|
|
let msg = ThreadAttached {
|
|
from: self.name(),
|
|
type_: "paused".to_owned(),
|
|
actor: registry.new_name("pause"),
|
|
frame: 0,
|
|
error: 0,
|
|
recording_endpoint: 0,
|
|
execution_point: 0,
|
|
popped_frames: vec![],
|
|
why: WhyMsg {
|
|
type_: "attached".to_owned(),
|
|
},
|
|
};
|
|
let _ = stream.write_json_packet(&msg);
|
|
let _ = stream.write_json_packet(&EmptyReplyMsg { from: self.name() });
|
|
ActorMessageStatus::Processed
|
|
},
|
|
|
|
"resume" => {
|
|
let msg = ThreadResumedReply {
|
|
from: self.name(),
|
|
type_: "resumed".to_owned(),
|
|
};
|
|
let _ = stream.write_json_packet(&msg);
|
|
let _ = stream.write_json_packet(&EmptyReplyMsg { from: self.name() });
|
|
ActorMessageStatus::Processed
|
|
},
|
|
|
|
"interrupt" => {
|
|
let msg = ThreadInterruptedReply {
|
|
from: self.name(),
|
|
type_: "interrupted".to_owned(),
|
|
};
|
|
let _ = stream.write_json_packet(&msg);
|
|
ActorMessageStatus::Processed
|
|
},
|
|
|
|
"reconfigure" => {
|
|
let _ = stream.write_json_packet(&EmptyReplyMsg { from: self.name() });
|
|
ActorMessageStatus::Processed
|
|
},
|
|
|
|
// Client has attached to the thread and wants to load script sources.
|
|
// <https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html#loading-script-sources>
|
|
"sources" => {
|
|
let msg = SourcesReply {
|
|
from: self.name(),
|
|
sources: vec![], // TODO: Add sources for the debugger here
|
|
};
|
|
let _ = stream.write_json_packet(&msg);
|
|
ActorMessageStatus::Processed
|
|
},
|
|
|
|
_ => ActorMessageStatus::Ignored,
|
|
})
|
|
}
|
|
}
|