send message to embedder in prompt_to_unload

This commit is contained in:
Gregory Terzian 2018-05-19 19:13:48 +08:00
parent 4234b1252a
commit 2812b3cf4a
3 changed files with 24 additions and 4 deletions

View file

@ -84,6 +84,8 @@ pub enum EmbedderMsg {
Alert(String, IpcSender<()>), Alert(String, IpcSender<()>),
/// Wether or not to follow a link /// Wether or not to follow a link
AllowNavigation(ServoUrl, IpcSender<bool>), AllowNavigation(ServoUrl, IpcSender<bool>),
/// Wether or not to unload a document
AllowUnload(IpcSender<bool>),
/// Sends an unconsumed key event back to the embedder. /// Sends an unconsumed key event back to the embedder.
KeyEvent(Option<char>, Key, KeyState, KeyModifiers), KeyEvent(Option<char>, Key, KeyState, KeyModifiers),
/// Changes the cursor. /// Changes the cursor.
@ -122,6 +124,7 @@ impl Debug for EmbedderMsg {
EmbedderMsg::MoveTo(..) => write!(f, "MoveTo"), EmbedderMsg::MoveTo(..) => write!(f, "MoveTo"),
EmbedderMsg::ResizeTo(..) => write!(f, "ResizeTo"), EmbedderMsg::ResizeTo(..) => write!(f, "ResizeTo"),
EmbedderMsg::Alert(..) => write!(f, "Alert"), EmbedderMsg::Alert(..) => write!(f, "Alert"),
EmbedderMsg::AllowUnload(..) => write!(f, "AllowUnload"),
EmbedderMsg::AllowNavigation(..) => write!(f, "AllowNavigation"), EmbedderMsg::AllowNavigation(..) => write!(f, "AllowNavigation"),
EmbedderMsg::KeyEvent(..) => write!(f, "KeyEvent"), EmbedderMsg::KeyEvent(..) => write!(f, "KeyEvent"),
EmbedderMsg::SetCursor(..) => write!(f, "SetCursor"), EmbedderMsg::SetCursor(..) => write!(f, "SetCursor"),

View file

@ -10,8 +10,10 @@ use dom::attr::Attr;
use dom::beforeunloadevent::BeforeUnloadEvent; use dom::beforeunloadevent::BeforeUnloadEvent;
use dom::bindings::callback::ExceptionHandling; use dom::bindings::callback::ExceptionHandling;
use dom::bindings::cell::DomRefCell; use dom::bindings::cell::DomRefCell;
use dom::bindings::codegen::Bindings::BeforeUnloadEventBinding::BeforeUnloadEventBinding::BeforeUnloadEventMethods;
use dom::bindings::codegen::Bindings::DocumentBinding; use dom::bindings::codegen::Bindings::DocumentBinding;
use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState, ElementCreationOptions}; use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState, ElementCreationOptions};
use dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementBinding::HTMLIFrameElementMethods; use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter; use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter;
@ -95,7 +97,7 @@ use fetch::FetchCanceller;
use html5ever::{LocalName, Namespace, QualName}; use html5ever::{LocalName, Namespace, QualName};
use hyper::header::{Header, SetCookie}; use hyper::header::{Header, SetCookie};
use hyper_serde::Serde; use hyper_serde::Serde;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{JSContext, JSObject, JSRuntime}; use js::jsapi::{JSContext, JSObject, JSRuntime};
use js::jsapi::JS_GetRuntime; use js::jsapi::JS_GetRuntime;
use metrics::{InteractiveFlag, InteractiveMetrics, InteractiveWindow, ProfilerMetadataFactory, ProgressiveWebMetric}; use metrics::{InteractiveFlag, InteractiveMetrics, InteractiveWindow, ProfilerMetadataFactory, ProgressiveWebMetric};
@ -108,7 +110,7 @@ use net_traits::pub_domains::is_pub_domain;
use net_traits::request::RequestInit; use net_traits::request::RequestInit;
use net_traits::response::HttpsState; use net_traits::response::HttpsState;
use num_traits::ToPrimitive; use num_traits::ToPrimitive;
use profile_traits::ipc; use profile_traits::ipc as profile_ipc;
use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType}; use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType};
use ref_slice::ref_slice; use ref_slice::ref_slice;
use script_layout_interface::message::{Msg, NodesFromPointQueryType, QueryMsg, ReflowGoal}; use script_layout_interface::message::{Msg, NodesFromPointQueryType, QueryMsg, ReflowGoal};
@ -1665,7 +1667,15 @@ impl Document {
// Step 7 // Step 7
self.salvageable.set(!has_listeners); self.salvageable.set(!has_listeners);
let mut can_unload = true; let mut can_unload = true;
// TODO: Step 8 send a message to embedder to prompt user. // TODO: Step 8, also check sandboxing modals flag.
let default_prevented = event.DefaultPrevented();
let return_value_not_empty = !event.downcast::<BeforeUnloadEvent>().unwrap().ReturnValue().is_empty();
if default_prevented || return_value_not_empty {
let (chan, port) = ipc::channel().expect("Failed to create IPC channel!");
let msg = EmbedderMsg::AllowUnload(chan);
self.send_to_embedder(msg);
can_unload = port.recv().unwrap();
}
// Step 9 // Step 9
if !recursive_flag { if !recursive_flag {
for iframe in self.iter_iframes() { for iframe in self.iter_iframes() {
@ -3638,7 +3648,7 @@ impl DocumentMethods for Document {
} }
let url = self.url(); let url = self.url();
let (tx, rx) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap(); let (tx, rx) = profile_ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
let _ = self.window let _ = self.window
.upcast::<GlobalScope>() .upcast::<GlobalScope>()
.resource_threads() .resource_threads()

View file

@ -266,6 +266,13 @@ impl Browser {
self.event_queue.push(WindowEvent::SendError(browser_id, reason)); self.event_queue.push(WindowEvent::SendError(browser_id, reason));
} }
} }
EmbedderMsg::AllowUnload(sender) => {
// Always allow unload for now.
if let Err(e) = sender.send(true) {
let reason = format!("Failed to send AllowUnload response: {}", e);
self.event_queue.push(WindowEvent::SendError(browser_id, reason));
}
}
EmbedderMsg::AllowNavigation(_url, response_chan) => { EmbedderMsg::AllowNavigation(_url, response_chan) => {
if let Err(e) = response_chan.send(true) { if let Err(e) = response_chan.send(true) {
warn!("Failed to send allow_navigation() response: {}", e); warn!("Failed to send allow_navigation() response: {}", e);