mirror of
https://github.com/servo/servo.git
synced 2025-07-30 10:40:27 +01:00
Auto merge of #20707 - gterzian:embedder_handling_of_prompts_and_alerts_2, r=payl
Embedder handling of prompts and alerts <!-- Please describe your changes on the following line: --> Allow embedder to allow alerts and prompts, but via constellation forwarding messages from script. --- <!-- 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 build-geckolib` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #19992 (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/20707) <!-- Reviewable:end -->
This commit is contained in:
commit
f6762d54e2
32 changed files with 413 additions and 375 deletions
|
@ -10,8 +10,10 @@ use dom::attr::Attr;
|
|||
use dom::beforeunloadevent::BeforeUnloadEvent;
|
||||
use dom::bindings::callback::ExceptionHandling;
|
||||
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::{DocumentMethods, DocumentReadyState, ElementCreationOptions};
|
||||
use dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods;
|
||||
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
|
||||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter;
|
||||
|
@ -88,13 +90,14 @@ use dom::webglcontextevent::WebGLContextEvent;
|
|||
use dom::window::{ReflowReason, Window};
|
||||
use dom::windowproxy::WindowProxy;
|
||||
use dom_struct::dom_struct;
|
||||
use embedder_traits::EmbedderMsg;
|
||||
use encoding_rs::{Encoding, UTF_8};
|
||||
use euclid::Point2D;
|
||||
use fetch::FetchCanceller;
|
||||
use html5ever::{LocalName, Namespace, QualName};
|
||||
use hyper::header::{Header, SetCookie};
|
||||
use hyper_serde::Serde;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
||||
use js::jsapi::JS_GetRuntime;
|
||||
use metrics::{InteractiveFlag, InteractiveMetrics, InteractiveWindow, ProfilerMetadataFactory, ProgressiveWebMetric};
|
||||
|
@ -107,7 +110,7 @@ use net_traits::pub_domains::is_pub_domain;
|
|||
use net_traits::request::RequestInit;
|
||||
use net_traits::response::HttpsState;
|
||||
use num_traits::ToPrimitive;
|
||||
use profile_traits::ipc;
|
||||
use profile_traits::ipc as profile_ipc;
|
||||
use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType};
|
||||
use ref_slice::ref_slice;
|
||||
use script_layout_interface::message::{Msg, NodesFromPointQueryType, QueryMsg, ReflowGoal};
|
||||
|
@ -855,7 +858,7 @@ impl Document {
|
|||
|
||||
// Notify the embedder to hide the input method.
|
||||
if elem.input_method_type().is_some() {
|
||||
self.send_to_constellation(ScriptMsg::HideIME);
|
||||
self.send_to_embedder(EmbedderMsg::HideIME);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -869,12 +872,12 @@ impl Document {
|
|||
// Update the focus state for all elements in the focus chain.
|
||||
// https://html.spec.whatwg.org/multipage/#focus-chain
|
||||
if focus_type == FocusType::Element {
|
||||
self.send_to_constellation(ScriptMsg::Focus);
|
||||
self.window().send_to_constellation(ScriptMsg::Focus);
|
||||
}
|
||||
|
||||
// Notify the embedder to display an input method.
|
||||
if let Some(kind) = elem.input_method_type() {
|
||||
self.send_to_constellation(ScriptMsg::ShowIME(kind));
|
||||
self.send_to_embedder(EmbedderMsg::ShowIME(kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -882,14 +885,22 @@ impl Document {
|
|||
/// Handles any updates when the document's title has changed.
|
||||
pub fn title_changed(&self) {
|
||||
if self.browsing_context().is_some() {
|
||||
self.send_title_to_constellation();
|
||||
self.send_title_to_embedder();
|
||||
}
|
||||
}
|
||||
|
||||
/// Sends this document's title to the constellation.
|
||||
pub fn send_title_to_constellation(&self) {
|
||||
let title = Some(String::from(self.Title()));
|
||||
self.send_to_constellation(ScriptMsg::SetTitle(title));
|
||||
pub fn send_title_to_embedder(&self) {
|
||||
let window = self.window();
|
||||
if window.is_top_level() {
|
||||
let title = Some(String::from(self.Title()));
|
||||
self.send_to_embedder(EmbedderMsg::ChangePageTitle(title));
|
||||
}
|
||||
}
|
||||
|
||||
fn send_to_embedder(&self, msg: EmbedderMsg) {
|
||||
let window = self.window();
|
||||
window.send_to_embedder(msg);
|
||||
}
|
||||
|
||||
pub fn dirty_all_nodes(&self) {
|
||||
|
@ -1352,8 +1363,8 @@ impl Document {
|
|||
}
|
||||
|
||||
if cancel_state == EventDefault::Allowed {
|
||||
let msg = ScriptMsg::SendKeyEvent(ch, key, state, modifiers);
|
||||
self.send_to_constellation(msg);
|
||||
let msg = EmbedderMsg::KeyEvent(ch, key, state, modifiers);
|
||||
self.send_to_embedder(msg);
|
||||
|
||||
// This behavior is unspecced
|
||||
// We are supposed to dispatch synthetic click activation for Space and/or Return,
|
||||
|
@ -1488,7 +1499,7 @@ impl Document {
|
|||
// repeated rAF.
|
||||
|
||||
let event = ScriptMsg::ChangeRunningAnimationsState(AnimationState::AnimationCallbacksPresent);
|
||||
self.send_to_constellation(event);
|
||||
self.window().send_to_constellation(event);
|
||||
}
|
||||
|
||||
ident
|
||||
|
@ -1559,7 +1570,7 @@ impl Document {
|
|||
);
|
||||
}
|
||||
let event = ScriptMsg::ChangeRunningAnimationsState(AnimationState::NoAnimationCallbacksPresent);
|
||||
self.send_to_constellation(event);
|
||||
self.window().send_to_constellation(event);
|
||||
}
|
||||
|
||||
// Update the counter of spurious animation frames.
|
||||
|
@ -1656,7 +1667,15 @@ impl Document {
|
|||
// Step 7
|
||||
self.salvageable.set(!has_listeners);
|
||||
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
|
||||
if !recursive_flag {
|
||||
for iframe in self.iter_iframes() {
|
||||
|
@ -2009,7 +2028,7 @@ impl Document {
|
|||
}
|
||||
|
||||
pub fn notify_constellation_load(&self) {
|
||||
self.send_to_constellation(ScriptMsg::LoadComplete);
|
||||
self.window().send_to_constellation(ScriptMsg::LoadComplete);
|
||||
}
|
||||
|
||||
pub fn set_current_parser(&self, script: Option<&ServoParser>) {
|
||||
|
@ -2167,11 +2186,6 @@ impl Document {
|
|||
registry.lookup_definition(local_name, is)
|
||||
}
|
||||
|
||||
fn send_to_constellation(&self, msg: ScriptMsg) {
|
||||
let global_scope = self.window.upcast::<GlobalScope>();
|
||||
global_scope.script_to_constellation_chan().send(msg).unwrap();
|
||||
}
|
||||
|
||||
pub fn increment_throw_on_dynamic_markup_insertion_counter(&self) {
|
||||
let counter = self.throw_on_dynamic_markup_insertion_counter.get();
|
||||
self.throw_on_dynamic_markup_insertion_counter.set(counter + 1);
|
||||
|
@ -2787,8 +2801,8 @@ impl Document {
|
|||
let window = self.window();
|
||||
// Step 6
|
||||
if !error {
|
||||
let event = ScriptMsg::SetFullscreenState(true);
|
||||
self.send_to_constellation(event);
|
||||
let event = EmbedderMsg::SetFullscreenState(true);
|
||||
self.send_to_embedder(event);
|
||||
}
|
||||
|
||||
let pipeline_id = self.window().pipeline_id();
|
||||
|
@ -2822,8 +2836,8 @@ impl Document {
|
|||
|
||||
let window = self.window();
|
||||
// Step 8
|
||||
let event = ScriptMsg::SetFullscreenState(false);
|
||||
self.send_to_constellation(event);
|
||||
let event = EmbedderMsg::SetFullscreenState(true);
|
||||
self.send_to_embedder(event);
|
||||
|
||||
// Step 9
|
||||
let trusted_element = Trusted::new(element.r());
|
||||
|
@ -3634,7 +3648,7 @@ impl DocumentMethods for Document {
|
|||
}
|
||||
|
||||
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
|
||||
.upcast::<GlobalScope>()
|
||||
.resource_threads()
|
||||
|
|
|
@ -12,13 +12,12 @@ use dom::bindings::str::DOMString;
|
|||
use dom::document::Document;
|
||||
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
|
||||
use dom::eventtarget::EventTarget;
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom::htmlelement::HTMLElement;
|
||||
use dom::node::{Node, document_from_node, window_from_node};
|
||||
use dom::virtualmethods::VirtualMethods;
|
||||
use dom_struct::dom_struct;
|
||||
use embedder_traits::EmbedderMsg;
|
||||
use html5ever::{LocalName, Prefix};
|
||||
use script_traits::ScriptMsg;
|
||||
use servo_url::ServoUrl;
|
||||
use style::attr::AttrValue;
|
||||
use time;
|
||||
|
@ -151,8 +150,10 @@ impl VirtualMethods for HTMLBodyElement {
|
|||
let window = window_from_node(self);
|
||||
let document = window.Document();
|
||||
document.set_reflow_timeout(time::precise_time_ns() + INITIAL_REFLOW_DELAY);
|
||||
let event = ScriptMsg::HeadParsed;
|
||||
window.upcast::<GlobalScope>().script_to_constellation_chan().send(event).unwrap();
|
||||
if window.is_top_level() {
|
||||
let msg = EmbedderMsg::HeadParsed;
|
||||
window.send_to_embedder(msg);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue {
|
||||
|
|
|
@ -38,12 +38,13 @@ use dom::validation::Validatable;
|
|||
use dom::validitystate::ValidationFlags;
|
||||
use dom::virtualmethods::VirtualMethods;
|
||||
use dom_struct::dom_struct;
|
||||
use embedder_traits::FilterPattern;
|
||||
use html5ever::{LocalName, Prefix};
|
||||
use mime_guess;
|
||||
use msg::constellation_msg::InputMethodType;
|
||||
use net_traits::{CoreResourceMsg, IpcSend};
|
||||
use net_traits::blob_url_store::get_blob_origin;
|
||||
use net_traits::filemanager_thread::{FileManagerThreadMsg, FilterPattern};
|
||||
use net_traits::filemanager_thread::FileManagerThreadMsg;
|
||||
use profile_traits::ipc;
|
||||
use script_layout_interface::rpc::TextIndexResponse;
|
||||
use script_traits::ScriptToConstellationChan;
|
||||
|
|
|
@ -16,15 +16,14 @@ use dom::document::Document;
|
|||
use dom::domtokenlist::DOMTokenList;
|
||||
use dom::element::{AttributeMutation, Element, ElementCreator};
|
||||
use dom::element::{cors_setting_for_element, reflect_cross_origin_attribute, set_cross_origin_attribute};
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom::htmlelement::HTMLElement;
|
||||
use dom::node::{Node, UnbindContext, document_from_node, window_from_node};
|
||||
use dom::stylesheet::StyleSheet as DOMStyleSheet;
|
||||
use dom::virtualmethods::VirtualMethods;
|
||||
use dom_struct::dom_struct;
|
||||
use embedder_traits::EmbedderMsg;
|
||||
use html5ever::{LocalName, Prefix};
|
||||
use net_traits::ReferrerPolicy;
|
||||
use script_traits::ScriptMsg;
|
||||
use servo_arc::Arc;
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::Cell;
|
||||
|
@ -306,8 +305,12 @@ impl HTMLLinkElement {
|
|||
let document = document_from_node(self);
|
||||
match document.base_url().join(href) {
|
||||
Ok(url) => {
|
||||
let event = ScriptMsg::NewFavicon(url.clone());
|
||||
document.window().upcast::<GlobalScope>().script_to_constellation_chan().send(event).unwrap();
|
||||
let window = document.window();
|
||||
if window.is_top_level() {
|
||||
let msg = EmbedderMsg::NewFavicon(url.clone());
|
||||
window.send_to_embedder(msg);
|
||||
}
|
||||
|
||||
}
|
||||
Err(e) => debug!("Parsing url {} failed: {}", href, e)
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ use dom::windowproxy::WindowProxy;
|
|||
use dom::worklet::Worklet;
|
||||
use dom::workletglobalscope::WorkletGlobalScopeType;
|
||||
use dom_struct::dom_struct;
|
||||
use embedder_traits::EmbedderMsg;
|
||||
use euclid::{Point2D, Vector2D, Rect, Size2D, TypedPoint2D, TypedScale, TypedSize2D};
|
||||
use fetch;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
|
@ -114,8 +115,6 @@ use task_source::performance_timeline::PerformanceTimelineTaskSource;
|
|||
use task_source::user_interaction::UserInteractionTaskSource;
|
||||
use time;
|
||||
use timers::{IsInterval, TimerCallback};
|
||||
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
||||
use tinyfiledialogs::{self, MessageBoxIcon};
|
||||
use url::Position;
|
||||
use webdriver_handlers::jsval_to_webdriver;
|
||||
use webrender_api::{ExternalScrollId, DeviceIntPoint, DeviceUintSize, DocumentId};
|
||||
|
@ -444,18 +443,6 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
||||
fn display_alert_dialog(message: &str) {
|
||||
if !opts::get().headless {
|
||||
tinyfiledialogs::message_box_ok("Alert!", message, MessageBoxIcon::Warning);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
|
||||
fn display_alert_dialog(_message: &str) {
|
||||
// tinyfiledialogs not supported on Android
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#atob
|
||||
pub fn base64_btoa(input: DOMString) -> Fallible<DOMString> {
|
||||
// "The btoa() method must throw an InvalidCharacterError exception if
|
||||
|
@ -541,14 +528,10 @@ impl WindowMethods for Window {
|
|||
stdout.flush().unwrap();
|
||||
stderr.flush().unwrap();
|
||||
}
|
||||
|
||||
let (sender, receiver) = ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap();
|
||||
self.send_to_constellation(ScriptMsg::Alert(s.to_string(), sender));
|
||||
|
||||
let should_display_alert_dialog = receiver.recv().unwrap();
|
||||
if should_display_alert_dialog {
|
||||
display_alert_dialog(&s);
|
||||
}
|
||||
let msg = EmbedderMsg::Alert(s.to_string(), sender);
|
||||
self.send_to_embedder(msg);
|
||||
receiver.recv().unwrap();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-window-closed
|
||||
|
@ -937,7 +920,7 @@ impl WindowMethods for Window {
|
|||
//TODO determine if this operation is allowed
|
||||
let dpr = self.device_pixel_ratio();
|
||||
let size = TypedSize2D::new(width, height).to_f32() * dpr;
|
||||
self.send_to_constellation(ScriptMsg::ResizeTo(size.to_u32()));
|
||||
self.send_to_embedder(EmbedderMsg::ResizeTo(size.to_u32()));
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-window-resizeby
|
||||
|
@ -953,7 +936,8 @@ impl WindowMethods for Window {
|
|||
//TODO determine if this operation is allowed
|
||||
let dpr = self.device_pixel_ratio();
|
||||
let point = TypedPoint2D::new(x, y).to_f32() * dpr;
|
||||
self.send_to_constellation(ScriptMsg::MoveTo(point.to_i32()));
|
||||
let msg = EmbedderMsg::MoveTo(point.to_i32());
|
||||
self.send_to_embedder(msg);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-window-moveby
|
||||
|
@ -1742,7 +1726,11 @@ impl Window {
|
|||
self.navigation_start_precise.set(time::precise_time_ns());
|
||||
}
|
||||
|
||||
fn send_to_constellation(&self, msg: ScriptMsg) {
|
||||
pub fn send_to_embedder(&self, msg: EmbedderMsg) {
|
||||
self.send_to_constellation(ScriptMsg::ForwardToEmbedder(msg));
|
||||
}
|
||||
|
||||
pub fn send_to_constellation(&self, msg: ScriptMsg) {
|
||||
self.upcast::<GlobalScope>()
|
||||
.script_to_constellation_chan()
|
||||
.send(msg)
|
||||
|
|
|
@ -93,7 +93,7 @@ extern crate style;
|
|||
extern crate style_traits;
|
||||
extern crate swapper;
|
||||
extern crate time;
|
||||
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
||||
#[cfg(target_os = "linux")]
|
||||
extern crate tinyfiledialogs;
|
||||
extern crate unicode_segmentation;
|
||||
extern crate url;
|
||||
|
|
|
@ -62,6 +62,7 @@ use dom::windowproxy::WindowProxy;
|
|||
use dom::worker::TrustedWorkerAddress;
|
||||
use dom::worklet::WorkletThreadPool;
|
||||
use dom::workletglobalscope::WorkletGlobalScopeInit;
|
||||
use embedder_traits::EmbedderMsg;
|
||||
use euclid::{Point2D, Vector2D, Rect};
|
||||
use fetch::FetchCanceller;
|
||||
use hyper::header::{ContentType, HttpDate, Headers, LastModified};
|
||||
|
@ -1822,7 +1823,7 @@ impl ScriptThread {
|
|||
Some(document) => document,
|
||||
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
|
||||
};
|
||||
document.send_title_to_constellation();
|
||||
document.send_title_to_embedder();
|
||||
}
|
||||
|
||||
/// Handles a request to exit a pipeline and shut down layout.
|
||||
|
@ -2282,6 +2283,7 @@ impl ScriptThread {
|
|||
Some(document) => document,
|
||||
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
|
||||
};
|
||||
let window = document.window();
|
||||
|
||||
// Get the previous target temporarily
|
||||
let prev_mouse_over_target = self.topmost_mouse_over_target.get();
|
||||
|
@ -2310,9 +2312,8 @@ impl ScriptThread {
|
|||
let url = document.url();
|
||||
url.join(&value).map(|url| url.to_string()).ok()
|
||||
});
|
||||
|
||||
let event = ScriptMsg::NodeStatus(status);
|
||||
self.script_sender.send((pipeline_id, event)).unwrap();
|
||||
let event = EmbedderMsg::Status(status);
|
||||
window.send_to_embedder(event);
|
||||
|
||||
state_already_changed = true;
|
||||
}
|
||||
|
@ -2325,8 +2326,8 @@ impl ScriptThread {
|
|||
.inclusive_ancestors()
|
||||
.filter_map(DomRoot::downcast::<HTMLAnchorElement>)
|
||||
.next() {
|
||||
let event = ScriptMsg::NodeStatus(None);
|
||||
self.script_sender.send((pipeline_id, event)).unwrap();
|
||||
let event = EmbedderMsg::Status(None);
|
||||
window.send_to_embedder(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue