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