mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
move msg to embedder_traits, use in script, handle send error in embedder
This commit is contained in:
parent
a297e8f288
commit
d438240772
31 changed files with 362 additions and 337 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -182,6 +182,7 @@ dependencies = [
|
||||||
"bluetooth_traits 0.0.1",
|
"bluetooth_traits 0.0.1",
|
||||||
"compositing 0.0.1",
|
"compositing 0.0.1",
|
||||||
"device 0.0.1 (git+https://github.com/servo/devices)",
|
"device 0.0.1 (git+https://github.com/servo/devices)",
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"servo_config 0.0.1",
|
"servo_config 0.0.1",
|
||||||
|
@ -419,6 +420,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
name = "compositing"
|
name = "compositing"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gfx_traits 0.0.1",
|
"gfx_traits 0.0.1",
|
||||||
"gleam 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -770,7 +772,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
name = "embedder_traits"
|
name = "embedder_traits"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"msg 0.0.1",
|
||||||
|
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"servo_url 0.0.1",
|
||||||
|
"style_traits 0.0.1",
|
||||||
|
"webrender_api 0.57.2 (git+https://github.com/servo/webrender)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1850,7 +1859,6 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"brotli 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"brotli 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"compositing 0.0.1",
|
|
||||||
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
"embedder_traits 0.0.1",
|
"embedder_traits 0.0.1",
|
||||||
|
@ -2601,6 +2609,7 @@ dependencies = [
|
||||||
"canvas_traits 0.0.1",
|
"canvas_traits 0.0.1",
|
||||||
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gfx_traits 0.0.1",
|
"gfx_traits 0.0.1",
|
||||||
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -14,8 +14,12 @@ bitflags = "1.0"
|
||||||
bluetooth_traits = {path = "../bluetooth_traits"}
|
bluetooth_traits = {path = "../bluetooth_traits"}
|
||||||
compositing = {path = "../compositing"}
|
compositing = {path = "../compositing"}
|
||||||
device = {git = "https://github.com/servo/devices", features = ["bluetooth-test"]}
|
device = {git = "https://github.com/servo/devices", features = ["bluetooth-test"]}
|
||||||
|
embedder_traits = {path = "../embedder_traits"}
|
||||||
ipc-channel = "0.10"
|
ipc-channel = "0.10"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
servo_config = {path = "../config"}
|
servo_config = {path = "../config"}
|
||||||
servo_rand = {path = "../rand"}
|
servo_rand = {path = "../rand"}
|
||||||
uuid = {version = "0.6", features = ["v4"]}
|
uuid = {version = "0.6", features = ["v4"]}
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
embedder_traits = { path = "../embedder_traits", features = ["tests"]}
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
extern crate bluetooth_traits;
|
extern crate bluetooth_traits;
|
||||||
extern crate compositing;
|
|
||||||
extern crate device;
|
extern crate device;
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate ipc_channel;
|
extern crate ipc_channel;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
@ -21,9 +21,9 @@ use bluetooth_traits::{BluetoothDeviceMsg, BluetoothRequest, BluetoothResponse,
|
||||||
use bluetooth_traits::{BluetoothError, BluetoothResponseResult, BluetoothResult};
|
use bluetooth_traits::{BluetoothError, BluetoothResponseResult, BluetoothResult};
|
||||||
use bluetooth_traits::blocklist::{uuid_is_blocklisted, Blocklist};
|
use bluetooth_traits::blocklist::{uuid_is_blocklisted, Blocklist};
|
||||||
use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence, RequestDeviceoptions};
|
use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence, RequestDeviceoptions};
|
||||||
use compositing::compositor_thread::{EmbedderMsg, EmbedderProxy};
|
|
||||||
use device::bluetooth::{BluetoothAdapter, BluetoothDevice, BluetoothGATTCharacteristic};
|
use device::bluetooth::{BluetoothAdapter, BluetoothDevice, BluetoothGATTCharacteristic};
|
||||||
use device::bluetooth::{BluetoothGATTDescriptor, BluetoothGATTService};
|
use device::bluetooth::{BluetoothGATTDescriptor, BluetoothGATTService};
|
||||||
|
use embedder_traits::{EmbedderMsg, EmbedderProxy};
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use servo_config::prefs::PREFS;
|
use servo_config::prefs::PREFS;
|
||||||
|
|
|
@ -14,6 +14,7 @@ path = "lib.rs"
|
||||||
default = []
|
default = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
embedder_traits = {path = "../embedder_traits"}
|
||||||
euclid = "0.17"
|
euclid = "0.17"
|
||||||
gfx_traits = {path = "../gfx_traits"}
|
gfx_traits = {path = "../gfx_traits"}
|
||||||
gleam = {version = "0.5", optional = true}
|
gleam = {version = "0.5", optional = true}
|
||||||
|
@ -36,3 +37,6 @@ webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
toml = "0.4.5"
|
toml = "0.4.5"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
embedder_traits = { path = "../embedder_traits", features = ["tests"]}
|
||||||
|
|
|
@ -6,68 +6,21 @@
|
||||||
|
|
||||||
use SendableFrameTree;
|
use SendableFrameTree;
|
||||||
use compositor::CompositingReason;
|
use compositor::CompositingReason;
|
||||||
|
use embedder_traits::EventLoopWaker;
|
||||||
use gfx_traits::Epoch;
|
use gfx_traits::Epoch;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use msg::constellation_msg::{InputMethodType, Key, KeyModifiers, KeyState, PipelineId, TopLevelBrowsingContextId};
|
use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId};
|
||||||
use net_traits::filemanager_thread::FilterPattern;
|
|
||||||
use net_traits::image::base::Image;
|
use net_traits::image::base::Image;
|
||||||
use profile_traits::mem;
|
use profile_traits::mem;
|
||||||
use profile_traits::time;
|
use profile_traits::time;
|
||||||
use script_traits::{AnimationState, ConstellationMsg, EventResult, LoadData};
|
use script_traits::{AnimationState, ConstellationMsg, EventResult};
|
||||||
use servo_url::ServoUrl;
|
|
||||||
use std::fmt::{Debug, Error, Formatter};
|
use std::fmt::{Debug, Error, Formatter};
|
||||||
use std::sync::mpsc::{Receiver, Sender};
|
use std::sync::mpsc::{Receiver, Sender};
|
||||||
use style_traits::cursor::CursorKind;
|
|
||||||
use style_traits::viewport::ViewportConstraints;
|
use style_traits::viewport::ViewportConstraints;
|
||||||
use webrender;
|
use webrender;
|
||||||
use webrender_api::{self, DeviceIntPoint, DeviceUintSize};
|
use webrender_api::{self, DeviceIntPoint, DeviceUintSize};
|
||||||
|
|
||||||
|
|
||||||
/// Used to wake up the event loop, provided by the servo port/embedder.
|
|
||||||
pub trait EventLoopWaker : 'static + Send {
|
|
||||||
fn clone(&self) -> Box<EventLoopWaker + Send>;
|
|
||||||
fn wake(&self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sends messages to the embedder.
|
|
||||||
pub struct EmbedderProxy {
|
|
||||||
pub sender: Sender<EmbedderMsg>,
|
|
||||||
pub event_loop_waker: Box<EventLoopWaker>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EmbedderProxy {
|
|
||||||
pub fn send(&self, msg: EmbedderMsg) {
|
|
||||||
// Send a message and kick the OS event loop awake.
|
|
||||||
if let Err(err) = self.sender.send(msg) {
|
|
||||||
warn!("Failed to send response ({}).", err);
|
|
||||||
}
|
|
||||||
self.event_loop_waker.wake();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for EmbedderProxy {
|
|
||||||
fn clone(&self) -> EmbedderProxy {
|
|
||||||
EmbedderProxy {
|
|
||||||
sender: self.sender.clone(),
|
|
||||||
event_loop_waker: self.event_loop_waker.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The port that the embedder receives messages on.
|
|
||||||
pub struct EmbedderReceiver {
|
|
||||||
pub receiver: Receiver<EmbedderMsg>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EmbedderReceiver {
|
|
||||||
pub fn try_recv_embedder_msg(&mut self) -> Option<EmbedderMsg> {
|
|
||||||
self.receiver.try_recv().ok()
|
|
||||||
}
|
|
||||||
pub fn recv_embedder_msg(&mut self) -> EmbedderMsg {
|
|
||||||
self.receiver.recv().unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sends messages to the compositor.
|
/// Sends messages to the compositor.
|
||||||
pub struct CompositorProxy {
|
pub struct CompositorProxy {
|
||||||
pub sender: Sender<Msg>,
|
pub sender: Sender<Msg>,
|
||||||
|
@ -113,47 +66,6 @@ impl CompositorProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum EmbedderMsg {
|
|
||||||
/// A status message to be displayed by the browser chrome.
|
|
||||||
Status(TopLevelBrowsingContextId, Option<String>),
|
|
||||||
/// Alerts the embedder that the current page has changed its title.
|
|
||||||
ChangePageTitle(TopLevelBrowsingContextId, Option<String>),
|
|
||||||
/// Move the window to a point
|
|
||||||
MoveTo(TopLevelBrowsingContextId, DeviceIntPoint),
|
|
||||||
/// Resize the window to size
|
|
||||||
ResizeTo(TopLevelBrowsingContextId, DeviceUintSize),
|
|
||||||
/// Wether or not to follow a link
|
|
||||||
AllowNavigation(TopLevelBrowsingContextId, ServoUrl, IpcSender<bool>),
|
|
||||||
/// Sends an unconsumed key event back to the embedder.
|
|
||||||
KeyEvent(Option<TopLevelBrowsingContextId>, Option<char>, Key, KeyState, KeyModifiers),
|
|
||||||
/// Changes the cursor.
|
|
||||||
SetCursor(CursorKind),
|
|
||||||
/// A favicon was detected
|
|
||||||
NewFavicon(TopLevelBrowsingContextId, ServoUrl),
|
|
||||||
/// <head> tag finished parsing
|
|
||||||
HeadParsed(TopLevelBrowsingContextId),
|
|
||||||
/// The history state has changed.
|
|
||||||
HistoryChanged(TopLevelBrowsingContextId, Vec<LoadData>, usize),
|
|
||||||
/// Enter or exit fullscreen
|
|
||||||
SetFullscreenState(TopLevelBrowsingContextId, bool),
|
|
||||||
/// The load of a page has begun
|
|
||||||
LoadStart(TopLevelBrowsingContextId),
|
|
||||||
/// The load of a page has completed
|
|
||||||
LoadComplete(TopLevelBrowsingContextId),
|
|
||||||
/// A pipeline panicked. First string is the reason, second one is the backtrace.
|
|
||||||
Panic(TopLevelBrowsingContextId, String, Option<String>),
|
|
||||||
/// Open dialog to select bluetooth device.
|
|
||||||
GetSelectedBluetoothDevice(Vec<String>, IpcSender<Option<String>>),
|
|
||||||
/// Open file dialog to select files. Set boolean flag to true allows to select multiple files.
|
|
||||||
SelectFiles(Vec<FilterPattern>, bool, IpcSender<Option<Vec<String>>>),
|
|
||||||
/// Request to present an IME to the user when an editable element is focused.
|
|
||||||
ShowIME(TopLevelBrowsingContextId, InputMethodType),
|
|
||||||
/// Request to hide the IME when the editable element is blurred.
|
|
||||||
HideIME(TopLevelBrowsingContextId),
|
|
||||||
/// Servo has shut down
|
|
||||||
Shutdown,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Messages from the painting thread and the constellation thread to the compositor thread.
|
/// Messages from the painting thread and the constellation thread to the compositor thread.
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
/// Requests that the compositor shut down.
|
/// Requests that the compositor shut down.
|
||||||
|
@ -233,32 +145,6 @@ impl Debug for Msg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for EmbedderMsg {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
|
||||||
match *self {
|
|
||||||
EmbedderMsg::Status(..) => write!(f, "Status"),
|
|
||||||
EmbedderMsg::ChangePageTitle(..) => write!(f, "ChangePageTitle"),
|
|
||||||
EmbedderMsg::MoveTo(..) => write!(f, "MoveTo"),
|
|
||||||
EmbedderMsg::ResizeTo(..) => write!(f, "ResizeTo"),
|
|
||||||
EmbedderMsg::AllowNavigation(..) => write!(f, "AllowNavigation"),
|
|
||||||
EmbedderMsg::KeyEvent(..) => write!(f, "KeyEvent"),
|
|
||||||
EmbedderMsg::SetCursor(..) => write!(f, "SetCursor"),
|
|
||||||
EmbedderMsg::NewFavicon(..) => write!(f, "NewFavicon"),
|
|
||||||
EmbedderMsg::HeadParsed(..) => write!(f, "HeadParsed"),
|
|
||||||
EmbedderMsg::HistoryChanged(..) => write!(f, "HistoryChanged"),
|
|
||||||
EmbedderMsg::SetFullscreenState(..) => write!(f, "SetFullscreenState"),
|
|
||||||
EmbedderMsg::LoadStart(..) => write!(f, "LoadStart"),
|
|
||||||
EmbedderMsg::LoadComplete(..) => write!(f, "LoadComplete"),
|
|
||||||
EmbedderMsg::Panic(..) => write!(f, "Panic"),
|
|
||||||
EmbedderMsg::GetSelectedBluetoothDevice(..) => write!(f, "GetSelectedBluetoothDevice"),
|
|
||||||
EmbedderMsg::SelectFiles(..) => write!(f, "SelectFiles"),
|
|
||||||
EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"),
|
|
||||||
EmbedderMsg::HideIME(..) => write!(f, "HideIME"),
|
|
||||||
EmbedderMsg::Shutdown => write!(f, "Shutdown"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Data used to construct a compositor.
|
/// Data used to construct a compositor.
|
||||||
pub struct InitialCompositorState {
|
pub struct InitialCompositorState {
|
||||||
/// A channel to the compositor.
|
/// A channel to the compositor.
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
extern crate gfx_traits;
|
extern crate gfx_traits;
|
||||||
#[cfg(feature = "gleam")]
|
#[cfg(feature = "gleam")]
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
|
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
|
||||||
|
|
||||||
use compositor_thread::EventLoopWaker;
|
use embedder_traits::EventLoopWaker;
|
||||||
use euclid::TypedScale;
|
use euclid::TypedScale;
|
||||||
#[cfg(feature = "gleam")]
|
#[cfg(feature = "gleam")]
|
||||||
use gleam::gl;
|
use gleam::gl;
|
||||||
|
@ -78,6 +78,8 @@ pub enum WindowEvent {
|
||||||
NewBrowser(ServoUrl, IpcSender<TopLevelBrowsingContextId>),
|
NewBrowser(ServoUrl, IpcSender<TopLevelBrowsingContextId>),
|
||||||
/// Close a top level browsing context
|
/// Close a top level browsing context
|
||||||
CloseBrowser(TopLevelBrowsingContextId),
|
CloseBrowser(TopLevelBrowsingContextId),
|
||||||
|
/// Panic a top level browsing context.
|
||||||
|
SendError(Option<TopLevelBrowsingContextId>, String),
|
||||||
/// Make a top level browsing context visible, hiding the previous
|
/// Make a top level browsing context visible, hiding the previous
|
||||||
/// visible one.
|
/// visible one.
|
||||||
SelectBrowser(TopLevelBrowsingContextId),
|
SelectBrowser(TopLevelBrowsingContextId),
|
||||||
|
@ -106,6 +108,7 @@ impl Debug for WindowEvent {
|
||||||
WindowEvent::Quit => write!(f, "Quit"),
|
WindowEvent::Quit => write!(f, "Quit"),
|
||||||
WindowEvent::Reload(..) => write!(f, "Reload"),
|
WindowEvent::Reload(..) => write!(f, "Reload"),
|
||||||
WindowEvent::NewBrowser(..) => write!(f, "NewBrowser"),
|
WindowEvent::NewBrowser(..) => write!(f, "NewBrowser"),
|
||||||
|
WindowEvent::SendError(..) => write!(f, "SendError"),
|
||||||
WindowEvent::CloseBrowser(..) => write!(f, "CloseBrowser"),
|
WindowEvent::CloseBrowser(..) => write!(f, "CloseBrowser"),
|
||||||
WindowEvent::SelectBrowser(..) => write!(f, "SelectBrowser"),
|
WindowEvent::SelectBrowser(..) => write!(f, "SelectBrowser"),
|
||||||
WindowEvent::ToggleWebRenderDebug(..) => write!(f, "ToggleWebRenderDebug"),
|
WindowEvent::ToggleWebRenderDebug(..) => write!(f, "ToggleWebRenderDebug"),
|
||||||
|
|
|
@ -98,10 +98,11 @@ use canvas_traits::canvas::CanvasId;
|
||||||
use canvas_traits::canvas::CanvasMsg;
|
use canvas_traits::canvas::CanvasMsg;
|
||||||
use clipboard::{ClipboardContext, ClipboardProvider};
|
use clipboard::{ClipboardContext, ClipboardProvider};
|
||||||
use compositing::SendableFrameTree;
|
use compositing::SendableFrameTree;
|
||||||
use compositing::compositor_thread::{CompositorProxy, EmbedderMsg, EmbedderProxy};
|
use compositing::compositor_thread::CompositorProxy;
|
||||||
use compositing::compositor_thread::Msg as ToCompositorMsg;
|
use compositing::compositor_thread::Msg as ToCompositorMsg;
|
||||||
use debugger;
|
use debugger;
|
||||||
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg};
|
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg};
|
||||||
|
use embedder_traits::{EmbedderMsg, EmbedderProxy};
|
||||||
use euclid::{Size2D, TypedSize2D, TypedScale};
|
use euclid::{Size2D, TypedSize2D, TypedScale};
|
||||||
use event_loop::EventLoop;
|
use event_loop::EventLoop;
|
||||||
use gfx::font_cache_thread::FontCacheThread;
|
use gfx::font_cache_thread::FontCacheThread;
|
||||||
|
@ -969,6 +970,15 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
FromCompositorMsg::CloseBrowser(top_level_browsing_context_id) => {
|
FromCompositorMsg::CloseBrowser(top_level_browsing_context_id) => {
|
||||||
self.handle_close_top_level_browsing_context(top_level_browsing_context_id);
|
self.handle_close_top_level_browsing_context(top_level_browsing_context_id);
|
||||||
}
|
}
|
||||||
|
// Panic a top level browsing context.
|
||||||
|
FromCompositorMsg::SendError(top_level_browsing_context_id, error) => {
|
||||||
|
debug!("constellation got SendError message");
|
||||||
|
if let Some(id) = top_level_browsing_context_id {
|
||||||
|
self.handle_panic(id, error, None);
|
||||||
|
} else {
|
||||||
|
warn!("constellation got a SendError message without top level id");
|
||||||
|
}
|
||||||
|
}
|
||||||
// Send frame tree to WebRender. Make it visible.
|
// Send frame tree to WebRender. Make it visible.
|
||||||
FromCompositorMsg::SelectBrowser(top_level_browsing_context_id) => {
|
FromCompositorMsg::SelectBrowser(top_level_browsing_context_id) => {
|
||||||
self.send_frame_tree(top_level_browsing_context_id);
|
self.send_frame_tree(top_level_browsing_context_id);
|
||||||
|
@ -1014,12 +1024,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
Some(ctx) => ctx,
|
Some(ctx) => ctx,
|
||||||
};
|
};
|
||||||
|
|
||||||
let source_is_top_level_pipeline = self.browsing_contexts
|
|
||||||
.get(&BrowsingContextId::from(source_top_ctx_id))
|
|
||||||
.map(|ctx| ctx.pipeline_id == source_pipeline_id)
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
match content {
|
match content {
|
||||||
|
FromScriptMsg::ForwardToEmbedder(embedder_msg) => {
|
||||||
|
self.embedder_proxy.send(embedder_msg);
|
||||||
|
}
|
||||||
FromScriptMsg::PipelineExited => {
|
FromScriptMsg::PipelineExited => {
|
||||||
self.handle_pipeline_exited(source_pipeline_id);
|
self.handle_pipeline_exited(source_pipeline_id);
|
||||||
}
|
}
|
||||||
|
@ -1119,34 +1127,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
warn!("Error replying to remove iframe ({})", e);
|
warn!("Error replying to remove iframe ({})", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FromScriptMsg::NewFavicon(url) => {
|
|
||||||
if source_is_top_level_pipeline {
|
|
||||||
self.embedder_proxy.send(EmbedderMsg::NewFavicon(source_top_ctx_id, url));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FromScriptMsg::HeadParsed => {
|
|
||||||
if source_is_top_level_pipeline {
|
|
||||||
self.embedder_proxy.send(EmbedderMsg::HeadParsed(source_top_ctx_id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FromScriptMsg::CreateCanvasPaintThread(size, sender) => {
|
FromScriptMsg::CreateCanvasPaintThread(size, sender) => {
|
||||||
self.handle_create_canvas_paint_thread_msg(&size, sender)
|
self.handle_create_canvas_paint_thread_msg(&size, sender)
|
||||||
}
|
}
|
||||||
FromScriptMsg::NodeStatus(message) => {
|
|
||||||
self.embedder_proxy.send(EmbedderMsg::Status(source_top_ctx_id, message));
|
|
||||||
}
|
|
||||||
FromScriptMsg::SetDocumentState(state) => {
|
FromScriptMsg::SetDocumentState(state) => {
|
||||||
self.document_states.insert(source_pipeline_id, state);
|
self.document_states.insert(source_pipeline_id, state);
|
||||||
}
|
}
|
||||||
FromScriptMsg::Alert(message, sender) => {
|
|
||||||
self.handle_alert(source_top_ctx_id, message, sender);
|
|
||||||
}
|
|
||||||
FromScriptMsg::MoveTo(point) => {
|
|
||||||
self.embedder_proxy.send(EmbedderMsg::MoveTo(source_top_ctx_id, point));
|
|
||||||
}
|
|
||||||
FromScriptMsg::ResizeTo(size) => {
|
|
||||||
self.embedder_proxy.send(EmbedderMsg::ResizeTo(source_top_ctx_id, size));
|
|
||||||
}
|
|
||||||
FromScriptMsg::GetClientWindow(send) => {
|
FromScriptMsg::GetClientWindow(send) => {
|
||||||
self.compositor_proxy.send(ToCompositorMsg::GetClientWindow(send));
|
self.compositor_proxy.send(ToCompositorMsg::GetClientWindow(send));
|
||||||
}
|
}
|
||||||
|
@ -1162,15 +1148,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
FromScriptMsg::LogEntry(thread_name, entry) => {
|
FromScriptMsg::LogEntry(thread_name, entry) => {
|
||||||
self.handle_log_entry(Some(source_top_ctx_id), thread_name, entry);
|
self.handle_log_entry(Some(source_top_ctx_id), thread_name, entry);
|
||||||
}
|
}
|
||||||
FromScriptMsg::SetTitle(title) => {
|
|
||||||
if source_is_top_level_pipeline {
|
|
||||||
self.embedder_proxy.send(EmbedderMsg::ChangePageTitle(source_top_ctx_id, title))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FromScriptMsg::SendKeyEvent(ch, key, key_state, key_modifiers) => {
|
|
||||||
let event = EmbedderMsg::KeyEvent(Some(source_top_ctx_id), ch, key, key_state, key_modifiers);
|
|
||||||
self.embedder_proxy.send(event);
|
|
||||||
}
|
|
||||||
FromScriptMsg::TouchEventProcessed(result) => {
|
FromScriptMsg::TouchEventProcessed(result) => {
|
||||||
self.compositor_proxy.send(ToCompositorMsg::TouchEventProcessed(result))
|
self.compositor_proxy.send(ToCompositorMsg::TouchEventProcessed(result))
|
||||||
}
|
}
|
||||||
|
@ -1208,15 +1185,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
FromScriptMsg::BroadcastStorageEvent(storage, url, key, old_value, new_value) => {
|
FromScriptMsg::BroadcastStorageEvent(storage, url, key, old_value, new_value) => {
|
||||||
self.handle_broadcast_storage_event(source_pipeline_id, storage, url, key, old_value, new_value);
|
self.handle_broadcast_storage_event(source_pipeline_id, storage, url, key, old_value, new_value);
|
||||||
}
|
}
|
||||||
FromScriptMsg::SetFullscreenState(state) => {
|
|
||||||
self.embedder_proxy.send(EmbedderMsg::SetFullscreenState(source_top_ctx_id, state));
|
|
||||||
}
|
|
||||||
FromScriptMsg::ShowIME(kind) => {
|
|
||||||
self.embedder_proxy.send(EmbedderMsg::ShowIME(source_top_ctx_id, kind));
|
|
||||||
}
|
|
||||||
FromScriptMsg::HideIME => {
|
|
||||||
self.embedder_proxy.send(EmbedderMsg::HideIME(source_top_ctx_id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1727,23 +1695,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_alert(&mut self,
|
|
||||||
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
|
||||||
_message: String,
|
|
||||||
sender: IpcSender<bool>) {
|
|
||||||
// FIXME: forward alert event to embedder
|
|
||||||
// https://github.com/servo/servo/issues/19992
|
|
||||||
let result = sender.send(true);
|
|
||||||
if let Err(e) = result {
|
|
||||||
let ctx_id = BrowsingContextId::from(top_level_browsing_context_id);
|
|
||||||
let pipeline_id = match self.browsing_contexts.get(&ctx_id) {
|
|
||||||
Some(ctx) => ctx.pipeline_id,
|
|
||||||
None => return warn!("Alert sent for unknown browsing context."),
|
|
||||||
};
|
|
||||||
self.handle_send_error(pipeline_id, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_load_url_msg(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId, source_id: PipelineId,
|
fn handle_load_url_msg(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId, source_id: PipelineId,
|
||||||
load_data: LoadData, replace: bool) {
|
load_data: LoadData, replace: bool) {
|
||||||
self.load_url(top_level_browsing_context_id, source_id, load_data, replace);
|
self.load_url(top_level_browsing_context_id, source_id, load_data, replace);
|
||||||
|
@ -2451,8 +2402,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
entries.extend(session_history.future.iter().rev()
|
entries.extend(session_history.future.iter().rev()
|
||||||
.scan(current_load_data.clone(), &resolve_load_data_future));
|
.scan(current_load_data.clone(), &resolve_load_data_future));
|
||||||
|
let urls = entries.iter().map(|entry| entry.url.clone()).collect();
|
||||||
let msg = EmbedderMsg::HistoryChanged(top_level_browsing_context_id, entries, current_index);
|
let msg = EmbedderMsg::HistoryChanged(top_level_browsing_context_id, urls, current_index);
|
||||||
self.embedder_proxy.send(msg);
|
self.embedder_proxy.send(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ extern crate clipboard;
|
||||||
extern crate compositing;
|
extern crate compositing;
|
||||||
extern crate debugger;
|
extern crate debugger;
|
||||||
extern crate devtools_traits;
|
extern crate devtools_traits;
|
||||||
#[cfg(all(not(target_os = "windows"), not(target_os = "ios")))]
|
#[cfg(not(target_os = "ios"))]
|
||||||
extern crate embedder_traits;
|
extern crate embedder_traits;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
#[cfg(all(not(target_os = "windows"), not(target_os = "ios")))]
|
#[cfg(all(not(target_os = "windows"), not(target_os = "ios")))]
|
||||||
|
|
|
@ -13,4 +13,11 @@ path = "lib.rs"
|
||||||
tests = []
|
tests = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
ipc-channel = "0.10"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
|
log = "0.4"
|
||||||
|
msg = {path = "../msg"}
|
||||||
|
serde = "1.0"
|
||||||
|
servo_url = {path = "../url"}
|
||||||
|
style_traits = {path = "../style_traits"}
|
||||||
|
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
||||||
|
|
|
@ -2,6 +2,146 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#[macro_use] extern crate lazy_static;
|
extern crate ipc_channel;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
extern crate msg;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde;
|
||||||
|
extern crate servo_url;
|
||||||
|
extern crate style_traits;
|
||||||
|
extern crate webrender_api;
|
||||||
|
|
||||||
pub mod resources;
|
pub mod resources;
|
||||||
|
|
||||||
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
use msg::constellation_msg::{InputMethodType, Key, KeyModifiers, KeyState, TopLevelBrowsingContextId};
|
||||||
|
use servo_url::ServoUrl;
|
||||||
|
use std::fmt::{Debug, Error, Formatter};
|
||||||
|
use std::sync::mpsc::{Receiver, Sender};
|
||||||
|
use style_traits::cursor::CursorKind;
|
||||||
|
use webrender_api::{DeviceIntPoint, DeviceUintSize};
|
||||||
|
|
||||||
|
|
||||||
|
/// Used to wake up the event loop, provided by the servo port/embedder.
|
||||||
|
pub trait EventLoopWaker : 'static + Send {
|
||||||
|
fn clone(&self) -> Box<EventLoopWaker + Send>;
|
||||||
|
fn wake(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends messages to the embedder.
|
||||||
|
pub struct EmbedderProxy {
|
||||||
|
pub sender: Sender<EmbedderMsg>,
|
||||||
|
pub event_loop_waker: Box<EventLoopWaker>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EmbedderProxy {
|
||||||
|
pub fn send(&self, msg: EmbedderMsg) {
|
||||||
|
// Send a message and kick the OS event loop awake.
|
||||||
|
if let Err(err) = self.sender.send(msg) {
|
||||||
|
warn!("Failed to send response ({}).", err);
|
||||||
|
}
|
||||||
|
self.event_loop_waker.wake();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for EmbedderProxy {
|
||||||
|
fn clone(&self) -> EmbedderProxy {
|
||||||
|
EmbedderProxy {
|
||||||
|
sender: self.sender.clone(),
|
||||||
|
event_loop_waker: self.event_loop_waker.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The port that the embedder receives messages on.
|
||||||
|
pub struct EmbedderReceiver {
|
||||||
|
pub receiver: Receiver<EmbedderMsg>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EmbedderReceiver {
|
||||||
|
pub fn try_recv_embedder_msg(&mut self) -> Option<EmbedderMsg> {
|
||||||
|
self.receiver.try_recv().ok()
|
||||||
|
}
|
||||||
|
pub fn recv_embedder_msg(&mut self) -> EmbedderMsg {
|
||||||
|
self.receiver.recv().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub enum EmbedderMsg {
|
||||||
|
/// A status message to be displayed by the browser chrome.
|
||||||
|
Status(TopLevelBrowsingContextId, Option<String>),
|
||||||
|
/// Alerts the embedder that the current page has changed its title.
|
||||||
|
ChangePageTitle(TopLevelBrowsingContextId, Option<String>),
|
||||||
|
/// Move the window to a point
|
||||||
|
MoveTo(TopLevelBrowsingContextId, DeviceIntPoint),
|
||||||
|
/// Resize the window to size
|
||||||
|
ResizeTo(TopLevelBrowsingContextId, DeviceUintSize),
|
||||||
|
// Show an alert message.
|
||||||
|
Alert(TopLevelBrowsingContextId, String, IpcSender<()>),
|
||||||
|
/// Wether or not to follow a link
|
||||||
|
AllowNavigation(TopLevelBrowsingContextId, ServoUrl, IpcSender<bool>),
|
||||||
|
/// Sends an unconsumed key event back to the embedder.
|
||||||
|
KeyEvent(Option<TopLevelBrowsingContextId>, Option<char>, Key, KeyState, KeyModifiers),
|
||||||
|
/// Changes the cursor.
|
||||||
|
SetCursor(CursorKind),
|
||||||
|
/// A favicon was detected
|
||||||
|
NewFavicon(TopLevelBrowsingContextId, ServoUrl),
|
||||||
|
/// <head> tag finished parsing
|
||||||
|
HeadParsed(TopLevelBrowsingContextId),
|
||||||
|
/// The history state has changed.
|
||||||
|
HistoryChanged(TopLevelBrowsingContextId, Vec<ServoUrl>, usize),
|
||||||
|
/// Enter or exit fullscreen
|
||||||
|
SetFullscreenState(TopLevelBrowsingContextId, bool),
|
||||||
|
/// The load of a page has begun
|
||||||
|
LoadStart(TopLevelBrowsingContextId),
|
||||||
|
/// The load of a page has completed
|
||||||
|
LoadComplete(TopLevelBrowsingContextId),
|
||||||
|
/// A pipeline panicked. First string is the reason, second one is the backtrace.
|
||||||
|
Panic(TopLevelBrowsingContextId, String, Option<String>),
|
||||||
|
/// Open dialog to select bluetooth device.
|
||||||
|
GetSelectedBluetoothDevice(Vec<String>, IpcSender<Option<String>>),
|
||||||
|
/// Open file dialog to select files. Set boolean flag to true allows to select multiple files.
|
||||||
|
SelectFiles(Vec<FilterPattern>, bool, IpcSender<Option<Vec<String>>>),
|
||||||
|
/// Request to present an IME to the user when an editable element is focused.
|
||||||
|
ShowIME(TopLevelBrowsingContextId, InputMethodType),
|
||||||
|
/// Request to hide the IME when the editable element is blurred.
|
||||||
|
HideIME(TopLevelBrowsingContextId),
|
||||||
|
/// Servo has shut down
|
||||||
|
Shutdown,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for EmbedderMsg {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
||||||
|
match *self {
|
||||||
|
EmbedderMsg::Status(..) => write!(f, "Status"),
|
||||||
|
EmbedderMsg::ChangePageTitle(..) => write!(f, "ChangePageTitle"),
|
||||||
|
EmbedderMsg::MoveTo(..) => write!(f, "MoveTo"),
|
||||||
|
EmbedderMsg::ResizeTo(..) => write!(f, "ResizeTo"),
|
||||||
|
EmbedderMsg::Alert(..) => write!(f, "Alert"),
|
||||||
|
EmbedderMsg::AllowNavigation(..) => write!(f, "AllowNavigation"),
|
||||||
|
EmbedderMsg::KeyEvent(..) => write!(f, "KeyEvent"),
|
||||||
|
EmbedderMsg::SetCursor(..) => write!(f, "SetCursor"),
|
||||||
|
EmbedderMsg::NewFavicon(..) => write!(f, "NewFavicon"),
|
||||||
|
EmbedderMsg::HeadParsed(..) => write!(f, "HeadParsed"),
|
||||||
|
EmbedderMsg::HistoryChanged(..) => write!(f, "HistoryChanged"),
|
||||||
|
EmbedderMsg::SetFullscreenState(..) => write!(f, "SetFullscreenState"),
|
||||||
|
EmbedderMsg::LoadStart(..) => write!(f, "LoadStart"),
|
||||||
|
EmbedderMsg::LoadComplete(..) => write!(f, "LoadComplete"),
|
||||||
|
EmbedderMsg::Panic(..) => write!(f, "Panic"),
|
||||||
|
EmbedderMsg::GetSelectedBluetoothDevice(..) => write!(f, "GetSelectedBluetoothDevice"),
|
||||||
|
EmbedderMsg::SelectFiles(..) => write!(f, "SelectFiles"),
|
||||||
|
EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"),
|
||||||
|
EmbedderMsg::HideIME(..) => write!(f, "HideIME"),
|
||||||
|
EmbedderMsg::Shutdown => write!(f, "Shutdown"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Filter for file selection;
|
||||||
|
/// the `String` content is expected to be extension (e.g, "doc", without the prefixing ".")
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct FilterPattern(pub String);
|
||||||
|
|
|
@ -16,7 +16,6 @@ doctest = false
|
||||||
base64 = "0.6"
|
base64 = "0.6"
|
||||||
brotli = "1.0.6"
|
brotli = "1.0.6"
|
||||||
cookie = "0.10"
|
cookie = "0.10"
|
||||||
compositing = {path = "../compositing"}
|
|
||||||
devtools_traits = {path = "../devtools_traits"}
|
devtools_traits = {path = "../devtools_traits"}
|
||||||
embedder_traits = { path = "../embedder_traits" }
|
embedder_traits = { path = "../embedder_traits" }
|
||||||
flate2 = "1"
|
flate2 = "1"
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use compositing::compositor_thread::{EmbedderMsg, EmbedderProxy};
|
use embedder_traits::{EmbedderMsg, EmbedderProxy, FilterPattern};
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use mime_guess::guess_mime_type_opt;
|
use mime_guess::guess_mime_type_opt;
|
||||||
use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError};
|
use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError};
|
||||||
use net_traits::filemanager_thread::{FileManagerResult, FileManagerThreadMsg, FileOrigin, FilterPattern};
|
use net_traits::filemanager_thread::{FileManagerResult, FileManagerThreadMsg, FileOrigin};
|
||||||
use net_traits::filemanager_thread::{FileManagerThreadError, ReadFileProgress, RelativePos, SelectedFile};
|
use net_traits::filemanager_thread::{FileManagerThreadError, ReadFileProgress, RelativePos, SelectedFile};
|
||||||
use servo_config::prefs::PREFS;
|
use servo_config::prefs::PREFS;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
extern crate base64;
|
extern crate base64;
|
||||||
extern crate brotli;
|
extern crate brotli;
|
||||||
extern crate compositing;
|
|
||||||
extern crate cookie as cookie_rs;
|
extern crate cookie as cookie_rs;
|
||||||
extern crate devtools_traits;
|
extern crate devtools_traits;
|
||||||
extern crate embedder_traits;
|
extern crate embedder_traits;
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
//! A thread that takes a URL and streams back the binary data.
|
//! A thread that takes a URL and streams back the binary data.
|
||||||
use compositing::compositor_thread::EmbedderProxy;
|
|
||||||
use connector::{create_http_connector, create_ssl_client};
|
use connector::{create_http_connector, create_ssl_client};
|
||||||
use cookie;
|
use cookie;
|
||||||
use cookie_rs;
|
use cookie_rs;
|
||||||
use cookie_storage::CookieStorage;
|
use cookie_storage::CookieStorage;
|
||||||
use devtools_traits::DevtoolsControlMsg;
|
use devtools_traits::DevtoolsControlMsg;
|
||||||
|
use embedder_traits::EmbedderProxy;
|
||||||
use embedder_traits::resources::{self, Resource};
|
use embedder_traits::resources::{self, Resource};
|
||||||
use fetch::cors_cache::CorsCache;
|
use fetch::cors_cache::CorsCache;
|
||||||
use fetch::methods::{CancellationListener, FetchContext, fetch};
|
use fetch::methods::{CancellationListener, FetchContext, fetch};
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use create_embedder_proxy;
|
use create_embedder_proxy;
|
||||||
|
use embedder_traits::FilterPattern;
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
use net::filemanager_thread::FileManager;
|
use net::filemanager_thread::FileManager;
|
||||||
use net_traits::blob_url_store::BlobURLStoreError;
|
use net_traits::blob_url_store::BlobURLStoreError;
|
||||||
use net_traits::filemanager_thread::{FilterPattern, FileManagerThreadMsg, FileManagerThreadError, ReadFileProgress};
|
use net_traits::filemanager_thread::{FileManagerThreadMsg, FileManagerThreadError, ReadFileProgress};
|
||||||
use servo_config::prefs::{PrefValue, PREFS};
|
use servo_config::prefs::{PrefValue, PREFS};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#![cfg(test)]
|
#![cfg(test)]
|
||||||
|
|
||||||
extern crate compositing;
|
|
||||||
extern crate cookie as cookie_rs;
|
extern crate cookie as cookie_rs;
|
||||||
extern crate devtools_traits;
|
extern crate devtools_traits;
|
||||||
extern crate embedder_traits;
|
extern crate embedder_traits;
|
||||||
|
@ -35,8 +34,8 @@ mod mime_classifier;
|
||||||
mod resource_thread;
|
mod resource_thread;
|
||||||
mod subresource_integrity;
|
mod subresource_integrity;
|
||||||
|
|
||||||
use compositing::compositor_thread::{EmbedderProxy, EventLoopWaker};
|
|
||||||
use devtools_traits::DevtoolsControlMsg;
|
use devtools_traits::DevtoolsControlMsg;
|
||||||
|
use embedder_traits::{EmbedderProxy, EventLoopWaker};
|
||||||
use embedder_traits::resources::{self, Resource};
|
use embedder_traits::resources::{self, Resource};
|
||||||
use hyper::server::{Handler, Listening, Server};
|
use hyper::server::{Handler, Listening, Server};
|
||||||
use net::connector::create_ssl_client;
|
use net::connector::create_ssl_client;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use blob_url_store::{BlobBuf, BlobURLStoreError};
|
use blob_url_store::{BlobBuf, BlobURLStoreError};
|
||||||
|
use embedder_traits::FilterPattern;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use num_traits::ToPrimitive;
|
use num_traits::ToPrimitive;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
|
@ -110,11 +111,6 @@ pub struct SelectedFile {
|
||||||
pub type_string: String,
|
pub type_string: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Filter for file selection;
|
|
||||||
/// the `String` content is expected to be extension (e.g, "doc", without the prefixing ".")
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
pub struct FilterPattern(pub String);
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum FileManagerThreadMsg {
|
pub enum FileManagerThreadMsg {
|
||||||
/// Select a single file. Last field is pre-selected file path for testing
|
/// Select a single file. Last field is pre-selected file path for testing
|
||||||
|
|
|
@ -88,6 +88,7 @@ use dom::webglcontextevent::WebGLContextEvent;
|
||||||
use dom::window::{ReflowReason, Window};
|
use dom::window::{ReflowReason, Window};
|
||||||
use dom::windowproxy::WindowProxy;
|
use dom::windowproxy::WindowProxy;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use embedder_traits::EmbedderMsg;
|
||||||
use encoding_rs::{Encoding, UTF_8};
|
use encoding_rs::{Encoding, UTF_8};
|
||||||
use euclid::Point2D;
|
use euclid::Point2D;
|
||||||
use fetch::FetchCanceller;
|
use fetch::FetchCanceller;
|
||||||
|
@ -855,7 +856,8 @@ impl Document {
|
||||||
|
|
||||||
// Notify the embedder to hide the input method.
|
// Notify the embedder to hide the input method.
|
||||||
if elem.input_method_type().is_some() {
|
if elem.input_method_type().is_some() {
|
||||||
self.send_to_constellation(ScriptMsg::HideIME);
|
let top_level_browsing_context_id = self.window().top_level_browsing_context_id();
|
||||||
|
self.send_to_embedder(EmbedderMsg::HideIME(top_level_browsing_context_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -869,12 +871,13 @@ impl Document {
|
||||||
// Update the focus state for all elements in the focus chain.
|
// Update the focus state for all elements in the focus chain.
|
||||||
// https://html.spec.whatwg.org/multipage/#focus-chain
|
// https://html.spec.whatwg.org/multipage/#focus-chain
|
||||||
if focus_type == FocusType::Element {
|
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.
|
// Notify the embedder to display an input method.
|
||||||
if let Some(kind) = elem.input_method_type() {
|
if let Some(kind) = elem.input_method_type() {
|
||||||
self.send_to_constellation(ScriptMsg::ShowIME(kind));
|
let top_level_browsing_context_id = self.window().top_level_browsing_context_id();
|
||||||
|
self.send_to_embedder(EmbedderMsg::ShowIME(top_level_browsing_context_id, kind));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -882,14 +885,23 @@ impl Document {
|
||||||
/// Handles any updates when the document's title has changed.
|
/// Handles any updates when the document's title has changed.
|
||||||
pub fn title_changed(&self) {
|
pub fn title_changed(&self) {
|
||||||
if self.browsing_context().is_some() {
|
if self.browsing_context().is_some() {
|
||||||
self.send_title_to_constellation();
|
self.send_title_to_embedder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends this document's title to the constellation.
|
/// Sends this document's title to the constellation.
|
||||||
pub fn send_title_to_constellation(&self) {
|
pub fn send_title_to_embedder(&self) {
|
||||||
let title = Some(String::from(self.Title()));
|
let window = self.window();
|
||||||
self.send_to_constellation(ScriptMsg::SetTitle(title));
|
if window.is_top_level() {
|
||||||
|
let title = Some(String::from(self.Title()));
|
||||||
|
let top_level_browsing_context_id = window.top_level_browsing_context_id();
|
||||||
|
self.send_to_embedder(EmbedderMsg::ChangePageTitle(top_level_browsing_context_id, title));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_to_embedder(&self, msg: EmbedderMsg) {
|
||||||
|
let window = self.window();
|
||||||
|
window.send_to_embedder(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dirty_all_nodes(&self) {
|
pub fn dirty_all_nodes(&self) {
|
||||||
|
@ -1352,8 +1364,9 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
if cancel_state == EventDefault::Allowed {
|
if cancel_state == EventDefault::Allowed {
|
||||||
let msg = ScriptMsg::SendKeyEvent(ch, key, state, modifiers);
|
let top_level_browsing_context_id = self.window().top_level_browsing_context_id();
|
||||||
self.send_to_constellation(msg);
|
let msg = EmbedderMsg::KeyEvent(Some(top_level_browsing_context_id), ch, key, state, modifiers);
|
||||||
|
self.send_to_embedder(msg);
|
||||||
|
|
||||||
// This behavior is unspecced
|
// This behavior is unspecced
|
||||||
// We are supposed to dispatch synthetic click activation for Space and/or Return,
|
// We are supposed to dispatch synthetic click activation for Space and/or Return,
|
||||||
|
@ -1488,7 +1501,7 @@ impl Document {
|
||||||
// repeated rAF.
|
// repeated rAF.
|
||||||
|
|
||||||
let event = ScriptMsg::ChangeRunningAnimationsState(AnimationState::AnimationCallbacksPresent);
|
let event = ScriptMsg::ChangeRunningAnimationsState(AnimationState::AnimationCallbacksPresent);
|
||||||
self.send_to_constellation(event);
|
self.window().send_to_constellation(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
ident
|
ident
|
||||||
|
@ -1559,7 +1572,7 @@ impl Document {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let event = ScriptMsg::ChangeRunningAnimationsState(AnimationState::NoAnimationCallbacksPresent);
|
let event = ScriptMsg::ChangeRunningAnimationsState(AnimationState::NoAnimationCallbacksPresent);
|
||||||
self.send_to_constellation(event);
|
self.window().send_to_constellation(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the counter of spurious animation frames.
|
// Update the counter of spurious animation frames.
|
||||||
|
@ -2009,7 +2022,7 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn notify_constellation_load(&self) {
|
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>) {
|
pub fn set_current_parser(&self, script: Option<&ServoParser>) {
|
||||||
|
@ -2167,11 +2180,6 @@ impl Document {
|
||||||
registry.lookup_definition(local_name, is)
|
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) {
|
pub fn increment_throw_on_dynamic_markup_insertion_counter(&self) {
|
||||||
let counter = self.throw_on_dynamic_markup_insertion_counter.get();
|
let counter = self.throw_on_dynamic_markup_insertion_counter.get();
|
||||||
self.throw_on_dynamic_markup_insertion_counter.set(counter + 1);
|
self.throw_on_dynamic_markup_insertion_counter.set(counter + 1);
|
||||||
|
@ -2787,8 +2795,9 @@ impl Document {
|
||||||
let window = self.window();
|
let window = self.window();
|
||||||
// Step 6
|
// Step 6
|
||||||
if !error {
|
if !error {
|
||||||
let event = ScriptMsg::SetFullscreenState(true);
|
let top_level_browsing_context_id = self.window().top_level_browsing_context_id();
|
||||||
self.send_to_constellation(event);
|
let event = EmbedderMsg::SetFullscreenState(top_level_browsing_context_id, true);
|
||||||
|
self.send_to_embedder(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
let pipeline_id = self.window().pipeline_id();
|
let pipeline_id = self.window().pipeline_id();
|
||||||
|
@ -2822,8 +2831,9 @@ impl Document {
|
||||||
|
|
||||||
let window = self.window();
|
let window = self.window();
|
||||||
// Step 8
|
// Step 8
|
||||||
let event = ScriptMsg::SetFullscreenState(false);
|
let top_level_browsing_context_id = self.window().top_level_browsing_context_id();
|
||||||
self.send_to_constellation(event);
|
let event = EmbedderMsg::SetFullscreenState(top_level_browsing_context_id, true);
|
||||||
|
self.send_to_embedder(event);
|
||||||
|
|
||||||
// Step 9
|
// Step 9
|
||||||
let trusted_element = Trusted::new(element.r());
|
let trusted_element = Trusted::new(element.r());
|
||||||
|
|
|
@ -12,13 +12,12 @@ use dom::bindings::str::DOMString;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
|
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::globalscope::GlobalScope;
|
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{Node, document_from_node, window_from_node};
|
use dom::node::{Node, document_from_node, window_from_node};
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use embedder_traits::EmbedderMsg;
|
||||||
use html5ever::{LocalName, Prefix};
|
use html5ever::{LocalName, Prefix};
|
||||||
use script_traits::ScriptMsg;
|
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use style::attr::AttrValue;
|
use style::attr::AttrValue;
|
||||||
use time;
|
use time;
|
||||||
|
@ -151,8 +150,11 @@ impl VirtualMethods for HTMLBodyElement {
|
||||||
let window = window_from_node(self);
|
let window = window_from_node(self);
|
||||||
let document = window.Document();
|
let document = window.Document();
|
||||||
document.set_reflow_timeout(time::precise_time_ns() + INITIAL_REFLOW_DELAY);
|
document.set_reflow_timeout(time::precise_time_ns() + INITIAL_REFLOW_DELAY);
|
||||||
let event = ScriptMsg::HeadParsed;
|
if window.is_top_level() {
|
||||||
window.upcast::<GlobalScope>().script_to_constellation_chan().send(event).unwrap();
|
let top_level_browsing_context_id = window.top_level_browsing_context_id();
|
||||||
|
let msg = EmbedderMsg::HeadParsed(top_level_browsing_context_id);
|
||||||
|
window.send_to_embedder(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue {
|
fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue {
|
||||||
|
|
|
@ -38,12 +38,13 @@ use dom::validation::Validatable;
|
||||||
use dom::validitystate::ValidationFlags;
|
use dom::validitystate::ValidationFlags;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use embedder_traits::FilterPattern;
|
||||||
use html5ever::{LocalName, Prefix};
|
use html5ever::{LocalName, Prefix};
|
||||||
use mime_guess;
|
use mime_guess;
|
||||||
use msg::constellation_msg::InputMethodType;
|
use msg::constellation_msg::InputMethodType;
|
||||||
use net_traits::{CoreResourceMsg, IpcSend};
|
use net_traits::{CoreResourceMsg, IpcSend};
|
||||||
use net_traits::blob_url_store::get_blob_origin;
|
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 profile_traits::ipc;
|
||||||
use script_layout_interface::rpc::TextIndexResponse;
|
use script_layout_interface::rpc::TextIndexResponse;
|
||||||
use script_traits::ScriptToConstellationChan;
|
use script_traits::ScriptToConstellationChan;
|
||||||
|
|
|
@ -16,15 +16,14 @@ use dom::document::Document;
|
||||||
use dom::domtokenlist::DOMTokenList;
|
use dom::domtokenlist::DOMTokenList;
|
||||||
use dom::element::{AttributeMutation, Element, ElementCreator};
|
use dom::element::{AttributeMutation, Element, ElementCreator};
|
||||||
use dom::element::{cors_setting_for_element, reflect_cross_origin_attribute, set_cross_origin_attribute};
|
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::htmlelement::HTMLElement;
|
||||||
use dom::node::{Node, UnbindContext, document_from_node, window_from_node};
|
use dom::node::{Node, UnbindContext, document_from_node, window_from_node};
|
||||||
use dom::stylesheet::StyleSheet as DOMStyleSheet;
|
use dom::stylesheet::StyleSheet as DOMStyleSheet;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use embedder_traits::EmbedderMsg;
|
||||||
use html5ever::{LocalName, Prefix};
|
use html5ever::{LocalName, Prefix};
|
||||||
use net_traits::ReferrerPolicy;
|
use net_traits::ReferrerPolicy;
|
||||||
use script_traits::ScriptMsg;
|
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
@ -306,8 +305,13 @@ impl HTMLLinkElement {
|
||||||
let document = document_from_node(self);
|
let document = document_from_node(self);
|
||||||
match document.base_url().join(href) {
|
match document.base_url().join(href) {
|
||||||
Ok(url) => {
|
Ok(url) => {
|
||||||
let event = ScriptMsg::NewFavicon(url.clone());
|
let window = document.window();
|
||||||
document.window().upcast::<GlobalScope>().script_to_constellation_chan().send(event).unwrap();
|
if window.is_top_level() {
|
||||||
|
let top_level_browsing_context_id = window.top_level_browsing_context_id();
|
||||||
|
let msg = EmbedderMsg::NewFavicon(top_level_browsing_context_id, url.clone());
|
||||||
|
window.send_to_embedder(msg);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Err(e) => debug!("Parsing url {} failed: {}", href, e)
|
Err(e) => debug!("Parsing url {} failed: {}", href, e)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ use dom::windowproxy::WindowProxy;
|
||||||
use dom::worklet::Worklet;
|
use dom::worklet::Worklet;
|
||||||
use dom::workletglobalscope::WorkletGlobalScopeType;
|
use dom::workletglobalscope::WorkletGlobalScopeType;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use embedder_traits::EmbedderMsg;
|
||||||
use euclid::{Point2D, Vector2D, Rect, Size2D, TypedPoint2D, TypedScale, TypedSize2D};
|
use euclid::{Point2D, Vector2D, Rect, Size2D, TypedPoint2D, TypedScale, TypedSize2D};
|
||||||
use fetch;
|
use fetch;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
@ -58,7 +59,7 @@ use js::jsval::UndefinedValue;
|
||||||
use js::rust::HandleValue;
|
use js::rust::HandleValue;
|
||||||
use layout_image::fetch_image_for_layout;
|
use layout_image::fetch_image_for_layout;
|
||||||
use microtask::MicrotaskQueue;
|
use microtask::MicrotaskQueue;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId};
|
||||||
use net_traits::{ResourceThreads, ReferrerPolicy};
|
use net_traits::{ResourceThreads, ReferrerPolicy};
|
||||||
use net_traits::image_cache::{ImageCache, ImageResponder, ImageResponse};
|
use net_traits::image_cache::{ImageCache, ImageResponder, ImageResponse};
|
||||||
use net_traits::image_cache::{PendingImageId, PendingImageResponse};
|
use net_traits::image_cache::{PendingImageId, PendingImageResponse};
|
||||||
|
@ -114,8 +115,6 @@ use task_source::performance_timeline::PerformanceTimelineTaskSource;
|
||||||
use task_source::user_interaction::UserInteractionTaskSource;
|
use task_source::user_interaction::UserInteractionTaskSource;
|
||||||
use time;
|
use time;
|
||||||
use timers::{IsInterval, TimerCallback};
|
use timers::{IsInterval, TimerCallback};
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
|
||||||
use tinyfiledialogs::{self, MessageBoxIcon};
|
|
||||||
use url::Position;
|
use url::Position;
|
||||||
use webdriver_handlers::jsval_to_webdriver;
|
use webdriver_handlers::jsval_to_webdriver;
|
||||||
use webrender_api::{ExternalScrollId, DeviceIntPoint, DeviceUintSize, DocumentId};
|
use webrender_api::{ExternalScrollId, DeviceIntPoint, DeviceUintSize, DocumentId};
|
||||||
|
@ -356,6 +355,11 @@ impl Window {
|
||||||
self.parent_info
|
self.parent_info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn top_level_browsing_context_id(&self) -> TopLevelBrowsingContextId {
|
||||||
|
let window_proxy = self.window_proxy.get().unwrap();
|
||||||
|
window_proxy.top_level_browsing_context_id()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_script_pair(&self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>) {
|
pub fn new_script_pair(&self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>) {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
(Box::new(SendableMainThreadScriptChan(tx)), Box::new(rx))
|
(Box::new(SendableMainThreadScriptChan(tx)), Box::new(rx))
|
||||||
|
@ -444,18 +448,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
|
// https://html.spec.whatwg.org/multipage/#atob
|
||||||
pub fn base64_btoa(input: DOMString) -> Fallible<DOMString> {
|
pub fn base64_btoa(input: DOMString) -> Fallible<DOMString> {
|
||||||
// "The btoa() method must throw an InvalidCharacterError exception if
|
// "The btoa() method must throw an InvalidCharacterError exception if
|
||||||
|
@ -541,14 +533,12 @@ impl WindowMethods for Window {
|
||||||
stdout.flush().unwrap();
|
stdout.flush().unwrap();
|
||||||
stderr.flush().unwrap();
|
stderr.flush().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let (sender, receiver) = ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap();
|
let (sender, receiver) = ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap();
|
||||||
self.send_to_constellation(ScriptMsg::Alert(s.to_string(), sender));
|
let window_proxy = self.window_proxy.get().unwrap();
|
||||||
|
let top_level_browsing_context_id = window_proxy.top_level_browsing_context_id();
|
||||||
let should_display_alert_dialog = receiver.recv().unwrap();
|
let msg = EmbedderMsg::Alert(top_level_browsing_context_id, s.to_string(), sender);
|
||||||
if should_display_alert_dialog {
|
self.send_to_embedder(msg);
|
||||||
display_alert_dialog(&s);
|
receiver.recv().unwrap();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-window-closed
|
// https://html.spec.whatwg.org/multipage/#dom-window-closed
|
||||||
|
@ -937,7 +927,8 @@ impl WindowMethods for Window {
|
||||||
//TODO determine if this operation is allowed
|
//TODO determine if this operation is allowed
|
||||||
let dpr = self.device_pixel_ratio();
|
let dpr = self.device_pixel_ratio();
|
||||||
let size = TypedSize2D::new(width, height).to_f32() * dpr;
|
let size = TypedSize2D::new(width, height).to_f32() * dpr;
|
||||||
self.send_to_constellation(ScriptMsg::ResizeTo(size.to_u32()));
|
let top_level_browsing_context_id = self.top_level_browsing_context_id();
|
||||||
|
self.send_to_embedder(EmbedderMsg::ResizeTo(top_level_browsing_context_id, size.to_u32()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-window-resizeby
|
// https://drafts.csswg.org/cssom-view/#dom-window-resizeby
|
||||||
|
@ -953,7 +944,10 @@ impl WindowMethods for Window {
|
||||||
//TODO determine if this operation is allowed
|
//TODO determine if this operation is allowed
|
||||||
let dpr = self.device_pixel_ratio();
|
let dpr = self.device_pixel_ratio();
|
||||||
let point = TypedPoint2D::new(x, y).to_f32() * dpr;
|
let point = TypedPoint2D::new(x, y).to_f32() * dpr;
|
||||||
self.send_to_constellation(ScriptMsg::MoveTo(point.to_i32()));
|
let window_proxy = self.window_proxy.get().unwrap();
|
||||||
|
let top_level_browsing_context_id = window_proxy.top_level_browsing_context_id();
|
||||||
|
let msg = EmbedderMsg::MoveTo(top_level_browsing_context_id, point.to_i32());
|
||||||
|
self.send_to_embedder(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-window-moveby
|
// https://drafts.csswg.org/cssom-view/#dom-window-moveby
|
||||||
|
@ -1742,7 +1736,11 @@ impl Window {
|
||||||
self.navigation_start_precise.set(time::precise_time_ns());
|
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>()
|
self.upcast::<GlobalScope>()
|
||||||
.script_to_constellation_chan()
|
.script_to_constellation_chan()
|
||||||
.send(msg)
|
.send(msg)
|
||||||
|
|
|
@ -93,7 +93,7 @@ extern crate style;
|
||||||
extern crate style_traits;
|
extern crate style_traits;
|
||||||
extern crate swapper;
|
extern crate swapper;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
#[cfg(target_os = "linux")]
|
||||||
extern crate tinyfiledialogs;
|
extern crate tinyfiledialogs;
|
||||||
extern crate unicode_segmentation;
|
extern crate unicode_segmentation;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
|
@ -62,6 +62,7 @@ use dom::windowproxy::WindowProxy;
|
||||||
use dom::worker::TrustedWorkerAddress;
|
use dom::worker::TrustedWorkerAddress;
|
||||||
use dom::worklet::WorkletThreadPool;
|
use dom::worklet::WorkletThreadPool;
|
||||||
use dom::workletglobalscope::WorkletGlobalScopeInit;
|
use dom::workletglobalscope::WorkletGlobalScopeInit;
|
||||||
|
use embedder_traits::EmbedderMsg;
|
||||||
use euclid::{Point2D, Vector2D, Rect};
|
use euclid::{Point2D, Vector2D, Rect};
|
||||||
use fetch::FetchCanceller;
|
use fetch::FetchCanceller;
|
||||||
use hyper::header::{ContentType, HttpDate, Headers, LastModified};
|
use hyper::header::{ContentType, HttpDate, Headers, LastModified};
|
||||||
|
@ -1822,7 +1823,7 @@ impl ScriptThread {
|
||||||
Some(document) => document,
|
Some(document) => document,
|
||||||
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
|
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.
|
/// Handles a request to exit a pipeline and shut down layout.
|
||||||
|
@ -2282,6 +2283,8 @@ impl ScriptThread {
|
||||||
Some(document) => document,
|
Some(document) => document,
|
||||||
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
|
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
|
||||||
};
|
};
|
||||||
|
let window = document.window();
|
||||||
|
let top_level_browsing_context_id = window.top_level_browsing_context_id();
|
||||||
|
|
||||||
// Get the previous target temporarily
|
// Get the previous target temporarily
|
||||||
let prev_mouse_over_target = self.topmost_mouse_over_target.get();
|
let prev_mouse_over_target = self.topmost_mouse_over_target.get();
|
||||||
|
@ -2310,9 +2313,8 @@ impl ScriptThread {
|
||||||
let url = document.url();
|
let url = document.url();
|
||||||
url.join(&value).map(|url| url.to_string()).ok()
|
url.join(&value).map(|url| url.to_string()).ok()
|
||||||
});
|
});
|
||||||
|
let event = EmbedderMsg::Status(top_level_browsing_context_id, status);
|
||||||
let event = ScriptMsg::NodeStatus(status);
|
window.send_to_embedder(event);
|
||||||
self.script_sender.send((pipeline_id, event)).unwrap();
|
|
||||||
|
|
||||||
state_already_changed = true;
|
state_already_changed = true;
|
||||||
}
|
}
|
||||||
|
@ -2325,8 +2327,8 @@ impl ScriptThread {
|
||||||
.inclusive_ancestors()
|
.inclusive_ancestors()
|
||||||
.filter_map(DomRoot::downcast::<HTMLAnchorElement>)
|
.filter_map(DomRoot::downcast::<HTMLAnchorElement>)
|
||||||
.next() {
|
.next() {
|
||||||
let event = ScriptMsg::NodeStatus(None);
|
let event = EmbedderMsg::Status(top_level_browsing_context_id, None);
|
||||||
self.script_sender.send((pipeline_id, event)).unwrap();
|
window.send_to_embedder(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ bluetooth_traits = {path = "../bluetooth_traits"}
|
||||||
canvas_traits = {path = "../canvas_traits"}
|
canvas_traits = {path = "../canvas_traits"}
|
||||||
cookie = "0.10"
|
cookie = "0.10"
|
||||||
devtools_traits = {path = "../devtools_traits"}
|
devtools_traits = {path = "../devtools_traits"}
|
||||||
|
embedder_traits = {path = "../embedder_traits"}
|
||||||
euclid = "0.17"
|
euclid = "0.17"
|
||||||
gfx_traits = {path = "../gfx_traits"}
|
gfx_traits = {path = "../gfx_traits"}
|
||||||
hyper = "0.10"
|
hyper = "0.10"
|
||||||
|
@ -34,3 +35,6 @@ time = "0.1.12"
|
||||||
url = "1.2"
|
url = "1.2"
|
||||||
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
||||||
webvr_traits = {path = "../webvr_traits"}
|
webvr_traits = {path = "../webvr_traits"}
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
embedder_traits = { path = "../embedder_traits", features = ["tests"]}
|
||||||
|
|
|
@ -13,6 +13,7 @@ extern crate bluetooth_traits;
|
||||||
extern crate canvas_traits;
|
extern crate canvas_traits;
|
||||||
extern crate cookie as cookie_rs;
|
extern crate cookie as cookie_rs;
|
||||||
extern crate devtools_traits;
|
extern crate devtools_traits;
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
extern crate gfx_traits;
|
extern crate gfx_traits;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
@ -702,6 +703,8 @@ pub enum ConstellationMsg {
|
||||||
NewBrowser(ServoUrl, IpcSender<TopLevelBrowsingContextId>),
|
NewBrowser(ServoUrl, IpcSender<TopLevelBrowsingContextId>),
|
||||||
/// Close a top level browsing context.
|
/// Close a top level browsing context.
|
||||||
CloseBrowser(TopLevelBrowsingContextId),
|
CloseBrowser(TopLevelBrowsingContextId),
|
||||||
|
/// Panic a top level browsing context.
|
||||||
|
SendError(Option<TopLevelBrowsingContextId>, String),
|
||||||
/// Make browser visible.
|
/// Make browser visible.
|
||||||
SelectBrowser(TopLevelBrowsingContextId),
|
SelectBrowser(TopLevelBrowsingContextId),
|
||||||
/// Forward an event to the script task of the given pipeline.
|
/// Forward an event to the script task of the given pipeline.
|
||||||
|
@ -730,6 +733,7 @@ impl fmt::Debug for ConstellationMsg {
|
||||||
WebVREvents(..) => "WebVREvents",
|
WebVREvents(..) => "WebVREvents",
|
||||||
NewBrowser(..) => "NewBrowser",
|
NewBrowser(..) => "NewBrowser",
|
||||||
CloseBrowser(..) => "CloseBrowser",
|
CloseBrowser(..) => "CloseBrowser",
|
||||||
|
SendError(..) => "SendError",
|
||||||
SelectBrowser(..) => "SelectBrowser",
|
SelectBrowser(..) => "SelectBrowser",
|
||||||
ForwardEvent(..) => "ForwardEvent",
|
ForwardEvent(..) => "ForwardEvent",
|
||||||
SetCursor(..) => "SetCursor",
|
SetCursor(..) => "SetCursor",
|
||||||
|
|
|
@ -12,11 +12,11 @@ use WorkerGlobalScopeInit;
|
||||||
use WorkerScriptLoadOrigin;
|
use WorkerScriptLoadOrigin;
|
||||||
use canvas_traits::canvas::{CanvasMsg, CanvasId};
|
use canvas_traits::canvas::{CanvasMsg, CanvasId};
|
||||||
use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
|
use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
|
||||||
|
use embedder_traits::EmbedderMsg;
|
||||||
use euclid::{Size2D, TypedSize2D};
|
use euclid::{Size2D, TypedSize2D};
|
||||||
use gfx_traits::Epoch;
|
use gfx_traits::Epoch;
|
||||||
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
||||||
use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, TraversalDirection};
|
use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, TraversalDirection};
|
||||||
use msg::constellation_msg::{InputMethodType, Key, KeyModifiers, KeyState};
|
|
||||||
use net_traits::CoreResourceMsg;
|
use net_traits::CoreResourceMsg;
|
||||||
use net_traits::request::RequestInit;
|
use net_traits::request::RequestInit;
|
||||||
use net_traits::storage_thread::StorageType;
|
use net_traits::storage_thread::StorageType;
|
||||||
|
@ -83,6 +83,8 @@ pub enum LogEntry {
|
||||||
/// Messages from the script to the constellation.
|
/// Messages from the script to the constellation.
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum ScriptMsg {
|
pub enum ScriptMsg {
|
||||||
|
/// Forward a message to the embedder.
|
||||||
|
ForwardToEmbedder(EmbedderMsg),
|
||||||
/// Requests are sent to constellation and fetches are checked manually
|
/// Requests are sent to constellation and fetches are checked manually
|
||||||
/// for cross-origin loads
|
/// for cross-origin loads
|
||||||
InitiateNavigateRequest(RequestInit, /* cancellation_chan */ IpcReceiver<()>),
|
InitiateNavigateRequest(RequestInit, /* cancellation_chan */ IpcReceiver<()>),
|
||||||
|
@ -104,8 +106,6 @@ pub enum ScriptMsg {
|
||||||
GetParentInfo(PipelineId, IpcSender<Option<PipelineId>>),
|
GetParentInfo(PipelineId, IpcSender<Option<PipelineId>>),
|
||||||
/// Get the nth child browsing context ID for a given browsing context, sorted in tree order.
|
/// Get the nth child browsing context ID for a given browsing context, sorted in tree order.
|
||||||
GetChildBrowsingContextId(BrowsingContextId, usize, IpcSender<Option<BrowsingContextId>>),
|
GetChildBrowsingContextId(BrowsingContextId, usize, IpcSender<Option<BrowsingContextId>>),
|
||||||
/// <head> tag finished parsing
|
|
||||||
HeadParsed,
|
|
||||||
/// All pending loads are complete, and the `load` event for this pipeline
|
/// All pending loads are complete, and the `load` event for this pipeline
|
||||||
/// has been dispatched.
|
/// has been dispatched.
|
||||||
LoadComplete,
|
LoadComplete,
|
||||||
|
@ -124,10 +124,6 @@ pub enum ScriptMsg {
|
||||||
ReplaceHistoryState(HistoryStateId, ServoUrl),
|
ReplaceHistoryState(HistoryStateId, ServoUrl),
|
||||||
/// Gets the length of the joint session history from the constellation.
|
/// Gets the length of the joint session history from the constellation.
|
||||||
JointSessionHistoryLength(IpcSender<u32>),
|
JointSessionHistoryLength(IpcSender<u32>),
|
||||||
/// Favicon detected
|
|
||||||
NewFavicon(ServoUrl),
|
|
||||||
/// Status message to be displayed in the chrome, eg. a link URL on mouseover.
|
|
||||||
NodeStatus(Option<String>),
|
|
||||||
/// Notification that this iframe should be removed.
|
/// Notification that this iframe should be removed.
|
||||||
/// Returns a list of pipelines which were closed.
|
/// Returns a list of pipelines which were closed.
|
||||||
RemoveIFrame(BrowsingContextId, IpcSender<Vec<PipelineId>>),
|
RemoveIFrame(BrowsingContextId, IpcSender<Vec<PipelineId>>),
|
||||||
|
@ -147,17 +143,6 @@ pub enum ScriptMsg {
|
||||||
SetDocumentState(DocumentState),
|
SetDocumentState(DocumentState),
|
||||||
/// Update the pipeline Url, which can change after redirections.
|
/// Update the pipeline Url, which can change after redirections.
|
||||||
SetFinalUrl(ServoUrl),
|
SetFinalUrl(ServoUrl),
|
||||||
/// Check if an alert dialog box should be presented
|
|
||||||
Alert(String, IpcSender<bool>),
|
|
||||||
/// Set title of current page
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#document.title>
|
|
||||||
SetTitle(Option<String>),
|
|
||||||
/// Send a key event
|
|
||||||
SendKeyEvent(Option<char>, Key, KeyState, KeyModifiers),
|
|
||||||
/// Move the window to a point
|
|
||||||
MoveTo(DeviceIntPoint),
|
|
||||||
/// Resize the window to size
|
|
||||||
ResizeTo(DeviceUintSize),
|
|
||||||
/// Script has handled a touch event, and either prevented or allowed default actions.
|
/// Script has handled a touch event, and either prevented or allowed default actions.
|
||||||
TouchEventProcessed(EventResult),
|
TouchEventProcessed(EventResult),
|
||||||
/// A log entry, with the top-level browsing context id and thread name
|
/// A log entry, with the top-level browsing context id and thread name
|
||||||
|
@ -171,18 +156,12 @@ pub enum ScriptMsg {
|
||||||
ForwardDOMMessage(DOMMessage, ServoUrl),
|
ForwardDOMMessage(DOMMessage, ServoUrl),
|
||||||
/// Store the data required to activate a service worker for the given scope
|
/// Store the data required to activate a service worker for the given scope
|
||||||
RegisterServiceWorker(ScopeThings, ServoUrl),
|
RegisterServiceWorker(ScopeThings, ServoUrl),
|
||||||
/// Enter or exit fullscreen
|
|
||||||
SetFullscreenState(bool),
|
|
||||||
/// Get Window Informations size and position
|
/// Get Window Informations size and position
|
||||||
GetClientWindow(IpcSender<(DeviceUintSize, DeviceIntPoint)>),
|
GetClientWindow(IpcSender<(DeviceUintSize, DeviceIntPoint)>),
|
||||||
/// Get the screen size (pixel)
|
/// Get the screen size (pixel)
|
||||||
GetScreenSize(IpcSender<(DeviceUintSize)>),
|
GetScreenSize(IpcSender<(DeviceUintSize)>),
|
||||||
/// Get the available screen size (pixel)
|
/// Get the available screen size (pixel)
|
||||||
GetScreenAvailSize(IpcSender<(DeviceUintSize)>),
|
GetScreenAvailSize(IpcSender<(DeviceUintSize)>),
|
||||||
/// Request to present an IME to the user when an editable element is focused.
|
|
||||||
ShowIME(InputMethodType),
|
|
||||||
/// Request to hide the IME when the editable element is blurred.
|
|
||||||
HideIME,
|
|
||||||
/// Requests that the compositor shut down.
|
/// Requests that the compositor shut down.
|
||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
@ -191,6 +170,7 @@ impl fmt::Debug for ScriptMsg {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use self::ScriptMsg::*;
|
use self::ScriptMsg::*;
|
||||||
let variant = match *self {
|
let variant = match *self {
|
||||||
|
ForwardToEmbedder(..) => "ForwardToEmbedder",
|
||||||
InitiateNavigateRequest(..) => "InitiateNavigateRequest",
|
InitiateNavigateRequest(..) => "InitiateNavigateRequest",
|
||||||
BroadcastStorageEvent(..) => "BroadcastStorageEvent",
|
BroadcastStorageEvent(..) => "BroadcastStorageEvent",
|
||||||
ChangeRunningAnimationsState(..) => "ChangeRunningAnimationsState",
|
ChangeRunningAnimationsState(..) => "ChangeRunningAnimationsState",
|
||||||
|
@ -200,7 +180,6 @@ impl fmt::Debug for ScriptMsg {
|
||||||
GetBrowsingContextId(..) => "GetBrowsingContextId",
|
GetBrowsingContextId(..) => "GetBrowsingContextId",
|
||||||
GetParentInfo(..) => "GetParentInfo",
|
GetParentInfo(..) => "GetParentInfo",
|
||||||
GetChildBrowsingContextId(..) => "GetChildBrowsingContextId",
|
GetChildBrowsingContextId(..) => "GetChildBrowsingContextId",
|
||||||
HeadParsed => "HeadParsed",
|
|
||||||
LoadComplete => "LoadComplete",
|
LoadComplete => "LoadComplete",
|
||||||
LoadUrl(..) => "LoadUrl",
|
LoadUrl(..) => "LoadUrl",
|
||||||
AbortLoadUrl => "AbortLoadUrl",
|
AbortLoadUrl => "AbortLoadUrl",
|
||||||
|
@ -209,8 +188,6 @@ impl fmt::Debug for ScriptMsg {
|
||||||
PushHistoryState(..) => "PushHistoryState",
|
PushHistoryState(..) => "PushHistoryState",
|
||||||
ReplaceHistoryState(..) => "ReplaceHistoryState",
|
ReplaceHistoryState(..) => "ReplaceHistoryState",
|
||||||
JointSessionHistoryLength(..) => "JointSessionHistoryLength",
|
JointSessionHistoryLength(..) => "JointSessionHistoryLength",
|
||||||
NewFavicon(..) => "NewFavicon",
|
|
||||||
NodeStatus(..) => "NodeStatus",
|
|
||||||
RemoveIFrame(..) => "RemoveIFrame",
|
RemoveIFrame(..) => "RemoveIFrame",
|
||||||
SetVisible(..) => "SetVisible",
|
SetVisible(..) => "SetVisible",
|
||||||
VisibilityChangeComplete(..) => "VisibilityChangeComplete",
|
VisibilityChangeComplete(..) => "VisibilityChangeComplete",
|
||||||
|
@ -220,23 +197,15 @@ impl fmt::Debug for ScriptMsg {
|
||||||
ActivateDocument => "ActivateDocument",
|
ActivateDocument => "ActivateDocument",
|
||||||
SetDocumentState(..) => "SetDocumentState",
|
SetDocumentState(..) => "SetDocumentState",
|
||||||
SetFinalUrl(..) => "SetFinalUrl",
|
SetFinalUrl(..) => "SetFinalUrl",
|
||||||
Alert(..) => "Alert",
|
|
||||||
SetTitle(..) => "SetTitle",
|
|
||||||
SendKeyEvent(..) => "SendKeyEvent",
|
|
||||||
MoveTo(..) => "MoveTo",
|
|
||||||
ResizeTo(..) => "ResizeTo",
|
|
||||||
TouchEventProcessed(..) => "TouchEventProcessed",
|
TouchEventProcessed(..) => "TouchEventProcessed",
|
||||||
LogEntry(..) => "LogEntry",
|
LogEntry(..) => "LogEntry",
|
||||||
DiscardDocument => "DiscardDocument",
|
DiscardDocument => "DiscardDocument",
|
||||||
PipelineExited => "PipelineExited",
|
PipelineExited => "PipelineExited",
|
||||||
ForwardDOMMessage(..) => "ForwardDOMMessage",
|
ForwardDOMMessage(..) => "ForwardDOMMessage",
|
||||||
RegisterServiceWorker(..) => "RegisterServiceWorker",
|
RegisterServiceWorker(..) => "RegisterServiceWorker",
|
||||||
SetFullscreenState(..) => "SetFullscreenState",
|
|
||||||
GetClientWindow(..) => "GetClientWindow",
|
GetClientWindow(..) => "GetClientWindow",
|
||||||
GetScreenSize(..) => "GetScreenSize",
|
GetScreenSize(..) => "GetScreenSize",
|
||||||
GetScreenAvailSize(..) => "GetScreenAvailSize",
|
GetScreenAvailSize(..) => "GetScreenAvailSize",
|
||||||
ShowIME(..) => "ShowIME",
|
|
||||||
HideIME => "HideIME",
|
|
||||||
Exit => "Exit",
|
Exit => "Exit",
|
||||||
};
|
};
|
||||||
write!(formatter, "ScriptMsg::{}", variant)
|
write!(formatter, "ScriptMsg::{}", variant)
|
||||||
|
|
|
@ -73,13 +73,13 @@ use bluetooth_traits::BluetoothRequest;
|
||||||
use canvas::gl_context::GLContextFactory;
|
use canvas::gl_context::GLContextFactory;
|
||||||
use canvas::webgl_thread::WebGLThreads;
|
use canvas::webgl_thread::WebGLThreads;
|
||||||
use compositing::{IOCompositor, ShutdownState, RenderNotifier};
|
use compositing::{IOCompositor, ShutdownState, RenderNotifier};
|
||||||
use compositing::compositor_thread::{self, CompositorProxy, CompositorReceiver, InitialCompositorState};
|
use compositing::compositor_thread::{CompositorProxy, CompositorReceiver, InitialCompositorState};
|
||||||
use compositing::compositor_thread::{EmbedderMsg, EmbedderProxy, EmbedderReceiver};
|
|
||||||
use compositing::windowing::{WindowEvent, WindowMethods};
|
use compositing::windowing::{WindowEvent, WindowMethods};
|
||||||
use constellation::{Constellation, InitialConstellationState, UnprivilegedPipelineContent};
|
use constellation::{Constellation, InitialConstellationState, UnprivilegedPipelineContent};
|
||||||
use constellation::{FromCompositorLogger, FromScriptLogger};
|
use constellation::{FromCompositorLogger, FromScriptLogger};
|
||||||
#[cfg(all(not(target_os = "windows"), not(target_os = "ios")))]
|
#[cfg(all(not(target_os = "windows"), not(target_os = "ios")))]
|
||||||
use constellation::content_process_sandbox_profile;
|
use constellation::content_process_sandbox_profile;
|
||||||
|
use embedder_traits::{EmbedderMsg, EmbedderProxy, EmbedderReceiver, EventLoopWaker};
|
||||||
use env_logger::Builder as EnvLoggerBuilder;
|
use env_logger::Builder as EnvLoggerBuilder;
|
||||||
use euclid::Length;
|
use euclid::Length;
|
||||||
#[cfg(all(not(target_os = "windows"), not(target_os = "ios")))]
|
#[cfg(all(not(target_os = "windows"), not(target_os = "ios")))]
|
||||||
|
@ -346,6 +346,13 @@ impl<Window> Servo<Window> where Window: WindowMethods + 'static {
|
||||||
warn!("Sending CloseBrowser message to constellation failed ({}).", e);
|
warn!("Sending CloseBrowser message to constellation failed ({}).", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowEvent::SendError(ctx, e) => {
|
||||||
|
let msg = ConstellationMsg::SendError(ctx, e);
|
||||||
|
if let Err(e) = self.constellation_chan.send(msg) {
|
||||||
|
warn!("Sending CloseBrowser message to constellation failed ({}).", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,7 +424,7 @@ impl<Window> Servo<Window> where Window: WindowMethods + 'static {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_embedder_channel(event_loop_waker: Box<compositor_thread::EventLoopWaker>)
|
fn create_embedder_channel(event_loop_waker: Box<EventLoopWaker>)
|
||||||
-> (EmbedderProxy, EmbedderReceiver) {
|
-> (EmbedderProxy, EmbedderReceiver) {
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = channel();
|
||||||
(EmbedderProxy {
|
(EmbedderProxy {
|
||||||
|
@ -429,7 +436,7 @@ fn create_embedder_channel(event_loop_waker: Box<compositor_thread::EventLoopWak
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_compositor_channel(event_loop_waker: Box<compositor_thread::EventLoopWaker>)
|
fn create_compositor_channel(event_loop_waker: Box<EventLoopWaker>)
|
||||||
-> (CompositorProxy, CompositorReceiver) {
|
-> (CompositorProxy, CompositorReceiver) {
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = channel();
|
||||||
(CompositorProxy {
|
(CompositorProxy {
|
||||||
|
|
|
@ -5,12 +5,10 @@
|
||||||
use euclid::{TypedPoint2D, TypedVector2D};
|
use euclid::{TypedPoint2D, TypedVector2D};
|
||||||
use glutin_app::keyutils::{CMD_OR_CONTROL, CMD_OR_ALT};
|
use glutin_app::keyutils::{CMD_OR_CONTROL, CMD_OR_ALT};
|
||||||
use glutin_app::window::{Window, LINE_HEIGHT};
|
use glutin_app::window::{Window, LINE_HEIGHT};
|
||||||
use servo::compositing::compositor_thread::EmbedderMsg;
|
|
||||||
use servo::compositing::windowing::{WebRenderDebugOption, WindowEvent};
|
use servo::compositing::windowing::{WebRenderDebugOption, WindowEvent};
|
||||||
use servo::ipc_channel::ipc::IpcSender;
|
use servo::embedder_traits::{EmbedderMsg, FilterPattern};
|
||||||
use servo::msg::constellation_msg::{Key, TopLevelBrowsingContextId as BrowserId};
|
use servo::msg::constellation_msg::{Key, TopLevelBrowsingContextId as BrowserId};
|
||||||
use servo::msg::constellation_msg::{KeyModifiers, KeyState, TraversalDirection};
|
use servo::msg::constellation_msg::{KeyModifiers, KeyState, TraversalDirection};
|
||||||
use servo::net_traits::filemanager_thread::FilterPattern;
|
|
||||||
use servo::net_traits::pub_domains::is_reg_domain;
|
use servo::net_traits::pub_domains::is_reg_domain;
|
||||||
use servo::script_traits::TouchEventType;
|
use servo::script_traits::TouchEventType;
|
||||||
use servo::servo_config::opts;
|
use servo::servo_config::opts;
|
||||||
|
@ -21,7 +19,8 @@ use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use tinyfiledialogs;
|
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
||||||
|
use tinyfiledialogs::{self, MessageBoxIcon};
|
||||||
|
|
||||||
pub struct Browser {
|
pub struct Browser {
|
||||||
current_url: Option<ServoUrl>,
|
current_url: Option<ServoUrl>,
|
||||||
|
@ -260,6 +259,13 @@ impl Browser {
|
||||||
EmbedderMsg::ResizeTo(_browser_id, size) => {
|
EmbedderMsg::ResizeTo(_browser_id, size) => {
|
||||||
self.window.set_inner_size(size);
|
self.window.set_inner_size(size);
|
||||||
}
|
}
|
||||||
|
EmbedderMsg::Alert(browser_id, message, sender) => {
|
||||||
|
display_alert_dialog(message.to_owned());
|
||||||
|
if let Err(e) = sender.send(()) {
|
||||||
|
let reason = format!("Failed to send Alert response: {}", e);
|
||||||
|
self.event_queue.push(WindowEvent::SendError(Some(browser_id), reason));
|
||||||
|
}
|
||||||
|
}
|
||||||
EmbedderMsg::AllowNavigation(_browser_id, _url, response_chan) => {
|
EmbedderMsg::AllowNavigation(_browser_id, _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);
|
||||||
|
@ -277,8 +283,8 @@ impl Browser {
|
||||||
EmbedderMsg::HeadParsed(_browser_id, ) => {
|
EmbedderMsg::HeadParsed(_browser_id, ) => {
|
||||||
self.loading_state = Some(LoadingState::Loading);
|
self.loading_state = Some(LoadingState::Loading);
|
||||||
}
|
}
|
||||||
EmbedderMsg::HistoryChanged(_browser_id, entries, current) => {
|
EmbedderMsg::HistoryChanged(_browser_id, urls, current) => {
|
||||||
self.current_url = Some(entries[current].url.clone());
|
self.current_url = Some(urls[current].clone());
|
||||||
}
|
}
|
||||||
EmbedderMsg::SetFullscreenState(_browser_id, state) => {
|
EmbedderMsg::SetFullscreenState(_browser_id, state) => {
|
||||||
self.window.set_fullscreen(state);
|
self.window.set_fullscreen(state);
|
||||||
|
@ -295,13 +301,22 @@ impl Browser {
|
||||||
EmbedderMsg::Panic(_browser_id, _reason, _backtrace) => {
|
EmbedderMsg::Panic(_browser_id, _reason, _backtrace) => {
|
||||||
},
|
},
|
||||||
EmbedderMsg::GetSelectedBluetoothDevice(devices, sender) => {
|
EmbedderMsg::GetSelectedBluetoothDevice(devices, sender) => {
|
||||||
platform_get_selected_devices(devices, sender);
|
let selected = platform_get_selected_devices(devices);
|
||||||
|
if let Err(e) = sender.send(selected) {
|
||||||
|
let reason = format!("Failed to send GetSelectedBluetoothDevice response: {}", e);
|
||||||
|
self.event_queue.push(WindowEvent::SendError(None, reason));
|
||||||
|
};
|
||||||
},
|
},
|
||||||
EmbedderMsg::SelectFiles(patterns, multiple_files, sender) => {
|
EmbedderMsg::SelectFiles(patterns, multiple_files, sender) => {
|
||||||
if opts::get().headless {
|
let res = match (opts::get().headless,
|
||||||
let _ = sender.send(None);
|
platform_get_selected_files(patterns, multiple_files)) {
|
||||||
}
|
(true, _) | (false, None) => sender.send(None),
|
||||||
platform_get_selected_files(patterns, multiple_files, sender);
|
(false, Some(files)) => sender.send(Some(files))
|
||||||
|
};
|
||||||
|
if let Err(e) = res {
|
||||||
|
let reason = format!("Failed to send SelectFiles response: {}", e);
|
||||||
|
self.event_queue.push(WindowEvent::SendError(None, reason));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
EmbedderMsg::ShowIME(_browser_id, _kind) => {
|
EmbedderMsg::ShowIME(_browser_id, _kind) => {
|
||||||
debug!("ShowIME received");
|
debug!("ShowIME received");
|
||||||
|
@ -315,8 +330,22 @@ impl Browser {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
||||||
|
fn display_alert_dialog(message: String) {
|
||||||
|
if !opts::get().headless {
|
||||||
|
let _ = thread::Builder::new().name("display alert dialog".to_owned()).spawn(move || {
|
||||||
|
tinyfiledialogs::message_box_ok("Alert!", &message, MessageBoxIcon::Warning);
|
||||||
|
}).unwrap().join().expect("Thread spawning failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
|
||||||
|
fn display_alert_dialog(_message: String) {
|
||||||
|
// tinyfiledialogs not supported on Android
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn platform_get_selected_devices(devices: Vec<String>, sender: IpcSender<Option<String>>) {
|
fn platform_get_selected_devices(devices: Vec<String>) -> Option<String> {
|
||||||
let picker_name = "Choose a device";
|
let picker_name = "Choose a device";
|
||||||
|
|
||||||
thread::Builder::new().name(picker_name.to_owned()).spawn(move || {
|
thread::Builder::new().name(picker_name.to_owned()).spawn(move || {
|
||||||
|
@ -328,58 +357,54 @@ fn platform_get_selected_devices(devices: Vec<String>, sender: IpcSender<Option<
|
||||||
match tinyfiledialogs::list_dialog("Choose a device", &["Id", "Name"], dialog_rows) {
|
match tinyfiledialogs::list_dialog("Choose a device", &["Id", "Name"], dialog_rows) {
|
||||||
Some(device) => {
|
Some(device) => {
|
||||||
// The device string format will be "Address|Name". We need the first part of it.
|
// The device string format will be "Address|Name". We need the first part of it.
|
||||||
let address = device.split("|").next().map(|s| s.to_string());
|
device.split("|").next().map(|s| s.to_string())
|
||||||
let _ = sender.send(address);
|
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
let _ = sender.send(None);
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).expect("Thread spawning failed");
|
}).unwrap().join().expect("Thread spawning failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
fn platform_get_selected_devices(devices: Vec<String>, sender: IpcSender<Option<String>>) {
|
fn platform_get_selected_devices(devices: Vec<String>) -> Option<String> {
|
||||||
for device in devices {
|
for device in devices {
|
||||||
if let Some(address) = device.split("|").next().map(|s| s.to_string()) {
|
if let Some(address) = device.split("|").next().map(|s| s.to_string()) {
|
||||||
let _ = sender.send(Some(address));
|
return Some(address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let _ = sender.send(None);
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
||||||
fn platform_get_selected_files(patterns: Vec<FilterPattern>,
|
fn platform_get_selected_files(patterns: Vec<FilterPattern>,
|
||||||
multiple_files: bool,
|
multiple_files: bool)
|
||||||
sender: IpcSender<Option<Vec<String>>>) {
|
-> Option<Vec<String>> {
|
||||||
let picker_name = if multiple_files { "Pick files" } else { "Pick a file" };
|
let picker_name = if multiple_files { "Pick files" } else { "Pick a file" };
|
||||||
|
|
||||||
thread::Builder::new().name(picker_name.to_owned()).spawn(move || {
|
thread::Builder::new().name(picker_name.to_owned()).spawn(move || {
|
||||||
let mut filter = vec![];
|
let mut filters = vec![];
|
||||||
for p in patterns {
|
for p in patterns {
|
||||||
let s = "*.".to_string() + &p.0;
|
let s = "*.".to_string() + &p.0;
|
||||||
filter.push(s)
|
filters.push(s)
|
||||||
}
|
}
|
||||||
|
let filter_ref = &(filters.iter().map(|s| s.as_str()).collect::<Vec<&str>>()[..]);
|
||||||
let filter_ref = &(filter.iter().map(|s| s.as_str()).collect::<Vec<&str>>()[..]);
|
let filter_opt = if filters.len() > 0 { Some((filter_ref, "")) } else { None };
|
||||||
let filter_opt = if filter.len() > 0 { Some((filter_ref, "")) } else { None };
|
|
||||||
|
|
||||||
if multiple_files {
|
if multiple_files {
|
||||||
let files = tinyfiledialogs::open_file_dialog_multi(picker_name, "", filter_opt);
|
tinyfiledialogs::open_file_dialog_multi(picker_name, "", filter_opt)
|
||||||
let _ = sender.send(files);
|
|
||||||
} else {
|
} else {
|
||||||
let file = tinyfiledialogs::open_file_dialog(picker_name, "", filter_opt);
|
let file = tinyfiledialogs::open_file_dialog(picker_name, "", filter_opt);
|
||||||
let _ = sender.send(file.map(|x| vec![x]));
|
file.map(|x| vec![x])
|
||||||
}
|
}
|
||||||
}).expect("Thread spawning failed");
|
}).unwrap().join().expect("Thread spawning failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
|
#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
|
||||||
fn platform_get_selected_files(_patterns: Vec<FilterPattern>,
|
fn platform_get_selected_files(_patterns: Vec<FilterPattern>,
|
||||||
_multiple_files: bool,
|
_multiple_files: bool)
|
||||||
sender: IpcSender<Option<Vec<String>>>) {
|
-> Option<Vec<String>> {
|
||||||
warn!("File picker not implemented");
|
warn!("File picker not implemented");
|
||||||
let _ = sender.send(None);
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sanitize_url(request: &str) -> Option<ServoUrl> {
|
fn sanitize_url(request: &str) -> Option<ServoUrl> {
|
||||||
|
|
|
@ -11,9 +11,9 @@ use gleam::gl;
|
||||||
use glutin::{Api, ContextBuilder, GlContext, GlRequest, GlWindow};
|
use glutin::{Api, ContextBuilder, GlContext, GlRequest, GlWindow};
|
||||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||||
use osmesa_sys;
|
use osmesa_sys;
|
||||||
use servo::compositing::compositor_thread::EventLoopWaker;
|
|
||||||
use servo::compositing::windowing::{AnimationState, MouseWindowEvent, WindowEvent};
|
use servo::compositing::windowing::{AnimationState, MouseWindowEvent, WindowEvent};
|
||||||
use servo::compositing::windowing::{EmbedderCoordinates, WindowMethods};
|
use servo::compositing::windowing::{EmbedderCoordinates, WindowMethods};
|
||||||
|
use servo::embedder_traits::EventLoopWaker;
|
||||||
use servo::msg::constellation_msg::{Key, KeyState};
|
use servo::msg::constellation_msg::{Key, KeyState};
|
||||||
use servo::script_traits::TouchEventType;
|
use servo::script_traits::TouchEventType;
|
||||||
use servo::servo_config::opts;
|
use servo::servo_config::opts;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue