///|
fn BidiProtocol::abort_in_flight_navigation_unless_matching(
self : BidiProtocol,
ctx_id : String,
navigation_id : String?,
message : String,
) -> Unit {
let should_abort = match self.in_flight_navigation_id.get(ctx_id) {
Some(existing_navigation_id) =>
match navigation_id {
Some(target_navigation_id) =>
existing_navigation_id != target_navigation_id
None => true
}
None => false
}
if should_abort {
let _ = self.fail_in_flight_navigation(ctx_id, "aborted", message)
}
}
///|
fn BidiProtocol::complete_pending_navigation_response(
self : BidiProtocol,
ctx_id : String,
url : String?,
navigation_id : String?,
) -> Unit {
let resolved_navigation_id = match navigation_id {
Some(navigation_id) => navigation_id
None =>
match self.in_flight_navigation_id.get(ctx_id) {
Some(navigation_id) => navigation_id
None => return
}
}
match self.in_flight_navigation_id.get(ctx_id) {
Some(current_navigation_id) =>
if current_navigation_id != resolved_navigation_id {
return
}
None => ()
}
let resolved_url = match url {
Some(url) => url
None => self.in_flight_navigation_url.get(ctx_id).unwrap_or("about:blank")
}
match self.pending_navigation_request.get(ctx_id) {
Some(request_id) =>
if self.pending_navigation_response_mode.get(ctx_id).unwrap_or("state") ==
"url" {
self.send_success(request_id, Some(Json::string(resolved_url)))
} else {
self.send_success(
request_id,
Some(
make_object({
"navigation": Json::string(resolved_navigation_id),
"url": Json::string(resolved_url),
}),
),
)
}
None => ()
}
self.clear_pending_navigation_state(ctx_id)
}
///|
fn BidiProtocol::fail_pending_navigation_response(
self : BidiProtocol,
ctx_id : String,
navigation_id : String?,
message : String,
) -> Unit {
let resolved_navigation_id = match navigation_id {
Some(navigation_id) => navigation_id
None =>
match self.in_flight_navigation_id.get(ctx_id) {
Some(navigation_id) => navigation_id
None => return
}
}
match self.in_flight_navigation_id.get(ctx_id) {
Some(current_navigation_id) =>
if current_navigation_id != resolved_navigation_id {
return
}
None => ()
}
match self.pending_navigation_request.get(ctx_id) {
Some(request_id) => self.send_error(request_id, "unknown error", message)
None => ()
}
self.clear_pending_navigation_state(ctx_id)
}
///|
fn outbox_message_matches_pending_navigation_lifecycle(
message : BidiOutMessage,
ctx_id : String,
url : String,
navigation_id : String,
) -> Bool {
match message {
Event(evt) =>
if evt.event_method == "browsingContext.load" ||
evt.event_method == "browsingContext.domContentLoaded" {
get_string_field(evt.params, "context").unwrap_or("") == ctx_id &&
get_string_field(evt.params, "url").unwrap_or("") == url &&
get_string_field(evt.params, "navigation").unwrap_or("") ==
navigation_id
} else if evt.event_method == "browsingContext.historyUpdated" {
get_string_field(evt.params, "context").unwrap_or("") == ctx_id &&
get_string_field(evt.params, "url").unwrap_or("") == url
} else {
false
}
_ => false
}
}
///|
fn BidiProtocol::strip_pending_navigation_lifecycle_events(
self : BidiProtocol,
ctx_id : String,
url : String,
navigation_id : String,
) -> Unit {
let retained : Array[BidiOutMessage] = []
for message in self.outbox {
if !outbox_message_matches_pending_navigation_lifecycle(
message, ctx_id, url, navigation_id,
) {
retained.push(message)
}
}
self.outbox = retained
}