mirror of
https://github.com/lexmount/moli.git
synced 2026-09-28 08:01:37 +00:00
refactor(cdp): remove ambiguous owner routing adapters
This commit is contained in:
@@ -83,8 +83,9 @@ pub use moli_renderer_v8::network::{
|
||||
};
|
||||
pub use moli_renderer_v8::{
|
||||
CompletedWorkerRuntimeInspectorCommandDispatch, DevToolsSessionKey,
|
||||
RendererActivityDiagnostics, RendererAgentAttachmentId, RendererAutofillAddressField,
|
||||
RendererAutofillCreditCard, RendererAutofillTriggerOutcome, RendererAutofillTriggerRequest,
|
||||
PendingWorkerRuntimeInspectorSessionResponse, RendererActivityDiagnostics,
|
||||
RendererAgentAttachmentId, RendererAutofillAddressField, RendererAutofillCreditCard,
|
||||
RendererAutofillTriggerOutcome, RendererAutofillTriggerRequest,
|
||||
RendererCaptureScreencastFrameReply, RendererCaptureScreencastFrameRequest,
|
||||
RendererCaptureScreenshotReply, RendererCaptureScreenshotRequest,
|
||||
RendererCommandTurnCompletion, RendererCommandTurnOutput, RendererDedicatedWorkerTargetEvent,
|
||||
|
||||
+154
-218
@@ -816,8 +816,7 @@ impl DeferredMainDocumentLoadPredecessorCandidate {
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub(crate) struct RuntimeAwaitJob {
|
||||
command_id: u64,
|
||||
session_id: Option<String>,
|
||||
owner_route: Option<CdpSessionRoute>,
|
||||
owner: CommandOwnerScope,
|
||||
object_group: Option<String>,
|
||||
action: &'static str,
|
||||
}
|
||||
@@ -825,15 +824,13 @@ pub(crate) struct RuntimeAwaitJob {
|
||||
impl RuntimeAwaitJob {
|
||||
pub(crate) fn new(
|
||||
command_id: u64,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
object_group: Option<&str>,
|
||||
action: &'static str,
|
||||
) -> Self {
|
||||
Self {
|
||||
command_id,
|
||||
session_id: session_id.map(str::to_owned),
|
||||
owner_route,
|
||||
owner: owner.clone(),
|
||||
object_group: object_group.map(str::to_owned),
|
||||
action,
|
||||
}
|
||||
@@ -842,15 +839,15 @@ impl RuntimeAwaitJob {
|
||||
pub(crate) fn trace_fields(&self) -> serde_json::Value {
|
||||
json!({
|
||||
"commandId": self.command_id,
|
||||
"sessionId": self.session_id,
|
||||
"ownerRoute": self.owner_route.as_ref().map(|route| format!("{route:?}")),
|
||||
"sessionId": self.owner.session_id(),
|
||||
"ownerRoute": self.owner.explicit_route().map(|route| format!("{route:?}")),
|
||||
"objectGroup": self.object_group,
|
||||
"action": self.action,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn session_id(&self) -> Option<String> {
|
||||
self.session_id.clone()
|
||||
self.owner.session_id().map(str::to_owned)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1643,7 +1640,12 @@ impl CdpConnection {
|
||||
}
|
||||
|
||||
fn target_id_for_session_owner(&self, session_id: Option<&str>) -> Option<String> {
|
||||
let (browser_context_id, target_id) = self.target_owner_identity_for_session(session_id)?;
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.target_id_for_owner(&owner)
|
||||
}
|
||||
|
||||
fn target_id_for_owner(&self, owner: &CommandOwnerScope) -> Option<String> {
|
||||
let (browser_context_id, target_id) = self.target_owner_identity_for_owner(owner)?;
|
||||
target_id.or_else(|| {
|
||||
self.browser_context_by_id(&browser_context_id)
|
||||
.and_then(BrowserContext::active_target_id)
|
||||
@@ -1651,11 +1653,11 @@ impl CdpConnection {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn session_owner_target_has_waiting_for_debugger_session(
|
||||
pub(crate) fn owner_target_has_waiting_for_debugger_session(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
self.target_id_for_session_owner(session_id)
|
||||
self.target_id_for_owner(owner)
|
||||
.is_some_and(|target_id| self.target_has_waiting_for_debugger_session(&target_id))
|
||||
}
|
||||
|
||||
@@ -1694,16 +1696,15 @@ impl CdpConnection {
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
) -> bool {
|
||||
self.has_pending_document_navigation_for_route(session_id, None)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.has_pending_document_navigation_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn has_pending_document_navigation_for_route(
|
||||
pub(crate) fn has_pending_document_navigation_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
self.target_owner_identity_for_route(session_id, owner_route)
|
||||
let Some((browser_context_id, target_id)) = self.target_owner_identity_for_owner(owner)
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
@@ -1713,13 +1714,11 @@ impl CdpConnection {
|
||||
})
|
||||
}
|
||||
|
||||
fn document_navigation_state_for_route(
|
||||
fn document_navigation_state_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> DevToolsDocumentNavigationState {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
self.target_owner_identity_for_route(session_id, owner_route)
|
||||
let Some((browser_context_id, target_id)) = self.target_owner_identity_for_owner(owner)
|
||||
else {
|
||||
return DevToolsDocumentNavigationState::Unavailable;
|
||||
};
|
||||
@@ -1738,7 +1737,7 @@ impl CdpConnection {
|
||||
// Otherwise a materialized `about:blank` is misclassified as
|
||||
// `AwaitingCommit`, and ChromeDriver-style pre-command navigation
|
||||
// waits can never complete.
|
||||
match self.target_session_owner_frame_tree_loader_id_for_route(session_id, owner_route) {
|
||||
match self.target_session_owner_frame_tree_loader_id_for_owner(owner) {
|
||||
Some(loader_id) => DevToolsDocumentNavigationState::Committed { loader_id },
|
||||
None => DevToolsDocumentNavigationState::AwaitingCommit,
|
||||
}
|
||||
@@ -1755,10 +1754,7 @@ impl CdpConnection {
|
||||
let Some(owner_scope) = self.command_owner_scope_for_devtools_context(context) else {
|
||||
return DevToolsDocumentNavigationState::Unavailable;
|
||||
};
|
||||
self.document_navigation_state_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
self.document_navigation_state_for_owner(&owner_scope)
|
||||
}
|
||||
|
||||
pub fn renderer_document_navigation_is_suspended_for_session_owner(
|
||||
@@ -1769,14 +1765,12 @@ impl CdpConnection {
|
||||
.is_ok_and(TargetRuntimeSlot::renderer_document_navigation_is_suspended)
|
||||
}
|
||||
|
||||
pub(crate) fn accepts_pending_document_navigation_for_route(
|
||||
pub(crate) fn accepts_pending_document_navigation_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
token: &DocumentNavigationToken,
|
||||
) -> bool {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
self.target_owner_identity_for_route(session_id, owner_route)
|
||||
let Some((browser_context_id, target_id)) = self.target_owner_identity_for_owner(owner)
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
@@ -1793,15 +1787,15 @@ impl CdpConnection {
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
) -> Result<(), String> {
|
||||
self.ensure_document_accessible_for_route(session_id, None)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.ensure_document_accessible_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn ensure_document_accessible_for_route(
|
||||
pub(crate) fn ensure_document_accessible_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<(), String> {
|
||||
if self.has_pending_document_navigation_for_route(session_id, owner_route) {
|
||||
if self.has_pending_document_navigation_for_owner(owner) {
|
||||
return Err("Navigation is changing the document".to_owned());
|
||||
}
|
||||
Ok(())
|
||||
@@ -1811,15 +1805,15 @@ impl CdpConnection {
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
) -> Option<String> {
|
||||
self.current_document_loader_id_for_route(session_id, None)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.current_document_loader_id_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn current_document_loader_id_for_route(
|
||||
pub(crate) fn current_document_loader_id_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<String> {
|
||||
self.runtime_session_owner_slot_for_route(session_id, owner_route)
|
||||
self.runtime_session_owner_slot_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.current_document_loader_id().map(str::to_owned))
|
||||
}
|
||||
@@ -1831,35 +1825,33 @@ impl CdpConnection {
|
||||
source_document: moli_core::RendererDocumentLifecycleIdentity,
|
||||
item: &moli_core::page::ScriptNetworkOutputItem,
|
||||
) -> Option<crate::domains::network::TargetNetworkBacklogPreparedDelivery> {
|
||||
self.ingest_renderer_page_network_output_item_and_prepare_live_delivery_for_route(
|
||||
session_id,
|
||||
None,
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.ingest_renderer_page_network_output_item_and_prepare_live_delivery_for_owner(
|
||||
&owner,
|
||||
None,
|
||||
source_document,
|
||||
item,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn ingest_renderer_page_network_output_item_and_prepare_live_delivery_for_route(
|
||||
pub(crate) fn ingest_renderer_page_network_output_item_and_prepare_live_delivery_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
source_renderer_page: Option<RendererPageResidenceIdentity>,
|
||||
source_document: moli_core::RendererDocumentLifecycleIdentity,
|
||||
item: &moli_core::page::ScriptNetworkOutputItem,
|
||||
) -> Option<crate::domains::network::TargetNetworkBacklogPreparedDelivery> {
|
||||
let primary_session_id =
|
||||
self.runtime_session_owner_primary_session_id_for_route(session_id, owner_route);
|
||||
let primary_session_id = self.runtime_session_owner_primary_session_id_for_owner(owner);
|
||||
let mut request_id_allocator = std::mem::take(&mut self.network_request_id_allocator);
|
||||
let delivery = self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| {
|
||||
slot.ingest_renderer_network_output_item_and_prepare_live_delivery(
|
||||
source_renderer_page,
|
||||
source_document,
|
||||
item,
|
||||
session_id,
|
||||
owner.session_id(),
|
||||
primary_session_id.as_deref(),
|
||||
None,
|
||||
&mut request_id_allocator,
|
||||
@@ -1873,16 +1865,16 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
) -> Result<&mut Page, String> {
|
||||
self.loaded_page_mut_for_protocol_access_for_route(session_id, None)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.loaded_page_mut_for_protocol_access_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn loaded_page_mut_for_protocol_access_for_route(
|
||||
pub(crate) fn loaded_page_mut_for_protocol_access_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<&mut Page, String> {
|
||||
self.ensure_document_accessible_for_route(session_id, owner_route)?;
|
||||
self.loaded_page_mut_for_interruptible_protocol_access_for_route(session_id, owner_route)
|
||||
self.ensure_document_accessible_for_owner(owner)?;
|
||||
self.loaded_page_mut_for_interruptible_protocol_access_for_owner(owner)
|
||||
}
|
||||
|
||||
/// Returns the Page that currently carries target-scoped configuration.
|
||||
@@ -1899,15 +1891,15 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
) -> Result<&mut Page, String> {
|
||||
self.loaded_page_mut_for_target_configuration_for_route(session_id, None)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.loaded_page_mut_for_target_configuration_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn loaded_page_mut_for_target_configuration_for_route(
|
||||
pub(crate) fn loaded_page_mut_for_target_configuration_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<&mut Page, String> {
|
||||
self.runtime_session_owner_slot_mut_for_route(session_id, owner_route)?
|
||||
self.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.loaded_page_mut()
|
||||
.ok_or_else(|| "NoDocumentLoaded".to_owned())
|
||||
}
|
||||
@@ -1923,27 +1915,25 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
) -> Result<&mut Page, String> {
|
||||
self.loaded_page_mut_for_interruptible_protocol_access_for_route(session_id, None)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.loaded_page_mut_for_interruptible_protocol_access_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn loaded_page_mut_for_interruptible_protocol_access_for_route(
|
||||
pub(crate) fn loaded_page_mut_for_interruptible_protocol_access_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<&mut Page, String> {
|
||||
self.runtime_session_owner_slot_mut_for_route(session_id, owner_route)?
|
||||
self.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.loaded_page_mut()
|
||||
.ok_or_else(|| "NoDocumentLoaded".to_owned())
|
||||
}
|
||||
|
||||
pub(crate) fn start_document_navigation_for_route(
|
||||
pub(crate) fn start_document_navigation_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
loader_id: String,
|
||||
) -> Option<DocumentNavigationToken> {
|
||||
let (browser_context_id, target_id) =
|
||||
self.target_owner_identity_for_route(session_id, owner_route)?;
|
||||
let (browser_context_id, target_id) = self.target_owner_identity_for_owner(owner)?;
|
||||
let target_id = target_id?;
|
||||
self.browser_context_by_id_mut(&browser_context_id)?
|
||||
.start_document_navigation_for_target(&target_id, loader_id)
|
||||
@@ -1954,8 +1944,7 @@ impl CdpConnection {
|
||||
owner: &CommandOwnerScope,
|
||||
token: &DocumentNavigationToken,
|
||||
) {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
self.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
let Some((browser_context_id, target_id)) = self.target_owner_identity_for_owner(owner)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
@@ -1979,10 +1968,7 @@ impl CdpConnection {
|
||||
Vec<moli_core::page::RendererDocumentLifecycleEvent>,
|
||||
) {
|
||||
let (binding, events, document_scope_changed) = {
|
||||
let Ok(slot) = self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) else {
|
||||
let Ok(slot) = self.runtime_session_owner_slot_mut_for_owner(owner) else {
|
||||
return (None, Vec::new());
|
||||
};
|
||||
let previous_document_scope = slot
|
||||
@@ -2020,10 +2006,7 @@ impl CdpConnection {
|
||||
Vec<moli_core::page::RendererDocumentLifecycleEvent>,
|
||||
) {
|
||||
let (binding, events, document_scope_changed, document_input_stream_opened) = {
|
||||
let Ok(slot) = self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) else {
|
||||
let Ok(slot) = self.runtime_session_owner_slot_mut_for_owner(owner) else {
|
||||
return (None, Vec::new());
|
||||
};
|
||||
let previous_document_scope = slot
|
||||
@@ -2059,34 +2042,26 @@ impl CdpConnection {
|
||||
// not defer this state transition to a later diagnostics snapshot:
|
||||
// that would make a later owner turn rediscover and settle output
|
||||
// produced by this renderer turn.
|
||||
self.with_target_owner_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner_state| owner_state.mark_initial_empty_document_exited(),
|
||||
);
|
||||
self.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
owner_state.mark_initial_empty_document_exited()
|
||||
});
|
||||
}
|
||||
(binding, events)
|
||||
}
|
||||
|
||||
fn retire_javascript_dialogs_for_owner(&mut self, owner: &CommandOwnerScope) {
|
||||
let event_session_ids =
|
||||
self.page_event_session_ids_for_route(owner.session_id(), owner.session_owner_route());
|
||||
if let Ok(slot) = self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
let event_session_ids = self.page_event_session_ids_for_owner(owner);
|
||||
if let Ok(slot) = self.runtime_session_owner_slot_mut_for_owner(owner) {
|
||||
slot.retire_javascript_dialog_scope();
|
||||
}
|
||||
for event_session_id in event_session_ids {
|
||||
let event_owner_route = event_session_id
|
||||
.is_none()
|
||||
.then_some(owner.session_owner_route())
|
||||
.flatten();
|
||||
let _ = self.with_target_devtools_session_state_for_route_mut(
|
||||
event_session_id.as_deref(),
|
||||
event_owner_route,
|
||||
|state| state.page_session_state.javascript_dialog_state.clear(),
|
||||
);
|
||||
let event_owner = event_session_id
|
||||
.as_deref()
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
let _ = self.with_target_devtools_session_state_for_owner_mut(&event_owner, |state| {
|
||||
state.page_session_state.javascript_dialog_state.clear()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2095,14 +2070,11 @@ impl CdpConnection {
|
||||
owner: &CommandOwnerScope,
|
||||
loader_id: &str,
|
||||
) -> bool {
|
||||
self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.is_ok_and(|slot| {
|
||||
slot.page_slot_mut()
|
||||
.begin_renderer_document_load_visibility_barrier(loader_id)
|
||||
})
|
||||
self.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.is_ok_and(|slot| {
|
||||
slot.page_slot_mut()
|
||||
.begin_renderer_document_load_visibility_barrier(loader_id)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn release_renderer_document_load_visibility_barrier_for_owner(
|
||||
@@ -2110,13 +2082,10 @@ impl CdpConnection {
|
||||
owner: &CommandOwnerScope,
|
||||
loader_id: &str,
|
||||
) -> Option<Vec<moli_core::page::RendererDocumentLifecycleEvent>> {
|
||||
self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.ok()?
|
||||
.page_slot_mut()
|
||||
.release_renderer_document_load_visibility_barrier(loader_id)
|
||||
self.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()?
|
||||
.page_slot_mut()
|
||||
.release_renderer_document_load_visibility_barrier(loader_id)
|
||||
}
|
||||
|
||||
pub(crate) fn cancel_renderer_document_load_visibility_barrier_for_owner(
|
||||
@@ -2124,14 +2093,11 @@ impl CdpConnection {
|
||||
owner: &CommandOwnerScope,
|
||||
loader_id: &str,
|
||||
) -> bool {
|
||||
self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.is_ok_and(|slot| {
|
||||
slot.page_slot_mut()
|
||||
.cancel_renderer_document_load_visibility_barrier(loader_id)
|
||||
})
|
||||
self.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.is_ok_and(|slot| {
|
||||
slot.page_slot_mut()
|
||||
.cancel_renderer_document_load_visibility_barrier(loader_id)
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -2163,10 +2129,7 @@ impl CdpConnection {
|
||||
RendererDocumentLifecycleObservation::Unavailable,
|
||||
);
|
||||
};
|
||||
let Ok(slot) = self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) else {
|
||||
let Ok(slot) = self.runtime_session_owner_slot_mut_for_owner(owner) else {
|
||||
return RendererDocumentLifecycleObserver::resolved(
|
||||
RendererDocumentLifecycleObservation::Unavailable,
|
||||
);
|
||||
@@ -2197,14 +2160,11 @@ impl CdpConnection {
|
||||
owner: &CommandOwnerScope,
|
||||
loader_id: &str,
|
||||
) -> bool {
|
||||
self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.is_ok_and(|slot| {
|
||||
slot.page_slot_mut()
|
||||
.arm_root_post_load_observation(loader_id)
|
||||
})
|
||||
self.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.is_ok_and(|slot| {
|
||||
slot.page_slot_mut()
|
||||
.arm_root_post_load_observation(loader_id)
|
||||
})
|
||||
}
|
||||
|
||||
/// Consumes the exact stopped-loading fact owned by an armed root post-load
|
||||
@@ -2227,10 +2187,7 @@ impl CdpConnection {
|
||||
};
|
||||
|
||||
let binding = self
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| {
|
||||
slot.page_slot_mut()
|
||||
@@ -2240,19 +2197,13 @@ impl CdpConnection {
|
||||
return Err(SettlementError::MissingArmedObservation);
|
||||
};
|
||||
if self
|
||||
.subscribed_page_event_session_ids_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.subscribed_page_event_session_ids_for_owner(owner)
|
||||
.is_empty()
|
||||
{
|
||||
return Ok(Settlement::Unobserved);
|
||||
}
|
||||
let attachments = self
|
||||
.page_event_protocol_attachments_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.page_event_protocol_attachments_for_owner(owner)
|
||||
.ok_or(SettlementError::SubscribedAttachmentUnavailable)?;
|
||||
let publish_sequence = self
|
||||
.scheduler_state
|
||||
@@ -2277,31 +2228,26 @@ impl CdpConnection {
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
) -> bool {
|
||||
if !self
|
||||
.runtime_session_owner_slot_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_for_owner(owner)
|
||||
.is_ok_and(|slot| slot.renderer_subresources_are_idle())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
let binding = self
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.page_slot_mut().take_root_network_idle_binding());
|
||||
let Some(binding) = binding else {
|
||||
return false;
|
||||
};
|
||||
let timestamp = monotonic_timestamp_seconds();
|
||||
for event_session_id in
|
||||
self.page_event_session_ids_for_route(owner.session_id(), owner.session_owner_route())
|
||||
{
|
||||
let event_owner_route = event_session_id
|
||||
.is_none()
|
||||
.then_some(owner.session_owner_route())
|
||||
.flatten();
|
||||
for event_session_id in self.page_event_session_ids_for_owner(owner) {
|
||||
let event_owner = event_session_id
|
||||
.as_deref()
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
let lifecycle_enabled = self
|
||||
.target_page_session_state_for_route(event_session_id.as_deref(), event_owner_route)
|
||||
.target_page_session_state_for_owner(&event_owner)
|
||||
.is_some_and(|state| state.page_lifecycle_events);
|
||||
crate::domains::page::emit_navigation_network_idle_background_events(
|
||||
out,
|
||||
@@ -2333,6 +2279,14 @@ impl CdpConnection {
|
||||
let route = self
|
||||
.target_session_route_for_target_id(target_id.as_str())
|
||||
.or_else(|| self.target_session_route_for_child_frame_id(target_id.as_str()))?;
|
||||
if let Some(session_id) = context.session_id.as_ref()
|
||||
&& let Some(session_route) = self.session_route(Some(session_id.as_str()))
|
||||
{
|
||||
if !session_route.addresses_same_target_as(&route) {
|
||||
return None;
|
||||
}
|
||||
return Some(CommandOwnerScope::for_session(session_id.as_str()));
|
||||
}
|
||||
return Some(CommandOwnerScope::for_route(route));
|
||||
}
|
||||
Some(CommandOwnerScope::capture(
|
||||
@@ -2352,10 +2306,7 @@ impl CdpConnection {
|
||||
context: &DevToolsCommandContext,
|
||||
) -> Option<DevToolsPageResidenceIdentity> {
|
||||
let owner_scope = self.command_owner_scope_for_devtools_context(context)?;
|
||||
self.target_page_residence_identity_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
self.target_page_residence_identity_for_owner(&owner_scope)
|
||||
}
|
||||
|
||||
pub fn capture_devtools_document_lifecycle_wait_key(
|
||||
@@ -2366,10 +2317,7 @@ impl CdpConnection {
|
||||
) -> Option<DevToolsDocumentLifecycleWaitKey> {
|
||||
let owner_scope = self.command_owner_scope_for_devtools_context(context)?;
|
||||
let registration = self
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(&owner_scope)
|
||||
.ok()?
|
||||
.page_slot_mut()
|
||||
.register_renderer_document_lifecycle_waiter(milestone, expected_loader_id);
|
||||
@@ -2392,14 +2340,11 @@ impl CdpConnection {
|
||||
let Some(owner_scope) = self.command_owner_scope_for_devtools_context(context) else {
|
||||
return DevToolsDocumentLifecycleWaitState::Unavailable;
|
||||
};
|
||||
self.runtime_session_owner_slot_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.ok()
|
||||
.map_or(DevToolsDocumentLifecycleWaitState::Unavailable, |slot| {
|
||||
devtools_document_lifecycle_wait_state_for_slot(slot, key)
|
||||
})
|
||||
self.runtime_session_owner_slot_for_owner(&owner_scope)
|
||||
.ok()
|
||||
.map_or(DevToolsDocumentLifecycleWaitState::Unavailable, |slot| {
|
||||
devtools_document_lifecycle_wait_state_for_slot(slot, key)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn release_devtools_document_lifecycle_wait_key(
|
||||
@@ -2410,30 +2355,25 @@ impl CdpConnection {
|
||||
let Some(owner_scope) = self.command_owner_scope_for_devtools_context(context) else {
|
||||
return false;
|
||||
};
|
||||
self.runtime_session_owner_slot_mut_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.is_ok_and(|slot| {
|
||||
slot.page_slot_mut()
|
||||
.release_renderer_document_lifecycle_waiter(
|
||||
key.registration_id,
|
||||
key.renderer_document,
|
||||
key.renderer_epoch,
|
||||
&key.frame_id,
|
||||
&key.loader_id,
|
||||
)
|
||||
})
|
||||
self.runtime_session_owner_slot_mut_for_owner(&owner_scope)
|
||||
.is_ok_and(|slot| {
|
||||
slot.page_slot_mut()
|
||||
.release_renderer_document_lifecycle_waiter(
|
||||
key.registration_id,
|
||||
key.renderer_document,
|
||||
key.renderer_epoch,
|
||||
&key.frame_id,
|
||||
&key.loader_id,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn accepts_document_body_completion_for_route(
|
||||
pub(crate) fn accepts_document_body_completion_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
token: &DocumentNavigationToken,
|
||||
) -> bool {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
self.target_owner_identity_for_route(session_id, owner_route)
|
||||
let Some((browser_context_id, target_id)) = self.target_owner_identity_for_owner(owner)
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
@@ -2451,8 +2391,7 @@ impl CdpConnection {
|
||||
owner: &CommandOwnerScope,
|
||||
loader_id: &str,
|
||||
) {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
self.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
let Some((browser_context_id, target_id)) = self.target_owner_identity_for_owner(owner)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
@@ -2522,32 +2461,27 @@ impl CdpConnection {
|
||||
}));
|
||||
}
|
||||
|
||||
pub(crate) fn background_navigation_completion_sender_for_route(
|
||||
pub(crate) fn background_navigation_completion_sender_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<
|
||||
tokio::sync::mpsc::UnboundedSender<crate::domains::page::BackgroundNavigationCompletion>,
|
||||
> {
|
||||
if !self.can_run_background_navigation_for_route(session_id, owner_route) {
|
||||
if !self.can_run_background_navigation_for_owner(owner) {
|
||||
return None;
|
||||
}
|
||||
self.scheduler_hooks
|
||||
.background_navigation_completion_sender()
|
||||
}
|
||||
|
||||
fn can_run_background_navigation_for_route(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
) -> bool {
|
||||
fn can_run_background_navigation_for_owner(&self, owner: &CommandOwnerScope) -> bool {
|
||||
if !self
|
||||
.scheduler_hooks
|
||||
.has_background_navigation_completion_sender()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
self.target_owner_identity_for_route(session_id, owner_route)
|
||||
self.target_owner_identity_for_owner(owner)
|
||||
.is_some_and(|(_, target_id)| target_id.is_some())
|
||||
}
|
||||
|
||||
@@ -2693,7 +2627,7 @@ impl CdpConnection {
|
||||
engine: NavigationEngine,
|
||||
) {
|
||||
let Some((browser_context_id, Some(target_id))) =
|
||||
self.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
self.target_owner_identity_for_owner(owner)
|
||||
else {
|
||||
self.replace_standalone_navigation_engine(engine);
|
||||
return;
|
||||
@@ -2746,12 +2680,14 @@ impl CdpConnection {
|
||||
/// authority.
|
||||
pub(crate) fn publish_prepared_top_level_location_navigation_owner_action(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
page_owner: TargetPageResidenceIdentity,
|
||||
navigation: moli_core::page::RendererDocumentSourcedTopLevelLocationNavigation,
|
||||
) {
|
||||
let action = TopLevelLocationNavigationOwnerAction::from_prepared(
|
||||
self, session_id, page_owner, navigation,
|
||||
owner.clone(),
|
||||
page_owner,
|
||||
navigation,
|
||||
);
|
||||
self.publish_top_level_location_navigation_owner_action(action);
|
||||
}
|
||||
@@ -3753,12 +3689,12 @@ impl CdpConnection {
|
||||
self.exact_target_info_changed_event_plan_for_target_delta(target_id)
|
||||
}
|
||||
|
||||
pub(crate) fn target_info_changed_event_plan_for_session_owner(
|
||||
pub(crate) fn target_info_changed_event_plan_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> TargetEventPlan {
|
||||
let Some((browser_context_id, Some(target_id))) =
|
||||
self.target_owner_identity_for_session(session_id)
|
||||
self.target_owner_identity_for_owner(owner)
|
||||
else {
|
||||
return TargetEventPlan::default();
|
||||
};
|
||||
|
||||
@@ -35,18 +35,15 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
) -> Option<(&mut NavigationEngine, &mut TargetRuntimeSlot)> {
|
||||
self.activity_source_engine_and_runtime_slot_mut_for_route(session_id, None)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.activity_source_engine_and_runtime_slot_mut_for_owner(&owner)
|
||||
}
|
||||
|
||||
fn activity_source_engine_and_runtime_slot_mut_for_route(
|
||||
fn activity_source_engine_and_runtime_slot_mut_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<(&mut NavigationEngine, &mut TargetRuntimeSlot)> {
|
||||
let route = match session_id {
|
||||
Some(_) => self.session_route(session_id)?,
|
||||
None => owner_route.cloned().unwrap_or(CdpSessionRoute::Browser),
|
||||
};
|
||||
let route = owner.resolve_route(self)?;
|
||||
let (browser_context_id, target_id) = match &route {
|
||||
CdpSessionRoute::PageTarget {
|
||||
browser_context_id,
|
||||
@@ -74,23 +71,13 @@ impl CdpConnection {
|
||||
.navigation_engine_and_runtime_slot_mut()
|
||||
}
|
||||
|
||||
fn activity_source_engine_and_runtime_slot_mut_for_owner(
|
||||
&mut self,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<(&mut NavigationEngine, &mut TargetRuntimeSlot)> {
|
||||
self.activity_source_engine_and_runtime_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn start_child_frame_lifecycle_work_for_owner(
|
||||
&mut self,
|
||||
owner: CommandOwnerScope,
|
||||
timeout: std::time::Duration,
|
||||
) -> Result<PendingChildFrameLifecycleWork, String> {
|
||||
let storage = self
|
||||
.navigation_load_inputs_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.navigation_load_inputs_for_owner(&owner)
|
||||
.resource_storage_handles();
|
||||
let Some((engine, slot)) =
|
||||
self.activity_source_engine_and_runtime_slot_mut_for_owner(&owner)
|
||||
|
||||
@@ -23,10 +23,7 @@ impl BidiChannelPageOwner {
|
||||
owner_scope: CommandOwnerScope,
|
||||
) -> Option<Self> {
|
||||
Some(Self {
|
||||
attachment: conn.target_page_protocol_attachment_identity_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)?,
|
||||
attachment: conn.target_page_protocol_attachment_identity_for_owner(&owner_scope)?,
|
||||
owner_scope,
|
||||
})
|
||||
}
|
||||
@@ -234,7 +231,7 @@ mod tests {
|
||||
.expect("implicit owner must capture the scoped Page");
|
||||
|
||||
assert_eq!(
|
||||
owner.command_owner().session_owner_route(),
|
||||
owner.command_owner().explicit_route(),
|
||||
Some(&owner_route),
|
||||
"deferred work must retain its exact Page route"
|
||||
);
|
||||
|
||||
@@ -94,16 +94,16 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
f: impl FnOnce(Option<TargetEmulationSessionStateMut<'_>>),
|
||||
) -> bool {
|
||||
self.mutate_emulation_session_state_for_route(session_id, None, f)
|
||||
let owner = crate::conn::CommandOwnerScope::capture(self, session_id);
|
||||
self.mutate_emulation_session_state_for_owner(&owner, f)
|
||||
}
|
||||
|
||||
pub(crate) fn mutate_emulation_session_state_for_route(
|
||||
pub(crate) fn mutate_emulation_session_state_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
f: impl FnOnce(Option<TargetEmulationSessionStateMut<'_>>),
|
||||
) -> bool {
|
||||
self.with_target_session_owner_mut_for_route(session_id, owner_route, |owner| {
|
||||
self.with_target_session_owner_mut_for_owner(owner, |owner| {
|
||||
owner.mutate_emulation_session_state(f)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
@@ -129,26 +129,24 @@ impl CdpConnection {
|
||||
.set_devtools_timezone_override(timezone_override)
|
||||
}
|
||||
|
||||
pub(crate) fn set_base_locale_override_for_route(
|
||||
pub(crate) fn set_base_locale_override_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
locale_override: Option<String>,
|
||||
) -> bool {
|
||||
let fallback_identity = self.base_browser_identity.clone();
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.set_base_locale_override(locale_override, &fallback_identity)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn set_base_timezone_override_for_route(
|
||||
pub(crate) fn set_base_timezone_override_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
timezone_override: Option<String>,
|
||||
) -> bool {
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| owner.set_base_timezone_override(timezone_override))
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@ use crate::conn::state::{
|
||||
TargetFetchConfig, TargetFetchOwner, TargetFetchSubresourceInterceptionSnapshot,
|
||||
};
|
||||
use crate::conn::{
|
||||
CapturedBody, CompletedFetchResponseBodyStreamReadDispatch, FetchInterceptionPattern,
|
||||
FetchRequestStage, InFlightSubresourceFetchRequest, PausedDocumentTransfer,
|
||||
PendingFetchAuthNavigation, PendingFetchNavigation, PendingFetchResponseBodyStreamRead,
|
||||
PendingFetchResponseBodyStreamReadStart, PendingSubresourceFetchAuthRequest,
|
||||
PendingSubresourceFetchRequest, PendingSubresourceFetchResponseRequest, TargetRuntimeSlot,
|
||||
CapturedBody, CommandOwnerScope, CompletedFetchResponseBodyStreamReadDispatch,
|
||||
FetchInterceptionPattern, FetchRequestStage, InFlightSubresourceFetchRequest,
|
||||
PausedDocumentTransfer, PendingFetchAuthNavigation, PendingFetchNavigation,
|
||||
PendingFetchResponseBodyStreamRead, PendingFetchResponseBodyStreamReadStart,
|
||||
PendingSubresourceFetchAuthRequest, PendingSubresourceFetchRequest,
|
||||
PendingSubresourceFetchResponseRequest, TargetRuntimeSlot,
|
||||
};
|
||||
use crate::devtools_runtime::{DevToolsNetworkInterceptId, DevToolsNetworkResourceType};
|
||||
use crate::domains::network::TargetIoStreamRead;
|
||||
@@ -221,12 +222,11 @@ fn remove_network_intercept_from_browser_context(
|
||||
}
|
||||
|
||||
impl CdpConnection {
|
||||
pub(crate) fn target_fetch_subresource_interception_snapshot_for_route(
|
||||
pub(crate) fn target_fetch_subresource_interception_snapshot_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<TargetFetchSubresourceInterceptionSnapshot> {
|
||||
self.target_session_owner_aggregate_fetch_config_for_route(session_id, owner_route)
|
||||
self.target_session_owner_aggregate_fetch_config_for_owner(owner)
|
||||
.map(|config| config.subresource_interception_snapshot())
|
||||
}
|
||||
|
||||
@@ -238,40 +238,37 @@ impl CdpConnection {
|
||||
.map(|config| config.subresource_interception_snapshot())
|
||||
}
|
||||
|
||||
pub(crate) fn target_fetch_event_session_id_for_route(
|
||||
pub(crate) fn target_fetch_event_session_id_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<String> {
|
||||
self.target_session_owner_aggregate_fetch_config_for_route(session_id, owner_route)
|
||||
self.target_session_owner_aggregate_fetch_config_for_owner(owner)
|
||||
.and_then(|config| config.session_id().map(str::to_owned))
|
||||
}
|
||||
|
||||
pub(crate) fn target_fetch_handle_auth_requests_for_route(
|
||||
pub(crate) fn target_fetch_handle_auth_requests_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
self.target_session_owner_aggregate_fetch_config_for_route(session_id, owner_route)
|
||||
self.target_session_owner_aggregate_fetch_config_for_owner(owner)
|
||||
.is_some_and(|config| config.handle_auth_requests())
|
||||
}
|
||||
|
||||
pub(crate) fn target_fetch_matches_auth_required_for_route(
|
||||
pub(crate) fn target_fetch_matches_auth_required_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
url: &url::Url,
|
||||
) -> bool {
|
||||
self.target_session_owner_aggregate_fetch_config_for_route(session_id, owner_route)
|
||||
self.target_session_owner_aggregate_fetch_config_for_owner(owner)
|
||||
.is_some_and(|config| config.matches_auth_required(url))
|
||||
}
|
||||
|
||||
pub(crate) fn target_fetch_matching_auth_required_network_intercepts_for_session_owner(
|
||||
pub(crate) fn target_fetch_matching_auth_required_network_intercepts_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
url: &url::Url,
|
||||
) -> Vec<DevToolsNetworkInterceptId> {
|
||||
self.target_session_owner_aggregate_fetch_config(session_id)
|
||||
self.target_session_owner_aggregate_fetch_config_for_owner(owner)
|
||||
.map(|config| config.matching_auth_required_network_intercepts(url))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
@@ -317,15 +314,14 @@ impl CdpConnection {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn allocate_pending_subresource_fetch_request_ids_for_route(
|
||||
pub(crate) fn allocate_pending_subresource_fetch_request_ids_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<(String, String), String> {
|
||||
let mut network_request_id_allocator =
|
||||
std::mem::take(&mut self.network_request_id_allocator);
|
||||
let result = self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.map(|runtime_slot| {
|
||||
runtime_slot
|
||||
.request_id_allocator()
|
||||
@@ -337,12 +333,11 @@ impl CdpConnection {
|
||||
result
|
||||
}
|
||||
|
||||
pub(crate) fn allocate_fetch_navigation_request_id_for_route(
|
||||
pub(crate) fn allocate_fetch_navigation_request_id_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<String, String> {
|
||||
self.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
self.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.map(|runtime_slot| {
|
||||
runtime_slot
|
||||
.request_id_allocator()
|
||||
@@ -367,17 +362,16 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
body: CapturedBody,
|
||||
) -> Result<String, String> {
|
||||
self.open_io_stream_body_source_for_route(session_id, None, body)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.open_io_stream_body_source_for_owner(&owner, body)
|
||||
}
|
||||
|
||||
pub(crate) fn open_io_stream_body_source_for_route(
|
||||
pub(crate) fn open_io_stream_body_source_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
body: CapturedBody,
|
||||
) -> Result<String, String> {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_owner(owner) else {
|
||||
return Err("NoDocumentLoaded".to_owned());
|
||||
};
|
||||
owner.open_scoped_io_stream_body_source(body)
|
||||
@@ -404,17 +398,14 @@ impl CdpConnection {
|
||||
.read_io_stream(handle, offset, size)
|
||||
}
|
||||
|
||||
pub(crate) fn register_synthetic_websocket_request_for_route(
|
||||
pub(crate) fn register_synthetic_websocket_request_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: String,
|
||||
network_request_id: String,
|
||||
socket_id: u64,
|
||||
) -> bool {
|
||||
let Ok(runtime_slot) =
|
||||
self.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Ok(runtime_slot) = self.runtime_session_owner_slot_mut_for_owner(owner) else {
|
||||
return false;
|
||||
};
|
||||
runtime_slot.register_synthetic_websocket_request(
|
||||
@@ -430,16 +421,16 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<u64> {
|
||||
self.synthetic_websocket_socket_id_for_route(session_id, None, request_id)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.synthetic_websocket_socket_id_for_owner(&owner, request_id)
|
||||
}
|
||||
|
||||
pub(crate) fn synthetic_websocket_socket_id_for_route(
|
||||
pub(crate) fn synthetic_websocket_socket_id_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: &str,
|
||||
) -> Option<u64> {
|
||||
self.runtime_session_owner_slot_for_route(session_id, owner_route)
|
||||
self.runtime_session_owner_slot_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|runtime_slot| {
|
||||
runtime_slot.synthetic_websocket_socket_id_for_request(request_id)
|
||||
@@ -456,75 +447,67 @@ impl CdpConnection {
|
||||
|
||||
pub(crate) fn pending_subresource_fetch_request_residence_is_current(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
pending: &PendingSubresourceFetchRequest,
|
||||
) -> bool {
|
||||
pending.installed_page_owner().is_none_or(|owner| {
|
||||
self.target_page_residence_identity_is_current_for_session(session_id, owner)
|
||||
})
|
||||
pending
|
||||
.installed_page_owner()
|
||||
.is_none_or(|owner| self.target_page_residence_identity_is_current(owner))
|
||||
}
|
||||
|
||||
fn installed_subresource_fetch_request_is_current(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
pending: &PendingSubresourceFetchRequest,
|
||||
) -> bool {
|
||||
pending.installed_page_owner().is_some_and(|owner| {
|
||||
self.target_page_residence_identity_is_current_for_session(session_id, owner)
|
||||
})
|
||||
pending
|
||||
.installed_page_owner()
|
||||
.is_some_and(|owner| self.target_page_residence_identity_is_current(owner))
|
||||
}
|
||||
|
||||
pub(crate) fn claim_subresource_continue_request_for_route(
|
||||
pub(crate) fn claim_subresource_continue_request_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
expected_page_owner: &crate::conn::TargetPageResidenceIdentity,
|
||||
internal_id: u64,
|
||||
allow_pending_completion: bool,
|
||||
) -> Option<crate::conn::ClaimedSubresourceContinueRequest> {
|
||||
if !self
|
||||
.target_page_residence_identity_is_current_for_session(session_id, expected_page_owner)
|
||||
{
|
||||
if !self.target_page_residence_identity_is_current(expected_page_owner) {
|
||||
return None;
|
||||
}
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)?
|
||||
self.target_session_owner_mut_for_owner(owner)?
|
||||
.claim_subresource_continue_request(
|
||||
expected_page_owner,
|
||||
internal_id,
|
||||
session_id,
|
||||
owner.session_id(),
|
||||
allow_pending_completion,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn consume_pending_request_action_for_route(
|
||||
pub(crate) fn consume_pending_request_action_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: &str,
|
||||
) -> Option<Result<(), &'static str>> {
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)?
|
||||
self.target_session_owner_mut_for_owner(owner)?
|
||||
.consume_pending_request_action(request_id)
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_fetch_navigation_for_route(
|
||||
pub(crate) fn take_pending_fetch_navigation_for_owner(
|
||||
&mut self,
|
||||
owner_session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingFetchNavigation> {
|
||||
self.target_session_owner_mut_for_route(owner_session_id, owner_route)?
|
||||
self.target_session_owner_mut_for_owner(owner)?
|
||||
.take_pending_fetch_navigation_for_action_session(request_id, action_session_id)
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_fetch_auth_navigation_for_route(
|
||||
pub(crate) fn take_pending_fetch_auth_navigation_for_owner(
|
||||
&mut self,
|
||||
owner_session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingFetchAuthNavigation> {
|
||||
self.target_session_owner_mut_for_route(owner_session_id, owner_route)?
|
||||
self.target_session_owner_mut_for_owner(owner)?
|
||||
.take_pending_fetch_auth_navigation_for_action_session(request_id, action_session_id)
|
||||
}
|
||||
|
||||
@@ -534,31 +517,31 @@ impl CdpConnection {
|
||||
request_id: String,
|
||||
pending: PendingFetchAuthNavigation,
|
||||
) -> bool {
|
||||
self.register_pending_fetch_auth_navigation_for_route(session_id, None, request_id, pending)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.register_pending_fetch_auth_navigation_for_owner(&owner, request_id, pending)
|
||||
}
|
||||
|
||||
pub(crate) fn register_pending_fetch_auth_navigation_for_route(
|
||||
pub(crate) fn register_pending_fetch_auth_navigation_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: String,
|
||||
pending: PendingFetchAuthNavigation,
|
||||
) -> bool {
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.register_pending_fetch_auth_navigation(request_id, pending)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn register_pending_fetch_response_navigation_for_session_owner(
|
||||
pub(crate) fn register_pending_fetch_response_navigation_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: String,
|
||||
document_navigation_token: Option<crate::conn::DocumentNavigationToken>,
|
||||
navigation: crate::conn::NavigationDispatchState,
|
||||
body: crate::conn::DocumentBodySource,
|
||||
) -> bool {
|
||||
self.target_session_owner_mut(session_id)
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.register_pending_fetch_response_navigation(
|
||||
request_id,
|
||||
@@ -569,58 +552,53 @@ impl CdpConnection {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_fetch_response_transfer_for_terminal_action_for_route(
|
||||
pub(crate) fn take_pending_fetch_response_transfer_for_terminal_action_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: &str,
|
||||
) -> Option<PausedDocumentTransfer> {
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)?
|
||||
self.target_session_owner_mut_for_owner(owner)?
|
||||
.take_pending_fetch_response_transfer_for_terminal_action(request_id)
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_fetch_response_transfer_for_body_read_for_route(
|
||||
pub(crate) fn take_pending_fetch_response_transfer_for_body_read_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: &str,
|
||||
) -> Option<PausedDocumentTransfer> {
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)?
|
||||
self.target_session_owner_mut_for_owner(owner)?
|
||||
.take_pending_fetch_response_transfer(request_id)
|
||||
}
|
||||
|
||||
pub(crate) fn register_pending_fetch_response_transfer_for_route(
|
||||
pub(crate) fn register_pending_fetch_response_transfer_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: String,
|
||||
transfer: PausedDocumentTransfer,
|
||||
) -> bool {
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.register_pending_fetch_response_transfer(request_id, transfer)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn pending_subresource_fetch_response_request_for_route(
|
||||
pub(crate) fn pending_subresource_fetch_response_request_for_owner(
|
||||
&mut self,
|
||||
owner_session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingSubresourceFetchResponseRequest> {
|
||||
self.target_session_owner_mut_for_route(owner_session_id, owner_route)?
|
||||
self.target_session_owner_mut_for_owner(owner)?
|
||||
.pending_subresource_fetch_response_request(request_id, action_session_id)
|
||||
}
|
||||
|
||||
pub(crate) fn mark_pending_subresource_fetch_response_body_taken_as_stream_for_route(
|
||||
pub(crate) fn mark_pending_subresource_fetch_response_body_taken_as_stream_for_owner(
|
||||
&mut self,
|
||||
owner_session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> bool {
|
||||
self.target_session_owner_mut_for_route(owner_session_id, owner_route)
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.mark_pending_subresource_fetch_response_body_taken_as_stream(
|
||||
request_id,
|
||||
@@ -780,81 +758,70 @@ impl CdpConnection {
|
||||
let pending = self
|
||||
.target_session_owner_mut(session_id)?
|
||||
.take_pending_subresource_fetch_request(request_id, session_id)?;
|
||||
self.pending_subresource_fetch_request_residence_is_current(session_id, &pending)
|
||||
self.pending_subresource_fetch_request_residence_is_current(&pending)
|
||||
.then_some(pending)
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_subresource_fetch_request_for_route(
|
||||
pub(crate) fn take_pending_subresource_fetch_request_for_owner(
|
||||
&mut self,
|
||||
owner_session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingSubresourceFetchRequest> {
|
||||
let pending = self
|
||||
.target_session_owner_mut_for_route(owner_session_id, owner_route)?
|
||||
.target_session_owner_mut_for_owner(owner)?
|
||||
.take_pending_subresource_fetch_request(request_id, action_session_id)?;
|
||||
self.pending_subresource_fetch_request_residence_is_current(owner_session_id, &pending)
|
||||
self.pending_subresource_fetch_request_residence_is_current(&pending)
|
||||
.then_some(pending)
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_subresource_fetch_auth_request_for_route(
|
||||
pub(crate) fn take_pending_subresource_fetch_auth_request_for_owner(
|
||||
&mut self,
|
||||
owner_session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingSubresourceFetchAuthRequest> {
|
||||
let pending = self
|
||||
.target_session_owner_mut_for_route(owner_session_id, owner_route)?
|
||||
.target_session_owner_mut_for_owner(owner)?
|
||||
.take_pending_subresource_fetch_auth_request(request_id, action_session_id)?;
|
||||
self.target_page_residence_identity_is_current_for_session(
|
||||
owner_session_id,
|
||||
&pending.page_owner,
|
||||
)
|
||||
.then_some(pending)
|
||||
self.target_page_residence_identity_is_current(&pending.page_owner)
|
||||
.then_some(pending)
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_subresource_fetch_response_request_for_route(
|
||||
pub(crate) fn take_pending_subresource_fetch_response_request_for_owner(
|
||||
&mut self,
|
||||
owner_session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingSubresourceFetchResponseRequest> {
|
||||
let pending = self
|
||||
.target_session_owner_mut_for_route(owner_session_id, owner_route)?
|
||||
.target_session_owner_mut_for_owner(owner)?
|
||||
.take_pending_subresource_fetch_response_request(request_id, action_session_id)?;
|
||||
self.target_page_residence_identity_is_current_for_session(
|
||||
owner_session_id,
|
||||
&pending.page_owner,
|
||||
)
|
||||
.then_some(pending)
|
||||
self.target_page_residence_identity_is_current(&pending.page_owner)
|
||||
.then_some(pending)
|
||||
}
|
||||
|
||||
pub(crate) fn take_in_flight_subresource_fetch_request_for_route(
|
||||
pub(crate) fn take_in_flight_subresource_fetch_request_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
internal_id: u64,
|
||||
) -> Option<InFlightSubresourceFetchRequest> {
|
||||
let in_flight = self
|
||||
.target_session_owner_mut_for_route(session_id, owner_route)?
|
||||
.target_session_owner_mut_for_owner(owner)?
|
||||
.take_in_flight_subresource_fetch_request(internal_id)?;
|
||||
self.installed_subresource_fetch_request_is_current(session_id, &in_flight.pending)
|
||||
self.installed_subresource_fetch_request_is_current(&in_flight.pending)
|
||||
.then_some(in_flight)
|
||||
}
|
||||
|
||||
pub(crate) fn in_flight_subresource_fetch_request_id_for_route(
|
||||
pub(crate) fn in_flight_subresource_fetch_request_id_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
internal_id: u64,
|
||||
) -> Option<String> {
|
||||
let (request_id, page_owner) = self
|
||||
.target_session_owner_mut_for_route(session_id, owner_route)?
|
||||
.target_session_owner_mut_for_owner(owner)?
|
||||
.in_flight_subresource_fetch_request_identity(internal_id)?;
|
||||
self.target_page_residence_identity_is_current_for_session(session_id, &page_owner)
|
||||
self.target_page_residence_identity_is_current(&page_owner)
|
||||
.then_some(request_id)
|
||||
}
|
||||
|
||||
@@ -864,70 +831,54 @@ impl CdpConnection {
|
||||
request_id: String,
|
||||
pending: PendingSubresourceFetchRequest,
|
||||
) -> bool {
|
||||
self.register_pending_subresource_fetch_request_for_route(
|
||||
session_id, None, request_id, pending,
|
||||
)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.register_pending_subresource_fetch_request_for_owner(&owner, request_id, pending)
|
||||
}
|
||||
|
||||
pub(crate) fn register_pending_subresource_fetch_request_for_route(
|
||||
pub(crate) fn register_pending_subresource_fetch_request_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: String,
|
||||
pending: PendingSubresourceFetchRequest,
|
||||
) -> bool {
|
||||
if !self.pending_subresource_fetch_request_residence_is_current(session_id, &pending) {
|
||||
if !self.pending_subresource_fetch_request_residence_is_current(&pending) {
|
||||
return false;
|
||||
}
|
||||
self.record_pending_subresource_network_request_identity_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
&pending,
|
||||
);
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
self.record_pending_subresource_network_request_identity_for_owner(owner, &pending);
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.register_pending_subresource_fetch_request(request_id, pending)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn register_in_flight_subresource_fetch_request_for_route(
|
||||
pub(crate) fn register_in_flight_subresource_fetch_request_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: Option<String>,
|
||||
pending: PendingSubresourceFetchRequest,
|
||||
) -> bool {
|
||||
if !self.installed_subresource_fetch_request_is_current(session_id, &pending) {
|
||||
if !self.installed_subresource_fetch_request_is_current(&pending) {
|
||||
return false;
|
||||
}
|
||||
self.record_pending_subresource_network_request_identity_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
&pending,
|
||||
);
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
self.record_pending_subresource_network_request_identity_for_owner(owner, &pending);
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.register_in_flight_subresource_fetch_request(request_id, pending)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn register_in_flight_response_stage_subresource_fetch_request_for_route(
|
||||
pub(crate) fn register_in_flight_response_stage_subresource_fetch_request_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: Option<String>,
|
||||
pending: PendingSubresourceFetchRequest,
|
||||
response_stage_blocked_intercepts: Vec<DevToolsNetworkInterceptId>,
|
||||
) -> bool {
|
||||
if !self.installed_subresource_fetch_request_is_current(session_id, &pending) {
|
||||
if !self.installed_subresource_fetch_request_is_current(&pending) {
|
||||
return false;
|
||||
}
|
||||
self.record_pending_subresource_network_request_identity_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
&pending,
|
||||
);
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
self.record_pending_subresource_network_request_identity_for_owner(owner, &pending);
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.register_in_flight_response_stage_subresource_fetch_request(
|
||||
request_id,
|
||||
@@ -938,22 +889,17 @@ impl CdpConnection {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn register_in_flight_deferred_response_stage_subresource_fetch_request_for_route(
|
||||
pub(crate) fn register_in_flight_deferred_response_stage_subresource_fetch_request_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: Option<String>,
|
||||
pending: PendingSubresourceFetchRequest,
|
||||
) -> bool {
|
||||
if !self.installed_subresource_fetch_request_is_current(session_id, &pending) {
|
||||
if !self.installed_subresource_fetch_request_is_current(&pending) {
|
||||
return false;
|
||||
}
|
||||
self.record_pending_subresource_network_request_identity_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
&pending,
|
||||
);
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
self.record_pending_subresource_network_request_identity_for_owner(owner, &pending);
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.register_in_flight_subresource_fetch_request_with_response_match_policy(
|
||||
request_id,
|
||||
@@ -969,29 +915,21 @@ impl CdpConnection {
|
||||
request_id: String,
|
||||
pending: PendingSubresourceFetchAuthRequest,
|
||||
) -> bool {
|
||||
self.register_pending_subresource_fetch_auth_request_for_route(
|
||||
session_id, None, request_id, pending,
|
||||
)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.register_pending_subresource_fetch_auth_request_for_owner(&owner, request_id, pending)
|
||||
}
|
||||
|
||||
pub(crate) fn register_pending_subresource_fetch_auth_request_for_route(
|
||||
pub(crate) fn register_pending_subresource_fetch_auth_request_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: String,
|
||||
pending: PendingSubresourceFetchAuthRequest,
|
||||
) -> bool {
|
||||
if !self
|
||||
.target_page_residence_identity_is_current_for_session(session_id, &pending.page_owner)
|
||||
{
|
||||
if !self.target_page_residence_identity_is_current(&pending.page_owner) {
|
||||
return false;
|
||||
}
|
||||
self.record_pending_subresource_auth_network_request_identity_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
&pending,
|
||||
);
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
self.record_pending_subresource_auth_network_request_identity_for_owner(owner, &pending);
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.register_pending_subresource_fetch_auth_request(request_id, pending)
|
||||
})
|
||||
@@ -1003,46 +941,39 @@ impl CdpConnection {
|
||||
request_id: String,
|
||||
pending: PendingSubresourceFetchResponseRequest,
|
||||
) -> bool {
|
||||
self.register_pending_subresource_fetch_response_request_for_route(
|
||||
session_id, None, request_id, pending,
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.register_pending_subresource_fetch_response_request_for_owner(
|
||||
&owner, request_id, pending,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn register_pending_subresource_fetch_response_request_for_route(
|
||||
pub(crate) fn register_pending_subresource_fetch_response_request_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: String,
|
||||
pending: PendingSubresourceFetchResponseRequest,
|
||||
) -> bool {
|
||||
if !self
|
||||
.target_page_residence_identity_is_current_for_session(session_id, &pending.page_owner)
|
||||
{
|
||||
if !self.target_page_residence_identity_is_current(&pending.page_owner) {
|
||||
return false;
|
||||
}
|
||||
self.record_pending_subresource_response_network_request_identity_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
&pending,
|
||||
self.record_pending_subresource_response_network_request_identity_for_owner(
|
||||
owner, &pending,
|
||||
);
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
self.target_session_owner_mut_for_owner(owner)
|
||||
.is_some_and(|mut owner| {
|
||||
owner.register_pending_subresource_fetch_response_request(request_id, pending)
|
||||
})
|
||||
}
|
||||
|
||||
fn record_pending_subresource_network_request_identity_for_route(
|
||||
fn record_pending_subresource_network_request_identity_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
pending: &PendingSubresourceFetchRequest,
|
||||
) {
|
||||
let Some(handle) = pending.network_request_handle else {
|
||||
return;
|
||||
};
|
||||
if let Ok(runtime_slot) =
|
||||
self.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
{
|
||||
if let Ok(runtime_slot) = self.runtime_session_owner_slot_mut_for_owner(owner) {
|
||||
runtime_slot.record_subresource_request_id_for_handle_if_absent(
|
||||
handle,
|
||||
pending.network_request_id.clone(),
|
||||
@@ -1050,18 +981,15 @@ impl CdpConnection {
|
||||
}
|
||||
}
|
||||
|
||||
fn record_pending_subresource_auth_network_request_identity_for_route(
|
||||
fn record_pending_subresource_auth_network_request_identity_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
pending: &PendingSubresourceFetchAuthRequest,
|
||||
) {
|
||||
let Some(handle) = pending.network_request_handle else {
|
||||
return;
|
||||
};
|
||||
if let Ok(runtime_slot) =
|
||||
self.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
{
|
||||
if let Ok(runtime_slot) = self.runtime_session_owner_slot_mut_for_owner(owner) {
|
||||
runtime_slot.record_subresource_request_id_for_handle_if_absent(
|
||||
handle,
|
||||
pending.network_request_id.clone(),
|
||||
@@ -1069,18 +997,15 @@ impl CdpConnection {
|
||||
}
|
||||
}
|
||||
|
||||
fn record_pending_subresource_response_network_request_identity_for_route(
|
||||
fn record_pending_subresource_response_network_request_identity_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
pending: &PendingSubresourceFetchResponseRequest,
|
||||
) {
|
||||
let Some(handle) = pending.network_request_handle else {
|
||||
return;
|
||||
};
|
||||
if let Ok(runtime_slot) =
|
||||
self.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
{
|
||||
if let Ok(runtime_slot) = self.runtime_session_owner_slot_mut_for_owner(owner) {
|
||||
runtime_slot.record_subresource_request_id_for_handle_if_absent(
|
||||
handle,
|
||||
pending.network_request_id.clone(),
|
||||
@@ -1094,22 +1019,21 @@ impl CdpConnection {
|
||||
handle_auth_requests: bool,
|
||||
patterns: Vec<FetchInterceptionPattern>,
|
||||
) -> Result<Option<moli_core::page::PendingPageCommand>, String> {
|
||||
self.start_enable_fetch_for_route(session_id, None, handle_auth_requests, patterns)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.start_enable_fetch_for_owner(&owner, handle_auth_requests, patterns)
|
||||
}
|
||||
|
||||
pub(crate) fn start_enable_fetch_for_route(
|
||||
pub(crate) fn start_enable_fetch_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
command_owner: &CommandOwnerScope,
|
||||
handle_auth_requests: bool,
|
||||
patterns: Vec<FetchInterceptionPattern>,
|
||||
) -> Result<Option<moli_core::page::PendingPageCommand>, String> {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_owner(command_owner) else {
|
||||
return Err("BrowserContextNotLoaded".to_owned());
|
||||
};
|
||||
let (subresource_enabled, subresource_resource_type) = owner.configure_fetch(
|
||||
session_id.map(str::to_owned),
|
||||
command_owner.session_id().map(str::to_owned),
|
||||
handle_auth_requests,
|
||||
patterns,
|
||||
);
|
||||
@@ -1125,18 +1049,16 @@ impl CdpConnection {
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn start_add_network_intercept_for_route(
|
||||
pub(crate) fn start_add_network_intercept_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
command_owner: &CommandOwnerScope,
|
||||
intercept_session_id: Option<String>,
|
||||
intercept_id: String,
|
||||
handle_auth_requests: bool,
|
||||
auth_url_patterns: Vec<String>,
|
||||
patterns: Vec<FetchInterceptionPattern>,
|
||||
) -> Result<Option<moli_core::page::PendingPageCommand>, String> {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_owner(command_owner) else {
|
||||
return Err("BrowserContextNotLoaded".to_owned());
|
||||
};
|
||||
let (subresource_enabled, subresource_resource_type) = owner.add_network_intercept(
|
||||
@@ -1157,15 +1079,13 @@ impl CdpConnection {
|
||||
.map_err(|error| format!("failed to update page fetch interception: {error}"))
|
||||
}
|
||||
|
||||
pub(crate) fn start_remove_network_intercept_for_route(
|
||||
pub(crate) fn start_remove_network_intercept_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
command_owner: &CommandOwnerScope,
|
||||
intercept_id: &str,
|
||||
allow_global_lookup: bool,
|
||||
) -> Result<Option<moli_core::page::PendingPageCommand>, String> {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_owner(command_owner) else {
|
||||
return Err("BrowserContextNotLoaded".to_owned());
|
||||
};
|
||||
let Some((subresource_enabled, subresource_resource_type)) =
|
||||
@@ -1217,13 +1137,13 @@ impl CdpConnection {
|
||||
)>,
|
||||
String,
|
||||
> {
|
||||
self.start_disable_fetch_for_route(session_id, None)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.start_disable_fetch_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn start_disable_fetch_for_route(
|
||||
pub(crate) fn start_disable_fetch_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
command_owner: &CommandOwnerScope,
|
||||
) -> Result<
|
||||
Option<(
|
||||
SessionOwnerPendingFetchState,
|
||||
@@ -1231,12 +1151,12 @@ impl CdpConnection {
|
||||
)>,
|
||||
String,
|
||||
> {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_owner(command_owner) else {
|
||||
return Ok(None);
|
||||
};
|
||||
let (pending, (subresource_enabled, subresource_resource_type), page_update_required) =
|
||||
owner.reset_fetch_config_for_session_and_drain_pending_state(session_id);
|
||||
owner
|
||||
.reset_fetch_config_for_session_and_drain_pending_state(command_owner.session_id());
|
||||
let page_command = if page_update_required
|
||||
&& let Some(page) = owner.runtime_slot_mut().loaded_page_mut()
|
||||
{
|
||||
@@ -1253,13 +1173,12 @@ impl CdpConnection {
|
||||
Ok(Some((pending, page_command)))
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_fetch_state_for_route(
|
||||
pub(crate) fn take_pending_fetch_state_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<SessionOwnerPendingFetchState> {
|
||||
Some(
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)?
|
||||
self.target_session_owner_mut_for_owner(owner)?
|
||||
.drain_fetch_pending_state(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -356,23 +356,17 @@ impl CdpConnection {
|
||||
data_type: DevToolsNetworkDataType,
|
||||
encoded_data_size: usize,
|
||||
) -> Vec<String> {
|
||||
self.network_data_collector_ids_for_route_body(
|
||||
session_id,
|
||||
None,
|
||||
data_type,
|
||||
encoded_data_size,
|
||||
)
|
||||
let owner = crate::conn::CommandOwnerScope::capture(self, session_id);
|
||||
self.network_data_collector_ids_for_owner_body(&owner, data_type, encoded_data_size)
|
||||
}
|
||||
|
||||
pub(crate) fn network_data_collector_ids_for_route_body(
|
||||
pub(crate) fn network_data_collector_ids_for_owner_body(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
data_type: DevToolsNetworkDataType,
|
||||
encoded_data_size: usize,
|
||||
) -> Vec<String> {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
self.target_owner_identity_for_route(session_id, owner_route)
|
||||
let Some((browser_context_id, target_id)) = self.target_owner_identity_for_owner(owner)
|
||||
else {
|
||||
return Vec::new();
|
||||
};
|
||||
@@ -445,10 +439,9 @@ impl CdpConnection {
|
||||
.is_ok_and(|runtime_slot| runtime_slot.has_network_event_listeners())
|
||||
}
|
||||
|
||||
pub(crate) fn network_backlog_prepared_delivery_for_route(
|
||||
pub(crate) fn network_backlog_prepared_delivery_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
trigger_session_id: Option<&str>,
|
||||
primary_session_id: Option<&str>,
|
||||
preferred_request_id: Option<NetworkBacklogPreferredRequestId<'_>>,
|
||||
@@ -456,7 +449,7 @@ impl CdpConnection {
|
||||
let mut network_request_id_allocator =
|
||||
std::mem::take(&mut self.network_request_id_allocator);
|
||||
let result = self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.map(|runtime_slot| {
|
||||
runtime_slot.network_backlog_prepared_delivery(
|
||||
@@ -490,10 +483,9 @@ impl CdpConnection {
|
||||
result
|
||||
}
|
||||
|
||||
pub(crate) fn pending_network_backlog_delivery_snapshot_for_route(
|
||||
pub(crate) fn pending_network_backlog_delivery_snapshot_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
trigger_session_id: Option<&str>,
|
||||
primary_session_id: Option<&str>,
|
||||
preferred_request_id: Option<NetworkBacklogPreferredRequestId<'_>>,
|
||||
@@ -501,7 +493,7 @@ impl CdpConnection {
|
||||
let mut network_request_id_allocator =
|
||||
std::mem::take(&mut self.network_request_id_allocator);
|
||||
let result = self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|runtime_slot| {
|
||||
runtime_slot.pending_network_backlog_delivery_snapshot(
|
||||
@@ -519,51 +511,49 @@ impl CdpConnection {
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
) -> Vec<Option<String>> {
|
||||
self.network_event_session_ids_for_route(session_id, None)
|
||||
let owner = crate::conn::CommandOwnerScope::capture(self, session_id);
|
||||
self.network_event_session_ids_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn network_event_session_ids_for_route(
|
||||
pub(crate) fn network_event_session_ids_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
) -> Vec<Option<String>> {
|
||||
let Ok(runtime_slot) = self.runtime_session_owner_slot_for_route(session_id, owner_route)
|
||||
else {
|
||||
return vec![session_id.map(str::to_owned)];
|
||||
let Ok(runtime_slot) = self.runtime_session_owner_slot_for_owner(owner) else {
|
||||
return vec![owner.session_id().map(str::to_owned)];
|
||||
};
|
||||
let primary_session_id =
|
||||
self.runtime_session_owner_primary_session_id_for_route(session_id, owner_route);
|
||||
runtime_slot.network_event_session_ids(session_id, primary_session_id.as_deref())
|
||||
let primary_session_id = self.runtime_session_owner_primary_session_id_for_owner(owner);
|
||||
runtime_slot.network_event_session_ids(owner.session_id(), primary_session_id.as_deref())
|
||||
}
|
||||
|
||||
pub(crate) fn enable_network_listener_for_session_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
) -> bool {
|
||||
self.set_network_listener_enabled_for_route(session_id, None, true)
|
||||
let owner = crate::conn::CommandOwnerScope::capture(self, session_id);
|
||||
self.set_network_listener_enabled_for_owner(&owner, true)
|
||||
}
|
||||
|
||||
fn set_network_listener_enabled_for_route(
|
||||
fn set_network_listener_enabled_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
enabled: bool,
|
||||
) -> bool {
|
||||
if let Some(session_id) = session_id
|
||||
if let Some(session_id) = owner.session_id()
|
||||
&& let Some(target) = self.service_worker_target_for_session_mut(Some(session_id))
|
||||
{
|
||||
return target.set_network_enabled(session_id, enabled);
|
||||
}
|
||||
if let Some(session_id) = session_id
|
||||
if let Some(session_id) = owner.session_id()
|
||||
&& let Some(target) = self.dedicated_worker_target_for_session_mut(Some(session_id))
|
||||
{
|
||||
return target.set_network_enabled(session_id, enabled);
|
||||
}
|
||||
self.with_target_session_owner_mut_for_route(session_id, owner_route, |owner| {
|
||||
self.with_target_session_owner_mut_for_owner(owner, |resolved| {
|
||||
if enabled {
|
||||
owner.enable_listener()
|
||||
resolved.enable_listener()
|
||||
} else {
|
||||
owner.disable_listener()
|
||||
resolved.disable_listener()
|
||||
}
|
||||
})
|
||||
.unwrap_or(false)
|
||||
@@ -573,14 +563,20 @@ impl CdpConnection {
|
||||
let Some(route) = self.target_session_route_for_target_id(target_id) else {
|
||||
return false;
|
||||
};
|
||||
self.set_network_listener_enabled_for_route(None, Some(&route), true)
|
||||
self.set_network_listener_enabled_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_route(route),
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn disable_network_listener_for_target(&mut self, target_id: &str) -> bool {
|
||||
let Some(route) = self.target_session_route_for_target_id(target_id) else {
|
||||
return false;
|
||||
};
|
||||
self.set_network_listener_enabled_for_route(None, Some(&route), false)
|
||||
self.set_network_listener_enabled_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_route(route),
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn set_global_cache_disabled(&mut self, cache_disabled: bool) {
|
||||
@@ -611,7 +607,8 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
) -> bool {
|
||||
self.set_network_listener_enabled_for_route(session_id, None, false)
|
||||
let owner = crate::conn::CommandOwnerScope::capture(self, session_id);
|
||||
self.set_network_listener_enabled_for_owner(&owner, false)
|
||||
}
|
||||
|
||||
pub(crate) fn start_set_cache_disabled_for_session_owner(
|
||||
@@ -676,13 +673,12 @@ impl CdpConnection {
|
||||
owner.start_set_extra_http_headers(extra_headers)
|
||||
}
|
||||
|
||||
pub(crate) fn start_set_target_extra_http_headers_for_route(
|
||||
pub(crate) fn start_set_target_extra_http_headers_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
command_owner: &crate::conn::CommandOwnerScope,
|
||||
extra_headers: Vec<(String, String)>,
|
||||
) -> Result<Option<PendingPageCommand>, String> {
|
||||
let Some(owner) = self.target_session_owner_mut_for_route(session_id, owner_route) else {
|
||||
let Some(owner) = self.target_session_owner_mut_for_owner(command_owner) else {
|
||||
return Err("BrowserContextNotLoaded".to_owned());
|
||||
};
|
||||
owner.start_set_target_extra_http_headers(extra_headers)
|
||||
@@ -708,10 +704,9 @@ impl CdpConnection {
|
||||
owner.start_replay_effective_network_request_policy()
|
||||
}
|
||||
|
||||
pub(crate) fn start_set_base_user_agent_override_for_route(
|
||||
pub(crate) fn start_set_base_user_agent_override_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
command_owner: &crate::conn::CommandOwnerScope,
|
||||
user_agent: Option<String>,
|
||||
) -> Result<Option<PendingPageCommand>, String> {
|
||||
let browser_identity = user_agent.as_ref().map(|user_agent| {
|
||||
@@ -720,22 +715,21 @@ impl CdpConnection {
|
||||
self.base_browser_identity.accept_language(),
|
||||
)
|
||||
});
|
||||
if owner_route.is_none()
|
||||
&& let Some(result) =
|
||||
self.start_set_non_page_browser_identity_override(session_id, browser_identity)
|
||||
{
|
||||
if let Some(result) = self.start_set_non_page_browser_identity_override(
|
||||
command_owner.session_id(),
|
||||
browser_identity,
|
||||
) {
|
||||
return result;
|
||||
}
|
||||
|
||||
let fallback_identity = self.base_browser_identity.clone();
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Some(mut owner) = self.target_session_owner_mut_for_owner(command_owner) else {
|
||||
return Err("BrowserContextNotLoaded".to_owned());
|
||||
};
|
||||
if !owner.set_base_user_agent_override(user_agent, &fallback_identity) {
|
||||
return Err("BrowserContextNotLoaded".to_owned());
|
||||
}
|
||||
self.start_rebuild_resource_runtime_for_route(session_id, owner_route)
|
||||
self.start_rebuild_resource_runtime_for_owner(command_owner)
|
||||
}
|
||||
|
||||
fn start_set_non_page_browser_identity_override(
|
||||
@@ -833,9 +827,9 @@ impl CdpConnection {
|
||||
upload_throughput: f64,
|
||||
connection_type: Option<String>,
|
||||
) -> Result<Option<PendingPageCommand>, String> {
|
||||
self.start_set_emulated_network_conditions_for_route(
|
||||
session_id,
|
||||
None,
|
||||
let owner = crate::conn::CommandOwnerScope::capture(self, session_id);
|
||||
self.start_set_emulated_network_conditions_for_owner(
|
||||
&owner,
|
||||
offline,
|
||||
latency,
|
||||
download_throughput,
|
||||
@@ -844,17 +838,16 @@ impl CdpConnection {
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn start_set_emulated_network_conditions_for_route(
|
||||
pub(crate) fn start_set_emulated_network_conditions_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
command_owner: &crate::conn::CommandOwnerScope,
|
||||
offline: bool,
|
||||
latency: f64,
|
||||
download_throughput: f64,
|
||||
upload_throughput: f64,
|
||||
connection_type: Option<String>,
|
||||
) -> Result<Option<PendingPageCommand>, String> {
|
||||
let Some(owner) = self.target_session_owner_mut_for_route(session_id, owner_route) else {
|
||||
let Some(owner) = self.target_session_owner_mut_for_owner(command_owner) else {
|
||||
return Err("BrowserContextNotLoaded".to_owned());
|
||||
};
|
||||
owner.start_set_emulated_network_conditions(
|
||||
@@ -921,13 +914,19 @@ mod tests {
|
||||
conn.browser_context = Some(browser_context);
|
||||
|
||||
let (active_fetch_id, active_network_request_id) = conn
|
||||
.allocate_pending_subresource_fetch_request_ids_for_route(Some("SID-active"), None)
|
||||
.allocate_pending_subresource_fetch_request_ids_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-active"),
|
||||
)
|
||||
.expect("active owner should allocate request ids");
|
||||
let (background_fetch_id, background_network_request_id) = conn
|
||||
.allocate_pending_subresource_fetch_request_ids_for_route(Some("SID-background"), None)
|
||||
.allocate_pending_subresource_fetch_request_ids_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-background"),
|
||||
)
|
||||
.expect("background owner should allocate request ids");
|
||||
let (second_active_fetch_id, second_active_network_request_id) = conn
|
||||
.allocate_pending_subresource_fetch_request_ids_for_route(Some("SID-active"), None)
|
||||
.allocate_pending_subresource_fetch_request_ids_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-active"),
|
||||
)
|
||||
.expect("active owner should allocate a second request id");
|
||||
|
||||
assert_eq!(active_fetch_id, "INT-SUB-1");
|
||||
|
||||
@@ -475,7 +475,8 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
) -> SessionOwnerAuditsEnableResult {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| owner.enable_audits())
|
||||
.unwrap_or({
|
||||
if accepts_without_target {
|
||||
@@ -487,7 +488,8 @@ impl CdpConnection {
|
||||
}
|
||||
|
||||
pub(crate) fn disable_audits_for_session_owner(&mut self, session_id: Option<&str>) -> bool {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| owner.disable_audits())
|
||||
.unwrap_or(accepts_without_target)
|
||||
}
|
||||
@@ -496,15 +498,12 @@ impl CdpConnection {
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
) -> Option<bool> {
|
||||
self.page_domain_enabled_for_route(session_id, None)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.page_domain_enabled_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn page_domain_enabled_for_route(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
) -> Option<bool> {
|
||||
self.target_session_owner_ref_for_route(session_id, owner_route)
|
||||
pub(crate) fn page_domain_enabled_for_owner(&self, owner: &CommandOwnerScope) -> Option<bool> {
|
||||
self.target_session_owner_ref_for_owner(owner)
|
||||
.and_then(|owner| owner.devtools_session_state())
|
||||
.map(devtools_session_page_domain_enabled)
|
||||
}
|
||||
@@ -536,10 +535,9 @@ impl CdpConnection {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn record_main_document_resource_body_for_route(
|
||||
pub(crate) fn record_main_document_resource_body_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
frame_id: String,
|
||||
loader_id: String,
|
||||
url: url::Url,
|
||||
@@ -547,7 +545,7 @@ impl CdpConnection {
|
||||
from_cache: bool,
|
||||
body: crate::conn::CapturedBody,
|
||||
) -> bool {
|
||||
self.with_target_owner_state_for_route_mut(session_id, owner_route, |owner_state| {
|
||||
self.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
owner_state.page_resource_store.record_main_document_body(
|
||||
frame_id,
|
||||
loader_id,
|
||||
@@ -571,27 +569,23 @@ impl CdpConnection {
|
||||
body: Option<crate::conn::CapturedBody>,
|
||||
) -> bool {
|
||||
if self
|
||||
.runtime_session_owner_slot_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(TargetRuntimeSlot::committed_document_loader_id)
|
||||
!= Some(loader_id.as_str())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
self.with_target_owner_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner_state| {
|
||||
owner_state.page_resource_store.commit_main_document(
|
||||
frame_id,
|
||||
loader_id,
|
||||
url,
|
||||
response_headers,
|
||||
from_cache,
|
||||
body,
|
||||
);
|
||||
},
|
||||
)
|
||||
self.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
owner_state.page_resource_store.commit_main_document(
|
||||
frame_id,
|
||||
loader_id,
|
||||
url,
|
||||
response_headers,
|
||||
from_cache,
|
||||
body,
|
||||
);
|
||||
})
|
||||
.is_some()
|
||||
}
|
||||
|
||||
@@ -623,15 +617,11 @@ impl CdpConnection {
|
||||
owner: &CommandOwnerScope,
|
||||
loader_id: &str,
|
||||
) {
|
||||
let _ = self.with_target_owner_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner_state| {
|
||||
owner_state
|
||||
.page_resource_store
|
||||
.discard_uncommitted_loader(loader_id);
|
||||
},
|
||||
);
|
||||
let _ = self.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
owner_state
|
||||
.page_resource_store
|
||||
.discard_uncommitted_loader(loader_id);
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn set_page_domain_enabled_for_session_owner(
|
||||
@@ -650,7 +640,7 @@ impl CdpConnection {
|
||||
.with_target_session_owner_mut(session_id, |owner| {
|
||||
owner.set_page_domain_enabled(enabled, subscription_generation)
|
||||
})
|
||||
.unwrap_or_else(|| self.accepts_unmaterialized_page_command(session_id, None));
|
||||
.unwrap_or_else(|| self.accepts_unmaterialized_page_command_for_session(session_id));
|
||||
if handled && let Some(browser_context_id) = owner_browser_context_id.as_deref() {
|
||||
self.sync_javascript_dialog_handler_enabled_for_browser_context(browser_context_id);
|
||||
}
|
||||
@@ -682,33 +672,23 @@ impl CdpConnection {
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
enabled: bool,
|
||||
) -> bool {
|
||||
let accepts_without_target = self
|
||||
.accepts_unmaterialized_page_command(owner.session_id(), owner.session_owner_route());
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(owner);
|
||||
let handled = self
|
||||
.with_target_session_owner_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner| owner.set_console_enabled(enabled),
|
||||
)
|
||||
.with_target_session_owner_mut_for_owner(owner, |owner| {
|
||||
owner.set_console_enabled(enabled)
|
||||
})
|
||||
.unwrap_or(accepts_without_target);
|
||||
if handled {
|
||||
let renderer_console_agent_owns_page_console_api_events = enabled
|
||||
&& self
|
||||
.runtime_session_owner_slot_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_for_owner(owner)
|
||||
.is_ok_and(|slot| slot.has_loaded_page());
|
||||
let _ = self.with_target_devtools_session_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|state| {
|
||||
state
|
||||
.console_output_session_state
|
||||
.renderer_console_agent_owns_page_console_api_events =
|
||||
renderer_console_agent_owns_page_console_api_events;
|
||||
},
|
||||
);
|
||||
let _ = self.with_target_devtools_session_state_for_owner_mut(owner, |state| {
|
||||
state
|
||||
.console_output_session_state
|
||||
.renderer_console_agent_owns_page_console_api_events =
|
||||
renderer_console_agent_owns_page_console_api_events;
|
||||
});
|
||||
}
|
||||
handled
|
||||
}
|
||||
@@ -725,21 +705,17 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
) -> bool {
|
||||
let accepts_without_target = self
|
||||
.accepts_unmaterialized_page_command(owner.session_id(), owner.session_owner_route());
|
||||
self.with_target_session_owner_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner| owner.clear_console_messages(),
|
||||
)
|
||||
.unwrap_or(accepts_without_target)
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(owner);
|
||||
self.with_target_session_owner_mut_for_owner(owner, |owner| owner.clear_console_messages())
|
||||
.unwrap_or(accepts_without_target)
|
||||
}
|
||||
|
||||
pub(crate) fn enable_log_for_session_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
) -> SessionOwnerLogEnableResult {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| owner.enable_log())
|
||||
.unwrap_or({
|
||||
if accepts_without_target {
|
||||
@@ -751,13 +727,15 @@ impl CdpConnection {
|
||||
}
|
||||
|
||||
pub(crate) fn disable_log_for_session_owner(&mut self, session_id: Option<&str>) -> bool {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| owner.disable_log())
|
||||
.unwrap_or(accepts_without_target)
|
||||
}
|
||||
|
||||
pub(crate) fn clear_log_for_session_owner(&mut self, session_id: Option<&str>) -> bool {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| owner.clear_log())
|
||||
.unwrap_or(accepts_without_target)
|
||||
}
|
||||
@@ -786,18 +764,17 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
enabled: bool,
|
||||
) -> bool {
|
||||
self.set_page_file_chooser_opened_event_enabled_for_route(session_id, None, enabled)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.set_page_file_chooser_opened_event_enabled_for_owner(&owner, enabled)
|
||||
}
|
||||
|
||||
fn set_page_file_chooser_opened_event_enabled_for_route(
|
||||
fn set_page_file_chooser_opened_event_enabled_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
enabled: bool,
|
||||
) -> bool {
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command(session_id, owner_route);
|
||||
self.with_target_session_owner_mut_for_route(session_id, owner_route, |owner| {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(owner);
|
||||
self.with_target_session_owner_mut_for_owner(owner, |owner| {
|
||||
owner.set_page_file_chooser_opened_event_enabled(enabled)
|
||||
})
|
||||
.unwrap_or(accepts_without_target)
|
||||
@@ -812,7 +789,7 @@ impl CdpConnection {
|
||||
.map(|(browser_context_id, _)| browser_context_id);
|
||||
let handled = self
|
||||
.with_target_session_owner_mut(session_id, |owner| owner.disable_page_domain())
|
||||
.unwrap_or_else(|| self.accepts_unmaterialized_page_command(session_id, None));
|
||||
.unwrap_or_else(|| self.accepts_unmaterialized_page_command_for_session(session_id));
|
||||
if handled && let Some(browser_context_id) = owner_browser_context_id.as_deref() {
|
||||
self.sync_javascript_dialog_handler_enabled_for_browser_context(browser_context_id);
|
||||
}
|
||||
@@ -823,14 +800,20 @@ impl CdpConnection {
|
||||
let Some(route) = self.target_session_route_for_target_id(target_id) else {
|
||||
return false;
|
||||
};
|
||||
self.set_page_file_chooser_opened_event_enabled_for_route(None, Some(&route), true)
|
||||
self.set_page_file_chooser_opened_event_enabled_for_owner(
|
||||
&CommandOwnerScope::for_route(route),
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn disable_file_dialog_opened_listener_for_target(&mut self, target_id: &str) -> bool {
|
||||
let Some(route) = self.target_session_route_for_target_id(target_id) else {
|
||||
return false;
|
||||
};
|
||||
self.set_page_file_chooser_opened_event_enabled_for_route(None, Some(&route), false)
|
||||
self.set_page_file_chooser_opened_event_enabled_for_owner(
|
||||
&CommandOwnerScope::for_route(route),
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn set_page_lifecycle_events_enabled_for_session_owner(
|
||||
@@ -838,7 +821,8 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
enabled: bool,
|
||||
) -> PageLifecycleEventsEnableResult {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| {
|
||||
owner.set_page_lifecycle_events_enabled(enabled)
|
||||
})
|
||||
@@ -858,7 +842,8 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
enabled: bool,
|
||||
) -> bool {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| {
|
||||
owner.set_page_bypass_csp_enabled(enabled)
|
||||
})
|
||||
@@ -870,7 +855,8 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
font_families: serde_json::Map<String, Value>,
|
||||
) -> bool {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| {
|
||||
owner.set_page_font_families(font_families)
|
||||
})
|
||||
@@ -882,7 +868,8 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
enabled: bool,
|
||||
) -> bool {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| {
|
||||
owner.set_page_intercept_file_chooser_dialog_enabled(enabled)
|
||||
})
|
||||
@@ -915,27 +902,25 @@ impl CdpConnection {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub(crate) fn begin_page_screencast_capture_for_route(
|
||||
pub(crate) fn begin_page_screencast_capture_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
generation: i32,
|
||||
) -> Option<bool> {
|
||||
Some(
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)?
|
||||
self.target_session_owner_mut_for_owner(owner)?
|
||||
.begin_page_screencast_capture(generation),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn complete_page_screencast_capture_for_route(
|
||||
pub(crate) fn complete_page_screencast_capture_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
generation: i32,
|
||||
frame_emitted: bool,
|
||||
) -> Option<bool> {
|
||||
Some(
|
||||
self.target_session_owner_mut_for_route(session_id, owner_route)?
|
||||
self.target_session_owner_mut_for_owner(owner)?
|
||||
.complete_page_screencast_capture(generation, frame_emitted),
|
||||
)
|
||||
}
|
||||
@@ -961,7 +946,8 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
time_domain: PerformanceTimeDomain,
|
||||
) -> Option<bool> {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| {
|
||||
owner.enable_performance(time_domain)
|
||||
})
|
||||
@@ -972,7 +958,8 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
) -> bool {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| owner.disable_performance())
|
||||
.unwrap_or(accepts_without_target)
|
||||
}
|
||||
@@ -982,7 +969,8 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
time_domain: PerformanceTimeDomain,
|
||||
) -> Option<bool> {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
self.with_target_session_owner_mut(session_id, |owner| {
|
||||
owner.set_performance_time_domain(time_domain)
|
||||
})
|
||||
|
||||
@@ -56,7 +56,8 @@ impl CdpConnection {
|
||||
session_id: Option<&str>,
|
||||
enabled: bool,
|
||||
) -> SessionOwnerInspectorEnableResult {
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(session_id, None);
|
||||
let accepts_without_target =
|
||||
self.accepts_unmaterialized_page_command_for_session(session_id);
|
||||
let target_crashed = self
|
||||
.target_owner_state_for_session(session_id)
|
||||
.is_some_and(|owner_state| owner_state.target_crash_state.is_crashed());
|
||||
@@ -90,14 +91,11 @@ impl CdpConnection {
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
enabled: bool,
|
||||
) -> SessionOwnerRuntimeFrontendEnableResult {
|
||||
let accepts_without_target = self
|
||||
.accepts_unmaterialized_page_command(owner.session_id(), owner.session_owner_route());
|
||||
let accepts_without_target = self.accepts_unmaterialized_page_command(owner);
|
||||
let result = self
|
||||
.with_target_session_owner_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner| owner.set_runtime_frontend_enabled(enabled),
|
||||
)
|
||||
.with_target_session_owner_mut_for_owner(owner, |owner| {
|
||||
owner.set_runtime_frontend_enabled(enabled)
|
||||
})
|
||||
.unwrap_or({
|
||||
if accepts_without_target {
|
||||
SessionOwnerRuntimeFrontendEnableResult::Handled
|
||||
@@ -108,11 +106,9 @@ impl CdpConnection {
|
||||
if matches!(result, SessionOwnerRuntimeFrontendEnableResult::Handled) && !enabled {
|
||||
let _ = self
|
||||
.set_renderer_runtime_agent_owns_page_console_api_events_for_owner(owner, false);
|
||||
let _ = self.with_target_devtools_session_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|state| state.clear_child_default_context_emission_state(),
|
||||
);
|
||||
let _ = self.with_target_devtools_session_state_for_owner_mut(owner, |state| {
|
||||
state.clear_child_default_context_emission_state()
|
||||
});
|
||||
}
|
||||
result
|
||||
}
|
||||
@@ -134,27 +130,22 @@ impl CdpConnection {
|
||||
}
|
||||
let owns = owns
|
||||
&& self
|
||||
.runtime_session_owner_slot_for_route(session_id, owner.session_owner_route())
|
||||
.runtime_session_owner_slot_for_owner(owner)
|
||||
.is_ok_and(|slot| slot.has_loaded_page());
|
||||
self.with_target_devtools_session_state_for_route_mut(
|
||||
session_id,
|
||||
owner.session_owner_route(),
|
||||
|state| {
|
||||
state
|
||||
.console_output_session_state
|
||||
.renderer_runtime_agent_owns_page_console_api_events = owns;
|
||||
},
|
||||
)
|
||||
self.with_target_devtools_session_state_for_owner_mut(owner, |state| {
|
||||
state
|
||||
.console_output_session_state
|
||||
.renderer_runtime_agent_owns_page_console_api_events = owns;
|
||||
})
|
||||
.is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn merge_v8_inspector_session_state_for_route(
|
||||
pub(crate) fn merge_v8_inspector_session_state_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &crate::conn::CommandOwnerScope,
|
||||
state: V8InspectorSessionState,
|
||||
) -> bool {
|
||||
self.with_target_devtools_session_state_for_route_mut(session_id, owner_route, |session| {
|
||||
self.with_target_devtools_session_state_for_owner_mut(owner, |session| {
|
||||
session.inspector_session_state.v8_state = Some(state);
|
||||
})
|
||||
.is_some()
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#[cfg(test)]
|
||||
use crate::conn::BrowserContext;
|
||||
use crate::conn::{CdpConnection, CdpSessionRoute, PageTargetHost};
|
||||
use crate::conn::{CdpConnection, CdpSessionRoute, CommandOwnerScope, PageTargetHost};
|
||||
use moli_page_types::DevToolsSessionKey;
|
||||
|
||||
pub(super) struct TargetSessionOwner {
|
||||
@@ -13,34 +11,23 @@ impl CdpConnection {
|
||||
/// Some generated Page-domain agents acknowledge enable/disable commands
|
||||
/// before a Page host exists. Keep that protocol behavior at the command
|
||||
/// boundary instead of manufacturing an owner that does not own a Page.
|
||||
pub(super) fn accepts_unmaterialized_page_command(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
) -> bool {
|
||||
if session_id.is_some() {
|
||||
pub(super) fn accepts_unmaterialized_page_command(&self, owner: &CommandOwnerScope) -> bool {
|
||||
if owner.session_id().is_some() {
|
||||
return false;
|
||||
}
|
||||
match owner_route {
|
||||
match owner.explicit_route() {
|
||||
Some(CdpSessionRoute::Browser | CdpSessionRoute::BrowserContext { .. }) => true,
|
||||
Some(_) => false,
|
||||
None => self
|
||||
.browser_context
|
||||
.as_ref()
|
||||
.and_then(|browser_context| browser_context.active_target_id())
|
||||
.is_none(),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn with_background_target_session<R>(
|
||||
&mut self,
|
||||
pub(super) fn accepts_unmaterialized_page_command_for_session(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
f: impl FnOnce(&mut BrowserContext, &str) -> R,
|
||||
) -> Option<R> {
|
||||
let (browser_context_id, target_id) = self.background_target_route(session_id)?;
|
||||
let browser_context = self.browser_context_by_id_mut(&browser_context_id)?;
|
||||
Some(f(browser_context, &target_id))
|
||||
) -> bool {
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.accepts_unmaterialized_page_command(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn mutate_target_page_state_for_session(
|
||||
@@ -57,32 +44,16 @@ impl CdpConnection {
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
) -> Option<TargetSessionOwner> {
|
||||
self.target_session_owner_for_route(session_id, None)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.target_session_owner_for_owner(&owner)
|
||||
}
|
||||
|
||||
/// Resolves target ownership from an explicit command route. A concrete
|
||||
/// session always resolves through the session registry; `owner_route`
|
||||
/// selects the owner of an internal command without a CDP session.
|
||||
pub(super) fn target_session_owner_for_route(
|
||||
/// Resolves target ownership from the command's single authority.
|
||||
pub(super) fn target_session_owner_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<TargetSessionOwner> {
|
||||
let route = match session_id {
|
||||
Some(session_id) => self.session_route(Some(session_id))?,
|
||||
None => match owner_route {
|
||||
Some(route) => route.clone(),
|
||||
None => {
|
||||
let browser_context = self.browser_context.as_ref()?;
|
||||
let target_id = browser_context.active_target_id()?;
|
||||
return Some(TargetSessionOwner {
|
||||
browser_context_id: browser_context.id.clone(),
|
||||
target_id: target_id.to_owned(),
|
||||
session_key: DevToolsSessionKey::Primary,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
let route = owner.resolve_route(self)?;
|
||||
|
||||
match route {
|
||||
CdpSessionRoute::Browser => {
|
||||
@@ -128,6 +99,7 @@ impl CdpConnection {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conn::BrowserContext;
|
||||
|
||||
#[test]
|
||||
fn empty_browser_context_does_not_materialize_a_page_owner() {
|
||||
@@ -135,8 +107,12 @@ mod tests {
|
||||
conn.browser_context = Some(BrowserContext::new("BID-empty-owner".to_owned()));
|
||||
|
||||
assert!(conn.target_session_owner(None).is_none());
|
||||
assert!(conn.accepts_unmaterialized_page_command(None, None));
|
||||
assert!(!conn.accepts_unmaterialized_page_command(Some("SID-missing"), None));
|
||||
assert!(conn.accepts_unmaterialized_page_command(&CommandOwnerScope::capture(&conn, None)));
|
||||
assert!(
|
||||
!conn.accepts_unmaterialized_page_command(&CommandOwnerScope::for_session(
|
||||
"SID-missing"
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -152,10 +128,8 @@ mod tests {
|
||||
session_key: DevToolsSessionKey::Primary,
|
||||
};
|
||||
|
||||
assert!(
|
||||
conn.target_session_owner_for_route(None, Some(&stale_route))
|
||||
.is_none()
|
||||
);
|
||||
assert!(!conn.accepts_unmaterialized_page_command(None, Some(&stale_route)));
|
||||
let owner = CommandOwnerScope::for_route(stale_route);
|
||||
assert!(conn.target_session_owner_for_owner(&owner).is_none());
|
||||
assert!(!conn.accepts_unmaterialized_page_command(&owner));
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,18 +22,6 @@ impl CommandOwnerScope {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn capture_for_route(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
) -> Self {
|
||||
match (session_id, owner_route) {
|
||||
(Some(session_id), _) => Self::for_session(session_id),
|
||||
(None, Some(route)) => Self::for_route(route.clone()),
|
||||
(None, None) => Self::capture(conn, None),
|
||||
}
|
||||
}
|
||||
|
||||
fn capture_default_route(conn: &CdpConnection) -> CdpSessionRoute {
|
||||
let Some(browser_context) = conn.browser_context.as_ref() else {
|
||||
return CdpSessionRoute::Browser;
|
||||
@@ -90,17 +78,23 @@ impl CommandOwnerScope {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the explicit route captured for a command without a session.
|
||||
/// Resolves this command's single authority to its current CDP route.
|
||||
///
|
||||
/// A concrete CDP session remains authoritative through `session_id`; the
|
||||
/// route freezes Chromium's primary Page attachment at command admission
|
||||
/// whenever no more explicit route was supplied. `Browser` and
|
||||
/// `BrowserContext` remain explicit authorities rather than a missing
|
||||
/// owner that can silently acquire a later active Page.
|
||||
pub(crate) fn session_owner_route(&self) -> Option<&CdpSessionRoute> {
|
||||
/// Session owners resolve through the attachment registry. Route owners
|
||||
/// retain the exact route captured at command admission. Callers therefore
|
||||
/// cannot express the old invalid combinations of an absent authority or
|
||||
/// both a session and an explicit route.
|
||||
pub(crate) fn resolve_route(&self, conn: &CdpConnection) -> Option<CdpSessionRoute> {
|
||||
match &self.identity {
|
||||
CommandOwnerIdentity::Session(session_id) => conn.session_route(Some(session_id)),
|
||||
CommandOwnerIdentity::Route(route) => Some(route.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn explicit_route(&self) -> Option<&CdpSessionRoute> {
|
||||
match &self.identity {
|
||||
CommandOwnerIdentity::Route(route) => Some(route),
|
||||
CommandOwnerIdentity::Session(_) => None,
|
||||
CommandOwnerIdentity::Route(route) => Some(route),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,7 +102,19 @@ impl CommandOwnerScope {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conn::BrowserContext;
|
||||
use crate::conn::{BrowserContext, PageTargetHost};
|
||||
use crate::devtools_runtime::{
|
||||
DevToolsCommandContext, DevToolsProtocol, DevToolsSessionId, DevToolsTargetId,
|
||||
};
|
||||
|
||||
fn page_context(session_id: &str, target_id: &str) -> DevToolsCommandContext {
|
||||
DevToolsCommandContext {
|
||||
protocol: DevToolsProtocol::Cdp,
|
||||
session_id: Some(DevToolsSessionId::from(session_id)),
|
||||
target_id: Some(DevToolsTargetId::from(target_id)),
|
||||
browser_context_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn root_page_scope_freezes_the_concrete_active_target() {
|
||||
@@ -124,7 +130,7 @@ mod tests {
|
||||
.set_active_target_id("TID-replacement");
|
||||
|
||||
assert_eq!(
|
||||
conn.target_owner_identity_for_route(scope.session_id(), scope.session_owner_route(),),
|
||||
conn.target_owner_identity_for_owner(&scope,),
|
||||
Some(("BID-scope".to_owned(), Some("TID-original".to_owned())))
|
||||
);
|
||||
}
|
||||
@@ -135,7 +141,7 @@ mod tests {
|
||||
|
||||
let scope = CommandOwnerScope::capture(&conn, None);
|
||||
|
||||
assert_eq!(scope.session_owner_route(), Some(&CdpSessionRoute::Browser));
|
||||
assert_eq!(scope.explicit_route(), Some(&CdpSessionRoute::Browser));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -146,10 +152,70 @@ mod tests {
|
||||
let scope = CommandOwnerScope::capture(&conn, None);
|
||||
|
||||
assert_eq!(
|
||||
scope.session_owner_route(),
|
||||
scope.explicit_route(),
|
||||
Some(&CdpSessionRoute::BrowserContext {
|
||||
browser_context_id: "BID-empty".to_owned(),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_target_preserves_matching_auxiliary_session_authority() {
|
||||
let mut conn = CdpConnection::default();
|
||||
let mut browser_context = BrowserContext::new_with_page_for_test("BID-owner", "TID-owner");
|
||||
browser_context.attach_active_session("SID-primary");
|
||||
assert!(
|
||||
browser_context
|
||||
.assign_auxiliary_session_to_target("TID-owner", "SID-auxiliary".to_owned(),)
|
||||
);
|
||||
conn.browser_context = Some(browser_context);
|
||||
|
||||
let owner = conn
|
||||
.command_owner_scope_for_devtools_context(&page_context("SID-auxiliary", "TID-owner"))
|
||||
.expect("matching auxiliary attachment should own the command");
|
||||
|
||||
assert_eq!(owner.session_id(), Some("SID-auxiliary"));
|
||||
assert!(owner.explicit_route().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_target_routes_protocol_neutral_session_and_rejects_wrong_cdp_attachment() {
|
||||
let mut conn = CdpConnection::default();
|
||||
let mut browser_context =
|
||||
BrowserContext::new_with_page_for_test("BID-owner", "TID-primary");
|
||||
browser_context.attach_active_session("SID-primary");
|
||||
assert!(
|
||||
browser_context.insert_page_target_host(PageTargetHost::with_url(
|
||||
"TID-background".to_owned(),
|
||||
Some("SID-background".to_owned()),
|
||||
"about:blank".to_owned(),
|
||||
))
|
||||
);
|
||||
conn.browser_context = Some(browser_context);
|
||||
|
||||
let protocol_neutral = conn
|
||||
.command_owner_scope_for_devtools_context(&page_context(
|
||||
"webdriver-session",
|
||||
"TID-background",
|
||||
))
|
||||
.expect("non-CDP session should use its explicit target");
|
||||
assert_eq!(protocol_neutral.session_id(), None);
|
||||
assert_eq!(
|
||||
protocol_neutral.explicit_route(),
|
||||
Some(&CdpSessionRoute::PageTarget {
|
||||
browser_context_id: "BID-owner".to_owned(),
|
||||
target_id: "TID-background".to_owned(),
|
||||
session_key: moli_page_types::DevToolsSessionKey::Primary,
|
||||
})
|
||||
);
|
||||
|
||||
assert!(
|
||||
conn.command_owner_scope_for_devtools_context(&page_context(
|
||||
"SID-primary",
|
||||
"TID-background",
|
||||
))
|
||||
.is_none(),
|
||||
"a real CDP attachment cannot address another target",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,10 +452,7 @@ impl CdpConnection {
|
||||
}
|
||||
let mut listener_events = Vec::new();
|
||||
if has_default_bidi_channel_preload_script
|
||||
|| self.target_owner_has_bidi_channel_preload_script_for_route(
|
||||
command_owner.session_id(),
|
||||
command_owner.session_owner_route(),
|
||||
)
|
||||
|| self.target_owner_has_bidi_channel_preload_script_for_owner(&command_owner)
|
||||
{
|
||||
let mut execution_context_ids = initial_runtime_execution_context_ids;
|
||||
// Target lifecycle creation can materialize initial about:blank without Runtime.enable;
|
||||
|
||||
@@ -629,7 +629,9 @@ async fn devtools_script_navigation_exact_cursor_rejects_replaced_page_owner_act
|
||||
.target_session_route_for_target_id(target_id.as_str())
|
||||
.expect("created target route");
|
||||
ctx.conn
|
||||
.runtime_session_owner_slot_mut_for_route(None, Some(&route))
|
||||
.runtime_session_owner_slot_mut_for_owner(&crate::conn::CommandOwnerScope::for_route(
|
||||
route.clone(),
|
||||
))
|
||||
.expect("created target runtime slot")
|
||||
.replace_page_attachment_id_for_test();
|
||||
|
||||
@@ -708,9 +710,8 @@ async fn bidi_fetch_control_resolves_background_request_owner() {
|
||||
));
|
||||
conn.browser_context = Some(browser_context);
|
||||
|
||||
conn.register_pending_fetch_navigation_request_for_route(
|
||||
Some("SID-background"),
|
||||
None,
|
||||
conn.register_pending_fetch_navigation_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-background"),
|
||||
PendingFetchNavigation {
|
||||
fetch_request_id: "FETCH-background".to_owned(),
|
||||
interception_session_id: Some("bidi-session-1".to_owned()),
|
||||
@@ -1588,7 +1589,9 @@ async fn devtools_runtime_command_uses_background_initial_document_without_resol
|
||||
let route = conn
|
||||
.target_session_route_for_target_id(second_target_id.as_str())
|
||||
.expect("background target route");
|
||||
conn.navigation_load_inputs_for_route(None, Some(&route))
|
||||
conn.navigation_load_inputs_for_owner(&crate::conn::CommandOwnerScope::for_route(
|
||||
route.clone(),
|
||||
))
|
||||
};
|
||||
assert!(
|
||||
background_load_inputs
|
||||
@@ -1788,7 +1791,9 @@ async fn protocol_neutral_await_promise_keeps_background_owner_route_across_pend
|
||||
.expect("active target route");
|
||||
assert!(
|
||||
!conn
|
||||
.target_devtools_session_state_for_route(None, Some(&active_route))
|
||||
.target_devtools_session_state_for_owner(&crate::conn::CommandOwnerScope::for_route(
|
||||
active_route.clone()
|
||||
))
|
||||
.is_some_and(crate::conn::DevToolsSessionState::has_pending_inspector_awaits),
|
||||
"internal id 0 pending await must not be registered on the active owner"
|
||||
);
|
||||
@@ -1797,8 +1802,10 @@ async fn protocol_neutral_await_promise_keeps_background_owner_route_across_pend
|
||||
.target_session_route_for_target_id(second_target_id.as_str())
|
||||
.expect("background target route");
|
||||
assert!(
|
||||
conn.target_devtools_session_state_for_route(None, Some(&background_route))
|
||||
.is_some_and(crate::conn::DevToolsSessionState::has_pending_inspector_awaits),
|
||||
conn.target_devtools_session_state_for_owner(&crate::conn::CommandOwnerScope::for_route(
|
||||
background_route.clone()
|
||||
))
|
||||
.is_some_and(crate::conn::DevToolsSessionState::has_pending_inspector_awaits),
|
||||
"internal id 0 pending await must be registered on the targeted background owner"
|
||||
);
|
||||
|
||||
@@ -1851,7 +1858,8 @@ async fn protocol_neutral_await_promise_keeps_background_owner_route_across_pend
|
||||
|
||||
#[tokio::test]
|
||||
async fn pending_runtime_binding_page_phase_keeps_background_owner_route_across_completion() {
|
||||
let mut conn = CdpConnection::new();
|
||||
let mut ctx = crate::testing::TestContext::from_conn(CdpConnection::new());
|
||||
let conn = &mut ctx.conn;
|
||||
let context = DevToolsCommandContext {
|
||||
protocol: DevToolsProtocol::WebDriverBidi,
|
||||
session_id: Some(DevToolsSessionId::from("bidi-binding-owner-route")),
|
||||
@@ -1861,7 +1869,7 @@ async fn pending_runtime_binding_page_phase_keeps_background_owner_route_across_
|
||||
|
||||
let (first_result, _) =
|
||||
crate::domains::target::execute_immediate_devtools_target_command_with_protocol_events(
|
||||
&mut conn,
|
||||
conn,
|
||||
DevToolsCommand::CreateTarget(DevToolsCreateTargetCommand {
|
||||
context: context.clone(),
|
||||
url: "about:blank".to_owned(),
|
||||
@@ -1875,7 +1883,7 @@ async fn pending_runtime_binding_page_phase_keeps_background_owner_route_across_
|
||||
panic!("expected create target result");
|
||||
};
|
||||
let first_target_id = first_result.target_id;
|
||||
ensure_initial_document_for_target_id_for_test(&mut conn, &first_target_id).await;
|
||||
ensure_initial_document_for_target_id_for_test(conn, &first_target_id).await;
|
||||
|
||||
let (second_result, _) = conn
|
||||
.execute_devtools_command(DevToolsCommand::CreateTarget(DevToolsCreateTargetCommand {
|
||||
@@ -1892,7 +1900,7 @@ async fn pending_runtime_binding_page_phase_keeps_background_owner_route_across_
|
||||
panic!("expected create target result");
|
||||
};
|
||||
let second_target_id = second_result.target_id;
|
||||
ensure_initial_document_for_target_id_for_test(&mut conn, &second_target_id).await;
|
||||
ensure_initial_document_for_target_id_for_test(conn, &second_target_id).await;
|
||||
|
||||
let first_context = DevToolsCommandContext {
|
||||
target_id: Some(first_target_id.clone()),
|
||||
@@ -1904,7 +1912,7 @@ async fn pending_runtime_binding_page_phase_keeps_background_owner_route_across_
|
||||
};
|
||||
assert_eq!(
|
||||
evaluate_string_for_test(
|
||||
&mut conn,
|
||||
conn,
|
||||
first_context,
|
||||
"globalThis.__bindingOwnerProbe = 'active'; globalThis.__bindingOwnerProbe",
|
||||
"active binding owner marker",
|
||||
@@ -1914,7 +1922,7 @@ async fn pending_runtime_binding_page_phase_keeps_background_owner_route_across_
|
||||
);
|
||||
assert_eq!(
|
||||
evaluate_string_for_test(
|
||||
&mut conn,
|
||||
conn,
|
||||
second_context,
|
||||
"globalThis.__bindingOwnerProbe = 'background'; globalThis.__bindingOwnerProbe",
|
||||
"background binding owner marker",
|
||||
@@ -1924,25 +1932,15 @@ async fn pending_runtime_binding_page_phase_keeps_background_owner_route_across_
|
||||
);
|
||||
|
||||
let background_session =
|
||||
attach_page_session_for_test(&mut conn, second_target_id.as_str()).await;
|
||||
let raw = serde_json::to_string(&json!({
|
||||
attach_page_session_for_test(&mut ctx.conn, second_target_id.as_str()).await;
|
||||
ctx.process_and_wait_for_response_async(json!({
|
||||
"id": 1269,
|
||||
"method": "Runtime.addBinding",
|
||||
"params": { "name": "backgroundRouteBinding" },
|
||||
"sessionId": background_session
|
||||
"sessionId": background_session.clone()
|
||||
}))
|
||||
.unwrap();
|
||||
let pending = match conn.start_command_dispatch(&raw) {
|
||||
CdpCommandTaskStep::Pending(pending) => pending,
|
||||
CdpCommandTaskStep::Complete(outcome) => {
|
||||
panic!(
|
||||
"background Runtime.addBinding should pend through renderer binding state apply: {:?}",
|
||||
outcome.into_parts().0
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let messages = complete_command_task_for_test(&mut conn, *pending).await;
|
||||
.await;
|
||||
let messages = ctx.take_all();
|
||||
assert!(
|
||||
messages
|
||||
.iter()
|
||||
@@ -1950,7 +1948,8 @@ async fn pending_runtime_binding_page_phase_keeps_background_owner_route_across_
|
||||
"Runtime.addBinding should complete successfully on the original background owner: {messages:?}"
|
||||
);
|
||||
assert!(
|
||||
conn.target_devtools_session_state_for_session(None)
|
||||
ctx.conn
|
||||
.target_devtools_session_state_for_session(None)
|
||||
.is_none_or(|state| state
|
||||
.runtime_bindings
|
||||
.iter()
|
||||
@@ -1958,7 +1957,8 @@ async fn pending_runtime_binding_page_phase_keeps_background_owner_route_across_
|
||||
"binding state apply completion must not write the active owner"
|
||||
);
|
||||
assert!(
|
||||
conn.target_devtools_session_state_for_session(Some(&background_session))
|
||||
ctx.conn
|
||||
.target_devtools_session_state_for_session(Some(&background_session))
|
||||
.is_some_and(|state| state
|
||||
.runtime_bindings
|
||||
.iter()
|
||||
@@ -1966,7 +1966,8 @@ async fn pending_runtime_binding_page_phase_keeps_background_owner_route_across_
|
||||
"binding state apply completion should persist on the original background owner"
|
||||
);
|
||||
assert_eq!(
|
||||
conn.browser_context
|
||||
ctx.conn
|
||||
.browser_context
|
||||
.as_ref()
|
||||
.expect("browser context")
|
||||
.active_target_id(),
|
||||
@@ -4085,9 +4086,10 @@ async fn set_file_input_files_shared_id_uses_renderer_binding_without_protocol_r
|
||||
.await;
|
||||
let fake_shared_id =
|
||||
crate::devtools_runtime::webdriver_bidi_node_shared_id_for_backend_node_id(backend_node_id);
|
||||
let owner = CommandOwnerScope::capture(&ctx.conn, None);
|
||||
ctx.conn
|
||||
.register_document_bidi_node_binding_for_session_owner_async(
|
||||
None,
|
||||
.register_document_bidi_node_binding_for_owner_async(
|
||||
&owner,
|
||||
fake_shared_id.as_str(),
|
||||
backend_node_id,
|
||||
)
|
||||
@@ -4150,9 +4152,10 @@ async fn locate_nodes_start_node_shared_id_uses_renderer_binding_without_protoco
|
||||
.await;
|
||||
let fake_shared_id =
|
||||
crate::devtools_runtime::webdriver_bidi_node_shared_id_for_backend_node_id(backend_node_id);
|
||||
let owner = CommandOwnerScope::capture(&ctx.conn, None);
|
||||
ctx.conn
|
||||
.register_document_bidi_node_binding_for_session_owner_async(
|
||||
None,
|
||||
.register_document_bidi_node_binding_for_owner_async(
|
||||
&owner,
|
||||
fake_shared_id.as_str(),
|
||||
backend_node_id,
|
||||
)
|
||||
@@ -4198,9 +4201,10 @@ async fn call_function_shared_id_uses_renderer_binding_without_protocol_registry
|
||||
.await;
|
||||
let fake_shared_id =
|
||||
crate::devtools_runtime::webdriver_bidi_node_shared_id_for_backend_node_id(backend_node_id);
|
||||
let owner = CommandOwnerScope::capture(&ctx.conn, None);
|
||||
ctx.conn
|
||||
.register_document_bidi_node_binding_for_session_owner_async(
|
||||
None,
|
||||
.register_document_bidi_node_binding_for_owner_async(
|
||||
&owner,
|
||||
fake_shared_id.as_str(),
|
||||
backend_node_id,
|
||||
)
|
||||
@@ -4640,7 +4644,9 @@ async fn devtools_command_applies_known_user_context_viewport_default() {
|
||||
.target_session_route_for_target_id(create_result.target_id.as_str())
|
||||
.expect("created target route");
|
||||
let inherited_metrics = conn
|
||||
.target_session_owner_emulated_device_metrics_for_route(None, Some(&route))
|
||||
.target_session_owner_emulated_device_metrics_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_route(route.clone()),
|
||||
)
|
||||
.expect("new target should inherit userContext default metrics");
|
||||
assert_eq!(
|
||||
(
|
||||
@@ -6245,7 +6251,9 @@ async fn devtools_command_executes_user_context_preload_without_default_leakage(
|
||||
.expect("custom userContext target route");
|
||||
assert!(
|
||||
ctx.conn
|
||||
.navigation_load_inputs_for_route(None, Some(&custom_route))
|
||||
.navigation_load_inputs_for_owner(&crate::conn::CommandOwnerScope::for_route(
|
||||
custom_route.clone()
|
||||
))
|
||||
.document_start_scripts
|
||||
.iter()
|
||||
.any(|script| script.source.contains("__bidiUserContextPreload")),
|
||||
@@ -8330,7 +8338,9 @@ async fn pending_emulation_timezone_keeps_background_owner_route_across_completi
|
||||
"background timezone",
|
||||
"background Emulation completion should preserve the captured owner"
|
||||
);
|
||||
let background_inputs = conn.navigation_load_inputs_for_route(None, Some(&background_route));
|
||||
let background_inputs = conn.navigation_load_inputs_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_route(background_route.clone()),
|
||||
);
|
||||
assert_eq!(background_inputs.timezone_override.as_deref(), Some("UTC"));
|
||||
assert!(
|
||||
conn.navigation_load_inputs_for_session_owner(None)
|
||||
@@ -8730,8 +8740,9 @@ async fn devtools_network_intercept_commands_route_to_fetch_owner() {
|
||||
.into_parts();
|
||||
auth_only_result.expect("auth-only add intercept should succeed");
|
||||
let auth_url = url::Url::parse("https://example.test/protected").unwrap();
|
||||
let owner = CommandOwnerScope::capture(&conn, None);
|
||||
let preflight = conn
|
||||
.prepare_navigation_request_for_route(None, None, &auth_url, None, false)
|
||||
.prepare_navigation_request_for_owner(&owner, &auth_url, None, false)
|
||||
.expect("auth-only intercept should prepare navigation preflight");
|
||||
assert!(preflight.document_auth_required);
|
||||
assert_eq!(
|
||||
|
||||
@@ -19,8 +19,8 @@ use url::Url;
|
||||
|
||||
use super::{
|
||||
BackgroundProtocolEvent, BrowserDownloadBehaviorSettings, CdpConnection,
|
||||
CommandDispatchContext, CompletedDownloadBody, CompletedDownloadBodyArtifact,
|
||||
NavigationDispatchState, output::BackgroundEventSender,
|
||||
CommandDispatchContext, CommandOwnerScope, CompletedDownloadBody,
|
||||
CompletedDownloadBodyArtifact, NavigationDispatchState, output::BackgroundEventSender,
|
||||
};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
@@ -227,13 +227,13 @@ impl CdpConnection {
|
||||
pub(crate) async fn handle_pending_download_activation_background_events_async(
|
||||
&mut self,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
activation: RendererPendingDownloadActivation,
|
||||
command_context: &mut CommandDispatchContext,
|
||||
) -> Result<(), String> {
|
||||
self.handle_pending_download_activation_with_event_route_async(
|
||||
out,
|
||||
session_id,
|
||||
owner,
|
||||
activation,
|
||||
true,
|
||||
command_context,
|
||||
@@ -244,13 +244,13 @@ impl CdpConnection {
|
||||
pub(crate) async fn handle_pending_download_activation_inline_async(
|
||||
&mut self,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
activation: RendererPendingDownloadActivation,
|
||||
command_context: &mut CommandDispatchContext,
|
||||
) -> Result<(), String> {
|
||||
self.handle_pending_download_activation_with_event_route_async(
|
||||
out,
|
||||
session_id,
|
||||
owner,
|
||||
activation,
|
||||
false,
|
||||
command_context,
|
||||
@@ -261,14 +261,12 @@ impl CdpConnection {
|
||||
async fn handle_pending_download_activation_with_event_route_async(
|
||||
&mut self,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
activation: RendererPendingDownloadActivation,
|
||||
allow_background_events: bool,
|
||||
command_context: &mut CommandDispatchContext,
|
||||
) -> Result<(), String> {
|
||||
if let Some(events) =
|
||||
self.denied_pending_download_activation_events(session_id, &activation)?
|
||||
{
|
||||
if let Some(events) = self.denied_pending_download_activation_events(owner, &activation)? {
|
||||
if allow_background_events && let Some(sender) = self.background_event_sender() {
|
||||
if command_context.response_flush().is_active() {
|
||||
command_context.extend_post_response_events(events);
|
||||
@@ -282,8 +280,7 @@ impl CdpConnection {
|
||||
}
|
||||
|
||||
if activation.response.is_some() {
|
||||
let Some(prepared) =
|
||||
self.prepare_prefetched_download_activation(session_id, activation)?
|
||||
let Some(prepared) = self.prepare_prefetched_download_activation(owner, activation)?
|
||||
else {
|
||||
return Ok(());
|
||||
};
|
||||
@@ -306,8 +303,7 @@ impl CdpConnection {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let Some(prepared) = self.prepare_pending_download_activation(session_id, activation)?
|
||||
else {
|
||||
let Some(prepared) = self.prepare_pending_download_activation(owner, activation)? else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
@@ -397,10 +393,10 @@ impl CdpConnection {
|
||||
|
||||
fn prepare_pending_download_activation(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
command_owner: &CommandOwnerScope,
|
||||
activation: RendererPendingDownloadActivation,
|
||||
) -> Result<Option<PreparedDownloadActivation>, String> {
|
||||
let Some(owner) = self.pending_download_owner_context(session_id) else {
|
||||
let Some(owner) = self.pending_download_owner_context(command_owner) else {
|
||||
return Ok(None);
|
||||
};
|
||||
let Some(settings) =
|
||||
@@ -434,7 +430,8 @@ impl CdpConnection {
|
||||
download_root,
|
||||
guid,
|
||||
behavior: settings.behavior,
|
||||
event_route: self.download_event_route(session_id, settings.automation_events_enabled),
|
||||
event_route: self
|
||||
.download_event_route(command_owner, settings.automation_events_enabled),
|
||||
suggested_filename_hint: activation.suggested_filename,
|
||||
cancel_handle,
|
||||
registry: self.download_registry.clone(),
|
||||
@@ -443,10 +440,10 @@ impl CdpConnection {
|
||||
|
||||
fn denied_pending_download_activation_events(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
command_owner: &CommandOwnerScope,
|
||||
activation: &RendererPendingDownloadActivation,
|
||||
) -> Result<Option<Vec<BackgroundProtocolEvent>>, String> {
|
||||
let Some(owner) = self.pending_download_owner_context(session_id) else {
|
||||
let Some(owner) = self.pending_download_owner_context(command_owner) else {
|
||||
return Ok(None);
|
||||
};
|
||||
let settings = self
|
||||
@@ -457,7 +454,8 @@ impl CdpConnection {
|
||||
{
|
||||
return Ok(None);
|
||||
}
|
||||
let event_route = self.download_event_route(session_id, settings.automation_events_enabled);
|
||||
let event_route =
|
||||
self.download_event_route(command_owner, settings.automation_events_enabled);
|
||||
if !event_route.has_observers() {
|
||||
return Ok(Some(Vec::new()));
|
||||
}
|
||||
@@ -496,10 +494,10 @@ impl CdpConnection {
|
||||
|
||||
fn prepare_prefetched_download_activation(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
command_owner: &CommandOwnerScope,
|
||||
activation: RendererPendingDownloadActivation,
|
||||
) -> Result<Option<PreparedNavigationDownload>, String> {
|
||||
let Some(owner) = self.pending_download_owner_context(session_id) else {
|
||||
let Some(owner) = self.pending_download_owner_context(command_owner) else {
|
||||
return Ok(None);
|
||||
};
|
||||
let Some(settings) =
|
||||
@@ -529,7 +527,8 @@ impl CdpConnection {
|
||||
download_root,
|
||||
guid: generate_download_guid()?,
|
||||
behavior: settings.behavior,
|
||||
event_route: self.download_event_route(session_id, settings.automation_events_enabled),
|
||||
event_route: self
|
||||
.download_event_route(command_owner, settings.automation_events_enabled),
|
||||
registry: self.download_registry.clone(),
|
||||
}))
|
||||
}
|
||||
@@ -540,13 +539,9 @@ impl CdpConnection {
|
||||
final_url: Url,
|
||||
body_artifact: CompletedDownloadBodyArtifact,
|
||||
) -> Result<Option<PreparedNavigationDownload>, String> {
|
||||
let owner_context_id = state
|
||||
.session_id
|
||||
.as_deref()
|
||||
.and_then(|session_id| {
|
||||
self.target_owner_identity_for_session(Some(session_id))
|
||||
.map(|(browser_context_id, _)| browser_context_id)
|
||||
})
|
||||
let owner_context_id = self
|
||||
.target_owner_identity_for_owner(&state.owner)
|
||||
.map(|(browser_context_id, _)| browser_context_id)
|
||||
.or_else(|| self.browser_context.as_ref().map(|bc| bc.id.clone()));
|
||||
let Some(settings) =
|
||||
self.effective_download_behavior_for_browser_context(owner_context_id.as_deref())
|
||||
@@ -570,10 +565,8 @@ impl CdpConnection {
|
||||
download_root,
|
||||
guid: generate_download_guid()?,
|
||||
behavior: settings.behavior,
|
||||
event_route: self.download_event_route(
|
||||
state.session_id.as_deref(),
|
||||
settings.automation_events_enabled,
|
||||
),
|
||||
event_route: self
|
||||
.download_event_route(&state.owner, settings.automation_events_enabled),
|
||||
registry: self.download_registry.clone(),
|
||||
}))
|
||||
}
|
||||
@@ -621,9 +614,9 @@ impl CdpConnection {
|
||||
|
||||
fn pending_download_owner_context(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<PendingDownloadOwnerContext> {
|
||||
let (browser_context_id, target_id) = self.target_owner_identity_for_session(session_id)?;
|
||||
let (browser_context_id, target_id) = self.target_owner_identity_for_owner(owner)?;
|
||||
let browser_context = self.browser_context_by_id(&browser_context_id)?;
|
||||
let frame_id = target_id
|
||||
.clone()
|
||||
@@ -634,7 +627,7 @@ impl CdpConnection {
|
||||
.map(|target_id| browser_context.effective_extra_headers_for_target(target_id))
|
||||
.unwrap_or_else(|| browser_context.effective_extra_headers());
|
||||
let initiator_url = self
|
||||
.runtime_session_owner_slot(session_id)
|
||||
.runtime_session_owner_slot_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page().map(|page| page.final_url().clone()));
|
||||
Some(PendingDownloadOwnerContext {
|
||||
@@ -662,11 +655,11 @@ impl CdpConnection {
|
||||
|
||||
fn download_event_route(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
automation_events_enabled: bool,
|
||||
) -> DownloadEventRoute {
|
||||
let page_observers = self
|
||||
.page_event_session_ids_for_session_owner(session_id)
|
||||
.page_event_session_ids_for_owner(owner)
|
||||
.into_iter()
|
||||
.filter_map(|event_session_id| {
|
||||
self.page_domain_subscription_generation_for_session_owner(
|
||||
@@ -1497,7 +1490,10 @@ mod tests {
|
||||
use moli_fetch::FetchCancelHandle;
|
||||
|
||||
use crate::{
|
||||
conn::{BackgroundProtocolEvent, BrowserContext, CdpConnection, PageTargetHost},
|
||||
conn::{
|
||||
BackgroundProtocolEvent, BrowserContext, CdpConnection, CommandOwnerScope,
|
||||
PageTargetHost,
|
||||
},
|
||||
devtools_runtime::AutomationEvent,
|
||||
};
|
||||
|
||||
@@ -1554,7 +1550,7 @@ mod tests {
|
||||
connection.browser_context = Some(browser_context);
|
||||
|
||||
let owner = connection
|
||||
.pending_download_owner_context(Some("SID-background"))
|
||||
.pending_download_owner_context(&CommandOwnerScope::for_session("SID-background"))
|
||||
.expect("background session must resolve its Page target");
|
||||
assert_eq!(owner.frame_id, "TID-background");
|
||||
assert_eq!(
|
||||
|
||||
@@ -5,7 +5,7 @@ use url::Url;
|
||||
|
||||
use super::body_spool::ensure_materialize_limit;
|
||||
use super::{
|
||||
CapturedBody, CapturedBodyWriter, CdpConnection, CdpSessionRoute, DocumentNavigationToken,
|
||||
CapturedBody, CapturedBodyWriter, CdpConnection, CommandOwnerScope, DocumentNavigationToken,
|
||||
NavigationDispatchState, NavigationLoadOutcome, PausedResponsePreparedDocument,
|
||||
};
|
||||
use crate::devtools_runtime::{DevToolsNetworkInterceptId, DevToolsNetworkResourceType};
|
||||
@@ -2056,9 +2056,9 @@ impl CdpConnection {
|
||||
intercept_response: bool,
|
||||
handle_auth_requests: bool,
|
||||
) -> Result<PendingSubresourceContinueOutcome, String> {
|
||||
self.continue_pending_subresource_fetch_for_route_async(
|
||||
session_id,
|
||||
None,
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.continue_pending_subresource_fetch_for_owner_async(
|
||||
&owner,
|
||||
internal_id,
|
||||
url,
|
||||
method,
|
||||
@@ -2070,10 +2070,9 @@ impl CdpConnection {
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn continue_pending_subresource_fetch_for_route_async(
|
||||
pub(crate) async fn continue_pending_subresource_fetch_for_owner_async(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
internal_id: u64,
|
||||
url: Option<Url>,
|
||||
method: Option<String>,
|
||||
@@ -2083,7 +2082,7 @@ impl CdpConnection {
|
||||
handle_auth_requests: bool,
|
||||
) -> Result<PendingSubresourceContinueOutcome, String> {
|
||||
let page = self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)?
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.loaded_page_mut()
|
||||
.ok_or_else(|| "NoDocumentLoaded".to_owned())?;
|
||||
page.continue_pending_subresource_fetch_async(
|
||||
@@ -2114,19 +2113,19 @@ impl CdpConnection {
|
||||
internal_id: u64,
|
||||
auth: SubresourceAuthCredentials,
|
||||
) -> Result<PendingSubresourceContinueOutcome, String> {
|
||||
self.continue_pending_subresource_auth_for_route_async(session_id, None, internal_id, auth)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.continue_pending_subresource_auth_for_owner_async(&owner, internal_id, auth)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn continue_pending_subresource_auth_for_route_async(
|
||||
pub(crate) async fn continue_pending_subresource_auth_for_owner_async(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
internal_id: u64,
|
||||
auth: SubresourceAuthCredentials,
|
||||
) -> Result<PendingSubresourceContinueOutcome, String> {
|
||||
let page = self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)?
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.loaded_page_mut()
|
||||
.ok_or_else(|| "NoDocumentLoaded".to_owned())?;
|
||||
page.continue_pending_subresource_auth_async(internal_id, auth)
|
||||
@@ -2149,24 +2148,19 @@ impl CdpConnection {
|
||||
internal_id: u64,
|
||||
error_text: String,
|
||||
) -> Result<Option<moli_core::RendererOutputFence>, String> {
|
||||
self.fail_pending_subresource_auth_for_route_async(
|
||||
session_id,
|
||||
None,
|
||||
internal_id,
|
||||
error_text,
|
||||
)
|
||||
.await
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.fail_pending_subresource_auth_for_owner_async(&owner, internal_id, error_text)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn fail_pending_subresource_auth_for_route_async(
|
||||
pub(crate) async fn fail_pending_subresource_auth_for_owner_async(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
internal_id: u64,
|
||||
error_text: String,
|
||||
) -> Result<Option<moli_core::RendererOutputFence>, String> {
|
||||
let page = self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)?
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.loaded_page_mut()
|
||||
.ok_or_else(|| "NoDocumentLoaded".to_owned())?;
|
||||
page.fail_pending_subresource_auth_async(internal_id, error_text)
|
||||
@@ -2189,24 +2183,19 @@ impl CdpConnection {
|
||||
internal_id: u64,
|
||||
error_text: String,
|
||||
) -> Result<Option<moli_core::RendererOutputFence>, String> {
|
||||
self.fail_pending_subresource_fetch_for_route_async(
|
||||
session_id,
|
||||
None,
|
||||
internal_id,
|
||||
error_text,
|
||||
)
|
||||
.await
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.fail_pending_subresource_fetch_for_owner_async(&owner, internal_id, error_text)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn fail_pending_subresource_fetch_for_route_async(
|
||||
pub(crate) async fn fail_pending_subresource_fetch_for_owner_async(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
internal_id: u64,
|
||||
error_text: String,
|
||||
) -> Result<Option<moli_core::RendererOutputFence>, String> {
|
||||
let page = self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)?
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.loaded_page_mut()
|
||||
.ok_or_else(|| "NoDocumentLoaded".to_owned())?;
|
||||
page.fail_pending_subresource_fetch_async(internal_id, error_text)
|
||||
@@ -2275,9 +2264,9 @@ impl CdpConnection {
|
||||
response_code: Option<u16>,
|
||||
response_headers: Option<Vec<(String, String)>>,
|
||||
) -> Result<(), String> {
|
||||
self.continue_pending_subresource_response_for_route_async(
|
||||
session_id,
|
||||
None,
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.continue_pending_subresource_response_for_owner_async(
|
||||
&owner,
|
||||
internal_id,
|
||||
response_code,
|
||||
response_headers,
|
||||
@@ -2285,16 +2274,15 @@ impl CdpConnection {
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn continue_pending_subresource_response_for_route_async(
|
||||
pub(crate) async fn continue_pending_subresource_response_for_owner_async(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
internal_id: u64,
|
||||
response_code: Option<u16>,
|
||||
response_headers: Option<Vec<(String, String)>>,
|
||||
) -> Result<(), String> {
|
||||
let page = self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)?
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.loaded_page_mut()
|
||||
.ok_or_else(|| "NoDocumentLoaded".to_owned())?;
|
||||
page.continue_pending_subresource_response_async(
|
||||
@@ -2325,24 +2313,19 @@ impl CdpConnection {
|
||||
internal_id: u64,
|
||||
error_text: String,
|
||||
) -> Result<Option<moli_core::RendererOutputFence>, String> {
|
||||
self.fail_pending_subresource_response_for_route_async(
|
||||
session_id,
|
||||
None,
|
||||
internal_id,
|
||||
error_text,
|
||||
)
|
||||
.await
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.fail_pending_subresource_response_for_owner_async(&owner, internal_id, error_text)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn fail_pending_subresource_response_for_route_async(
|
||||
pub(crate) async fn fail_pending_subresource_response_for_owner_async(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
internal_id: u64,
|
||||
error_text: String,
|
||||
) -> Result<Option<moli_core::RendererOutputFence>, String> {
|
||||
let page = self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)?
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.loaded_page_mut()
|
||||
.ok_or_else(|| "NoDocumentLoaded".to_owned())?;
|
||||
page.fail_pending_subresource_response_async(internal_id, error_text)
|
||||
|
||||
@@ -25,7 +25,7 @@ impl CdpConnection {
|
||||
&self,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<RendererAgentAttachmentId> {
|
||||
self.runtime_session_owner_slot_for_route(owner.session_id(), owner.session_owner_route())
|
||||
self.runtime_session_owner_slot_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.current_renderer_attachment())
|
||||
.map(RendererAgentAttachment::id)
|
||||
@@ -53,12 +53,9 @@ impl CdpConnection {
|
||||
agent_token: RendererDevToolsAgentToken,
|
||||
) -> Result<PreparedRendererAgentAttachment, String> {
|
||||
self.validate_navigation_target_owner_for_scope(owner, token)?;
|
||||
self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?
|
||||
.prepare_renderer_agent_candidate_token(token, agent_token)
|
||||
.map_err(|error| error.to_string())
|
||||
self.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.prepare_renderer_agent_candidate_token(token, agent_token)
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
pub(crate) fn route_current_renderer_inspector_output_for_owner(
|
||||
@@ -67,13 +64,12 @@ impl CdpConnection {
|
||||
batches: Vec<RendererRuntimeInspectorMessageBatch>,
|
||||
) -> Vec<RendererRuntimeInspectorMessageBatch> {
|
||||
let session_id = owner.session_id();
|
||||
let owner_route = owner.session_owner_route();
|
||||
let mut batches = self.filter_renderer_inspector_batches_for_target_owner(owner, batches);
|
||||
if batches.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
let current_attachment = self
|
||||
.runtime_session_owner_slot_for_route(session_id, owner_route)
|
||||
.runtime_session_owner_slot_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.current_renderer_attachment());
|
||||
if let Some(current_attachment) = current_attachment {
|
||||
@@ -120,26 +116,23 @@ impl CdpConnection {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
match self
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.and_then(|slot| {
|
||||
slot.route_current_renderer_inspector_output(attachment_id, batches)
|
||||
.map_err(|error| error.to_string())
|
||||
}) {
|
||||
Ok(batches) => {
|
||||
let primary_session_id = self
|
||||
.runtime_session_owner_primary_session_id_for_route(session_id, owner_route);
|
||||
let primary_session_id =
|
||||
self.runtime_session_owner_primary_session_id_for_owner(owner);
|
||||
for (session, state) in state_updates {
|
||||
let state_session_id = match &session {
|
||||
DevToolsSessionKey::Primary => primary_session_id.as_deref(),
|
||||
DevToolsSessionKey::Attached(session_id) => Some(session_id.as_str()),
|
||||
};
|
||||
let state_owner_route =
|
||||
state_session_id.is_none().then_some(owner_route).flatten();
|
||||
let _ = self.merge_v8_inspector_session_state_for_route(
|
||||
state_session_id,
|
||||
state_owner_route,
|
||||
state,
|
||||
);
|
||||
let state_owner = state_session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
let _ = self.merge_v8_inspector_session_state_for_owner(&state_owner, state);
|
||||
}
|
||||
batches
|
||||
}
|
||||
@@ -162,17 +155,11 @@ impl CdpConnection {
|
||||
) -> Result<CommittedRendererAgentAttachment, String> {
|
||||
self.validate_navigation_target_owner_for_scope(owner, candidate.navigation())?;
|
||||
let transaction = self
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.commit_renderer_agent_candidate_transaction(candidate, renderer_page)
|
||||
.map_err(|error| error.to_string())?;
|
||||
let page_owner = self
|
||||
.pending_target_page_residence_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.pending_target_page_residence_identity_for_owner(owner)
|
||||
.ok_or_else(|| "NavigationTargetOwnerMissing".to_owned())?;
|
||||
self.bind_renderer_page_output_owner(renderer_page, page_owner);
|
||||
Ok(transaction)
|
||||
@@ -184,12 +171,9 @@ impl CdpConnection {
|
||||
transaction: CommittedRendererAgentAttachment,
|
||||
) -> Result<(), String> {
|
||||
self.validate_navigation_target_owner_for_scope(owner, transaction.navigation())?;
|
||||
self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?
|
||||
.rollback_committed_renderer_agent_candidate(transaction)
|
||||
.map_err(|error| error.to_string())
|
||||
self.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.rollback_committed_renderer_agent_candidate(transaction)
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
pub(crate) fn finish_renderer_document_navigation_for_owner(
|
||||
@@ -204,10 +188,7 @@ impl CdpConnection {
|
||||
return None;
|
||||
}
|
||||
match self
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.and_then(|slot| {
|
||||
slot.finish_renderer_document_navigation(token)
|
||||
.map_err(|error| error.to_string())
|
||||
@@ -230,8 +211,7 @@ impl CdpConnection {
|
||||
owner: &CommandOwnerScope,
|
||||
batches: Vec<RendererRuntimeInspectorMessageBatch>,
|
||||
) -> Vec<RendererRuntimeInspectorMessageBatch> {
|
||||
let owner_identity =
|
||||
self.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let owner_identity = self.target_owner_identity_for_owner(owner);
|
||||
batches
|
||||
.into_iter()
|
||||
.filter(|batch| match &batch.session {
|
||||
@@ -251,7 +231,7 @@ impl CdpConnection {
|
||||
token: &DocumentNavigationToken,
|
||||
) -> Result<(), String> {
|
||||
let (_, target_id) = self
|
||||
.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.target_owner_identity_for_owner(owner)
|
||||
.ok_or_else(|| "NoDocumentLoaded".to_owned())?;
|
||||
if target_id.as_deref() != Some(token.target_id.as_str()) {
|
||||
return Err("renderer channel navigation target owner mismatch".to_owned());
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use super::super::{BrowserContext, ConnectionNetworkRequestIdAllocator, PageTargetHost};
|
||||
#[cfg(test)]
|
||||
use super::super::{
|
||||
DocumentBodySource, DocumentNavigationToken, NavigationDispatchState, PausedDocumentTransfer,
|
||||
PendingFetchAuthNavigation, PendingFetchNavigation, PendingSubresourceFetchAuthRequest,
|
||||
PendingSubresourceFetchRequest, PendingSubresourceFetchResponseRequest,
|
||||
DocumentBodySource, DocumentNavigationToken, NavigationDispatchState,
|
||||
PendingSubresourceFetchRequest,
|
||||
};
|
||||
|
||||
fn document_navigation_loader_id(sequence: u64) -> String {
|
||||
@@ -72,22 +71,6 @@ impl BrowserContext {
|
||||
self.page_targets.insert(host)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn take_active_target_pending_fetch_state(
|
||||
&mut self,
|
||||
) -> (
|
||||
Vec<PendingFetchNavigation>,
|
||||
Vec<PendingFetchAuthNavigation>,
|
||||
Vec<PausedDocumentTransfer>,
|
||||
Vec<(String, PendingSubresourceFetchRequest)>,
|
||||
Vec<(String, PendingSubresourceFetchAuthRequest)>,
|
||||
Vec<(String, PendingSubresourceFetchResponseRequest)>,
|
||||
) {
|
||||
self.active_page_target_mut()
|
||||
.fetch_owner
|
||||
.drain_pending_requests()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn open_pending_fetch_response_body_stream(
|
||||
&mut self,
|
||||
@@ -425,7 +408,10 @@ mod tests {
|
||||
.fetch_owner
|
||||
.has_in_flight_subresource_fetches_for_test()
|
||||
);
|
||||
let _ = bc.take_active_target_pending_fetch_state();
|
||||
let _ = bc
|
||||
.active_page_target_mut()
|
||||
.fetch_owner
|
||||
.drain_pending_requests();
|
||||
assert!(
|
||||
!bc.active_page_target()
|
||||
.fetch_owner
|
||||
|
||||
@@ -18,7 +18,7 @@ impl CdpConnection {
|
||||
owner: &TargetPageResidenceIdentity,
|
||||
completion: CompletedPageCommand,
|
||||
) -> RendererCommandTurnOutput {
|
||||
if !self.target_page_residence_identity_is_current_for_session(session_id, owner) {
|
||||
if !self.target_page_residence_identity_is_current(owner) {
|
||||
return completion.into_output();
|
||||
}
|
||||
|
||||
|
||||
@@ -227,15 +227,15 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
) -> Result<Option<PendingPageCommand>, String> {
|
||||
self.start_rebuild_resource_runtime_for_route(session_id, None)
|
||||
let owner = super::CommandOwnerScope::capture(self, session_id);
|
||||
self.start_rebuild_resource_runtime_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn start_rebuild_resource_runtime_for_route(
|
||||
pub(crate) fn start_rebuild_resource_runtime_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&super::CdpSessionRoute>,
|
||||
owner: &super::CommandOwnerScope,
|
||||
) -> Result<Option<PendingPageCommand>, String> {
|
||||
let load_inputs = self.navigation_load_inputs_for_route(session_id, owner_route);
|
||||
let load_inputs = self.navigation_load_inputs_for_owner(owner);
|
||||
let navigator_identity = load_inputs
|
||||
.navigator_identity_override
|
||||
.clone()
|
||||
@@ -249,7 +249,7 @@ impl CdpConnection {
|
||||
storage.into_navigation_storage(),
|
||||
)
|
||||
.map_err(|error| format!("failed to rebuild resource runtime: {error}"))?;
|
||||
let Some(page) = self.resource_runtime_apply_page_for_route(session_id, owner_route) else {
|
||||
let Some(page) = self.resource_runtime_apply_page_for_owner(owner) else {
|
||||
return Ok(None);
|
||||
};
|
||||
page.start_replace_browser_resource_runtime_with_navigator_identity(
|
||||
@@ -271,14 +271,13 @@ impl CdpConnection {
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn finish_rebuild_resource_runtime_for_route(
|
||||
pub(crate) fn finish_rebuild_resource_runtime_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&super::CdpSessionRoute>,
|
||||
owner: &super::CommandOwnerScope,
|
||||
completion: CompletedPageCommand,
|
||||
) -> Result<(), String> {
|
||||
finish_resource_runtime_update_on_current_attachment(
|
||||
self.resource_runtime_apply_page_for_route(session_id, owner_route),
|
||||
self.resource_runtime_apply_page_for_owner(owner),
|
||||
completion,
|
||||
)
|
||||
}
|
||||
@@ -300,13 +299,12 @@ impl CdpConnection {
|
||||
.ok()
|
||||
}
|
||||
|
||||
fn resource_runtime_apply_page_for_route(
|
||||
fn resource_runtime_apply_page_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&super::CdpSessionRoute>,
|
||||
owner: &super::CommandOwnerScope,
|
||||
) -> Option<&mut moli_core::page::Page> {
|
||||
if matches!(
|
||||
session_id.and_then(|session_id| self.session_route(Some(session_id))),
|
||||
owner.resolve_route(self),
|
||||
Some(super::CdpSessionRoute::Browser)
|
||||
) {
|
||||
return self
|
||||
@@ -314,7 +312,7 @@ impl CdpConnection {
|
||||
.as_mut()
|
||||
.and_then(|bc| bc.active_page_target_mut().runtime_slot.loaded_page_mut());
|
||||
}
|
||||
self.loaded_page_mut_for_target_configuration_for_route(session_id, owner_route)
|
||||
self.loaded_page_mut_for_target_configuration_for_owner(owner)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1547,10 +1547,7 @@ impl CdpConnection {
|
||||
navigation: &NavigationDispatchState,
|
||||
) -> TargetNavigationLoadInputs {
|
||||
apply_navigation_request_load_policy(
|
||||
self.navigation_load_inputs_for_route(
|
||||
navigation.owner.session_id(),
|
||||
navigation.owner.session_owner_route(),
|
||||
),
|
||||
self.navigation_load_inputs_for_owner(&navigation.owner),
|
||||
navigation.request_load_policy,
|
||||
)
|
||||
.with_main_document_commit_seed(RendererMainDocumentCommitSeed::from_navigation(navigation))
|
||||
@@ -1562,8 +1559,7 @@ impl CdpConnection {
|
||||
final_url: &Url,
|
||||
) -> Result<PreparedDocumentPageCommitConfiguration, String> {
|
||||
let idle_override = self.idle_override_for_navigation(owner, final_url);
|
||||
let load_inputs =
|
||||
self.navigation_load_inputs_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let load_inputs = self.navigation_load_inputs_for_owner(owner);
|
||||
// The renderer runtime is shared by the BrowserContext, but each Page
|
||||
// target owns its NavigationEngine and may have a different transport
|
||||
// identity. Resolve through that target's engine at the commit
|
||||
@@ -1616,7 +1612,7 @@ impl CdpConnection {
|
||||
// navigation can retain that frame-host state; a cross-site renderer
|
||||
// replacement must start with the actual idle state.
|
||||
let page = self
|
||||
.runtime_session_owner_slot_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_for_owner(owner)
|
||||
.ok()?
|
||||
.loaded_page()?;
|
||||
moli_site::same_site_urls(page.final_url(), final_url, true)
|
||||
@@ -1695,12 +1691,8 @@ impl CdpConnection {
|
||||
let main_document_commit = load_inputs
|
||||
.main_document_commit_for_final_url(&final_url, None)
|
||||
.map(Arc::new);
|
||||
let page_reservation = self.reserve_renderer_page_for_route(
|
||||
navigation.owner.session_id(),
|
||||
navigation.owner.session_owner_route(),
|
||||
&load_inputs,
|
||||
&engine,
|
||||
);
|
||||
let page_reservation =
|
||||
self.reserve_renderer_page_for_owner(&navigation.owner, &load_inputs, &engine);
|
||||
let prepared_page = engine
|
||||
.prepare_streaming_raw_page_from_external_body_with_storage_and_inspector_session_restores_async(
|
||||
page_reservation,
|
||||
@@ -1785,9 +1777,7 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<Option<PendingInitialDocumentPageBuild>, String> {
|
||||
let runtime_slot = match self
|
||||
.runtime_session_owner_slot_for_route(owner.session_id(), owner.session_owner_route())
|
||||
{
|
||||
let runtime_slot = match self.runtime_session_owner_slot_for_owner(owner) {
|
||||
Ok(slot) => slot,
|
||||
Err(_) => return Ok(None),
|
||||
};
|
||||
@@ -1805,10 +1795,7 @@ impl CdpConnection {
|
||||
// it, while rejecting the ensure would incorrectly reject attachment.
|
||||
// Treat this as an already-satisfied ensure and let the exact
|
||||
// target-owned navigation install the replacement Document.
|
||||
if self.has_pending_document_navigation_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
if self.has_pending_document_navigation_for_owner(owner) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
@@ -1827,22 +1814,16 @@ impl CdpConnection {
|
||||
&self,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
if let Some(is_on_initial_empty_document) = self
|
||||
.runtime_session_owner_record_is_on_initial_empty_document_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
if let Some(is_on_initial_empty_document) =
|
||||
self.runtime_session_owner_record_is_on_initial_empty_document_for_owner(owner)
|
||||
{
|
||||
return is_on_initial_empty_document;
|
||||
}
|
||||
self.runtime_session_owner_target_url_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.as_deref()
|
||||
.and_then(|raw_url| Url::parse(raw_url).ok())
|
||||
.as_ref()
|
||||
.is_some_and(moli_url::is_about_blank)
|
||||
self.runtime_session_owner_target_url_for_owner(owner)
|
||||
.as_deref()
|
||||
.and_then(|raw_url| Url::parse(raw_url).ok())
|
||||
.as_ref()
|
||||
.is_some_and(moli_url::is_about_blank)
|
||||
}
|
||||
|
||||
/// Returns whether the materialized initial `about:blank` still needs to
|
||||
@@ -1851,16 +1832,16 @@ impl CdpConnection {
|
||||
/// This is a structural lifecycle query. It deliberately does not look
|
||||
/// at `waitForDebuggerOnStart`: the explicit debugger-resume path uses it
|
||||
/// after the paused session has been released.
|
||||
pub(crate) fn runtime_session_owner_needs_initial_document_navigation(
|
||||
pub(crate) fn runtime_session_owner_needs_initial_document_navigation_for_owner(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
if !self.runtime_session_owner_initial_empty_document_has_replacement_url(session_id) {
|
||||
if !self.runtime_session_owner_initial_empty_document_has_replacement_url_for_owner(owner) {
|
||||
return false;
|
||||
}
|
||||
if self.runtime_session_owner_initial_empty_document_has_pending_cross_document_navigation(
|
||||
session_id,
|
||||
) {
|
||||
if self
|
||||
.runtime_session_owner_initial_empty_document_has_pending_cross_document_navigation_for_owner(owner)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
true
|
||||
@@ -1878,22 +1859,38 @@ impl CdpConnection {
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
) -> bool {
|
||||
!self.session_owner_target_has_waiting_for_debugger_session(session_id)
|
||||
&& self.runtime_session_owner_needs_initial_document_navigation(session_id)
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.runtime_session_owner_can_start_initial_document_navigation_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn runtime_session_owner_can_start_initial_document_navigation_for_owner(
|
||||
&self,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
!self.owner_target_has_waiting_for_debugger_session(owner)
|
||||
&& self.runtime_session_owner_needs_initial_document_navigation_for_owner(owner)
|
||||
}
|
||||
|
||||
pub(crate) fn runtime_session_owner_initial_empty_document_has_replacement_url(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
) -> bool {
|
||||
if !self.runtime_session_owner_target_is_initial_about_blank(session_id) {
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
self.runtime_session_owner_initial_empty_document_has_replacement_url_for_owner(&owner)
|
||||
}
|
||||
|
||||
pub(crate) fn runtime_session_owner_initial_empty_document_has_replacement_url_for_owner(
|
||||
&self,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
if !self.runtime_session_owner_target_is_initial_about_blank_for_owner(owner) {
|
||||
return false;
|
||||
}
|
||||
let Some(target_url) = self.runtime_session_owner_target_url(session_id) else {
|
||||
let Some(target_url) = self.runtime_session_owner_target_url_for_owner(owner) else {
|
||||
return false;
|
||||
};
|
||||
let Some(initial_url) =
|
||||
self.runtime_session_owner_record_initial_empty_document_url(session_id)
|
||||
self.runtime_session_owner_record_initial_empty_document_url_for_owner(owner)
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
@@ -1904,9 +1901,7 @@ impl CdpConnection {
|
||||
&mut self,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<Option<PendingInitialDocumentPageBuild>, String> {
|
||||
let runtime_slot = match self
|
||||
.runtime_session_owner_slot_for_route(owner.session_id(), owner.session_owner_route())
|
||||
{
|
||||
let runtime_slot = match self.runtime_session_owner_slot_for_owner(owner) {
|
||||
Ok(slot) => slot,
|
||||
Err(_) => return Ok(None),
|
||||
};
|
||||
@@ -1923,10 +1918,9 @@ impl CdpConnection {
|
||||
}
|
||||
|
||||
let page_owner = self
|
||||
.initial_document_page_owner_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.initial_document_page_owner_for_owner(owner)
|
||||
.ok_or_else(|| "TargetNotLoaded".to_owned())?;
|
||||
let load_inputs =
|
||||
self.navigation_load_inputs_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let load_inputs = self.navigation_load_inputs_for_owner(owner);
|
||||
let requested_url = self
|
||||
.runtime_session_owner_initial_empty_document_url_for_owner(owner)
|
||||
.unwrap_or_else(|| Url::parse("about:blank").expect("about:blank should be valid"));
|
||||
@@ -1934,35 +1928,23 @@ impl CdpConnection {
|
||||
load_inputs.fetch_subresource_interception;
|
||||
let mut engine = self.background_navigation_engine_for_load_inputs(&load_inputs);
|
||||
let page_storage = load_inputs.page_storage_handles();
|
||||
let top_level_storage_key = self
|
||||
.runtime_session_owner_initial_empty_document_storage_key_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
self.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?
|
||||
.start_initial_document_page_build();
|
||||
let top_level_storage_key =
|
||||
self.runtime_session_owner_initial_empty_document_storage_key_for_owner(owner);
|
||||
self.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.start_initial_document_page_build();
|
||||
let page_reservation = engine.reserve_page_for_creation();
|
||||
let renderer_page = RendererPageResidenceIdentity::from_parts(
|
||||
page_reservation.local_host_id(),
|
||||
page_reservation.page_id(),
|
||||
);
|
||||
if !self
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)?
|
||||
.bind_initial_document_page_build_renderer_page(renderer_page)
|
||||
{
|
||||
let message =
|
||||
"initial document Page reservation no longer matches its target build".to_owned();
|
||||
let _ = self
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.map(|slot| {
|
||||
slot.fail_initial_document_page_build(message.clone());
|
||||
slot.mark_loaded_page_absent(
|
||||
@@ -1977,10 +1959,7 @@ impl CdpConnection {
|
||||
// command; binding after `start_*` would leave a real cross-thread race
|
||||
// where the concrete FIFO receives its first publication ownerless.
|
||||
let renderer_page_owner = self
|
||||
.pending_target_page_residence_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.pending_target_page_residence_identity_for_owner(owner)
|
||||
.ok_or_else(|| "initial document Page reservation lost its target owner".to_owned())?;
|
||||
self.bind_renderer_page_output_owner(renderer_page, renderer_page_owner);
|
||||
let pending = engine
|
||||
@@ -2019,10 +1998,7 @@ impl CdpConnection {
|
||||
.map_err(|error| {
|
||||
let message = format!("failed to start initial document page build: {error}");
|
||||
let _ = self
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.map(|slot| {
|
||||
slot.fail_initial_document_page_build(message.clone());
|
||||
slot.mark_loaded_page_absent(
|
||||
@@ -2087,21 +2063,15 @@ impl CdpConnection {
|
||||
&self,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<Url> {
|
||||
if let Some(raw_url) = self
|
||||
.runtime_session_owner_record_initial_empty_document_url_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
if let Some(raw_url) =
|
||||
self.runtime_session_owner_record_initial_empty_document_url_for_owner(owner)
|
||||
{
|
||||
return Url::parse(&raw_url).ok().filter(moli_url::is_about_blank);
|
||||
}
|
||||
self.runtime_session_owner_target_url_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.as_deref()
|
||||
.and_then(|raw_url| Url::parse(raw_url).ok())
|
||||
.filter(moli_url::is_about_blank)
|
||||
self.runtime_session_owner_target_url_for_owner(owner)
|
||||
.as_deref()
|
||||
.and_then(|raw_url| Url::parse(raw_url).ok())
|
||||
.filter(moli_url::is_about_blank)
|
||||
}
|
||||
|
||||
fn complete_initial_document_page_build_for_page_owner(
|
||||
@@ -2224,8 +2194,7 @@ impl CdpConnection {
|
||||
raw_url: &str,
|
||||
) -> Result<LoadedNavigation, String> {
|
||||
let owner = CommandOwnerScope::capture(self, None);
|
||||
let load_inputs =
|
||||
self.navigation_load_inputs_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let load_inputs = self.navigation_load_inputs_for_owner(&owner);
|
||||
self.load_navigation_via_runtime_with_load_inputs_async(&owner, raw_url, load_inputs)
|
||||
.await
|
||||
}
|
||||
@@ -2328,7 +2297,7 @@ impl CdpConnection {
|
||||
) -> Result<NavigationLoadOutcome, String> {
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
let load_inputs = apply_navigation_request_load_policy(
|
||||
self.navigation_load_inputs_for_route(owner.session_id(), owner.session_owner_route()),
|
||||
self.navigation_load_inputs_for_owner(&owner),
|
||||
request_load_policy,
|
||||
);
|
||||
self.load_navigation_request_via_runtime_with_network_events_and_load_inputs_async(
|
||||
@@ -2484,12 +2453,8 @@ impl CdpConnection {
|
||||
let shared_resource_runtime =
|
||||
self.shared_resource_runtime_for_navigation_load_inputs(&load_inputs);
|
||||
let engine = self.background_navigation_engine_for_load_inputs(&load_inputs);
|
||||
let page_reservation = self.reserve_renderer_page_for_route(
|
||||
navigation.owner.session_id(),
|
||||
navigation.owner.session_owner_route(),
|
||||
&load_inputs,
|
||||
&engine,
|
||||
);
|
||||
let page_reservation =
|
||||
self.reserve_renderer_page_for_owner(&navigation.owner, &load_inputs, &engine);
|
||||
Some(BackgroundNavigationLoadJob {
|
||||
engine,
|
||||
page_reservation,
|
||||
@@ -2535,12 +2500,8 @@ impl CdpConnection {
|
||||
let shared_resource_runtime =
|
||||
self.shared_resource_runtime_for_navigation_load_inputs(&load_inputs);
|
||||
let engine = self.background_navigation_engine_for_load_inputs(&load_inputs);
|
||||
let page_reservation = self.reserve_renderer_page_for_route(
|
||||
navigation.owner.session_id(),
|
||||
navigation.owner.session_owner_route(),
|
||||
&load_inputs,
|
||||
&engine,
|
||||
);
|
||||
let page_reservation =
|
||||
self.reserve_renderer_page_for_owner(&navigation.owner, &load_inputs, &engine);
|
||||
BackgroundStreamingResponseNavigationLoadJob {
|
||||
engine,
|
||||
page_reservation,
|
||||
@@ -2569,36 +2530,15 @@ impl CdpConnection {
|
||||
owner: &CommandOwnerScope,
|
||||
load_inputs: &TargetNavigationLoadInputs,
|
||||
engine: &NavigationEngine,
|
||||
) -> RendererPageReservationToken {
|
||||
self.reserve_renderer_page_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
load_inputs,
|
||||
engine,
|
||||
)
|
||||
}
|
||||
|
||||
fn reserve_renderer_page_for_route(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
load_inputs: &TargetNavigationLoadInputs,
|
||||
engine: &NavigationEngine,
|
||||
) -> RendererPageReservationToken {
|
||||
let page_reservation = engine.reserve_page_for_creation();
|
||||
self.bind_renderer_page_reservation_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
load_inputs,
|
||||
page_reservation,
|
||||
);
|
||||
self.bind_renderer_page_reservation_for_owner(owner, load_inputs, page_reservation);
|
||||
page_reservation
|
||||
}
|
||||
|
||||
fn bind_renderer_page_reservation_for_route(
|
||||
fn bind_renderer_page_reservation_for_owner(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
load_inputs: &TargetNavigationLoadInputs,
|
||||
page_reservation: RendererPageReservationToken,
|
||||
) {
|
||||
@@ -2610,7 +2550,7 @@ impl CdpConnection {
|
||||
// reservation; recording `target_id: None` here would conflict with
|
||||
// that exact owner when the stream-open control is later consumed.
|
||||
if let Some((browser_context_id, Some(_target_id))) =
|
||||
self.target_owner_identity_for_route(session_id, owner_route)
|
||||
self.target_owner_identity_for_owner(owner)
|
||||
{
|
||||
assert_eq!(
|
||||
load_inputs.browser_context_id.as_deref(),
|
||||
@@ -2622,11 +2562,7 @@ impl CdpConnection {
|
||||
page_reservation.page_id(),
|
||||
);
|
||||
let page_owner = self
|
||||
.reserve_target_page_residence_identity_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
renderer_page,
|
||||
)
|
||||
.reserve_target_page_residence_identity_for_owner(owner, renderer_page)
|
||||
.expect("navigation Page reservation must retain its target owner");
|
||||
self.bind_renderer_page_output_owner(renderer_page, page_owner);
|
||||
}
|
||||
@@ -3183,10 +3119,9 @@ impl CdpConnection {
|
||||
.map_err(|error| format!("failed to fetch page `{raw_url}`: {error}"))
|
||||
}
|
||||
|
||||
pub(crate) async fn fetch_navigation_auth_raw_response_for_route_async(
|
||||
pub(crate) async fn fetch_navigation_auth_raw_response_for_owner_async(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_load_policy: NavigationRequestLoadPolicy,
|
||||
method: &str,
|
||||
raw_url: &str,
|
||||
@@ -3195,7 +3130,7 @@ impl CdpConnection {
|
||||
auth: SubresourceAuthCredentials,
|
||||
) -> Result<NetworkFetchResult<RawResponse>, String> {
|
||||
let load_inputs = apply_navigation_request_load_policy(
|
||||
self.navigation_load_inputs_for_route(session_id, owner_route),
|
||||
self.navigation_load_inputs_for_owner(owner),
|
||||
request_load_policy,
|
||||
);
|
||||
ensure_url_not_blocked_for_load_inputs(&load_inputs, raw_url)?;
|
||||
@@ -3245,10 +3180,9 @@ impl CdpConnection {
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn fetch_navigation_streaming_raw_response_for_route_async(
|
||||
pub(crate) async fn fetch_navigation_streaming_raw_response_for_owner_async(
|
||||
&mut self,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
request_load_policy: NavigationRequestLoadPolicy,
|
||||
method: &str,
|
||||
raw_url: &str,
|
||||
@@ -3257,7 +3191,7 @@ impl CdpConnection {
|
||||
auth: Option<SubresourceAuthCredentials>,
|
||||
) -> Result<NetworkFetchResult<StreamingRawResponse>, String> {
|
||||
let load_inputs = apply_navigation_request_load_policy(
|
||||
self.navigation_load_inputs_for_route(session_id, owner_route),
|
||||
self.navigation_load_inputs_for_owner(owner),
|
||||
request_load_policy,
|
||||
);
|
||||
self.fetch_navigation_streaming_raw_response_with_load_inputs_async(
|
||||
@@ -3477,8 +3411,7 @@ impl CdpConnection {
|
||||
response: NetworkFetchResult<RawResponse>,
|
||||
) -> Result<NavigationLoadOutcome, String> {
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
let load_inputs =
|
||||
self.navigation_load_inputs_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let load_inputs = self.navigation_load_inputs_for_owner(&owner);
|
||||
self.build_navigation_from_buffered_raw_response_with_load_inputs_async(
|
||||
&owner,
|
||||
&load_inputs,
|
||||
@@ -3671,8 +3604,7 @@ impl CdpConnection {
|
||||
body_progress_source: MainDocumentBodyProgressSource,
|
||||
) -> Result<NavigationLoadOutcome, String> {
|
||||
let owner = CommandOwnerScope::capture(self, session_id);
|
||||
let load_inputs =
|
||||
self.navigation_load_inputs_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let load_inputs = self.navigation_load_inputs_for_owner(&owner);
|
||||
self.build_navigation_from_streaming_raw_response_with_load_inputs_async(
|
||||
&owner,
|
||||
&load_inputs,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::conn::{BackgroundProtocolEvent, BrowserContext, CdpConnection};
|
||||
use crate::conn::{BackgroundProtocolEvent, BrowserContext, CdpConnection, CommandOwnerScope};
|
||||
|
||||
/// The stable Target identities on both sides of one foreground selection.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@@ -144,10 +144,15 @@ impl CdpConnection {
|
||||
let Some(route) = self.target_session_route_for_target_id(target_id) else {
|
||||
return Vec::new();
|
||||
};
|
||||
self.page_event_session_ids_for_route(None, Some(&route))
|
||||
let owner = CommandOwnerScope::for_route(route);
|
||||
self.page_event_session_ids_for_owner(&owner)
|
||||
.into_iter()
|
||||
.filter(|session_id| {
|
||||
self.target_page_session_state_for_route(session_id.as_deref(), Some(&route))
|
||||
let event_owner = session_id
|
||||
.as_deref()
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
self.target_page_session_state_for_owner(&event_owner)
|
||||
.is_some_and(|state| state.page_screencast.is_active())
|
||||
})
|
||||
.collect()
|
||||
|
||||
@@ -40,6 +40,24 @@ pub(crate) enum CdpSessionRoute {
|
||||
}
|
||||
|
||||
impl CdpSessionRoute {
|
||||
pub(crate) fn addresses_same_target_as(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(
|
||||
Self::PageTarget {
|
||||
browser_context_id: left_context,
|
||||
target_id: left_target,
|
||||
..
|
||||
},
|
||||
Self::PageTarget {
|
||||
browser_context_id: right_context,
|
||||
target_id: right_target,
|
||||
..
|
||||
},
|
||||
) => left_context == right_context && left_target == right_target,
|
||||
_ => self == other,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn browser_context_id(&self) -> Option<&str> {
|
||||
match self {
|
||||
Self::Browser => None,
|
||||
@@ -272,43 +290,6 @@ impl CdpConnection {
|
||||
self.browser_contexts()
|
||||
.any(|browser_context| browser_context.has_attached_child_frame_id(frame_id))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn has_background_target_session(&self, session_id: Option<&str>) -> bool {
|
||||
self.background_target_route(session_id).is_some()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn background_target_id_for_session(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
) -> Option<String> {
|
||||
self.background_target_route(session_id)
|
||||
.map(|(_, target_id)| target_id)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn background_target_route(
|
||||
&self,
|
||||
session_id: Option<&str>,
|
||||
) -> Option<(String, String)> {
|
||||
match self.session_route(session_id)? {
|
||||
CdpSessionRoute::PageTarget {
|
||||
browser_context_id,
|
||||
target_id,
|
||||
..
|
||||
} => (!self
|
||||
.browser_context_by_id(&browser_context_id)?
|
||||
.is_active_target(&target_id))
|
||||
.then_some((browser_context_id, target_id)),
|
||||
CdpSessionRoute::Browser
|
||||
| CdpSessionRoute::BrowserContext { .. }
|
||||
| CdpSessionRoute::TabTarget { .. }
|
||||
| CdpSessionRoute::SharedWorkerTarget { .. }
|
||||
| CdpSessionRoute::DedicatedWorkerTarget { .. }
|
||||
| CdpSessionRoute::ServiceWorkerTarget { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
fn prepared_browser_context_session_route(
|
||||
browser_context: &BrowserContext,
|
||||
@@ -387,8 +368,11 @@ mod tests {
|
||||
|
||||
assert_eq!(connection.session_route(Some("SID-a")), Some(route));
|
||||
assert_eq!(
|
||||
connection.background_target_route(Some("SID-a")),
|
||||
Some(("BID-route".to_owned(), "TID-a".to_owned()))
|
||||
connection
|
||||
.browser_context
|
||||
.as_ref()
|
||||
.and_then(BrowserContext::active_target_id),
|
||||
Some("TID-b")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -435,13 +435,17 @@ fn background_navigation_completion_sender_routes_explicit_session_owners() {
|
||||
conn.set_background_navigation_completion_sender(sender);
|
||||
|
||||
assert!(
|
||||
conn.background_navigation_completion_sender_for_route(Some("SID-active"), None)
|
||||
.is_some(),
|
||||
conn.background_navigation_completion_sender_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-active")
|
||||
)
|
||||
.is_some(),
|
||||
"a command scoped to a concrete target owner can continue navigation work in the background"
|
||||
);
|
||||
assert!(
|
||||
conn.background_navigation_completion_sender_for_route(Some("SID-inactive"), None)
|
||||
.is_some(),
|
||||
conn.background_navigation_completion_sender_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-inactive")
|
||||
)
|
||||
.is_some(),
|
||||
"inactive-context target owners should also be routable by explicit session id"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use moli_core::page::RendererDocumentSourcedTopLevelLocationNavigation;
|
||||
|
||||
use super::{CdpConnection, CommandOwnerScope, TargetPageResidenceIdentity};
|
||||
use super::{CommandOwnerScope, TargetPageResidenceIdentity};
|
||||
|
||||
/// One renderer-requested top-level navigation projected from a concrete
|
||||
/// renderer output record.
|
||||
@@ -34,13 +34,12 @@ impl TopLevelLocationNavigationOwnerAction {
|
||||
/// concrete action rather than execute the navigation inline or rescan the
|
||||
/// current Page.
|
||||
pub(crate) fn from_prepared(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_scope: CommandOwnerScope,
|
||||
page_owner: TargetPageResidenceIdentity,
|
||||
navigation: RendererDocumentSourcedTopLevelLocationNavigation,
|
||||
) -> Self {
|
||||
Self {
|
||||
owner_scope: CommandOwnerScope::capture(conn, session_id),
|
||||
owner_scope,
|
||||
page_owner,
|
||||
navigation,
|
||||
}
|
||||
|
||||
@@ -678,16 +678,13 @@ pub(crate) async fn complete_pending_accessibility_command(
|
||||
let CompletedAccessibilityCommandWork::Page(completed) = completed;
|
||||
let completed = *completed;
|
||||
|
||||
let session_id = owner_scope.session_id().map(str::to_owned);
|
||||
let session_id_ref = session_id.as_deref();
|
||||
let owner_route = owner_scope.session_owner_route();
|
||||
if let Err(message) = conn.ensure_document_accessible_for_route(session_id_ref, owner_route) {
|
||||
if let Err(message) = conn.ensure_document_accessible_for_owner(&owner_scope) {
|
||||
return AccessibilityCommandDispatchStep::Complete(CommandOutputPlan::error(
|
||||
-32000, message,
|
||||
));
|
||||
}
|
||||
let Some(page) = conn
|
||||
.loaded_page_mut_for_protocol_access_for_route(session_id_ref, owner_route)
|
||||
.loaded_page_mut_for_protocol_access_for_owner(&owner_scope)
|
||||
.ok()
|
||||
else {
|
||||
return AccessibilityCommandDispatchStep::Complete(CommandOutputPlan::error(
|
||||
|
||||
@@ -147,10 +147,10 @@ impl MainDocumentNavigationActivity {
|
||||
self.emit_navigation_result_from_state_into_buffer(out);
|
||||
}
|
||||
let mut target_info_events = Vec::new();
|
||||
crate::domains::target::emit_target_info_changed_for_session_owner_background_event(
|
||||
crate::domains::target::emit_target_info_changed_for_owner_background_event(
|
||||
conn,
|
||||
&mut target_info_events,
|
||||
self.state.owner.session_id(),
|
||||
&self.state.owner,
|
||||
);
|
||||
out.extend_background_events_after_messages(target_info_events);
|
||||
if timing_enabled {
|
||||
@@ -313,17 +313,10 @@ impl MainDocumentNavigationActivity {
|
||||
// The document token is the document identity. A same-document
|
||||
// navigation may update the target URL between DCL and load, but
|
||||
// it must not make the current document's load completion stale.
|
||||
return conn.accepts_document_body_completion_for_route(
|
||||
self.state.owner.session_id(),
|
||||
self.state.owner.session_owner_route(),
|
||||
token,
|
||||
);
|
||||
return conn.accepts_document_body_completion_for_owner(&self.state.owner, token);
|
||||
}
|
||||
conn.runtime_session_owner_target_url_for_route(
|
||||
self.state.owner.session_id(),
|
||||
self.state.owner.session_owner_route(),
|
||||
)
|
||||
.is_some_and(|url| url == self.final_url.as_str())
|
||||
conn.runtime_session_owner_target_url_for_owner(&self.state.owner)
|
||||
.is_some_and(|url| url == self.final_url.as_str())
|
||||
}
|
||||
|
||||
async fn emit_download_navigation_commit_into_buffer_async(
|
||||
@@ -581,7 +574,7 @@ impl MainDocumentNavigationActivity {
|
||||
let error = conn
|
||||
.handle_pending_download_activation_inline_async(
|
||||
&mut download_events,
|
||||
self.state.owner.session_id(),
|
||||
&self.state.owner,
|
||||
download,
|
||||
&mut command_context,
|
||||
)
|
||||
@@ -672,12 +665,7 @@ impl DeferredMainDocumentLoadCompletionAdmission {
|
||||
) -> DeferredMainDocumentLoadCompletionActivity {
|
||||
let is_current = self.is_still_current_for_scheduler(conn);
|
||||
let renderer_page_residence_identity = is_current
|
||||
.then(|| {
|
||||
conn.renderer_page_residence_identity_for_route(
|
||||
self.owner_scope().session_id(),
|
||||
self.owner_scope().session_owner_route(),
|
||||
)
|
||||
})
|
||||
.then(|| conn.renderer_page_residence_identity_for_owner(self.owner_scope()))
|
||||
.flatten();
|
||||
let lifecycle_observer = if is_current {
|
||||
conn.register_exact_renderer_document_lifecycle_observer_for_owner(
|
||||
@@ -1622,8 +1610,11 @@ mod tests {
|
||||
Some(&binding),
|
||||
RendererDocumentLifecycleMilestone::Load,
|
||||
);
|
||||
conn.start_document_navigation_for_route(Some("SID-nav"), None, "LID-2".to_owned())
|
||||
.expect("replacement navigation token");
|
||||
conn.start_document_navigation_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-nav"),
|
||||
"LID-2".to_owned(),
|
||||
)
|
||||
.expect("replacement navigation token");
|
||||
|
||||
assert_eq!(
|
||||
observer.wait().await,
|
||||
@@ -1654,8 +1645,11 @@ mod tests {
|
||||
conn.enqueue_deferred_main_document_load_completion(old_completion);
|
||||
let work = take_deferred_load_work_for_test(&mut conn);
|
||||
|
||||
conn.start_document_navigation_for_route(Some("SID-nav"), None, "LID-2".to_owned())
|
||||
.expect("replacement navigation token");
|
||||
conn.start_document_navigation_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-nav"),
|
||||
"LID-2".to_owned(),
|
||||
)
|
||||
.expect("replacement navigation token");
|
||||
|
||||
assert!(
|
||||
conn.take_scheduler_events().is_empty(),
|
||||
|
||||
@@ -47,11 +47,9 @@ impl PreparedProtocolOutputs {
|
||||
source_document: moli_core::RendererDocumentLifecycleIdentity,
|
||||
item: &moli_core::page::ScriptNetworkOutputItem,
|
||||
) -> Option<Self> {
|
||||
let session_id = owner.session_id();
|
||||
let renderer_live = conn
|
||||
.ingest_renderer_page_network_output_item_and_prepare_live_delivery_for_route(
|
||||
session_id,
|
||||
owner.session_owner_route(),
|
||||
.ingest_renderer_page_network_output_item_and_prepare_live_delivery_for_owner(
|
||||
owner,
|
||||
source_renderer_page,
|
||||
source_document,
|
||||
item,
|
||||
@@ -138,26 +136,11 @@ impl PreparedProtocolOutputs {
|
||||
.append_to_output_sink(&mut prepared);
|
||||
return prepared;
|
||||
}
|
||||
let source_batches = vec![batch.clone()];
|
||||
let batches = conn.route_current_renderer_inspector_output_for_owner(
|
||||
owner,
|
||||
source_batches.clone(),
|
||||
);
|
||||
if batches.is_empty() {
|
||||
crate::domains::runtime::RuntimePreparedOutputs::
|
||||
from_retired_renderer_runtime_inspector_session_responses(
|
||||
conn,
|
||||
owner,
|
||||
&source_batches,
|
||||
)
|
||||
.append_to_output_sink(&mut prepared);
|
||||
return prepared;
|
||||
}
|
||||
crate::domains::runtime::RuntimePreparedOutputs::
|
||||
from_renderer_runtime_inspector_message_batches(
|
||||
from_page_renderer_runtime_inspector_message_batches(
|
||||
conn,
|
||||
owner,
|
||||
&batches,
|
||||
vec![batch.clone()],
|
||||
)
|
||||
.append_to_output_sink(&mut prepared);
|
||||
}
|
||||
@@ -219,7 +202,6 @@ impl PreparedProtocolOutputs {
|
||||
owner: &CommandOwnerScope,
|
||||
action: RendererOwnerAction,
|
||||
) -> Self {
|
||||
let session_id = owner.session_id();
|
||||
let mut prepared = Self::empty();
|
||||
match action {
|
||||
RendererOwnerAction::FileChooser(activation) => {
|
||||
@@ -360,9 +342,7 @@ impl PreparedProtocolOutputs {
|
||||
.append_to_output_sink(&mut prepared);
|
||||
}
|
||||
RendererOwnerAction::SharedWorkerTargetLifecycle(event) => {
|
||||
if let Some((browser_context_id, _)) =
|
||||
conn.target_owner_identity_for_route(session_id, owner.session_owner_route())
|
||||
{
|
||||
if let Some((browser_context_id, _)) = conn.target_owner_identity_for_owner(owner) {
|
||||
crate::domains::target::
|
||||
shared_worker_target_lifecycle_prepared_outputs_for_event(
|
||||
conn,
|
||||
@@ -375,9 +355,7 @@ impl PreparedProtocolOutputs {
|
||||
}
|
||||
}
|
||||
RendererOwnerAction::ServiceWorkerTargetLifecycle(event) => {
|
||||
if let Some((browser_context_id, _)) =
|
||||
conn.target_owner_identity_for_route(session_id, owner.session_owner_route())
|
||||
{
|
||||
if let Some((browser_context_id, _)) = conn.target_owner_identity_for_owner(owner) {
|
||||
crate::domains::target::
|
||||
service_worker_target_lifecycle_prepared_outputs_for_event(
|
||||
conn,
|
||||
|
||||
@@ -28,10 +28,9 @@ fn renderer_owner_action_owner(
|
||||
if publication_owner.session_id().is_some() {
|
||||
return publication_owner.clone();
|
||||
}
|
||||
let Some((browser_context_id, target_id)) = conn.target_owner_identity_for_route(
|
||||
publication_owner.session_id(),
|
||||
publication_owner.session_owner_route(),
|
||||
) else {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
conn.target_owner_identity_for_owner(publication_owner)
|
||||
else {
|
||||
return publication_owner.clone();
|
||||
};
|
||||
let Some(target_id) = target_id else {
|
||||
@@ -132,7 +131,7 @@ async fn ingest_renderer_output_publication(
|
||||
projection,
|
||||
} => {
|
||||
let owner = CommandOwnerScope::for_session(&session_id);
|
||||
project_renderer_output_records_for_route(
|
||||
project_renderer_output_records_for_owner(
|
||||
conn,
|
||||
&owner,
|
||||
records,
|
||||
@@ -148,7 +147,7 @@ async fn ingest_renderer_output_publication(
|
||||
projection,
|
||||
} => {
|
||||
let owner = CommandOwnerScope::for_route(owner_route);
|
||||
project_renderer_output_records_for_route(
|
||||
project_renderer_output_records_for_owner(
|
||||
conn,
|
||||
&owner,
|
||||
records,
|
||||
@@ -162,7 +161,7 @@ async fn ingest_renderer_output_publication(
|
||||
}
|
||||
}
|
||||
|
||||
async fn project_renderer_output_records_for_route(
|
||||
async fn project_renderer_output_records_for_owner(
|
||||
conn: &mut CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
records: Vec<moli_core::RendererOutputRecord>,
|
||||
@@ -301,10 +300,7 @@ mod tests {
|
||||
Some(&RendererRuntimeCommandCausalIdentity::new(None, 2)),
|
||||
);
|
||||
assert_eq!(
|
||||
conn.target_owner_identity_for_route(
|
||||
implicit.session_id(),
|
||||
implicit.session_owner_route(),
|
||||
),
|
||||
conn.target_owner_identity_for_owner(&implicit,),
|
||||
Some((
|
||||
"BID-owner-action".to_owned(),
|
||||
Some("TID-owner-action".to_owned()),
|
||||
|
||||
@@ -157,14 +157,10 @@ impl RuntimeCommandCausalOwner {
|
||||
}
|
||||
|
||||
fn capture_for_scope(conn: &CdpConnection, scope: &CommandOwnerScope) -> Option<Self> {
|
||||
if let Some(page) = conn.target_page_residence_identity_for_route(
|
||||
scope.session_id(),
|
||||
scope.session_owner_route(),
|
||||
) {
|
||||
if let Some(page) = conn.target_page_residence_identity_for_owner(scope) {
|
||||
return Some(Self::Page(page));
|
||||
}
|
||||
let (browser_context_id, target_id) =
|
||||
conn.target_owner_identity_for_route(scope.session_id(), scope.session_owner_route())?;
|
||||
let (browser_context_id, target_id) = conn.target_owner_identity_for_owner(scope)?;
|
||||
Some(Self::Target {
|
||||
browser_context_id,
|
||||
target_id,
|
||||
|
||||
@@ -43,9 +43,8 @@ impl PreparedSubresourceContinueAction {
|
||||
event: PendingSubresourceContinueEvent,
|
||||
) -> Self {
|
||||
let internal_id = Self::internal_id(&event);
|
||||
let request = conn.claim_subresource_continue_request_for_route(
|
||||
command_owner.session_id(),
|
||||
command_owner.session_owner_route(),
|
||||
let request = conn.claim_subresource_continue_request_for_owner(
|
||||
command_owner,
|
||||
&owner,
|
||||
internal_id,
|
||||
matches!(&event, PendingSubresourceContinueEvent::Completed { .. }),
|
||||
@@ -64,10 +63,7 @@ impl PreparedSubresourceContinueAction {
|
||||
event: PendingSubresourceContinueEvent,
|
||||
) -> Option<Self> {
|
||||
let command_owner = CommandOwnerScope::capture(conn, session_id);
|
||||
let owner = conn.target_page_residence_identity_for_route(
|
||||
command_owner.session_id(),
|
||||
command_owner.session_owner_route(),
|
||||
)?;
|
||||
let owner = conn.target_page_residence_identity_for_owner(&command_owner)?;
|
||||
Some(Self::capture(conn, &command_owner, owner, event))
|
||||
}
|
||||
}
|
||||
@@ -78,17 +74,12 @@ pub(in crate::domains) fn prepare_subresource_continue_action_for_renderer_recor
|
||||
source_document: moli_core::RendererDocumentLifecycleIdentity,
|
||||
event: PendingSubresourceContinueEvent,
|
||||
) -> Option<PreparedSubresourceContinueAction> {
|
||||
if conn.target_root_document_lifecycle_identity_for_route(
|
||||
command_owner.session_id(),
|
||||
command_owner.session_owner_route(),
|
||||
) != Some(source_document)
|
||||
if conn.target_root_document_lifecycle_identity_for_owner(command_owner)
|
||||
!= Some(source_document)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
let owner = conn.target_page_residence_identity_for_route(
|
||||
command_owner.session_id(),
|
||||
command_owner.session_owner_route(),
|
||||
)?;
|
||||
let owner = conn.target_page_residence_identity_for_owner(command_owner)?;
|
||||
Some(PreparedSubresourceContinueAction::capture(
|
||||
conn,
|
||||
command_owner,
|
||||
@@ -104,10 +95,7 @@ pub(in crate::domains) async fn flush_prepared_subresource_continue_actions_back
|
||||
actions: Vec<PreparedSubresourceContinueAction>,
|
||||
) {
|
||||
for action in actions {
|
||||
if conn.target_page_residence_identity_is_current_for_session(
|
||||
command_owner.session_id(),
|
||||
&action.owner,
|
||||
) {
|
||||
if conn.target_page_residence_identity_is_current(&action.owner) {
|
||||
flush_prepared_subresource_continue_action_background_events_async(
|
||||
conn,
|
||||
out,
|
||||
@@ -126,9 +114,8 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
action: PreparedSubresourceContinueAction,
|
||||
) {
|
||||
let session_id = command_owner.session_id();
|
||||
let owner_route = command_owner.session_owner_route();
|
||||
let PreparedSubresourceContinueAction { event, request, .. } = action;
|
||||
let fetch_session_id = conn.target_fetch_event_session_id_for_route(session_id, owner_route);
|
||||
let fetch_session_id = conn.target_fetch_event_session_id_for_owner(command_owner);
|
||||
let fetch_event_session_id = fetch_session_id.as_deref().or(session_id);
|
||||
|
||||
match event {
|
||||
@@ -160,9 +147,8 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
};
|
||||
let Some(request_id) = in_flight.request_id else {
|
||||
let _ = conn
|
||||
.continue_pending_subresource_response_for_route_async(
|
||||
session_id,
|
||||
owner_route,
|
||||
.continue_pending_subresource_response_for_owner_async(
|
||||
command_owner,
|
||||
response_info.internal_id,
|
||||
None,
|
||||
None,
|
||||
@@ -183,10 +169,7 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
.response_stage_url_match_policy
|
||||
.requires_final_url_match()
|
||||
&& !conn
|
||||
.target_fetch_subresource_interception_snapshot_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
)
|
||||
.target_fetch_subresource_interception_snapshot_for_owner(command_owner)
|
||||
.is_some_and(|snapshot| {
|
||||
snapshot.matches_response_stage(
|
||||
response_info.resource_type.into(),
|
||||
@@ -195,9 +178,8 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
})
|
||||
{
|
||||
let _ = conn
|
||||
.continue_pending_subresource_response_for_route_async(
|
||||
session_id,
|
||||
owner_route,
|
||||
.continue_pending_subresource_response_for_owner_async(
|
||||
command_owner,
|
||||
response_info.internal_id,
|
||||
None,
|
||||
None,
|
||||
@@ -215,18 +197,15 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
return;
|
||||
}
|
||||
let blocked_intercepts = if in_flight.response_stage_blocked_intercepts.is_empty() {
|
||||
conn.target_fetch_subresource_interception_snapshot_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
)
|
||||
.map(|snapshot| {
|
||||
snapshot.matching_network_intercepts(
|
||||
FetchRequestStage::Response,
|
||||
response_info.resource_type.into(),
|
||||
&response_info.final_url,
|
||||
)
|
||||
})
|
||||
.unwrap_or_default()
|
||||
conn.target_fetch_subresource_interception_snapshot_for_owner(command_owner)
|
||||
.map(|snapshot| {
|
||||
snapshot.matching_network_intercepts(
|
||||
FetchRequestStage::Response,
|
||||
response_info.resource_type.into(),
|
||||
&response_info.final_url,
|
||||
)
|
||||
})
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
in_flight.response_stage_blocked_intercepts.clone()
|
||||
};
|
||||
@@ -248,10 +227,7 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
&in_flight.pending.frame_id,
|
||||
)
|
||||
.or_else(|| {
|
||||
conn.target_fetch_subresource_interception_snapshot_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
)
|
||||
conn.target_fetch_subresource_interception_snapshot_for_owner(command_owner)
|
||||
})
|
||||
.map(|snapshot| {
|
||||
snapshot.matching_response_stage_pause_sessions(
|
||||
@@ -277,10 +253,7 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
let mut remaining_sessions = Vec::new();
|
||||
for session in response_stage_sessions.into_iter().skip(1) {
|
||||
let Ok((next_request_id, _)) = conn
|
||||
.allocate_pending_subresource_fetch_request_ids_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
)
|
||||
.allocate_pending_subresource_fetch_request_ids_for_owner(command_owner)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
@@ -305,13 +278,11 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
pending_response.action_session_id = response_event_session_id.clone();
|
||||
let pending_owner_session_id = pending_response.owner_session_id.clone();
|
||||
let pending_owner_session_id = pending_owner_session_id.as_deref().or(session_id);
|
||||
let pending_owner_route = pending_owner_session_id
|
||||
.is_none()
|
||||
.then_some(owner_route)
|
||||
.flatten();
|
||||
if !conn.register_pending_subresource_fetch_response_request_for_route(
|
||||
pending_owner_session_id,
|
||||
pending_owner_route,
|
||||
let pending_owner = pending_owner_session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| command_owner.clone());
|
||||
if !conn.register_pending_subresource_fetch_response_request_for_owner(
|
||||
&pending_owner,
|
||||
request_id.clone(),
|
||||
pending_response.clone(),
|
||||
) {
|
||||
@@ -332,9 +303,8 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
};
|
||||
let Some(request_id) = in_flight.request_id else {
|
||||
let _ = conn
|
||||
.fail_pending_subresource_auth_for_route_async(
|
||||
session_id,
|
||||
owner_route,
|
||||
.fail_pending_subresource_auth_for_owner_async(
|
||||
command_owner,
|
||||
auth_info.internal_id,
|
||||
"Fetch auth challenge has no DevTools request".to_owned(),
|
||||
)
|
||||
@@ -351,7 +321,7 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
return;
|
||||
};
|
||||
let blocked_intercepts = conn
|
||||
.target_fetch_subresource_interception_snapshot_for_route(session_id, owner_route)
|
||||
.target_fetch_subresource_interception_snapshot_for_owner(command_owner)
|
||||
.map(|snapshot| snapshot.matching_auth_required_network_intercepts(&auth_info.url))
|
||||
.unwrap_or_default();
|
||||
let blocked_intercepts = if blocked_intercepts.is_empty() {
|
||||
@@ -376,10 +346,7 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
&in_flight.pending.frame_id,
|
||||
)
|
||||
.or_else(|| {
|
||||
conn.target_fetch_subresource_interception_snapshot_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
)
|
||||
conn.target_fetch_subresource_interception_snapshot_for_owner(command_owner)
|
||||
})
|
||||
.map(|snapshot| {
|
||||
snapshot.matching_auth_required_pause_sessions(session_id, &auth_info.url)
|
||||
@@ -401,10 +368,7 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
let mut remaining_sessions = Vec::new();
|
||||
for session in auth_sessions.into_iter().skip(1) {
|
||||
let Ok((next_request_id, _)) = conn
|
||||
.allocate_pending_subresource_fetch_request_ids_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
)
|
||||
.allocate_pending_subresource_fetch_request_ids_for_owner(command_owner)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
@@ -429,13 +393,11 @@ async fn flush_prepared_subresource_continue_action_background_events_async(
|
||||
pending_auth.action_session_id = auth_event_session_id.clone();
|
||||
let pending_owner_session_id = pending_auth.owner_session_id.clone();
|
||||
let pending_owner_session_id = pending_owner_session_id.as_deref().or(session_id);
|
||||
let pending_owner_route = pending_owner_session_id
|
||||
.is_none()
|
||||
.then_some(owner_route)
|
||||
.flatten();
|
||||
if !conn.register_pending_subresource_fetch_auth_request_for_route(
|
||||
pending_owner_session_id,
|
||||
pending_owner_route,
|
||||
let pending_owner = pending_owner_session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| command_owner.clone());
|
||||
if !conn.register_pending_subresource_fetch_auth_request_for_owner(
|
||||
&pending_owner,
|
||||
request_id.clone(),
|
||||
pending_auth.clone(),
|
||||
) {
|
||||
@@ -658,10 +620,7 @@ async fn flush_post_subresource_network_activity_background_events_async(
|
||||
frame_id: &str,
|
||||
network_request_id: &str,
|
||||
) {
|
||||
conn.ingest_runtime_session_owner_output_updates_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
conn.ingest_runtime_session_owner_output_updates_for_owner(owner);
|
||||
project_network_backlog_for_owner(conn, out, owner, frame_id, Some(network_request_id));
|
||||
clear_fetch_pause_network_announcement(conn, owner, network_request_id);
|
||||
}
|
||||
@@ -692,9 +651,7 @@ fn clear_fetch_pause_network_announcement(
|
||||
owner: &CommandOwnerScope,
|
||||
request_id: &str,
|
||||
) {
|
||||
if let Ok(runtime_slot) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
{
|
||||
if let Ok(runtime_slot) = conn.runtime_session_owner_slot_mut_for_owner(owner) {
|
||||
runtime_slot.clear_fetch_pause_announced_request_id(request_id);
|
||||
}
|
||||
}
|
||||
@@ -708,9 +665,7 @@ fn record_subresource_network_request_handle(
|
||||
let Some(request_handle) = request_handle else {
|
||||
return;
|
||||
};
|
||||
if let Ok(runtime_slot) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
{
|
||||
if let Ok(runtime_slot) = conn.runtime_session_owner_slot_mut_for_owner(owner) {
|
||||
runtime_slot.record_subresource_request_id_for_handle_if_absent(
|
||||
request_handle,
|
||||
request_id.to_owned(),
|
||||
|
||||
@@ -130,10 +130,8 @@ pub(crate) fn complete_pending_autofill_command(
|
||||
conn: &mut CdpConnection,
|
||||
completed: CompletedAutofillCommandDispatch,
|
||||
) -> CommandOutputPlan {
|
||||
let session_id = completed.owner_scope.session_id();
|
||||
let owner_route = completed.owner_scope.session_owner_route();
|
||||
let outcome = completed.completed.and_then(|completion| {
|
||||
conn.loaded_page_mut_for_protocol_access_for_route(session_id, owner_route)
|
||||
conn.loaded_page_mut_for_protocol_access_for_owner(&completed.owner_scope)
|
||||
.and_then(|page| {
|
||||
page.finish_autofill_trigger(completion)
|
||||
.map_err(|error| error.to_string())
|
||||
|
||||
@@ -399,10 +399,7 @@ pub(crate) fn complete_pending_css_command(
|
||||
} = completed;
|
||||
let session_id = owner_scope.session_id();
|
||||
let Some(page) = conn
|
||||
.loaded_page_mut_for_protocol_access_for_route(
|
||||
session_id,
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.loaded_page_mut_for_protocol_access_for_owner(&owner_scope)
|
||||
.ok()
|
||||
else {
|
||||
return CssCommandDispatchStep::Complete(CommandOutputPlan::error(
|
||||
|
||||
@@ -152,11 +152,14 @@ mod tests {
|
||||
.map(str::to_owned)
|
||||
.expect("Debugger.scriptParsed for the suspended-renderer source");
|
||||
|
||||
let navigation_owner = CommandOwnerScope::capture(&ctx.conn, None);
|
||||
let navigation = ctx
|
||||
.conn
|
||||
.start_document_navigation_for_route(None, None, "LOADER-debugger-interrupt".to_owned())
|
||||
.start_document_navigation_for_owner(
|
||||
&navigation_owner,
|
||||
"LOADER-debugger-interrupt".to_owned(),
|
||||
)
|
||||
.expect("start cross-Document navigation");
|
||||
let navigation_owner = CommandOwnerScope::capture(&ctx.conn, None);
|
||||
assert!(
|
||||
ctx.conn
|
||||
.renderer_document_navigation_is_suspended_for_session_owner(None)
|
||||
|
||||
@@ -145,15 +145,12 @@ pub(crate) fn dom_agent_enabled_for_session(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
) -> bool {
|
||||
dom_agent_enabled_for_route(conn, session_id, None)
|
||||
let owner = CommandOwnerScope::capture(conn, session_id);
|
||||
dom_agent_enabled_for_owner(conn, &owner)
|
||||
}
|
||||
|
||||
pub(crate) fn dom_agent_enabled_for_route(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
) -> bool {
|
||||
conn.target_devtools_session_state_for_route(session_id, owner_route)
|
||||
pub(crate) fn dom_agent_enabled_for_owner(conn: &CdpConnection, owner: &CommandOwnerScope) -> bool {
|
||||
conn.target_devtools_session_state_for_owner(owner)
|
||||
.is_some_and(|state| state.dom_session_state.enabled)
|
||||
}
|
||||
|
||||
@@ -179,12 +176,11 @@ fn disable_dom_agent_for_session(conn: &mut CdpConnection, session_id: Option<&s
|
||||
.is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn dom_agent_includes_whitespace_for_route(
|
||||
pub(crate) fn dom_agent_includes_whitespace_for_owner(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
conn.target_devtools_session_state_for_route(session_id, owner_route)
|
||||
conn.target_devtools_session_state_for_owner(owner)
|
||||
.is_some_and(|state| {
|
||||
state.dom_session_state.enabled && state.dom_session_state.include_whitespace
|
||||
})
|
||||
@@ -194,25 +190,19 @@ fn loaded_page_mut_for_owner<'a>(
|
||||
conn: &'a mut CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<&'a mut Page> {
|
||||
conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.ok()
|
||||
conn.loaded_page_mut_for_protocol_access_for_owner(owner)
|
||||
.ok()
|
||||
}
|
||||
|
||||
fn target_owner_exists_for_owner(conn: &CdpConnection, owner: &CommandOwnerScope) -> bool {
|
||||
conn.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
conn.target_owner_identity_for_owner(owner)
|
||||
.and_then(|(_, target_id)| target_id)
|
||||
.is_some()
|
||||
}
|
||||
|
||||
fn top_frame_id_for_owner(conn: &CdpConnection, owner: &CommandOwnerScope) -> Option<String> {
|
||||
conn.target_session_owner_frame_tree_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.map(|(frame_id, _, _, _)| frame_id)
|
||||
conn.target_session_owner_frame_tree_identity_for_owner(owner)
|
||||
.map(|(frame_id, _, _, _)| frame_id)
|
||||
}
|
||||
|
||||
fn cached_dom_remote_object_node_for_owner(
|
||||
@@ -220,8 +210,7 @@ fn cached_dom_remote_object_node_for_owner(
|
||||
owner: &CommandOwnerScope,
|
||||
object_id: &str,
|
||||
) -> Option<Value> {
|
||||
let (browser_context_id, target_id) =
|
||||
conn.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())?;
|
||||
let (browser_context_id, target_id) = conn.target_owner_identity_for_owner(owner)?;
|
||||
let browser_context = conn.browser_context_by_id(&browser_context_id)?;
|
||||
let target_id = target_id
|
||||
.as_deref()
|
||||
@@ -239,9 +228,7 @@ fn cache_dom_remote_object_node_for_owner(
|
||||
object_id: String,
|
||||
node: Value,
|
||||
) {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
conn.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
else {
|
||||
let Some((browser_context_id, target_id)) = conn.target_owner_identity_for_owner(owner) else {
|
||||
return;
|
||||
};
|
||||
if let Some(browser_context) = conn.browser_context_by_id_mut(&browser_context_id) {
|
||||
|
||||
@@ -87,10 +87,7 @@ impl DomPreparedOutputs {
|
||||
batches: &[RendererDomMutationEventBatch],
|
||||
) -> Self {
|
||||
let current_attachment = conn
|
||||
.runtime_session_owner_slot_for_route(
|
||||
source_owner.session_id(),
|
||||
source_owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_for_owner(source_owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.current_renderer_attachment());
|
||||
Self {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use serde_json::json;
|
||||
|
||||
use super::{
|
||||
dom_agent_includes_whitespace_for_route, frontend_binding, node_snapshot_to_cdp,
|
||||
dom_agent_includes_whitespace_for_owner, frontend_binding, node_snapshot_to_cdp,
|
||||
resolve::{
|
||||
PendingDomCommandStartError, attributes_result_from_renderer_resolution,
|
||||
devtools_dom_geometry_result_from_renderer, property_result_from_renderer_resolution,
|
||||
@@ -9,12 +9,12 @@ use super::{
|
||||
text_result_from_renderer_resolution,
|
||||
},
|
||||
};
|
||||
use crate::conn::{CdpConnection, CdpSessionRoute};
|
||||
use crate::conn::{CdpConnection, CommandOwnerScope};
|
||||
use crate::devtools_runtime::{
|
||||
DevToolsCommand, DevToolsCommandResult, DevToolsDescribeNodeCommand,
|
||||
DevToolsDescribeNodeResult, DevToolsDomGeometryCommand, DevToolsDomGeometryResult,
|
||||
DevToolsDomNodeReference, DevToolsGetAttributesResult, DevToolsGetOuterHtmlCommand,
|
||||
DevToolsGetOuterHtmlResult, DevToolsGetPropertyResult, DevToolsGetTextResult, DevToolsProtocol,
|
||||
DevToolsGetOuterHtmlResult, DevToolsGetPropertyResult, DevToolsGetTextResult,
|
||||
DevToolsQuerySelectorResult, DevToolsResolveNodeCommand, DevToolsResolveNodeResult,
|
||||
DevToolsScrollIntoViewIfNeededCommand,
|
||||
};
|
||||
@@ -23,24 +23,32 @@ use moli_core::page::{
|
||||
RendererDocumentNodeReference,
|
||||
};
|
||||
|
||||
fn loaded_page_mut_for_route<'a>(
|
||||
fn loaded_page_mut_for_owner<'a>(
|
||||
conn: &'a mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: &CdpSessionRoute,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<&'a mut Page> {
|
||||
conn.loaded_page_mut_for_protocol_access_for_route(session_id, Some(owner_route))
|
||||
conn.loaded_page_mut_for_protocol_access_for_owner(owner)
|
||||
.ok()
|
||||
}
|
||||
|
||||
fn renderer_inspector_session_id_for_owner(
|
||||
conn: &CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<String> {
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner)
|
||||
}
|
||||
|
||||
pub(super) async fn execute_devtools_dom_command(
|
||||
conn: &mut CdpConnection,
|
||||
frame_id: &str,
|
||||
owner: &CommandOwnerScope,
|
||||
command: DevToolsCommand,
|
||||
) -> Result<DevToolsCommandResult, PendingDomCommandStartError> {
|
||||
match command {
|
||||
DevToolsCommand::QuerySelector(command) => {
|
||||
let result = query_selector_command(
|
||||
conn,
|
||||
owner,
|
||||
frame_id,
|
||||
command.root,
|
||||
&command.selector,
|
||||
@@ -50,47 +58,43 @@ pub(super) async fn execute_devtools_dom_command(
|
||||
Ok(DevToolsCommandResult::QuerySelector(result))
|
||||
}
|
||||
DevToolsCommand::GetAttributes(command) => {
|
||||
let result = attributes_command(conn, frame_id, command.reference).await?;
|
||||
let result = attributes_command(conn, owner, command.reference).await?;
|
||||
Ok(DevToolsCommandResult::GetAttributes(result))
|
||||
}
|
||||
DevToolsCommand::GetText(command) => {
|
||||
let result = text_command(conn, frame_id, command.reference).await?;
|
||||
let result = text_command(conn, owner, command.reference).await?;
|
||||
Ok(DevToolsCommandResult::GetText(result))
|
||||
}
|
||||
DevToolsCommand::GetProperty(command) => {
|
||||
let result = property_command(conn, frame_id, command.reference, &command.name).await?;
|
||||
let result = property_command(conn, owner, command.reference, &command.name).await?;
|
||||
Ok(DevToolsCommandResult::GetProperty(result))
|
||||
}
|
||||
DevToolsCommand::GetOuterHtml(command) => {
|
||||
let DevToolsGetOuterHtmlCommand {
|
||||
context,
|
||||
context: _,
|
||||
reference,
|
||||
include_shadow_dom,
|
||||
} = command;
|
||||
let session_id = (context.protocol == DevToolsProtocol::Cdp)
|
||||
.then(|| context.session_id.as_ref().map(|id| id.as_str()))
|
||||
.flatten();
|
||||
let outer_html =
|
||||
outer_html_command(conn, session_id, frame_id, reference, include_shadow_dom)
|
||||
.await?;
|
||||
outer_html_command(conn, owner, frame_id, reference, include_shadow_dom).await?;
|
||||
Ok(DevToolsCommandResult::GetOuterHtml(
|
||||
DevToolsGetOuterHtmlResult { outer_html },
|
||||
))
|
||||
}
|
||||
DevToolsCommand::DescribeNode(command) => {
|
||||
let result = describe_node_command(conn, frame_id, command).await?;
|
||||
let result = describe_node_command(conn, owner, frame_id, command).await?;
|
||||
Ok(DevToolsCommandResult::DescribeNode(result))
|
||||
}
|
||||
DevToolsCommand::ResolveNode(command) => {
|
||||
let result = resolve_node_command(conn, frame_id, command).await?;
|
||||
let result = resolve_node_command(conn, owner, command).await?;
|
||||
Ok(DevToolsCommandResult::ResolveNode(result))
|
||||
}
|
||||
DevToolsCommand::DomGeometry(command) => {
|
||||
let result = dom_geometry_command(conn, frame_id, command).await?;
|
||||
let result = dom_geometry_command(conn, owner, command).await?;
|
||||
Ok(DevToolsCommandResult::DomGeometry(result))
|
||||
}
|
||||
DevToolsCommand::ScrollIntoViewIfNeeded(command) => {
|
||||
scroll_into_view_if_needed_command(conn, frame_id, command).await?;
|
||||
scroll_into_view_if_needed_command(conn, owner, command).await?;
|
||||
Ok(DevToolsCommandResult::Empty)
|
||||
}
|
||||
_ => Err(PendingDomCommandStartError::no_such_target()),
|
||||
@@ -99,43 +103,27 @@ pub(super) async fn execute_devtools_dom_command(
|
||||
|
||||
async fn query_selector_command(
|
||||
conn: &mut CdpConnection,
|
||||
frame_id: &str,
|
||||
root: Option<DevToolsDomNodeReference>,
|
||||
selector: &str,
|
||||
multiple: bool,
|
||||
) -> Result<DevToolsQuerySelectorResult, PendingDomCommandStartError> {
|
||||
let route = conn
|
||||
.target_session_route_for_child_frame_id(frame_id)
|
||||
.ok_or_else(PendingDomCommandStartError::no_such_target)?;
|
||||
query_selector_command_in_session(conn, None, &route, frame_id, root, selector, multiple).await
|
||||
}
|
||||
|
||||
async fn query_selector_command_in_session(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: &CdpSessionRoute,
|
||||
owner: &CommandOwnerScope,
|
||||
frame_id: &str,
|
||||
root: Option<DevToolsDomNodeReference>,
|
||||
selector: &str,
|
||||
multiple: bool,
|
||||
) -> Result<DevToolsQuerySelectorResult, PendingDomCommandStartError> {
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_route(session_id, Some(owner_route));
|
||||
let include_whitespace =
|
||||
dom_agent_includes_whitespace_for_route(conn, session_id, Some(owner_route));
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
let root_backend_node_id = match root {
|
||||
Some(reference) => {
|
||||
let reference =
|
||||
resolve_frontend_node_reference(conn, session_id, owner_route, reference).await?;
|
||||
let reference = resolve_frontend_node_reference(conn, owner, reference).await?;
|
||||
required_child_frame_backend_node_id(&reference)?
|
||||
}
|
||||
None => {
|
||||
child_frame_document_root_node_reference(conn, session_id, owner_route, frame_id)
|
||||
child_frame_document_root_node_reference(conn, owner, frame_id)
|
||||
.await?
|
||||
.backend_node_id
|
||||
}
|
||||
};
|
||||
let page = loaded_page_mut_for_route(conn, session_id, owner_route)
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
.start_child_frame_document_query_selector_for_backend_node_id(
|
||||
@@ -159,16 +147,14 @@ async fn query_selector_command_in_session(
|
||||
|
||||
async fn resolve_frontend_node_reference(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: &CdpSessionRoute,
|
||||
owner: &CommandOwnerScope,
|
||||
reference: DevToolsDomNodeReference,
|
||||
) -> Result<DevToolsDomNodeReference, PendingDomCommandStartError> {
|
||||
let DevToolsDomNodeReference::FrontendNodeId(frontend_node_id) = reference else {
|
||||
return Ok(reference);
|
||||
};
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_route(session_id, Some(owner_route));
|
||||
let page = loaded_page_mut_for_route(conn, session_id, owner_route)
|
||||
let renderer_inspector_session_id = renderer_inspector_session_id_for_owner(conn, owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
.start_document_frontend_node_binding(renderer_inspector_session_id, frontend_node_id)
|
||||
@@ -177,7 +163,7 @@ async fn resolve_frontend_node_reference(
|
||||
.wait()
|
||||
.await
|
||||
.map_err(PendingDomCommandStartError::renderer_error)?;
|
||||
let page = loaded_page_mut_for_route(conn, session_id, owner_route)
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
frontend_binding::finish_reference(page, completion).map_err(|message| {
|
||||
PendingDomCommandStartError {
|
||||
@@ -189,13 +175,11 @@ async fn resolve_frontend_node_reference(
|
||||
|
||||
async fn child_frame_document_root_node_reference(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: &CdpSessionRoute,
|
||||
owner: &CommandOwnerScope,
|
||||
frame_id: &str,
|
||||
) -> Result<RendererDocumentNodeReference, PendingDomCommandStartError> {
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_route(session_id, Some(owner_route));
|
||||
let page = loaded_page_mut_for_route(conn, session_id, owner_route)
|
||||
let renderer_inspector_session_id = renderer_inspector_session_id_for_owner(conn, owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
.start_child_frame_document_root_node_reference(frame_id, renderer_inspector_session_id)
|
||||
@@ -204,7 +188,7 @@ async fn child_frame_document_root_node_reference(
|
||||
.wait()
|
||||
.await
|
||||
.map_err(PendingDomCommandStartError::renderer_error)?;
|
||||
let page = loaded_page_mut_for_route(conn, session_id, owner_route)
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
page.finish_document_node_reference(completion)
|
||||
.map_err(PendingDomCommandStartError::renderer_error)?
|
||||
@@ -213,14 +197,11 @@ async fn child_frame_document_root_node_reference(
|
||||
|
||||
async fn attributes_command(
|
||||
conn: &mut CdpConnection,
|
||||
frame_id: &str,
|
||||
owner: &CommandOwnerScope,
|
||||
reference: DevToolsDomNodeReference,
|
||||
) -> Result<DevToolsGetAttributesResult, PendingDomCommandStartError> {
|
||||
let route = conn
|
||||
.target_session_route_for_child_frame_id(frame_id)
|
||||
.ok_or_else(PendingDomCommandStartError::no_such_target)?;
|
||||
let reference = resolve_frontend_node_reference(conn, None, &route, reference).await?;
|
||||
let page = loaded_page_mut_for_route(conn, None, &route)
|
||||
let reference = resolve_frontend_node_reference(conn, owner, reference).await?;
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = start_document_node_attributes_for_reference(page, reference)?;
|
||||
let completion = pending
|
||||
@@ -243,14 +224,11 @@ fn start_document_node_attributes_for_reference(
|
||||
|
||||
async fn text_command(
|
||||
conn: &mut CdpConnection,
|
||||
frame_id: &str,
|
||||
owner: &CommandOwnerScope,
|
||||
reference: DevToolsDomNodeReference,
|
||||
) -> Result<DevToolsGetTextResult, PendingDomCommandStartError> {
|
||||
let route = conn
|
||||
.target_session_route_for_child_frame_id(frame_id)
|
||||
.ok_or_else(PendingDomCommandStartError::no_such_target)?;
|
||||
let reference = resolve_frontend_node_reference(conn, None, &route, reference).await?;
|
||||
let page = loaded_page_mut_for_route(conn, None, &route)
|
||||
let reference = resolve_frontend_node_reference(conn, owner, reference).await?;
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = start_document_node_text_for_reference(page, reference)?;
|
||||
let completion = pending
|
||||
@@ -273,15 +251,12 @@ fn start_document_node_text_for_reference(
|
||||
|
||||
async fn property_command(
|
||||
conn: &mut CdpConnection,
|
||||
frame_id: &str,
|
||||
owner: &CommandOwnerScope,
|
||||
reference: DevToolsDomNodeReference,
|
||||
name: &str,
|
||||
) -> Result<DevToolsGetPropertyResult, PendingDomCommandStartError> {
|
||||
let route = conn
|
||||
.target_session_route_for_child_frame_id(frame_id)
|
||||
.ok_or_else(PendingDomCommandStartError::no_such_target)?;
|
||||
let reference = resolve_frontend_node_reference(conn, None, &route, reference).await?;
|
||||
let page = loaded_page_mut_for_route(conn, None, &route)
|
||||
let reference = resolve_frontend_node_reference(conn, owner, reference).await?;
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = start_document_node_property_for_reference(page, reference, name)?;
|
||||
let completion = pending
|
||||
@@ -305,48 +280,24 @@ fn start_document_node_property_for_reference(
|
||||
|
||||
async fn outer_html_command(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
frame_id: &str,
|
||||
reference: Option<DevToolsDomNodeReference>,
|
||||
include_shadow_dom: bool,
|
||||
) -> Result<String, PendingDomCommandStartError> {
|
||||
let route = conn
|
||||
.target_session_route_for_child_frame_id(frame_id)
|
||||
.ok_or_else(PendingDomCommandStartError::no_such_target)?;
|
||||
outer_html_command_in_session(
|
||||
conn,
|
||||
session_id,
|
||||
&route,
|
||||
frame_id,
|
||||
reference,
|
||||
include_shadow_dom,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn outer_html_command_in_session(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: &CdpSessionRoute,
|
||||
owner: &CommandOwnerScope,
|
||||
frame_id: &str,
|
||||
reference: Option<DevToolsDomNodeReference>,
|
||||
include_shadow_dom: bool,
|
||||
) -> Result<String, PendingDomCommandStartError> {
|
||||
let reference = match reference {
|
||||
Some(reference) => {
|
||||
Some(resolve_frontend_node_reference(conn, session_id, owner_route, reference).await?)
|
||||
}
|
||||
Some(reference) => Some(resolve_frontend_node_reference(conn, owner, reference).await?),
|
||||
None => None,
|
||||
};
|
||||
let backend_node_id = match reference {
|
||||
Some(reference) => required_child_frame_backend_node_id(&reference)?,
|
||||
None => {
|
||||
child_frame_document_root_node_reference(conn, session_id, owner_route, frame_id)
|
||||
child_frame_document_root_node_reference(conn, owner, frame_id)
|
||||
.await?
|
||||
.backend_node_id
|
||||
}
|
||||
};
|
||||
let page = loaded_page_mut_for_route(conn, session_id, owner_route)
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
.start_outer_html_for_backend_node_id(backend_node_id, include_shadow_dom)
|
||||
@@ -362,28 +313,14 @@ async fn outer_html_command_in_session(
|
||||
|
||||
async fn resolve_node_command(
|
||||
conn: &mut CdpConnection,
|
||||
frame_id: &str,
|
||||
owner: &CommandOwnerScope,
|
||||
command: DevToolsResolveNodeCommand,
|
||||
) -> Result<DevToolsResolveNodeResult, PendingDomCommandStartError> {
|
||||
let route = conn
|
||||
.target_session_route_for_child_frame_id(frame_id)
|
||||
.ok_or_else(PendingDomCommandStartError::no_such_target)?;
|
||||
resolve_node_command_in_session(conn, None, &route, command).await
|
||||
}
|
||||
|
||||
async fn resolve_node_command_in_session(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: &CdpSessionRoute,
|
||||
command: DevToolsResolveNodeCommand,
|
||||
) -> Result<DevToolsResolveNodeResult, PendingDomCommandStartError> {
|
||||
let reference =
|
||||
resolve_frontend_node_reference(conn, session_id, owner_route, command.reference).await?;
|
||||
let reference = resolve_frontend_node_reference(conn, owner, command.reference).await?;
|
||||
let object_group = command.object_group;
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_route(session_id, Some(owner_route));
|
||||
let renderer_inspector_session_id = renderer_inspector_session_id_for_owner(conn, owner);
|
||||
let remote_object = {
|
||||
let page = loaded_page_mut_for_route(conn, session_id, owner_route)
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let backend_node_id = required_child_frame_backend_node_id(&reference)?;
|
||||
let pending = page
|
||||
@@ -422,18 +359,13 @@ async fn resolve_node_command_in_session(
|
||||
}
|
||||
let result = json!({ "object": remote_object.clone() });
|
||||
if let Some(object_group) = object_group.as_deref() {
|
||||
conn.register_runtime_remote_object_ids_from_value_for_route_with_group(
|
||||
session_id,
|
||||
Some(owner_route),
|
||||
conn.register_runtime_remote_object_ids_from_value_for_owner_with_group(
|
||||
owner,
|
||||
&result,
|
||||
object_group,
|
||||
);
|
||||
} else {
|
||||
conn.register_runtime_remote_object_ids_from_value_for_route(
|
||||
session_id,
|
||||
Some(owner_route),
|
||||
&result,
|
||||
);
|
||||
conn.register_runtime_remote_object_ids_from_value_for_owner(owner, &result);
|
||||
}
|
||||
Ok(DevToolsResolveNodeResult {
|
||||
object: remote_object,
|
||||
@@ -442,24 +374,21 @@ async fn resolve_node_command_in_session(
|
||||
|
||||
async fn describe_node_command(
|
||||
conn: &mut CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
frame_id: &str,
|
||||
command: DevToolsDescribeNodeCommand,
|
||||
) -> Result<DevToolsDescribeNodeResult, PendingDomCommandStartError> {
|
||||
let DevToolsDescribeNodeCommand {
|
||||
context,
|
||||
context: _,
|
||||
reference,
|
||||
depth,
|
||||
pierce,
|
||||
} = command;
|
||||
let session_id = (context.protocol == DevToolsProtocol::Cdp)
|
||||
.then(|| context.session_id.as_ref().map(|id| id.as_str()))
|
||||
.flatten();
|
||||
let snapshot = match reference {
|
||||
Some(reference) => {
|
||||
node_snapshot_for_reference(conn, session_id, frame_id, reference, depth, pierce)
|
||||
.await?
|
||||
node_snapshot_for_reference(conn, owner, reference, depth, pierce).await?
|
||||
}
|
||||
None => child_frame_root_node_snapshot(conn, session_id, frame_id, depth, pierce).await?,
|
||||
None => child_frame_root_node_snapshot(conn, owner, frame_id, depth, pierce).await?,
|
||||
};
|
||||
let Some(node) = node_snapshot_to_cdp(&snapshot, Some(snapshot.node_id), Some(frame_id)) else {
|
||||
return Err(PendingDomCommandStartError::node_not_found());
|
||||
@@ -469,33 +398,15 @@ async fn describe_node_command(
|
||||
|
||||
async fn node_snapshot_for_reference(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
frame_id: &str,
|
||||
owner: &CommandOwnerScope,
|
||||
reference: DevToolsDomNodeReference,
|
||||
depth: i32,
|
||||
pierce: bool,
|
||||
) -> Result<moli_core::page::DocumentNodeSnapshot, PendingDomCommandStartError> {
|
||||
let route = conn
|
||||
.target_session_route_for_child_frame_id(frame_id)
|
||||
.ok_or_else(PendingDomCommandStartError::no_such_target)?;
|
||||
node_snapshot_for_reference_in_session(conn, session_id, &route, reference, depth, pierce).await
|
||||
}
|
||||
|
||||
async fn node_snapshot_for_reference_in_session(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: &CdpSessionRoute,
|
||||
reference: DevToolsDomNodeReference,
|
||||
depth: i32,
|
||||
pierce: bool,
|
||||
) -> Result<moli_core::page::DocumentNodeSnapshot, PendingDomCommandStartError> {
|
||||
let reference =
|
||||
resolve_frontend_node_reference(conn, session_id, owner_route, reference).await?;
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_route(session_id, Some(owner_route));
|
||||
let include_whitespace =
|
||||
dom_agent_includes_whitespace_for_route(conn, session_id, Some(owner_route));
|
||||
let page = loaded_page_mut_for_route(conn, session_id, owner_route)
|
||||
let reference = resolve_frontend_node_reference(conn, owner, reference).await?;
|
||||
let renderer_inspector_session_id = renderer_inspector_session_id_for_owner(conn, owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let backend_node_id = required_child_frame_backend_node_id(&reference)?;
|
||||
let pending = page
|
||||
@@ -519,23 +430,17 @@ async fn node_snapshot_for_reference_in_session(
|
||||
|
||||
async fn child_frame_root_node_snapshot(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
frame_id: &str,
|
||||
depth: i32,
|
||||
pierce: bool,
|
||||
) -> Result<moli_core::page::DocumentNodeSnapshot, PendingDomCommandStartError> {
|
||||
let route = conn
|
||||
.target_session_route_for_child_frame_id(frame_id)
|
||||
.ok_or_else(PendingDomCommandStartError::no_such_target)?;
|
||||
let backend_node_id =
|
||||
child_frame_document_root_node_reference(conn, session_id, &route, frame_id)
|
||||
.await?
|
||||
.backend_node_id;
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_route(session_id, Some(&route));
|
||||
let include_whitespace =
|
||||
dom_agent_includes_whitespace_for_route(conn, session_id, Some(&route));
|
||||
let page = loaded_page_mut_for_route(conn, session_id, &route)
|
||||
let backend_node_id = child_frame_document_root_node_reference(conn, owner, frame_id)
|
||||
.await?
|
||||
.backend_node_id;
|
||||
let renderer_inspector_session_id = renderer_inspector_session_id_for_owner(conn, owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
.start_document_node_snapshot_for_backend_node_id_in_inspector_session(
|
||||
@@ -558,10 +463,10 @@ async fn child_frame_root_node_snapshot(
|
||||
|
||||
async fn dom_geometry_command(
|
||||
conn: &mut CdpConnection,
|
||||
frame_id: &str,
|
||||
owner: &CommandOwnerScope,
|
||||
command: DevToolsDomGeometryCommand,
|
||||
) -> Result<DevToolsDomGeometryResult, PendingDomCommandStartError> {
|
||||
let geometry = document_geometry_for_reference(conn, frame_id, command.reference).await?;
|
||||
let geometry = document_geometry_for_reference(conn, owner, command.reference).await?;
|
||||
devtools_dom_geometry_result_from_renderer(command.operation, geometry).map_err(|error| {
|
||||
PendingDomCommandStartError {
|
||||
code: -32000,
|
||||
@@ -572,7 +477,7 @@ async fn dom_geometry_command(
|
||||
|
||||
async fn scroll_into_view_if_needed_command(
|
||||
conn: &mut CdpConnection,
|
||||
frame_id: &str,
|
||||
owner: &CommandOwnerScope,
|
||||
command: DevToolsScrollIntoViewIfNeededCommand,
|
||||
) -> Result<(), PendingDomCommandStartError> {
|
||||
let Some(reference) = command.reference else {
|
||||
@@ -581,7 +486,7 @@ async fn scroll_into_view_if_needed_command(
|
||||
// The lightweight headless renderer currently treats scrollIntoViewIfNeeded
|
||||
// as a geometry-validating no-op. Match the top-level path for child-frame
|
||||
// elements: prove the referenced node has geometry, then complete.
|
||||
match document_geometry_for_reference(conn, frame_id, reference).await? {
|
||||
match document_geometry_for_reference(conn, owner, reference).await? {
|
||||
RendererDocumentNodeGeometry::FoundElement { .. } => Ok(()),
|
||||
RendererDocumentNodeGeometry::FoundNonElement { .. }
|
||||
| RendererDocumentNodeGeometry::NoLayoutObject
|
||||
@@ -594,24 +499,11 @@ async fn scroll_into_view_if_needed_command(
|
||||
|
||||
async fn document_geometry_for_reference(
|
||||
conn: &mut CdpConnection,
|
||||
frame_id: &str,
|
||||
owner: &CommandOwnerScope,
|
||||
reference: DevToolsDomNodeReference,
|
||||
) -> Result<RendererDocumentNodeGeometry, PendingDomCommandStartError> {
|
||||
let route = conn
|
||||
.target_session_route_for_child_frame_id(frame_id)
|
||||
.ok_or_else(PendingDomCommandStartError::no_such_target)?;
|
||||
document_geometry_for_reference_in_session(conn, None, &route, reference).await
|
||||
}
|
||||
|
||||
async fn document_geometry_for_reference_in_session(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: &CdpSessionRoute,
|
||||
reference: DevToolsDomNodeReference,
|
||||
) -> Result<RendererDocumentNodeGeometry, PendingDomCommandStartError> {
|
||||
let reference =
|
||||
resolve_frontend_node_reference(conn, session_id, owner_route, reference).await?;
|
||||
let page = loaded_page_mut_for_route(conn, session_id, owner_route)
|
||||
let reference = resolve_frontend_node_reference(conn, owner, reference).await?;
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let backend_node_id = required_child_frame_backend_node_id(&reference)?;
|
||||
let pending = page
|
||||
|
||||
@@ -318,11 +318,8 @@ pub(super) fn start_disable_dom_agent_command(
|
||||
cmd: &Cmd<'_>,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let owner = CommandOwnerScope::capture(conn, cmd.session_id);
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(&owner);
|
||||
let Some(page) = loaded_page_mut_for_owner(conn, &owner) else {
|
||||
return Ok(None);
|
||||
};
|
||||
@@ -817,8 +814,7 @@ fn start_pending_dom_command(
|
||||
});
|
||||
}
|
||||
if action.requires_document_access()
|
||||
&& let Err(message) = conn
|
||||
.ensure_document_accessible_for_route(owner.session_id(), owner.session_owner_route())
|
||||
&& let Err(message) = conn.ensure_document_accessible_for_owner(&owner)
|
||||
{
|
||||
return Err(PendingDomCommandStartError {
|
||||
code: -32000,
|
||||
@@ -1262,11 +1258,8 @@ fn start_cdp_dom_edit_command(
|
||||
) -> Result<PendingDomCommandDispatch, PendingDomCommandStartError> {
|
||||
let owner = CommandOwnerScope::capture(conn, cmd.session_id);
|
||||
let edit = super::edit::renderer_dom_edit_from_cdp(cmd, action)?;
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(&owner);
|
||||
let page = loaded_page_mut_for_owner(conn, &owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
@@ -1465,16 +1458,9 @@ fn start_devtools_describe_node_command(
|
||||
},
|
||||
);
|
||||
}
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = start_inspector_document_node_snapshot_for_reference(
|
||||
@@ -1536,16 +1522,9 @@ fn start_devtools_request_child_nodes_command(
|
||||
command: DevToolsRequestChildNodesCommand,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let top_frame_id = top_frame_id_for_owner(conn, owner);
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
let next_depth = if command.depth > 0 {
|
||||
command.depth - 1
|
||||
} else {
|
||||
@@ -1675,16 +1654,9 @@ fn start_devtools_query_selector_command(
|
||||
command: DevToolsQuerySelectorCommand,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let top_frame_id = top_frame_id_for_owner(conn, owner);
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
let Some(reference) = command.root else {
|
||||
let page =
|
||||
loaded_page_mut_for_owner(conn, owner).ok_or_else(|| PendingDomCommandStartError {
|
||||
@@ -1910,16 +1882,9 @@ fn start_devtools_get_document_command(
|
||||
PendingDomDocumentSnapshotOperation::GetDocument
|
||||
};
|
||||
let top_frame_id = top_frame_id_for_owner(conn, owner);
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let depth = match operation {
|
||||
@@ -1969,11 +1934,8 @@ fn start_devtools_get_frame_owner_command(
|
||||
owner: &CommandOwnerScope,
|
||||
command: DevToolsGetFrameOwnerCommand,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let page =
|
||||
loaded_page_mut_for_owner(conn, owner).ok_or_else(|| PendingDomCommandStartError {
|
||||
code: -32000,
|
||||
@@ -2029,16 +1991,10 @@ fn start_devtools_get_node_for_location_command(
|
||||
command: DevToolsGetNodeForLocationCommand,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let top_frame_id = conn
|
||||
.target_session_owner_frame_tree_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.target_session_owner_frame_tree_identity_for_owner(owner)
|
||||
.map(|identity| identity.0)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let inspector_session_id = conn.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let inspector_session_id = conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
@@ -2130,11 +2086,8 @@ fn start_devtools_resolve_node_command(
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let reference = command.reference;
|
||||
let top_frame_id = top_frame_id_for_owner(conn, owner);
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
if let DevToolsDomNodeReference::FrontendNodeId(frontend_node_id) = reference {
|
||||
return start_document_frontend_node_binding_command(
|
||||
conn,
|
||||
@@ -2301,16 +2254,9 @@ fn start_dom_object_reference_operation(
|
||||
operation: PendingDomObjectReferenceOperation,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let reference = dom_object_reference_id_for_owner(conn, owner, &object_id);
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let object_id = reference;
|
||||
@@ -2424,11 +2370,8 @@ fn start_devtools_push_nodes_by_backend_ids_command(
|
||||
owner: &CommandOwnerScope,
|
||||
command: DevToolsPushNodesByBackendIdsCommand,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let renderer_runtime_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_runtime_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let renderer_backend_positions = (0..command.backend_node_ids.len()).collect::<Vec<_>>();
|
||||
@@ -2513,16 +2456,9 @@ fn complete_pending_dom_command(
|
||||
};
|
||||
let CompletedDomCommandWork::Page(completion) = completed_work;
|
||||
let completion = *completion;
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
session_id,
|
||||
owner_scope.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
session_id,
|
||||
owner_scope.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(&owner_scope);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, &owner_scope);
|
||||
|
||||
let kind = match completed.kind {
|
||||
PendingDomCommandKind::PerformSearchLive => {
|
||||
@@ -3214,17 +3150,9 @@ fn complete_pending_dom_command_result(
|
||||
completed: CompletedDomCommandDispatch,
|
||||
) -> DevToolsDomCommandTaskStep {
|
||||
let owner_scope = completed.owner_scope.clone();
|
||||
let session_id = owner_scope.session_id();
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
session_id,
|
||||
owner_scope.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
session_id,
|
||||
owner_scope.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(&owner_scope);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, &owner_scope);
|
||||
let completed_work = match completed.completed {
|
||||
Ok(completion) => completion,
|
||||
Err(error) => {
|
||||
@@ -4335,16 +4263,9 @@ fn complete_frontend_node_binding_for_describe_node(
|
||||
top_frame_id: Option<String>,
|
||||
out: &mut DomCommandOutput,
|
||||
) -> DomCommandTaskStep {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
complete_frontend_node_binding_followup(
|
||||
conn,
|
||||
command_id,
|
||||
@@ -4383,16 +4304,9 @@ fn complete_frontend_node_binding_for_describe_node_result(
|
||||
pierce: bool,
|
||||
top_frame_id: Option<String>,
|
||||
) -> DevToolsDomCommandTaskStep {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
complete_frontend_node_binding_followup_result(
|
||||
conn,
|
||||
command_id,
|
||||
@@ -4431,16 +4345,9 @@ fn complete_frontend_node_binding_for_request_child_nodes(
|
||||
top_frame_id: Option<String>,
|
||||
out: &mut DomCommandOutput,
|
||||
) -> DomCommandTaskStep {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
complete_frontend_node_binding_followup(
|
||||
conn,
|
||||
command_id,
|
||||
@@ -4470,16 +4377,9 @@ fn complete_frontend_node_binding_for_request_child_nodes_result(
|
||||
pierce: bool,
|
||||
top_frame_id: Option<String>,
|
||||
) -> DevToolsDomCommandTaskStep {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
complete_frontend_node_binding_followup_result(
|
||||
conn,
|
||||
command_id,
|
||||
@@ -4510,16 +4410,9 @@ fn complete_frontend_node_binding_for_query_selector(
|
||||
top_frame_id: Option<String>,
|
||||
out: &mut DomCommandOutput,
|
||||
) -> DomCommandTaskStep {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
complete_frontend_node_binding_followup(
|
||||
conn,
|
||||
command_id,
|
||||
@@ -4549,16 +4442,9 @@ fn complete_frontend_node_binding_for_query_selector_result(
|
||||
selector: String,
|
||||
multiple: bool,
|
||||
) -> DevToolsDomCommandTaskStep {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
complete_frontend_node_binding_followup_result(
|
||||
conn,
|
||||
command_id,
|
||||
@@ -4614,11 +4500,8 @@ fn complete_frontend_node_binding_for_resolve_node(
|
||||
top_frame_id: Option<String>,
|
||||
out: &mut DomCommandOutput,
|
||||
) -> DomCommandTaskStep {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
complete_frontend_node_binding_followup(
|
||||
conn,
|
||||
command_id,
|
||||
@@ -4649,11 +4532,8 @@ fn complete_frontend_node_binding_for_resolve_node_result(
|
||||
object_group: Option<String>,
|
||||
top_frame_id: Option<String>,
|
||||
) -> DevToolsDomCommandTaskStep {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
complete_frontend_node_binding_followup_result(
|
||||
conn,
|
||||
command_id,
|
||||
@@ -5780,11 +5660,8 @@ fn start_document_frontend_node_binding_command(
|
||||
frontend_node_id: u32,
|
||||
kind: PendingDomCommandKind,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
@@ -5932,28 +5809,30 @@ pub(crate) async fn execute_devtools_dom_command_async(
|
||||
conn: &mut CdpConnection,
|
||||
command: DevToolsCommand,
|
||||
) -> Result<DevToolsCommandResult, DevToolsError> {
|
||||
let (target_id, command_session_id) = devtools_dom_command_route(&command)?;
|
||||
let owner = if let Some(target_id) = target_id.as_deref() {
|
||||
if conn.target_session_route_for_target_id(target_id).is_none() {
|
||||
let result = super::child_frame::execute_devtools_dom_command(conn, target_id, command)
|
||||
let context = devtools_dom_command_context(&command)?;
|
||||
let target_id = context
|
||||
.target_id
|
||||
.as_ref()
|
||||
.map(|target_id| target_id.to_string());
|
||||
let owner = conn
|
||||
.command_owner_scope_for_devtools_context(context)
|
||||
.ok_or_else(|| DevToolsError::new(DevToolsErrorKind::NoSuchTarget, "NoSuchTarget"))?;
|
||||
if let Some(target_id) = target_id.as_deref()
|
||||
&& conn.target_session_route_for_target_id(target_id).is_none()
|
||||
{
|
||||
let result =
|
||||
super::child_frame::execute_devtools_dom_command(conn, target_id, &owner, command)
|
||||
.await
|
||||
.map_err(DevToolsError::from)?;
|
||||
return Ok(result);
|
||||
}
|
||||
let route = conn
|
||||
.target_session_route_for_target_id(target_id)
|
||||
.ok_or_else(|| DevToolsError::new(DevToolsErrorKind::NoSuchTarget, "NoSuchTarget"))?;
|
||||
CommandOwnerScope::for_route(route)
|
||||
} else {
|
||||
CommandOwnerScope::capture(conn, command_session_id.as_deref())
|
||||
};
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
execute_devtools_dom_command_for_owner(conn, &owner, command).await
|
||||
}
|
||||
|
||||
fn devtools_dom_command_route(
|
||||
fn devtools_dom_command_context(
|
||||
command: &DevToolsCommand,
|
||||
) -> Result<(Option<String>, Option<String>), DevToolsError> {
|
||||
) -> Result<&crate::devtools_runtime::DevToolsCommandContext, DevToolsError> {
|
||||
let context = match command {
|
||||
DevToolsCommand::QuerySelector(command) => &command.context,
|
||||
DevToolsCommand::GetAttributes(command) => &command.context,
|
||||
@@ -5983,16 +5862,7 @@ fn devtools_dom_command_route(
|
||||
));
|
||||
}
|
||||
};
|
||||
Ok((
|
||||
context
|
||||
.target_id
|
||||
.as_ref()
|
||||
.map(|target_id| target_id.to_string()),
|
||||
context
|
||||
.session_id
|
||||
.as_ref()
|
||||
.map(|session_id| session_id.to_string()),
|
||||
))
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
async fn execute_devtools_dom_command_for_owner(
|
||||
|
||||
@@ -83,16 +83,9 @@ pub(super) fn start_devtools_perform_search_command(
|
||||
owner: &CommandOwnerScope,
|
||||
command: DevToolsPerformSearchCommand,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let include_whitespace = super::dom_agent_includes_whitespace_for_route(
|
||||
conn,
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let include_whitespace = super::dom_agent_includes_whitespace_for_owner(conn, owner);
|
||||
let Some(page) = super::loaded_page_mut_for_owner(conn, owner) else {
|
||||
return Ok(None);
|
||||
};
|
||||
@@ -119,11 +112,8 @@ pub(super) fn start_devtools_get_search_results_command(
|
||||
owner: &CommandOwnerScope,
|
||||
command: DevToolsGetSearchResultsCommand,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let Some(page) = super::loaded_page_mut_for_owner(conn, owner) else {
|
||||
return Ok(None);
|
||||
};
|
||||
@@ -149,11 +139,8 @@ pub(super) fn start_devtools_discard_search_results_command(
|
||||
owner: &CommandOwnerScope,
|
||||
command: DevToolsDiscardSearchResultsCommand,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let Some(page) = super::loaded_page_mut_for_owner(conn, owner) else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
@@ -101,11 +101,8 @@ pub(super) fn start_devtools_set_file_input_files_command(
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let is_shared_node_id = is_webdriver_bidi_node_shared_id(command.object_id.as_str());
|
||||
if is_shared_node_id {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
@@ -424,11 +421,8 @@ fn start_set_file_input_files_frontend_node_binding(
|
||||
file_paths: Vec<String>,
|
||||
append: bool,
|
||||
) -> Result<Option<PendingDomCommandDispatch>, PendingDomCommandStartError> {
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
@@ -455,11 +449,8 @@ fn start_set_file_input_files_for_remote_reference(
|
||||
append: bool,
|
||||
) -> Result<PendingDomCommandDispatch, PendingDomCommandStartError> {
|
||||
let reference = dom_object_reference_id_for_owner(conn, owner, &object_id);
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let page = loaded_page_mut_for_owner(conn, owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let object_id = reference;
|
||||
|
||||
@@ -28,11 +28,8 @@ pub(super) fn start_set_node_stack_traces_enabled_command(
|
||||
Ok(Some(params)) => params,
|
||||
_ => return Err(PendingDomCommandStartError::invalid_params()),
|
||||
};
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(&owner);
|
||||
let page = super::loaded_page_mut_for_owner(conn, &owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
@@ -55,11 +52,8 @@ pub(super) fn start_get_node_stack_traces_command(
|
||||
Ok(Some(params)) => params,
|
||||
_ => return Err(PendingDomCommandStartError::invalid_params()),
|
||||
};
|
||||
let renderer_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(&owner);
|
||||
let page = super::loaded_page_mut_for_owner(conn, &owner)
|
||||
.ok_or_else(PendingDomCommandStartError::no_document_loaded)?;
|
||||
let pending = page
|
||||
|
||||
@@ -244,18 +244,14 @@ pub(crate) fn complete_pending_dom_debugger_command(
|
||||
completed: CompletedDomDebuggerCommandDispatch,
|
||||
) -> CommandOutputPlan {
|
||||
let session_id = completed.owner_scope.session_id().map(str::to_owned);
|
||||
let owner_route = completed.owner_scope.session_owner_route();
|
||||
match completed.operation {
|
||||
CompletedDomDebuggerOperation::GetEventListeners => {
|
||||
let resolution = completed.completed.and_then(|completion| {
|
||||
conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
session_id.as_deref(),
|
||||
owner_route,
|
||||
)
|
||||
.and_then(|page| {
|
||||
page.finish_dom_debugger_get_event_listeners(completion)
|
||||
.map_err(|error| error.to_string())
|
||||
})
|
||||
conn.loaded_page_mut_for_protocol_access_for_owner(&completed.owner_scope)
|
||||
.and_then(|page| {
|
||||
page.finish_dom_debugger_get_event_listeners(completion)
|
||||
.map_err(|error| error.to_string())
|
||||
})
|
||||
});
|
||||
match resolution {
|
||||
Ok(RendererDomDebuggerEventListenersResolution::Found(listeners)) => {
|
||||
@@ -272,17 +268,14 @@ pub(crate) fn complete_pending_dom_debugger_command(
|
||||
enabled,
|
||||
} => {
|
||||
let completion = completed.completed.and_then(|completion| {
|
||||
conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
session_id.as_deref(),
|
||||
owner_route,
|
||||
)
|
||||
.and_then(|page| {
|
||||
page.finish_unit_runtime_page_command(
|
||||
completion,
|
||||
"DOMDebugger event listener breakpoint",
|
||||
)
|
||||
.map_err(|error| error.to_string())
|
||||
})
|
||||
conn.loaded_page_mut_for_protocol_access_for_owner(&completed.owner_scope)
|
||||
.and_then(|page| {
|
||||
page.finish_unit_runtime_page_command(
|
||||
completion,
|
||||
"DOMDebugger event listener breakpoint",
|
||||
)
|
||||
.map_err(|error| error.to_string())
|
||||
})
|
||||
});
|
||||
if let Err(message) = completion {
|
||||
return CommandOutputPlan::error(-32000, message);
|
||||
@@ -311,14 +304,14 @@ pub(crate) fn complete_pending_dom_debugger_command(
|
||||
enabled,
|
||||
} => {
|
||||
let completion = completed.completed.and_then(|completion| {
|
||||
conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
session_id.as_deref(),
|
||||
owner_route,
|
||||
)
|
||||
.and_then(|page| {
|
||||
page.finish_unit_runtime_page_command(completion, "DOMDebugger XHR breakpoint")
|
||||
conn.loaded_page_mut_for_protocol_access_for_owner(&completed.owner_scope)
|
||||
.and_then(|page| {
|
||||
page.finish_unit_runtime_page_command(
|
||||
completion,
|
||||
"DOMDebugger XHR breakpoint",
|
||||
)
|
||||
.map_err(|error| error.to_string())
|
||||
})
|
||||
})
|
||||
});
|
||||
if let Err(message) = completion {
|
||||
return CommandOutputPlan::error(-32000, message);
|
||||
@@ -340,14 +333,11 @@ pub(crate) fn complete_pending_dom_debugger_command(
|
||||
}
|
||||
CompletedDomDebuggerOperation::ConfigureDomBreakpoint => {
|
||||
let resolution = completed.completed.and_then(|completion| {
|
||||
conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
session_id.as_deref(),
|
||||
owner_route,
|
||||
)
|
||||
.and_then(|page| {
|
||||
page.finish_dom_debugger_configure_dom_breakpoint(completion)
|
||||
.map_err(|error| error.to_string())
|
||||
})
|
||||
conn.loaded_page_mut_for_protocol_access_for_owner(&completed.owner_scope)
|
||||
.and_then(|page| {
|
||||
page.finish_dom_debugger_configure_dom_breakpoint(completion)
|
||||
.map_err(|error| error.to_string())
|
||||
})
|
||||
});
|
||||
match resolution {
|
||||
Ok(RendererDomDebuggerDomBreakpointResolution::Configured) => {
|
||||
|
||||
@@ -148,10 +148,8 @@ pub(crate) fn complete_pending_dom_snapshot_command(
|
||||
conn: &mut CdpConnection,
|
||||
completed: CompletedDomSnapshotCommandDispatch,
|
||||
) -> DomSnapshotCommandDispatchStep {
|
||||
let session_id = completed.owner_scope.session_id();
|
||||
let owner_route = completed.owner_scope.session_owner_route();
|
||||
let Some(page) = conn
|
||||
.loaded_page_mut_for_protocol_access_for_route(session_id, owner_route)
|
||||
.loaded_page_mut_for_protocol_access_for_owner(&completed.owner_scope)
|
||||
.ok()
|
||||
else {
|
||||
return DomSnapshotCommandDispatchStep::Complete(CommandOutputPlan::error(
|
||||
|
||||
@@ -77,9 +77,7 @@ fn dom_storage_subscriptions_for_browser_context_owner(
|
||||
conn: &CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Vec<(Option<String>, WebStorageMutationSubscription)> {
|
||||
let Some((browser_context_id, _)) =
|
||||
conn.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
else {
|
||||
let Some((browser_context_id, _)) = conn.target_owner_identity_for_owner(owner) else {
|
||||
return dom_storage_subscriptions_for_owner(conn, owner);
|
||||
};
|
||||
let Some(browser_context) = conn.browser_context_by_id(&browser_context_id) else {
|
||||
@@ -116,7 +114,7 @@ fn dom_storage_subscriptions_for_owner(
|
||||
conn: &CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Vec<(Option<String>, WebStorageMutationSubscription)> {
|
||||
conn.page_event_session_ids_for_route(owner.session_id(), owner.session_owner_route())
|
||||
conn.page_event_session_ids_for_owner(owner)
|
||||
.into_iter()
|
||||
.filter_map(|event_session_id| {
|
||||
let subscription = conn
|
||||
|
||||
@@ -6,9 +6,7 @@ use serde_json::json;
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
conn::{
|
||||
BrowserContextPageStorageHandles, CdpConnection, CdpSessionRoute, Cmd, CommandOwnerScope,
|
||||
},
|
||||
conn::{BrowserContextPageStorageHandles, CdpConnection, Cmd, CommandOwnerScope},
|
||||
domains::{actions::DomStorageAction, command_output::CommandOutputPlan},
|
||||
};
|
||||
|
||||
@@ -202,11 +200,7 @@ fn start_storage_operation(
|
||||
operation: DomStorageOperation,
|
||||
) -> DomStorageCommandTaskStep {
|
||||
let owner_scope = CommandOwnerScope::capture(conn, cmd.session_id);
|
||||
if let Err(plan) = storage_handles_for_route(
|
||||
conn,
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) {
|
||||
if let Err(plan) = storage_handles_for_owner(conn, &owner_scope) {
|
||||
return DomStorageCommandTaskStep::Complete(plan);
|
||||
}
|
||||
|
||||
@@ -216,18 +210,14 @@ fn start_storage_operation(
|
||||
{
|
||||
return DomStorageCommandTaskStep::Complete(complete_storage_operation(
|
||||
conn,
|
||||
cmd.session_id,
|
||||
owner_scope.session_owner_route(),
|
||||
&owner_scope,
|
||||
storage_id,
|
||||
operation,
|
||||
&storage_key,
|
||||
));
|
||||
}
|
||||
|
||||
if let Ok(page) = conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) {
|
||||
if let Ok(page) = conn.loaded_page_mut_for_protocol_access_for_owner(&owner_scope) {
|
||||
return match page.start_document_storage_key_snapshot() {
|
||||
Ok(pending) => {
|
||||
DomStorageCommandTaskStep::Pending(Box::new(PendingDomStorageCommandDispatch {
|
||||
@@ -257,8 +247,7 @@ fn start_storage_operation(
|
||||
};
|
||||
DomStorageCommandTaskStep::Complete(complete_storage_operation(
|
||||
conn,
|
||||
cmd.session_id,
|
||||
owner_scope.session_owner_route(),
|
||||
&owner_scope,
|
||||
storage_id,
|
||||
operation,
|
||||
&storage_key,
|
||||
@@ -313,10 +302,7 @@ fn complete_top_frame_resolution(
|
||||
}
|
||||
};
|
||||
let storage_key = {
|
||||
let Ok(page) = conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) else {
|
||||
let Ok(page) = conn.loaded_page_mut_for_protocol_access_for_owner(&owner_scope) else {
|
||||
return DomStorageCommandTaskStep::Complete(frame_not_found_plan());
|
||||
};
|
||||
match page.finish_document_storage_key_snapshot(completion) {
|
||||
@@ -333,8 +319,7 @@ fn complete_top_frame_resolution(
|
||||
if storage_id_matches_key(&storage_id, &storage_key) {
|
||||
return DomStorageCommandTaskStep::Complete(complete_storage_operation(
|
||||
conn,
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
&owner_scope,
|
||||
storage_id,
|
||||
operation,
|
||||
&storage_key,
|
||||
@@ -342,10 +327,7 @@ fn complete_top_frame_resolution(
|
||||
}
|
||||
|
||||
let child_pending = {
|
||||
let Ok(page) = conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) else {
|
||||
let Ok(page) = conn.loaded_page_mut_for_protocol_access_for_owner(&owner_scope) else {
|
||||
return DomStorageCommandTaskStep::Complete(frame_not_found_plan());
|
||||
};
|
||||
page.start_child_frame_tree_snapshot()
|
||||
@@ -383,10 +365,7 @@ fn complete_child_frame_resolution(
|
||||
}
|
||||
};
|
||||
let child_frames = {
|
||||
let Ok(page) = conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) else {
|
||||
let Ok(page) = conn.loaded_page_mut_for_protocol_access_for_owner(&owner_scope) else {
|
||||
return DomStorageCommandTaskStep::Complete(frame_not_found_plan());
|
||||
};
|
||||
match page.finish_child_frame_tree_snapshot(completion) {
|
||||
@@ -404,8 +383,7 @@ fn complete_child_frame_resolution(
|
||||
};
|
||||
DomStorageCommandTaskStep::Complete(complete_storage_operation(
|
||||
conn,
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
&owner_scope,
|
||||
storage_id,
|
||||
operation,
|
||||
&storage_key,
|
||||
@@ -414,8 +392,7 @@ fn complete_child_frame_resolution(
|
||||
|
||||
fn complete_storage_operation(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
storage_id: DomStorageId,
|
||||
operation: DomStorageOperation,
|
||||
storage_key: &str,
|
||||
@@ -423,7 +400,7 @@ fn complete_storage_operation(
|
||||
if !storage_id_matches_key(&storage_id, storage_key) {
|
||||
return frame_not_found_plan();
|
||||
}
|
||||
let handles = match storage_handles_for_route(conn, session_id, owner_route) {
|
||||
let handles = match storage_handles_for_owner(conn, owner) {
|
||||
Ok(handles) => handles,
|
||||
Err(plan) => return plan,
|
||||
};
|
||||
@@ -470,16 +447,15 @@ fn storage_handles_for_session_owner(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
) -> Result<BrowserContextPageStorageHandles, CommandOutputPlan> {
|
||||
storage_handles_for_route(conn, session_id, None)
|
||||
let owner = CommandOwnerScope::capture(conn, session_id);
|
||||
storage_handles_for_owner(conn, &owner)
|
||||
}
|
||||
|
||||
fn storage_handles_for_route(
|
||||
fn storage_handles_for_owner(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<BrowserContextPageStorageHandles, CommandOutputPlan> {
|
||||
let Some((browser_context_id, Some(target_id))) =
|
||||
conn.target_owner_identity_for_route(session_id, owner_route)
|
||||
let Some((browser_context_id, Some(target_id))) = conn.target_owner_identity_for_owner(owner)
|
||||
else {
|
||||
return Err(CommandOutputPlan::error(
|
||||
-32000,
|
||||
|
||||
@@ -857,7 +857,8 @@ fn start_device_metrics_override_command(
|
||||
screen_width: Some(screen_width),
|
||||
screen_height: Some(screen_height),
|
||||
};
|
||||
match start_devtools_set_viewport_command(conn, cmd.id, command, None) {
|
||||
let owner = CommandOwnerScope::capture(conn, cmd.session_id);
|
||||
match start_devtools_set_viewport_command(conn, cmd.id, command, owner) {
|
||||
Ok(Some(pending)) => EmulationCommandTaskStep::Pending(pending),
|
||||
Ok(None) => EmulationCommandTaskStep::Complete(CommandOutputPlan::success()),
|
||||
Err(error) => {
|
||||
@@ -937,27 +938,18 @@ fn start_devtools_set_viewport_command(
|
||||
conn: &mut CdpConnection,
|
||||
command_id: Option<u64>,
|
||||
command: DevToolsSetViewportCommand,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner_scope: CommandOwnerScope,
|
||||
) -> Result<Option<PendingEmulationCommandDispatch>, DevToolsError> {
|
||||
let owner_scope = CommandOwnerScope::capture_for_route(
|
||||
conn,
|
||||
command.context.session_id.as_ref().map(|id| id.as_str()),
|
||||
owner_route,
|
||||
);
|
||||
let session_id = owner_scope.session_id();
|
||||
let owner_route = owner_scope.session_owner_route();
|
||||
if conn.browser_context.is_none()
|
||||
&& conn
|
||||
.target_owner_identity_for_route(session_id, owner_route)
|
||||
.is_none()
|
||||
&& conn.target_owner_identity_for_owner(&owner_scope).is_none()
|
||||
{
|
||||
return Ok(None);
|
||||
}
|
||||
let metrics = set_viewport_metrics_from_command(conn, session_id, owner_route, &command)?;
|
||||
let metrics = set_viewport_metrics_from_command(conn, &owner_scope, &command)?;
|
||||
let had_existing_device_metrics = conn
|
||||
.target_session_owner_emulated_device_metrics_for_route(session_id, owner_route)
|
||||
.target_session_owner_emulated_device_metrics_for_owner(&owner_scope)
|
||||
.is_some();
|
||||
if !conn.mutate_emulation_session_state_for_route(session_id, owner_route, |state| {
|
||||
if !conn.mutate_emulation_session_state_for_owner(&owner_scope, |state| {
|
||||
if let Some(state) = state {
|
||||
*state.emulated_device_metrics = Some(metrics.clone());
|
||||
}
|
||||
@@ -969,12 +961,12 @@ fn start_devtools_set_viewport_command(
|
||||
}
|
||||
let runtime_call_id = conn.next_internal_runtime_command_id();
|
||||
let Some(page) = conn
|
||||
.loaded_page_mut_for_target_configuration_for_route(session_id, owner_route)
|
||||
.loaded_page_mut_for_target_configuration_for_owner(&owner_scope)
|
||||
.ok()
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
let session_id = session_id.map(str::to_owned);
|
||||
let session_id = owner_scope.session_id().map(str::to_owned);
|
||||
let viewport_surface = Some(metrics.viewport_surface().to_page_viewport_surface());
|
||||
let pending_viewport = page
|
||||
.start_set_viewport_surface(viewport_surface)
|
||||
@@ -1008,12 +1000,10 @@ fn start_devtools_set_viewport_command(
|
||||
|
||||
fn set_viewport_metrics_from_command(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
command: &DevToolsSetViewportCommand,
|
||||
) -> Result<EmulatedDeviceMetrics, DevToolsError> {
|
||||
let current_metrics =
|
||||
conn.target_session_owner_emulated_device_metrics_for_route(session_id, owner_route);
|
||||
let current_metrics = conn.target_session_owner_emulated_device_metrics_for_owner(owner);
|
||||
set_viewport_metrics_from_current(current_metrics.as_ref(), command)
|
||||
}
|
||||
|
||||
@@ -1263,7 +1253,8 @@ fn start_geolocation_override_for_current_route(
|
||||
route: &CdpSessionRoute,
|
||||
override_state: Option<EmulatedGeolocationOverrideState>,
|
||||
) -> Result<Vec<PendingEmulationPageCommand>, DevToolsError> {
|
||||
if !conn.mutate_emulation_session_state_for_route(None, Some(route), |state| {
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
if !conn.mutate_emulation_session_state_for_owner(&owner, |state| {
|
||||
if let Some(state) = state {
|
||||
*state.geolocation_override = override_state;
|
||||
}
|
||||
@@ -1349,7 +1340,8 @@ fn start_network_conditions_for_current_route(
|
||||
route: &CdpSessionRoute,
|
||||
network_conditions: Option<DevToolsNetworkConditions>,
|
||||
) -> Result<Vec<PendingEmulationPageCommand>, DevToolsError> {
|
||||
if !conn.mutate_emulation_session_state_for_route(None, Some(route), |state| {
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
if !conn.mutate_emulation_session_state_for_owner(&owner, |state| {
|
||||
if let Some(state) = state {
|
||||
*state.network_conditions = network_conditions.map(emulated_network_conditions);
|
||||
}
|
||||
@@ -1377,10 +1369,10 @@ fn start_network_conditions_update_for_current_route(
|
||||
}),
|
||||
PendingEmulationPageTarget::SessionOwner { .. } => false,
|
||||
};
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
let network_update = conn
|
||||
.start_set_emulated_network_conditions_for_route(
|
||||
None,
|
||||
Some(route),
|
||||
.start_set_emulated_network_conditions_for_owner(
|
||||
&owner,
|
||||
effective_offline,
|
||||
0.0,
|
||||
-1.0,
|
||||
@@ -1410,8 +1402,9 @@ fn start_extra_headers_for_current_route(
|
||||
headers: Vec<(String, String)>,
|
||||
) -> Result<Vec<PendingEmulationPageCommand>, DevToolsError> {
|
||||
let target = pending_emulation_target_for_route(conn, route)?;
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
let pending = conn
|
||||
.start_set_target_extra_http_headers_for_route(None, Some(route), headers)
|
||||
.start_set_target_extra_http_headers_for_owner(&owner, headers)
|
||||
.map_err(devtools_emulation_owner_error)?;
|
||||
Ok(pending
|
||||
.map(|pending| {
|
||||
@@ -1482,10 +1475,7 @@ fn loaded_page_mut_for_pending_emulation_target<'a>(
|
||||
.and_then(|target| target.loaded_page_mut())
|
||||
.map(|page| &*page),
|
||||
PendingEmulationPageTarget::SessionOwner { owner_scope } => conn
|
||||
.loaded_page_mut_for_target_configuration_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.loaded_page_mut_for_target_configuration_for_owner(owner_scope)
|
||||
.ok()
|
||||
.map(|page| &*page),
|
||||
}
|
||||
@@ -1648,8 +1638,9 @@ fn start_user_agent_override_for_current_route(
|
||||
user_agent: Option<String>,
|
||||
) -> Result<Option<PendingEmulationPageCommand>, DevToolsError> {
|
||||
let target = pending_emulation_target_for_route(conn, route)?;
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
let pending = conn
|
||||
.start_set_base_user_agent_override_for_route(None, Some(route), user_agent)
|
||||
.start_set_base_user_agent_override_for_owner(&owner, user_agent)
|
||||
.map_err(devtools_emulation_owner_error)?;
|
||||
if let Some(pending) = pending {
|
||||
return Ok(Some(PendingEmulationPageCommand {
|
||||
@@ -1667,12 +1658,13 @@ fn start_user_agent_loader_update_for_current_route(
|
||||
route: &CdpSessionRoute,
|
||||
) -> Result<Option<PendingEmulationPageCommand>, DevToolsError> {
|
||||
let target = pending_emulation_target_for_route(conn, route)?;
|
||||
let load_inputs = conn.navigation_load_inputs_for_route(None, Some(route));
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
let load_inputs = conn.navigation_load_inputs_for_owner(&owner);
|
||||
let resource_runtime = conn
|
||||
.build_registered_browser_resource_runtime_for_navigation_load_inputs(&load_inputs)
|
||||
.map_err(|error| DevToolsError::new(DevToolsErrorKind::Internal, error))?;
|
||||
let Some(page) = conn
|
||||
.loaded_page_mut_for_target_configuration_for_route(None, Some(route))
|
||||
.loaded_page_mut_for_target_configuration_for_owner(&owner)
|
||||
.ok()
|
||||
else {
|
||||
return Ok(None);
|
||||
@@ -1757,7 +1749,8 @@ fn start_locale_override_for_current_route(
|
||||
route: &CdpSessionRoute,
|
||||
locale: Option<String>,
|
||||
) -> Result<Vec<PendingEmulationPageCommand>, DevToolsError> {
|
||||
if !conn.set_base_locale_override_for_route(None, Some(route), locale) {
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
if !conn.set_base_locale_override_for_owner(&owner, locale) {
|
||||
return Err(devtools_emulation_owner_error(
|
||||
"BrowserContextNotLoaded".to_owned(),
|
||||
));
|
||||
@@ -1774,11 +1767,12 @@ fn start_locale_update_for_current_route(
|
||||
pending.push(identity_update);
|
||||
}
|
||||
let target = pending_emulation_target_for_route(conn, route)?;
|
||||
let Some(locale_override) = locale_override_for_route(conn, None, Some(route)) else {
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
let Some(locale_override) = locale_override_for_owner(conn, &owner) else {
|
||||
return Ok(pending);
|
||||
};
|
||||
let Some(page) = conn
|
||||
.loaded_page_mut_for_target_configuration_for_route(None, Some(route))
|
||||
.loaded_page_mut_for_target_configuration_for_owner(&owner)
|
||||
.ok()
|
||||
else {
|
||||
return Ok(pending);
|
||||
@@ -1863,7 +1857,8 @@ fn start_timezone_override_for_current_route(
|
||||
route: &CdpSessionRoute,
|
||||
timezone: Option<String>,
|
||||
) -> Result<Option<PendingEmulationPageCommand>, DevToolsError> {
|
||||
if !conn.set_base_timezone_override_for_route(None, Some(route), timezone) {
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
if !conn.set_base_timezone_override_for_owner(&owner, timezone) {
|
||||
return Err(devtools_emulation_owner_error(
|
||||
"BrowserContextNotLoaded".to_owned(),
|
||||
));
|
||||
@@ -1876,9 +1871,10 @@ fn start_timezone_update_for_current_route(
|
||||
route: &CdpSessionRoute,
|
||||
) -> Result<Option<PendingEmulationPageCommand>, DevToolsError> {
|
||||
let target = pending_emulation_target_for_route(conn, route)?;
|
||||
let load_inputs = conn.navigation_load_inputs_for_route(None, Some(route));
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
let load_inputs = conn.navigation_load_inputs_for_owner(&owner);
|
||||
let Some(page) = conn
|
||||
.loaded_page_mut_for_target_configuration_for_route(None, Some(route))
|
||||
.loaded_page_mut_for_target_configuration_for_owner(&owner)
|
||||
.ok()
|
||||
else {
|
||||
return Ok(None);
|
||||
@@ -2033,7 +2029,12 @@ async fn execute_devtools_set_viewport_command_async(
|
||||
};
|
||||
let mut command = command;
|
||||
command.context.session_id = None;
|
||||
return match start_devtools_set_viewport_command(conn, None, command, Some(&route)) {
|
||||
return match start_devtools_set_viewport_command(
|
||||
conn,
|
||||
None,
|
||||
command,
|
||||
CommandOwnerScope::for_route(route),
|
||||
) {
|
||||
Ok(Some(pending)) => {
|
||||
let completed = pending.wait().await;
|
||||
complete_pending_devtools_emulation_command(conn, completed)
|
||||
@@ -2042,7 +2043,11 @@ async fn execute_devtools_set_viewport_command_async(
|
||||
Err(error) => Err(error),
|
||||
};
|
||||
}
|
||||
match start_devtools_set_viewport_command(conn, None, command, None) {
|
||||
let owner = CommandOwnerScope::capture(
|
||||
conn,
|
||||
command.context.session_id.as_ref().map(|id| id.as_str()),
|
||||
);
|
||||
match start_devtools_set_viewport_command(conn, None, command, owner) {
|
||||
Ok(Some(pending)) => {
|
||||
let completed = pending.wait().await;
|
||||
complete_pending_devtools_emulation_command(conn, completed)
|
||||
@@ -2064,21 +2069,28 @@ async fn execute_devtools_set_window_state_command_async(
|
||||
)?;
|
||||
let mut command = command;
|
||||
command.context.session_id = None;
|
||||
return execute_devtools_set_window_state_for_current_route(conn, command, Some(&route))
|
||||
.await;
|
||||
return execute_devtools_set_window_state_for_owner(
|
||||
conn,
|
||||
command,
|
||||
CommandOwnerScope::for_route(route),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
execute_devtools_set_window_state_for_current_route(conn, command, None).await
|
||||
let owner = CommandOwnerScope::capture(
|
||||
conn,
|
||||
command.context.session_id.as_ref().map(|id| id.as_str()),
|
||||
);
|
||||
execute_devtools_set_window_state_for_owner(conn, command, owner).await
|
||||
}
|
||||
|
||||
async fn execute_devtools_set_window_state_for_current_route(
|
||||
async fn execute_devtools_set_window_state_for_owner(
|
||||
conn: &mut CdpConnection,
|
||||
command: crate::devtools_runtime::DevToolsSetWindowStateCommand,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: CommandOwnerScope,
|
||||
) -> Result<DevToolsCommandResult, DevToolsError> {
|
||||
let session_id = command.context.session_id.as_ref().map(|id| id.as_str());
|
||||
let state = target_window_surface_state_from_devtools(command.state);
|
||||
if conn
|
||||
.with_target_owner_state_for_route_mut(session_id, owner_route, |owner_state| {
|
||||
.with_target_owner_state_for_owner_mut(&owner, |owner_state| {
|
||||
owner_state.set_window_surface_state(state);
|
||||
})
|
||||
.is_none()
|
||||
@@ -2088,9 +2100,8 @@ async fn execute_devtools_set_window_state_for_current_route(
|
||||
"BrowserContextNotLoaded",
|
||||
));
|
||||
}
|
||||
let pending =
|
||||
start_session_surface_override_page_command_for_route(conn, session_id, owner_route)
|
||||
.map_err(devtools_emulation_owner_error)?;
|
||||
let pending = start_session_surface_override_page_command_for_owner(conn, &owner)
|
||||
.map_err(devtools_emulation_owner_error)?;
|
||||
complete_emulation_page_updates(conn, devtools_command_session_id(&command.context), pending)
|
||||
.await
|
||||
}
|
||||
@@ -2105,19 +2116,20 @@ async fn execute_devtools_set_client_window_state_command_async(
|
||||
let mut window_state_context = command.context.clone();
|
||||
window_state_context.session_id = None;
|
||||
window_state_context.target_id = Some(command.client_window.clone());
|
||||
let result = execute_devtools_set_window_state_for_current_route(
|
||||
let result = execute_devtools_set_window_state_for_owner(
|
||||
conn,
|
||||
crate::devtools_runtime::DevToolsSetWindowStateCommand {
|
||||
context: window_state_context,
|
||||
state: command.state,
|
||||
},
|
||||
Some(&route),
|
||||
CommandOwnerScope::for_route(route.clone()),
|
||||
)
|
||||
.await;
|
||||
|
||||
match result {
|
||||
Ok(_) => {
|
||||
let _ = conn.with_target_owner_state_for_route_mut(None, Some(&route), |owner_state| {
|
||||
let owner = CommandOwnerScope::for_route(route);
|
||||
let _ = conn.with_target_owner_state_for_owner_mut(&owner, |owner_state| {
|
||||
owner_state.set_window_surface_geometry(
|
||||
command.width,
|
||||
command.height,
|
||||
@@ -2518,10 +2530,9 @@ fn pending_emulation_page_configuration_will_be_replayed(
|
||||
};
|
||||
let current_attachment_id = match target {
|
||||
PendingEmulationPageTarget::SessionOwner { owner_scope } => {
|
||||
let Some((browser_context_id, target_id)) = conn.target_owner_identity_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) else {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
conn.target_owner_identity_for_owner(owner_scope)
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
let Some(browser_context) = conn.browser_context_by_id(&browser_context_id) else {
|
||||
@@ -2749,20 +2760,17 @@ fn start_session_surface_override_page_command(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
) -> Result<Vec<PendingEmulationPageCommand>, String> {
|
||||
start_session_surface_override_page_command_for_route(conn, session_id, None)
|
||||
let owner = CommandOwnerScope::capture(conn, session_id);
|
||||
start_session_surface_override_page_command_for_owner(conn, &owner)
|
||||
}
|
||||
|
||||
fn start_session_surface_override_page_command_for_route(
|
||||
fn start_session_surface_override_page_command_for_owner(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner_scope: &CommandOwnerScope,
|
||||
) -> Result<Vec<PendingEmulationPageCommand>, String> {
|
||||
let owner_scope = CommandOwnerScope::capture_for_route(conn, session_id, owner_route);
|
||||
let session_id = owner_scope.session_id();
|
||||
let owner_route = owner_scope.session_owner_route();
|
||||
let script = {
|
||||
let Some((browser_context_id, target_id)) =
|
||||
conn.target_owner_identity_for_route(session_id, owner_route)
|
||||
conn.target_owner_identity_for_owner(owner_scope)
|
||||
else {
|
||||
return Err("BrowserContextNotLoaded".to_owned());
|
||||
};
|
||||
@@ -2782,13 +2790,15 @@ fn start_session_surface_override_page_command_for_route(
|
||||
};
|
||||
let runtime_call_id = conn.next_internal_runtime_command_id();
|
||||
let Some(page) = conn
|
||||
.loaded_page_mut_for_target_configuration_for_route(session_id, owner_route)
|
||||
.loaded_page_mut_for_target_configuration_for_owner(owner_scope)
|
||||
.ok()
|
||||
else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
start_surface_override_page_command(
|
||||
PendingEmulationPageTarget::SessionOwner { owner_scope },
|
||||
PendingEmulationPageTarget::SessionOwner {
|
||||
owner_scope: owner_scope.clone(),
|
||||
},
|
||||
page,
|
||||
script,
|
||||
runtime_call_id,
|
||||
@@ -2816,19 +2826,16 @@ fn start_surface_override_for_route(
|
||||
}
|
||||
}
|
||||
PendingEmulationPageTarget::SessionOwner { owner_scope } => {
|
||||
return start_session_surface_override_page_command_for_route(
|
||||
conn,
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
);
|
||||
return start_session_surface_override_page_command_for_owner(conn, owner_scope);
|
||||
}
|
||||
};
|
||||
let Some(script) = script else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
let runtime_call_id = conn.next_internal_runtime_command_id();
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
let Some(page) = conn
|
||||
.loaded_page_mut_for_target_configuration_for_route(None, Some(route))
|
||||
.loaded_page_mut_for_target_configuration_for_owner(&owner)
|
||||
.ok()
|
||||
else {
|
||||
return Ok(Vec::new());
|
||||
@@ -2873,16 +2880,15 @@ fn locale_override_for_session(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
) -> Option<Option<String>> {
|
||||
locale_override_for_route(conn, session_id, None)
|
||||
let owner = CommandOwnerScope::capture(conn, session_id);
|
||||
locale_override_for_owner(conn, &owner)
|
||||
}
|
||||
|
||||
fn locale_override_for_route(
|
||||
fn locale_override_for_owner(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<Option<String>> {
|
||||
let (browser_context_id, target_id) =
|
||||
conn.target_owner_identity_for_route(session_id, owner_route)?;
|
||||
let (browser_context_id, target_id) = conn.target_owner_identity_for_owner(owner)?;
|
||||
let browser_context = conn.browser_context_by_id(&browser_context_id)?;
|
||||
if let Some(target_id) = target_id {
|
||||
return Some(browser_context.effective_locale_override_for_target_owned(&target_id));
|
||||
@@ -2899,17 +2905,10 @@ fn finish_pending_emulation_page_command(
|
||||
match target {
|
||||
PendingEmulationPageTarget::SessionOwner { owner_scope } => {
|
||||
if matches!(operation, PendingEmulationPageOperation::SetUserAgentLoader) {
|
||||
return conn.finish_rebuild_resource_runtime_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
completion,
|
||||
);
|
||||
return conn.finish_rebuild_resource_runtime_for_owner(&owner_scope, completion);
|
||||
}
|
||||
let page = conn
|
||||
.loaded_page_mut_for_target_configuration_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.loaded_page_mut_for_target_configuration_for_owner(&owner_scope)
|
||||
.ok();
|
||||
finish_emulation_page_operation_on_current_attachment(page, operation, completion)
|
||||
}
|
||||
|
||||
@@ -727,9 +727,8 @@ async fn idle_override_updates_idle_detector_and_clear_restores_actual_state() {
|
||||
}));
|
||||
|
||||
ctx.conn
|
||||
.start_document_navigation_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.start_document_navigation_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
"LID-idle-cross-document".to_owned(),
|
||||
)
|
||||
.expect("cross-Document navigation should enter the pending state");
|
||||
|
||||
@@ -9,9 +9,8 @@ mod state;
|
||||
mod subresource;
|
||||
|
||||
use crate::conn::{
|
||||
BackgroundProtocolEvent, CdpConnection, CdpSessionRoute, Cmd, CommandOwnerScope,
|
||||
DevToolsCommandExecutionOutput, FetchInterceptionPattern,
|
||||
FetchRequestStage as ConnFetchRequestStage,
|
||||
BackgroundProtocolEvent, CdpConnection, Cmd, CommandOwnerScope, DevToolsCommandExecutionOutput,
|
||||
FetchInterceptionPattern, FetchRequestStage as ConnFetchRequestStage,
|
||||
};
|
||||
use crate::devtools_runtime::{
|
||||
DevToolsAddNetworkInterceptCommand, DevToolsAddNetworkInterceptResult, DevToolsCommand,
|
||||
@@ -343,15 +342,10 @@ pub(crate) async fn execute_devtools_fetch_command_async_with_protocol_events(
|
||||
command: DevToolsCommand,
|
||||
) -> DevToolsCommandExecutionOutput {
|
||||
let success_result = devtools_fetch_success_result(&command);
|
||||
let (owner_session_id, owner_route) = match fetch_devtools_command_session_ids(conn, &command) {
|
||||
Ok(session_ids) => session_ids,
|
||||
let owner = match fetch_devtools_command_owner(conn, &command) {
|
||||
Ok(owner) => owner,
|
||||
Err(error) => return DevToolsCommandExecutionOutput::new(Err(error)),
|
||||
};
|
||||
let owner = CommandOwnerScope::capture_for_route(
|
||||
conn,
|
||||
owner_session_id.as_deref(),
|
||||
owner_route.as_ref(),
|
||||
);
|
||||
let step = start_devtools_fetch_command_for_owner(conn, None, &owner, command);
|
||||
match step {
|
||||
FetchCommandTaskStep::Complete(mut plan) => {
|
||||
@@ -414,66 +408,64 @@ fn start_devtools_fetch_command_for_owner(
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_devtools_command_session_ids(
|
||||
fn fetch_devtools_command_owner(
|
||||
conn: &CdpConnection,
|
||||
command: &DevToolsCommand,
|
||||
) -> Result<(Option<String>, Option<CdpSessionRoute>), DevToolsError> {
|
||||
) -> Result<CommandOwnerScope, DevToolsError> {
|
||||
let (context, request_id) = match command {
|
||||
DevToolsCommand::AddNetworkIntercept(command) => {
|
||||
return fetch_config_devtools_command_session_ids(conn, command.context.clone());
|
||||
return fetch_config_devtools_command_owner(conn, &command.context);
|
||||
}
|
||||
DevToolsCommand::RemoveNetworkIntercept(command) => {
|
||||
return fetch_config_devtools_command_session_ids(conn, command.context.clone());
|
||||
return fetch_config_devtools_command_owner(conn, &command.context);
|
||||
}
|
||||
DevToolsCommand::ContinueInterceptedRequest(command) => {
|
||||
(command.context.clone(), command.request_id.as_str())
|
||||
(&command.context, command.request_id.as_str())
|
||||
}
|
||||
DevToolsCommand::ContinueInterceptedResponse(command) => {
|
||||
(command.context.clone(), command.request_id.as_str())
|
||||
(&command.context, command.request_id.as_str())
|
||||
}
|
||||
DevToolsCommand::ContinueWithAuth(command) => {
|
||||
(command.context.clone(), command.request_id.as_str())
|
||||
(&command.context, command.request_id.as_str())
|
||||
}
|
||||
DevToolsCommand::FailInterceptedRequest(command) => {
|
||||
(command.context.clone(), command.request_id.as_str())
|
||||
(&command.context, command.request_id.as_str())
|
||||
}
|
||||
DevToolsCommand::FulfillInterceptedRequest(command) => {
|
||||
(command.context.clone(), command.request_id.as_str())
|
||||
(&command.context, command.request_id.as_str())
|
||||
}
|
||||
_ => return Ok((None, None)),
|
||||
_ => return Ok(CommandOwnerScope::capture(conn, None)),
|
||||
};
|
||||
let response_session_id = context
|
||||
.session_id
|
||||
.as_ref()
|
||||
.map(|session| session.as_str().to_owned());
|
||||
if context.protocol == DevToolsProtocol::Cdp {
|
||||
return Ok((response_session_id, None));
|
||||
return Ok(CommandOwnerScope::capture(
|
||||
conn,
|
||||
context.session_id.as_ref().map(|session| session.as_str()),
|
||||
));
|
||||
}
|
||||
Ok((None, conn.pending_fetch_request_session_route(request_id)))
|
||||
Ok(conn
|
||||
.pending_fetch_request_session_route(request_id)
|
||||
.map(CommandOwnerScope::for_route)
|
||||
.unwrap_or_else(|| CommandOwnerScope::capture(conn, None)))
|
||||
}
|
||||
|
||||
fn fetch_config_devtools_command_session_ids(
|
||||
fn fetch_config_devtools_command_owner(
|
||||
conn: &CdpConnection,
|
||||
context: crate::devtools_runtime::DevToolsCommandContext,
|
||||
) -> Result<(Option<String>, Option<CdpSessionRoute>), DevToolsError> {
|
||||
let response_session_id = context
|
||||
.session_id
|
||||
.as_ref()
|
||||
.map(|session| session.as_str().to_owned());
|
||||
context: &crate::devtools_runtime::DevToolsCommandContext,
|
||||
) -> Result<CommandOwnerScope, DevToolsError> {
|
||||
if context.protocol == DevToolsProtocol::Cdp {
|
||||
return Ok((response_session_id, None));
|
||||
return Ok(CommandOwnerScope::capture(
|
||||
conn,
|
||||
context.session_id.as_ref().map(|session| session.as_str()),
|
||||
));
|
||||
}
|
||||
let owner_route = if let Some(target_id) = context.target_id.as_ref() {
|
||||
Some(
|
||||
conn.target_session_route_for_target_id(target_id.as_str())
|
||||
.ok_or_else(|| {
|
||||
DevToolsError::new(DevToolsErrorKind::NoSuchTarget, "NoSuchTarget")
|
||||
})?,
|
||||
)
|
||||
if let Some(target_id) = context.target_id.as_ref() {
|
||||
let route = conn
|
||||
.target_session_route_for_target_id(target_id.as_str())
|
||||
.ok_or_else(|| DevToolsError::new(DevToolsErrorKind::NoSuchTarget, "NoSuchTarget"))?;
|
||||
Ok(CommandOwnerScope::for_route(route))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok((None, owner_route))
|
||||
Ok(CommandOwnerScope::capture(conn, None))
|
||||
}
|
||||
}
|
||||
|
||||
fn start_enable_command(conn: &mut CdpConnection, cmd: &Cmd<'_>) -> FetchCommandTaskStep {
|
||||
@@ -535,9 +527,8 @@ fn start_devtools_add_network_intercept_command(
|
||||
.as_ref()
|
||||
.map(|session_id| session_id.as_str().to_owned())
|
||||
};
|
||||
match conn.start_add_network_intercept_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
match conn.start_add_network_intercept_for_owner(
|
||||
owner,
|
||||
intercept_session_id,
|
||||
command.intercept_id.as_str().to_owned(),
|
||||
handle_auth_requests,
|
||||
@@ -573,12 +564,7 @@ fn start_devtools_remove_network_intercept_command(
|
||||
intercept_id: &str,
|
||||
allow_global_lookup: bool,
|
||||
) -> FetchCommandTaskStep {
|
||||
match conn.start_remove_network_intercept_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
intercept_id,
|
||||
allow_global_lookup,
|
||||
) {
|
||||
match conn.start_remove_network_intercept_for_owner(owner, intercept_id, allow_global_lookup) {
|
||||
Ok(Some(pending)) => {
|
||||
FetchCommandTaskStep::Pending(PendingFetchCommandDispatch::new_for_owner(
|
||||
command_id,
|
||||
@@ -821,10 +807,7 @@ fn complete_fetch_config_update_command(
|
||||
Ok(completion) => completion,
|
||||
Err(error) => return CommandOutputPlan::error(-32000, error),
|
||||
};
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) {
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_owner(&owner_scope) {
|
||||
Ok(page) => page,
|
||||
Err(message) if message == "NoDocumentLoaded" => {
|
||||
return CommandOutputPlan::from_devtools_result(result);
|
||||
@@ -881,10 +864,7 @@ async fn complete_disable_command_async(
|
||||
return;
|
||||
}
|
||||
};
|
||||
match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => {
|
||||
if let Err(error) = page.finish_set_fetch_subresource_interception(completion) {
|
||||
out.push_error(
|
||||
@@ -956,9 +936,8 @@ async fn complete_disable_command_async(
|
||||
}
|
||||
for (_, pending) in pending_subresource_fetches {
|
||||
if let Ok(predecessor) = conn
|
||||
.fail_pending_subresource_fetch_for_route_async(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
.fail_pending_subresource_fetch_for_owner_async(
|
||||
owner,
|
||||
pending.internal_id,
|
||||
"Fetch interception disabled".to_owned(),
|
||||
)
|
||||
@@ -980,9 +959,8 @@ async fn complete_disable_command_async(
|
||||
}
|
||||
for (_, pending) in pending_subresource_auths {
|
||||
if let Ok(predecessor) = conn
|
||||
.fail_pending_subresource_auth_for_route_async(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
.fail_pending_subresource_auth_for_owner_async(
|
||||
owner,
|
||||
pending.internal_id,
|
||||
"Fetch interception disabled".to_owned(),
|
||||
)
|
||||
@@ -1004,9 +982,8 @@ async fn complete_disable_command_async(
|
||||
}
|
||||
for (_, pending) in pending_subresource_responses {
|
||||
if let Ok(predecessor) = conn
|
||||
.fail_pending_subresource_response_for_route_async(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
.fail_pending_subresource_response_for_owner_async(
|
||||
owner,
|
||||
pending.internal_id,
|
||||
"Fetch interception disabled".to_owned(),
|
||||
)
|
||||
|
||||
@@ -168,11 +168,8 @@ pub(super) fn start_devtools_continue_with_auth_command_for_pending(
|
||||
) {
|
||||
Some(correlation) => Some(correlation),
|
||||
None => {
|
||||
conn.register_pending_subresource_fetch_auth_request_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
pending,
|
||||
conn.register_pending_subresource_fetch_auth_request_for_owner(
|
||||
owner, request_id, pending,
|
||||
);
|
||||
return Some(FetchCommandTaskStep::Complete(
|
||||
CommandOutputPlan::error(-32000, "RequestNotFound"),
|
||||
@@ -182,10 +179,7 @@ pub(super) fn start_devtools_continue_with_auth_command_for_pending(
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let pending_page = match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
let pending_page = match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => (match command.action {
|
||||
DevToolsAuthChallengeAction::Default => page
|
||||
.start_fail_pending_subresource_auth(
|
||||
@@ -206,11 +200,8 @@ pub(super) fn start_devtools_continue_with_auth_command_for_pending(
|
||||
if let Some(correlation) = cancel_correlation {
|
||||
correlation.rollback(conn);
|
||||
}
|
||||
conn.register_pending_subresource_fetch_auth_request_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
pending,
|
||||
conn.register_pending_subresource_fetch_auth_request_for_owner(
|
||||
owner, request_id, pending,
|
||||
);
|
||||
return Some(FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
-32000,
|
||||
@@ -249,9 +240,8 @@ pub(super) fn start_devtools_continue_with_auth_command_for_pending(
|
||||
command.username.as_deref().unwrap_or_default(),
|
||||
command.password.as_deref().unwrap_or_default(),
|
||||
) else {
|
||||
conn.register_pending_subresource_fetch_auth_request_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
conn.register_pending_subresource_fetch_auth_request_for_owner(
|
||||
owner,
|
||||
request_id.clone(),
|
||||
pending,
|
||||
);
|
||||
@@ -270,11 +260,8 @@ pub(super) fn start_devtools_continue_with_auth_command_for_pending(
|
||||
) {
|
||||
Some(correlation) => correlation,
|
||||
None => {
|
||||
conn.register_pending_subresource_fetch_auth_request_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
pending,
|
||||
conn.register_pending_subresource_fetch_auth_request_for_owner(
|
||||
owner, request_id, pending,
|
||||
);
|
||||
return Some(FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
-32000,
|
||||
@@ -282,10 +269,7 @@ pub(super) fn start_devtools_continue_with_auth_command_for_pending(
|
||||
)));
|
||||
}
|
||||
};
|
||||
let pending_page = match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
let pending_page = match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => page
|
||||
.start_continue_pending_subresource_auth(pending.internal_id, auth)
|
||||
.map_err(|error| format!("subresource auth continue failed: {error}")),
|
||||
@@ -295,11 +279,8 @@ pub(super) fn start_devtools_continue_with_auth_command_for_pending(
|
||||
Ok(pending_page) => pending_page,
|
||||
Err(message) => {
|
||||
correlation.rollback(conn);
|
||||
conn.register_pending_subresource_fetch_auth_request_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
pending,
|
||||
conn.register_pending_subresource_fetch_auth_request_for_owner(
|
||||
owner, request_id, pending,
|
||||
);
|
||||
return Some(FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
-32000, message,
|
||||
@@ -371,9 +352,8 @@ pub(super) fn start_devtools_continue_with_auth_command_for_pending(
|
||||
command.username.as_deref().unwrap_or_default(),
|
||||
command.password.as_deref().unwrap_or_default(),
|
||||
) else {
|
||||
conn.register_pending_fetch_auth_navigation_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
conn.register_pending_fetch_auth_navigation_for_owner(
|
||||
owner,
|
||||
request_id.clone(),
|
||||
pending,
|
||||
);
|
||||
@@ -617,10 +597,9 @@ async fn complete_subresource_auth_terminal_async(
|
||||
out: &mut FetchCommandOutput,
|
||||
) {
|
||||
let activity_session_id = pending.owner_session_id.as_deref().or(owner.session_id());
|
||||
let activity_owner_route = activity_session_id
|
||||
.is_none()
|
||||
.then(|| owner.session_owner_route())
|
||||
.flatten();
|
||||
let activity_owner = activity_session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
let Some(completed) = completed else {
|
||||
if let Some(correlation) = correlation {
|
||||
correlation.rollback(conn);
|
||||
@@ -638,9 +617,7 @@ async fn complete_subresource_auth_terminal_async(
|
||||
return;
|
||||
}
|
||||
};
|
||||
let result = match conn
|
||||
.loaded_page_mut_for_protocol_access_for_route(activity_session_id, activity_owner_route)
|
||||
{
|
||||
let result = match conn.loaded_page_mut_for_protocol_access_for_owner(&activity_owner) {
|
||||
Ok(page) if expose_challenged_response => page
|
||||
.finish_cancel_pending_subresource_auth(completion)
|
||||
.map(|_| ()),
|
||||
@@ -683,10 +660,7 @@ fn finish_continue_subresource_auth(
|
||||
completed: Option<Result<CompletedPageCommand, String>>,
|
||||
) -> Result<(), String> {
|
||||
let completion = completed.ok_or_else(|| "Missing renderer completion".to_owned())??;
|
||||
let page = conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?;
|
||||
let page = conn.loaded_page_mut_for_protocol_access_for_owner(owner)?;
|
||||
page.finish_continue_pending_subresource_auth(completion)
|
||||
.map(|_| ())
|
||||
.map_err(|error| format!("subresource auth continue failed: {error}"))
|
||||
|
||||
@@ -30,11 +30,9 @@ pub(super) fn start_get_response_body_command(
|
||||
));
|
||||
}
|
||||
};
|
||||
if let Some(transfer) = conn.take_pending_fetch_response_transfer_for_body_read_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
¶ms.request_id,
|
||||
) {
|
||||
if let Some(transfer) = conn
|
||||
.take_pending_fetch_response_transfer_for_body_read_for_owner(&owner, ¶ms.request_id)
|
||||
{
|
||||
return FetchCommandTaskStep::Pending(PendingFetchCommandDispatch::new_for_owner(
|
||||
cmd.id,
|
||||
owner,
|
||||
@@ -114,30 +112,19 @@ pub(super) fn complete_get_response_body_from_transfer(
|
||||
};
|
||||
let plan = match *result {
|
||||
Ok((Some(bytes), transfer)) => {
|
||||
conn.register_pending_fetch_response_transfer_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
transfer,
|
||||
);
|
||||
conn.register_pending_fetch_response_transfer_for_owner(owner, request_id, transfer);
|
||||
response_body_command_output_plan(bytes)
|
||||
}
|
||||
Ok((None, transfer)) => {
|
||||
conn.register_pending_fetch_response_transfer_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
conn.register_pending_fetch_response_transfer_for_owner(
|
||||
owner,
|
||||
request_id.clone(),
|
||||
transfer,
|
||||
);
|
||||
get_response_body_without_transfer_command_output_plan(conn, owner, &request_id)
|
||||
}
|
||||
Err((message, transfer)) => {
|
||||
conn.register_pending_fetch_response_transfer_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
transfer,
|
||||
);
|
||||
conn.register_pending_fetch_response_transfer_for_owner(owner, request_id, transfer);
|
||||
CommandOutputPlan::error(-32000, message)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -260,10 +260,7 @@ fn start_devtools_continue_intercepted_request_command(
|
||||
let headers = command.headers.clone().or(chain_headers);
|
||||
pending.request_stage_chain = None;
|
||||
let configured_response_stage = conn
|
||||
.target_fetch_subresource_interception_snapshot_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.target_fetch_subresource_interception_snapshot_for_owner(owner)
|
||||
.is_some_and(|snapshot| {
|
||||
snapshot.has_response_stage_candidate(pending.resource_type.into())
|
||||
});
|
||||
@@ -277,10 +274,7 @@ fn start_devtools_continue_intercepted_request_command(
|
||||
}
|
||||
return FetchCommandTaskStep::Complete(CommandOutputPlan::success());
|
||||
}
|
||||
let handle_auth_requests = conn.target_fetch_handle_auth_requests_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let handle_auth_requests = conn.target_fetch_handle_auth_requests_for_owner(owner);
|
||||
let should_register =
|
||||
pending.resource_type != SubresourceResourceType::WebSocket || intercept_response;
|
||||
let correlation = match if configured_response_stage && !command.intercept_response {
|
||||
@@ -301,11 +295,8 @@ fn start_devtools_continue_intercepted_request_command(
|
||||
} {
|
||||
Some(correlation) => correlation,
|
||||
None => {
|
||||
conn.register_pending_subresource_fetch_request_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
pending,
|
||||
conn.register_pending_subresource_fetch_request_for_owner(
|
||||
owner, request_id, pending,
|
||||
);
|
||||
return FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
-32000,
|
||||
@@ -313,10 +304,7 @@ fn start_devtools_continue_intercepted_request_command(
|
||||
));
|
||||
}
|
||||
};
|
||||
let pending_page = match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
let pending_page = match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => page
|
||||
.start_continue_pending_subresource_fetch(
|
||||
pending.internal_id,
|
||||
@@ -334,11 +322,8 @@ fn start_devtools_continue_intercepted_request_command(
|
||||
Ok(pending_page) => pending_page,
|
||||
Err(message) => {
|
||||
correlation.rollback(conn);
|
||||
conn.register_pending_subresource_fetch_request_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
pending,
|
||||
conn.register_pending_subresource_fetch_request_for_owner(
|
||||
owner, request_id, pending,
|
||||
);
|
||||
return FetchCommandTaskStep::Complete(CommandOutputPlan::error(-32000, message));
|
||||
}
|
||||
@@ -434,10 +419,7 @@ fn finish_continue_subresource_request(
|
||||
completed: Option<Result<CompletedPageCommand, String>>,
|
||||
) -> Result<(), String> {
|
||||
let completion = completed.ok_or_else(|| "Missing renderer completion".to_owned())??;
|
||||
let page = conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?;
|
||||
let page = conn.loaded_page_mut_for_protocol_access_for_owner(owner)?;
|
||||
page.finish_continue_pending_subresource_fetch(completion)
|
||||
.map(|_| ())
|
||||
.map_err(|error| format!("subresource fetch continue failed: {error}"))
|
||||
@@ -546,10 +528,7 @@ fn start_devtools_fail_intercepted_request_command(
|
||||
let mut plan = CommandOutputPlan::success();
|
||||
let mut events = Vec::new();
|
||||
let loader_id = conn
|
||||
.current_document_loader_id_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.current_document_loader_id_for_owner(owner)
|
||||
.unwrap_or_else(|| DEFAULT_LOADER_ID.to_owned());
|
||||
network::emit_loading_failed(
|
||||
&mut events,
|
||||
@@ -564,10 +543,7 @@ fn start_devtools_fail_intercepted_request_command(
|
||||
plan.extend_background_events(events);
|
||||
return FetchCommandTaskStep::Complete(plan);
|
||||
}
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => page,
|
||||
Err(message) if message == "NoDocumentLoaded" => {
|
||||
return FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
@@ -608,10 +584,7 @@ fn start_devtools_fail_intercepted_request_command(
|
||||
action_session_id,
|
||||
&request_id,
|
||||
) {
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => page,
|
||||
Err(message) if message == "NoDocumentLoaded" => {
|
||||
return FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
@@ -646,11 +619,9 @@ fn start_devtools_fail_intercepted_request_command(
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(transfer) = conn.take_pending_fetch_response_transfer_for_terminal_action_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
&request_id,
|
||||
) {
|
||||
if let Some(transfer) =
|
||||
conn.take_pending_fetch_response_transfer_for_terminal_action_for_owner(owner, &request_id)
|
||||
{
|
||||
return FetchCommandTaskStep::Pending(PendingFetchCommandDispatch::new_for_owner(
|
||||
command_id,
|
||||
owner.clone(),
|
||||
@@ -712,10 +683,7 @@ pub(super) async fn complete_fail_request_command_async(
|
||||
return;
|
||||
}
|
||||
};
|
||||
match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => {
|
||||
if let Err(error) = page.finish_fail_pending_subresource_fetch(completion) {
|
||||
out.push_error(-32000, format!("subresource fetch fail failed: {error}"));
|
||||
@@ -754,10 +722,7 @@ pub(super) async fn complete_fail_request_command_async(
|
||||
return;
|
||||
}
|
||||
};
|
||||
match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => {
|
||||
if let Err(error) = page.finish_fail_pending_subresource_response(completion) {
|
||||
out.push_error(
|
||||
@@ -956,10 +921,7 @@ fn start_devtools_fulfill_intercepted_request_command(
|
||||
let websocket_socket_id = pending.websocket_socket_id;
|
||||
let register_synthetic_websocket =
|
||||
pending.resource_type == SubresourceResourceType::WebSocket && response_code == 101;
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => page,
|
||||
Err(message) if message == "NoDocumentLoaded" => {
|
||||
return FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
@@ -1007,10 +969,7 @@ fn start_devtools_fulfill_intercepted_request_command(
|
||||
action_session_id,
|
||||
&request_id,
|
||||
) {
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => page,
|
||||
Err(message) if message == "NoDocumentLoaded" => {
|
||||
return FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
@@ -1064,11 +1023,9 @@ fn start_devtools_fulfill_intercepted_request_command(
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(transfer) = conn.take_pending_fetch_response_transfer_for_terminal_action_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
&request_id,
|
||||
) {
|
||||
if let Some(transfer) =
|
||||
conn.take_pending_fetch_response_transfer_for_terminal_action_for_owner(owner, &request_id)
|
||||
{
|
||||
return FetchCommandTaskStep::Pending(PendingFetchCommandDispatch::new_for_owner(
|
||||
command_id,
|
||||
owner.clone(),
|
||||
@@ -1116,10 +1073,7 @@ pub(super) async fn complete_fulfill_request_command_async(
|
||||
return;
|
||||
}
|
||||
};
|
||||
match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => {
|
||||
if let Err(error) = page.finish_fulfill_pending_subresource_fetch(completion) {
|
||||
out.push_error(
|
||||
@@ -1139,9 +1093,8 @@ pub(super) async fn complete_fulfill_request_command_async(
|
||||
}
|
||||
}
|
||||
if register_synthetic_websocket && let Some(socket_id) = websocket_socket_id {
|
||||
conn.register_synthetic_websocket_request_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
conn.register_synthetic_websocket_request_for_owner(
|
||||
owner,
|
||||
request_id,
|
||||
network_request_id,
|
||||
socket_id,
|
||||
@@ -1170,10 +1123,7 @@ pub(super) async fn complete_fulfill_request_command_async(
|
||||
return;
|
||||
}
|
||||
};
|
||||
match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => {
|
||||
if let Err(error) = page.finish_fulfill_pending_subresource_response(completion)
|
||||
{
|
||||
@@ -1424,10 +1374,7 @@ pub(super) fn complete_websocket_page_command(
|
||||
return;
|
||||
}
|
||||
};
|
||||
let result = match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
let result = match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => match operation {
|
||||
PendingWebSocketCommandOperation::DispatchText => {
|
||||
page.finish_receive_synthetic_websocket_text(completion)
|
||||
@@ -1560,17 +1507,12 @@ fn start_devtools_continue_intercepted_response_command(
|
||||
command.context.protocol,
|
||||
command.context.session_id.as_ref(),
|
||||
);
|
||||
if let Some(transfer) = conn.take_pending_fetch_response_transfer_for_terminal_action_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
&request_id,
|
||||
) {
|
||||
if let Some(transfer) =
|
||||
conn.take_pending_fetch_response_transfer_for_terminal_action_for_owner(owner, &request_id)
|
||||
{
|
||||
let _ = &command.response_phrase;
|
||||
let transfer_response_headers = response_headers.clone().unwrap_or_default();
|
||||
if let Some(sender) = conn.background_navigation_completion_sender_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
if let Some(sender) = conn.background_navigation_completion_sender_for_owner(owner) {
|
||||
match transfer.into_pending_streaming_document_response_navigation() {
|
||||
Ok(pending) => {
|
||||
// Chromium ACKs Fetch.continueResponse when the response-stage
|
||||
@@ -1627,11 +1569,8 @@ fn start_devtools_continue_intercepted_response_command(
|
||||
&request_id,
|
||||
) {
|
||||
if pending.response_body_taken_as_stream {
|
||||
conn.register_pending_subresource_fetch_response_request_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
pending,
|
||||
conn.register_pending_subresource_fetch_response_request_for_owner(
|
||||
owner, request_id, pending,
|
||||
);
|
||||
return FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
-32602,
|
||||
@@ -1681,11 +1620,8 @@ fn start_devtools_continue_intercepted_response_command(
|
||||
|| response_headers.is_some()
|
||||
|| command.response_phrase.is_some()
|
||||
{
|
||||
conn.register_pending_subresource_fetch_response_request_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
pending,
|
||||
conn.register_pending_subresource_fetch_response_request_for_owner(
|
||||
owner, request_id, pending,
|
||||
);
|
||||
return FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
-32602,
|
||||
@@ -1705,10 +1641,7 @@ fn start_devtools_continue_intercepted_response_command(
|
||||
response_headers
|
||||
};
|
||||
let pending_internal_id = pending.internal_id;
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
command_session_id,
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
let page = match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => page,
|
||||
Err(message) if message == "NoDocumentLoaded" => {
|
||||
return FetchCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
@@ -1812,12 +1745,7 @@ async fn continue_response_transfer_inline(
|
||||
.await;
|
||||
}
|
||||
Err(transfer) => {
|
||||
conn.register_pending_fetch_response_transfer_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
transfer,
|
||||
);
|
||||
conn.register_pending_fetch_response_transfer_for_owner(owner, request_id, transfer);
|
||||
out.push_error(-32000, "ResponseBodyStreamActive");
|
||||
}
|
||||
}
|
||||
@@ -1861,10 +1789,7 @@ pub(super) async fn complete_continue_response_command_async(
|
||||
return;
|
||||
}
|
||||
};
|
||||
match conn.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => {
|
||||
if let Err(error) =
|
||||
page.finish_continue_pending_subresource_response(completion)
|
||||
@@ -2364,9 +2289,8 @@ mod protocol_neutral_tests {
|
||||
);
|
||||
|
||||
assert!(
|
||||
conn.take_pending_subresource_fetch_response_request_for_route(
|
||||
Some("SID-primary"),
|
||||
None,
|
||||
conn.take_pending_subresource_fetch_response_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-primary"),
|
||||
Some("SID-primary"),
|
||||
"FETCH-response-aux",
|
||||
)
|
||||
@@ -2374,9 +2298,8 @@ mod protocol_neutral_tests {
|
||||
"old owner action session must not be able to resolve the chained response"
|
||||
);
|
||||
let chained = conn
|
||||
.take_pending_subresource_fetch_response_request_for_route(
|
||||
Some("SID-aux"),
|
||||
None,
|
||||
.take_pending_subresource_fetch_response_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-aux"),
|
||||
Some("SID-aux"),
|
||||
"FETCH-response-aux",
|
||||
)
|
||||
@@ -2480,9 +2403,8 @@ mod protocol_neutral_tests {
|
||||
"BiDi-only session id has no CDP route and must not own the stored pending request"
|
||||
);
|
||||
let chained = conn
|
||||
.take_pending_subresource_fetch_request_for_route(
|
||||
Some("SID-primary"),
|
||||
None,
|
||||
.take_pending_subresource_fetch_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-primary"),
|
||||
Some("BIDI-SID"),
|
||||
"FETCH-bidi",
|
||||
)
|
||||
|
||||
@@ -37,10 +37,7 @@ fn prepare_navigation_response_stage(
|
||||
return true;
|
||||
}
|
||||
let Some(response_stage) = conn
|
||||
.target_fetch_subresource_interception_snapshot_for_route(
|
||||
pending.navigation.owner.session_id(),
|
||||
pending.navigation.owner.session_owner_route(),
|
||||
)
|
||||
.target_fetch_subresource_interception_snapshot_for_owner(&pending.navigation.owner)
|
||||
.and_then(|snapshot| {
|
||||
snapshot
|
||||
.matching_response_stage_pause_sessions(
|
||||
@@ -66,11 +63,9 @@ pub(crate) async fn load_or_pause_navigation_for_auth_into_buffer_async(
|
||||
prior_network_observation_journal: Option<NetworkObservationJournal>,
|
||||
) {
|
||||
let navigate_owner = pending.navigation.owner.clone();
|
||||
let navigate_session_id = pending.navigation.owner.session_id().map(str::to_owned);
|
||||
network::record_main_document_request_body(conn, &pending.navigation);
|
||||
let should_handle_auth = conn.target_fetch_matches_auth_required_for_route(
|
||||
navigate_session_id.as_deref(),
|
||||
navigate_owner.session_owner_route(),
|
||||
let should_handle_auth = conn.target_fetch_matches_auth_required_for_owner(
|
||||
&navigate_owner,
|
||||
&pending.navigation.requested_url,
|
||||
) && pending.navigation.requested_url.scheme() != "data";
|
||||
|
||||
@@ -82,9 +77,8 @@ pub(crate) async fn load_or_pause_navigation_for_auth_into_buffer_async(
|
||||
let has_auth_credentials = auth.is_some();
|
||||
if pending.intercept_response && navigation_response_stage_auth_can_stream(auth.as_ref()) {
|
||||
match conn
|
||||
.fetch_navigation_streaming_raw_response_for_route_async(
|
||||
navigate_session_id.as_deref(),
|
||||
navigate_owner.session_owner_route(),
|
||||
.fetch_navigation_streaming_raw_response_for_owner_async(
|
||||
&navigate_owner,
|
||||
pending.navigation.request_load_policy,
|
||||
&method,
|
||||
&raw_url,
|
||||
@@ -140,9 +134,8 @@ pub(crate) async fn load_or_pause_navigation_for_auth_into_buffer_async(
|
||||
// before libcurl has completed the credential retry, so keep
|
||||
// credential replay on the buffered path until the fetch runtime
|
||||
// can mark intermediate auth responses separately.
|
||||
conn.fetch_navigation_auth_raw_response_for_route_async(
|
||||
navigate_session_id.as_deref(),
|
||||
navigate_owner.session_owner_route(),
|
||||
conn.fetch_navigation_auth_raw_response_for_owner_async(
|
||||
&navigate_owner,
|
||||
pending.navigation.request_load_policy,
|
||||
&method,
|
||||
&raw_url,
|
||||
@@ -153,9 +146,8 @@ pub(crate) async fn load_or_pause_navigation_for_auth_into_buffer_async(
|
||||
.await
|
||||
} else {
|
||||
match conn
|
||||
.fetch_navigation_streaming_raw_response_for_route_async(
|
||||
navigate_session_id.as_deref(),
|
||||
navigate_owner.session_owner_route(),
|
||||
.fetch_navigation_streaming_raw_response_for_owner_async(
|
||||
&navigate_owner,
|
||||
pending.navigation.request_load_policy,
|
||||
&method,
|
||||
&raw_url,
|
||||
@@ -225,9 +217,8 @@ pub(crate) async fn load_or_pause_navigation_for_auth_into_buffer_async(
|
||||
|
||||
if pending.intercept_response && pending.navigation.requested_url.scheme() != "data" {
|
||||
match conn
|
||||
.fetch_navigation_streaming_raw_response_for_route_async(
|
||||
navigate_session_id.as_deref(),
|
||||
navigate_owner.session_owner_route(),
|
||||
.fetch_navigation_streaming_raw_response_for_owner_async(
|
||||
&navigate_owner,
|
||||
pending.navigation.request_load_policy,
|
||||
&pending.navigation.request_method,
|
||||
pending.navigation.requested_url.as_str(),
|
||||
@@ -581,8 +572,8 @@ async fn handle_streaming_response_head_for_navigation_into_buffer_async(
|
||||
}
|
||||
};
|
||||
let (response, network_observation_journal) = response.into_parts_with_observation_journal();
|
||||
conn.register_pending_fetch_response_navigation_for_session_owner(
|
||||
pending.navigation.owner.session_id(),
|
||||
conn.register_pending_fetch_response_navigation_for_owner(
|
||||
&pending.navigation.owner,
|
||||
pending.fetch_request_id.clone(),
|
||||
pending.document_navigation_token.clone(),
|
||||
pending.navigation.clone(),
|
||||
@@ -690,8 +681,8 @@ fn pause_buffered_raw_response_stage_navigation_into_buffer(
|
||||
let response_headers = response.response().headers.clone();
|
||||
let request_cookie_report = response.response().request_cookie_report.clone();
|
||||
let (response, network_observation_journal) = response.into_parts_with_observation_journal();
|
||||
conn.register_pending_fetch_response_navigation_for_session_owner(
|
||||
pending.navigation.owner.session_id(),
|
||||
conn.register_pending_fetch_response_navigation_for_owner(
|
||||
&pending.navigation.owner,
|
||||
pending.fetch_request_id.clone(),
|
||||
pending.document_navigation_token.clone(),
|
||||
pending.navigation.clone(),
|
||||
@@ -759,8 +750,6 @@ pub(crate) async fn continue_subresource_without_fetch_pause_async(
|
||||
handle_auth_requests: bool,
|
||||
owner_kind: PendingSubresourceFetchOwnerKind,
|
||||
) {
|
||||
let session_id = owner.session_id();
|
||||
let owner_route = owner.session_owner_route();
|
||||
let pending = PendingSubresourceFetchRequest {
|
||||
residence: crate::conn::PendingSubresourceFetchResidence::InstalledPage(page_owner),
|
||||
owner_session_id: None,
|
||||
@@ -776,9 +765,8 @@ pub(crate) async fn continue_subresource_without_fetch_pause_async(
|
||||
request_stage_chain: None,
|
||||
};
|
||||
if conn
|
||||
.continue_pending_subresource_fetch_for_route_async(
|
||||
session_id,
|
||||
owner_route,
|
||||
.continue_pending_subresource_fetch_for_owner_async(
|
||||
owner,
|
||||
internal_id,
|
||||
None,
|
||||
None,
|
||||
@@ -790,12 +778,7 @@ pub(crate) async fn continue_subresource_without_fetch_pause_async(
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
conn.register_in_flight_subresource_fetch_request_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
request_id,
|
||||
pending,
|
||||
);
|
||||
conn.register_in_flight_subresource_fetch_request_for_owner(owner, request_id, pending);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,8 +789,8 @@ fn navigation_auth_required_blocked_intercepts(
|
||||
if !pending.auth_required_blocked_intercepts.is_empty() {
|
||||
return pending.auth_required_blocked_intercepts.clone();
|
||||
}
|
||||
let intercepts = conn.target_fetch_matching_auth_required_network_intercepts_for_session_owner(
|
||||
pending.navigation.owner.session_id(),
|
||||
let intercepts = conn.target_fetch_matching_auth_required_network_intercepts_for_owner(
|
||||
&pending.navigation.owner,
|
||||
&pending.navigation.requested_url,
|
||||
);
|
||||
if !intercepts.is_empty() {
|
||||
@@ -875,10 +858,7 @@ fn register_navigation_auth_required_event(
|
||||
let auth_sessions = conn
|
||||
.target_fetch_subresource_interception_snapshot_for_target(&pending.navigation.frame_id)
|
||||
.or_else(|| {
|
||||
conn.target_fetch_subresource_interception_snapshot_for_route(
|
||||
pending.navigation.owner.session_id(),
|
||||
pending.navigation.owner.session_owner_route(),
|
||||
)
|
||||
conn.target_fetch_subresource_interception_snapshot_for_owner(&pending.navigation.owner)
|
||||
})
|
||||
.map(|snapshot| {
|
||||
snapshot.matching_auth_required_pause_sessions(
|
||||
@@ -902,10 +882,9 @@ fn register_navigation_auth_required_event(
|
||||
);
|
||||
let mut remaining_sessions = Vec::new();
|
||||
for session in auth_sessions.into_iter().skip(1) {
|
||||
let Ok(next_request_id) = conn.allocate_fetch_navigation_request_id_for_route(
|
||||
pending.navigation.owner.session_id(),
|
||||
pending.navigation.owner.session_owner_route(),
|
||||
) else {
|
||||
let Ok(next_request_id) =
|
||||
conn.allocate_fetch_navigation_request_id_for_owner(&pending.navigation.owner)
|
||||
else {
|
||||
break;
|
||||
};
|
||||
remaining_sessions.push(PendingSubresourceFetchAuthStage {
|
||||
@@ -930,13 +909,11 @@ fn register_navigation_auth_required_event(
|
||||
.owner_session_id
|
||||
.as_deref()
|
||||
.or(pending.navigation.owner.session_id());
|
||||
let pending_owner_route = pending_owner_session_id
|
||||
.is_none()
|
||||
.then(|| pending.navigation.owner.session_owner_route())
|
||||
.flatten();
|
||||
conn.register_pending_fetch_auth_navigation_for_route(
|
||||
pending_owner_session_id,
|
||||
pending_owner_route,
|
||||
let pending_owner = pending_owner_session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| pending.navigation.owner.clone());
|
||||
conn.register_pending_fetch_auth_navigation_for_owner(
|
||||
&pending_owner,
|
||||
pending.fetch_request_id.clone(),
|
||||
pending_auth.clone(),
|
||||
);
|
||||
@@ -956,14 +933,12 @@ pub(crate) async fn continue_subresource_for_response_stage_async(
|
||||
handle_auth_requests: bool,
|
||||
response_stage_blocked_intercepts: Vec<DevToolsNetworkInterceptId>,
|
||||
) {
|
||||
let owner_route = session_id
|
||||
.is_none()
|
||||
.then(|| owner.session_owner_route())
|
||||
.flatten();
|
||||
let action_owner = session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
if conn
|
||||
.continue_pending_subresource_fetch_for_route_async(
|
||||
session_id,
|
||||
owner_route,
|
||||
.continue_pending_subresource_fetch_for_owner_async(
|
||||
&action_owner,
|
||||
pending.internal_id,
|
||||
None,
|
||||
None,
|
||||
@@ -975,9 +950,8 @@ pub(crate) async fn continue_subresource_for_response_stage_async(
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
conn.register_in_flight_response_stage_subresource_fetch_request_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
conn.register_in_flight_response_stage_subresource_fetch_request_for_owner(
|
||||
&action_owner,
|
||||
Some(request_id),
|
||||
pending,
|
||||
response_stage_blocked_intercepts,
|
||||
@@ -993,14 +967,12 @@ pub(crate) async fn continue_subresource_for_deferred_response_stage_async(
|
||||
pending: PendingSubresourceFetchRequest,
|
||||
handle_auth_requests: bool,
|
||||
) {
|
||||
let owner_route = session_id
|
||||
.is_none()
|
||||
.then(|| owner.session_owner_route())
|
||||
.flatten();
|
||||
let action_owner = session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
if conn
|
||||
.continue_pending_subresource_fetch_for_route_async(
|
||||
session_id,
|
||||
owner_route,
|
||||
.continue_pending_subresource_fetch_for_owner_async(
|
||||
&action_owner,
|
||||
pending.internal_id,
|
||||
None,
|
||||
None,
|
||||
@@ -1012,9 +984,8 @@ pub(crate) async fn continue_subresource_for_deferred_response_stage_async(
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
conn.register_in_flight_deferred_response_stage_subresource_fetch_request_for_route(
|
||||
session_id,
|
||||
owner_route,
|
||||
conn.register_in_flight_deferred_response_stage_subresource_fetch_request_for_owner(
|
||||
&action_owner,
|
||||
Some(request_id),
|
||||
pending,
|
||||
);
|
||||
|
||||
@@ -27,9 +27,8 @@ impl PreparedSubresourceCorrelation {
|
||||
should_register: bool,
|
||||
) -> Option<Self> {
|
||||
if should_register
|
||||
&& !conn.register_in_flight_subresource_fetch_request_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
&& !conn.register_in_flight_subresource_fetch_request_for_owner(
|
||||
owner,
|
||||
Some(request_id.to_owned()),
|
||||
pending.clone(),
|
||||
)
|
||||
@@ -45,9 +44,8 @@ impl PreparedSubresourceCorrelation {
|
||||
|
||||
pub(super) fn rollback(self, conn: &mut CdpConnection) {
|
||||
if self.registered {
|
||||
conn.take_in_flight_subresource_fetch_request_for_route(
|
||||
self.owner_scope.session_id(),
|
||||
self.owner_scope.session_owner_route(),
|
||||
conn.take_in_flight_subresource_fetch_request_for_owner(
|
||||
&self.owner_scope,
|
||||
self.internal_id,
|
||||
);
|
||||
}
|
||||
@@ -59,9 +57,8 @@ impl PreparedSubresourceCorrelation {
|
||||
request_id: &str,
|
||||
pending: &PendingSubresourceFetchRequest,
|
||||
) -> Option<Self> {
|
||||
if !conn.register_in_flight_deferred_response_stage_subresource_fetch_request_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
if !conn.register_in_flight_deferred_response_stage_subresource_fetch_request_for_owner(
|
||||
owner,
|
||||
Some(request_id.to_owned()),
|
||||
pending.clone(),
|
||||
) {
|
||||
@@ -123,11 +120,7 @@ pub(crate) fn pending_request_action_result_with_id_validation(
|
||||
if validate_id && validate_request_id(request_id).is_err() {
|
||||
return Err(CommandOutputPlan::error(-32602, "InvalidParams"));
|
||||
}
|
||||
let Some(result) = conn.consume_pending_request_action_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
request_id,
|
||||
) else {
|
||||
let Some(result) = conn.consume_pending_request_action_for_owner(owner, request_id) else {
|
||||
return Err(CommandOutputPlan::error(-31998, "BrowserContextNotLoaded"));
|
||||
};
|
||||
if result.is_err() {
|
||||
@@ -142,12 +135,7 @@ pub(crate) fn take_pending_navigation(
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingFetchNavigation> {
|
||||
conn.take_pending_fetch_navigation_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
action_session_id,
|
||||
request_id,
|
||||
)
|
||||
conn.take_pending_fetch_navigation_for_owner(owner, action_session_id, request_id)
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_auth_navigation_for_action_session(
|
||||
@@ -156,12 +144,7 @@ pub(crate) fn take_pending_auth_navigation_for_action_session(
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingFetchAuthNavigation> {
|
||||
conn.take_pending_fetch_auth_navigation_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
action_session_id,
|
||||
request_id,
|
||||
)
|
||||
conn.take_pending_fetch_auth_navigation_for_owner(owner, action_session_id, request_id)
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_subresource_fetch_request_for_action_session(
|
||||
@@ -170,12 +153,7 @@ pub(crate) fn take_pending_subresource_fetch_request_for_action_session(
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingSubresourceFetchRequest> {
|
||||
conn.take_pending_subresource_fetch_request_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
action_session_id,
|
||||
request_id,
|
||||
)
|
||||
conn.take_pending_subresource_fetch_request_for_owner(owner, action_session_id, request_id)
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_subresource_auth_request_for_action_session(
|
||||
@@ -184,12 +162,7 @@ pub(crate) fn take_pending_subresource_auth_request_for_action_session(
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingSubresourceFetchAuthRequest> {
|
||||
conn.take_pending_subresource_fetch_auth_request_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
action_session_id,
|
||||
request_id,
|
||||
)
|
||||
conn.take_pending_subresource_fetch_auth_request_for_owner(owner, action_session_id, request_id)
|
||||
}
|
||||
|
||||
pub(crate) fn take_pending_subresource_response_request_for_action_session(
|
||||
@@ -198,9 +171,8 @@ pub(crate) fn take_pending_subresource_response_request_for_action_session(
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingSubresourceFetchResponseRequest> {
|
||||
conn.take_pending_subresource_fetch_response_request_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
conn.take_pending_subresource_fetch_response_request_for_owner(
|
||||
owner,
|
||||
action_session_id,
|
||||
request_id,
|
||||
)
|
||||
@@ -212,12 +184,7 @@ pub(crate) fn pending_subresource_response_request_for_action_session(
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> Option<PendingSubresourceFetchResponseRequest> {
|
||||
conn.pending_subresource_fetch_response_request_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
action_session_id,
|
||||
request_id,
|
||||
)
|
||||
conn.pending_subresource_fetch_response_request_for_owner(owner, action_session_id, request_id)
|
||||
}
|
||||
|
||||
pub(crate) fn mark_pending_subresource_response_body_taken_as_stream_for_action_session(
|
||||
@@ -226,9 +193,8 @@ pub(crate) fn mark_pending_subresource_response_body_taken_as_stream_for_action_
|
||||
action_session_id: Option<&str>,
|
||||
request_id: &str,
|
||||
) -> bool {
|
||||
conn.mark_pending_subresource_fetch_response_body_taken_as_stream_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
conn.mark_pending_subresource_fetch_response_body_taken_as_stream_for_owner(
|
||||
owner,
|
||||
action_session_id,
|
||||
request_id,
|
||||
)
|
||||
|
||||
@@ -61,11 +61,7 @@ pub(crate) async fn subresource_fetch_pause_prepared_outputs_for_renderer_record
|
||||
source_document: moli_core::RendererDocumentLifecycleIdentity,
|
||||
info: moli_core::page::PendingSubresourceFetchInfo,
|
||||
) -> network::NetworkPreparedOutputs {
|
||||
if conn.target_root_document_lifecycle_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) != Some(source_document)
|
||||
{
|
||||
if conn.target_root_document_lifecycle_identity_for_owner(owner) != Some(source_document) {
|
||||
return network::NetworkPreparedOutputs::default();
|
||||
}
|
||||
network::NetworkPreparedOutputs::from_subresource_fetch_pauses(
|
||||
@@ -90,11 +86,7 @@ pub(crate) async fn detached_parser_script_fetch_pause_prepared_outputs_for_rend
|
||||
info: moli_core::page::PendingSubresourceFetchInfo,
|
||||
continuation: DetachedParserScriptFetchContinuation,
|
||||
) -> network::NetworkPreparedOutputs {
|
||||
if conn.target_root_document_lifecycle_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) != Some(source_document)
|
||||
{
|
||||
if conn.target_root_document_lifecycle_identity_for_owner(owner) != Some(source_document) {
|
||||
return network::NetworkPreparedOutputs::default();
|
||||
}
|
||||
network::NetworkPreparedOutputs::from_subresource_fetch_pauses(
|
||||
@@ -121,22 +113,21 @@ async fn prepare_subresource_fetch_pause_sources_async(
|
||||
) -> Vec<network::TargetSubresourceFetchPauseOutput> {
|
||||
let mut outputs = Vec::new();
|
||||
let session_id = owner.session_id();
|
||||
let owner_route = owner.session_owner_route();
|
||||
let page_owner = conn.target_page_residence_identity_for_route(session_id, owner_route);
|
||||
let page_owner = conn.target_page_residence_identity_for_owner(owner);
|
||||
let Some((fetch_snapshot, frame_id)) = (|| {
|
||||
let target_frame_id = conn
|
||||
.target_session_owner_frame_tree_identity_for_route(session_id, owner_route)
|
||||
.target_session_owner_frame_tree_identity_for_owner(owner)
|
||||
.map(|(target_id, _, _, _)| target_id)?;
|
||||
let frame_id = frame_id.unwrap_or(&target_frame_id);
|
||||
Some((
|
||||
conn.target_fetch_subresource_interception_snapshot_for_route(session_id, owner_route)?,
|
||||
conn.target_fetch_subresource_interception_snapshot_for_owner(owner)?,
|
||||
frame_id.to_owned(),
|
||||
))
|
||||
})() else {
|
||||
return outputs;
|
||||
};
|
||||
let loader_id = conn
|
||||
.current_document_loader_id_for_route(session_id, owner_route)
|
||||
.current_document_loader_id_for_owner(owner)
|
||||
.unwrap_or_else(|| DEFAULT_LOADER_ID.to_owned());
|
||||
for source in sources {
|
||||
let PendingSubresourceFetchPauseSource {
|
||||
@@ -144,7 +135,7 @@ async fn prepare_subresource_fetch_pause_sources_async(
|
||||
detached_parser_script_fetch_continuation,
|
||||
} = source;
|
||||
let Ok((request_id, network_request_id)) =
|
||||
conn.allocate_pending_subresource_fetch_request_ids_for_route(session_id, owner_route)
|
||||
conn.allocate_pending_subresource_fetch_request_ids_for_owner(owner)
|
||||
else {
|
||||
return outputs;
|
||||
};
|
||||
@@ -307,8 +298,8 @@ async fn prepare_subresource_fetch_pause_sources_async(
|
||||
);
|
||||
let mut remaining_sessions = Vec::new();
|
||||
for session in request_stage_pause_sessions.into_iter().skip(1) {
|
||||
let Ok((next_request_id, _)) = conn
|
||||
.allocate_pending_subresource_fetch_request_ids_for_route(session_id, owner_route)
|
||||
let Ok((next_request_id, _)) =
|
||||
conn.allocate_pending_subresource_fetch_request_ids_for_owner(owner)
|
||||
else {
|
||||
return outputs;
|
||||
};
|
||||
@@ -385,10 +376,9 @@ pub(crate) fn emit_subresource_fetch_pause_outputs(
|
||||
.as_deref()
|
||||
.filter(|session_id| conn.session_route(Some(session_id)).is_some())
|
||||
.or(owner.session_id());
|
||||
let pending_owner_route = pending_owner_session_id
|
||||
.is_none()
|
||||
.then(|| owner.session_owner_route())
|
||||
.flatten();
|
||||
let pending_owner = pending_owner_session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
pending.action_session_id = event_session_id.clone();
|
||||
let blocked_intercepts = blocked_intercepts_from_fetch_payload(&payload);
|
||||
let fetch_event = subresource_request_paused_event(
|
||||
@@ -398,17 +388,14 @@ pub(crate) fn emit_subresource_fetch_pause_outputs(
|
||||
payload,
|
||||
blocked_intercepts,
|
||||
);
|
||||
if !conn.register_pending_subresource_fetch_request_for_route(
|
||||
pending_owner_session_id,
|
||||
pending_owner_route,
|
||||
if !conn.register_pending_subresource_fetch_request_for_owner(
|
||||
&pending_owner,
|
||||
request_id,
|
||||
pending,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if let Ok(runtime_slot) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(pending_owner_session_id, pending_owner_route)
|
||||
{
|
||||
if let Ok(runtime_slot) = conn.runtime_session_owner_slot_mut_for_owner(&pending_owner) {
|
||||
// Chromium publishes Network.requestWillBeSent before the Fetch pause.
|
||||
// The renderer's later transport start belongs to the same lifecycle
|
||||
// and must not publish a second initial Network event.
|
||||
|
||||
@@ -130,7 +130,10 @@ async fn assert_correlation_lifetime(
|
||||
assert!(matches!(&step, CdpCommandTaskStep::Pending(_)));
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.in_flight_subresource_fetch_request_id_for_route(Some("SID-1"), None, internal_id,)
|
||||
.in_flight_subresource_fetch_request_id_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
internal_id,
|
||||
)
|
||||
.as_deref(),
|
||||
Some(request_id),
|
||||
"renderer-visible network work must have protocol correlation state"
|
||||
@@ -144,8 +147,10 @@ async fn assert_correlation_lifetime(
|
||||
"the synthetic unknown renderer request should fail"
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.in_flight_subresource_fetch_request_id_for_route(Some("SID-1"), None, internal_id,),
|
||||
ctx.conn.in_flight_subresource_fetch_request_id_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
internal_id,
|
||||
),
|
||||
None,
|
||||
"failed renderer completion must roll back prepared correlation state"
|
||||
);
|
||||
@@ -174,10 +179,8 @@ async fn deferred_fetch_command_keeps_its_exact_page_for_implicit_work() {
|
||||
.wait()
|
||||
.await;
|
||||
assert_eq!(
|
||||
ctx.conn.target_owner_identity_for_route(
|
||||
completed.owner_scope.session_id(),
|
||||
completed.owner_scope.session_owner_route(),
|
||||
),
|
||||
ctx.conn
|
||||
.target_owner_identity_for_owner(&completed.owner_scope,),
|
||||
Some(("BID-1".to_owned(), Some("TID-background".to_owned()))),
|
||||
"protocol-neutral completion work must stay on the Page that issued the Fetch command"
|
||||
);
|
||||
@@ -210,10 +213,8 @@ async fn deferred_sessionless_fetch_command_freezes_the_active_page_at_admission
|
||||
.expect("browser context")
|
||||
.set_active_target_id("TID-next");
|
||||
assert_eq!(
|
||||
ctx.conn.target_owner_identity_for_route(
|
||||
completed.owner_scope.session_id(),
|
||||
completed.owner_scope.session_owner_route(),
|
||||
),
|
||||
ctx.conn
|
||||
.target_owner_identity_for_owner(&completed.owner_scope,),
|
||||
Some((
|
||||
"BID-sessionless".to_owned(),
|
||||
Some("TID-original".to_owned())
|
||||
@@ -275,9 +276,8 @@ async fn pending_fetch_command_state_is_bound_to_page_attachment() {
|
||||
.replace_page_attachment_id_for_test();
|
||||
assert!(
|
||||
ctx.conn
|
||||
.take_pending_subresource_fetch_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.take_pending_subresource_fetch_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
Some("SID-1"),
|
||||
"INT-collision",
|
||||
)
|
||||
@@ -301,9 +301,8 @@ async fn pending_fetch_command_state_is_bound_to_page_attachment() {
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.take_pending_subresource_fetch_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.take_pending_subresource_fetch_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
Some("SID-1"),
|
||||
"INT-collision",
|
||||
)
|
||||
@@ -331,9 +330,8 @@ async fn completed_continue_atomically_claims_a_pause_still_pending_publication(
|
||||
|
||||
assert!(
|
||||
ctx.conn
|
||||
.claim_subresource_continue_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.claim_subresource_continue_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
&page_owner,
|
||||
74,
|
||||
false,
|
||||
@@ -343,7 +341,12 @@ async fn completed_continue_atomically_claims_a_pause_still_pending_publication(
|
||||
);
|
||||
let claimed = ctx
|
||||
.conn
|
||||
.claim_subresource_continue_request_for_route(Some("SID-1"), None, &page_owner, 74, true)
|
||||
.claim_subresource_continue_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
&page_owner,
|
||||
74,
|
||||
true,
|
||||
)
|
||||
.expect("terminal completion should claim the still-pending pause");
|
||||
let ClaimedSubresourceContinueRequest::PendingCompletion(pending) = claimed else {
|
||||
panic!("terminal completion must preserve the pending-publication race state");
|
||||
@@ -351,9 +354,8 @@ async fn completed_continue_atomically_claims_a_pause_still_pending_publication(
|
||||
assert_eq!(pending.network_request_id, "NETWORK-74");
|
||||
assert!(
|
||||
ctx.conn
|
||||
.claim_subresource_continue_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.claim_subresource_continue_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
&page_owner,
|
||||
74,
|
||||
true,
|
||||
@@ -373,18 +375,16 @@ async fn completed_continue_atomically_claims_a_pause_still_pending_publication(
|
||||
let replacement = pending_request(&replacement_owner, 75);
|
||||
assert!(
|
||||
ctx.conn
|
||||
.register_in_flight_subresource_fetch_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.register_in_flight_subresource_fetch_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
Some("INT-replacement".to_owned()),
|
||||
replacement,
|
||||
)
|
||||
);
|
||||
assert!(
|
||||
ctx.conn
|
||||
.claim_subresource_continue_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.claim_subresource_continue_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
&page_owner,
|
||||
75,
|
||||
true,
|
||||
@@ -394,7 +394,10 @@ async fn completed_continue_atomically_claims_a_pause_still_pending_publication(
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.in_flight_subresource_fetch_request_id_for_route(Some("SID-1"), None, 75)
|
||||
.in_flight_subresource_fetch_request_id_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
75
|
||||
)
|
||||
.as_deref(),
|
||||
Some("INT-replacement"),
|
||||
"a rejected stale capture must leave the replacement request resident"
|
||||
@@ -410,9 +413,8 @@ async fn continuation_claim_preserves_state_owned_by_a_different_page_residence(
|
||||
.expect("initial Page residence should exist");
|
||||
assert!(
|
||||
ctx.conn
|
||||
.register_in_flight_subresource_fetch_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.register_in_flight_subresource_fetch_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
Some("INT-retired-in-flight".to_owned()),
|
||||
pending_request(&retired_owner, 76),
|
||||
)
|
||||
@@ -437,9 +439,8 @@ async fn continuation_claim_preserves_state_owned_by_a_different_page_residence(
|
||||
|
||||
assert!(
|
||||
ctx.conn
|
||||
.claim_subresource_continue_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.claim_subresource_continue_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
&replacement_owner,
|
||||
76,
|
||||
false,
|
||||
@@ -449,9 +450,8 @@ async fn continuation_claim_preserves_state_owned_by_a_different_page_residence(
|
||||
);
|
||||
assert!(
|
||||
ctx.conn
|
||||
.claim_subresource_continue_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.claim_subresource_continue_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
&replacement_owner,
|
||||
77,
|
||||
true,
|
||||
@@ -466,9 +466,8 @@ async fn continuation_claim_preserves_state_owned_by_a_different_page_residence(
|
||||
.install_page_attachment_id_for_test(retired_owner.page_attachment_id());
|
||||
let ClaimedSubresourceContinueRequest::InFlight(in_flight) = ctx
|
||||
.conn
|
||||
.claim_subresource_continue_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.claim_subresource_continue_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
&retired_owner,
|
||||
76,
|
||||
false,
|
||||
@@ -484,7 +483,12 @@ async fn continuation_claim_preserves_state_owned_by_a_different_page_residence(
|
||||
|
||||
let ClaimedSubresourceContinueRequest::PendingCompletion(pending) = ctx
|
||||
.conn
|
||||
.claim_subresource_continue_request_for_route(Some("SID-1"), None, &retired_owner, 77, true)
|
||||
.claim_subresource_continue_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
&retired_owner,
|
||||
77,
|
||||
true,
|
||||
)
|
||||
.expect("owner mismatch must leave the pending request resident")
|
||||
else {
|
||||
panic!("the preserved request should remain pending");
|
||||
@@ -514,9 +518,8 @@ async fn pending_fetch_auth_state_is_bound_to_page_attachment() {
|
||||
.replace_page_attachment_id_for_test();
|
||||
assert!(
|
||||
ctx.conn
|
||||
.take_pending_subresource_fetch_auth_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.take_pending_subresource_fetch_auth_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
Some("SID-1"),
|
||||
"AUTH-collision",
|
||||
)
|
||||
@@ -540,9 +543,8 @@ async fn pending_fetch_auth_state_is_bound_to_page_attachment() {
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.take_pending_subresource_fetch_auth_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.take_pending_subresource_fetch_auth_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
Some("SID-1"),
|
||||
"AUTH-collision",
|
||||
)
|
||||
@@ -574,9 +576,8 @@ async fn pending_fetch_response_state_is_bound_to_page_attachment() {
|
||||
.replace_page_attachment_id_for_test();
|
||||
assert!(
|
||||
ctx.conn
|
||||
.take_pending_subresource_fetch_response_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.take_pending_subresource_fetch_response_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
Some("SID-1"),
|
||||
"RESPONSE-collision",
|
||||
)
|
||||
@@ -600,9 +601,8 @@ async fn pending_fetch_response_state_is_bound_to_page_attachment() {
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.take_pending_subresource_fetch_response_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
.take_pending_subresource_fetch_response_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
Some("SID-1"),
|
||||
"RESPONSE-collision",
|
||||
)
|
||||
|
||||
@@ -927,7 +927,9 @@ async fn run_navigation_cdp_fetch_then_bidi_network_auth_required_terminal(
|
||||
let parsed_url = Url::parse(&url).unwrap();
|
||||
let auth_pause_sessions = ctx
|
||||
.conn
|
||||
.target_fetch_subresource_interception_snapshot_for_route(Some("SID-1"), None)
|
||||
.target_fetch_subresource_interception_snapshot_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
)
|
||||
.expect("active target fetch snapshot")
|
||||
.matching_auth_required_pause_sessions(Some("SID-1"), &parsed_url);
|
||||
assert_eq!(
|
||||
|
||||
@@ -1825,7 +1825,9 @@ async fn run_cdp_fetch_then_bidi_network_auth_required_terminal_credentials_comp
|
||||
let protected_parsed_url = Url::parse(&protected_url).unwrap();
|
||||
let auth_pause_sessions = ctx
|
||||
.conn
|
||||
.target_fetch_subresource_interception_snapshot_for_route(Some("SID-1"), None)
|
||||
.target_fetch_subresource_interception_snapshot_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
)
|
||||
.expect("active target fetch snapshot")
|
||||
.matching_auth_required_pause_sessions(Some("SID-1"), &protected_parsed_url);
|
||||
assert_eq!(
|
||||
|
||||
@@ -1139,7 +1139,9 @@ async fn response_body_stream_taken_blocks_chained_bidi_response_stage_pause() {
|
||||
let api_url = Url::parse(&hit_url).unwrap();
|
||||
let response_pause_sessions = ctx
|
||||
.conn
|
||||
.target_fetch_subresource_interception_snapshot_for_route(Some("SID-1"), None)
|
||||
.target_fetch_subresource_interception_snapshot_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
)
|
||||
.expect("active target fetch snapshot")
|
||||
.matching_response_stage_pause_sessions(
|
||||
Some("SID-1"),
|
||||
@@ -6992,7 +6994,9 @@ async fn cdp_fetch_then_bidi_network_intercept_response_stage_chain_completes()
|
||||
let api_url = Url::parse(&hit_url).unwrap();
|
||||
let response_pause_sessions = ctx
|
||||
.conn
|
||||
.target_fetch_subresource_interception_snapshot_for_route(Some("SID-1"), None)
|
||||
.target_fetch_subresource_interception_snapshot_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
)
|
||||
.expect("active target fetch snapshot")
|
||||
.matching_response_stage_pause_sessions(
|
||||
Some("SID-1"),
|
||||
|
||||
@@ -343,7 +343,7 @@ fn set_ignore_input_events_command_output_plan(
|
||||
}
|
||||
|
||||
fn input_events_ignored_for_owner(conn: &CdpConnection, owner: &CommandOwnerScope) -> bool {
|
||||
conn.page_event_session_ids_for_route(owner.session_id(), owner.session_owner_route())
|
||||
conn.page_event_session_ids_for_owner(owner)
|
||||
.into_iter()
|
||||
.any(|event_session_id| {
|
||||
conn.target_page_session_state_for_session(event_session_id.as_deref())
|
||||
@@ -572,8 +572,7 @@ fn start_pending_input_command(
|
||||
) -> Result<Option<PendingInputCommandDispatch>, PendingInputCommandStartError> {
|
||||
let owner = CommandOwnerScope::capture(conn, cmd.session_id);
|
||||
if action.requires_document_access()
|
||||
&& let Err(message) = conn
|
||||
.ensure_document_accessible_for_route(owner.session_id(), owner.session_owner_route())
|
||||
&& let Err(message) = conn.ensure_document_accessible_for_owner(&owner)
|
||||
{
|
||||
return Err(PendingInputCommandStartError {
|
||||
code: -32000,
|
||||
@@ -1005,27 +1004,18 @@ fn start_page_input_command(
|
||||
start: impl FnOnce(&Page) -> anyhow::Result<PendingPageCommand>,
|
||||
) -> Result<Option<PendingInputCommandDispatch>, PendingInputCommandStartError> {
|
||||
let page_owner = conn
|
||||
.target_page_residence_identity_for_route(
|
||||
command_owner.session_id(),
|
||||
command_owner.session_owner_route(),
|
||||
)
|
||||
.target_page_residence_identity_for_owner(command_owner)
|
||||
.ok_or_else(PendingInputCommandStartError::no_document_loaded)?;
|
||||
let page_residence_token = if kind.uses_renderer_host_ack_cleanup() {
|
||||
Some(
|
||||
conn.capture_target_page_residence_token_for_route(
|
||||
command_owner.session_id(),
|
||||
command_owner.session_owner_route(),
|
||||
)
|
||||
.ok_or_else(PendingInputCommandStartError::no_document_loaded)?,
|
||||
conn.capture_target_page_residence_token_for_owner(command_owner)
|
||||
.ok_or_else(PendingInputCommandStartError::no_document_loaded)?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let page = conn
|
||||
.loaded_page_mut_for_protocol_access_for_route(
|
||||
command_owner.session_id(),
|
||||
command_owner.session_owner_route(),
|
||||
)
|
||||
.loaded_page_mut_for_protocol_access_for_owner(command_owner)
|
||||
.ok()
|
||||
.ok_or_else(PendingInputCommandStartError::no_document_loaded)?;
|
||||
let pending = start(page).map_err(PendingInputCommandStartError::renderer_error)?;
|
||||
@@ -1519,10 +1509,7 @@ impl InputPreparedOutputs {
|
||||
owner: &CommandOwnerScope,
|
||||
activation: RendererPendingFileChooserActivation,
|
||||
) -> Self {
|
||||
let Some(page_owner) = conn.target_page_residence_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) else {
|
||||
let Some(page_owner) = conn.target_page_residence_identity_for_owner(owner) else {
|
||||
return Self::default();
|
||||
};
|
||||
let Some(activation) = file_chooser::PreparedFileChooserActivation::capture(
|
||||
@@ -1630,7 +1617,7 @@ async fn handle_input_dispatch_outcome_async(
|
||||
let mut events = Vec::new();
|
||||
conn.handle_pending_download_activation_background_events_async(
|
||||
&mut events,
|
||||
session_id,
|
||||
&action_owner,
|
||||
download,
|
||||
command_context,
|
||||
)
|
||||
@@ -1648,7 +1635,7 @@ async fn handle_input_dispatch_outcome_async(
|
||||
file_chooser::emit_prepared_activation_async(
|
||||
conn,
|
||||
out.events_mut(),
|
||||
session_id,
|
||||
&action_owner,
|
||||
file_chooser,
|
||||
)
|
||||
.await;
|
||||
@@ -1663,7 +1650,7 @@ async fn handle_input_dispatch_outcome_async(
|
||||
pub(in crate::domains) async fn emit_download_activity_background_events_async(
|
||||
conn: &mut CdpConnection,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
prepared_outputs: Option<&mut ProtocolOutputPayloads>,
|
||||
command_context: &mut CommandDispatchContext,
|
||||
) {
|
||||
@@ -1671,14 +1658,14 @@ pub(in crate::domains) async fn emit_download_activity_background_events_async(
|
||||
.and_then(ProtocolOutputPayloads::input_mut)
|
||||
.and_then(InputPreparedOutputSlot::take_download_activations)
|
||||
{
|
||||
emit_download_activations(conn, out, session_id, activations, command_context).await;
|
||||
emit_download_activations(conn, out, owner, activations, command_context).await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn emit_download_activations(
|
||||
conn: &mut CdpConnection,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
activations: Vec<RendererPendingDownloadActivation>,
|
||||
command_context: &mut CommandDispatchContext,
|
||||
) {
|
||||
@@ -1686,7 +1673,7 @@ async fn emit_download_activations(
|
||||
if let Err(error) = conn
|
||||
.handle_pending_download_activation_background_events_async(
|
||||
out,
|
||||
session_id,
|
||||
owner,
|
||||
activation,
|
||||
command_context,
|
||||
)
|
||||
@@ -1703,14 +1690,14 @@ async fn emit_download_activations(
|
||||
pub(in crate::domains) async fn emit_file_chooser_activity_background_events_async(
|
||||
conn: &mut CdpConnection,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
prepared_outputs: Option<&mut ProtocolOutputPayloads>,
|
||||
) {
|
||||
if let Some(activations) = prepared_outputs
|
||||
.and_then(ProtocolOutputPayloads::input_mut)
|
||||
.and_then(InputPreparedOutputSlot::take_file_chooser_activations)
|
||||
{
|
||||
file_chooser::emit_prepared_activations_async(conn, out, session_id, activations).await;
|
||||
file_chooser::emit_prepared_activations_async(conn, out, owner, activations).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2200,7 +2187,7 @@ mod producer_tests {
|
||||
super::file_chooser::emit_prepared_activation_async(
|
||||
&mut conn,
|
||||
&mut out,
|
||||
Some("SID-typed"),
|
||||
&CommandOwnerScope::for_session("SID-typed"),
|
||||
prepared,
|
||||
)
|
||||
.await;
|
||||
@@ -2297,7 +2284,7 @@ mod producer_tests {
|
||||
super::file_chooser::emit_prepared_activation_async(
|
||||
&mut conn,
|
||||
&mut out,
|
||||
Some("SID-document-collision"),
|
||||
&CommandOwnerScope::for_session("SID-document-collision"),
|
||||
prepared,
|
||||
)
|
||||
.await;
|
||||
@@ -2378,7 +2365,7 @@ mod producer_tests {
|
||||
super::file_chooser::emit_prepared_activations_async(
|
||||
&mut conn,
|
||||
&mut out,
|
||||
Some("SID-page-replacement"),
|
||||
&CommandOwnerScope::for_session("SID-page-replacement"),
|
||||
vec![stale, current],
|
||||
)
|
||||
.await;
|
||||
@@ -2421,7 +2408,7 @@ mod producer_tests {
|
||||
super::emit_download_activity_background_events_async(
|
||||
&mut conn,
|
||||
&mut out,
|
||||
Some("SID-download"),
|
||||
&CommandOwnerScope::for_session("SID-download"),
|
||||
Some(&mut prepared),
|
||||
&mut command_context,
|
||||
)
|
||||
@@ -2476,7 +2463,7 @@ mod producer_tests {
|
||||
super::emit_file_chooser_activity_background_events_async(
|
||||
&mut conn,
|
||||
&mut out,
|
||||
Some("SID-1"),
|
||||
&CommandOwnerScope::for_session("SID-1"),
|
||||
Some(&mut prepared),
|
||||
)
|
||||
.await;
|
||||
@@ -2524,7 +2511,7 @@ mod producer_tests {
|
||||
super::emit_file_chooser_activity_background_events_async(
|
||||
&mut conn,
|
||||
&mut out,
|
||||
Some("SID-context"),
|
||||
&CommandOwnerScope::for_session("SID-context"),
|
||||
Some(&mut prepared),
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -35,9 +35,7 @@ impl PreparedFileChooserActivation {
|
||||
page_owner: TargetPageResidenceIdentity,
|
||||
activation: RendererPendingFileChooserActivation,
|
||||
) -> Option<Self> {
|
||||
if !conn
|
||||
.target_page_residence_identity_is_current_for_session(owner.session_id(), &page_owner)
|
||||
{
|
||||
if !conn.target_page_residence_identity_is_current(&page_owner) {
|
||||
return None;
|
||||
}
|
||||
let source_document = activation.source_document();
|
||||
@@ -45,11 +43,8 @@ impl PreparedFileChooserActivation {
|
||||
.source_frame_id()
|
||||
.map(str::to_owned)
|
||||
.or_else(|| {
|
||||
conn.target_session_owner_frame_tree_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.map(|(frame_id, _, _, _)| frame_id)
|
||||
conn.target_session_owner_frame_tree_identity_for_owner(owner)
|
||||
.map(|(frame_id, _, _, _)| frame_id)
|
||||
})?;
|
||||
Some(Self {
|
||||
page_owner,
|
||||
@@ -94,26 +89,27 @@ impl PreparedFileChooserActivation {
|
||||
pub(super) async fn emit_prepared_activations_async(
|
||||
conn: &mut CdpConnection,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
activations: Vec<PreparedFileChooserActivation>,
|
||||
) {
|
||||
for activation in activations {
|
||||
emit_prepared_activation_async(conn, out, session_id, activation).await;
|
||||
emit_prepared_activation_async(conn, out, owner, activation).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) async fn emit_prepared_activation_async(
|
||||
conn: &mut CdpConnection,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
activation: PreparedFileChooserActivation,
|
||||
) {
|
||||
if !activation_is_current(conn, session_id, &activation) {
|
||||
let session_id = owner.session_id();
|
||||
if !activation_is_current(conn, &activation) {
|
||||
trace_stale_activation(session_id, &activation);
|
||||
return;
|
||||
}
|
||||
let event_enabled = conn
|
||||
.target_page_session_state_for_session(session_id)
|
||||
.target_page_session_state_for_owner(owner)
|
||||
.is_some_and(|state| {
|
||||
state.page_intercept_file_chooser_dialog_enabled
|
||||
|| state.page_file_chooser_opened_event_enabled
|
||||
@@ -126,9 +122,8 @@ pub(super) async fn emit_prepared_activation_async(
|
||||
} else {
|
||||
"selectSingle"
|
||||
};
|
||||
let element_shared_id =
|
||||
element_shared_id_async(conn, session_id, activation.backend_node_id).await;
|
||||
if !activation_is_current(conn, session_id, &activation) {
|
||||
let element_shared_id = element_shared_id_async(conn, owner, activation.backend_node_id).await;
|
||||
if !activation_is_current(conn, &activation) {
|
||||
trace_stale_activation(session_id, &activation);
|
||||
return;
|
||||
}
|
||||
@@ -141,12 +136,8 @@ pub(super) async fn emit_prepared_activation_async(
|
||||
));
|
||||
}
|
||||
|
||||
fn activation_is_current(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
activation: &PreparedFileChooserActivation,
|
||||
) -> bool {
|
||||
conn.target_page_residence_identity_is_current_for_session(session_id, &activation.page_owner)
|
||||
fn activation_is_current(conn: &CdpConnection, activation: &PreparedFileChooserActivation) -> bool {
|
||||
conn.target_page_residence_identity_is_current(&activation.page_owner)
|
||||
}
|
||||
|
||||
fn trace_stale_activation(session_id: Option<&str>, activation: &PreparedFileChooserActivation) {
|
||||
@@ -164,7 +155,7 @@ fn trace_stale_activation(session_id: Option<&str>, activation: &PreparedFileCho
|
||||
|
||||
async fn element_shared_id_async(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
backend_node_id: u32,
|
||||
) -> DevToolsRemoteHandleId {
|
||||
// The event identity belongs to the frozen activation, while the DOM-agent
|
||||
@@ -173,10 +164,7 @@ async fn element_shared_id_async(
|
||||
// before or during this async handoff; it must not erase the element from
|
||||
// the already-accepted file-chooser event.
|
||||
match conn
|
||||
.document_bidi_node_shared_id_for_backend_node_id_for_session_owner_async(
|
||||
session_id,
|
||||
backend_node_id,
|
||||
)
|
||||
.document_bidi_node_shared_id_for_backend_node_id_for_owner_async(owner, backend_node_id)
|
||||
.await
|
||||
{
|
||||
Ok(RendererDomBidiNodeSharedIdResolution::SharedId(shared_id)) => {
|
||||
@@ -194,8 +182,8 @@ async fn element_shared_id_async(
|
||||
|
||||
let shared_id = webdriver_bidi_node_shared_id_for_backend_node_id(backend_node_id);
|
||||
if let Err(error) = conn
|
||||
.register_document_bidi_node_binding_for_session_owner_async(
|
||||
session_id,
|
||||
.register_document_bidi_node_binding_for_owner_async(
|
||||
owner,
|
||||
shared_id.as_str(),
|
||||
backend_node_id,
|
||||
)
|
||||
|
||||
@@ -333,9 +333,10 @@ async fn pending_mouse_event_acknowledges_when_page_is_replaced_before_renderer_
|
||||
.conn
|
||||
.target_page_residence_identity_for_session(None)
|
||||
.expect("the original Page should have a residence identity");
|
||||
let command_owner = CommandOwnerScope::capture(&ctx.conn, None);
|
||||
let page_residence_token = ctx
|
||||
.conn
|
||||
.capture_target_page_residence_token_for_route(None, None)
|
||||
.capture_target_page_residence_token_for_owner(&command_owner)
|
||||
.expect("the original Page should expose its attachment lifetime");
|
||||
|
||||
let replacement_url = "data:text/html,<body>replacement-before-completion</body>";
|
||||
@@ -375,9 +376,10 @@ async fn completed_renderer_ack_wins_when_page_replacement_is_already_observable
|
||||
let mut ctx = TestContext::new();
|
||||
with_loaded_document(&mut ctx, "<body>origin</body>").await;
|
||||
|
||||
let command_owner = CommandOwnerScope::capture(&ctx.conn, None);
|
||||
let page_residence_token = ctx
|
||||
.conn
|
||||
.capture_target_page_residence_token_for_route(None, None)
|
||||
.capture_target_page_residence_token_for_owner(&command_owner)
|
||||
.expect("the original Page should expose its attachment lifetime");
|
||||
ctx.install_navigation_fixture_for_session_owner(
|
||||
"data:text/html,<body>replacement-after-ack</body>",
|
||||
|
||||
@@ -738,11 +738,8 @@ fn complete_network_policy_refresh(
|
||||
}
|
||||
};
|
||||
if let Err(error) = finish_network_page_operation_on_current_attachment(
|
||||
conn.loaded_page_mut_for_target_configuration_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.ok(),
|
||||
conn.loaded_page_mut_for_target_configuration_for_owner(&owner_scope)
|
||||
.ok(),
|
||||
NetworkPageCommandFinish::RequestPolicy,
|
||||
completion,
|
||||
) {
|
||||
@@ -780,11 +777,8 @@ fn complete_unit_page_network_command(
|
||||
}
|
||||
};
|
||||
match finish_network_page_operation_on_current_attachment(
|
||||
conn.loaded_page_mut_for_target_configuration_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.ok(),
|
||||
conn.loaded_page_mut_for_target_configuration_for_owner(&owner_scope)
|
||||
.ok(),
|
||||
finish,
|
||||
completion,
|
||||
) {
|
||||
@@ -854,11 +848,7 @@ fn complete_rebuild_loader_network_command(
|
||||
return CommandOutputPlan::error(-32000, "InvalidNetworkCommandCompletion");
|
||||
}
|
||||
};
|
||||
match conn.finish_rebuild_resource_runtime_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
completion,
|
||||
) {
|
||||
match conn.finish_rebuild_resource_runtime_for_owner(&owner_scope, completion) {
|
||||
Ok(()) => CommandOutputPlan::success(),
|
||||
Err(error) => CommandOutputPlan::error(-32000, error),
|
||||
}
|
||||
@@ -872,17 +862,9 @@ fn network_page_configuration_will_be_replayed(
|
||||
let Some(dispatched_attachment) = dispatched_attachment else {
|
||||
return false;
|
||||
};
|
||||
let owner_still_exists = conn
|
||||
.target_owner_identity_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.is_some();
|
||||
let owner_still_exists = conn.target_owner_identity_for_owner(owner_scope).is_some();
|
||||
let current_attachment = conn
|
||||
.loaded_page_mut_for_target_configuration_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.loaded_page_mut_for_target_configuration_for_owner(owner_scope)
|
||||
.ok()
|
||||
.and_then(|page| page.renderer_agent_attachment_id());
|
||||
owner_still_exists && current_attachment != Some(dispatched_attachment)
|
||||
|
||||
@@ -407,10 +407,7 @@ impl NetworkOutputProjectionStep {
|
||||
.and_then(NetworkPreparedOutputSlot::take_subresource_fetch_pauses)
|
||||
{
|
||||
let mut events = Vec::new();
|
||||
let network_session_ids = conn.network_event_session_ids_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let network_session_ids = conn.network_event_session_ids_for_owner(&owner);
|
||||
fetch::emit_subresource_fetch_pause_outputs(
|
||||
conn,
|
||||
&mut events,
|
||||
@@ -472,13 +469,9 @@ pub(in crate::domains) fn network_backlog_prepared_outputs_for_owner(
|
||||
) -> NetworkPreparedOutputs {
|
||||
let mut outputs = NetworkPreparedOutputs::default();
|
||||
let session_id = owner.session_id();
|
||||
let primary_session_id = conn.runtime_session_owner_primary_session_id_for_route(
|
||||
session_id,
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
if let Some(backlog) = conn.network_backlog_prepared_delivery_for_route(
|
||||
session_id,
|
||||
owner.session_owner_route(),
|
||||
let primary_session_id = conn.runtime_session_owner_primary_session_id_for_owner(owner);
|
||||
if let Some(backlog) = conn.network_backlog_prepared_delivery_for_owner(
|
||||
owner,
|
||||
session_id,
|
||||
primary_session_id.as_deref(),
|
||||
preferred_request_id,
|
||||
@@ -613,9 +606,8 @@ mod tests {
|
||||
request_stage_chain: None,
|
||||
};
|
||||
assert!(
|
||||
conn.register_in_flight_subresource_fetch_request_for_route(
|
||||
Some("SID-1"),
|
||||
None,
|
||||
conn.register_in_flight_subresource_fetch_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
Some("fetch-req-1".to_owned()),
|
||||
pending,
|
||||
),
|
||||
@@ -694,9 +686,8 @@ mod tests {
|
||||
.target_page_residence_identity_for_session(Some("SID-collision"))
|
||||
.expect("old Page residence should exist");
|
||||
let reused_handle = SubresourceNetworkRequestHandle::new(9);
|
||||
assert!(conn.register_in_flight_subresource_fetch_request_for_route(
|
||||
Some("SID-collision"),
|
||||
None,
|
||||
assert!(conn.register_in_flight_subresource_fetch_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-collision"),
|
||||
Some("FETCH-old".to_owned()),
|
||||
pending_request_for_page(old_owner, 7, "NETWORK-old", reused_handle),
|
||||
));
|
||||
@@ -730,9 +721,8 @@ mod tests {
|
||||
let replacement_owner = conn
|
||||
.target_page_residence_identity_for_session(Some("SID-collision"))
|
||||
.expect("replacement Page residence should exist");
|
||||
assert!(conn.register_in_flight_subresource_fetch_request_for_route(
|
||||
Some("SID-collision"),
|
||||
None,
|
||||
assert!(conn.register_in_flight_subresource_fetch_request_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-collision"),
|
||||
Some("FETCH-new".to_owned()),
|
||||
pending_request_for_page(replacement_owner, 7, "NETWORK-new", reused_handle),
|
||||
));
|
||||
@@ -752,8 +742,11 @@ mod tests {
|
||||
"stale continuation must not project an event for the replacement request"
|
||||
);
|
||||
assert_eq!(
|
||||
conn.in_flight_subresource_fetch_request_id_for_route(Some("SID-collision"), None, 7,)
|
||||
.as_deref(),
|
||||
conn.in_flight_subresource_fetch_request_id_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-collision"),
|
||||
7,
|
||||
)
|
||||
.as_deref(),
|
||||
Some("FETCH-new"),
|
||||
"stale apply must not claim the replacement request even when both renderer IDs collide"
|
||||
);
|
||||
|
||||
@@ -219,9 +219,7 @@ fn emit_complete_subresource_network_delivery_record(
|
||||
let record_document_url = output.document_url();
|
||||
let timestamp = base_timestamp + ((output.index() + 1) as f64 * 0.000_001);
|
||||
let resource_type = output.resource_type().into();
|
||||
let Ok(runtime_slot) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
else {
|
||||
let Ok(runtime_slot) = conn.runtime_session_owner_slot_mut_for_owner(owner) else {
|
||||
return false;
|
||||
};
|
||||
let request_was_announced_by_fetch_pause =
|
||||
@@ -423,7 +421,7 @@ fn emit_staged_subresource_request_started(
|
||||
let timestamp = base_timestamp + ((output.index() + 1) as f64 * 0.000_001);
|
||||
let resource_type = output.resource_type().into();
|
||||
let request_was_announced_by_fetch_pause = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.is_ok_and(|runtime_slot| runtime_slot.take_fetch_pause_announced_request_id(request_id));
|
||||
if output.resource_type() != moli_core::page::SubresourceResourceType::WebSocket {
|
||||
record_subresource_pending_response_body(conn, owner, request_id, event_session_ids);
|
||||
@@ -551,11 +549,7 @@ fn emit_staged_subresource_response_started(
|
||||
);
|
||||
let fetch_request_id = (!blocked_intercepts.is_empty())
|
||||
.then(|| {
|
||||
conn.in_flight_subresource_fetch_request_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
output.handle().get(),
|
||||
)
|
||||
conn.in_flight_subresource_fetch_request_id_for_owner(owner, output.handle().get())
|
||||
})
|
||||
.flatten();
|
||||
emit_response_received(
|
||||
@@ -589,12 +583,9 @@ fn matching_subresource_network_intercepts(
|
||||
resource_type: DevToolsNetworkResourceType,
|
||||
url: &url::Url,
|
||||
) -> Vec<DevToolsNetworkInterceptId> {
|
||||
conn.target_fetch_subresource_interception_snapshot_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.map(|snapshot| snapshot.matching_network_intercepts(request_stage, resource_type, url))
|
||||
.unwrap_or_default()
|
||||
conn.target_fetch_subresource_interception_snapshot_for_owner(owner)
|
||||
.map(|snapshot| snapshot.matching_network_intercepts(request_stage, resource_type, url))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn emit_staged_subresource_body_finished(
|
||||
@@ -714,15 +705,11 @@ pub(crate) fn emit_pending_network_backlog_activity_background_events(
|
||||
preferred_request_id,
|
||||
prepared_outputs,
|
||||
} = context;
|
||||
let primary_session_id = conn.runtime_session_owner_primary_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let primary_session_id = conn.runtime_session_owner_primary_session_id_for_owner(&owner);
|
||||
let Some((frame_id, snapshot)) = (|| {
|
||||
let frame_id = frame_id.map(str::to_owned).or_else(|| {
|
||||
conn.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())?
|
||||
.1
|
||||
})?;
|
||||
let frame_id = frame_id
|
||||
.map(str::to_owned)
|
||||
.or_else(|| conn.target_owner_identity_for_owner(&owner)?.1)?;
|
||||
let snapshot = pending_network_backlog_delivery_snapshot(
|
||||
conn,
|
||||
&owner,
|
||||
@@ -757,13 +744,10 @@ pub(crate) fn emit_prepared_renderer_network_live_background_events(
|
||||
owner: &CommandOwnerScope,
|
||||
prepared: &mut TargetNetworkBacklogPreparedDelivery,
|
||||
) {
|
||||
let session_id = owner.session_id();
|
||||
let Some((frame_id, snapshot)) = (|| {
|
||||
let frame_id = conn
|
||||
.target_owner_identity_for_route(session_id, owner.session_owner_route())?
|
||||
.1?;
|
||||
let frame_id = conn.target_owner_identity_for_owner(owner)?.1?;
|
||||
let snapshot = conn
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner.session_owner_route())
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()?
|
||||
.pending_network_backlog_delivery_snapshot_from_backlog(prepared)?;
|
||||
Some((frame_id, snapshot))
|
||||
@@ -822,19 +806,13 @@ fn pending_network_backlog_delivery_snapshot(
|
||||
prepared_network_outputs: Option<&mut NetworkPreparedOutputs>,
|
||||
) -> Option<PendingNetworkBacklogDeliverySnapshot> {
|
||||
if let Some(prepared_network_outputs) = prepared_network_outputs {
|
||||
let runtime_slot = conn
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.ok()?;
|
||||
let runtime_slot = conn.runtime_session_owner_slot_mut_for_owner(owner).ok()?;
|
||||
return runtime_slot.pending_network_backlog_delivery_snapshot_from_backlog(
|
||||
prepared_network_outputs.backlog_mut(),
|
||||
);
|
||||
}
|
||||
conn.pending_network_backlog_delivery_snapshot_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
conn.pending_network_backlog_delivery_snapshot_for_owner(
|
||||
owner,
|
||||
owner.session_id(),
|
||||
primary_session_id,
|
||||
preferred_request_id,
|
||||
@@ -846,9 +824,7 @@ fn mark_network_backlog_delivery_snapshot_emitted(
|
||||
owner: &CommandOwnerScope,
|
||||
snapshot: &PendingNetworkBacklogDeliverySnapshot,
|
||||
) {
|
||||
let Ok(runtime_slot) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
else {
|
||||
let Ok(runtime_slot) = conn.runtime_session_owner_slot_mut_for_owner(owner) else {
|
||||
return;
|
||||
};
|
||||
runtime_slot.mark_network_backlog_delivery_snapshot_emitted(snapshot);
|
||||
@@ -863,12 +839,8 @@ fn record_subresource_response_body_source(
|
||||
) {
|
||||
let captured_body = crate::conn::CapturedBody::from_subresource_response_body(response_body);
|
||||
let data_type = crate::devtools_runtime::DevToolsNetworkDataType::Response;
|
||||
let collector_ids = conn.network_data_collector_ids_for_route_body(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
data_type,
|
||||
captured_body.len(),
|
||||
);
|
||||
let collector_ids =
|
||||
conn.network_data_collector_ids_for_owner_body(owner, data_type, captured_body.len());
|
||||
let collection_was_gated = conn.network_data_collection_is_gated_for_body(data_type);
|
||||
conn.record_collected_network_data_body(
|
||||
request_id.to_owned(),
|
||||
@@ -877,9 +849,7 @@ fn record_subresource_response_body_source(
|
||||
collector_ids.iter().cloned(),
|
||||
collection_was_gated,
|
||||
);
|
||||
let Ok(runtime_slot) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
else {
|
||||
let Ok(runtime_slot) = conn.runtime_session_owner_slot_mut_for_owner(owner) else {
|
||||
return;
|
||||
};
|
||||
runtime_slot.record_captured_response_body_source_with_collector_scope(
|
||||
@@ -902,12 +872,8 @@ fn record_subresource_request_body(
|
||||
return;
|
||||
};
|
||||
let data_type = crate::devtools_runtime::DevToolsNetworkDataType::Request;
|
||||
let collector_ids = conn.network_data_collector_ids_for_route_body(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
data_type,
|
||||
request_body.len(),
|
||||
);
|
||||
let collector_ids =
|
||||
conn.network_data_collector_ids_for_owner_body(owner, data_type, request_body.len());
|
||||
let collection_was_gated = conn.network_data_collection_is_gated_for_body(data_type);
|
||||
conn.record_collected_network_data_body(
|
||||
request_id.to_owned(),
|
||||
@@ -916,9 +882,7 @@ fn record_subresource_request_body(
|
||||
collector_ids.iter().cloned(),
|
||||
collection_was_gated,
|
||||
);
|
||||
let Ok(runtime_slot) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
else {
|
||||
let Ok(runtime_slot) = conn.runtime_session_owner_slot_mut_for_owner(owner) else {
|
||||
return;
|
||||
};
|
||||
runtime_slot.record_captured_request_body_with_collector_scope(
|
||||
@@ -936,18 +900,15 @@ fn record_subresource_pending_response_body(
|
||||
request_id: &str,
|
||||
session_ids: &[Option<String>],
|
||||
) {
|
||||
let collector_ids = conn.network_data_collector_ids_for_route_body(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
let collector_ids = conn.network_data_collector_ids_for_owner_body(
|
||||
owner,
|
||||
crate::devtools_runtime::DevToolsNetworkDataType::Response,
|
||||
0,
|
||||
);
|
||||
let collection_was_gated = conn.network_data_collection_is_gated_for_body(
|
||||
crate::devtools_runtime::DevToolsNetworkDataType::Response,
|
||||
);
|
||||
let Ok(runtime_slot) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
else {
|
||||
let Ok(runtime_slot) = conn.runtime_session_owner_slot_mut_for_owner(owner) else {
|
||||
return;
|
||||
};
|
||||
runtime_slot.record_pending_response_body_with_collector_scope(
|
||||
@@ -965,18 +926,15 @@ fn record_subresource_failed_response_body(
|
||||
request_id: &str,
|
||||
session_ids: &[Option<String>],
|
||||
) {
|
||||
let collector_ids = conn.network_data_collector_ids_for_route_body(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
let collector_ids = conn.network_data_collector_ids_for_owner_body(
|
||||
owner,
|
||||
crate::devtools_runtime::DevToolsNetworkDataType::Response,
|
||||
0,
|
||||
);
|
||||
let collection_was_gated = conn.network_data_collection_is_gated_for_body(
|
||||
crate::devtools_runtime::DevToolsNetworkDataType::Response,
|
||||
);
|
||||
let Ok(runtime_slot) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
else {
|
||||
let Ok(runtime_slot) = conn.runtime_session_owner_slot_mut_for_owner(owner) else {
|
||||
return;
|
||||
};
|
||||
runtime_slot.record_failed_response_body_with_collector_scope(
|
||||
|
||||
@@ -103,10 +103,7 @@ pub(super) fn complete_network_resource_preparation(
|
||||
}
|
||||
};
|
||||
let preparation = match conn
|
||||
.loaded_page_mut_for_protocol_access_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.loaded_page_mut_for_protocol_access_for_owner(&owner_scope)
|
||||
.and_then(|page| {
|
||||
if page.renderer_agent_attachment_id() != completion.renderer_agent_attachment_id() {
|
||||
return Err("Document changed while preparing the network resource load".to_owned());
|
||||
@@ -177,9 +174,8 @@ pub(super) fn complete_network_resource_fetch(
|
||||
Some(headers),
|
||||
);
|
||||
}
|
||||
let stream = match conn.open_io_stream_body_source_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
let stream = match conn.open_io_stream_body_source_for_owner(
|
||||
&owner_scope,
|
||||
CapturedBody::from_bytes_spooled(response.body),
|
||||
) {
|
||||
Ok(stream) => stream,
|
||||
|
||||
@@ -51,7 +51,10 @@ async fn network_configuration_commands_succeed_while_the_target_is_changing_doc
|
||||
let mut ctx = TestContext::new();
|
||||
install_network_session_page(&mut ctx, "data:text/html,committed").await;
|
||||
ctx.conn
|
||||
.start_document_navigation_for_route(Some("SID-navigation"), None, "LID-pending".to_owned())
|
||||
.start_document_navigation_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-navigation"),
|
||||
"LID-pending".to_owned(),
|
||||
)
|
||||
.expect("the replacement navigation should start");
|
||||
|
||||
ctx.process_async(json!({
|
||||
|
||||
@@ -130,14 +130,12 @@ pub(in crate::domains) fn inspector_issue_prepared_outputs(
|
||||
owner: &CommandOwnerScope,
|
||||
) -> ObservablePreparedOutputs {
|
||||
let mut prepared = ObservablePreparedOutputs::default();
|
||||
let session_id = owner.session_id();
|
||||
let owner_route = owner.session_owner_route();
|
||||
// Inspector issues are Document facts. Resolve them only against the
|
||||
// exact committed Document captured by the renderer; otherwise a late
|
||||
// issue from a retired generation could be stored and replayed as if it
|
||||
// belonged to its replacement.
|
||||
let Some(document_binding) = conn
|
||||
.runtime_session_owner_slot_for_route(session_id, owner_route)
|
||||
.runtime_session_owner_slot_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.committed_renderer_document_binding())
|
||||
else {
|
||||
@@ -149,14 +147,12 @@ pub(in crate::domains) fn inspector_issue_prepared_outputs(
|
||||
let page_attachment_id = document_binding.page_attachment_id;
|
||||
let frame_id = document_binding.frame_id.clone();
|
||||
let loader_id = document_binding.loader_id.clone();
|
||||
let Some(storage) =
|
||||
conn.with_target_owner_state_for_route_mut(session_id, owner_route, |owner_state| {
|
||||
owner_state
|
||||
.audits_storage_state
|
||||
.append_concrete_issue(issue);
|
||||
owner_state.audits_storage_state.clone()
|
||||
})
|
||||
else {
|
||||
let Some(storage) = conn.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
owner_state
|
||||
.audits_storage_state
|
||||
.append_concrete_issue(issue);
|
||||
owner_state.audits_storage_state.clone()
|
||||
}) else {
|
||||
return prepared;
|
||||
};
|
||||
|
||||
@@ -164,11 +160,13 @@ pub(in crate::domains) fn inspector_issue_prepared_outputs(
|
||||
// then fans out to every enabled frontend session. Each session keeps its
|
||||
// own cursor, matching Blink's per-session Audits agent state without
|
||||
// rediscovering the issue from a later Page snapshot.
|
||||
for event_session_id in conn.page_event_session_ids_for_route(session_id, owner_route) {
|
||||
for event_session_id in conn.page_event_session_ids_for_owner(owner) {
|
||||
let event_session_id = event_session_id.as_deref();
|
||||
let event_owner_route = event_session_id.is_none().then_some(owner_route).flatten();
|
||||
let event_owner = event_session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
let Some(cursor) = conn
|
||||
.target_page_session_state_for_route(event_session_id, event_owner_route)
|
||||
.target_page_session_state_for_owner(&event_owner)
|
||||
.and_then(|state| state.audits.pending_cursor(&storage))
|
||||
else {
|
||||
continue;
|
||||
@@ -232,50 +230,44 @@ fn push_runtime_observable_tail_prepared_outputs(
|
||||
deliver_log_to_enabled_sessions: bool,
|
||||
runtime_audience: RuntimeObservableAudience,
|
||||
) {
|
||||
let session_id = owner.session_id();
|
||||
let owner_route = owner.session_owner_route();
|
||||
let owner_state = conn
|
||||
.target_owner_state_for_route(session_id, owner_route)
|
||||
.target_owner_state_for_owner(owner)
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
let include_console_api_messages =
|
||||
!renderer_agent_owns_page_console_api_events(conn, session_id, owner_route);
|
||||
let include_console_api_messages = !renderer_agent_owns_page_console_api_events(conn, owner);
|
||||
|
||||
push_console_log_source_prepared_outputs(
|
||||
prepared,
|
||||
conn,
|
||||
source,
|
||||
session_id,
|
||||
owner,
|
||||
&owner_state,
|
||||
include_console_api_messages,
|
||||
deliver_log_to_enabled_sessions,
|
||||
owner_route,
|
||||
);
|
||||
|
||||
let attachments = match runtime_audience {
|
||||
RuntimeObservableAudience::SourceSession => conn
|
||||
.target_page_protocol_attachment_identity_for_route(session_id, owner_route)
|
||||
.target_page_protocol_attachment_identity_for_owner(owner)
|
||||
.into_iter()
|
||||
.collect(),
|
||||
RuntimeObservableAudience::EnabledTargetAttachments => conn
|
||||
.runtime_event_protocol_attachments_for_route(session_id, owner_route)
|
||||
.runtime_event_protocol_attachments_for_owner(owner)
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
for attachment in attachments {
|
||||
let event_session_id = attachment.session_id();
|
||||
let event_owner_route = event_session_id.is_none().then_some(owner_route).flatten();
|
||||
let event_owner = event_session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
if !conn
|
||||
.target_runtime_session_state_for_route(event_session_id, event_owner_route)
|
||||
.target_runtime_session_state_for_owner(&event_owner)
|
||||
.is_some_and(|state| state.runtime_frontend_enabled)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let include_runtime_console_api_messages =
|
||||
!renderer_runtime_agent_owns_page_console_api_events(
|
||||
conn,
|
||||
event_session_id,
|
||||
event_owner_route,
|
||||
);
|
||||
!renderer_runtime_agent_owns_page_console_api_events(conn, &event_owner);
|
||||
if let Some(items) = source.source_items_prepared_for_state(
|
||||
&owner_state.runtime_observable_state,
|
||||
include_runtime_console_api_messages,
|
||||
@@ -289,16 +281,13 @@ fn push_console_log_source_prepared_outputs(
|
||||
prepared: &mut ObservablePreparedOutputs,
|
||||
conn: &CdpConnection,
|
||||
source: &super::TargetRuntimeObservableSourceOutput,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
owner_state: &crate::conn::TargetOwnerState,
|
||||
include_console_api_messages: bool,
|
||||
deliver_log_to_enabled_sessions: bool,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
) {
|
||||
let queue = TargetObservableOutputQueue::from_runtime_source_output_ref(Some(source));
|
||||
if let Some(devtools_session_state) =
|
||||
conn.target_devtools_session_state_for_route(session_id, owner_route)
|
||||
{
|
||||
if let Some(devtools_session_state) = conn.target_devtools_session_state_for_owner(owner) {
|
||||
prepared.extend(
|
||||
queue.console_log_backlog_ranges(
|
||||
source.url(),
|
||||
@@ -310,7 +299,7 @@ fn push_console_log_source_prepared_outputs(
|
||||
include_console_api_messages,
|
||||
owner_state,
|
||||
&devtools_session_state.console_output_session_state,
|
||||
session_id,
|
||||
owner.session_id(),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -329,30 +318,27 @@ fn push_console_log_source_prepared_outputs(
|
||||
source.url(),
|
||||
source.page_attachment_id(),
|
||||
owner_state,
|
||||
session_id,
|
||||
owner_route,
|
||||
owner,
|
||||
);
|
||||
}
|
||||
|
||||
fn renderer_agent_owns_page_console_api_events(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
if session_id.is_some_and(|session_id| {
|
||||
if owner.session_id().is_some_and(|session_id| {
|
||||
conn.shared_worker_target_for_session(Some(session_id))
|
||||
.is_some()
|
||||
}) {
|
||||
return false;
|
||||
}
|
||||
let Ok(runtime_slot) = conn.runtime_session_owner_slot_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Ok(runtime_slot) = conn.runtime_session_owner_slot_for_owner(owner) else {
|
||||
return false;
|
||||
};
|
||||
if !runtime_slot.has_loaded_page() {
|
||||
return false;
|
||||
}
|
||||
conn.target_devtools_session_state_for_route(session_id, owner_route)
|
||||
conn.target_devtools_session_state_for_owner(owner)
|
||||
.is_some_and(|state| {
|
||||
state
|
||||
.console_output_session_state
|
||||
@@ -362,23 +348,21 @@ fn renderer_agent_owns_page_console_api_events(
|
||||
|
||||
fn renderer_runtime_agent_owns_page_console_api_events(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
if session_id.is_some_and(|session_id| {
|
||||
if owner.session_id().is_some_and(|session_id| {
|
||||
conn.shared_worker_target_for_session(Some(session_id))
|
||||
.is_some()
|
||||
}) {
|
||||
return false;
|
||||
}
|
||||
let Ok(runtime_slot) = conn.runtime_session_owner_slot_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Ok(runtime_slot) = conn.runtime_session_owner_slot_for_owner(owner) else {
|
||||
return false;
|
||||
};
|
||||
if !runtime_slot.has_loaded_page() {
|
||||
return false;
|
||||
}
|
||||
conn.target_devtools_session_state_for_route(session_id, owner_route)
|
||||
conn.target_devtools_session_state_for_owner(owner)
|
||||
.is_some_and(|state| {
|
||||
state
|
||||
.console_output_session_state
|
||||
@@ -402,13 +386,8 @@ fn runtime_console_source_tail_for_owner(
|
||||
message: RuntimeConsoleMessageSnapshot,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<super::TargetRuntimeObservableSourceOutput> {
|
||||
let url = conn.runtime_session_owner_target_url_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?;
|
||||
let runtime_slot = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.ok()?;
|
||||
let url = conn.runtime_session_owner_target_url_for_owner(owner)?;
|
||||
let runtime_slot = conn.runtime_session_owner_slot_mut_for_owner(owner).ok()?;
|
||||
runtime_slot.append_renderer_runtime_console_message(url, message)
|
||||
}
|
||||
|
||||
@@ -418,13 +397,8 @@ fn runtime_lifecycle_error_source_tail_for_owner(
|
||||
execution_context_id: Option<i64>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<super::TargetRuntimeObservableSourceOutput> {
|
||||
let url = conn.runtime_session_owner_target_url_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?;
|
||||
let runtime_slot = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.ok()?;
|
||||
let url = conn.runtime_session_owner_target_url_for_owner(owner)?;
|
||||
let runtime_slot = conn.runtime_session_owner_slot_mut_for_owner(owner).ok()?;
|
||||
runtime_slot.append_renderer_runtime_lifecycle_error(url, text, execution_context_id)
|
||||
}
|
||||
|
||||
@@ -454,19 +428,14 @@ pub(in crate::domains) fn live_log_prepared_outputs_for_renderer_network_fact(
|
||||
conn: &CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> ObservablePreparedOutputs {
|
||||
let session_id = owner.session_id();
|
||||
let owner_route = owner.session_owner_route();
|
||||
let owner_state = conn
|
||||
.target_owner_state_for_route(session_id, owner_route)
|
||||
.target_owner_state_for_owner(owner)
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
let Some(runtime_slot) = conn
|
||||
.runtime_session_owner_slot_for_route(session_id, owner_route)
|
||||
.ok()
|
||||
else {
|
||||
let Some(runtime_slot) = conn.runtime_session_owner_slot_for_owner(owner).ok() else {
|
||||
return ObservablePreparedOutputs::default();
|
||||
};
|
||||
let Some(url) = conn.runtime_session_owner_target_url_for_route(session_id, owner_route) else {
|
||||
let Some(url) = conn.runtime_session_owner_target_url_for_owner(owner) else {
|
||||
return ObservablePreparedOutputs::default();
|
||||
};
|
||||
let Some(queue) = TargetObservableOutputQueue::from_log_storage(runtime_slot) else {
|
||||
@@ -483,8 +452,7 @@ pub(in crate::domains) fn live_log_prepared_outputs_for_renderer_network_fact(
|
||||
&url,
|
||||
page_attachment_id,
|
||||
&owner_state,
|
||||
session_id,
|
||||
owner_route,
|
||||
owner,
|
||||
);
|
||||
prepared
|
||||
}
|
||||
@@ -504,8 +472,10 @@ fn observable_console_log_prepared_outputs_for_session_owner(
|
||||
let url = conn.runtime_session_owner_target_url(session_id)?;
|
||||
let queue = super::output_queue::TargetObservableOutputQueue::from_runtime_slot(runtime_slot)?;
|
||||
let page_attachment_id = runtime_slot.page_attachment_id()?;
|
||||
let include_console_api_messages =
|
||||
!renderer_agent_owns_page_console_api_events(conn, session_id, None);
|
||||
let include_console_api_messages = !renderer_agent_owns_page_console_api_events(
|
||||
conn,
|
||||
&CommandOwnerScope::capture(conn, session_id),
|
||||
);
|
||||
let mut prepared = ObservablePreparedOutputs::default();
|
||||
|
||||
if console_allowed
|
||||
@@ -529,6 +499,7 @@ fn observable_console_log_prepared_outputs_for_session_owner(
|
||||
}
|
||||
|
||||
if log_allowed {
|
||||
let owner = CommandOwnerScope::capture(conn, session_id);
|
||||
push_log_prepared_outputs_for_enabled_sessions(
|
||||
&mut prepared,
|
||||
conn,
|
||||
@@ -536,8 +507,7 @@ fn observable_console_log_prepared_outputs_for_session_owner(
|
||||
&url,
|
||||
page_attachment_id,
|
||||
&owner_state,
|
||||
session_id,
|
||||
None,
|
||||
&owner,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -551,18 +521,19 @@ fn push_log_prepared_outputs_for_enabled_sessions(
|
||||
url: &str,
|
||||
page_attachment_id: crate::conn::TargetPageAttachmentId,
|
||||
owner_state: &crate::conn::TargetOwnerState,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) {
|
||||
// A concrete Page error is stored once but observed by every Log agent
|
||||
// attached to that target. The publication route names one canonical
|
||||
// session only; it must not accidentally turn a target-owned fact into a
|
||||
// single-session event.
|
||||
for event_session_id in conn.page_event_session_ids_for_route(session_id, owner_route) {
|
||||
for event_session_id in conn.page_event_session_ids_for_owner(owner) {
|
||||
let event_session_id = event_session_id.as_deref();
|
||||
let event_owner_route = event_session_id.is_none().then_some(owner_route).flatten();
|
||||
let event_owner = event_session_id
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
let Some(devtools_session_state) =
|
||||
conn.target_devtools_session_state_for_route(event_session_id, event_owner_route)
|
||||
conn.target_devtools_session_state_for_owner(&event_owner)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
@@ -23,17 +23,13 @@ pub(in crate::domains) fn advance_runtime_observable_cursors_to_current_for_owne
|
||||
if let Some((context_console_counts, exception_entries)) =
|
||||
runtime_observable_cursor_end_from_owner_queue_for_owner(conn, owner)
|
||||
{
|
||||
let _ = conn.with_target_owner_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner_state| {
|
||||
owner_state.runtime_observable_state.advance_to_current(
|
||||
context_console_counts,
|
||||
0,
|
||||
exception_entries,
|
||||
);
|
||||
},
|
||||
);
|
||||
let _ = conn.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
owner_state.runtime_observable_state.advance_to_current(
|
||||
context_console_counts,
|
||||
0,
|
||||
exception_entries,
|
||||
);
|
||||
});
|
||||
return;
|
||||
}
|
||||
let Some((owner_queue_console_entries, exception_entries)) =
|
||||
@@ -41,31 +37,22 @@ pub(in crate::domains) fn advance_runtime_observable_cursors_to_current_for_owne
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let _ = conn.with_target_owner_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner_state| {
|
||||
owner_state.runtime_observable_state.advance_to_current(
|
||||
HashMap::new(),
|
||||
owner_queue_console_entries,
|
||||
exception_entries,
|
||||
);
|
||||
},
|
||||
);
|
||||
let _ = conn.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
owner_state.runtime_observable_state.advance_to_current(
|
||||
HashMap::new(),
|
||||
owner_queue_console_entries,
|
||||
exception_entries,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn runtime_observable_cursor_end_from_owner_queue_for_owner(
|
||||
conn: &CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<(HashMap<i64, usize>, usize)> {
|
||||
let runtime_slot = conn
|
||||
.runtime_session_owner_slot_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.ok()?;
|
||||
let runtime_slot = conn.runtime_session_owner_slot_for_owner(owner).ok()?;
|
||||
let source = runtime_slot.observable_output_latest_source_tail()?;
|
||||
let url = conn.runtime_session_owner_target_url_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?;
|
||||
let url = conn.runtime_session_owner_target_url_for_owner(owner)?;
|
||||
(source.url() == url && runtime_slot.page_attachment_id() == Some(source.page_attachment_id()))
|
||||
.then_some(source)?
|
||||
.cursor_end()
|
||||
@@ -75,7 +62,7 @@ fn runtime_observable_cursor_end_from_owner_observable_queue_for_owner(
|
||||
conn: &CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<(usize, usize)> {
|
||||
conn.runtime_session_owner_slot_for_route(owner.session_id(), owner.session_owner_route())
|
||||
conn.runtime_session_owner_slot_for_owner(owner)
|
||||
.ok()?
|
||||
.observable_output_cursor_end()
|
||||
}
|
||||
|
||||
+227
-383
File diff suppressed because it is too large
Load Diff
@@ -128,8 +128,6 @@ pub(super) fn complete_get_app_manifest_command(
|
||||
completed: CompletedGetAppManifestCommand,
|
||||
command_context: &mut CommandDispatchContext,
|
||||
) -> PageCommandTaskStep {
|
||||
let session_id = owner.session_id();
|
||||
let owner_route = owner.session_owner_route();
|
||||
match completed.work {
|
||||
CompletedGetAppManifestWork::Prepare(completion) => {
|
||||
let completion = match completion {
|
||||
@@ -142,7 +140,7 @@ pub(super) fn complete_get_app_manifest_command(
|
||||
}
|
||||
};
|
||||
let preparation = match conn
|
||||
.loaded_page_mut_for_protocol_access_for_route(session_id, owner_route)
|
||||
.loaded_page_mut_for_protocol_access_for_owner(owner)
|
||||
.and_then(|page| {
|
||||
page.finish_prepare_app_manifest_load(completion)
|
||||
.map_err(|error| error.to_string())
|
||||
@@ -174,15 +172,14 @@ pub(super) fn complete_get_app_manifest_command(
|
||||
}
|
||||
CompletedGetAppManifestWork::Fetch(outcome) => {
|
||||
let (result, publication) = (*outcome).into_parts();
|
||||
let pending =
|
||||
match conn.loaded_page_mut_for_protocol_access_for_route(session_id, owner_route) {
|
||||
Ok(page) => page.start_publish_app_manifest_load(publication),
|
||||
Err(message) => {
|
||||
return PageCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
-32000, message,
|
||||
));
|
||||
}
|
||||
};
|
||||
let pending = match conn.loaded_page_mut_for_protocol_access_for_owner(owner) {
|
||||
Ok(page) => page.start_publish_app_manifest_load(publication),
|
||||
Err(message) => {
|
||||
return PageCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
-32000, message,
|
||||
));
|
||||
}
|
||||
};
|
||||
match pending {
|
||||
Ok(pending) => pending_step(
|
||||
command_id,
|
||||
@@ -212,7 +209,7 @@ pub(super) fn complete_get_app_manifest_command(
|
||||
}
|
||||
};
|
||||
let output = match conn
|
||||
.loaded_page_mut_for_protocol_access_for_route(session_id, owner_route)
|
||||
.loaded_page_mut_for_protocol_access_for_owner(owner)
|
||||
.and_then(|page| {
|
||||
page.finish_publish_app_manifest_load(completion)
|
||||
.map_err(|error| error.to_string())
|
||||
@@ -226,7 +223,7 @@ pub(super) fn complete_get_app_manifest_command(
|
||||
};
|
||||
let mut ordered_events = Vec::new();
|
||||
command_context.consume_renderer_command_turn_output(output);
|
||||
conn.ingest_runtime_session_owner_output_updates_for_route(session_id, owner_route);
|
||||
conn.ingest_runtime_session_owner_output_updates_for_owner(owner);
|
||||
emit_pending_network_backlog_activity_background_events(
|
||||
conn,
|
||||
&mut ordered_events,
|
||||
|
||||
@@ -185,8 +185,7 @@ pub(crate) fn emit_bound_renderer_document_lifecycle_background_events(
|
||||
binding: &CommittedRendererDocumentBinding,
|
||||
events: &[RendererDocumentLifecycleEvent],
|
||||
) {
|
||||
let session_ids =
|
||||
conn.page_event_session_ids_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let session_ids = conn.page_event_session_ids_for_owner(owner);
|
||||
for event in events {
|
||||
if event.frame != binding.renderer_frame || event.document != binding.renderer_document {
|
||||
continue;
|
||||
@@ -197,15 +196,11 @@ pub(crate) fn emit_bound_renderer_document_lifecycle_background_events(
|
||||
RendererDocumentLifecycleMilestone::DomContentLoaded,
|
||||
) => {
|
||||
for session_id in &session_ids {
|
||||
let owner_route = session_id
|
||||
.is_none()
|
||||
.then_some(owner.session_owner_route())
|
||||
.flatten();
|
||||
if crate::domains::dom::dom_agent_enabled_for_route(
|
||||
conn,
|
||||
session_id.as_deref(),
|
||||
owner_route,
|
||||
) {
|
||||
let event_owner = session_id
|
||||
.as_deref()
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
if crate::domains::dom::dom_agent_enabled_for_owner(conn, &event_owner) {
|
||||
emit_cdp_page_background_automation_event(
|
||||
out,
|
||||
navigation_frame_event(
|
||||
@@ -217,11 +212,8 @@ pub(crate) fn emit_bound_renderer_document_lifecycle_background_events(
|
||||
session_id.as_deref(),
|
||||
);
|
||||
}
|
||||
let lifecycle_enabled = page_lifecycle_events_enabled_for_route(
|
||||
conn,
|
||||
session_id.as_deref(),
|
||||
owner_route,
|
||||
);
|
||||
let lifecycle_enabled =
|
||||
page_lifecycle_events_enabled_for_owner(conn, &event_owner);
|
||||
emit_renderer_navigation_domcontentloaded_background_events(
|
||||
out,
|
||||
session_id.as_deref(),
|
||||
@@ -236,15 +228,12 @@ pub(crate) fn emit_bound_renderer_document_lifecycle_background_events(
|
||||
RendererDocumentLifecycleMilestone::Load,
|
||||
) => {
|
||||
for session_id in &session_ids {
|
||||
let owner_route = session_id
|
||||
.is_none()
|
||||
.then_some(owner.session_owner_route())
|
||||
.flatten();
|
||||
let lifecycle_enabled = page_lifecycle_events_enabled_for_route(
|
||||
conn,
|
||||
session_id.as_deref(),
|
||||
owner_route,
|
||||
);
|
||||
let event_owner = session_id
|
||||
.as_deref()
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
let lifecycle_enabled =
|
||||
page_lifecycle_events_enabled_for_owner(conn, &event_owner);
|
||||
emit_renderer_navigation_load_background_events(
|
||||
out,
|
||||
session_id.as_deref(),
|
||||
@@ -263,18 +252,15 @@ pub(crate) fn emit_bound_renderer_document_lifecycle_background_events(
|
||||
| RendererLifecycleStartReason::JavascriptDocumentReplacement,
|
||||
} => {
|
||||
let frame_identity = conn
|
||||
.target_session_owner_frame_tree_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.target_session_owner_frame_tree_identity_for_owner(owner)
|
||||
.map(|(_, url, security_origin, secure_context_type)| {
|
||||
(url, security_origin, secure_context_type)
|
||||
});
|
||||
for session_id in &session_ids {
|
||||
let owner_route = session_id
|
||||
.is_none()
|
||||
.then_some(owner.session_owner_route())
|
||||
.flatten();
|
||||
let event_owner = session_id
|
||||
.as_deref()
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
if let Some((url, security_origin, secure_context_type)) =
|
||||
frame_identity.as_ref()
|
||||
{
|
||||
@@ -289,11 +275,8 @@ pub(crate) fn emit_bound_renderer_document_lifecycle_background_events(
|
||||
secure_context_type.clone(),
|
||||
));
|
||||
}
|
||||
let lifecycle_enabled = page_lifecycle_events_enabled_for_route(
|
||||
conn,
|
||||
session_id.as_deref(),
|
||||
owner_route,
|
||||
);
|
||||
let lifecycle_enabled =
|
||||
page_lifecycle_events_enabled_for_owner(conn, &event_owner);
|
||||
emit_navigation_lifecycle_init_background_events(
|
||||
out,
|
||||
session_id.as_deref(),
|
||||
@@ -310,12 +293,11 @@ pub(crate) fn emit_bound_renderer_document_lifecycle_background_events(
|
||||
}
|
||||
}
|
||||
|
||||
fn page_lifecycle_events_enabled_for_route(
|
||||
fn page_lifecycle_events_enabled_for_owner(
|
||||
conn: &CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
conn.target_page_session_state_for_route(session_id, owner_route)
|
||||
conn.target_page_session_state_for_owner(owner)
|
||||
.is_some_and(|state| state.page_lifecycle_events)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use moli_core::page::RendererMainDocumentCommit;
|
||||
|
||||
use crate::conn::CdpConnection;
|
||||
use crate::conn::{CdpConnection, CommandOwnerScope};
|
||||
use crate::domains::activity::{
|
||||
ProtocolOutputPayloads, ProtocolOutputProjectionContext, ProtocolOutputSink, ProtocolOutputSlot,
|
||||
};
|
||||
@@ -46,18 +46,14 @@ pub(in crate::domains) async fn project_main_document_commit_async(
|
||||
|
||||
for commit in commits {
|
||||
let owner = context.owner();
|
||||
let Some((current_frame_id, _, _, _)) = conn
|
||||
.target_session_owner_frame_tree_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
let Some((current_frame_id, _, _, _)) =
|
||||
conn.target_session_owner_frame_tree_identity_for_owner(owner)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let Some(current_loader_id) = conn.target_session_owner_frame_tree_loader_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) else {
|
||||
let Some(current_loader_id) =
|
||||
conn.target_session_owner_frame_tree_loader_id_for_owner(owner)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
if current_frame_id != commit.frame_id || current_loader_id != commit.loader_id {
|
||||
@@ -67,16 +63,15 @@ pub(in crate::domains) async fn project_main_document_commit_async(
|
||||
continue;
|
||||
}
|
||||
|
||||
let session_ids =
|
||||
conn.page_event_session_ids_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let session_ids = conn.page_event_session_ids_for_owner(owner);
|
||||
let mut events = Vec::new();
|
||||
for session_id in session_ids {
|
||||
let event_owner_route = session_id
|
||||
.is_none()
|
||||
.then_some(owner.session_owner_route())
|
||||
.flatten();
|
||||
let event_owner = session_id
|
||||
.as_deref()
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
let lifecycle_enabled = conn
|
||||
.target_page_session_state_for_route(session_id.as_deref(), event_owner_route)
|
||||
.target_page_session_state_for_owner(&event_owner)
|
||||
.is_some_and(|state| state.page_lifecycle_events);
|
||||
super::emit_navigation_lifecycle_init_background_events(
|
||||
&mut events,
|
||||
@@ -87,11 +82,7 @@ pub(in crate::domains) async fn project_main_document_commit_async(
|
||||
commit.timestamp,
|
||||
);
|
||||
|
||||
let dom_enabled = crate::domains::dom::dom_agent_enabled_for_route(
|
||||
conn,
|
||||
session_id.as_deref(),
|
||||
event_owner_route,
|
||||
);
|
||||
let dom_enabled = crate::domains::dom::dom_agent_enabled_for_owner(conn, &event_owner);
|
||||
super::emit_navigation_frame_commit_background_events(
|
||||
&mut events,
|
||||
session_id.as_deref(),
|
||||
|
||||
@@ -354,9 +354,7 @@ fn send_background_navigation_started(
|
||||
url: &str,
|
||||
initiator: NavigationStartInitiator,
|
||||
) {
|
||||
for session_id in
|
||||
conn.page_event_session_ids_for_route(owner.session_id(), owner.session_owner_route())
|
||||
{
|
||||
for session_id in conn.page_event_session_ids_for_owner(owner) {
|
||||
let mut events = Vec::new();
|
||||
emit_navigation_started_background_events(
|
||||
&mut events,
|
||||
@@ -381,9 +379,7 @@ fn emit_navigation_started_for_session_owner(
|
||||
url: &str,
|
||||
initiator: NavigationStartInitiator,
|
||||
) {
|
||||
for session_id in
|
||||
conn.page_event_session_ids_for_route(owner.session_id(), owner.session_owner_route())
|
||||
{
|
||||
for session_id in conn.page_event_session_ids_for_owner(owner) {
|
||||
emit_navigation_started_background_events(
|
||||
out,
|
||||
session_id.as_deref(),
|
||||
@@ -422,11 +418,7 @@ impl MaterializedNavigationCompletion {
|
||||
}
|
||||
|
||||
pub(crate) fn is_current_for_connection(&self, conn: &CdpConnection) -> bool {
|
||||
conn.accepts_pending_document_navigation_for_route(
|
||||
self.state.owner.session_id(),
|
||||
self.state.owner.session_owner_route(),
|
||||
&self.token,
|
||||
)
|
||||
conn.accepts_pending_document_navigation_for_owner(&self.state.owner, &self.token)
|
||||
}
|
||||
|
||||
pub(crate) fn requested_url(&self) -> &str {
|
||||
@@ -488,11 +480,7 @@ impl BackgroundMainDocumentBodyCompletion {
|
||||
}
|
||||
|
||||
pub(crate) fn is_current_for_connection(&self, conn: &CdpConnection) -> bool {
|
||||
conn.accepts_document_body_completion_for_route(
|
||||
self.state.owner.session_id(),
|
||||
self.state.owner.session_owner_route(),
|
||||
&self.token,
|
||||
)
|
||||
conn.accepts_document_body_completion_for_owner(&self.state.owner, &self.token)
|
||||
}
|
||||
|
||||
pub(crate) fn record_if_current(self, conn: &mut CdpConnection) {
|
||||
@@ -501,9 +489,8 @@ impl BackgroundMainDocumentBodyCompletion {
|
||||
}
|
||||
match self.body {
|
||||
Ok(body) => {
|
||||
let _ = conn.record_main_document_resource_body_for_route(
|
||||
self.state.owner.session_id(),
|
||||
self.state.owner.session_owner_route(),
|
||||
let _ = conn.record_main_document_resource_body_for_owner(
|
||||
&self.state.owner,
|
||||
self.state.frame_id.clone(),
|
||||
self.state.loader_id.clone(),
|
||||
self.final_url,
|
||||
@@ -582,11 +569,7 @@ impl BackgroundNavigationLifecycleCompletion {
|
||||
}
|
||||
|
||||
pub(crate) fn is_current_for_connection(&self, conn: &CdpConnection) -> bool {
|
||||
conn.accepts_pending_document_navigation_for_route(
|
||||
self.state.owner.session_id(),
|
||||
self.state.owner.session_owner_route(),
|
||||
&self.token,
|
||||
)
|
||||
conn.accepts_pending_document_navigation_for_owner(&self.state.owner, &self.token)
|
||||
}
|
||||
|
||||
pub(crate) fn requested_url(&self) -> &str {
|
||||
@@ -702,9 +685,9 @@ fn navigation_cookie_access_report_for_owner(
|
||||
// at the destination document. Redirect diagnostics still need the
|
||||
// pre-commit initiator, so callers may override it with a snapshot taken
|
||||
// before mutating browser context state.
|
||||
let initiator_url = initiator_url_override.cloned().or_else(|| {
|
||||
conn.navigation_initiator_url_for_route(owner.session_id(), owner.session_owner_route())
|
||||
});
|
||||
let initiator_url = initiator_url_override
|
||||
.cloned()
|
||||
.or_else(|| conn.navigation_initiator_url_for_owner(owner));
|
||||
let request_context = network::navigation_cookie_request_context(
|
||||
request_url,
|
||||
method,
|
||||
@@ -968,8 +951,8 @@ pub(crate) fn execute_devtools_get_navigation_history_command(
|
||||
let route = conn
|
||||
.target_session_route_for_target_id(target_id.as_str())
|
||||
.ok_or_else(|| DevToolsError::new(DevToolsErrorKind::NoSuchTarget, "NoSuchTarget"))?;
|
||||
let snapshot =
|
||||
conn.target_session_owner_navigation_history_snapshot_for_route(None, Some(&route));
|
||||
let owner = CommandOwnerScope::for_route(route);
|
||||
let snapshot = conn.target_session_owner_navigation_history_snapshot_for_owner(&owner);
|
||||
let Some((current_index, entries)) = snapshot else {
|
||||
return Err(DevToolsError::new(
|
||||
DevToolsErrorKind::NoSuchTarget,
|
||||
@@ -1038,20 +1021,22 @@ fn start_protocol_neutral_navigation_command(
|
||||
let wait = devtools_navigation_wait(&command);
|
||||
let result_url = match &command {
|
||||
DevToolsCommand::Navigate(command) => command.url.clone(),
|
||||
DevToolsCommand::Reload(_) => match conn
|
||||
.runtime_session_owner_target_url_for_route(None, Some(&route))
|
||||
{
|
||||
Some(url) => url,
|
||||
None => {
|
||||
let error = DevToolsError::new(DevToolsErrorKind::NoSuchTarget, "TargetNotLoaded");
|
||||
return (
|
||||
PageCommandTaskStep::Complete(CommandOutputPlan::from_devtools_error(
|
||||
error.clone(),
|
||||
)),
|
||||
Err(error),
|
||||
);
|
||||
DevToolsCommand::Reload(_) => {
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
match conn.runtime_session_owner_target_url_for_owner(&owner) {
|
||||
Some(url) => url,
|
||||
None => {
|
||||
let error =
|
||||
DevToolsError::new(DevToolsErrorKind::NoSuchTarget, "TargetNotLoaded");
|
||||
return (
|
||||
PageCommandTaskStep::Complete(CommandOutputPlan::from_devtools_error(
|
||||
error.clone(),
|
||||
)),
|
||||
Err(error),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
DevToolsCommand::TraverseHistory(_) => String::new(),
|
||||
_ => String::new(),
|
||||
};
|
||||
@@ -1296,11 +1281,8 @@ fn direct_navigation_result_from_completed_load(
|
||||
completed: &CompletedNavigateLoadCommand,
|
||||
result: &mut DirectNavigationResult,
|
||||
) -> Result<(), DevToolsError> {
|
||||
if !conn.accepts_pending_document_navigation_for_route(
|
||||
completed.state.owner.session_id(),
|
||||
completed.state.owner.session_owner_route(),
|
||||
&completed.token,
|
||||
) {
|
||||
if !conn.accepts_pending_document_navigation_for_owner(&completed.state.owner, &completed.token)
|
||||
{
|
||||
if superseded_cdp_page_navigate_payload(&completed.state).is_some() {
|
||||
result.set_cdp_navigation_aborted(&completed.state.frame_id);
|
||||
return Ok(());
|
||||
@@ -1400,7 +1382,8 @@ fn fill_navigation_id_from_current_loader_for_route(
|
||||
if result.navigation_id.is_some() {
|
||||
return;
|
||||
}
|
||||
let loader_id = conn.current_document_loader_id_for_route(None, Some(route));
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
let loader_id = conn.current_document_loader_id_for_owner(&owner);
|
||||
result.ensure_navigation_id_from_loader(loader_id);
|
||||
}
|
||||
|
||||
@@ -1449,10 +1432,7 @@ fn session_owner_navigation_is_same_document_fragment(
|
||||
owner: &CommandOwnerScope,
|
||||
target: &str,
|
||||
) -> bool {
|
||||
let Some(current) = conn.runtime_session_owner_target_url_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) else {
|
||||
let Some(current) = conn.runtime_session_owner_target_url_for_owner(owner) else {
|
||||
return false;
|
||||
};
|
||||
let (Ok(mut current), Ok(mut target)) = (Url::parse(¤t), Url::parse(target)) else {
|
||||
@@ -1494,7 +1474,7 @@ fn start_top_level_same_document_navigate(
|
||||
result_payload: Value,
|
||||
) -> NavigateCommandStart {
|
||||
let Some(page) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
else {
|
||||
@@ -1537,27 +1517,23 @@ fn start_child_frame_navigate_command(
|
||||
wait: DevToolsNavigationWait,
|
||||
result_payload: Value,
|
||||
) -> NavigateCommandStart {
|
||||
let Some(source_document) = conn.target_root_document_lifecycle_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) else {
|
||||
let Some(source_document) = conn.target_root_document_lifecycle_identity_for_owner(owner)
|
||||
else {
|
||||
return NavigateCommandStart::CompletePlan(CommandOutputPlan::error(
|
||||
-32000,
|
||||
"NoDocumentLoaded",
|
||||
));
|
||||
};
|
||||
let Some(activity_binding) = conn.target_root_document_protocol_attachment_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
source_document,
|
||||
) else {
|
||||
let Some(activity_binding) =
|
||||
conn.target_root_document_protocol_attachment_identity_for_owner(owner, source_document)
|
||||
else {
|
||||
return NavigateCommandStart::CompletePlan(CommandOutputPlan::error(
|
||||
-32000,
|
||||
"NoDocumentLoaded",
|
||||
));
|
||||
};
|
||||
let Some(page) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
else {
|
||||
@@ -1641,29 +1617,15 @@ fn build_cdp_reload_command(
|
||||
fn start_devtools_reload_command(
|
||||
conn: &mut CdpConnection,
|
||||
command_id: Option<u64>,
|
||||
command: &DevToolsReloadCommand,
|
||||
_command: &DevToolsReloadCommand,
|
||||
options: DevToolsNavigationStartOptions,
|
||||
) -> PageCommandTaskStep {
|
||||
let context_session_id = command.context.session_id.as_ref().map(|id| id.as_str());
|
||||
let owner = if options.owner.session_id().is_none()
|
||||
&& options.owner.session_owner_route().is_none()
|
||||
&& context_session_id.is_some()
|
||||
{
|
||||
CommandOwnerScope::capture(conn, context_session_id)
|
||||
} else {
|
||||
options.owner
|
||||
};
|
||||
let Some(url) = conn.runtime_session_owner_target_url_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) else {
|
||||
let owner = options.owner;
|
||||
let Some(url) = conn.runtime_session_owner_target_url_for_owner(&owner) else {
|
||||
return PageCommandTaskStep::Complete(CommandOutputPlan::error(-31998, "TargetNotLoaded"));
|
||||
};
|
||||
if conn
|
||||
.mark_next_navigation_history_replace_current_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.mark_next_navigation_history_replace_current_for_owner(&owner)
|
||||
.is_none()
|
||||
{
|
||||
return PageCommandTaskStep::Complete(CommandOutputPlan::error(-31998, "TargetNotLoaded"));
|
||||
@@ -1757,11 +1719,8 @@ fn resolve_devtools_history_traversal_destination(
|
||||
owner: &CommandOwnerScope,
|
||||
destination: &DevToolsHistoryTraversalDestination,
|
||||
) -> Result<ResolvedDevToolsHistoryTraversal, DevToolsError> {
|
||||
let Some((current_index, entries)) = conn
|
||||
.target_session_owner_navigation_history_snapshot_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
let Some((current_index, entries)) =
|
||||
conn.target_session_owner_navigation_history_snapshot_for_owner(owner)
|
||||
else {
|
||||
return Err(DevToolsError::new(
|
||||
DevToolsErrorKind::NoSuchTarget,
|
||||
@@ -1823,10 +1782,7 @@ fn start_same_document_history_traversal_command(
|
||||
fallback: HistoryTraversalUrlFallback,
|
||||
) -> PageCommandTaskStep {
|
||||
let page = conn
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
fallback.owner.session_id(),
|
||||
fallback.owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(&fallback.owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page())
|
||||
.ok_or_else(|| anyhow::anyhow!("TargetNotLoaded"));
|
||||
@@ -1873,10 +1829,7 @@ pub(super) fn complete_pending_same_document_history_traversal_command(
|
||||
}
|
||||
};
|
||||
let result = conn
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
fallback.owner.session_id(),
|
||||
fallback.owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(&fallback.owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
.ok_or_else(|| anyhow::anyhow!("TargetNotLoaded"))
|
||||
@@ -1922,21 +1875,20 @@ fn start_history_traversal_url_fallback(
|
||||
|
||||
pub(super) fn start_session_owner_history_traversal_from_renderer(
|
||||
conn: &mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
delta: i64,
|
||||
) -> PageCommandTaskStep {
|
||||
let owner = CommandOwnerScope::capture(conn, session_id);
|
||||
let reloaded_after_crash_session_ids = reloaded_after_crash_session_ids(conn, &owner);
|
||||
let reloaded_after_crash_session_ids = reloaded_after_crash_session_ids(conn, owner);
|
||||
let destination = DevToolsHistoryTraversalDestination::Delta(delta);
|
||||
let (entry_id, url) =
|
||||
match resolve_devtools_history_traversal_destination(conn, &owner, &destination) {
|
||||
match resolve_devtools_history_traversal_destination(conn, owner, &destination) {
|
||||
Ok(ResolvedDevToolsHistoryTraversal::Entry { entry_id, url, .. }) => (entry_id, url),
|
||||
Ok(ResolvedDevToolsHistoryTraversal::Noop) => {
|
||||
return PageCommandTaskStep::Complete(CommandOutputPlan::success());
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::debug!(
|
||||
session_id,
|
||||
session_id = owner.session_id(),
|
||||
delta,
|
||||
error = error.message.as_str(),
|
||||
"ignoring renderer history traversal without a browser-side destination"
|
||||
@@ -1950,7 +1902,7 @@ pub(super) fn start_session_owner_history_traversal_from_renderer(
|
||||
entry_id,
|
||||
&url,
|
||||
DevToolsNavigationStartOptions {
|
||||
owner,
|
||||
owner: owner.clone(),
|
||||
result_projection: NavigationResultProjection::Cdp(json!({})),
|
||||
reloaded_after_crash_session_ids,
|
||||
allow_background_navigation: false,
|
||||
@@ -1974,11 +1926,7 @@ fn start_resolved_history_traversal_command(
|
||||
source: HistoryTraversalStartSource,
|
||||
) -> PageCommandTaskStep {
|
||||
if conn
|
||||
.mark_next_navigation_history_traverse_to_entry_for_route(
|
||||
options.owner.session_id(),
|
||||
options.owner.session_owner_route(),
|
||||
entry_id,
|
||||
)
|
||||
.mark_next_navigation_history_traverse_to_entry_for_owner(&options.owner, entry_id)
|
||||
.is_none()
|
||||
{
|
||||
return PageCommandTaskStep::Complete(CommandOutputPlan::error(-31998, "TargetNotLoaded"));
|
||||
@@ -2017,15 +1965,8 @@ fn start_devtools_traverse_history_command(
|
||||
conn: &mut CdpConnection,
|
||||
command_id: Option<u64>,
|
||||
command: &DevToolsTraverseHistoryCommand,
|
||||
mut options: DevToolsNavigationStartOptions,
|
||||
options: DevToolsNavigationStartOptions,
|
||||
) -> PageCommandTaskStep {
|
||||
let context_session_id = command.context.session_id.as_ref().map(|id| id.as_str());
|
||||
if options.owner.session_id().is_none()
|
||||
&& options.owner.session_owner_route().is_none()
|
||||
&& context_session_id.is_some()
|
||||
{
|
||||
options.owner = CommandOwnerScope::capture(conn, context_session_id);
|
||||
}
|
||||
let (entry_id, url, same_document_delta) = match resolve_devtools_history_traversal_destination(
|
||||
conn,
|
||||
&options.owner,
|
||||
@@ -2600,7 +2541,7 @@ pub(super) fn complete_reset_navigation_history_command(
|
||||
}
|
||||
};
|
||||
let Some(page) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
else {
|
||||
@@ -2621,7 +2562,7 @@ pub(super) fn complete_reset_navigation_history_command(
|
||||
));
|
||||
}
|
||||
}
|
||||
match conn.reset_navigation_history_for_route(owner.session_id(), owner.session_owner_route()) {
|
||||
match conn.reset_navigation_history_for_owner(owner) {
|
||||
Some(true) => PageCommandTaskStep::Complete(CommandOutputPlan::success()),
|
||||
Some(false) => PageCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
-32000,
|
||||
@@ -2636,12 +2577,12 @@ fn reloaded_after_crash_session_ids(
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Vec<Option<String>> {
|
||||
if !conn
|
||||
.target_owner_state_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.target_owner_state_for_owner(owner)
|
||||
.is_some_and(|owner_state| owner_state.target_crash_state.is_crashed())
|
||||
{
|
||||
return Vec::new();
|
||||
}
|
||||
conn.page_event_session_ids_for_route(owner.session_id(), owner.session_owner_route())
|
||||
conn.page_event_session_ids_for_owner(owner)
|
||||
.into_iter()
|
||||
.filter(|event_session_id| {
|
||||
conn.target_runtime_session_state_for_session(event_session_id.as_deref())
|
||||
@@ -2656,13 +2597,9 @@ fn clear_crash_state_after_navigation(
|
||||
owner: &CommandOwnerScope,
|
||||
reloaded_after_crash_session_ids: &[Option<String>],
|
||||
) {
|
||||
let _ = conn.with_target_owner_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner_state| {
|
||||
owner_state.target_crash_state.clear();
|
||||
},
|
||||
);
|
||||
let _ = conn.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
owner_state.target_crash_state.clear();
|
||||
});
|
||||
for session_id in reloaded_after_crash_session_ids {
|
||||
out.push(inspector_target_reloaded_after_crash_event(
|
||||
session_id.as_deref(),
|
||||
@@ -2676,13 +2613,9 @@ fn clear_crash_state_after_navigation_into_plan(
|
||||
owner: &CommandOwnerScope,
|
||||
reloaded_after_crash_session_ids: &[Option<String>],
|
||||
) {
|
||||
let _ = conn.with_target_owner_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner_state| {
|
||||
owner_state.target_crash_state.clear();
|
||||
},
|
||||
);
|
||||
let _ = conn.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
owner_state.target_crash_state.clear();
|
||||
});
|
||||
for session_id in reloaded_after_crash_session_ids {
|
||||
plan.push_background_event(inspector_target_reloaded_after_crash_event(
|
||||
session_id.as_deref(),
|
||||
@@ -2785,7 +2718,6 @@ fn start_navigate_to_url_command_with_background_policy_and_request(
|
||||
initiator: NavigationStartInitiator,
|
||||
) -> NavigateCommandStart {
|
||||
let command_session_id = owner.session_id();
|
||||
let owner_route = owner.session_owner_route();
|
||||
let mut out = Vec::new();
|
||||
let timestamp = monotonic_timestamp_seconds();
|
||||
let mut fetch_request_stage = FetchRequestStage::Request;
|
||||
@@ -2801,9 +2733,8 @@ fn start_navigate_to_url_command_with_background_policy_and_request(
|
||||
error.to_string(),
|
||||
));
|
||||
}
|
||||
let mut navigation_preflight = conn.prepare_navigation_request_for_route(
|
||||
command_session_id,
|
||||
owner_route,
|
||||
let mut navigation_preflight = conn.prepare_navigation_request_for_owner(
|
||||
owner,
|
||||
&requested_url,
|
||||
referrer,
|
||||
url.starts_with("data:"),
|
||||
@@ -2812,7 +2743,7 @@ fn start_navigate_to_url_command_with_background_policy_and_request(
|
||||
.as_ref()
|
||||
.map(|preflight| preflight.frame_id.clone())
|
||||
.or_else(|| {
|
||||
conn.target_owner_identity_for_route(command_session_id, owner_route)
|
||||
conn.target_owner_identity_for_owner(owner)
|
||||
.and_then(|(_, target_id)| target_id)
|
||||
})
|
||||
.unwrap_or_else(|| "FRAME-0".to_owned());
|
||||
@@ -2910,11 +2841,8 @@ fn start_navigate_to_url_command_with_background_policy_and_request(
|
||||
}
|
||||
|
||||
let navigation_loader_id = navigation_state.loader_id.as_str();
|
||||
let document_navigation_token = conn.start_document_navigation_for_route(
|
||||
command_session_id,
|
||||
owner_route,
|
||||
navigation_loader_id.to_owned(),
|
||||
);
|
||||
let document_navigation_token =
|
||||
conn.start_document_navigation_for_owner(owner, navigation_loader_id.to_owned());
|
||||
let Some(document_navigation_token) = document_navigation_token else {
|
||||
return NavigateCommandStart::CompletePlan(CommandOutputPlan::error(
|
||||
-31998,
|
||||
@@ -2976,9 +2904,8 @@ fn start_navigate_to_url_command_with_background_policy_and_request(
|
||||
);
|
||||
}
|
||||
pending.navigation.request_announced = pending.navigation.request_id.is_some();
|
||||
let _ = conn.register_pending_fetch_navigation_request_for_route(
|
||||
pending.navigation.owner.session_id(),
|
||||
pending.navigation.owner.session_owner_route(),
|
||||
let _ = conn.register_pending_fetch_navigation_request_for_owner(
|
||||
&pending.navigation.owner,
|
||||
pending.clone(),
|
||||
);
|
||||
out.push(fetch::request_paused_background_event(
|
||||
@@ -3016,8 +2943,7 @@ fn start_navigate_to_url_command_with_background_policy_and_request(
|
||||
}
|
||||
|
||||
if allow_background_navigation
|
||||
&& let Some(sender) =
|
||||
conn.background_navigation_completion_sender_for_route(command_session_id, owner_route)
|
||||
&& let Some(sender) = conn.background_navigation_completion_sender_for_owner(owner)
|
||||
{
|
||||
let body_progress_source = if navigation_state.request_id.is_some() {
|
||||
let request_cookie_report = navigation_cookie_access_report_for_owner(
|
||||
@@ -3135,10 +3061,7 @@ pub(super) fn start_initial_document_navigation_for_session_owner(
|
||||
owner: &CommandOwnerScope,
|
||||
result_payload: Value,
|
||||
) -> Result<NavigateCommandStart, CommandOutputPlan> {
|
||||
let Some(url) = conn.runtime_session_owner_target_url_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) else {
|
||||
let Some(url) = conn.runtime_session_owner_target_url_for_owner(owner) else {
|
||||
if conn.browser_context.is_none() {
|
||||
return Err(CommandOutputPlan::error(-31998, "BrowserContextNotLoaded"));
|
||||
}
|
||||
@@ -3169,11 +3092,7 @@ pub(super) async fn complete_pending_navigate_load_command(
|
||||
engine,
|
||||
navigation,
|
||||
} = completed;
|
||||
let is_current = conn.accepts_pending_document_navigation_for_route(
|
||||
state.owner.session_id(),
|
||||
state.owner.session_owner_route(),
|
||||
&token,
|
||||
);
|
||||
let is_current = conn.accepts_pending_document_navigation_for_owner(&state.owner, &token);
|
||||
let should_replace_owner_engine = is_current
|
||||
&& matches!(
|
||||
navigation,
|
||||
@@ -3222,10 +3141,7 @@ pub(super) async fn complete_pending_child_frame_navigate_command(
|
||||
};
|
||||
let (navigated, renderer_output) = {
|
||||
let Some(page) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
else {
|
||||
@@ -3312,10 +3228,7 @@ pub(super) async fn complete_pending_same_document_navigate_command(
|
||||
};
|
||||
let (navigated, output) = {
|
||||
let Some(page) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
else {
|
||||
@@ -3503,10 +3416,7 @@ async fn complete_materialized_navigation_into_buffer_inner_async(
|
||||
}
|
||||
}
|
||||
let primary_protocol_session_id = conn
|
||||
.runtime_session_owner_primary_session_id_for_route(
|
||||
navigation_owner.session_id(),
|
||||
navigation_owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_primary_session_id_for_owner(&navigation_owner)
|
||||
.or_else(|| navigation_session_id.clone());
|
||||
let (routed_renderer_output, renderer_call_replacements) = conn
|
||||
.finish_renderer_document_navigation_for_owner(&navigation_owner, &token)
|
||||
@@ -3567,17 +3477,17 @@ fn push_navigation_commit_error(
|
||||
fn emit_same_document_navigation_background_event(
|
||||
conn: &mut CdpConnection,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
url: Url,
|
||||
navigation_type: &str,
|
||||
history_update: SameDocumentHistoryUpdate,
|
||||
) {
|
||||
let Some(frame_id) =
|
||||
conn.record_same_document_navigation_for_session_owner(session_id, &url, history_update)
|
||||
conn.record_same_document_navigation_for_owner(owner, &url, history_update)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
for event_session_id in conn.page_event_session_ids_for_session_owner(session_id) {
|
||||
for event_session_id in conn.page_event_session_ids_for_owner(owner) {
|
||||
let event = SameDocumentNavigationEvent {
|
||||
target_id: DevToolsTargetId::from(frame_id.as_str()),
|
||||
frame_id: DevToolsFrameId::from(frame_id.as_str()),
|
||||
@@ -3594,14 +3504,13 @@ fn emit_same_document_navigation_background_event(
|
||||
pub(crate) async fn emit_same_document_navigation_background_events_async(
|
||||
conn: &mut CdpConnection,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
navigations: Vec<super::PagePreparedSameDocumentNavigation>,
|
||||
) {
|
||||
for navigation in navigations {
|
||||
let session_id = owner.session_id();
|
||||
let source_document = navigation.source_document();
|
||||
if !conn
|
||||
.target_page_residence_identity_is_current_for_session(session_id, navigation.owner())
|
||||
{
|
||||
if !conn.target_page_residence_identity_is_current(navigation.owner()) {
|
||||
tracing::debug!(
|
||||
session_id,
|
||||
?source_document,
|
||||
@@ -3616,7 +3525,7 @@ pub(crate) async fn emit_same_document_navigation_background_events_async(
|
||||
let Ok(url) = Url::parse(&navigation.url) else {
|
||||
continue;
|
||||
};
|
||||
if conn.has_pending_document_navigation_for_session_owner(session_id) {
|
||||
if conn.has_pending_document_navigation_for_owner(owner) {
|
||||
tracing::debug!(
|
||||
session_id,
|
||||
url = url.as_str(),
|
||||
@@ -3628,7 +3537,7 @@ pub(crate) async fn emit_same_document_navigation_background_events_async(
|
||||
emit_same_document_navigation_background_event(
|
||||
conn,
|
||||
out,
|
||||
session_id,
|
||||
owner,
|
||||
url,
|
||||
&navigation.navigation_type,
|
||||
navigation.history_update,
|
||||
|
||||
@@ -507,17 +507,14 @@ async fn restore_and_commit_loaded_navigation_page_async(
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
}
|
||||
let preload_channel_execution_context_ids = if conn
|
||||
.target_owner_has_bidi_channel_preload_script_for_route(
|
||||
state.owner.session_id(),
|
||||
state.owner.session_owner_route(),
|
||||
) {
|
||||
dedupe_preload_channel_execution_context_ids(std::mem::take(
|
||||
&mut outcome.preload_channel_execution_context_ids,
|
||||
))
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let preload_channel_execution_context_ids =
|
||||
if conn.target_owner_has_bidi_channel_preload_script_for_owner(&state.owner) {
|
||||
dedupe_preload_channel_execution_context_ids(std::mem::take(
|
||||
&mut outcome.preload_channel_execution_context_ids,
|
||||
))
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let mut preload_channel_listener_events = Vec::new();
|
||||
for execution_context_id in preload_channel_execution_context_ids {
|
||||
Box::pin(
|
||||
|
||||
@@ -129,15 +129,9 @@ async fn append_loaded_page_document_start_script_for_owner_async(
|
||||
owner: &CommandOwnerScope,
|
||||
script: &DocumentStartScript,
|
||||
) -> Result<(), String> {
|
||||
let renderer_runtime_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let slot = conn.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?;
|
||||
let renderer_runtime_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let slot = conn.runtime_session_owner_slot_mut_for_owner(owner)?;
|
||||
if let Some(page) = slot.loaded_page_mut() {
|
||||
page.add_document_start_script_runtime_activity_async(
|
||||
renderer_runtime_inspector_session_id.as_deref(),
|
||||
@@ -155,10 +149,7 @@ async fn remove_loaded_page_document_start_script_for_owner_async(
|
||||
owner: &CommandOwnerScope,
|
||||
registry_key: &str,
|
||||
) -> Result<(), String> {
|
||||
let slot = conn.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)?;
|
||||
let slot = conn.runtime_session_owner_slot_mut_for_owner(owner)?;
|
||||
if let Some(page) = slot.loaded_page_mut() {
|
||||
page.remove_document_start_script_by_registry_key_async(registry_key)
|
||||
.await
|
||||
@@ -503,10 +494,7 @@ async fn execute_devtools_single_route_add_preload_script_command(
|
||||
let identifier = if is_bidi_default_preload_command(&command) {
|
||||
execute_devtools_default_add_preload_script_command(conn, owner, command).await?
|
||||
} else {
|
||||
if conn
|
||||
.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.is_none()
|
||||
{
|
||||
if conn.target_owner_identity_for_owner(owner).is_none() {
|
||||
return Err(preload_missing_owner_error(conn));
|
||||
}
|
||||
let mut side_effects = CommandOutputPlan::default();
|
||||
@@ -531,7 +519,7 @@ async fn execute_devtools_default_add_preload_script_command(
|
||||
) -> Result<String, DevToolsError> {
|
||||
let script = document_start_script_from_add_preload_command(&command)?;
|
||||
let Some(browser_context_id) = conn
|
||||
.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.target_owner_identity_for_owner(owner)
|
||||
.map(|(browser_context_id, _)| browser_context_id)
|
||||
else {
|
||||
return Err(DevToolsError::new(
|
||||
@@ -558,13 +546,10 @@ async fn append_default_document_start_script_direct_async(
|
||||
identifier: String,
|
||||
script: &DocumentStartScript,
|
||||
) -> Result<String, DevToolsError> {
|
||||
let renderer_runtime_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_runtime_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let Some(page) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
else {
|
||||
@@ -582,7 +567,7 @@ async fn append_default_document_start_script_direct_async(
|
||||
.await
|
||||
.map_err(|error| devtools_preload_internal_error(error.to_string()))?;
|
||||
let Some(page) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
else {
|
||||
@@ -600,23 +585,18 @@ async fn execute_devtools_single_route_remove_preload_script_command(
|
||||
) -> Result<(), DevToolsError> {
|
||||
let protocol = command.context.protocol;
|
||||
let script_id = command.script_id.into_string();
|
||||
let owner_identity =
|
||||
conn.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let owner_identity = conn.target_owner_identity_for_owner(owner);
|
||||
let target_registry_key = owner_identity.as_ref().map(|(_, target_id)| {
|
||||
BrowserContext::target_document_start_script_registry_key(target_id.as_deref(), &script_id)
|
||||
});
|
||||
let remove_result = conn.with_target_owner_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|owner_state| {
|
||||
remove_stored_document_start_script_registry_key(
|
||||
owner_state,
|
||||
None,
|
||||
&script_id,
|
||||
target_registry_key.clone(),
|
||||
)
|
||||
},
|
||||
);
|
||||
let remove_result = conn.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
remove_stored_document_start_script_registry_key(
|
||||
owner_state,
|
||||
None,
|
||||
&script_id,
|
||||
target_registry_key.clone(),
|
||||
)
|
||||
});
|
||||
let Some((mut removed, mut registry_key)) = remove_result else {
|
||||
return Err(preload_missing_owner_error(conn));
|
||||
};
|
||||
@@ -648,7 +628,7 @@ async fn remove_document_start_script_direct_async(
|
||||
return Ok(());
|
||||
};
|
||||
let Some(page) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
else {
|
||||
@@ -662,7 +642,7 @@ async fn remove_document_start_script_direct_async(
|
||||
.await
|
||||
.map_err(|error| devtools_preload_internal_error(error.to_string()))?;
|
||||
let Some(page) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
else {
|
||||
@@ -996,8 +976,9 @@ fn find_preload_script_route(conn: &mut CdpConnection, script_id: &str) -> Optio
|
||||
let Some(route) = conn.target_session_route_for_target_id(&target_id) else {
|
||||
continue;
|
||||
};
|
||||
let owner = CommandOwnerScope::for_route(route.clone());
|
||||
let has_script = conn
|
||||
.target_owner_state_for_route(None, Some(&route))
|
||||
.target_owner_state_for_owner(&owner)
|
||||
.is_some_and(|owner_state| {
|
||||
owner_state
|
||||
.document_start_scripts
|
||||
@@ -1298,7 +1279,7 @@ fn start_create_isolated_world_initial_navigation_or_renderer_phase(
|
||||
mut task: CreateIsolatedWorldCommandTask,
|
||||
) -> PageCommandTaskStep {
|
||||
let should_start_target_url_navigation =
|
||||
conn.runtime_session_owner_can_start_initial_document_navigation(owner.session_id());
|
||||
conn.runtime_session_owner_can_start_initial_document_navigation_for_owner(&owner);
|
||||
if !should_start_target_url_navigation {
|
||||
return start_create_isolated_world_frame_or_world_phase(conn, command_id, owner, task);
|
||||
}
|
||||
@@ -1368,11 +1349,8 @@ fn start_create_isolated_world_frame_or_world_phase(
|
||||
let frame_id = (task.params.frame_id != task.target_id).then(|| task.params.frame_id.clone());
|
||||
let world_name = task.params.world_name.clone();
|
||||
let grant_universal_access = task.params.grant_universal_access;
|
||||
let renderer_runtime_inspector_session_id = conn
|
||||
.target_renderer_runtime_inspector_session_id_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let renderer_runtime_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(&owner);
|
||||
let page =
|
||||
match loaded_page_mut_for_create_isolated_world_renderer_command(conn, &owner, &mut task) {
|
||||
Ok(page) => page,
|
||||
@@ -1402,7 +1380,7 @@ fn loaded_page_mut_for_create_isolated_world_renderer_command<'a>(
|
||||
task: &mut CreateIsolatedWorldCommandTask,
|
||||
) -> Result<&'a mut moli_core::page::Page, CommandOutputPlan> {
|
||||
let slot = conn
|
||||
.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.map_err(|error| CommandOutputPlan::error(-32000, error))?;
|
||||
task.pending_renderer_agent_attachment_id = Some(
|
||||
slot.current_renderer_attachment()
|
||||
@@ -1421,7 +1399,7 @@ fn create_isolated_world_renderer_completion_is_stale(
|
||||
let Some(expected_attachment_id) = task.pending_renderer_agent_attachment_id else {
|
||||
return false;
|
||||
};
|
||||
conn.runtime_session_owner_slot_for_route(owner.session_id(), owner.session_owner_route())
|
||||
conn.runtime_session_owner_slot_for_owner(owner)
|
||||
.map(|slot| {
|
||||
slot.current_renderer_attachment()
|
||||
.map(|attachment| attachment.id())
|
||||
@@ -1627,10 +1605,7 @@ pub(super) async fn complete_pending_create_isolated_world_command(
|
||||
};
|
||||
let completed_world = {
|
||||
let Some(page) = conn
|
||||
.runtime_session_owner_slot_mut_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()
|
||||
.and_then(|slot| slot.loaded_page_mut())
|
||||
else {
|
||||
@@ -1742,26 +1717,22 @@ async fn add_script_to_evaluate_on_new_document_direct_async(
|
||||
command_context: &mut CommandDispatchContext,
|
||||
) -> Result<String, DevToolsError> {
|
||||
let script = document_start_script_from_add_preload_command(&command)?;
|
||||
let session_id = owner.session_id();
|
||||
let owner_route = owner.session_owner_route();
|
||||
let renderer_inspector_session_id =
|
||||
conn.target_renderer_runtime_inspector_session_id_for_route(session_id, owner_route);
|
||||
conn.target_renderer_runtime_inspector_session_id_for_owner(owner);
|
||||
let script_owner_session = (command.context.protocol == DevToolsProtocol::Cdp).then(|| {
|
||||
DevToolsSessionKey::from_wire_session_id(renderer_inspector_session_id.as_deref())
|
||||
});
|
||||
let target_id = conn
|
||||
.target_owner_identity_for_route(session_id, owner_route)
|
||||
.target_owner_identity_for_owner(owner)
|
||||
.and_then(|(_, target_id)| target_id);
|
||||
let Some(recorded) =
|
||||
conn.with_target_owner_state_for_route_mut(session_id, owner_route, |owner_state| {
|
||||
record_document_start_script(
|
||||
owner_state,
|
||||
target_id.as_deref(),
|
||||
script_owner_session.as_ref(),
|
||||
&script,
|
||||
)
|
||||
})
|
||||
else {
|
||||
let Some(recorded) = conn.with_target_owner_state_for_owner_mut(owner, |owner_state| {
|
||||
record_document_start_script(
|
||||
owner_state,
|
||||
target_id.as_deref(),
|
||||
script_owner_session.as_ref(),
|
||||
&script,
|
||||
)
|
||||
}) else {
|
||||
return Err(preload_missing_owner_error(conn));
|
||||
};
|
||||
let identifier = recorded.identifier.clone();
|
||||
@@ -1771,7 +1742,7 @@ async fn add_script_to_evaluate_on_new_document_direct_async(
|
||||
}
|
||||
let pending_run_immediately = {
|
||||
let renderer_runtime_inspector_session_id = renderer_inspector_session_id;
|
||||
let slot = match conn.runtime_session_owner_slot_mut_for_route(session_id, owner_route) {
|
||||
let slot = match conn.runtime_session_owner_slot_mut_for_owner(owner) {
|
||||
Ok(slot) => slot,
|
||||
Err(error) => return Err(devtools_preload_internal_error(error)),
|
||||
};
|
||||
@@ -1799,7 +1770,7 @@ async fn add_script_to_evaluate_on_new_document_direct_async(
|
||||
.map_err(|error| devtools_preload_internal_error(error.to_string()))?;
|
||||
let (result, output) = {
|
||||
let slot = conn
|
||||
.runtime_session_owner_slot_mut_for_route(session_id, owner_route)
|
||||
.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.map_err(devtools_preload_internal_error)?;
|
||||
let page = slot.loaded_page_mut().ok_or_else(|| {
|
||||
devtools_preload_internal_error("NoDocumentLoaded".to_owned())
|
||||
|
||||
@@ -299,7 +299,7 @@ fn complete_error(message: impl Into<String>) -> PageCommandTaskStep {
|
||||
}
|
||||
|
||||
fn loaded_page<'a>(conn: &'a mut CdpConnection, owner: &CommandOwnerScope) -> Option<&'a mut Page> {
|
||||
conn.runtime_session_owner_slot_mut_for_route(owner.session_id(), owner.session_owner_route())
|
||||
conn.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
.ok()?
|
||||
.loaded_page_mut()
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ fn take_pending_fetch_state_for_owner(
|
||||
Vec<(String, crate::conn::PendingSubresourceFetchAuthRequest)>,
|
||||
Vec<(String, crate::conn::PendingSubresourceFetchResponseRequest)>,
|
||||
) {
|
||||
conn.take_pending_fetch_state_for_route(owner.session_id(), owner.session_owner_route())
|
||||
conn.take_pending_fetch_state_for_owner(owner)
|
||||
.unwrap_or_else(|| {
|
||||
(
|
||||
Vec::new(),
|
||||
@@ -179,7 +179,6 @@ async fn fail_pending_fetch_state_for_owner_background_events_async(
|
||||
crate::conn::PendingSubresourceFetchResponseRequest,
|
||||
)>,
|
||||
) -> Option<RendererOutputFence> {
|
||||
let session_id = owner.session_id();
|
||||
// A protocol navigation waiter may expose an operation-specific failure,
|
||||
// while Network.loadingFailed must retain the underlying net error. For
|
||||
// Page.stopLoading Chromium reports ERR_ABORTED/canceled=true even though
|
||||
@@ -235,13 +234,12 @@ async fn fail_pending_fetch_state_for_owner_background_events_async(
|
||||
merge_renderer_output_predecessor(&mut renderer_output_predecessor, predecessor);
|
||||
}
|
||||
for (_, pending) in pending_subresource_fetches {
|
||||
if !conn.pending_subresource_fetch_request_residence_is_current(session_id, &pending) {
|
||||
if !conn.pending_subresource_fetch_request_residence_is_current(&pending) {
|
||||
continue;
|
||||
}
|
||||
match conn
|
||||
.fail_pending_subresource_fetch_for_route_async(
|
||||
session_id,
|
||||
owner.session_owner_route(),
|
||||
.fail_pending_subresource_fetch_for_owner_async(
|
||||
owner,
|
||||
pending.internal_id,
|
||||
subresource_error_text.to_owned(),
|
||||
)
|
||||
@@ -262,15 +260,12 @@ async fn fail_pending_fetch_state_for_owner_background_events_async(
|
||||
}
|
||||
}
|
||||
for (_, pending) in pending_subresource_auths {
|
||||
if !conn
|
||||
.target_page_residence_identity_is_current_for_session(session_id, &pending.page_owner)
|
||||
{
|
||||
if !conn.target_page_residence_identity_is_current(&pending.page_owner) {
|
||||
continue;
|
||||
}
|
||||
match conn
|
||||
.fail_pending_subresource_auth_for_route_async(
|
||||
session_id,
|
||||
owner.session_owner_route(),
|
||||
.fail_pending_subresource_auth_for_owner_async(
|
||||
owner,
|
||||
pending.internal_id,
|
||||
subresource_error_text.to_owned(),
|
||||
)
|
||||
@@ -288,15 +283,12 @@ async fn fail_pending_fetch_state_for_owner_background_events_async(
|
||||
}
|
||||
}
|
||||
for (_, pending) in pending_subresource_responses {
|
||||
if !conn
|
||||
.target_page_residence_identity_is_current_for_session(session_id, &pending.page_owner)
|
||||
{
|
||||
if !conn.target_page_residence_identity_is_current(&pending.page_owner) {
|
||||
continue;
|
||||
}
|
||||
match conn
|
||||
.fail_pending_subresource_response_for_route_async(
|
||||
session_id,
|
||||
owner.session_owner_route(),
|
||||
.fail_pending_subresource_response_for_owner_async(
|
||||
owner,
|
||||
pending.internal_id,
|
||||
subresource_error_text.to_owned(),
|
||||
)
|
||||
@@ -337,10 +329,9 @@ fn fail_crashed_subresource_fetches_background_events(
|
||||
pending_subresource_responses: Vec<(String, PendingSubresourceFetchResponseRequest)>,
|
||||
) {
|
||||
let loader_id = conn
|
||||
.current_document_loader_id_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.current_document_loader_id_for_owner(owner)
|
||||
.unwrap_or_else(|| DEFAULT_LOADER_ID.to_owned());
|
||||
let event_session_ids =
|
||||
conn.network_event_session_ids_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let event_session_ids = conn.network_event_session_ids_for_owner(owner);
|
||||
let timestamp = monotonic_timestamp_seconds();
|
||||
|
||||
let mut emit_failure =
|
||||
@@ -404,9 +395,7 @@ pub(super) async fn complete_stop_loading_command_dispatch(
|
||||
owner: &CommandOwnerScope,
|
||||
) -> PageCommandTaskStep {
|
||||
let mut out = Vec::new();
|
||||
let session_id = owner.session_id();
|
||||
if let Ok(slot) =
|
||||
conn.runtime_session_owner_slot_mut_for_route(session_id, owner.session_owner_route())
|
||||
if let Ok(slot) = conn.runtime_session_owner_slot_mut_for_owner(owner)
|
||||
&& let Some(page) = slot.loaded_page_mut()
|
||||
&& let Err(error) = page.stop_document_lifecycle_async().await
|
||||
{
|
||||
@@ -473,9 +462,7 @@ pub(super) async fn complete_crash_command_dispatch(
|
||||
) -> PageCommandTaskStep {
|
||||
let mut out = Vec::new();
|
||||
let session_id = owner.session_id();
|
||||
let Some((_, target_id)) =
|
||||
conn.target_owner_identity_for_route(session_id, owner.session_owner_route())
|
||||
else {
|
||||
let Some((_, target_id)) = conn.target_owner_identity_for_owner(owner) else {
|
||||
return PageCommandTaskStep::Complete(CommandOutputPlan::error_without_session(
|
||||
-31998,
|
||||
super::missing_page_target_error_message(conn, session_id),
|
||||
@@ -501,10 +488,7 @@ pub(super) async fn complete_crash_command_dispatch(
|
||||
// it never enters a V8InspectorSession or the ordinary target IO task FIFO.
|
||||
// Seal both DevTools receivers and interrupt active V8 synchronously so
|
||||
// target retirement cannot wait behind earlier JavaScript or IO work.
|
||||
if let Ok(page) = conn.loaded_page_mut_for_interruptible_protocol_access_for_route(
|
||||
session_id,
|
||||
owner.session_owner_route(),
|
||||
) {
|
||||
if let Ok(page) = conn.loaded_page_mut_for_interruptible_protocol_access_for_owner(owner) {
|
||||
page.crash_devtools_target_from_io();
|
||||
}
|
||||
|
||||
@@ -513,8 +497,7 @@ pub(super) async fn complete_crash_command_dispatch(
|
||||
// Page; otherwise a late completion from (for example) the primary
|
||||
// session can wait forever on a response sender owned by the retired
|
||||
// renderer while the crash was issued by an auxiliary session.
|
||||
let target_inspector_session_ids =
|
||||
conn.page_event_session_ids_for_route(session_id, owner.session_owner_route());
|
||||
let target_inspector_session_ids = conn.page_event_session_ids_for_owner(owner);
|
||||
let mut pending_await_events = Vec::new();
|
||||
for inspector_session_id in &target_inspector_session_ids {
|
||||
let inspector_owner = inspector_session_id
|
||||
@@ -566,26 +549,19 @@ async fn mark_page_target_crashed_background_events_async(
|
||||
owner: &CommandOwnerScope,
|
||||
target_id: &str,
|
||||
) -> Vec<BackgroundProtocolEvent> {
|
||||
let inspector_session_ids =
|
||||
conn.page_event_session_ids_for_route(owner.session_id(), owner.session_owner_route());
|
||||
let inspector_session_ids = conn.page_event_session_ids_for_owner(owner);
|
||||
for inspector_session_id in &inspector_session_ids {
|
||||
let inspector_owner = inspector_session_id
|
||||
.as_deref()
|
||||
.map(CommandOwnerScope::for_session)
|
||||
.unwrap_or_else(|| owner.clone());
|
||||
let _ = conn.with_target_devtools_session_state_for_route_mut(
|
||||
inspector_owner.session_id(),
|
||||
inspector_owner.session_owner_route(),
|
||||
|state| {
|
||||
state
|
||||
.runtime_session_state
|
||||
.record_inspector_target_crashed();
|
||||
},
|
||||
);
|
||||
let _ = conn.with_target_devtools_session_state_for_owner_mut(&inspector_owner, |state| {
|
||||
state
|
||||
.runtime_session_state
|
||||
.record_inspector_target_crashed();
|
||||
});
|
||||
}
|
||||
let _ = conn
|
||||
.mark_target_crashed_for_route_async(owner.session_id(), owner.session_owner_route())
|
||||
.await;
|
||||
let _ = conn.mark_target_crashed_for_owner_async(owner).await;
|
||||
let mut out = inspector_session_ids
|
||||
.into_iter()
|
||||
.map(|inspector_session_id| {
|
||||
@@ -615,9 +591,7 @@ pub(super) async fn complete_close_command_dispatch(
|
||||
) -> PageCommandTaskStep {
|
||||
let mut out = Vec::new();
|
||||
let session_id = owner.session_id();
|
||||
let Some((_, target_id)) =
|
||||
conn.target_owner_identity_for_route(session_id, owner.session_owner_route())
|
||||
else {
|
||||
let Some((_, target_id)) = conn.target_owner_identity_for_owner(owner) else {
|
||||
return PageCommandTaskStep::Complete(CommandOutputPlan::error_without_session(
|
||||
-31998,
|
||||
super::missing_page_target_error_message(conn, session_id),
|
||||
@@ -686,10 +660,7 @@ pub(crate) async fn complete_page_target_termination_owner_action_async(
|
||||
let (owner_scope, expected_target_id) = action.into_parts();
|
||||
let mut out = Vec::new();
|
||||
let current_target_id = conn
|
||||
.target_owner_identity_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.target_owner_identity_for_owner(&owner_scope)
|
||||
.and_then(|(_, target_id)| target_id);
|
||||
if current_target_id.as_deref() != Some(expected_target_id.as_str()) {
|
||||
return crate::conn::CdpTurnOutcome::new_with_protocol_events(
|
||||
|
||||
@@ -1575,7 +1575,9 @@ async fn runtime_document_close_emits_lifecycle_for_repeated_playwright_set_cont
|
||||
for iteration in 0..32 {
|
||||
let previous_document = ctx
|
||||
.conn
|
||||
.target_root_document_lifecycle_identity_for_route(Some("SID-1"), None)
|
||||
.target_root_document_lifecycle_identity_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
)
|
||||
.expect("the previous replacement must retain an exact Document identity");
|
||||
let id = 100 + iteration;
|
||||
ctx.process_async(json!({
|
||||
@@ -3679,13 +3681,18 @@ async fn screencast_commands_update_page_session_state() {
|
||||
assert_eq!(config.every_nth_frame(), 1);
|
||||
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.begin_page_screencast_capture_for_route(Some("SID-screencast"), None, 1),
|
||||
ctx.conn.begin_page_screencast_capture_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-screencast"),
|
||||
1
|
||||
),
|
||||
Some(true)
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.complete_page_screencast_capture_for_route(Some("SID-screencast"), None, 1, true,),
|
||||
ctx.conn.complete_page_screencast_capture_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-screencast"),
|
||||
1,
|
||||
true,
|
||||
),
|
||||
Some(true)
|
||||
);
|
||||
|
||||
@@ -4164,17 +4171,15 @@ async fn repeated_start_invalidates_old_screencast_ack_generation() {
|
||||
|
||||
let generation = i32::try_from(id - 62).expect("small screencast generation");
|
||||
assert_eq!(
|
||||
ctx.conn.begin_page_screencast_capture_for_route(
|
||||
Some("SID-screencast-generation"),
|
||||
None,
|
||||
ctx.conn.begin_page_screencast_capture_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-screencast-generation"),
|
||||
generation,
|
||||
),
|
||||
Some(true)
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn.complete_page_screencast_capture_for_route(
|
||||
Some("SID-screencast-generation"),
|
||||
None,
|
||||
ctx.conn.complete_page_screencast_capture_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-screencast-generation"),
|
||||
generation,
|
||||
true,
|
||||
),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::conn::{
|
||||
CdpConnection, CdpRendererCommandAccess, CdpSessionRoute, Cmd, CommandOwnerScope,
|
||||
PerformanceTimeDomain, RendererCommandCorrelation, RendererCommandDescriptor,
|
||||
monotonic_timestamp_seconds,
|
||||
CdpConnection, CdpRendererCommandAccess, Cmd, CommandOwnerScope, PerformanceTimeDomain,
|
||||
RendererCommandCorrelation, RendererCommandDescriptor, monotonic_timestamp_seconds,
|
||||
};
|
||||
use crate::domains::actions::PerformanceAction;
|
||||
use crate::domains::command_output::CommandOutputPlan;
|
||||
@@ -114,16 +113,16 @@ impl CompletedPerformanceCommandDispatch {
|
||||
|
||||
fn loaded_page_mut_for_renderer_access<'a>(
|
||||
conn: &'a mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
renderer_access: CdpRendererCommandAccess,
|
||||
owner_route: Option<&CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<&'a mut Page, String> {
|
||||
match renderer_access {
|
||||
CdpRendererCommandAccess::MainThread => {
|
||||
conn.loaded_page_mut_for_protocol_access_for_route(session_id, owner_route)
|
||||
conn.loaded_page_mut_for_protocol_access_for_owner(owner)
|
||||
}
|
||||
CdpRendererCommandAccess::Io => {
|
||||
conn.loaded_page_mut_for_interruptible_protocol_access_for_owner(owner)
|
||||
}
|
||||
CdpRendererCommandAccess::Io => conn
|
||||
.loaded_page_mut_for_interruptible_protocol_access_for_route(session_id, owner_route),
|
||||
CdpRendererCommandAccess::OwnerIndependent => {
|
||||
Err("Performance.getMetrics requires a renderer Page".to_owned())
|
||||
}
|
||||
@@ -236,19 +235,15 @@ pub(crate) fn try_start_performance_command_dispatch(
|
||||
let owner_scope = CommandOwnerScope::capture(conn, cmd.session_id);
|
||||
if renderer_access == CdpRendererCommandAccess::Io {
|
||||
let (renderer_page, attachment_id, snapshot) = {
|
||||
let page = match loaded_page_mut_for_renderer_access(
|
||||
conn,
|
||||
cmd.session_id,
|
||||
renderer_access,
|
||||
owner_scope.session_owner_route(),
|
||||
) {
|
||||
Ok(page) => page,
|
||||
Err(_) => {
|
||||
return PerformanceCommandTaskStep::Complete(
|
||||
default_metrics_command_output_plan(),
|
||||
);
|
||||
}
|
||||
};
|
||||
let page =
|
||||
match loaded_page_mut_for_renderer_access(conn, renderer_access, &owner_scope) {
|
||||
Ok(page) => page,
|
||||
Err(_) => {
|
||||
return PerformanceCommandTaskStep::Complete(
|
||||
default_metrics_command_output_plan(),
|
||||
);
|
||||
}
|
||||
};
|
||||
(
|
||||
crate::conn::RendererPageResidenceIdentity::from_page(page),
|
||||
page.renderer_agent_attachment_id(),
|
||||
@@ -261,13 +256,8 @@ pub(crate) fn try_start_performance_command_dispatch(
|
||||
if cmd.id.is_none()
|
||||
|| response_delivery == moli_page_types::RendererInspectorResponseDelivery::CommandReply
|
||||
{
|
||||
let page = loaded_page_mut_for_renderer_access(
|
||||
conn,
|
||||
cmd.session_id,
|
||||
renderer_access,
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.expect("the captured Performance Page must remain loaded synchronously");
|
||||
let page = loaded_page_mut_for_renderer_access(conn, renderer_access, &owner_scope)
|
||||
.expect("the captured Performance Page must remain loaded synchronously");
|
||||
let (pending, snapshot) = page.start_performance_metric_snapshot_from_io();
|
||||
return PerformanceCommandTaskStep::Pending(PendingPerformanceCommandDispatch {
|
||||
command_id: cmd.id,
|
||||
@@ -312,26 +302,21 @@ pub(crate) fn try_start_performance_command_dispatch(
|
||||
response_rx.is_none(),
|
||||
"Performance session output must not allocate a command-reply receiver",
|
||||
);
|
||||
let pending = loaded_page_mut_for_renderer_access(
|
||||
conn,
|
||||
cmd.session_id,
|
||||
renderer_access,
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.ok()
|
||||
.filter(|page| {
|
||||
crate::conn::RendererPageResidenceIdentity::from_page(page) == renderer_page
|
||||
&& page.renderer_agent_attachment_id() == Some(attachment_id)
|
||||
})
|
||||
.ok_or_else(|| "Performance renderer attachment changed before IO dispatch".to_owned())
|
||||
.and_then(|page| {
|
||||
page.start_performance_get_metrics_from_io_with_response(
|
||||
renderer_inspector_session_id,
|
||||
result,
|
||||
response,
|
||||
)
|
||||
.map_err(|error| error.to_string())
|
||||
});
|
||||
let pending = loaded_page_mut_for_renderer_access(conn, renderer_access, &owner_scope)
|
||||
.ok()
|
||||
.filter(|page| {
|
||||
crate::conn::RendererPageResidenceIdentity::from_page(page) == renderer_page
|
||||
&& page.renderer_agent_attachment_id() == Some(attachment_id)
|
||||
})
|
||||
.ok_or_else(|| "Performance renderer attachment changed before IO dispatch".to_owned())
|
||||
.and_then(|page| {
|
||||
page.start_performance_get_metrics_from_io_with_response(
|
||||
renderer_inspector_session_id,
|
||||
result,
|
||||
response,
|
||||
)
|
||||
.map_err(|error| error.to_string())
|
||||
});
|
||||
let pending = match pending {
|
||||
Ok(pending) => pending,
|
||||
Err(error) => {
|
||||
@@ -356,12 +341,7 @@ pub(crate) fn try_start_performance_command_dispatch(
|
||||
}),
|
||||
});
|
||||
}
|
||||
let page = match loaded_page_mut_for_renderer_access(
|
||||
conn,
|
||||
cmd.session_id,
|
||||
renderer_access,
|
||||
owner_scope.session_owner_route(),
|
||||
) {
|
||||
let page = match loaded_page_mut_for_renderer_access(conn, renderer_access, &owner_scope) {
|
||||
Ok(page) => page,
|
||||
Err(_) => {
|
||||
return PerformanceCommandTaskStep::Complete(default_metrics_command_output_plan());
|
||||
@@ -412,33 +392,23 @@ pub(crate) async fn complete_pending_performance_command(
|
||||
renderer_page,
|
||||
completed,
|
||||
} = completed;
|
||||
let session_id = owner_scope.session_id().map(str::to_owned);
|
||||
let snapshot = match completed {
|
||||
Ok(CompletedPerformanceRendererCommand::Main(completed_page)) => {
|
||||
loaded_page_mut_for_renderer_access(
|
||||
conn,
|
||||
session_id.as_deref(),
|
||||
renderer_access,
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.ok()
|
||||
.filter(|page| {
|
||||
crate::conn::RendererPageResidenceIdentity::from_page(page) == renderer_page
|
||||
})
|
||||
.and_then(|page| page.finish_performance_metric_snapshot(completed_page).ok())
|
||||
.unwrap_or_default()
|
||||
loaded_page_mut_for_renderer_access(conn, renderer_access, &owner_scope)
|
||||
.ok()
|
||||
.filter(|page| {
|
||||
crate::conn::RendererPageResidenceIdentity::from_page(page) == renderer_page
|
||||
})
|
||||
.and_then(|page| page.finish_performance_metric_snapshot(completed_page).ok())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
Ok(CompletedPerformanceRendererCommand::IoCommandReply(snapshot)) => {
|
||||
let remains_current = loaded_page_mut_for_renderer_access(
|
||||
conn,
|
||||
session_id.as_deref(),
|
||||
renderer_access,
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.ok()
|
||||
.is_some_and(|page| {
|
||||
crate::conn::RendererPageResidenceIdentity::from_page(page) == renderer_page
|
||||
});
|
||||
let remains_current =
|
||||
loaded_page_mut_for_renderer_access(conn, renderer_access, &owner_scope)
|
||||
.ok()
|
||||
.is_some_and(|page| {
|
||||
crate::conn::RendererPageResidenceIdentity::from_page(page) == renderer_page
|
||||
});
|
||||
if remains_current {
|
||||
snapshot
|
||||
} else {
|
||||
@@ -456,11 +426,8 @@ pub(crate) async fn complete_pending_performance_command(
|
||||
plan.set_renderer_output_predecessor(predecessor);
|
||||
return plan;
|
||||
}
|
||||
if !conn.take_renderer_call_if_correlation_matches_for_route(
|
||||
session_id.as_deref(),
|
||||
owner_scope.session_owner_route(),
|
||||
correlation,
|
||||
) {
|
||||
if !conn.take_renderer_call_if_correlation_matches_for_owner(&owner_scope, correlation)
|
||||
{
|
||||
return CommandOutputPlan::default();
|
||||
}
|
||||
RendererPerformanceMetricSnapshot::default()
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::domains::activity::{
|
||||
ProtocolOutputPayloads, ProtocolOutputProjectionContext, ProtocolOutputSink, ProtocolOutputSlot,
|
||||
};
|
||||
use crate::{
|
||||
conn::{BackgroundProtocolEvent, CdpConnection, CommandOwnerScope},
|
||||
conn::{BackgroundProtocolEvent, CdpConnection, CdpSessionRoute, CommandOwnerScope},
|
||||
domains::command_output::protocol_message_background_event_for_target,
|
||||
domains::runtime_context_events::{
|
||||
RuntimeContextProtocolEvent, apply_runtime_context_protocol_event_side_effects_typed,
|
||||
@@ -57,18 +57,19 @@ struct RuntimeInspectorMessageBatch {
|
||||
|
||||
/// Projection authority for one prepared Inspector batch.
|
||||
///
|
||||
/// Ordinary observations remain tied to the exact Page attachment that
|
||||
/// produced them. A retired terminal response is a distinct state rather than
|
||||
/// an absent attachment: its exact renderer correlation was already consumed
|
||||
/// at ingress, and no notification or renderer state can inhabit this variant.
|
||||
/// Document and Worker observations remain tied to their concrete attachment.
|
||||
/// Terminal responses instead belong to the DevTools session that registered
|
||||
/// their renderer call. This mirrors Chromium's browser-side call-id journal:
|
||||
/// replacing a document does not invalidate a response which already won that
|
||||
/// session correlation, but it never authorizes observations from the retired
|
||||
/// document.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
enum RuntimeInspectorMessageAuthority {
|
||||
CurrentPage(crate::conn::TargetPageProtocolAttachmentIdentity),
|
||||
CurrentWorker(crate::conn::TargetWorkerProtocolAttachmentIdentity),
|
||||
AuthorizedRetiredTerminal {
|
||||
browser_context_id: String,
|
||||
target_id: Option<String>,
|
||||
session_id: Option<String>,
|
||||
SessionResponse {
|
||||
owner: CommandOwnerScope,
|
||||
expected_route: CdpSessionRoute,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -77,7 +78,7 @@ impl RuntimeInspectorMessageAuthority {
|
||||
match self {
|
||||
Self::CurrentPage(attachment) => attachment.session_id(),
|
||||
Self::CurrentWorker(attachment) => Some(attachment.session_id()),
|
||||
Self::AuthorizedRetiredTerminal { session_id, .. } => session_id.as_deref(),
|
||||
Self::SessionResponse { owner, .. } => owner.session_id(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,34 +88,22 @@ impl RuntimeInspectorMessageAuthority {
|
||||
conn.target_page_protocol_attachment_identity_is_current(attachment)
|
||||
}
|
||||
Self::CurrentWorker(attachment) => attachment.is_current(),
|
||||
Self::AuthorizedRetiredTerminal {
|
||||
browser_context_id,
|
||||
target_id,
|
||||
session_id,
|
||||
} => {
|
||||
let Some((current_browser_context_id, current_target_id)) =
|
||||
conn.target_owner_identity_for_session(session_id.as_deref())
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
let current_target_id = current_target_id.or_else(|| {
|
||||
conn.browser_context_by_id(¤t_browser_context_id)
|
||||
.and_then(|context| context.active_target_id_owned())
|
||||
});
|
||||
current_browser_context_id == *browser_context_id && current_target_id == *target_id
|
||||
}
|
||||
Self::SessionResponse {
|
||||
owner,
|
||||
expected_route,
|
||||
} => owner.resolve_route(conn).as_ref() == Some(expected_route),
|
||||
}
|
||||
}
|
||||
|
||||
fn command_owner(&self) -> Option<crate::conn::CommandOwnerScope> {
|
||||
fn command_owner(&self) -> crate::conn::CommandOwnerScope {
|
||||
match self {
|
||||
Self::CurrentPage(attachment) => Some(
|
||||
crate::conn::CommandOwnerScope::for_page_attachment(attachment),
|
||||
),
|
||||
Self::CurrentWorker(attachment) => {
|
||||
Some(CommandOwnerScope::for_session(attachment.session_id()))
|
||||
Self::CurrentPage(attachment) => {
|
||||
crate::conn::CommandOwnerScope::for_page_attachment(attachment)
|
||||
}
|
||||
Self::AuthorizedRetiredTerminal { .. } => None,
|
||||
Self::CurrentWorker(attachment) => {
|
||||
CommandOwnerScope::for_session(attachment.session_id())
|
||||
}
|
||||
Self::SessionResponse { owner, .. } => owner.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,13 +207,10 @@ impl RuntimeOutputProjectionStep {
|
||||
session_id.as_deref(),
|
||||
);
|
||||
for execution_context_id in batch.created_execution_context_ids {
|
||||
let Some(owner) = owner.as_ref() else {
|
||||
continue;
|
||||
};
|
||||
Box::pin(
|
||||
super::start_bidi_preload_channel_listeners_for_execution_context_background_events_async(
|
||||
conn,
|
||||
owner,
|
||||
&owner,
|
||||
execution_context_id,
|
||||
context.command.protocol_events_mut(),
|
||||
),
|
||||
@@ -269,15 +255,49 @@ pub(in crate::domains) async fn project_runtime_inspector_post_response_messages
|
||||
}
|
||||
|
||||
impl RuntimePreparedOutputs {
|
||||
fn append_inspector_message(
|
||||
&mut self,
|
||||
order: RendererRuntimeInspectorMessageResponseOrder,
|
||||
authority: RuntimeInspectorMessageAuthority,
|
||||
message: RuntimeInspectorMessage,
|
||||
) {
|
||||
let batches = match order {
|
||||
RendererRuntimeInspectorMessageResponseOrder::BeforeCommandResponse => {
|
||||
&mut self.inspector_message_batches
|
||||
}
|
||||
RendererRuntimeInspectorMessageResponseOrder::AfterCommandResponse => {
|
||||
&mut self.post_response_inspector_message_batches
|
||||
}
|
||||
};
|
||||
let created_execution_context_id = message.created_execution_context_id();
|
||||
if let Some(last) = batches.last_mut()
|
||||
&& last.authority == authority
|
||||
{
|
||||
last.messages.push(message);
|
||||
if let Some(execution_context_id) = created_execution_context_id
|
||||
&& !last
|
||||
.created_execution_context_ids
|
||||
.contains(&execution_context_id)
|
||||
{
|
||||
last.created_execution_context_ids
|
||||
.push(execution_context_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
batches.push(RuntimeInspectorMessageBatch {
|
||||
authority,
|
||||
messages: vec![message],
|
||||
created_execution_context_ids: created_execution_context_id.into_iter().collect(),
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn from_renderer_runtime_binding_call(
|
||||
conn: &CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
call: moli_core::page::PendingRuntimeBindingCall,
|
||||
) -> Self {
|
||||
let Some(attachment) = conn.target_page_protocol_attachment_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
) else {
|
||||
let Some(attachment) = conn.target_page_protocol_attachment_identity_for_owner(owner)
|
||||
else {
|
||||
return Self::default();
|
||||
};
|
||||
Self {
|
||||
@@ -292,13 +312,26 @@ impl RuntimePreparedOutputs {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_renderer_runtime_inspector_message_batches(
|
||||
pub(crate) fn from_page_renderer_runtime_inspector_message_batches(
|
||||
conn: &mut CdpConnection,
|
||||
source_owner: &CommandOwnerScope,
|
||||
batches: &[RendererRuntimeInspectorMessageBatch],
|
||||
source_batches: Vec<RendererRuntimeInspectorMessageBatch>,
|
||||
) -> Self {
|
||||
let current_batches = conn.route_current_renderer_inspector_output_for_owner(
|
||||
source_owner,
|
||||
source_batches.clone(),
|
||||
);
|
||||
let observations_are_current = !current_batches.is_empty();
|
||||
let batches = if observations_are_current {
|
||||
current_batches
|
||||
} else {
|
||||
source_batches
|
||||
};
|
||||
let mut outputs = Self::default();
|
||||
for batch in batches.iter().filter(|batch| !batch.messages.is_empty()) {
|
||||
for batch in batches
|
||||
.into_iter()
|
||||
.filter(|batch| !batch.messages.is_empty())
|
||||
{
|
||||
let Some(attachment) = conn
|
||||
.target_page_protocol_attachment_identity_for_renderer_inspector_owner(
|
||||
source_owner,
|
||||
@@ -307,47 +340,53 @@ impl RuntimePreparedOutputs {
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let mut renderer_messages = batch.messages.clone();
|
||||
if let Some(renderer_agent_attachment_id) = batch.renderer_agent_attachment_id() {
|
||||
conn.restore_frontend_command_ids_in_devtools_session_output(
|
||||
attachment.session_id(),
|
||||
renderer_agent_attachment_id,
|
||||
&mut renderer_messages,
|
||||
let response_owner = CommandOwnerScope::for_page_attachment(&attachment);
|
||||
let response_route = response_owner.resolve_route(conn);
|
||||
let renderer_agent_attachment_id = batch.renderer_agent_attachment_id();
|
||||
let order = batch.command_response_order();
|
||||
for message in batch.messages {
|
||||
let is_terminal_response = matches!(
|
||||
&message,
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.renderer_call_id().is_some()
|
||||
);
|
||||
}
|
||||
if renderer_messages.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let messages = renderer_messages
|
||||
.into_iter()
|
||||
.map(|message| {
|
||||
RuntimeInspectorMessage::from_renderer_message(
|
||||
message,
|
||||
attachment.page_owner().target_id(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let mut created_execution_context_ids = Vec::new();
|
||||
for execution_context_id in messages
|
||||
.iter()
|
||||
.filter_map(RuntimeInspectorMessage::created_execution_context_id)
|
||||
{
|
||||
if !created_execution_context_ids.contains(&execution_context_id) {
|
||||
created_execution_context_ids.push(execution_context_id);
|
||||
if is_terminal_response {
|
||||
let Some(expected_route) = response_route.clone() else {
|
||||
continue;
|
||||
};
|
||||
let mut response = vec![message];
|
||||
conn.restore_frontend_command_ids_in_devtools_session_output_for_owner(
|
||||
&response_owner,
|
||||
renderer_agent_attachment_id,
|
||||
&mut response,
|
||||
observations_are_current,
|
||||
);
|
||||
let Some(response) = response.pop() else {
|
||||
continue;
|
||||
};
|
||||
outputs.append_inspector_message(
|
||||
order,
|
||||
RuntimeInspectorMessageAuthority::SessionResponse {
|
||||
owner: response_owner.clone(),
|
||||
expected_route,
|
||||
},
|
||||
RuntimeInspectorMessage::from_renderer_message(
|
||||
response,
|
||||
attachment.page_owner().target_id(),
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let prepared = RuntimeInspectorMessageBatch {
|
||||
authority: RuntimeInspectorMessageAuthority::CurrentPage(attachment),
|
||||
messages,
|
||||
created_execution_context_ids,
|
||||
};
|
||||
match batch.command_response_order() {
|
||||
RendererRuntimeInspectorMessageResponseOrder::BeforeCommandResponse => {
|
||||
outputs.inspector_message_batches.push(prepared);
|
||||
if observations_are_current {
|
||||
outputs.append_inspector_message(
|
||||
order,
|
||||
RuntimeInspectorMessageAuthority::CurrentPage(attachment.clone()),
|
||||
RuntimeInspectorMessage::from_renderer_message(
|
||||
message,
|
||||
attachment.page_owner().target_id(),
|
||||
),
|
||||
);
|
||||
}
|
||||
RendererRuntimeInspectorMessageResponseOrder::AfterCommandResponse => outputs
|
||||
.post_response_inspector_message_batches
|
||||
.push(prepared),
|
||||
}
|
||||
}
|
||||
outputs
|
||||
@@ -366,122 +405,45 @@ impl RuntimePreparedOutputs {
|
||||
else {
|
||||
return Self::default();
|
||||
};
|
||||
let mut renderer_messages = batch.messages.clone();
|
||||
conn.restore_frontend_command_ids_in_worker_devtools_session_output(
|
||||
session_id,
|
||||
&mut renderer_messages,
|
||||
);
|
||||
if renderer_messages.is_empty() {
|
||||
let response_owner = CommandOwnerScope::for_session(session_id);
|
||||
let Some(response_route) = response_owner.resolve_route(conn) else {
|
||||
return Self::default();
|
||||
}
|
||||
let target_id = attachment.target_id().to_owned();
|
||||
let prepared = RuntimeInspectorMessageBatch {
|
||||
authority: RuntimeInspectorMessageAuthority::CurrentWorker(attachment),
|
||||
messages: renderer_messages
|
||||
.into_iter()
|
||||
.map(|message| {
|
||||
RuntimeInspectorMessage::from_renderer_message(message, Some(&target_id))
|
||||
})
|
||||
.collect(),
|
||||
// Worker contexts never own Page/BiDi preload-channel listeners.
|
||||
created_execution_context_ids: Vec::new(),
|
||||
};
|
||||
let target_id = attachment.target_id().to_owned();
|
||||
let mut outputs = Self::default();
|
||||
match batch.command_response_order() {
|
||||
RendererRuntimeInspectorMessageResponseOrder::BeforeCommandResponse => {
|
||||
outputs.inspector_message_batches.push(prepared);
|
||||
}
|
||||
RendererRuntimeInspectorMessageResponseOrder::AfterCommandResponse => {
|
||||
outputs
|
||||
.post_response_inspector_message_batches
|
||||
.push(prepared);
|
||||
}
|
||||
}
|
||||
outputs
|
||||
}
|
||||
|
||||
/// Preserves only terminal session responses from an attachment that was
|
||||
/// current when the response lease was claimed but retired before its Page
|
||||
/// journal crossed protocol ingress.
|
||||
///
|
||||
/// The exact renderer correlation is consumed here. This makes the
|
||||
/// resulting response an already-authorized session fact, while all
|
||||
/// notifications, context events, V8 state, and remote-object projection
|
||||
/// from the retired document are discarded.
|
||||
pub(crate) fn from_retired_renderer_runtime_inspector_session_responses(
|
||||
conn: &mut CdpConnection,
|
||||
source_owner: &CommandOwnerScope,
|
||||
batches: &[RendererRuntimeInspectorMessageBatch],
|
||||
) -> Self {
|
||||
let mut outputs = Self::default();
|
||||
for batch in batches {
|
||||
let Some(renderer_agent_attachment_id) = batch.renderer_agent_attachment_id() else {
|
||||
continue;
|
||||
};
|
||||
let Some(protocol_attachment) = conn
|
||||
.target_page_protocol_attachment_identity_for_renderer_inspector_owner(
|
||||
source_owner,
|
||||
batch.session.wire_session_id(),
|
||||
)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let session_id = protocol_attachment.session_id().map(str::to_owned);
|
||||
if conn.renderer_agent_attachment_is_current_for_session_owner(
|
||||
session_id.as_deref(),
|
||||
renderer_agent_attachment_id,
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut responses = batch
|
||||
.messages
|
||||
.iter()
|
||||
.filter(|message| {
|
||||
matches!(
|
||||
message,
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.renderer_call_id().is_some()
|
||||
)
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
conn.restore_frontend_command_ids_in_retired_devtools_session_output(
|
||||
session_id.as_deref(),
|
||||
renderer_agent_attachment_id,
|
||||
&mut responses,
|
||||
let order = batch.command_response_order();
|
||||
for message in batch.messages.clone() {
|
||||
let is_terminal_response = matches!(
|
||||
&message,
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.renderer_call_id().is_some()
|
||||
);
|
||||
if responses.is_empty() {
|
||||
if is_terminal_response {
|
||||
let mut response = vec![message];
|
||||
conn.restore_frontend_command_ids_in_devtools_session_output_for_owner(
|
||||
&response_owner,
|
||||
None,
|
||||
&mut response,
|
||||
true,
|
||||
);
|
||||
let Some(response) = response.pop() else {
|
||||
continue;
|
||||
};
|
||||
outputs.append_inspector_message(
|
||||
order,
|
||||
RuntimeInspectorMessageAuthority::SessionResponse {
|
||||
owner: response_owner.clone(),
|
||||
expected_route: response_route.clone(),
|
||||
},
|
||||
RuntimeInspectorMessage::from_renderer_message(response, Some(&target_id)),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
let target_id = protocol_attachment.page_owner().target_id();
|
||||
let messages = responses
|
||||
.into_iter()
|
||||
.map(|message| RuntimeInspectorMessage::from_renderer_message(message, target_id))
|
||||
.collect();
|
||||
let prepared = RuntimeInspectorMessageBatch {
|
||||
authority: RuntimeInspectorMessageAuthority::AuthorizedRetiredTerminal {
|
||||
browser_context_id: protocol_attachment
|
||||
.page_owner()
|
||||
.browser_context_id()
|
||||
.to_owned(),
|
||||
target_id: protocol_attachment
|
||||
.page_owner()
|
||||
.target_id()
|
||||
.map(str::to_owned),
|
||||
session_id,
|
||||
},
|
||||
messages,
|
||||
created_execution_context_ids: Vec::new(),
|
||||
};
|
||||
match batch.command_response_order() {
|
||||
RendererRuntimeInspectorMessageResponseOrder::BeforeCommandResponse => {
|
||||
outputs.inspector_message_batches.push(prepared);
|
||||
}
|
||||
RendererRuntimeInspectorMessageResponseOrder::AfterCommandResponse => outputs
|
||||
.post_response_inspector_message_batches
|
||||
.push(prepared),
|
||||
}
|
||||
outputs.append_inspector_message(
|
||||
order,
|
||||
RuntimeInspectorMessageAuthority::CurrentWorker(attachment.clone()),
|
||||
RuntimeInspectorMessage::from_renderer_message(message, Some(&target_id)),
|
||||
);
|
||||
}
|
||||
outputs
|
||||
}
|
||||
@@ -594,8 +556,8 @@ pub(in crate::domains) fn push_routed_renderer_runtime_inspector_message_batch_b
|
||||
Some(session_id) => CommandOwnerScope::for_session(session_id),
|
||||
None => CommandOwnerScope::capture(conn, None),
|
||||
};
|
||||
let prepared = RuntimePreparedOutputs::from_renderer_runtime_inspector_message_batches(
|
||||
conn, &owner, &batches,
|
||||
let prepared = RuntimePreparedOutputs::from_page_renderer_runtime_inspector_message_batches(
|
||||
conn, &owner, batches,
|
||||
);
|
||||
for batch in prepared
|
||||
.inspector_message_batches
|
||||
@@ -618,8 +580,8 @@ pub(in crate::domains) fn push_routed_renderer_runtime_inspector_message_batch_b
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use moli_core::page::{
|
||||
DevToolsSessionKey, RendererAgentAttachmentId, RendererDevToolsAgentToken,
|
||||
RendererRuntimeInspectorMessage, RendererRuntimeInspectorMessageBatch,
|
||||
DevToolsSessionKey, RendererAgentAttachmentId, RendererRuntimeInspectorMessage,
|
||||
RendererRuntimeInspectorMessageBatch,
|
||||
};
|
||||
use moli_page_types::RendererInspectorResponseDelivery;
|
||||
use serde_json::Value;
|
||||
@@ -732,20 +694,33 @@ mod tests {
|
||||
.map_or(DevToolsSessionKey::Primary, |session_id| {
|
||||
DevToolsSessionKey::Attached(session_id.to_owned())
|
||||
});
|
||||
let agent_token = conn
|
||||
.runtime_session_owner_slot_for_owner(&owner)
|
||||
.expect("runtime owner slot")
|
||||
.current_renderer_attachment()
|
||||
.expect("current renderer attachment")
|
||||
.agent_token();
|
||||
let batches = vec![RendererRuntimeInspectorMessageBatch::new(
|
||||
RendererDevToolsAgentToken::allocate(),
|
||||
agent_token,
|
||||
session,
|
||||
renderer_messages(messages),
|
||||
)];
|
||||
RuntimePreparedOutputs::from_renderer_runtime_inspector_message_batches(
|
||||
conn, &owner, &batches,
|
||||
RuntimePreparedOutputs::from_page_renderer_runtime_inspector_message_batches(
|
||||
conn, &owner, batches,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn renderer_inspector_batches_keep_their_command_response_side() {
|
||||
let (mut conn, _) = runtime_binding_attachment_fixture();
|
||||
let agent_token = RendererDevToolsAgentToken::allocate();
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn renderer_inspector_batches_keep_their_command_response_side() {
|
||||
let mut ctx = TestContext::new();
|
||||
load_document(&mut ctx, "<!doctype html><main>batch order</main>").await;
|
||||
let agent_token = ctx
|
||||
.conn
|
||||
.runtime_session_owner_slot(Some("SID-1"))
|
||||
.expect("runtime owner slot")
|
||||
.current_renderer_attachment()
|
||||
.expect("current renderer attachment")
|
||||
.agent_token();
|
||||
let session = DevToolsSessionKey::Primary;
|
||||
let batches = vec![
|
||||
RendererRuntimeInspectorMessageBatch::new(
|
||||
@@ -766,10 +741,10 @@ mod tests {
|
||||
),
|
||||
];
|
||||
|
||||
let outputs = RuntimePreparedOutputs::from_renderer_runtime_inspector_message_batches(
|
||||
&mut conn,
|
||||
let outputs = RuntimePreparedOutputs::from_page_renderer_runtime_inspector_message_batches(
|
||||
&mut ctx.conn,
|
||||
&CommandOwnerScope::for_session("SID-1"),
|
||||
&batches,
|
||||
batches,
|
||||
);
|
||||
|
||||
assert_eq!(outputs.inspector_message_batches.len(), 1);
|
||||
@@ -857,12 +832,11 @@ mod tests {
|
||||
);
|
||||
batch.bind_renderer_agent_attachment(retired_attachment);
|
||||
|
||||
let outputs =
|
||||
RuntimePreparedOutputs::from_retired_renderer_runtime_inspector_session_responses(
|
||||
&mut ctx.conn,
|
||||
&CommandOwnerScope::for_session("SID-1"),
|
||||
&[batch],
|
||||
);
|
||||
let outputs = RuntimePreparedOutputs::from_page_renderer_runtime_inspector_message_batches(
|
||||
&mut ctx.conn,
|
||||
&CommandOwnerScope::for_session("SID-1"),
|
||||
vec![batch],
|
||||
);
|
||||
let outputs_after_detach = outputs.clone();
|
||||
let events = drain_runtime_inspector_outputs(&mut ctx.conn, outputs, None)
|
||||
.await
|
||||
@@ -1047,9 +1021,10 @@ mod tests {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn runtime_inspector_activity_uses_capture_time_attachment() {
|
||||
let (mut conn, _attachment) = runtime_binding_attachment_fixture();
|
||||
let mut ctx = TestContext::new();
|
||||
load_document(&mut ctx, "<!doctype html><main>capture</main>").await;
|
||||
let outputs = renderer_inspector_outputs(
|
||||
&mut conn,
|
||||
&mut ctx.conn,
|
||||
Some("SID-1"),
|
||||
None,
|
||||
vec![json!({
|
||||
@@ -1062,7 +1037,8 @@ mod tests {
|
||||
})],
|
||||
);
|
||||
let events =
|
||||
drain_runtime_inspector_outputs(&mut conn, outputs, Some("SID-unrelated-drain")).await;
|
||||
drain_runtime_inspector_outputs(&mut ctx.conn, outputs, Some("SID-unrelated-drain"))
|
||||
.await;
|
||||
|
||||
assert_eq!(events.len(), 1);
|
||||
let (message, automation_event) = events.into_iter().next().unwrap().into_parts();
|
||||
@@ -1083,20 +1059,22 @@ mod tests {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn runtime_inspector_activity_discards_replaced_page_output() {
|
||||
let (mut conn, _attachment) = runtime_binding_attachment_fixture();
|
||||
let mut ctx = TestContext::new();
|
||||
load_document(&mut ctx, "<!doctype html><main>old</main>").await;
|
||||
let outputs = renderer_inspector_outputs(
|
||||
&mut conn,
|
||||
&mut ctx.conn,
|
||||
Some("SID-1"),
|
||||
None,
|
||||
vec![json!({
|
||||
"id": 91,
|
||||
"result": { "value": "old-page-response" }
|
||||
"method": "Debugger.scriptParsed",
|
||||
"params": { "scriptId": "old-page" }
|
||||
})],
|
||||
);
|
||||
conn.runtime_session_owner_slot_mut(Some("SID-1"))
|
||||
ctx.conn
|
||||
.runtime_session_owner_slot_mut(Some("SID-1"))
|
||||
.expect("Runtime inspector target")
|
||||
.replace_page_attachment_id_for_test();
|
||||
let events = drain_runtime_inspector_outputs(&mut conn, outputs, Some("SID-1")).await;
|
||||
let events = drain_runtime_inspector_outputs(&mut ctx.conn, outputs, Some("SID-1")).await;
|
||||
|
||||
assert!(
|
||||
events.is_empty(),
|
||||
@@ -1106,9 +1084,10 @@ mod tests {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn runtime_inspector_activity_discards_detached_attachment() {
|
||||
let (mut conn, _attachment) = runtime_binding_attachment_fixture();
|
||||
let mut ctx = TestContext::new();
|
||||
load_document(&mut ctx, "<!doctype html><main>detach</main>").await;
|
||||
let outputs = renderer_inspector_outputs(
|
||||
&mut conn,
|
||||
&mut ctx.conn,
|
||||
Some("SID-1"),
|
||||
None,
|
||||
vec![json!({
|
||||
@@ -1117,14 +1096,15 @@ mod tests {
|
||||
})],
|
||||
);
|
||||
assert_eq!(
|
||||
conn.browser_context
|
||||
ctx.conn
|
||||
.browser_context
|
||||
.as_mut()
|
||||
.expect("browser context")
|
||||
.detach_active_session()
|
||||
.as_deref(),
|
||||
Some("SID-1"),
|
||||
);
|
||||
let events = drain_runtime_inspector_outputs(&mut conn, outputs, None).await;
|
||||
let events = drain_runtime_inspector_outputs(&mut ctx.conn, outputs, None).await;
|
||||
|
||||
assert!(
|
||||
events.is_empty(),
|
||||
@@ -1133,73 +1113,76 @@ mod tests {
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn runtime_inspector_activity_preserves_auxiliary_renderer_route() {
|
||||
let (mut conn, _attachment) = runtime_binding_attachment_fixture();
|
||||
async fn runtime_inspector_activity_preserves_attached_renderer_route() {
|
||||
let mut ctx = TestContext::new();
|
||||
load_document(&mut ctx, "<!doctype html><main>attached</main>").await;
|
||||
assert!(
|
||||
conn.browser_context
|
||||
ctx.conn
|
||||
.browser_context
|
||||
.as_mut()
|
||||
.expect("browser context")
|
||||
.assign_auxiliary_session_to_target("TID-1", "SID-aux".to_owned())
|
||||
);
|
||||
let outputs = renderer_inspector_outputs(
|
||||
&mut conn,
|
||||
&mut ctx.conn,
|
||||
Some("SID-1"),
|
||||
Some("SID-aux"),
|
||||
vec![json!({
|
||||
"id": 92,
|
||||
"result": { "value": "auxiliary-response" }
|
||||
"method": "Debugger.scriptParsed",
|
||||
"params": { "scriptId": "attached-session" }
|
||||
})],
|
||||
);
|
||||
let events = drain_runtime_inspector_outputs(&mut conn, outputs, Some("SID-1"))
|
||||
let events = drain_runtime_inspector_outputs(&mut ctx.conn, outputs, Some("SID-1"))
|
||||
.await
|
||||
.into_iter()
|
||||
.map(crate::conn::BackgroundProtocolEvent::into_protocol_message)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(events.len(), 1);
|
||||
assert_eq!(events[0]["id"], json!(92));
|
||||
assert_eq!(events[0]["method"], json!("Debugger.scriptParsed"));
|
||||
assert_eq!(
|
||||
events[0]["sessionId"],
|
||||
json!("SID-aux"),
|
||||
"an auxiliary renderer inspector batch must retain its own attachment instead of following the source or drain session"
|
||||
"an attached renderer inspector batch must retain its own session instead of following the source or drain session"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn runtime_inspector_activity_authorizes_each_page_batch_independently() {
|
||||
let (mut conn, _attachment) = runtime_binding_attachment_fixture();
|
||||
let mut ctx = TestContext::new();
|
||||
load_document(&mut ctx, "<!doctype html><main>first</main>").await;
|
||||
let mut outputs = renderer_inspector_outputs(
|
||||
&mut conn,
|
||||
&mut ctx.conn,
|
||||
Some("SID-1"),
|
||||
None,
|
||||
vec![json!({
|
||||
"id": 93,
|
||||
"result": { "value": "old-page" }
|
||||
"method": "Debugger.scriptParsed",
|
||||
"params": { "scriptId": "old-page" }
|
||||
})],
|
||||
);
|
||||
conn.runtime_session_owner_slot_mut(Some("SID-1"))
|
||||
ctx.conn
|
||||
.runtime_session_owner_slot_mut(Some("SID-1"))
|
||||
.expect("Runtime inspector target")
|
||||
.replace_page_attachment_id_for_test();
|
||||
outputs.extend(renderer_inspector_outputs(
|
||||
&mut conn,
|
||||
&mut ctx.conn,
|
||||
Some("SID-1"),
|
||||
None,
|
||||
vec![json!({
|
||||
"id": 94,
|
||||
"result": { "value": "replacement-page" }
|
||||
"method": "Debugger.scriptParsed",
|
||||
"params": { "scriptId": "replacement-page" }
|
||||
})],
|
||||
));
|
||||
let events =
|
||||
drain_runtime_inspector_outputs(&mut conn, outputs, Some("SID-unrelated-drain"))
|
||||
drain_runtime_inspector_outputs(&mut ctx.conn, outputs, Some("SID-unrelated-drain"))
|
||||
.await
|
||||
.into_iter()
|
||||
.map(crate::conn::BackgroundProtocolEvent::into_protocol_message)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(events.len(), 1);
|
||||
assert_eq!(events[0]["id"], json!(94));
|
||||
assert_eq!(
|
||||
events[0]["result"]["value"],
|
||||
events[0]["params"]["scriptId"],
|
||||
json!("replacement-page"),
|
||||
"one captured slot must validate each capture-time Page attachment instead of authorizing the whole slot from projection context"
|
||||
);
|
||||
|
||||
@@ -18,11 +18,9 @@ pub(super) fn persist_runtime_binding_definition_for_owner(
|
||||
name: String,
|
||||
execution_context_name: Option<String>,
|
||||
) -> Result<(), String> {
|
||||
conn.with_target_devtools_session_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|state| state.upsert_runtime_binding_definition(name, execution_context_name),
|
||||
)
|
||||
conn.with_target_devtools_session_state_for_owner_mut(owner, |state| {
|
||||
state.upsert_runtime_binding_definition(name, execution_context_name)
|
||||
})
|
||||
.ok_or_else(|| "BrowserContextNotLoaded".to_owned())
|
||||
}
|
||||
|
||||
@@ -31,11 +29,9 @@ pub(super) fn remove_runtime_binding_definitions_for_owner(
|
||||
owner: &CommandOwnerScope,
|
||||
name: &str,
|
||||
) -> Result<(), String> {
|
||||
conn.with_target_devtools_session_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|state| state.remove_runtime_binding_definitions(name),
|
||||
)
|
||||
conn.with_target_devtools_session_state_for_owner_mut(owner, |state| {
|
||||
state.remove_runtime_binding_definitions(name)
|
||||
})
|
||||
.ok_or_else(|| "BrowserContextNotLoaded".to_owned())
|
||||
}
|
||||
|
||||
@@ -43,10 +39,8 @@ pub(super) fn clear_runtime_binding_definitions_for_owner(
|
||||
conn: &mut CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<(), String> {
|
||||
conn.with_target_devtools_session_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|state| state.clear_runtime_binding_definitions(),
|
||||
)
|
||||
conn.with_target_devtools_session_state_for_owner_mut(owner, |state| {
|
||||
state.clear_runtime_binding_definitions()
|
||||
})
|
||||
.ok_or_else(|| "BrowserContextNotLoaded".to_owned())
|
||||
}
|
||||
|
||||
@@ -480,6 +480,9 @@ struct RuntimeBindingCommandTask {
|
||||
execution_context_id: Option<i64>,
|
||||
inspector_json: Option<String>,
|
||||
command_response: Option<RuntimeBindingCommandResponse>,
|
||||
response_delivery: RendererInspectorResponseDelivery,
|
||||
session_response_predecessor: Option<moli_core::RendererOutputFence>,
|
||||
session_response_succeeded: Option<bool>,
|
||||
should_persist: bool,
|
||||
skip_live_page_update_after_inspector_success: bool,
|
||||
}
|
||||
@@ -1026,11 +1029,7 @@ fn start_main_runtime_inspector_command_for_owner(
|
||||
cmd,
|
||||
&owner_scope,
|
||||
inspector_json,
|
||||
if await_promise {
|
||||
RendererInspectorResponseDelivery::CommandReply
|
||||
} else {
|
||||
cmd.terminal_response_delivery(RendererInspectorResponseDelivery::DevToolsSession)
|
||||
},
|
||||
cmd.terminal_response_delivery(RendererInspectorResponseDelivery::DevToolsSession),
|
||||
) {
|
||||
Ok(pending) => pending,
|
||||
Err(message) => {
|
||||
@@ -1179,7 +1178,7 @@ pub(crate) fn start_heap_profiler_inspector_command_dispatch(
|
||||
cmd,
|
||||
&owner_scope,
|
||||
cmd.json.to_owned(),
|
||||
RendererInspectorResponseDelivery::CommandReply,
|
||||
cmd.terminal_response_delivery(RendererInspectorResponseDelivery::DevToolsSession),
|
||||
) {
|
||||
Ok(pending) => pending,
|
||||
Err(message) => {
|
||||
@@ -1656,10 +1655,7 @@ fn start_runtime_enable_command_for_owner(
|
||||
command_id: Option<u64>,
|
||||
owner_scope: CommandOwnerScope,
|
||||
) -> RuntimeCommandTaskStep {
|
||||
let has_loaded_page = match conn.runtime_session_owner_slot_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) {
|
||||
let has_loaded_page = match conn.runtime_session_owner_slot_for_owner(&owner_scope) {
|
||||
Ok(slot) => slot.has_loaded_page(),
|
||||
Err(_) if owner_scope.session_id().is_some() => {
|
||||
return RuntimeCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
@@ -1729,7 +1725,7 @@ fn runtime_remove_binding_should_skip_live_page_update(
|
||||
conn: &CdpConnection,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> bool {
|
||||
conn.target_runtime_session_state_for_route(owner.session_id(), owner.session_owner_route())
|
||||
conn.target_runtime_session_state_for_owner(owner)
|
||||
.is_some_and(|state| state.runtime_frontend_enabled)
|
||||
}
|
||||
|
||||
@@ -1797,21 +1793,19 @@ fn try_start_pending_runtime_binding_command(
|
||||
execution_context_id,
|
||||
inspector_json: Some(cmd.json.to_owned()),
|
||||
command_response: None,
|
||||
response_delivery: cmd
|
||||
.terminal_response_delivery(RendererInspectorResponseDelivery::DevToolsSession),
|
||||
session_response_predecessor: None,
|
||||
session_response_succeeded: None,
|
||||
should_persist,
|
||||
skip_live_page_update_after_inspector_success: false,
|
||||
};
|
||||
let live_page_update_unavailable = conn
|
||||
.runtime_session_owner_slot_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_for_owner(&owner_scope)
|
||||
.is_ok_and(|slot| !slot.has_loaded_page())
|
||||
|| should_persist
|
||||
&& conn
|
||||
.runtime_session_owner_slot_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_for_owner(&owner_scope)
|
||||
.is_ok_and(|slot| slot.renderer_document_navigation_is_suspended());
|
||||
if live_page_update_unavailable {
|
||||
task.command_response = Some(RuntimeBindingCommandResponse::empty_success());
|
||||
@@ -1844,19 +1838,22 @@ fn try_start_pending_runtime_binding_command(
|
||||
}
|
||||
let action_label = action.label();
|
||||
let pending = match action {
|
||||
RuntimeBindingCommand::Add => start_pending_runtime_context_resolved_inspector_dispatch(
|
||||
conn,
|
||||
cmd,
|
||||
&owner_scope,
|
||||
action_label,
|
||||
cmd.json.to_owned(),
|
||||
),
|
||||
RuntimeBindingCommand::Add => {
|
||||
start_pending_runtime_context_resolved_inspector_dispatch_with_delivery(
|
||||
conn,
|
||||
cmd,
|
||||
&owner_scope,
|
||||
action_label,
|
||||
cmd.json.to_owned(),
|
||||
task.response_delivery,
|
||||
)
|
||||
}
|
||||
RuntimeBindingCommand::Remove => start_pending_runtime_inspector_dispatch_with_delivery(
|
||||
conn,
|
||||
cmd,
|
||||
&owner_scope,
|
||||
cmd.json.to_owned(),
|
||||
RendererInspectorResponseDelivery::CommandReply,
|
||||
task.response_delivery,
|
||||
),
|
||||
};
|
||||
let pending = match pending {
|
||||
@@ -1933,23 +1930,6 @@ fn start_pending_runtime_io_inspector_dispatch(
|
||||
}
|
||||
}
|
||||
|
||||
fn start_pending_runtime_context_resolved_inspector_dispatch(
|
||||
conn: &mut CdpConnection,
|
||||
cmd: &Cmd<'_>,
|
||||
owner: &CommandOwnerScope,
|
||||
action: &'static str,
|
||||
inspector_json: String,
|
||||
) -> Result<PendingRuntimeProtocolMessageDispatch, String> {
|
||||
start_pending_runtime_context_resolved_inspector_dispatch_with_delivery(
|
||||
conn,
|
||||
cmd,
|
||||
owner,
|
||||
action,
|
||||
inspector_json,
|
||||
RendererInspectorResponseDelivery::CommandReply,
|
||||
)
|
||||
}
|
||||
|
||||
fn start_pending_runtime_context_resolved_inspector_dispatch_with_delivery(
|
||||
conn: &mut CdpConnection,
|
||||
cmd: &Cmd<'_>,
|
||||
@@ -2089,11 +2069,7 @@ fn start_cdp_devtools_script_runtime_command(
|
||||
command,
|
||||
inspector_json,
|
||||
await_promise,
|
||||
if await_promise {
|
||||
RendererInspectorResponseDelivery::CommandReply
|
||||
} else {
|
||||
cmd.terminal_response_delivery(RendererInspectorResponseDelivery::DevToolsSession)
|
||||
},
|
||||
cmd.terminal_response_delivery(RendererInspectorResponseDelivery::DevToolsSession),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4219,26 +4195,19 @@ pub(crate) async fn start_bidi_preload_channel_listeners_for_execution_context_b
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
) {
|
||||
let session_id = owner.session_id();
|
||||
let handoff_owners = conn.target_owner_bidi_channel_preload_handoffs_for_route(
|
||||
session_id,
|
||||
owner.session_owner_route(),
|
||||
);
|
||||
let handoff_owners = conn.target_owner_bidi_channel_preload_handoffs_for_owner(owner);
|
||||
if handoff_owners.is_empty() {
|
||||
return;
|
||||
}
|
||||
let target_id = conn
|
||||
.target_owner_identity_for_route(session_id, owner.session_owner_route())
|
||||
.target_owner_identity_for_owner(owner)
|
||||
.and_then(|(_, target_id)| target_id)
|
||||
.map(DevToolsTargetId::from);
|
||||
let route = owner
|
||||
.session_owner_route()
|
||||
.cloned()
|
||||
.or_else(|| conn.session_route(session_id))
|
||||
.or_else(|| {
|
||||
target_id
|
||||
.as_ref()
|
||||
.and_then(|target_id| conn.target_session_route_for_target_id(target_id.as_str()))
|
||||
});
|
||||
let route = owner.resolve_route(conn).or_else(|| {
|
||||
target_id
|
||||
.as_ref()
|
||||
.and_then(|target_id| conn.target_session_route_for_target_id(target_id.as_str()))
|
||||
});
|
||||
let Some(route) = route else {
|
||||
return;
|
||||
};
|
||||
@@ -7681,7 +7650,7 @@ fn start_pending_runtime_binding_inspector_phase(
|
||||
let descriptor = RendererCommandDescriptor::from_frontend_policy(
|
||||
inspector_json,
|
||||
task.renderer_policy,
|
||||
RendererInspectorResponseDelivery::CommandReply,
|
||||
task.response_delivery,
|
||||
);
|
||||
conn.start_runtime_protocol_message_with_context_resolution_for_owner_with_deferred_response(
|
||||
&completed.owner_scope,
|
||||
@@ -7702,7 +7671,7 @@ fn start_pending_runtime_binding_inspector_phase(
|
||||
let descriptor = RendererCommandDescriptor::from_frontend_policy(
|
||||
inspector_json,
|
||||
task.renderer_policy,
|
||||
RendererInspectorResponseDelivery::CommandReply,
|
||||
task.response_delivery,
|
||||
);
|
||||
conn.start_runtime_protocol_message_for_owner_with_deferred_response(
|
||||
&completed.owner_scope,
|
||||
@@ -7819,7 +7788,7 @@ fn prepare_runtime_inspector_payload_for_owner(
|
||||
}
|
||||
RuntimeInspectorPayloadPreparation::PrepareCallFunctionOn => {
|
||||
let (browser_context_id, target_id) = conn
|
||||
.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.target_owner_identity_for_owner(owner)
|
||||
.map(|(browser_context_id, target_id)| (Some(browser_context_id), target_id))
|
||||
.unwrap_or((None, None));
|
||||
let command = build_cdp_call_function_command(
|
||||
@@ -8320,12 +8289,8 @@ async fn complete_pending_runtime_inspector_command(
|
||||
if !saw_current_response
|
||||
&& renderer_response_rx.is_some()
|
||||
&& completed.command_id.is_some_and(|command_id| {
|
||||
conn.renderer_runtime_command_cause_for_route(
|
||||
completed.session_id(),
|
||||
completed.owner_scope.session_owner_route(),
|
||||
command_id,
|
||||
)
|
||||
.is_none()
|
||||
conn.renderer_runtime_command_cause_for_owner(&completed.owner_scope, command_id)
|
||||
.is_none()
|
||||
})
|
||||
{
|
||||
renderer_response_rx.take();
|
||||
@@ -8359,7 +8324,8 @@ async fn complete_pending_runtime_inspector_command(
|
||||
saw_current_response,
|
||||
);
|
||||
}
|
||||
if completed.wait_for_deferred_reply
|
||||
if response_delivery == RendererInspectorResponseDelivery::CommandReply
|
||||
&& completed.wait_for_deferred_reply
|
||||
&& (renderer_response_rx.is_some() || !saw_current_response)
|
||||
&& completed.command_id.is_some()
|
||||
{
|
||||
@@ -8571,10 +8537,7 @@ fn complete_pending_runtime_enable_command(
|
||||
{
|
||||
return CommandOutputPlan::error(-32000, message);
|
||||
}
|
||||
let frame_id = conn.runtime_session_owner_frame_id_for_route(
|
||||
completed.owner_scope.session_id(),
|
||||
completed.owner_scope.session_owner_route(),
|
||||
);
|
||||
let frame_id = conn.runtime_session_owner_frame_id_for_owner(&completed.owner_scope);
|
||||
|
||||
let mut plan = CommandOutputPlan::success();
|
||||
for event in replay.into_events() {
|
||||
@@ -8682,19 +8645,50 @@ async fn complete_pending_runtime_binding_inspector_command(
|
||||
completed_inspector: Result<CompletedRuntimeProtocolMessageDispatch, String>,
|
||||
response_flush: &crate::conn::CommandResponseFlushContext,
|
||||
) -> RuntimeCommandTaskStep {
|
||||
let (messages, mut renderer_response_rx) = match completed_inspector {
|
||||
let (
|
||||
messages,
|
||||
mut renderer_response_rx,
|
||||
response_delivery,
|
||||
session_response_predecessor,
|
||||
session_response_succeeded,
|
||||
) = match completed_inspector {
|
||||
Ok(mut completed_protocol) => {
|
||||
let response_delivery = completed_protocol.response_delivery();
|
||||
let session_response_predecessor = completed_protocol.session_response_predecessor();
|
||||
let session_response_succeeded = completed_protocol.session_response_succeeded();
|
||||
let renderer_response_rx = completed_protocol.take_deferred_response_receiver();
|
||||
match conn
|
||||
.complete_runtime_protocol_message_async(completed_protocol)
|
||||
.await
|
||||
{
|
||||
Ok(messages) => (messages, renderer_response_rx),
|
||||
Ok(messages) => (
|
||||
messages,
|
||||
renderer_response_rx,
|
||||
response_delivery,
|
||||
session_response_predecessor,
|
||||
session_response_succeeded,
|
||||
),
|
||||
Err(message) => {
|
||||
return RuntimeCommandTaskStep::Complete(runtime_inspector_error_plan(
|
||||
completed.command_id,
|
||||
message,
|
||||
));
|
||||
if session_response_succeeded.is_some() {
|
||||
tracing::warn!(
|
||||
command_id = completed.command_id,
|
||||
session_id = completed.session_id(),
|
||||
error = %message,
|
||||
"could not apply Runtime binding browser projection after the renderer session settled the terminal response"
|
||||
);
|
||||
(
|
||||
None,
|
||||
renderer_response_rx,
|
||||
response_delivery,
|
||||
session_response_predecessor,
|
||||
session_response_succeeded,
|
||||
)
|
||||
} else {
|
||||
return RuntimeCommandTaskStep::Complete(runtime_inspector_error_plan(
|
||||
completed.command_id,
|
||||
message,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8705,6 +8699,11 @@ async fn complete_pending_runtime_binding_inspector_command(
|
||||
));
|
||||
}
|
||||
};
|
||||
debug_assert_eq!(response_delivery, task.response_delivery);
|
||||
if let Some(predecessor) = session_response_predecessor {
|
||||
predecessor.merge_into_same_stream_tail(&mut task.session_response_predecessor);
|
||||
}
|
||||
task.session_response_succeeded = session_response_succeeded;
|
||||
let mut routed_output = RuntimeInspectorRoutedOutput::default();
|
||||
let saw_current_response = if let Some(messages) = messages {
|
||||
route_renderer_command_turn_output_into_routed_output(
|
||||
@@ -8722,7 +8721,12 @@ async fn complete_pending_runtime_binding_inspector_command(
|
||||
if saw_current_response {
|
||||
renderer_response_rx.take();
|
||||
}
|
||||
if let Some(renderer_response_rx) = renderer_response_rx {
|
||||
if response_delivery == RendererInspectorResponseDelivery::DevToolsSession {
|
||||
renderer_response_rx.take();
|
||||
}
|
||||
if response_delivery == RendererInspectorResponseDelivery::CommandReply
|
||||
&& let Some(renderer_response_rx) = renderer_response_rx
|
||||
{
|
||||
route_registered_runtime_response_receiver_into(
|
||||
conn,
|
||||
completed.command_id,
|
||||
@@ -8732,11 +8736,13 @@ async fn complete_pending_runtime_binding_inspector_command(
|
||||
)
|
||||
.await;
|
||||
}
|
||||
record_runtime_binding_command_response_from_routed_events(
|
||||
&mut task,
|
||||
routed_output.events(),
|
||||
completed.command_id,
|
||||
);
|
||||
if response_delivery == RendererInspectorResponseDelivery::CommandReply {
|
||||
record_runtime_binding_command_response_from_routed_events(
|
||||
&mut task,
|
||||
routed_output.events(),
|
||||
completed.command_id,
|
||||
);
|
||||
}
|
||||
if routed_output.background_event_count() > 0 {
|
||||
tracing::debug!(
|
||||
events = routed_output.background_event_count(),
|
||||
@@ -8838,6 +8844,12 @@ fn complete_runtime_binding_after_live_update(
|
||||
|
||||
fn runtime_binding_output_plan(task: RuntimeBindingCommandTask) -> CommandOutputPlan {
|
||||
let mut plan = CommandOutputPlan::default();
|
||||
if let Some(predecessor) = task.session_response_predecessor {
|
||||
plan.set_renderer_output_predecessor(predecessor);
|
||||
}
|
||||
if task.session_response_succeeded.is_some() {
|
||||
return plan;
|
||||
}
|
||||
match task.command_response {
|
||||
Some(response) => response.push_into_plan(&mut plan),
|
||||
None => plan.push_error(-32000, "MissingRuntimeBindingCommandResponse"),
|
||||
@@ -8888,6 +8900,9 @@ fn record_runtime_binding_command_response_from_routed_events(
|
||||
}
|
||||
|
||||
fn runtime_binding_command_response_succeeded(task: &RuntimeBindingCommandTask) -> bool {
|
||||
if let Some(succeeded) = task.session_response_succeeded {
|
||||
return succeeded;
|
||||
}
|
||||
task.command_response
|
||||
.as_ref()
|
||||
.is_some_and(RuntimeBindingCommandResponse::succeeded)
|
||||
@@ -9221,11 +9236,8 @@ fn start_pending_shared_worker_runtime_inspector_command(
|
||||
action.label(),
|
||||
)
|
||||
.map_err(|error| error.to_string())?;
|
||||
let response_delivery = if await_promise {
|
||||
RendererInspectorResponseDelivery::CommandReply
|
||||
} else {
|
||||
cmd.terminal_response_delivery(RendererInspectorResponseDelivery::DevToolsSession)
|
||||
};
|
||||
let response_delivery =
|
||||
cmd.terminal_response_delivery(RendererInspectorResponseDelivery::DevToolsSession);
|
||||
let pending = match start_shared_worker_frontend_inspector_dispatch(
|
||||
conn,
|
||||
cmd,
|
||||
@@ -9293,11 +9305,8 @@ fn start_pending_service_worker_runtime_inspector_command(
|
||||
action.label(),
|
||||
)
|
||||
.map_err(|error| error.to_string())?;
|
||||
let response_delivery = if await_promise {
|
||||
RendererInspectorResponseDelivery::CommandReply
|
||||
} else {
|
||||
cmd.terminal_response_delivery(RendererInspectorResponseDelivery::DevToolsSession)
|
||||
};
|
||||
let response_delivery =
|
||||
cmd.terminal_response_delivery(RendererInspectorResponseDelivery::DevToolsSession);
|
||||
let pending = match start_service_worker_frontend_inspector_dispatch(
|
||||
conn,
|
||||
cmd,
|
||||
@@ -9465,6 +9474,12 @@ async fn complete_pending_shared_worker_runtime_inspector_command(
|
||||
) = match completed_inspector {
|
||||
Ok(mut completed_protocol) => {
|
||||
let response_delivery = completed_protocol.response_delivery();
|
||||
if response_delivery == RendererInspectorResponseDelivery::DevToolsSession
|
||||
&& !completed.await_promise
|
||||
&& let Err(message) = completed_protocol.wait_for_session_response().await
|
||||
{
|
||||
return complete_shared_worker_runtime_inspector_error(conn, completed, message);
|
||||
}
|
||||
let session_response_predecessor = completed_protocol.session_response_predecessor();
|
||||
let session_response_succeeded = completed_protocol.session_response_succeeded();
|
||||
let renderer_response_rx = completed_protocol.take_deferred_response_receiver();
|
||||
@@ -9543,6 +9558,18 @@ async fn complete_pending_shared_worker_runtime_inspector_command(
|
||||
renderer_response_rx,
|
||||
);
|
||||
}
|
||||
if response_delivery == RendererInspectorResponseDelivery::DevToolsSession
|
||||
&& completed.await_promise
|
||||
&& session_response_succeeded.is_none()
|
||||
{
|
||||
// The Worker accepted an asynchronous Inspector command. Its terminal
|
||||
// response now belongs exclusively to the Worker target journal and
|
||||
// may arrive on a later turn; releasing this command here lets the
|
||||
// same or another DevTools session continue driving the worker.
|
||||
routed_output
|
||||
.push_background_events_before_response_events(&mut plan, completed.command_id);
|
||||
return RuntimeCommandTaskStep::Complete(plan);
|
||||
}
|
||||
let succeeded = session_response_succeeded
|
||||
.unwrap_or_else(|| routed_output.command_response_succeeded(completed.command_id));
|
||||
apply_shared_worker_runtime_completion_projection(
|
||||
@@ -9636,6 +9663,12 @@ async fn complete_pending_service_worker_runtime_inspector_command(
|
||||
) = match completed_inspector {
|
||||
Ok(mut completed_protocol) => {
|
||||
let response_delivery = completed_protocol.response_delivery();
|
||||
if response_delivery == RendererInspectorResponseDelivery::DevToolsSession
|
||||
&& !completed.await_promise
|
||||
&& let Err(message) = completed_protocol.wait_for_session_response().await
|
||||
{
|
||||
return complete_service_worker_runtime_inspector_error(conn, completed, message);
|
||||
}
|
||||
let session_response_predecessor = completed_protocol.session_response_predecessor();
|
||||
let session_response_succeeded = completed_protocol.session_response_succeeded();
|
||||
let renderer_response_rx = completed_protocol.take_deferred_response_receiver();
|
||||
@@ -9714,6 +9747,14 @@ async fn complete_pending_service_worker_runtime_inspector_command(
|
||||
renderer_response_rx,
|
||||
);
|
||||
}
|
||||
if response_delivery == RendererInspectorResponseDelivery::DevToolsSession
|
||||
&& completed.await_promise
|
||||
&& session_response_succeeded.is_none()
|
||||
{
|
||||
routed_output
|
||||
.push_background_events_before_response_events(&mut plan, completed.command_id);
|
||||
return RuntimeCommandTaskStep::Complete(plan);
|
||||
}
|
||||
let succeeded = session_response_succeeded
|
||||
.unwrap_or_else(|| routed_output.command_response_succeeded(completed.command_id));
|
||||
apply_service_worker_runtime_completion_projection(
|
||||
@@ -10346,10 +10387,7 @@ fn start_runtime_disable_command_for_owner(
|
||||
response_delivery: RendererInspectorResponseDelivery,
|
||||
) -> RuntimeCommandTaskStep {
|
||||
if !conn
|
||||
.runtime_session_owner_slot_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.runtime_session_owner_slot_for_owner(&owner_scope)
|
||||
.is_ok_and(|slot| slot.has_loaded_page())
|
||||
{
|
||||
return RuntimeCommandTaskStep::Complete(disable_command_output_plan_sync_for_owner(
|
||||
@@ -10460,7 +10498,7 @@ fn apply_runtime_disable_projection_after_success_for_owner(
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Result<(), String> {
|
||||
let was_enabled = conn
|
||||
.target_runtime_session_state_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.target_runtime_session_state_for_owner(owner)
|
||||
.is_some_and(|state| state.runtime_frontend_enabled);
|
||||
match conn.set_runtime_frontend_enabled_for_owner(owner, false) {
|
||||
SessionOwnerRuntimeFrontendEnableResult::Handled => {
|
||||
|
||||
@@ -2448,7 +2448,9 @@ async fn page_navigate_network_failure_commits_error_document() {
|
||||
);
|
||||
let error_document_loader_id = ctx
|
||||
.conn
|
||||
.target_session_owner_frame_tree_loader_id_for_route(Some("SID-1"), None)
|
||||
.target_session_owner_frame_tree_loader_id_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1"),
|
||||
)
|
||||
.expect("error Document loader id");
|
||||
let stale_request_id = "REQ-before-network-error";
|
||||
let stale_body_completion = BackgroundNavigationCompletion::main_document_body(
|
||||
@@ -2492,7 +2494,9 @@ async fn page_navigate_network_failure_commits_error_document() {
|
||||
assert!(stale_completion_scheduler_events.is_empty());
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.target_session_owner_frame_tree_loader_id_for_route(Some("SID-1"), None)
|
||||
.target_session_owner_frame_tree_loader_id_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session("SID-1")
|
||||
)
|
||||
.as_deref(),
|
||||
Some(error_document_loader_id.as_str()),
|
||||
"stale body completion must not replace the error Document loader"
|
||||
@@ -2838,7 +2842,7 @@ async fn evaluate_await_promise_scheduler_routed_reply_clears_pending_await_regi
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn runtime_await_promise_pending_registers_renderer_response_receiver() {
|
||||
async fn runtime_await_promise_releases_dispatch_before_session_response() {
|
||||
let mut ctx = TestContext::new();
|
||||
with_loaded_document_async(&mut ctx, "<html><title>ok</title><body></body></html>").await;
|
||||
|
||||
@@ -2868,50 +2872,45 @@ async fn runtime_await_promise_pending_registers_renderer_response_receiver() {
|
||||
.conn
|
||||
.try_start_pending_command_dispatch(&raw)
|
||||
.expect("Runtime.awaitPromise should start as a pending command");
|
||||
let (mut pending, scheduler_events) = match ctx
|
||||
.conn
|
||||
.complete_pending_command_dispatch(pending.wait().await)
|
||||
let completed = tokio::time::timeout(std::time::Duration::from_secs(1), pending.wait())
|
||||
.await
|
||||
{
|
||||
CdpCommandTaskStep::Pending(pending) => (*pending, ctx.conn.take_scheduler_events()),
|
||||
CdpCommandTaskStep::Complete(outcome) => {
|
||||
panic!(
|
||||
"never-settling Runtime.awaitPromise should stay pending after initial inspector dispatch: {:?}",
|
||||
outcome.into_parts().0
|
||||
);
|
||||
}
|
||||
.expect("initial Page Inspector dispatch must not wait for Promise settlement");
|
||||
let CdpCommandTaskStep::Complete(outcome) =
|
||||
ctx.conn.complete_pending_command_dispatch(completed).await
|
||||
else {
|
||||
panic!("a Page session response must not enter the CommandReply deferred-reply lane");
|
||||
};
|
||||
drop(outcome);
|
||||
assert!(
|
||||
scheduler_events.is_empty(),
|
||||
"pending Runtime.awaitPromise must wait on its inspector response receiver, not scheduler follow-up work: {scheduler_events:?}"
|
||||
ctx.conn.take_scheduler_events().is_empty(),
|
||||
"an unresolved session response must not manufacture scheduler follow-up work"
|
||||
);
|
||||
|
||||
assert!(
|
||||
pending.waits_for_scheduler_deferred_inspector_reply(),
|
||||
"Runtime.awaitPromise should enter scheduler deferred-reply state"
|
||||
ctx.conn
|
||||
.has_pending_inspector_awaits_for_session_owner(None),
|
||||
"the unresolved await must remain registered to its exact Page session"
|
||||
);
|
||||
assert!(
|
||||
ctx.conn
|
||||
.has_pending_inspector_awaits_for_session_owner(None),
|
||||
"scheduler-deferred Runtime.awaitPromise should remain visible as pending command-owned work"
|
||||
.has_unclaimed_pending_inspector_awaits_for_session_owner(None),
|
||||
"the session output path must leave the await under renderer ownership"
|
||||
);
|
||||
assert!(
|
||||
!ctx.conn
|
||||
.has_unclaimed_pending_inspector_awaits_for_session_owner(None),
|
||||
"scheduler-deferred Runtime.awaitPromise should claim the pending await out of the document registry"
|
||||
);
|
||||
assert!(
|
||||
ctx.conn
|
||||
.has_claimed_pending_inspector_awaits_for_session_owner(None),
|
||||
"scheduler-deferred Runtime.awaitPromise should be tracked by the command-owned await index"
|
||||
"the CommandReply claimed-await index must remain unused"
|
||||
);
|
||||
assert!(
|
||||
pending
|
||||
.take_scheduler_deferred_inspector_reply_receiver()
|
||||
.is_some(),
|
||||
"pending Runtime.awaitPromise should own the renderer response receiver"
|
||||
|
||||
ctx.process_async(json!({
|
||||
"id": 3_024,
|
||||
"method": "Page.close"
|
||||
}))
|
||||
.await;
|
||||
assert_eq!(
|
||||
take_response_by_id(&mut ctx, 3_023)["error"]["message"],
|
||||
json!("Page closed")
|
||||
);
|
||||
pending.forget_scheduler_deferred_inspector_reply(&mut ctx.conn);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@@ -3399,7 +3399,7 @@ async fn shared_worker_await_promise_timer_reply_arrives_through_renderer_receiv
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn shared_worker_await_promise_pending_registers_renderer_response_receiver() {
|
||||
async fn shared_worker_await_promise_releases_dispatch_before_session_response() {
|
||||
let mut ctx = TestContext::new();
|
||||
with_loaded_document_async(&mut ctx, "<!doctype html><body></body>").await;
|
||||
let shared_worker_session_id = start_attached_shared_worker_session(
|
||||
@@ -3429,31 +3429,33 @@ onconnect = event => {
|
||||
.conn
|
||||
.try_start_pending_command_dispatch(&raw)
|
||||
.expect("shared worker Runtime.evaluate awaitPromise should start as a pending command");
|
||||
let mut pending = match ctx
|
||||
.conn
|
||||
.complete_pending_command_dispatch(pending.wait().await)
|
||||
let completed = tokio::time::timeout(std::time::Duration::from_secs(1), pending.wait())
|
||||
.await
|
||||
{
|
||||
CdpCommandTaskStep::Pending(pending) => *pending,
|
||||
CdpCommandTaskStep::Complete(outcome) => {
|
||||
panic!(
|
||||
"shared worker Runtime.evaluate awaitPromise should stay pending after initial inspector dispatch: {:?}",
|
||||
outcome.into_parts().0
|
||||
);
|
||||
}
|
||||
.expect("initial Worker Inspector dispatch must not wait for Promise settlement");
|
||||
let CdpCommandTaskStep::Complete(outcome) =
|
||||
ctx.conn.complete_pending_command_dispatch(completed).await
|
||||
else {
|
||||
panic!("a Worker session response must not enter the CommandReply deferred-reply lane");
|
||||
};
|
||||
assert!(
|
||||
outcome.into_parts().0.is_empty(),
|
||||
"the unresolved terminal response must remain in the Worker session output journal"
|
||||
);
|
||||
assert!(
|
||||
ctx.conn
|
||||
.has_pending_inspector_awaits_for_session_owner(Some(&shared_worker_session_id)),
|
||||
"the unresolved await must remain registered to its exact Worker session"
|
||||
);
|
||||
|
||||
assert!(
|
||||
pending.waits_for_scheduler_deferred_inspector_reply(),
|
||||
"awaitPromise should enter scheduler deferred-reply state"
|
||||
);
|
||||
assert!(
|
||||
pending
|
||||
.take_scheduler_deferred_inspector_reply_receiver()
|
||||
.is_some(),
|
||||
"shared worker awaitPromise should own the renderer response receiver"
|
||||
);
|
||||
pending.forget_scheduler_deferred_inspector_reply(&mut ctx.conn);
|
||||
ctx.process_async(json!({
|
||||
"id": 91_103,
|
||||
"method": "Target.detachFromTarget",
|
||||
"params": { "sessionId": shared_worker_session_id }
|
||||
}))
|
||||
.await;
|
||||
assert_eq!(take_response_by_id(&mut ctx, 91_103)["result"], json!({}));
|
||||
let failed_await = take_response_by_id(&mut ctx, 91_102);
|
||||
assert_eq!(failed_await["error"]["message"], json!("Target detached"));
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
|
||||
@@ -295,9 +295,7 @@ pub(crate) fn qualify_runtime_context_protocol_event_for_owner_typed(
|
||||
);
|
||||
return;
|
||||
}
|
||||
let Some((_, Some(target_id))) =
|
||||
conn.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
else {
|
||||
let Some((_, Some(target_id))) = conn.target_owner_identity_for_owner(owner) else {
|
||||
return;
|
||||
};
|
||||
match event {
|
||||
@@ -422,18 +420,16 @@ pub(crate) fn should_emit_child_default_context_inventory_replay_once_for_owner(
|
||||
return true;
|
||||
}
|
||||
if conn
|
||||
.target_devtools_session_state_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.target_devtools_session_state_for_owner(owner)
|
||||
.is_some_and(|state| {
|
||||
state.has_emitted_child_default_execution_context_id(execution_context_id)
|
||||
})
|
||||
{
|
||||
return false;
|
||||
}
|
||||
let _ = conn.with_target_devtools_session_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|state| state.mark_child_default_execution_context_id_emitted(execution_context_id),
|
||||
);
|
||||
let _ = conn.with_target_devtools_session_state_for_owner_mut(owner, |state| {
|
||||
state.mark_child_default_execution_context_id_emitted(execution_context_id)
|
||||
});
|
||||
true
|
||||
}
|
||||
|
||||
@@ -473,9 +469,7 @@ fn record_child_default_context_delivery_for_owner(
|
||||
let Some(execution_context_id) = child_default_execution_context_id(event) else {
|
||||
return;
|
||||
};
|
||||
let Some(root_frame_id) = conn
|
||||
.runtime_session_owner_frame_id_for_route(owner.session_id(), owner.session_owner_route())
|
||||
else {
|
||||
let Some(root_frame_id) = conn.runtime_session_owner_frame_id_for_owner(owner) else {
|
||||
return;
|
||||
};
|
||||
if event
|
||||
@@ -485,11 +479,9 @@ fn record_child_default_context_delivery_for_owner(
|
||||
{
|
||||
return;
|
||||
}
|
||||
let _ = conn.with_target_devtools_session_state_for_route_mut(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
|state| state.mark_child_default_execution_context_id_emitted(execution_context_id),
|
||||
);
|
||||
let _ = conn.with_target_devtools_session_state_for_owner_mut(owner, |state| {
|
||||
state.mark_child_default_execution_context_id_emitted(execution_context_id)
|
||||
});
|
||||
}
|
||||
|
||||
fn mark_child_default_context_event_emitted(
|
||||
|
||||
@@ -97,11 +97,7 @@ pub(crate) fn complete_pending_security_command(
|
||||
Err(error) => return CommandOutputPlan::error(-32000, error),
|
||||
};
|
||||
let owner_scope = completed.owner_scope;
|
||||
match conn.finish_rebuild_resource_runtime_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
completion,
|
||||
) {
|
||||
match conn.finish_rebuild_resource_runtime_for_owner(&owner_scope, completion) {
|
||||
Ok(()) => CommandOutputPlan::success(),
|
||||
Err(error) => CommandOutputPlan::error(-32000, error),
|
||||
}
|
||||
|
||||
@@ -479,19 +479,11 @@ fn start_get_storage_key_for_frame_command(
|
||||
};
|
||||
|
||||
let owner_scope = CommandOwnerScope::capture(conn, cmd.session_id);
|
||||
let Some((target_id, target_url, _, _)) = conn
|
||||
.target_session_owner_frame_tree_identity_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
let Some((target_id, target_url, _, _)) =
|
||||
conn.target_session_owner_frame_tree_identity_for_owner(&owner_scope)
|
||||
else {
|
||||
let plan = if conn.browser_context.is_none()
|
||||
&& conn
|
||||
.target_owner_identity_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.is_none()
|
||||
&& conn.target_owner_identity_for_owner(&owner_scope).is_none()
|
||||
{
|
||||
CommandOutputPlan::error(-31998, "BrowserContextNotLoaded")
|
||||
} else {
|
||||
@@ -501,9 +493,7 @@ fn start_get_storage_key_for_frame_command(
|
||||
};
|
||||
|
||||
if params.frame_id == target_id {
|
||||
if let Some(page) =
|
||||
loaded_page_mut_for_session(conn, cmd.session_id, owner_scope.session_owner_route())
|
||||
{
|
||||
if let Some(page) = loaded_page_mut_for_owner(conn, &owner_scope) {
|
||||
return match page.start_document_storage_key_snapshot() {
|
||||
Ok(pending) => StorageCommandTaskStep::Pending(PendingStorageCommandDispatch {
|
||||
command_id: cmd.id,
|
||||
@@ -526,15 +516,10 @@ fn start_get_storage_key_for_frame_command(
|
||||
));
|
||||
}
|
||||
|
||||
if let Err(message) = conn.ensure_document_accessible_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) {
|
||||
if let Err(message) = conn.ensure_document_accessible_for_owner(&owner_scope) {
|
||||
return StorageCommandTaskStep::Complete(CommandOutputPlan::error(-32000, message));
|
||||
}
|
||||
let Some(page) =
|
||||
loaded_page_mut_for_session(conn, cmd.session_id, owner_scope.session_owner_route())
|
||||
else {
|
||||
let Some(page) = loaded_page_mut_for_owner(conn, &owner_scope) else {
|
||||
return StorageCommandTaskStep::Complete(CommandOutputPlan::error(
|
||||
-32000,
|
||||
"NoFrameForGivenId",
|
||||
@@ -782,11 +767,7 @@ fn complete_get_storage_key_for_top_frame_command(
|
||||
Ok(completion) => completion,
|
||||
Err(error) => return CommandOutputPlan::error(-32000, error),
|
||||
};
|
||||
let Some(page) = loaded_page_mut_for_session(
|
||||
conn,
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) else {
|
||||
let Some(page) = loaded_page_mut_for_owner(conn, owner_scope) else {
|
||||
return CommandOutputPlan::error(-32000, "NoFrameForGivenId");
|
||||
};
|
||||
match page.finish_document_storage_key_snapshot(completion) {
|
||||
@@ -805,11 +786,7 @@ fn complete_get_storage_key_for_frame_command(
|
||||
Ok(completion) => completion,
|
||||
Err(error) => return CommandOutputPlan::error(-32000, error),
|
||||
};
|
||||
let Some(page) = loaded_page_mut_for_session(
|
||||
conn,
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
) else {
|
||||
let Some(page) = loaded_page_mut_for_owner(conn, owner_scope) else {
|
||||
return CommandOutputPlan::error(-32000, "NoFrameForGivenId");
|
||||
};
|
||||
let child_frames = match page.finish_child_frame_tree_snapshot(completion) {
|
||||
@@ -920,12 +897,11 @@ fn complete_set_cookies_result(
|
||||
Ok(set_cookie_reports_result(&reports))
|
||||
}
|
||||
|
||||
fn loaded_page_mut_for_session<'a>(
|
||||
fn loaded_page_mut_for_owner<'a>(
|
||||
conn: &'a mut CdpConnection,
|
||||
session_id: Option<&str>,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
) -> Option<&'a mut moli_core::page::Page> {
|
||||
conn.loaded_page_mut_for_protocol_access_for_route(session_id, owner_route)
|
||||
conn.loaded_page_mut_for_protocol_access_for_owner(owner)
|
||||
.ok()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::conn::{
|
||||
BackgroundProtocolEvent, BrowserContext, CdpConnection, Cmd, TargetHandlerAccessMode,
|
||||
BackgroundProtocolEvent, BrowserContext, CdpConnection, Cmd, CommandOwnerScope,
|
||||
TargetHandlerAccessMode,
|
||||
};
|
||||
use crate::devtools_runtime::{
|
||||
DevToolsActivateTargetCommand, DevToolsCloseTargetCommand, DevToolsCommand,
|
||||
@@ -35,19 +36,16 @@ pub(crate) use popup::{
|
||||
PopupTargetCreation, PopupTargetOpenerIdentity, complete_popup_target_activation_action_async,
|
||||
complete_popup_target_navigation_owner_action_async,
|
||||
create_popup_target_from_renderer_output_background_events_async,
|
||||
emit_target_info_changed_for_session_owner_background_event,
|
||||
emit_target_info_changed_for_owner_background_event,
|
||||
schedule_initial_document_target_url_navigation_after_debugger_barrier_release_for_target,
|
||||
schedule_initial_document_target_url_navigation_after_debugger_resume,
|
||||
};
|
||||
pub(crate) fn popup_activation_creates_new_target_for_route(
|
||||
pub(crate) fn popup_activation_creates_new_target_for_owner(
|
||||
conn: &CdpConnection,
|
||||
owner_session_id: Option<&str>,
|
||||
owner_route: Option<&crate::conn::CdpSessionRoute>,
|
||||
owner: &CommandOwnerScope,
|
||||
target_name: &str,
|
||||
) -> bool {
|
||||
if let Some((browser_context_id, _)) =
|
||||
conn.target_owner_identity_for_route(owner_session_id, owner_route)
|
||||
{
|
||||
if let Some((browser_context_id, _)) = conn.target_owner_identity_for_owner(owner) {
|
||||
return conn
|
||||
.browser_context_by_id(&browser_context_id)
|
||||
.is_none_or(|browser_context| {
|
||||
|
||||
@@ -503,10 +503,7 @@ pub(crate) async fn complete_popup_target_navigation_owner_action_async(
|
||||
) -> crate::conn::CdpTurnOutcome {
|
||||
let (owner_scope, browser_context_id, target_id, url, kind) = action.into_parts();
|
||||
let target_is_current = conn
|
||||
.target_owner_identity_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
.target_owner_identity_for_owner(&owner_scope)
|
||||
.is_some_and(|(current_browser_context_id, current_target_id)| {
|
||||
current_browser_context_id == browser_context_id
|
||||
&& current_target_id.as_deref() == Some(target_id.as_str())
|
||||
@@ -578,15 +575,13 @@ pub(crate) async fn complete_popup_target_activation_action_async(
|
||||
action: PopupTargetActivationAction,
|
||||
) -> crate::conn::CdpTurnOutcome {
|
||||
let (owner_scope, browser_context_id, target_id) = action.into_parts();
|
||||
let target_is_current =
|
||||
conn.target_owner_identity_for_route(
|
||||
owner_scope.session_id(),
|
||||
owner_scope.session_owner_route(),
|
||||
)
|
||||
let target_is_current = conn
|
||||
.target_owner_identity_for_owner(&owner_scope)
|
||||
.is_some_and(|(current_browser_context_id, current_target_id)| {
|
||||
current_browser_context_id == browser_context_id
|
||||
&& current_target_id.as_deref() == Some(target_id.as_str())
|
||||
}) && popup_target_has_loaded_page(conn, &browser_context_id, &target_id);
|
||||
})
|
||||
&& popup_target_has_loaded_page(conn, &browser_context_id, &target_id);
|
||||
if !target_is_current {
|
||||
tracing::debug!(
|
||||
browser_context_id,
|
||||
@@ -651,12 +646,12 @@ async fn activate_popup_target_async(
|
||||
result
|
||||
}
|
||||
|
||||
pub(crate) fn emit_target_info_changed_for_session_owner_background_event(
|
||||
pub(crate) fn emit_target_info_changed_for_owner_background_event(
|
||||
conn: &mut CdpConnection,
|
||||
out: &mut Vec<BackgroundProtocolEvent>,
|
||||
session_id: Option<&str>,
|
||||
owner: &CommandOwnerScope,
|
||||
) {
|
||||
out.extend(conn.target_info_changed_event_plan_for_session_owner(session_id));
|
||||
out.extend(conn.target_info_changed_event_plan_for_owner(owner));
|
||||
}
|
||||
|
||||
fn emit_target_info_changed_for_target_background_event(
|
||||
|
||||
@@ -134,7 +134,9 @@ async fn arm_popup_route(
|
||||
ctx.expect_result(base + 2, json!({}), Some(popup_session_id));
|
||||
let fetch_snapshot = ctx
|
||||
.conn
|
||||
.target_fetch_subresource_interception_snapshot_for_route(Some(popup_session_id), None)
|
||||
.target_fetch_subresource_interception_snapshot_for_owner(
|
||||
&crate::conn::CommandOwnerScope::for_session(popup_session_id),
|
||||
)
|
||||
.expect("popup target Fetch configuration");
|
||||
let matching_sessions = fetch_snapshot.matching_request_stage_pause_sessions(
|
||||
Some(popup_session_id),
|
||||
|
||||
@@ -1343,18 +1343,12 @@ async fn session_route_finds_browser_active_auxiliary_background_and_inactive_se
|
||||
);
|
||||
assert_eq!(ctx.conn.session_route(Some("SID-missing")), None);
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.background_target_id_for_session(Some("SID-inactive-background")),
|
||||
Some("TID-000000000D".to_owned())
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn
|
||||
.background_target_id_for_session(Some("SID-inactive-aux-background")),
|
||||
Some("TID-000000000D".to_owned())
|
||||
);
|
||||
assert!(
|
||||
ctx.conn
|
||||
.has_background_target_session(Some("SID-inactive-background"))
|
||||
ctx.conn.session_route(Some("SID-inactive-background")),
|
||||
Some(CdpSessionRoute::PageTarget {
|
||||
browser_context_id: "BID-B".to_owned(),
|
||||
target_id: "TID-000000000D".to_owned(),
|
||||
session_key: moli_page_types::DevToolsSessionKey::Primary,
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn.session_route(Some("SID-inactive-aux-background")),
|
||||
@@ -1373,39 +1367,28 @@ async fn session_route_finds_browser_active_auxiliary_background_and_inactive_se
|
||||
target_id: "TID-shared-inactive".to_owned(),
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn.with_background_target_session(
|
||||
Some("SID-inactive-background"),
|
||||
|bc, target_id| {
|
||||
assert_eq!(bc.id, "BID-B");
|
||||
bc.background_target_mut(target_id)
|
||||
.expect("background target must exist")
|
||||
.devtools_sessions[moli_page_types::DevToolsSessionKey::Primary]
|
||||
.console_output_session_state
|
||||
.console_enabled = true;
|
||||
target_id.to_owned()
|
||||
}
|
||||
),
|
||||
Some("TID-000000000D".to_owned())
|
||||
);
|
||||
ctx.conn
|
||||
.browser_context_by_id_mut("BID-B")
|
||||
.expect("inactive browser context")
|
||||
.page_target_mut("TID-000000000D")
|
||||
.expect("stable page target")
|
||||
.devtools_sessions[moli_page_types::DevToolsSessionKey::Primary]
|
||||
.console_output_session_state
|
||||
.console_enabled = true;
|
||||
assert_eq!(
|
||||
ctx.conn.browser_context.as_ref().map(|bc| bc.id.as_str()),
|
||||
Some("BID-A"),
|
||||
"direct background route helpers must not promote inactive browser contexts"
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.conn.with_background_target_session(
|
||||
Some("SID-inactive-background"),
|
||||
|bc, target_id| {
|
||||
assert_eq!(bc.id, "BID-B");
|
||||
bc.background_target(target_id)
|
||||
.expect("background target must exist")
|
||||
.devtools_sessions[moli_page_types::DevToolsSessionKey::Primary]
|
||||
.console_output_session_state
|
||||
.console_enabled
|
||||
}
|
||||
),
|
||||
Some(true)
|
||||
assert!(
|
||||
ctx.conn
|
||||
.browser_context_by_id("BID-B")
|
||||
.expect("inactive browser context")
|
||||
.page_target("TID-000000000D")
|
||||
.expect("stable page target")
|
||||
.devtools_sessions[moli_page_types::DevToolsSessionKey::Primary]
|
||||
.console_output_session_state
|
||||
.console_enabled
|
||||
);
|
||||
|
||||
assert!(
|
||||
|
||||
@@ -431,20 +431,14 @@ pub(in crate::domains) fn dedicated_worker_target_lifecycle_prepared_outputs_for
|
||||
owner: &CommandOwnerScope,
|
||||
event: RendererDedicatedWorkerTargetEvent,
|
||||
) -> TargetPreparedOutputs {
|
||||
let session_id = owner.session_id();
|
||||
let owner_route = owner.session_owner_route();
|
||||
let Some(owner_page) = conn.target_page_residence_identity_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Some(owner_page) = conn.target_page_residence_identity_for_owner(owner) else {
|
||||
return TargetPreparedOutputs::default();
|
||||
};
|
||||
let Some(owner_renderer_page) =
|
||||
conn.renderer_page_residence_identity_for_route(session_id, owner_route)
|
||||
else {
|
||||
let Some(owner_renderer_page) = conn.renderer_page_residence_identity_for_owner(owner) else {
|
||||
return TargetPreparedOutputs::default();
|
||||
};
|
||||
let browser_context_id = owner_page.browser_context_id().to_owned();
|
||||
let owner_page_network_sessions =
|
||||
conn.network_event_session_ids_for_route(session_id, owner_route);
|
||||
let owner_page_network_sessions = conn.network_event_session_ids_for_owner(owner);
|
||||
dedicated_worker_target_lifecycle_outputs_for_events(
|
||||
conn,
|
||||
browser_context_id,
|
||||
|
||||
@@ -309,7 +309,7 @@ impl TestContext {
|
||||
let owner = crate::conn::CommandOwnerScope::capture(&self.conn, session_id);
|
||||
let (_, target_id) = self
|
||||
.conn
|
||||
.target_owner_identity_for_route(owner.session_id(), owner.session_owner_route())
|
||||
.target_owner_identity_for_owner(&owner)
|
||||
.expect("navigation fixture requires an installed browser context");
|
||||
let target_id = target_id.expect("navigation fixture requires an exact target");
|
||||
let navigation_engine = navigation.take_navigation_engine_replacement();
|
||||
@@ -357,10 +357,8 @@ impl TestContext {
|
||||
.adopt_loaded_navigation_engine_for_owner(&owner, navigation_engine);
|
||||
}
|
||||
assert_eq!(
|
||||
self.conn.target_root_document_lifecycle_identity_for_route(
|
||||
owner.session_id(),
|
||||
owner.session_owner_route(),
|
||||
),
|
||||
self.conn
|
||||
.target_root_document_lifecycle_identity_for_owner(&owner,),
|
||||
Some(binding.renderer_document_identity()),
|
||||
"navigation fixture must retain its exact renderer Document binding"
|
||||
);
|
||||
@@ -384,6 +382,16 @@ impl TestContext {
|
||||
.expect("test message must be a valid serialisable CDP command");
|
||||
let command_id = command.request().id();
|
||||
let session_id = command.request().session_id().map(str::to_owned);
|
||||
let command_awaits_promise = match command.request().method() {
|
||||
"Runtime.awaitPromise" => true,
|
||||
"Runtime.evaluate" | "Runtime.callFunctionOn" | "Runtime.runScript" => command
|
||||
.request()
|
||||
.params()
|
||||
.and_then(|params| params.get("awaitPromise"))
|
||||
.and_then(Value::as_bool)
|
||||
.unwrap_or(false),
|
||||
_ => false,
|
||||
};
|
||||
let response_start = self.sent.len();
|
||||
Box::pin(self.process_parsed_command_like_scheduler(&command, true)).await;
|
||||
Box::pin(self.route_ready_test_command_response(command_id, response_start)).await;
|
||||
@@ -391,6 +399,10 @@ impl TestContext {
|
||||
.conn
|
||||
.renderer_runtime_command_cause_for_frontend(session_id.as_deref(), command_id)
|
||||
.is_some()
|
||||
&& !(command_awaits_promise
|
||||
&& self
|
||||
.conn
|
||||
.has_pending_inspector_awaits_for_session_owner(session_id.as_deref()))
|
||||
&& !self
|
||||
.pending_runtime_deferred_replies
|
||||
.iter()
|
||||
|
||||
+11
-11
@@ -217,17 +217,17 @@ pub use runtime::RendererRuntimeInspectorMessageResponseOrder;
|
||||
pub use runtime::{
|
||||
CompletedWorkerRuntimeInspectorCommandDispatch, DetachedParserScriptFetchContinuation,
|
||||
DevToolsSessionKey, ExternalRawDocumentBodyStream, JsRuntime, JsRuntimeOwner, PageId,
|
||||
PendingHtmlPage, PreparedRendererDocument, RendererAccessibilityPayloadsForObjectId,
|
||||
RendererActivityDiagnostics, RendererAgentAttachmentId, RendererAutofillAddressField,
|
||||
RendererAutofillCreditCard, RendererAutofillTriggerOutcome, RendererAutofillTriggerRequest,
|
||||
RendererBrowserContextRuntime, RendererBrowserContextRuntimeId,
|
||||
RendererBrowserContextRuntimeOwner, RendererBrowserContextRuntimeOwnerAccess,
|
||||
RendererCaptureScreencastFrameReply, RendererCaptureScreencastFrameRequest,
|
||||
RendererCaptureScreenshotReply, RendererCaptureScreenshotRequest,
|
||||
RendererCapturedScreencastFrame, RendererCapturedScreenshot, RendererCommandTurnCompletion,
|
||||
RendererCommandTurnOutput, RendererCountEntry, RendererDedicatedWorkerTargetEvent,
|
||||
RendererDedicatedWorkerTargetInfo, RendererDevToolsAgentToken,
|
||||
RendererDevToolsMainCommandEnvelope, RendererDocumentBoxModel,
|
||||
PendingHtmlPage, PendingWorkerRuntimeInspectorSessionResponse, PreparedRendererDocument,
|
||||
RendererAccessibilityPayloadsForObjectId, RendererActivityDiagnostics,
|
||||
RendererAgentAttachmentId, RendererAutofillAddressField, RendererAutofillCreditCard,
|
||||
RendererAutofillTriggerOutcome, RendererAutofillTriggerRequest, RendererBrowserContextRuntime,
|
||||
RendererBrowserContextRuntimeId, RendererBrowserContextRuntimeOwner,
|
||||
RendererBrowserContextRuntimeOwnerAccess, RendererCaptureScreencastFrameReply,
|
||||
RendererCaptureScreencastFrameRequest, RendererCaptureScreenshotReply,
|
||||
RendererCaptureScreenshotRequest, RendererCapturedScreencastFrame, RendererCapturedScreenshot,
|
||||
RendererCommandTurnCompletion, RendererCommandTurnOutput, RendererCountEntry,
|
||||
RendererDedicatedWorkerTargetEvent, RendererDedicatedWorkerTargetInfo,
|
||||
RendererDevToolsAgentToken, RendererDevToolsMainCommandEnvelope, RendererDocumentBoxModel,
|
||||
RendererDocumentChildNodeSnapshotEvent, RendererDocumentChildNodeSnapshotEvents,
|
||||
RendererDocumentChildNodeSnapshots, RendererDocumentCommitPermit,
|
||||
RendererDocumentFrontendNodeIdsResolution, RendererDocumentHitTestResult,
|
||||
|
||||
@@ -115,23 +115,31 @@ impl RendererBrowserContextRuntime {
|
||||
};
|
||||
let response = response
|
||||
.route_to_worker_devtools_session_output(inspector_session_id.clone(), output_journal);
|
||||
let error_response = response.clone();
|
||||
let settlement = response
|
||||
.take_session_response_settlement_receiver()
|
||||
.expect("a Worker DevTools response must own one settlement receiver");
|
||||
let (response_tx, response_rx) = oneshot::channel();
|
||||
if !target.handle.dispatch_runtime_protocol_message(
|
||||
let dispatched = target.handle.dispatch_runtime_protocol_message(
|
||||
Some(inspector_session_id),
|
||||
raw_json,
|
||||
Some(response),
|
||||
response_tx,
|
||||
) {
|
||||
return Err("DedicatedWorkerRuntimeUnavailable".to_owned());
|
||||
}
|
||||
let dispatch = response_rx
|
||||
.await
|
||||
.map_err(|_| "DedicatedWorkerRuntimeUnavailable".to_owned())?;
|
||||
crate::runtime::CompletedWorkerRuntimeInspectorCommandDispatch::finish(dispatch, settlement)
|
||||
.await
|
||||
);
|
||||
let dispatch = if dispatched {
|
||||
response_rx
|
||||
.await
|
||||
.unwrap_or_else(|_| Err("DedicatedWorkerRuntimeUnavailable".to_owned()))
|
||||
} else {
|
||||
Err("DedicatedWorkerRuntimeUnavailable".to_owned())
|
||||
};
|
||||
Ok(
|
||||
crate::runtime::CompletedWorkerRuntimeInspectorCommandDispatch::finish(
|
||||
dispatch,
|
||||
settlement,
|
||||
error_response,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
async fn dispatch_dedicated_worker_runtime_protocol_message_with_optional_deferred_response(
|
||||
|
||||
@@ -308,9 +308,9 @@ use self::page_surface::RendererPageTable;
|
||||
pub use self::page_surface::RendererRuntimeInspectorMessageResponseOrder;
|
||||
pub use self::page_surface::{
|
||||
CompletedWorkerRuntimeInspectorCommandDispatch, DevToolsSessionKey,
|
||||
RendererAccessibilityPayloadsForObjectId, RendererActivityDiagnostics,
|
||||
RendererAgentAttachmentId, RendererAutofillAddressField, RendererAutofillCreditCard,
|
||||
RendererAutofillTriggerOutcome, RendererAutofillTriggerRequest,
|
||||
PendingWorkerRuntimeInspectorSessionResponse, RendererAccessibilityPayloadsForObjectId,
|
||||
RendererActivityDiagnostics, RendererAgentAttachmentId, RendererAutofillAddressField,
|
||||
RendererAutofillCreditCard, RendererAutofillTriggerOutcome, RendererAutofillTriggerRequest,
|
||||
RendererCaptureScreencastFrameReply, RendererCaptureScreenshotReply,
|
||||
RendererCapturedScreencastFrame, RendererCapturedScreenshot, RendererCommandTurnCompletion,
|
||||
RendererCommandTurnOutput, RendererCountEntry, RendererDedicatedWorkerTargetEvent,
|
||||
|
||||
@@ -2749,8 +2749,21 @@ impl RendererRuntimeInspectorSessionResponseSettlement {
|
||||
#[derive(Debug)]
|
||||
pub struct CompletedWorkerRuntimeInspectorCommandDispatch {
|
||||
messages: Vec<RendererRuntimeInspectorMessage>,
|
||||
predecessor: RendererOutputFence,
|
||||
response_succeeded: bool,
|
||||
pending_session_response: PendingWorkerRuntimeInspectorSessionResponse,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PendingWorkerRuntimeInspectorSessionResponse {
|
||||
settlement: oneshot::Receiver<RendererRuntimeInspectorSessionResponseSettlement>,
|
||||
}
|
||||
|
||||
impl PendingWorkerRuntimeInspectorSessionResponse {
|
||||
pub async fn wait(self) -> Result<(RendererOutputFence, bool), String> {
|
||||
self.settlement
|
||||
.await
|
||||
.map(RendererRuntimeInspectorSessionResponseSettlement::into_parts)
|
||||
.map_err(|_| "WorkerRuntimeInspectorResponseCanceled".to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl CompletedWorkerRuntimeInspectorCommandDispatch {
|
||||
@@ -2758,28 +2771,33 @@ impl CompletedWorkerRuntimeInspectorCommandDispatch {
|
||||
self,
|
||||
) -> (
|
||||
Vec<RendererRuntimeInspectorMessage>,
|
||||
RendererOutputFence,
|
||||
bool,
|
||||
PendingWorkerRuntimeInspectorSessionResponse,
|
||||
) {
|
||||
(self.messages, self.predecessor, self.response_succeeded)
|
||||
(self.messages, self.pending_session_response)
|
||||
}
|
||||
|
||||
pub(crate) async fn finish(
|
||||
pub(crate) fn finish(
|
||||
dispatch: Result<Vec<RendererRuntimeInspectorMessage>, String>,
|
||||
settlement: oneshot::Receiver<RendererRuntimeInspectorSessionResponseSettlement>,
|
||||
) -> Result<Self, String> {
|
||||
match settlement.await {
|
||||
Ok(settlement) => {
|
||||
let (predecessor, response_succeeded) = settlement.into_parts();
|
||||
Ok(Self {
|
||||
messages: dispatch.unwrap_or_default(),
|
||||
predecessor,
|
||||
response_succeeded,
|
||||
})
|
||||
error_response: RendererRuntimeInspectorResponseSender,
|
||||
) -> Self {
|
||||
let messages = match dispatch {
|
||||
Ok(messages) => messages,
|
||||
Err(message) => {
|
||||
let call_id = error_response.call_id();
|
||||
let _ = error_response.send(json!({
|
||||
"id": call_id,
|
||||
"error": {
|
||||
"code": -32000,
|
||||
"message": message,
|
||||
}
|
||||
}));
|
||||
Vec::new()
|
||||
}
|
||||
Err(_) => Err(dispatch
|
||||
.err()
|
||||
.unwrap_or_else(|| "WorkerRuntimeInspectorResponseCanceled".to_owned())),
|
||||
};
|
||||
Self {
|
||||
messages,
|
||||
pending_session_response: PendingWorkerRuntimeInspectorSessionResponse { settlement },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ impl ServiceWorkerRuntimeService {
|
||||
};
|
||||
let response = response
|
||||
.route_to_worker_devtools_session_output(inspector_session_id.clone(), output_journal);
|
||||
let error_response = response.clone();
|
||||
let settlement = response
|
||||
.take_session_response_settlement_receiver()
|
||||
.expect("a Worker DevTools response must own one settlement receiver");
|
||||
@@ -63,8 +64,13 @@ impl ServiceWorkerRuntimeService {
|
||||
response,
|
||||
)
|
||||
.await;
|
||||
crate::runtime::CompletedWorkerRuntimeInspectorCommandDispatch::finish(dispatch, settlement)
|
||||
.await
|
||||
Ok(
|
||||
crate::runtime::CompletedWorkerRuntimeInspectorCommandDispatch::finish(
|
||||
dispatch,
|
||||
settlement,
|
||||
error_response,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn detach_runtime_inspector_session(
|
||||
|
||||
@@ -50,6 +50,7 @@ impl SharedWorkerRuntimeService {
|
||||
inspector_session_id.clone(),
|
||||
host.target_output().clone(),
|
||||
);
|
||||
let error_response = response.clone();
|
||||
let settlement = response
|
||||
.take_session_response_settlement_receiver()
|
||||
.expect("a Worker DevTools response must own one settlement receiver");
|
||||
@@ -60,8 +61,13 @@ impl SharedWorkerRuntimeService {
|
||||
response,
|
||||
)
|
||||
.await;
|
||||
crate::runtime::CompletedWorkerRuntimeInspectorCommandDispatch::finish(dispatch, settlement)
|
||||
.await
|
||||
Ok(
|
||||
crate::runtime::CompletedWorkerRuntimeInspectorCommandDispatch::finish(
|
||||
dispatch,
|
||||
settlement,
|
||||
error_response,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn detach_runtime_inspector_session(
|
||||
|
||||
Reference in New Issue
Block a user