aboutsummaryrefslogtreecommitdiffstats
path: root/components/devtools
diff options
context:
space:
mode:
Diffstat (limited to 'components/devtools')
-rw-r--r--components/devtools/actors/watcher.rs69
-rw-r--r--components/devtools/actors/worker.rs29
-rw-r--r--components/devtools/lib.rs71
3 files changed, 131 insertions, 38 deletions
diff --git a/components/devtools/actors/watcher.rs b/components/devtools/actors/watcher.rs
index 6a84499b6dd..b0b2c755fd8 100644
--- a/components/devtools/actors/watcher.rs
+++ b/components/devtools/actors/watcher.rs
@@ -20,8 +20,10 @@ use serde_json::{Map, Value};
use self::network_parent::{NetworkParentActor, NetworkParentActorMsg};
use super::thread::ThreadActor;
+use super::worker::WorkerMsg;
use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
use crate::actors::browsing_context::{BrowsingContextActor, BrowsingContextActorMsg};
+use crate::actors::root::RootActor;
use crate::actors::watcher::target_configuration::{
TargetConfigurationActor, TargetConfigurationActorMsg,
};
@@ -29,8 +31,8 @@ use crate::actors::watcher::thread_configuration::{
ThreadConfigurationActor, ThreadConfigurationActorMsg,
};
use crate::protocol::JsonPacketStream;
-use crate::resource::ResourceAvailable;
-use crate::{EmptyReplyMsg, StreamId};
+use crate::resource::{ResourceAvailable, ResourceAvailableReply};
+use crate::{EmptyReplyMsg, StreamId, WorkerActor};
pub mod network_parent;
pub mod target_configuration;
@@ -55,7 +57,7 @@ impl SessionContext {
supported_targets: HashMap::from([
("frame", true),
("process", false),
- ("worker", false),
+ ("worker", true),
("service_worker", false),
("shared_worker", false),
]),
@@ -103,11 +105,18 @@ pub enum SessionContextType {
}
#[derive(Serialize)]
+#[serde(untagged)]
+enum TargetActorMsg {
+ BrowsingContext(BrowsingContextActorMsg),
+ Worker(WorkerMsg),
+}
+
+#[derive(Serialize)]
struct WatchTargetsReply {
from: String,
#[serde(rename = "type")]
type_: String,
- target: BrowsingContextActorMsg,
+ target: TargetActorMsg,
}
#[derive(Serialize)]
@@ -212,16 +221,38 @@ impl Actor for WatcherActor {
_id: StreamId,
) -> Result<ActorMessageStatus, ()> {
let target = registry.find::<BrowsingContextActor>(&self.browsing_context_actor);
+ let root = registry.find::<RootActor>("root");
Ok(match msg_type {
"watchTargets" => {
- let msg = WatchTargetsReply {
- from: self.name(),
- type_: "target-available-form".into(),
- target: target.encodable(),
- };
- let _ = stream.write_json_packet(&msg);
+ // As per logs we either get targetType as "frame" or "worker"
+ let target_type = msg
+ .get("targetType")
+ .and_then(Value::as_str)
+ .unwrap_or("frame"); // default to "frame"
+
+ if target_type == "frame" {
+ let msg = WatchTargetsReply {
+ from: self.name(),
+ type_: "target-available-form".into(),
+ target: TargetActorMsg::BrowsingContext(target.encodable()),
+ };
+ let _ = stream.write_json_packet(&msg);
- target.frame_update(stream);
+ target.frame_update(stream);
+ } else if target_type == "worker" {
+ for worker_name in &root.workers {
+ let worker = registry.find::<WorkerActor>(worker_name);
+ let worker_msg = WatchTargetsReply {
+ from: self.name(),
+ type_: "target-available-form".into(),
+ target: TargetActorMsg::Worker(worker.encodable()),
+ };
+ let _ = stream.write_json_packet(&worker_msg);
+ }
+ } else {
+ warn!("Unexpected target_type: {}", target_type);
+ return Ok(ActorMessageStatus::Ignored);
+ }
// Messages that contain a `type` field are used to send event callbacks, but they
// don't count as a reply. Since every message needs to be responded, we send an
@@ -267,6 +298,22 @@ impl Actor for WatcherActor {
let thread_actor = registry.find::<ThreadActor>(&target.thread);
let sources = thread_actor.source_manager.sources();
target.resources_available(sources.iter().collect(), "source".into());
+
+ for worker_name in &root.workers {
+ let worker = registry.find::<WorkerActor>(worker_name);
+ let thread = registry.find::<ThreadActor>(&worker.thread);
+ let worker_sources = thread.source_manager.sources();
+
+ let msg = ResourceAvailableReply {
+ from: worker.name(),
+ type_: "resources-available-array".into(),
+ array: vec![(
+ "source".to_string(),
+ worker_sources.iter().cloned().collect(),
+ )],
+ };
+ let _ = stream.write_json_packet(&msg);
+ }
},
"console-message" | "error-message" => {},
_ => warn!("resource {} not handled yet", resource),
diff --git a/components/devtools/actors/worker.rs b/components/devtools/actors/worker.rs
index 42c9d9a9c28..68ff56fb3b2 100644
--- a/components/devtools/actors/worker.rs
+++ b/components/devtools/actors/worker.rs
@@ -17,7 +17,7 @@ use servo_url::ServoUrl;
use crate::StreamId;
use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
use crate::protocol::JsonPacketStream;
-use crate::resource::ResourceAvailable;
+use crate::resource::{ResourceAvailable, ResourceAvailableReply};
#[derive(Clone, Copy)]
#[allow(dead_code)]
@@ -48,8 +48,10 @@ impl WorkerActor {
url: self.url.to_string(),
traits: WorkerTraits {
is_parent_intercept_enabled: false,
+ supports_top_level_target_flag: false,
},
type_: self.type_ as u32,
+ target_type: "worker".to_string(),
}
}
}
@@ -131,6 +133,28 @@ impl Actor for WorkerActor {
}
}
+impl WorkerActor {
+ pub(crate) fn resource_available<T: Serialize>(&self, resource: T, resource_type: String) {
+ self.resources_available(vec![resource], resource_type);
+ }
+
+ pub(crate) fn resources_available<T: Serialize>(
+ &self,
+ resources: Vec<T>,
+ resource_type: String,
+ ) {
+ let msg = ResourceAvailableReply::<T> {
+ from: self.name(),
+ type_: "resources-available-array".into(),
+ array: vec![(resource_type, resources)],
+ };
+
+ for stream in self.streams.borrow_mut().values_mut() {
+ let _ = stream.write_json_packet(&msg);
+ }
+ }
+}
+
#[derive(Serialize)]
struct DetachedReply {
from: String,
@@ -160,6 +184,7 @@ struct ConnectReply {
#[serde(rename_all = "camelCase")]
struct WorkerTraits {
is_parent_intercept_enabled: bool,
+ supports_top_level_target_flag: bool,
}
#[derive(Serialize)]
@@ -173,4 +198,6 @@ pub(crate) struct WorkerMsg {
traits: WorkerTraits,
#[serde(rename = "type")]
type_: u32,
+ #[serde(rename = "targetType")]
+ target_type: String,
}
diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs
index 4d1e0222177..5fb9485e9d3 100644
--- a/components/devtools/lib.rs
+++ b/components/devtools/lib.rs
@@ -510,35 +510,54 @@ impl DevtoolsInstance {
fn handle_script_source_info(&mut self, pipeline_id: PipelineId, source_info: SourceInfo) {
let mut actors = self.actors.lock().unwrap();
- let browsing_context_id = match self.pipelines.get(&pipeline_id) {
- Some(id) => id,
- None => return,
- };
+ if let Some(worker_id) = source_info.worker_id {
+ let Some(worker_actor_name) = self.actor_workers.get(&worker_id) else {
+ return;
+ };
- let actor_name = match self.browsing_contexts.get(browsing_context_id) {
- Some(name) => name,
- None => return,
- };
+ let thread_actor_name = actors.find::<WorkerActor>(worker_actor_name).thread.clone();
- let thread_actor_name = actors
- .find::<BrowsingContextActor>(actor_name)
- .thread
- .clone();
-
- let thread_actor = actors.find_mut::<ThreadActor>(&thread_actor_name);
- thread_actor
- .source_manager
- .add_source(source_info.url.clone());
-
- let source = SourceData {
- actor: thread_actor_name.clone(),
- url: source_info.url.to_string(),
- is_black_boxed: false,
- };
+ let thread_actor = actors.find_mut::<ThreadActor>(&thread_actor_name);
+ thread_actor
+ .source_manager
+ .add_source(source_info.url.clone());
+
+ let source = SourceData {
+ actor: thread_actor_name.clone(),
+ url: source_info.url.to_string(),
+ is_black_boxed: false,
+ };
- // Notify browsing context about the new source
- let browsing_context = actors.find::<BrowsingContextActor>(actor_name);
- browsing_context.resource_available(source, "source".into());
+ let worker_actor = actors.find::<WorkerActor>(worker_actor_name);
+ worker_actor.resource_available(source, "source".into());
+ } else {
+ let Some(browsing_context_id) = self.pipelines.get(&pipeline_id) else {
+ return;
+ };
+ let Some(actor_name) = self.browsing_contexts.get(browsing_context_id) else {
+ return;
+ };
+
+ let thread_actor_name = actors
+ .find::<BrowsingContextActor>(actor_name)
+ .thread
+ .clone();
+
+ let thread_actor = actors.find_mut::<ThreadActor>(&thread_actor_name);
+ thread_actor
+ .source_manager
+ .add_source(source_info.url.clone());
+
+ let source = SourceData {
+ actor: thread_actor_name.clone(),
+ url: source_info.url.to_string(),
+ is_black_boxed: false,
+ };
+
+ // Notify browsing context about the new source
+ let browsing_context = actors.find::<BrowsingContextActor>(actor_name);
+ browsing_context.resource_available(source, "source".into());
+ }
}
}