Auto merge of #20329 - gterzian:before_unload, r=cbrewster

Implement beforeunload event and infrastructure

<!-- Please describe your changes on the following line: -->

Implementation of:
1. https://html.spec.whatwg.org/multipage/#prompt-to-unload-a-document, and
2. https://html.spec.whatwg.org/multipage/#unload-a-document
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [ ] `./mach test-tidy` does not report any errors
- [ ] These changes fix #10787 and fix #20485 and fix #20588 and fix #20496 (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20329)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-05-07 13:22:23 -04:00 committed by GitHub
commit 1d8283e010
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 341 additions and 113 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);
@ -2544,6 +2547,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
@ -2994,6 +2999,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);