devtools/actors/inspector/
highlighter.rs1use devtools_traits::DevtoolScriptControlMsg;
9use malloc_size_of_derive::MallocSizeOf;
10use serde::Serialize;
11use serde_json::{self, Map, Value};
12
13use crate::actor::{Actor, ActorEncode, ActorError, ActorRegistry};
14use crate::actors::browsing_context::BrowsingContextActor;
15use crate::actors::inspector::InspectorActor;
16use crate::protocol::ClientRequest;
17use crate::{ActorMsg, EmptyReplyMsg, StreamId};
18
19#[derive(MallocSizeOf)]
20pub(crate) struct HighlighterActor {
21 pub name: String,
22 pub browsing_context_name: String,
23}
24
25#[derive(Serialize)]
26struct ShowReply {
27 from: String,
28 value: bool,
29}
30
31impl Actor for HighlighterActor {
32 fn name(&self) -> String {
33 self.name.clone()
34 }
35
36 fn handle_message(
44 &self,
45 request: ClientRequest,
46 registry: &ActorRegistry,
47 msg_type: &str,
48 msg: &Map<String, Value>,
49 _id: StreamId,
50 ) -> Result<(), ActorError> {
51 match msg_type {
52 "show" => {
53 let Some(node_actor) = msg.get("node") else {
54 return Err(ActorError::MissingParameter);
55 };
56
57 let Some(node_actor_name) = node_actor.as_str() else {
58 return Err(ActorError::BadParameterType);
59 };
60
61 if node_actor_name.starts_with(ActorRegistry::base_name::<InspectorActor>()) {
62 let msg = ShowReply {
65 from: self.name(),
66 value: false,
67 };
68 return request.reply_final(&msg);
69 }
70
71 self.instruct_script_thread_to_highlight_node(
72 Some(node_actor_name.to_owned()),
73 registry,
74 );
75 let msg = ShowReply {
76 from: self.name(),
77 value: true,
78 };
79 request.reply_final(&msg)?
80 },
81
82 "hide" => {
83 self.instruct_script_thread_to_highlight_node(None, registry);
84
85 let msg = EmptyReplyMsg { from: self.name() };
86 request.reply_final(&msg)?
87 },
88
89 "finalize" => {
90 request.mark_handled();
91 },
92
93 _ => return Err(ActorError::UnrecognizedPacketType),
94 };
95 Ok(())
96 }
97}
98
99impl HighlighterActor {
100 fn instruct_script_thread_to_highlight_node(
101 &self,
102 node_name: Option<String>,
103 registry: &ActorRegistry,
104 ) {
105 let node_id = node_name.map(|node_name| registry.actor_to_script(node_name));
106 let browsing_context_actor =
107 registry.find::<BrowsingContextActor>(&self.browsing_context_name);
108 browsing_context_actor
109 .script_chan()
110 .send(DevtoolScriptControlMsg::HighlightDomNode(
111 browsing_context_actor.pipeline_id(),
112 node_id,
113 ))
114 .unwrap();
115 }
116}
117
118impl ActorEncode<ActorMsg> for HighlighterActor {
119 fn encode(&self, _: &ActorRegistry) -> ActorMsg {
120 ActorMsg { actor: self.name() }
121 }
122}