viewpoint_core/page/frame/
core.rs1use std::collections::HashMap;
4use std::sync::Arc;
5
6use parking_lot::RwLock;
7use viewpoint_cdp::CdpConnection;
8use viewpoint_cdp::protocol::runtime::ExecutionContextId;
9
10use super::execution_context::{ExecutionContextRegistry, MAIN_WORLD_KEY};
11
12#[derive(Debug, Clone)]
14pub(super) struct FrameData {
15 pub url: String,
17 pub name: String,
19 pub detached: bool,
21 pub execution_contexts: HashMap<String, ExecutionContextId>,
24}
25
26#[derive(Debug)]
31pub struct Frame {
32 pub(super) connection: Arc<CdpConnection>,
34 pub(super) session_id: String,
36 pub(super) id: String,
38 pub(super) parent_id: Option<String>,
40 pub(super) loader_id: String,
42 pub(super) data: RwLock<FrameData>,
44 pub(super) context_registry: Option<Arc<ExecutionContextRegistry>>,
46 pub(super) context_index: usize,
48 pub(super) page_index: usize,
50 pub(super) frame_index: usize,
52}
53
54impl Frame {
55 pub(crate) fn new(
57 connection: Arc<CdpConnection>,
58 session_id: String,
59 id: String,
60 parent_id: Option<String>,
61 loader_id: String,
62 url: String,
63 name: String,
64 ) -> Self {
65 Self {
66 connection,
67 session_id,
68 id,
69 parent_id,
70 loader_id,
71 data: RwLock::new(FrameData {
72 url,
73 name,
74 detached: false,
75 execution_contexts: HashMap::new(),
76 }),
77 context_registry: None,
78 context_index: 0,
79 page_index: 0,
80 frame_index: 0,
81 }
82 }
83
84 pub(crate) fn new_with_indices(
86 connection: Arc<CdpConnection>,
87 session_id: String,
88 id: String,
89 parent_id: Option<String>,
90 loader_id: String,
91 url: String,
92 name: String,
93 context_index: usize,
94 page_index: usize,
95 frame_index: usize,
96 ) -> Self {
97 Self {
98 connection,
99 session_id,
100 id,
101 parent_id,
102 loader_id,
103 data: RwLock::new(FrameData {
104 url,
105 name,
106 detached: false,
107 execution_contexts: HashMap::new(),
108 }),
109 context_registry: None,
110 context_index,
111 page_index,
112 frame_index,
113 }
114 }
115
116 pub(crate) fn with_context_registry(
118 connection: Arc<CdpConnection>,
119 session_id: String,
120 id: String,
121 parent_id: Option<String>,
122 loader_id: String,
123 url: String,
124 name: String,
125 context_registry: Arc<ExecutionContextRegistry>,
126 ) -> Self {
127 Self {
128 connection,
129 session_id,
130 id,
131 parent_id,
132 loader_id,
133 data: RwLock::new(FrameData {
134 url,
135 name,
136 detached: false,
137 execution_contexts: HashMap::new(),
138 }),
139 context_registry: Some(context_registry),
140 context_index: 0,
141 page_index: 0,
142 frame_index: 0,
143 }
144 }
145
146 pub(crate) fn with_context_registry_and_indices(
148 connection: Arc<CdpConnection>,
149 session_id: String,
150 id: String,
151 parent_id: Option<String>,
152 loader_id: String,
153 url: String,
154 name: String,
155 context_registry: Arc<ExecutionContextRegistry>,
156 context_index: usize,
157 page_index: usize,
158 frame_index: usize,
159 ) -> Self {
160 Self {
161 connection,
162 session_id,
163 id,
164 parent_id,
165 loader_id,
166 data: RwLock::new(FrameData {
167 url,
168 name,
169 detached: false,
170 execution_contexts: HashMap::new(),
171 }),
172 context_registry: Some(context_registry),
173 context_index,
174 page_index,
175 frame_index,
176 }
177 }
178
179 pub fn frame_index(&self) -> usize {
181 self.frame_index
182 }
183
184 pub fn id(&self) -> &str {
186 &self.id
187 }
188
189 pub fn parent_id(&self) -> Option<&str> {
193 self.parent_id.as_deref()
194 }
195
196 pub fn is_main(&self) -> bool {
198 self.parent_id.is_none()
199 }
200
201 pub fn loader_id(&self) -> &str {
203 &self.loader_id
204 }
205
206 pub fn url(&self) -> String {
208 self.data.read().url.clone()
209 }
210
211 pub fn name(&self) -> String {
213 self.data.read().name.clone()
214 }
215
216 pub fn is_detached(&self) -> bool {
218 self.data.read().detached
219 }
220
221 pub(crate) fn set_url(&self, url: String) {
223 self.data.write().url = url;
224 }
225
226 pub(crate) fn set_name(&self, name: String) {
228 self.data.write().name = name;
229 }
230
231 pub(crate) fn set_detached(&self) {
233 self.data.write().detached = true;
234 }
235
236 pub(crate) fn main_world_context_id(&self) -> Option<ExecutionContextId> {
241 if let Some(ref registry) = self.context_registry {
243 if let Some(context_id) = registry.main_world_context(&self.id) {
244 return Some(context_id);
245 }
246 }
247 self.data
249 .read()
250 .execution_contexts
251 .get(MAIN_WORLD_KEY)
252 .copied()
253 }
254
255 pub(crate) fn set_execution_context(&self, world_name: String, id: ExecutionContextId) {
261 self.data.write().execution_contexts.insert(world_name, id);
262 }
263
264 pub(crate) fn remove_execution_context(&self, id: ExecutionContextId) -> bool {
269 let mut data = self.data.write();
270 let original_len = data.execution_contexts.len();
271 data.execution_contexts
272 .retain(|_, &mut ctx_id| ctx_id != id);
273 data.execution_contexts.len() < original_len
274 }
275
276 pub(crate) fn clear_execution_contexts(&self) {
280 self.data.write().execution_contexts.clear();
281 }
282
283 pub(crate) fn session_id(&self) -> &str {
285 &self.session_id
286 }
287
288 pub(crate) fn connection(&self) -> &Arc<CdpConnection> {
290 &self.connection
291 }
292}