mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Remove insaccessible history states
This commit is contained in:
parent
087bd20b6d
commit
c08ad45681
6 changed files with 70 additions and 12 deletions
|
@ -2490,15 +2490,15 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
|||
},
|
||||
Some(old_pipeline_id) => {
|
||||
// Deactivate the old pipeline, and activate the new one.
|
||||
let pipelines_to_close = if let Some(replace_reloader) = change.replace {
|
||||
let (pipelines_to_close, states_to_close) = if let Some(replace_reloader) = change.replace {
|
||||
let session_history = self.joint_session_histories
|
||||
.entry(change.top_level_browsing_context_id).or_insert(JointSessionHistory::new());
|
||||
session_history.replace(replace_reloader.clone(),
|
||||
NeedsToReload::No(change.new_pipeline_id));
|
||||
|
||||
match replace_reloader {
|
||||
NeedsToReload::No(pipeline_id) => vec![pipeline_id],
|
||||
NeedsToReload::Yes(..) => vec![],
|
||||
NeedsToReload::No(pipeline_id) => (Some(vec![pipeline_id]), None),
|
||||
NeedsToReload::Yes(..) => (None, None),
|
||||
}
|
||||
} else {
|
||||
let session_history = self.joint_session_histories
|
||||
|
@ -2509,21 +2509,51 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
|||
old_reloader: NeedsToReload::No(old_pipeline_id),
|
||||
};
|
||||
|
||||
session_history.push_diff(diff).into_iter()
|
||||
.filter_map(|diff| match diff {
|
||||
SessionHistoryDiff::BrowsingContextDiff { new_reloader, .. } => Some(new_reloader),
|
||||
SessionHistoryDiff::PipelineDiff { .. } => None,
|
||||
})
|
||||
.filter_map(|pipeline_id| pipeline_id.alive_pipeline_id())
|
||||
.collect::<Vec<_>>()
|
||||
let mut pipelines_to_close = vec![];
|
||||
let mut states_to_close = HashMap::new();
|
||||
|
||||
let diffs_to_close = session_history.push_diff(diff);
|
||||
|
||||
for diff in diffs_to_close {
|
||||
match diff {
|
||||
SessionHistoryDiff::BrowsingContextDiff { new_reloader, .. } => {
|
||||
if let Some(pipeline_id) = new_reloader.alive_pipeline_id() {
|
||||
pipelines_to_close.push(pipeline_id);
|
||||
}
|
||||
}
|
||||
SessionHistoryDiff::PipelineDiff { pipeline_reloader, new_history_state_id, .. } => {
|
||||
if let Some(pipeline_id) = pipeline_reloader.alive_pipeline_id() {
|
||||
let states = states_to_close.entry(pipeline_id).or_insert(Vec::new());
|
||||
states.push(new_history_state_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(Some(pipelines_to_close), Some(states_to_close))
|
||||
};
|
||||
|
||||
self.update_activity(old_pipeline_id);
|
||||
self.update_activity(change.new_pipeline_id);
|
||||
|
||||
if let Some(states_to_close) = states_to_close {
|
||||
for (pipeline_id, states) in states_to_close {
|
||||
let msg = ConstellationControlMsg::RemoveHistoryStates(pipeline_id, states);
|
||||
let result = match self.pipelines.get(&pipeline_id) {
|
||||
None => return warn!("Pipeline {} removed history states after closure", pipeline_id),
|
||||
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||
};
|
||||
if let Err(e) = result {
|
||||
self.handle_send_error(pipeline_id, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(pipelines_to_close) = pipelines_to_close {
|
||||
for pipeline_id in pipelines_to_close {
|
||||
self.close_pipeline(pipeline_id, DiscardBrowsingContext::No, ExitPipelineMode::Normal);
|
||||
}
|
||||
}
|
||||
|
||||
self.notify_history_changed(change.top_level_browsing_context_id);
|
||||
}
|
||||
|
|
|
@ -252,6 +252,12 @@ impl ResourceChannelManager {
|
|||
let mut history_states = http_state.history_states.write().unwrap();
|
||||
history_states.insert(history_state_id, history_state);
|
||||
}
|
||||
CoreResourceMsg::RemoveHistoryStates(states_to_remove) => {
|
||||
let mut history_states = http_state.history_states.write().unwrap();
|
||||
for history_state in states_to_remove {
|
||||
history_states.remove(&history_state);
|
||||
}
|
||||
}
|
||||
CoreResourceMsg::Synchronize(sender) => {
|
||||
let _ = sender.send(());
|
||||
}
|
||||
|
|
|
@ -368,6 +368,8 @@ pub enum CoreResourceMsg {
|
|||
GetHistoryState(HistoryStateId, IpcSender<Option<Vec<u8>>>),
|
||||
/// Set a history state for a given history state id
|
||||
SetHistoryState(HistoryStateId, Vec<u8>),
|
||||
/// Removes history states for the given ids
|
||||
RemoveHistoryStates(Vec<HistoryStateId>),
|
||||
/// Synchronization message solely for knowing the state of the ResourceChannelManager loop
|
||||
Synchronize(IpcSender<()>),
|
||||
/// Send the network sender in constellation to CoreResourceThread
|
||||
|
|
|
@ -102,6 +102,13 @@ impl History {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn remove_states(&self, states: Vec<HistoryStateId>) {
|
||||
let _ = self.window
|
||||
.upcast::<GlobalScope>()
|
||||
.resource_threads()
|
||||
.send(CoreResourceMsg::RemoveHistoryStates(states));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-history-pushstate
|
||||
// https://html.spec.whatwg.org/multipage/#dom-history-replacestate
|
||||
fn push_or_replace_state(&self,
|
||||
|
|
|
@ -1170,6 +1170,7 @@ impl ScriptThread {
|
|||
PostMessage(id, ..) => Some(id),
|
||||
UpdatePipelineId(_, _, id, _) => Some(id),
|
||||
UpdateHistoryStateId(id, ..) => Some(id),
|
||||
RemoveHistoryStates(id, ..) => Some(id),
|
||||
FocusIFrame(id, ..) => Some(id),
|
||||
WebDriverScriptCommand(id, ..) => Some(id),
|
||||
TickAllAnimations(id) => Some(id),
|
||||
|
@ -1298,6 +1299,8 @@ impl ScriptThread {
|
|||
reason),
|
||||
ConstellationControlMsg::UpdateHistoryStateId(pipeline_id, history_state_id) =>
|
||||
self.handle_update_history_state_id_msg(pipeline_id, history_state_id),
|
||||
ConstellationControlMsg::RemoveHistoryStates(pipeline_id, history_states) =>
|
||||
self.handle_remove_history_states(pipeline_id, history_states),
|
||||
ConstellationControlMsg::FocusIFrame(parent_pipeline_id, frame_id) =>
|
||||
self.handle_focus_iframe_msg(parent_pipeline_id, frame_id),
|
||||
ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, msg) =>
|
||||
|
@ -1683,6 +1686,13 @@ impl ScriptThread {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_remove_history_states(&self, pipeline_id: PipelineId, history_states: Vec<HistoryStateId>) {
|
||||
match { self.documents.borrow().find_window(pipeline_id) } {
|
||||
None => return warn!("update history state after pipeline {} closed.", pipeline_id),
|
||||
Some(window) => window.History().r().remove_states(history_states),
|
||||
}
|
||||
}
|
||||
|
||||
/// Window was resized, but this script was not active, so don't reflow yet
|
||||
fn handle_resize_inactive_msg(&self, id: PipelineId, new_size: WindowSizeData) {
|
||||
let window = self.documents.borrow().find_window(id)
|
||||
|
|
|
@ -291,6 +291,8 @@ pub enum ConstellationControlMsg {
|
|||
UpdatePipelineId(PipelineId, BrowsingContextId, PipelineId, UpdatePipelineIdReason),
|
||||
/// Updates the history state of a given pipeline.
|
||||
UpdateHistoryStateId(PipelineId, Option<HistoryStateId>),
|
||||
/// Removes inaccesible history states.
|
||||
RemoveHistoryStates(PipelineId, Vec<HistoryStateId>),
|
||||
/// Set an iframe to be focused. Used when an element in an iframe gains focus.
|
||||
/// PipelineId is for the parent, BrowsingContextId is for the nested browsing context
|
||||
FocusIFrame(PipelineId, BrowsingContextId),
|
||||
|
@ -346,6 +348,7 @@ impl fmt::Debug for ConstellationControlMsg {
|
|||
PostMessage(..) => "PostMessage",
|
||||
UpdatePipelineId(..) => "UpdatePipelineId",
|
||||
UpdateHistoryStateId(..) => "UpdateHistoryStateId",
|
||||
RemoveHistoryStates(..) => "RemoveHistoryStates",
|
||||
FocusIFrame(..) => "FocusIFrame",
|
||||
WebDriverScriptCommand(..) => "WebDriverScriptCommand",
|
||||
TickAllAnimations(..) => "TickAllAnimations",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue