///|
fn BidiProtocol::close_wait_for_destroyed(
self : BidiProtocol,
context_id : String,
) -> Bool {
self.context_children.get(context_id).unwrap_or([]).length() > 0 ||
self.context_had_synthetic_child.get(context_id).unwrap_or(false)
}
///|
fn BidiProtocol::handle_browsing_context_get_close_metadata(
self : BidiProtocol,
request_id : Int,
params : Json?,
) -> Unit {
let map = match params {
Some(Object(map)) => map
_ => {
self.send_error(
request_id, "invalid argument", "params must be an object",
)
return
}
}
let context_id = match map.get("context") {
Some(String(context_id)) => context_id
_ => {
self.send_error(
request_id, "invalid argument", "context must be a string",
)
return
}
}
if !self.manager.has_session(context_id) {
self.send_error(
request_id,
"no such frame",
"Unknown context: " + context_id,
)
return
}
if self.context_parent.contains(context_id) {
self.send_error(request_id, "invalid argument", "context must be top-level")
return
}
let wait_for_destroyed = self.close_wait_for_destroyed(context_id)
self.send_success(
request_id,
Some(make_object({ "waitForDestroyed": Json::boolean(wait_for_destroyed) })),
)
}
///|
fn BidiProtocol::handle_browsing_context_close_with_state(
self : BidiProtocol,
request_id : Int,
params : Json?,
) -> Unit {
self.handle_browsing_context_close_mode(request_id, params, true)
}
///|
fn BidiProtocol::handle_browsing_context_close_result(
self : BidiProtocol,
request_id : Int,
params : Json?,
) -> Unit {
self.handle_browsing_context_close_mode(request_id, params, false)
}
///|
fn BidiProtocol::handle_browsing_context_close_mode(
self : BidiProtocol,
request_id : Int,
params : Json?,
include_wait_for_destroyed : Bool,
) -> Unit {
let map = match params {
Some(Object(map)) => map
_ => {
self.send_error(
request_id, "invalid argument", "params must be an object",
)
return
}
}
let context_id = match map.get("context") {
Some(String(context_id)) => context_id
_ => {
self.send_error(
request_id, "invalid argument", "context must be a string",
)
return
}
}
let prompt_unload = match
get_map_field_with_alias(map, "promptUnload", "prompt_unload") {
Some(True) => true
Some(False) | Some(Null) | None => false
Some(_) => {
self.send_error(
request_id, "invalid argument", "promptUnload must be a boolean",
)
return
}
}
if !self.manager.has_session(context_id) {
self.send_error(
request_id,
"no such frame",
"Unknown context: " + context_id,
)
return
}
if self.context_parent.contains(context_id) {
self.send_error(request_id, "invalid argument", "context must be top-level")
return
}
let wait_for_destroyed = self.close_wait_for_destroyed(context_id)
if prompt_unload && self.has_beforeunload_prompt_in_scope(context_id) {
let handler = self.resolve_unhandled_prompt_handler(
context_id, "beforeunload",
)
self.clear_pending_prompt_state(context_id)
self.pending_prompt_type[context_id] = "beforeunload"
self.pending_close_request[context_id] = request_id
self.pending_close_wait_for_destroyed[context_id] = wait_for_destroyed
self.pending_close_response_mode[context_id] = if include_wait_for_destroyed {
"wait"
} else {
"empty"
}
self.emit_user_prompt_opened(
context_id,
"beforeunload",
handler,
"beforeunload",
None,
)
return
}
if include_wait_for_destroyed {
self.send_success(
request_id,
Some(
make_object({ "waitForDestroyed": Json::boolean(wait_for_destroyed) }),
),
)
self.close_context_and_cleanup(context_id, true) |> ignore
} else {
self.close_context_and_cleanup(context_id, true) |> ignore
self.send_success(request_id, Some(make_object({})))
}
}