use std::sync::Arc;
use tracing::{trace, warn};
use zendriver_transport::{SessionHandle, TargetInfo};
use crate::browser::BrowserInner;
use crate::frame::Frame;
pub(crate) async fn register_oopif_frame(
browser: &Arc<BrowserInner>,
target_info: &TargetInfo,
session: SessionHandle,
) -> Option<()> {
let mut candidates: Vec<&str> = Vec::with_capacity(2);
if let Some(opener) = target_info.opener_frame_id.as_deref() {
candidates.push(opener);
}
candidates.push(&target_info.target_id);
let tabs = browser.tabs.read().await;
for tab in tabs.values() {
let frames = tab.inner.frames.read().await;
for cand in &candidates {
if frames.contains_key(*cand) {
drop(frames);
let frame_id = target_info.target_id.clone();
let parent_frame_id = (*cand).to_string();
let oopif = Frame::new(
frame_id.clone(),
Some(parent_frame_id),
String::new(),
None,
session,
Arc::downgrade(&tab.inner),
);
tab.inner.frames.write().await.insert(frame_id, oopif);
trace!(
target_id = %target_info.target_id,
"OOPIF frame registered under parent tab",
);
return Some(());
}
}
}
warn!(
target_id = %target_info.target_id,
opener_frame_id = ?target_info.opener_frame_id,
"OOPIF attached with no matching parent frame; skipping registration",
);
None
}
pub(crate) async fn deregister_oopif_frame(browser: &Arc<BrowserInner>, session_id: &str) -> bool {
let tabs = browser.tabs.read().await;
for tab in tabs.values() {
let to_remove: Vec<String> = {
let frames = tab.inner.frames.read().await;
frames
.iter()
.filter(|(_, frame)| frame.session().session_id() == session_id)
.map(|(frame_id, _)| frame_id.clone())
.collect()
};
if !to_remove.is_empty() {
let mut frames = tab.inner.frames.write().await;
for frame_id in &to_remove {
frames.remove(frame_id);
}
return true;
}
}
false
}