/* 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/. */ //! Types used by the embedding layer and/or exposed to the API. This crate is responsible for //! defining types that cross the process boundary from the embedding/rendering layer all the way //! to script, thus it should have very minimal dependencies on other parts of Servo. If a type //! is not exposed in the API or doesn't involve messages sent to the embedding/libservo layer, it //! is probably a better fit for the `constellation_traits` crate. pub mod embedder_controls; pub mod input_events; pub mod resources; pub mod user_contents; pub mod webdriver; use std::collections::HashMap; use std::ffi::c_void; use std::fmt::{Debug, Display, Error, Formatter}; use std::hash::Hash; use std::ops::Range; use std::sync::Arc; use base::generic_channel::{GenericCallback, GenericSender, GenericSharedMemory, SendResult}; use base::id::{PipelineId, WebViewId}; use crossbeam_channel::Sender; use euclid::{Box2D, Point2D, Scale, Size2D, Vector2D}; use http::{HeaderMap, Method, StatusCode}; use log::warn; use malloc_size_of::malloc_size_of_is_0; use malloc_size_of_derive::MallocSizeOf; use pixels::SharedRasterImage; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use servo_geometry::{DeviceIndependentIntRect, DeviceIndependentIntSize}; use servo_url::ServoUrl; use strum::{EnumMessage, IntoStaticStr}; use style::queries::values::PrefersColorScheme; use style_traits::CSSPixel; use url::Url; use uuid::Uuid; use webrender_api::ExternalScrollId; use webrender_api::units::{ DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixel, DevicePoint, DeviceRect, DeviceVector2D, LayoutPoint, LayoutRect, LayoutSize, LayoutVector2D, }; pub use crate::embedder_controls::*; pub use crate::input_events::*; use crate::user_contents::UserContentManagerId; pub use crate::webdriver::*; /// A point in a `WebView`, either expressed in device pixels or page pixels. /// Page pixels are CSS pixels, which take into account device pixel scale, /// page zoom, and pinch zoom. #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] pub enum WebViewPoint { Device(DevicePoint), Page(Point2D), } impl WebViewPoint { pub fn as_device_point(&self, scale: Scale) -> DevicePoint { match self { Self::Device(point) => *point, Self::Page(point) => *point * scale, } } } impl From for WebViewPoint { fn from(point: DevicePoint) -> Self { Self::Device(point) } } impl From for WebViewPoint { fn from(point: LayoutPoint) -> Self { Self::Page(Point2D::new(point.x, point.y)) } } impl From> for WebViewPoint { fn from(point: Point2D) -> Self { Self::Page(point) } } /// A rectangle in a `WebView`, either expressed in device pixels or page pixels. /// Page pixels are CSS pixels, which take into account device pixel scale, /// page zoom, and pinch zoom. #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] pub enum WebViewRect { Device(DeviceRect), Page(Box2D), } impl WebViewRect { pub fn as_device_rect(&self, scale: Scale) -> DeviceRect { match self { Self::Device(rect) => *rect, Self::Page(rect) => *rect * scale, } } } impl From for WebViewRect { fn from(rect: DeviceRect) -> Self { Self::Device(rect) } } impl From for WebViewRect { fn from(rect: LayoutRect) -> Self { Self::Page(Box2D::new( Point2D::new(rect.min.x, rect.min.y), Point2D::new(rect.max.x, rect.max.y), )) } } impl From> for WebViewRect { fn from(rect: Box2D) -> Self { Self::Page(rect) } } #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] pub enum WebViewVector { Device(DeviceVector2D), Page(Vector2D), } impl WebViewVector { pub fn as_device_vector(&self, scale: Scale) -> DeviceVector2D { match self { Self::Device(vector) => *vector, Self::Page(vector) => *vector * scale, } } } impl From for WebViewVector { fn from(vector: DeviceVector2D) -> Self { Self::Device(vector) } } impl From for WebViewVector { fn from(vector: LayoutVector2D) -> Self { Self::Page(Vector2D::new(vector.x, vector.y)) } } impl From> for WebViewVector { fn from(vector: Vector2D) -> Self { Self::Page(vector) } } #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] pub enum Scroll { Delta(WebViewVector), Start, End, } /// Tracks whether Servo isn't shutting down, is in the process of shutting down, /// or has finished shutting down. #[derive(Clone, Copy, Debug, PartialEq)] pub enum ShutdownState { NotShuttingDown, ShuttingDown, FinishedShuttingDown, } /// 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, Default, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)] pub enum Cursor { None, #[default] 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, } pub trait EventLoopWaker: 'static + Send + Sync { fn clone_box(&self) -> Box; fn wake(&self) {} } impl Clone for Box { fn clone(&self) -> Self { self.clone_box() } } /// Sends messages to the embedder. pub struct GenericEmbedderProxy { pub sender: Sender, pub event_loop_waker: Box, } impl GenericEmbedderProxy { pub fn send(&self, message: T) { // Send a message and kick the OS event loop awake. if let Err(err) = self.sender.send(message) { warn!("Failed to send response ({:?}).", err); } self.event_loop_waker.wake(); } } impl Clone for GenericEmbedderProxy { fn clone(&self) -> Self { Self { sender: self.sender.clone(), event_loop_waker: self.event_loop_waker.clone(), } } } pub type EmbedderProxy = GenericEmbedderProxy; /// A [`RefreshDriver`] is a trait that can be implemented by Servo embedders in /// order to drive let Servo know when to start preparing the next frame. For example, /// on systems that support Vsync notifications, an embedder may want to implement /// this trait to drive Servo animations via those notifications. pub trait RefreshDriver { /// Servo will call this method when it wants to be informed of the next frame start /// time. Implementors should call the callback when it is time to start preparing /// the new frame. /// /// Multiple callbacks may be registered for the same frame. It is up to the implementation /// to call *all* callbacks that have been registered since the last frame. fn observe_next_frame(&self, start_frame_callback: Box); } #[derive(Debug, Default, Deserialize, PartialEq, Serialize)] pub struct AuthenticationResponse { /// Username for http request authentication pub username: String, /// Password for http request authentication pub password: String, } /// A response to a request to allow or deny an action. #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub enum AllowOrDeny { Allow, Deny, } #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] /// Whether a protocol handler is requested to be registered or unregistered. pub enum RegisterOrUnregister { Register, Unregister, } #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ProtocolHandlerUpdateRegistration { /// The scheme for the protocol handler pub scheme: String, /// The URL to navigate to when handling requests for scheme pub url: ServoUrl, /// Whether this update is to register or unregister the protocol handler pub register_or_unregister: RegisterOrUnregister, } /// Data about a `WebView` or `