aboutsummaryrefslogtreecommitdiffstats
path: root/components/shared/embedder/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/shared/embedder/lib.rs')
-rw-r--r--components/shared/embedder/lib.rs347
1 files changed, 347 insertions, 0 deletions
diff --git a/components/shared/embedder/lib.rs b/components/shared/embedder/lib.rs
new file mode 100644
index 00000000000..ecaf57a14bb
--- /dev/null
+++ b/components/shared/embedder/lib.rs
@@ -0,0 +1,347 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+pub mod resources;
+
+use std::fmt::{Debug, Error, Formatter};
+
+use crossbeam_channel::{Receiver, Sender};
+use ipc_channel::ipc::IpcSender;
+use keyboard_types::KeyboardEvent;
+use log::warn;
+use msg::constellation_msg::{InputMethodType, PipelineId, TopLevelBrowsingContextId};
+use num_derive::FromPrimitive;
+use serde::{Deserialize, Serialize};
+use servo_url::ServoUrl;
+use webrender_api::units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize};
+pub use webxr_api::MainThreadWaker as EventLoopWaker;
+
+/// A cursor for the window. This is different from a CSS cursor (see
+/// `CursorKind`) in that it has no `Auto` value.
+#[repr(u8)]
+#[derive(Clone, Copy, Debug, Deserialize, Eq, FromPrimitive, PartialEq, Serialize)]
+pub enum Cursor {
+ None,
+ Default,
+ Pointer,
+ ContextMenu,
+ Help,
+ Progress,
+ Wait,
+ Cell,
+ Crosshair,
+ Text,
+ VerticalText,
+ Alias,
+ Copy,
+ Move,
+ NoDrop,
+ NotAllowed,
+ Grab,
+ Grabbing,
+ EResize,
+ NResize,
+ NeResize,
+ NwResize,
+ SResize,
+ SeResize,
+ SwResize,
+ WResize,
+ EwResize,
+ NsResize,
+ NeswResize,
+ NwseResize,
+ ColResize,
+ RowResize,
+ AllScroll,
+ ZoomIn,
+ ZoomOut,
+}
+
+/// Sends messages to the embedder.
+pub struct EmbedderProxy {
+ pub sender: Sender<(Option<TopLevelBrowsingContextId>, EmbedderMsg)>,
+ pub event_loop_waker: Box<dyn EventLoopWaker>,
+}
+
+impl EmbedderProxy {
+ pub fn send(&self, msg: (Option<TopLevelBrowsingContextId>, 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<(Option<TopLevelBrowsingContextId>, EmbedderMsg)>,
+}
+
+impl EmbedderReceiver {
+ pub fn try_recv_embedder_msg(
+ &mut self,
+ ) -> Option<(Option<TopLevelBrowsingContextId>, EmbedderMsg)> {
+ self.receiver.try_recv().ok()
+ }
+ pub fn recv_embedder_msg(&mut self) -> (Option<TopLevelBrowsingContextId>, EmbedderMsg) {
+ self.receiver.recv().unwrap()
+ }
+}
+
+#[derive(Deserialize, Serialize)]
+pub enum ContextMenuResult {
+ Dismissed,
+ Ignored,
+ Selected(usize),
+}
+
+#[derive(Deserialize, Serialize)]
+pub enum PromptDefinition {
+ /// Show a message.
+ Alert(String, IpcSender<()>),
+ /// Ask a Ok/Cancel question.
+ OkCancel(String, IpcSender<PromptResult>),
+ /// Ask a Yes/No question.
+ YesNo(String, IpcSender<PromptResult>),
+ /// Ask the user to enter text.
+ Input(String, String, IpcSender<Option<String>>),
+}
+
+#[derive(Deserialize, PartialEq, Serialize)]
+pub enum PromptOrigin {
+ /// Prompt is triggered from content (window.prompt/alert/confirm/…).
+ /// Prompt message is unknown.
+ Untrusted,
+ /// Prompt is triggered from Servo (ask for permission, show error,…).
+ Trusted,
+}
+
+#[derive(Deserialize, PartialEq, Serialize)]
+pub enum PromptResult {
+ /// Prompt was closed by clicking on the primary button (ok/yes)
+ Primary,
+ /// Prompt was closed by clicking on the secondary button (cancel/no)
+ Secondary,
+ /// Prompt was dismissed
+ Dismissed,
+}
+
+#[derive(Deserialize, Serialize)]
+pub enum EmbedderMsg {
+ /// A status message to be displayed by the browser chrome.
+ Status(Option<String>),
+ /// Alerts the embedder that the current page has changed its title.
+ ChangePageTitle(Option<String>),
+ /// Move the window to a point
+ MoveTo(DeviceIntPoint),
+ /// Resize the window to size
+ ResizeTo(DeviceIntSize),
+ /// Show dialog to user
+ Prompt(PromptDefinition, PromptOrigin),
+ /// Show a context menu to the user
+ ShowContextMenu(IpcSender<ContextMenuResult>, Option<String>, Vec<String>),
+ /// Whether or not to allow a pipeline to load a url.
+ AllowNavigationRequest(PipelineId, ServoUrl),
+ /// Whether or not to allow script to open a new tab/browser
+ AllowOpeningBrowser(IpcSender<bool>),
+ /// A new browser was created by script
+ BrowserCreated(TopLevelBrowsingContextId),
+ /// Wether or not to unload a document
+ AllowUnload(IpcSender<bool>),
+ /// Sends an unconsumed key event back to the embedder.
+ Keyboard(KeyboardEvent),
+ /// Gets system clipboard contents
+ GetClipboardContents(IpcSender<String>),
+ /// Sets system clipboard contents
+ SetClipboardContents(String),
+ /// Changes the cursor.
+ SetCursor(Cursor),
+ /// A favicon was detected
+ NewFavicon(ServoUrl),
+ /// <head> tag finished parsing
+ HeadParsed,
+ /// The history state has changed.
+ HistoryChanged(Vec<ServoUrl>, usize),
+ /// Enter or exit fullscreen
+ SetFullscreenState(bool),
+ /// The load of a page has begun
+ LoadStart,
+ /// The load of a page has completed
+ LoadComplete,
+ /// A browser is to be closed
+ CloseBrowser,
+ /// A pipeline panicked. First string is the reason, second one is the backtrace.
+ Panic(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>>>),
+ /// Open interface to request permission specified by prompt.
+ PromptPermission(PermissionPrompt, IpcSender<PermissionRequest>),
+ /// Request to present an IME to the user when an editable element is focused.
+ /// If the input is text, the second parameter defines the pre-existing string
+ /// text content and the zero-based index into the string locating the insertion point.
+ /// bool is true for multi-line and false otherwise.
+ ShowIME(InputMethodType, Option<(String, i32)>, bool, DeviceIntRect),
+ /// Request to hide the IME when the editable element is blurred.
+ HideIME,
+ /// Servo has shut down
+ Shutdown,
+ /// Report a complete sampled profile
+ ReportProfile(Vec<u8>),
+ /// Notifies the embedder about media session events
+ /// (i.e. when there is metadata for the active media session, playback state changes...).
+ MediaSessionEvent(MediaSessionEvent),
+ /// Report the status of Devtools Server with a token that can be used to bypass the permission prompt.
+ OnDevtoolsStarted(Result<u16, ()>, String),
+ /// Compositing done, but external code needs to present.
+ ReadyToPresent,
+}
+
+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::Prompt(..) => write!(f, "Prompt"),
+ EmbedderMsg::AllowUnload(..) => write!(f, "AllowUnload"),
+ EmbedderMsg::AllowNavigationRequest(..) => write!(f, "AllowNavigationRequest"),
+ EmbedderMsg::Keyboard(..) => write!(f, "Keyboard"),
+ EmbedderMsg::GetClipboardContents(..) => write!(f, "GetClipboardContents"),
+ EmbedderMsg::SetClipboardContents(..) => write!(f, "SetClipboardContents"),
+ EmbedderMsg::SetCursor(..) => write!(f, "SetCursor"),
+ EmbedderMsg::NewFavicon(..) => write!(f, "NewFavicon"),
+ EmbedderMsg::HeadParsed => write!(f, "HeadParsed"),
+ EmbedderMsg::CloseBrowser => write!(f, "CloseBrowser"),
+ 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::PromptPermission(..) => write!(f, "PromptPermission"),
+ EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"),
+ EmbedderMsg::HideIME => write!(f, "HideIME"),
+ EmbedderMsg::Shutdown => write!(f, "Shutdown"),
+ EmbedderMsg::AllowOpeningBrowser(..) => write!(f, "AllowOpeningBrowser"),
+ EmbedderMsg::BrowserCreated(..) => write!(f, "BrowserCreated"),
+ EmbedderMsg::ReportProfile(..) => write!(f, "ReportProfile"),
+ EmbedderMsg::MediaSessionEvent(..) => write!(f, "MediaSessionEvent"),
+ EmbedderMsg::OnDevtoolsStarted(..) => write!(f, "OnDevtoolsStarted"),
+ EmbedderMsg::ShowContextMenu(..) => write!(f, "ShowContextMenu"),
+ EmbedderMsg::ReadyToPresent => write!(f, "ReadyToPresent"),
+ }
+ }
+}
+
+/// 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);
+
+/// https://w3c.github.io/mediasession/#mediametadata
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub struct MediaMetadata {
+ /// Title
+ pub title: String,
+ /// Artist
+ pub artist: String,
+ /// Album
+ pub album: String,
+}
+
+impl MediaMetadata {
+ pub fn new(title: String) -> Self {
+ Self {
+ title,
+ artist: "".to_owned(),
+ album: "".to_owned(),
+ }
+ }
+}
+
+/// https://w3c.github.io/mediasession/#enumdef-mediasessionplaybackstate
+#[repr(i32)]
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub enum MediaSessionPlaybackState {
+ /// The browsing context does not specify whether it’s playing or paused.
+ None_ = 1,
+ /// The browsing context is currently playing media and it can be paused.
+ Playing,
+ /// The browsing context has paused media and it can be resumed.
+ Paused,
+}
+
+/// https://w3c.github.io/mediasession/#dictdef-mediapositionstate
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub struct MediaPositionState {
+ pub duration: f64,
+ pub playback_rate: f64,
+ pub position: f64,
+}
+
+impl MediaPositionState {
+ pub fn new(duration: f64, playback_rate: f64, position: f64) -> Self {
+ Self {
+ duration,
+ playback_rate,
+ position,
+ }
+ }
+}
+
+/// Type of events sent from script to the embedder about the media session.
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub enum MediaSessionEvent {
+ /// Indicates that the media metadata is available.
+ SetMetadata(MediaMetadata),
+ /// Indicates that the playback state has changed.
+ PlaybackStateChange(MediaSessionPlaybackState),
+ /// Indicates that the position state is set.
+ SetPositionState(MediaPositionState),
+}
+
+/// Enum with variants that match the DOM PermissionName enum
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub enum PermissionName {
+ Geolocation,
+ Notifications,
+ Push,
+ Midi,
+ Camera,
+ Microphone,
+ Speaker,
+ DeviceInfo,
+ BackgroundSync,
+ Bluetooth,
+ PersistentStorage,
+}
+
+/// Information required to display a permission prompt
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub enum PermissionPrompt {
+ Insecure(PermissionName),
+ Request(PermissionName),
+}
+
+/// Status for prompting user for permission.
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub enum PermissionRequest {
+ Granted,
+ Denied,
+}