beforeunload and unload infrastructure

This commit is contained in:
Gregory Terzian 2018-03-18 13:20:24 +08:00
parent a1d1b18710
commit 427eaed535
28 changed files with 267 additions and 60 deletions

View file

@ -1033,6 +1033,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
FromScriptMsg::PipelineExited => {
self.handle_pipeline_exited(source_pipeline_id);
}
FromScriptMsg::DiscardDocument => {
self.handle_discard_document(source_top_ctx_id, source_pipeline_id);
}
FromScriptMsg::InitiateNavigateRequest(req_init, cancel_chan) => {
debug!("constellation got initiate navigate request message");
self.handle_navigate_request(source_pipeline_id, req_init, cancel_chan);
@ -2547,6 +2550,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
self.notify_history_changed(change.top_level_browsing_context_id);
},
Some(old_pipeline_id) => {
// https://html.spec.whatwg.org/multipage/#unload-a-document
self.unload_document(old_pipeline_id);
// Deactivate the old pipeline, and activate the new one.
let (pipelines_to_close, states_to_close) = if let Some(replace_reloader) = change.replace {
let session_history = self.joint_session_histories
@ -2997,6 +3002,28 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
debug!("Closed browsing context children {}.", browsing_context_id);
}
// Discard the pipeline for a given document, udpdate the joint session history.
fn handle_discard_document(&mut self,
top_level_browsing_context_id: TopLevelBrowsingContextId,
pipeline_id: PipelineId) {
let load_data = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.load_data.clone(),
None => return
};
self.joint_session_histories
.entry(top_level_browsing_context_id).or_insert(JointSessionHistory::new())
.replace_reloader(NeedsToReload::No(pipeline_id), NeedsToReload::Yes(pipeline_id, load_data));
self.close_pipeline(pipeline_id, DiscardBrowsingContext::No, ExitPipelineMode::Normal);
}
// Send a message to script requesting the document associated with this pipeline runs the 'unload' algorithm.
fn unload_document(&self, pipeline_id: PipelineId) {
if let Some(pipeline) = self.pipelines.get(&pipeline_id) {
let msg = ConstellationControlMsg::UnloadDocument(pipeline_id);
let _ = pipeline.event_loop.send(msg);
}
}
// Close all pipelines at and beneath a given browsing context
fn close_pipeline(&mut self, pipeline_id: PipelineId, dbc: DiscardBrowsingContext, exit_mode: ExitPipelineMode) {
debug!("Closing pipeline {:?}.", pipeline_id);