Replace HistoryEntryReplacement with NavigationHistoryBehavior from the navigation API (#34681)

Signed-off-by: Shane Handley <shanehandley@fastmail.com>
This commit is contained in:
shanehandley 2024-12-18 23:47:20 +11:00 committed by GitHub
parent 3cbc8c2442
commit 3a4e5d4245
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 127 additions and 108 deletions

View file

@ -138,9 +138,9 @@ use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent};
use script_traits::{ use script_traits::{
webdriver_msg, AnimationState, AnimationTickType, AuxiliaryBrowsingContextLoadInfo, webdriver_msg, AnimationState, AnimationTickType, AuxiliaryBrowsingContextLoadInfo,
BroadcastMsg, CompositorEvent, ConstellationControlMsg, DiscardBrowsingContext, BroadcastMsg, CompositorEvent, ConstellationControlMsg, DiscardBrowsingContext,
DocumentActivity, DocumentState, GamepadEvent, HistoryEntryReplacement, IFrameLoadInfo, DocumentActivity, DocumentState, GamepadEvent, IFrameLoadInfo, IFrameLoadInfoWithData,
IFrameLoadInfoWithData, IFrameSandboxState, IFrameSizeMsg, Job, LayoutMsg as FromLayoutMsg, IFrameSandboxState, IFrameSizeMsg, Job, LayoutMsg as FromLayoutMsg, LoadData, LoadOrigin,
LoadData, LoadOrigin, LogEntry, MediaSessionActionType, MessagePortMsg, MouseEventType, LogEntry, MediaSessionActionType, MessagePortMsg, MouseEventType, NavigationHistoryBehavior,
PortMessageTask, SWManagerMsg, SWManagerSenders, ScriptMsg as FromScriptMsg, PortMessageTask, SWManagerMsg, SWManagerSenders, ScriptMsg as FromScriptMsg,
ScriptToConstellationChan, ServiceWorkerManagerFactory, ServiceWorkerMsg, ScriptToConstellationChan, ServiceWorkerManagerFactory, ServiceWorkerMsg,
StructuredSerializedData, Theme, TimerSchedulerMsg, TraversalDirection, UpdatePipelineIdReason, StructuredSerializedData, Theme, TimerSchedulerMsg, TraversalDirection, UpdatePipelineIdReason,
@ -175,7 +175,7 @@ use crate::session_history::{
use crate::timer_scheduler::TimerScheduler; use crate::timer_scheduler::TimerScheduler;
use crate::webview::WebViewManager; use crate::webview::WebViewManager;
type PendingApprovalNavigations = HashMap<PipelineId, (LoadData, HistoryEntryReplacement)>; type PendingApprovalNavigations = HashMap<PipelineId, (LoadData, NavigationHistoryBehavior)>;
#[derive(Debug)] #[derive(Debug)]
/// The state used by MessagePortInfo to represent the various states the port can be in. /// The state used by MessagePortInfo to represent the various states the port can be in.
@ -1373,13 +1373,13 @@ where
}; };
match pending { match pending {
Some((load_data, replace)) => { Some((load_data, history_handling)) => {
if allowed { if allowed {
self.load_url( self.load_url(
top_level_browsing_context_id, top_level_browsing_context_id,
pipeline_id, pipeline_id,
load_data, load_data,
replace, history_handling,
); );
} else { } else {
let pipeline_is_top_level_pipeline = self let pipeline_is_top_level_pipeline = self
@ -1449,7 +1449,7 @@ where
top_level_browsing_context_id, top_level_browsing_context_id,
pipeline_id, pipeline_id,
load_data, load_data,
HistoryEntryReplacement::Disabled, NavigationHistoryBehavior::Push,
); );
}, },
FromCompositorMsg::IsReadyToSaveImage(pipeline_states) => { FromCompositorMsg::IsReadyToSaveImage(pipeline_states) => {
@ -1673,8 +1673,13 @@ where
self.handle_change_running_animations_state(source_pipeline_id, animation_state) self.handle_change_running_animations_state(source_pipeline_id, animation_state)
}, },
// Ask the embedder for permission to load a new page. // Ask the embedder for permission to load a new page.
FromScriptMsg::LoadUrl(load_data, replace) => { FromScriptMsg::LoadUrl(load_data, history_handling) => {
self.schedule_navigation(source_top_ctx_id, source_pipeline_id, load_data, replace); self.schedule_navigation(
source_top_ctx_id,
source_pipeline_id,
load_data,
history_handling,
);
}, },
FromScriptMsg::AbortLoadUrl => { FromScriptMsg::AbortLoadUrl => {
self.handle_abort_load_url_msg(source_pipeline_id); self.handle_abort_load_url_msg(source_pipeline_id);
@ -3273,7 +3278,7 @@ where
top_level_browsing_context_id, top_level_browsing_context_id,
new_pipeline_id, new_pipeline_id,
is_private, is_private,
mut replace, mut history_handling,
.. ..
} = load_info.info; } = load_info.info;
@ -3286,7 +3291,7 @@ where
// see https://html.spec.whatwg.org/multipage/#the-iframe-element:completely-loaded // see https://html.spec.whatwg.org/multipage/#the-iframe-element:completely-loaded
if let Some(old_pipeline) = old_pipeline { if let Some(old_pipeline) = old_pipeline {
if !old_pipeline.completely_loaded { if !old_pipeline.completely_loaded {
replace = HistoryEntryReplacement::Enabled; history_handling = NavigationHistoryBehavior::Replace;
} }
debug!( debug!(
"{:?}: Old pipeline is {}completely loaded", "{:?}: Old pipeline is {}completely loaded",
@ -3332,11 +3337,10 @@ where
}, },
}; };
let replace = match replace { let replace = if history_handling == NavigationHistoryBehavior::Replace {
HistoryEntryReplacement::Enabled => { Some(NeedsToReload::No(browsing_context.pipeline_id))
Some(NeedsToReload::No(browsing_context.pipeline_id)) } else {
}, None
HistoryEntryReplacement::Disabled => None,
}; };
// https://github.com/rust-lang/rust/issues/59159 // https://github.com/rust-lang/rust/issues/59159
@ -3592,7 +3596,7 @@ where
top_level_browsing_context_id: TopLevelBrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId,
source_id: PipelineId, source_id: PipelineId,
load_data: LoadData, load_data: LoadData,
replace: HistoryEntryReplacement, history_handling: NavigationHistoryBehavior,
) { ) {
match self.pending_approval_navigations.entry(source_id) { match self.pending_approval_navigations.entry(source_id) {
Entry::Occupied(_) => { Entry::Occupied(_) => {
@ -3602,7 +3606,7 @@ where
); );
}, },
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
let _ = entry.insert((load_data.clone(), replace)); let _ = entry.insert((load_data.clone(), history_handling));
}, },
}; };
// Allow the embedder to handle the url itself // Allow the embedder to handle the url itself
@ -3622,14 +3626,15 @@ where
top_level_browsing_context_id: TopLevelBrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId,
source_id: PipelineId, source_id: PipelineId,
load_data: LoadData, load_data: LoadData,
replace: HistoryEntryReplacement, history_handling: NavigationHistoryBehavior,
) -> Option<PipelineId> { ) -> Option<PipelineId> {
debug!( debug!(
"{}: Loading ({}replacing): {}", "{}: Loading ({}replacing): {}",
source_id, source_id,
match replace { match history_handling {
HistoryEntryReplacement::Enabled => "", NavigationHistoryBehavior::Push => "",
HistoryEntryReplacement::Disabled => "not ", NavigationHistoryBehavior::Replace => "not ",
NavigationHistoryBehavior::Auto => "unsure if ",
}, },
load_data.url, load_data.url,
); );
@ -3676,7 +3681,7 @@ where
parent_pipeline_id, parent_pipeline_id,
browsing_context_id, browsing_context_id,
load_data, load_data,
replace, history_handling,
); );
let result = match self.pipelines.get(&parent_pipeline_id) { let result = match self.pipelines.get(&parent_pipeline_id) {
Some(parent_pipeline) => parent_pipeline.event_loop.send(msg), Some(parent_pipeline) => parent_pipeline.event_loop.send(msg),
@ -3712,9 +3717,10 @@ where
// Create the new pipeline // Create the new pipeline
let replace = match replace { let replace = if history_handling == NavigationHistoryBehavior::Replace {
HistoryEntryReplacement::Enabled => Some(NeedsToReload::No(pipeline_id)), Some(NeedsToReload::No(pipeline_id))
HistoryEntryReplacement::Disabled => None, } else {
None
}; };
let new_pipeline_id = PipelineId::new(); let new_pipeline_id = PipelineId::new();
@ -3826,7 +3832,7 @@ where
&mut self, &mut self,
pipeline_id: PipelineId, pipeline_id: PipelineId,
new_url: ServoUrl, new_url: ServoUrl,
replacement_enabled: HistoryEntryReplacement, history_handling: NavigationHistoryBehavior,
) { ) {
let (top_level_browsing_context_id, old_url) = match self.pipelines.get_mut(&pipeline_id) { let (top_level_browsing_context_id, old_url) = match self.pipelines.get_mut(&pipeline_id) {
Some(pipeline) => { Some(pipeline) => {
@ -3838,18 +3844,20 @@ where
}, },
}; };
match replacement_enabled { match history_handling {
HistoryEntryReplacement::Disabled => { NavigationHistoryBehavior::Replace => {},
_ => {
let diff = SessionHistoryDiff::Hash { let diff = SessionHistoryDiff::Hash {
pipeline_reloader: NeedsToReload::No(pipeline_id), pipeline_reloader: NeedsToReload::No(pipeline_id),
new_url, new_url,
old_url, old_url,
}; };
self.get_joint_session_history(top_level_browsing_context_id) self.get_joint_session_history(top_level_browsing_context_id)
.push_diff(diff); .push_diff(diff);
self.notify_history_changed(top_level_browsing_context_id); self.notify_history_changed(top_level_browsing_context_id);
}, },
HistoryEntryReplacement::Enabled => {},
} }
} }
@ -4662,7 +4670,7 @@ where
top_level_browsing_context_id, top_level_browsing_context_id,
load_data, load_data,
response_sender, response_sender,
HistoryEntryReplacement::Disabled, NavigationHistoryBehavior::Push,
); );
}, },
WebDriverCommandMsg::Refresh(top_level_browsing_context_id, response_sender) => { WebDriverCommandMsg::Refresh(top_level_browsing_context_id, response_sender) => {
@ -4681,7 +4689,7 @@ where
top_level_browsing_context_id, top_level_browsing_context_id,
load_data, load_data,
response_sender, response_sender,
HistoryEntryReplacement::Enabled, NavigationHistoryBehavior::Replace,
); );
}, },
WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd) => { WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd) => {
@ -4909,7 +4917,7 @@ where
top_level_browsing_context_id: TopLevelBrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId,
load_data: LoadData, load_data: LoadData,
response_sender: IpcSender<webdriver_msg::LoadStatus>, response_sender: IpcSender<webdriver_msg::LoadStatus>,
replace: HistoryEntryReplacement, history_handling: NavigationHistoryBehavior,
) { ) {
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) { let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
@ -4926,7 +4934,7 @@ where
top_level_browsing_context_id, top_level_browsing_context_id,
pipeline_id, pipeline_id,
load_data, load_data,
replace, history_handling,
) { ) {
debug!( debug!(
"Setting up webdriver load notification for {:?}", "Setting up webdriver load notification for {:?}",

View file

@ -15,7 +15,7 @@ use js::rust::HandleObject;
use mime::{self, Mime}; use mime::{self, Mime};
use net_traits::http_percent_encode; use net_traits::http_percent_encode;
use net_traits::request::Referrer; use net_traits::request::Referrer;
use script_traits::{HistoryEntryReplacement, LoadData, LoadOrigin}; use script_traits::{LoadData, LoadOrigin, NavigationHistoryBehavior};
use servo_atoms::Atom; use servo_atoms::Atom;
use servo_rand::random; use servo_rand::random;
use style::attr::AttrValue; use style::attr::AttrValue;
@ -1030,7 +1030,7 @@ impl HTMLFormElement {
window window
.root() .root()
.load_url( .load_url(
HistoryEntryReplacement::Disabled, NavigationHistoryBehavior::Push,
false, false,
load_data, load_data,
CanGc::note(), CanGc::note(),

View file

@ -13,8 +13,8 @@ use net_traits::ReferrerPolicy;
use profile_traits::ipc as ProfiledIpc; use profile_traits::ipc as ProfiledIpc;
use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed}; use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
use script_traits::{ use script_traits::{
HistoryEntryReplacement, IFrameLoadInfo, IFrameLoadInfoWithData, JsEvalResult, LoadData, IFrameLoadInfo, IFrameLoadInfoWithData, JsEvalResult, LoadData, LoadOrigin,
LoadOrigin, NewLayoutInfo, ScriptMsg, UpdatePipelineIdReason, WindowSizeData, NavigationHistoryBehavior, NewLayoutInfo, ScriptMsg, UpdatePipelineIdReason, WindowSizeData,
}; };
use servo_atoms::Atom; use servo_atoms::Atom;
use servo_url::ServoUrl; use servo_url::ServoUrl;
@ -117,17 +117,22 @@ impl HTMLIFrameElement {
pub fn navigate_or_reload_child_browsing_context( pub fn navigate_or_reload_child_browsing_context(
&self, &self,
load_data: LoadData, load_data: LoadData,
replace: HistoryEntryReplacement, history_handling: NavigationHistoryBehavior,
can_gc: CanGc, can_gc: CanGc,
) { ) {
self.start_new_pipeline(load_data, PipelineType::Navigation, replace, can_gc); self.start_new_pipeline(
load_data,
PipelineType::Navigation,
history_handling,
can_gc,
);
} }
fn start_new_pipeline( fn start_new_pipeline(
&self, &self,
mut load_data: LoadData, mut load_data: LoadData,
pipeline_type: PipelineType, pipeline_type: PipelineType,
replace: HistoryEntryReplacement, history_handling: NavigationHistoryBehavior,
can_gc: CanGc, can_gc: CanGc,
) { ) {
let sandboxed = if self.is_sandboxed() { let sandboxed = if self.is_sandboxed() {
@ -191,7 +196,7 @@ impl HTMLIFrameElement {
new_pipeline_id, new_pipeline_id,
is_private: false, // FIXME is_private: false, // FIXME
inherited_secure_context: load_data.inherited_secure_context, inherited_secure_context: load_data.inherited_secure_context,
replace, history_handling,
}; };
let window_size = WindowSizeData { let window_size = WindowSizeData {
@ -269,7 +274,7 @@ impl HTMLIFrameElement {
load_data.srcdoc = String::from(element.get_string_attribute(&local_name!("srcdoc"))); load_data.srcdoc = String::from(element.get_string_attribute(&local_name!("srcdoc")));
self.navigate_or_reload_child_browsing_context( self.navigate_or_reload_child_browsing_context(
load_data, load_data,
HistoryEntryReplacement::Disabled, NavigationHistoryBehavior::Push,
can_gc, can_gc,
); );
return; return;
@ -361,12 +366,14 @@ impl HTMLIFrameElement {
// see https://html.spec.whatwg.org/multipage/#the-iframe-element:about:blank-3 // see https://html.spec.whatwg.org/multipage/#the-iframe-element:about:blank-3
let is_about_blank = let is_about_blank =
pipeline_id.is_some() && pipeline_id == self.about_blank_pipeline_id.get(); pipeline_id.is_some() && pipeline_id == self.about_blank_pipeline_id.get();
let replace = if is_about_blank {
HistoryEntryReplacement::Enabled let history_handling = if is_about_blank {
NavigationHistoryBehavior::Replace
} else { } else {
HistoryEntryReplacement::Disabled NavigationHistoryBehavior::Push
}; };
self.navigate_or_reload_child_browsing_context(load_data, replace, can_gc);
self.navigate_or_reload_child_browsing_context(load_data, history_handling, can_gc);
} }
fn create_nested_browsing_context(&self, can_gc: CanGc) { fn create_nested_browsing_context(&self, can_gc: CanGc) {
@ -407,7 +414,7 @@ impl HTMLIFrameElement {
self.start_new_pipeline( self.start_new_pipeline(
load_data, load_data,
PipelineType::InitialAboutBlank, PipelineType::InitialAboutBlank,
HistoryEntryReplacement::Disabled, NavigationHistoryBehavior::Push,
can_gc, can_gc,
); );
} }

View file

@ -10,7 +10,7 @@ use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix}; use html5ever::{LocalName, Prefix};
use js::rust::HandleObject; use js::rust::HandleObject;
use regex::bytes::Regex; use regex::bytes::Regex;
use script_traits::HistoryEntryReplacement; use script_traits::NavigationHistoryBehavior;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use style::str::HTML_SPACE_CHARACTERS; use style::str::HTML_SPACE_CHARACTERS;
@ -49,7 +49,7 @@ impl RefreshRedirectDue {
pub fn invoke(self, can_gc: CanGc) { pub fn invoke(self, can_gc: CanGc) {
self.window.Location().navigate( self.window.Location().navigate(
self.url.clone(), self.url.clone(),
HistoryEntryReplacement::Enabled, NavigationHistoryBehavior::Replace,
NavigationType::DeclarativeRefresh, NavigationType::DeclarativeRefresh,
can_gc, can_gc,
); );

View file

@ -4,7 +4,7 @@
use dom_struct::dom_struct; use dom_struct::dom_struct;
use net_traits::request::Referrer; use net_traits::request::Referrer;
use script_traits::{HistoryEntryReplacement, LoadData, LoadOrigin}; use script_traits::{LoadData, LoadOrigin, NavigationHistoryBehavior};
use servo_url::{MutableOrigin, ServoUrl}; use servo_url::{MutableOrigin, ServoUrl};
use crate::dom::bindings::codegen::Bindings::LocationBinding::LocationMethods; use crate::dom::bindings::codegen::Bindings::LocationBinding::LocationMethods;
@ -69,7 +69,7 @@ impl Location {
pub fn navigate( pub fn navigate(
&self, &self,
url: ServoUrl, url: ServoUrl,
replacement_flag: HistoryEntryReplacement, history_handling: NavigationHistoryBehavior,
navigation_type: NavigationType, navigation_type: NavigationType,
can_gc: CanGc, can_gc: CanGc,
) { ) {
@ -131,7 +131,7 @@ impl Location {
None, // Top navigation doesn't inherit secure context None, // Top navigation doesn't inherit secure context
); );
self.window self.window
.load_url(replacement_flag, reload_triggered, load_data, can_gc); .load_url(history_handling, reload_triggered, load_data, can_gc);
} }
/// Get if this `Location`'s [relevant `Document`][1] is non-null. /// Get if this `Location`'s [relevant `Document`][1] is non-null.
@ -233,7 +233,7 @@ impl Location {
// Step 6: Location-object navigate to copyURL. // Step 6: Location-object navigate to copyURL.
self.navigate( self.navigate(
copy_url, copy_url,
HistoryEntryReplacement::Disabled, NavigationHistoryBehavior::Push,
NavigationType::Normal, NavigationType::Normal,
can_gc, can_gc,
); );
@ -254,7 +254,7 @@ impl Location {
let url = self.window.get_url(); let url = self.window.get_url();
self.navigate( self.navigate(
url, url,
HistoryEntryReplacement::Enabled, NavigationHistoryBehavior::Replace,
NavigationType::ReloadByConstellation, NavigationType::ReloadByConstellation,
can_gc, can_gc,
); );
@ -290,7 +290,7 @@ impl LocationMethods<crate::DomTypeHolder> for Location {
let url = self.get_url_if_same_origin()?; let url = self.get_url_if_same_origin()?;
self.navigate( self.navigate(
url, url,
HistoryEntryReplacement::Enabled, NavigationHistoryBehavior::Replace,
NavigationType::ReloadByScript, NavigationType::ReloadByScript,
can_gc, can_gc,
); );
@ -312,7 +312,7 @@ impl LocationMethods<crate::DomTypeHolder> for Location {
// the replacement flag set. // the replacement flag set.
self.navigate( self.navigate(
url, url,
HistoryEntryReplacement::Enabled, NavigationHistoryBehavior::Replace,
NavigationType::Normal, NavigationType::Normal,
can_gc, can_gc,
); );
@ -424,7 +424,7 @@ impl LocationMethods<crate::DomTypeHolder> for Location {
// Step 3: Location-object navigate to the resulting URL record. // Step 3: Location-object navigate to the resulting URL record.
self.navigate( self.navigate(
url, url,
HistoryEntryReplacement::Disabled, NavigationHistoryBehavior::Push,
NavigationType::Normal, NavigationType::Normal,
can_gc, can_gc,
); );

View file

@ -56,7 +56,7 @@ use script_layout_interface::{
}; };
use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use script_traits::{ use script_traits::{
ConstellationControlMsg, DocumentState, HistoryEntryReplacement, IFrameSizeMsg, LoadData, ConstellationControlMsg, DocumentState, IFrameSizeMsg, LoadData, NavigationHistoryBehavior,
ScriptMsg, ScriptToConstellationChan, ScrollState, StructuredSerializedData, Theme, ScriptMsg, ScriptToConstellationChan, ScrollState, StructuredSerializedData, Theme,
TimerSchedulerMsg, WindowSizeData, WindowSizeType, TimerSchedulerMsg, WindowSizeData, WindowSizeType,
}; };
@ -2387,7 +2387,7 @@ impl Window {
/// <https://html.spec.whatwg.org/multipage/#navigating-across-documents> /// <https://html.spec.whatwg.org/multipage/#navigating-across-documents>
pub fn load_url( pub fn load_url(
&self, &self,
replace: HistoryEntryReplacement, history_handling: NavigationHistoryBehavior,
force_reload: bool, force_reload: bool,
load_data: LoadData, load_data: LoadData,
can_gc: CanGc, can_gc: CanGc,
@ -2403,7 +2403,7 @@ impl Window {
if let Some(fragment) = load_data.url.fragment() { if let Some(fragment) = load_data.url.fragment() {
self.send_to_constellation(ScriptMsg::NavigatedToFragment( self.send_to_constellation(ScriptMsg::NavigatedToFragment(
load_data.url.clone(), load_data.url.clone(),
replace, history_handling,
)); ));
doc.check_and_scroll_fragment(fragment, can_gc); doc.check_and_scroll_fragment(fragment, can_gc);
let this = Trusted::new(self); let this = Trusted::new(self);
@ -2462,7 +2462,7 @@ impl Window {
window_proxy.browsing_context_id(), window_proxy.browsing_context_id(),
pipeline_id, pipeline_id,
load_data, load_data,
replace, history_handling,
); );
}; };
} }

View file

@ -31,8 +31,8 @@ use js::JSCLASS_IS_GLOBAL;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use net_traits::request::Referrer; use net_traits::request::Referrer;
use script_traits::{ use script_traits::{
AuxiliaryBrowsingContextLoadInfo, HistoryEntryReplacement, LoadData, LoadOrigin, NewLayoutInfo, AuxiliaryBrowsingContextLoadInfo, LoadData, LoadOrigin, NavigationHistoryBehavior,
ScriptMsg, NewLayoutInfo, ScriptMsg,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_url::{ImmutableOrigin, ServoUrl}; use servo_url::{ImmutableOrigin, ServoUrl};
@ -526,12 +526,13 @@ impl WindowProxy {
referrer_policy, referrer_policy,
Some(secure), Some(secure),
); );
let replacement_flag = if new { let history_handling = if new {
HistoryEntryReplacement::Enabled NavigationHistoryBehavior::Replace
} else { } else {
HistoryEntryReplacement::Disabled NavigationHistoryBehavior::Push
}; };
target_window.load_url(replacement_flag, false, load_data, can_gc);
target_window.load_url(history_handling, false, load_data, can_gc);
} }
if noopener { if noopener {
// Step 15 (Dis-owning has been done in create_auxiliary_browsing_context). // Step 15 (Dis-owning has been done in create_auxiliary_browsing_context).

View file

@ -7,7 +7,7 @@
use html5ever::{local_name, namespace_url, ns}; use html5ever::{local_name, namespace_url, ns};
use malloc_size_of::malloc_size_of_is_0; use malloc_size_of::malloc_size_of_is_0;
use net_traits::request::Referrer; use net_traits::request::Referrer;
use script_traits::{HistoryEntryReplacement, LoadData, LoadOrigin}; use script_traits::{LoadData, LoadOrigin, NavigationHistoryBehavior};
use style::str::HTML_SPACE_CHARACTERS; use style::str::HTML_SPACE_CHARACTERS;
use crate::dom::bindings::codegen::Bindings::AttrBinding::Attr_Binding::AttrMethods; use crate::dom::bindings::codegen::Bindings::AttrBinding::Attr_Binding::AttrMethods;
@ -367,20 +367,17 @@ pub fn follow_hyperlink(
let noopener = relations.get_element_noopener(target_attribute_value.as_ref()); let noopener = relations.get_element_noopener(target_attribute_value.as_ref());
// Step 7. // Step 7.
let (maybe_chosen, replace) = match target_attribute_value { let (maybe_chosen, history_handling) = match target_attribute_value {
Some(name) => { Some(name) => {
let (maybe_chosen, new) = source.choose_browsing_context(name, noopener); let (maybe_chosen, new) = source.choose_browsing_context(name, noopener);
let replace = if new { let history_handling = if new {
HistoryEntryReplacement::Enabled NavigationHistoryBehavior::Replace
} else { } else {
HistoryEntryReplacement::Disabled NavigationHistoryBehavior::Push
}; };
(maybe_chosen, replace) (maybe_chosen, history_handling)
}, },
None => ( None => (Some(window.window_proxy()), NavigationHistoryBehavior::Push),
Some(window.window_proxy()),
HistoryEntryReplacement::Disabled,
),
}; };
// Step 8. // Step 8.
@ -433,7 +430,7 @@ pub fn follow_hyperlink(
let target = Trusted::new(target_window); let target = Trusted::new(target_window);
let task = task!(navigate_follow_hyperlink: move || { let task = task!(navigate_follow_hyperlink: move || {
debug!("following hyperlink to {}", load_data.url); debug!("following hyperlink to {}", load_data.url);
target.root().load_url(replace, false, load_data, CanGc::note()); target.root().load_url(history_handling, false, load_data, CanGc::note());
}); });
target_window target_window
.task_manager() .task_manager()

View file

@ -82,9 +82,9 @@ use script_layout_interface::{
use script_traits::webdriver_msg::WebDriverScriptCommand; use script_traits::webdriver_msg::WebDriverScriptCommand;
use script_traits::{ use script_traits::{
CompositorEvent, ConstellationControlMsg, DiscardBrowsingContext, DocumentActivity, CompositorEvent, ConstellationControlMsg, DiscardBrowsingContext, DocumentActivity,
EventResult, HistoryEntryReplacement, InitialScriptState, JsEvalResult, LayoutMsg, LoadData, EventResult, InitialScriptState, JsEvalResult, LayoutMsg, LoadData, LoadOrigin,
LoadOrigin, MediaSessionActionType, MouseButton, MouseEventType, NewLayoutInfo, Painter, MediaSessionActionType, MouseButton, MouseEventType, NavigationHistoryBehavior, NewLayoutInfo,
ProgressiveWebMetricType, ScriptMsg, ScriptToConstellationChan, ScrollState, Painter, ProgressiveWebMetricType, ScriptMsg, ScriptToConstellationChan, ScrollState,
StructuredSerializedData, Theme, TimerSchedulerMsg, TouchEventType, TouchId, StructuredSerializedData, Theme, TimerSchedulerMsg, TouchEventType, TouchId,
UntrustedNodeAddress, UpdatePipelineIdReason, WheelDelta, WindowSizeData, WindowSizeType, UntrustedNodeAddress, UpdatePipelineIdReason, WheelDelta, WindowSizeData, WindowSizeType,
}; };
@ -915,7 +915,7 @@ impl ScriptThread {
browsing_context: BrowsingContextId, browsing_context: BrowsingContextId,
pipeline_id: PipelineId, pipeline_id: PipelineId,
mut load_data: LoadData, mut load_data: LoadData,
replace: HistoryEntryReplacement, history_handling: NavigationHistoryBehavior,
) { ) {
with_script_thread(|script_thread| { with_script_thread(|script_thread| {
let is_javascript = load_data.url.scheme() == "javascript"; let is_javascript = load_data.url.scheme() == "javascript";
@ -936,7 +936,7 @@ impl ScriptThread {
if ScriptThread::check_load_origin(&load_data.load_origin, &window.get_url().origin()) { if ScriptThread::check_load_origin(&load_data.load_origin, &window.get_url().origin()) {
ScriptThread::eval_js_url(&trusted_global.root(), &mut load_data, CanGc::note()); ScriptThread::eval_js_url(&trusted_global.root(), &mut load_data, CanGc::note());
sender sender
.send((pipeline_id, ScriptMsg::LoadUrl(load_data, replace))) .send((pipeline_id, ScriptMsg::LoadUrl(load_data, history_handling)))
.unwrap(); .unwrap();
} }
} }
@ -955,7 +955,7 @@ impl ScriptThread {
script_thread script_thread
.script_sender .script_sender
.send((pipeline_id, ScriptMsg::LoadUrl(load_data, replace))) .send((pipeline_id, ScriptMsg::LoadUrl(load_data, history_handling)))
.expect("Sending a LoadUrl message to the constellation failed"); .expect("Sending a LoadUrl message to the constellation failed");
} }
}); });
@ -2242,12 +2242,12 @@ impl ScriptThread {
parent_pipeline_id, parent_pipeline_id,
browsing_context_id, browsing_context_id,
load_data, load_data,
replace, history_handling,
) => self.handle_navigate_iframe( ) => self.handle_navigate_iframe(
parent_pipeline_id, parent_pipeline_id,
browsing_context_id, browsing_context_id,
load_data, load_data,
replace, history_handling,
can_gc, can_gc,
), ),
ConstellationControlMsg::UnloadDocument(pipeline_id) => { ConstellationControlMsg::UnloadDocument(pipeline_id) => {
@ -3923,7 +3923,7 @@ impl ScriptThread {
parent_pipeline_id: PipelineId, parent_pipeline_id: PipelineId,
browsing_context_id: BrowsingContextId, browsing_context_id: BrowsingContextId,
load_data: LoadData, load_data: LoadData,
replace: HistoryEntryReplacement, history_handling: NavigationHistoryBehavior,
can_gc: CanGc, can_gc: CanGc,
) { ) {
let iframe = self let iframe = self
@ -3931,7 +3931,7 @@ impl ScriptThread {
.borrow() .borrow()
.find_iframe(parent_pipeline_id, browsing_context_id); .find_iframe(parent_pipeline_id, browsing_context_id);
if let Some(iframe) = iframe { if let Some(iframe) = iframe {
iframe.navigate_or_reload_child_browsing_context(load_data, replace, can_gc); iframe.navigate_or_reload_child_browsing_context(load_data, history_handling, can_gc);
} }
} }

View file

@ -64,9 +64,9 @@ use webrender_traits::{
}; };
pub use crate::script_msg::{ pub use crate::script_msg::{
DOMMessage, EventResult, HistoryEntryReplacement, IFrameSizeMsg, Job, JobError, JobResult, DOMMessage, EventResult, IFrameSizeMsg, Job, JobError, JobResult, JobResultValue, JobType,
JobResultValue, JobType, LayoutMsg, LogEntry, SWManagerMsg, SWManagerSenders, ScopeThings, LayoutMsg, LogEntry, SWManagerMsg, SWManagerSenders, ScopeThings, ScriptMsg, ServiceWorkerMsg,
ScriptMsg, ServiceWorkerMsg, TraversalDirection, TraversalDirection,
}; };
use crate::serializable::{BlobData, BlobImpl}; use crate::serializable::{BlobData, BlobImpl};
use crate::transferable::MessagePortImpl; use crate::transferable::MessagePortImpl;
@ -233,6 +233,21 @@ pub enum DiscardBrowsingContext {
No, No,
} }
/// <https://html.spec.whatwg.org/multipage/#navigation-supporting-concepts:navigationhistorybehavior>
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
pub enum NavigationHistoryBehavior {
/// The default value, which will be converted very early in the navigate algorithm into "push"
/// or "replace". Usually it becomes "push", but under certain circumstances it becomes
/// "replace" instead.
#[default]
Auto,
/// A regular navigation which adds a new session history entry, and will clear the forward
/// session history.
Push,
/// A navigation that will replace the active session history entry.
Replace,
}
/// Is a document fully active, active or inactive? /// Is a document fully active, active or inactive?
/// A document is active if it is the current active document in its session history, /// A document is active if it is the current active document in its session history,
/// it is fuly active if it is active and all of its ancestors are active, /// it is fuly active if it is active and all of its ancestors are active,
@ -316,7 +331,7 @@ pub enum ConstellationControlMsg {
PipelineId, PipelineId,
BrowsingContextId, BrowsingContextId,
LoadData, LoadData,
HistoryEntryReplacement, NavigationHistoryBehavior,
), ),
/// Post a message to a given window. /// Post a message to a given window.
PostMessage { PostMessage {
@ -721,9 +736,9 @@ pub struct IFrameLoadInfo {
pub is_private: bool, pub is_private: bool,
/// Whether this iframe should be considered secure /// Whether this iframe should be considered secure
pub inherited_secure_context: Option<bool>, pub inherited_secure_context: Option<bool>,
/// Wether this load should replace the current entry (reload). If true, the current /// Whether this load should replace the current entry (reload). If true, the current
/// entry will be replaced instead of a new entry being added. /// entry will be replaced instead of a new entry being added.
pub replace: HistoryEntryReplacement, pub history_handling: NavigationHistoryBehavior,
} }
/// Specifies the information required to load a URL in an iframe. /// Specifies the information required to load a URL in an iframe.

View file

@ -28,8 +28,8 @@ use webgpu::{wgc, WebGPU, WebGPUResponse};
use crate::{ use crate::{
AnimationState, AuxiliaryBrowsingContextLoadInfo, BroadcastMsg, DocumentState, AnimationState, AuxiliaryBrowsingContextLoadInfo, BroadcastMsg, DocumentState,
IFrameLoadInfoWithData, LoadData, MessagePortMsg, PortMessageTask, StructuredSerializedData, IFrameLoadInfoWithData, LoadData, MessagePortMsg, NavigationHistoryBehavior, PortMessageTask,
WindowSizeType, WorkerGlobalScopeInit, WorkerScriptLoadOrigin, StructuredSerializedData, WindowSizeType, WorkerGlobalScopeInit, WorkerScriptLoadOrigin,
}; };
/// An iframe sizing operation. /// An iframe sizing operation.
@ -83,15 +83,6 @@ pub enum LogEntry {
Warn(String), Warn(String),
} }
/// <https://html.spec.whatwg.org/multipage/#replacement-enabled>
#[derive(Debug, Deserialize, Serialize)]
pub enum HistoryEntryReplacement {
/// Traverse the history with replacement enabled.
Enabled,
/// Traverse the history with replacement disabled.
Disabled,
}
/// Messages from the script to the constellation. /// Messages from the script to the constellation.
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub enum ScriptMsg { pub enum ScriptMsg {
@ -181,7 +172,7 @@ pub enum ScriptMsg {
LoadComplete, LoadComplete,
/// A new load has been requested, with an option to replace the current entry once loaded /// A new load has been requested, with an option to replace the current entry once loaded
/// instead of adding a new entry. /// instead of adding a new entry.
LoadUrl(LoadData, HistoryEntryReplacement), LoadUrl(LoadData, NavigationHistoryBehavior),
/// Abort loading after sending a LoadUrl message. /// Abort loading after sending a LoadUrl message.
AbortLoadUrl, AbortLoadUrl,
/// Post a message to the currently active window of a given browsing context. /// Post a message to the currently active window of a given browsing context.
@ -199,7 +190,7 @@ pub enum ScriptMsg {
data: StructuredSerializedData, data: StructuredSerializedData,
}, },
/// Inform the constellation that a fragment was navigated to and whether or not it was a replacement navigation. /// Inform the constellation that a fragment was navigated to and whether or not it was a replacement navigation.
NavigatedToFragment(ServoUrl, HistoryEntryReplacement), NavigatedToFragment(ServoUrl, NavigationHistoryBehavior),
/// HTMLIFrameElement Forward or Back traversal. /// HTMLIFrameElement Forward or Back traversal.
TraverseHistory(TraversalDirection), TraverseHistory(TraversalDirection),
/// Inform the constellation of a pushed history state. /// Inform the constellation of a pushed history state.