#![deny(missing_docs)]
#![deny(unsafe_code)]
use std::fmt;
use crossbeam_channel::RecvTimeoutError;
use devtools_traits::ScriptToDevtoolsControlMsg;
use embedder_traits::user_contents::{UserContentManagerId, UserContents};
use embedder_traits::{
EmbedderControlId, EmbedderControlResponse, FocusSequenceNumber, InputEventAndId,
JavaScriptEvaluationId, MediaSessionActionType, PaintHitTestResult, ScriptToEmbedderChan,
Theme, ViewportDetails, WebDriverScriptCommand,
};
use euclid::{Scale, Size2D};
use fonts_traits::SystemFontServiceProxySender;
use keyboard_types::Modifiers;
use malloc_size_of_derive::MallocSizeOf;
use media::WindowGLContext;
use net_traits::ResourceThreads;
use paint_api::{CrossProcessPaintApi, PinchZoomInfos};
use pixels::PixelFormat;
use profile_traits::mem;
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize};
use servo_base::cross_process_instant::CrossProcessInstant;
use servo_base::generic_channel::{GenericCallback, GenericReceiver, GenericSender};
use servo_base::id::{
BrowsingContextId, HistoryStateId, PipelineId, PipelineNamespaceId, PipelineNamespaceRequest,
ScriptEventLoopId, WebViewId,
};
#[cfg(feature = "bluetooth")]
use servo_bluetooth_traits::BluetoothRequest;
use servo_canvas_traits::webgl::WebGLPipeline;
use servo_config::prefs::PrefValue;
use servo_constellation_traits::{
KeyboardScroll, LoadData, NavigationHistoryBehavior, ScriptToConstellationSender,
ScrollStateUpdate, StructuredSerializedData, TargetSnapshotParams, WindowSizeType,
};
use servo_url::{ImmutableOrigin, ServoUrl};
use storage_traits::StorageThreads;
use storage_traits::webstorage_thread::WebStorageType;
use strum::IntoStaticStr;
use style_traits::{CSSPixel, SpeculativePainter};
use stylo_atoms::Atom;
#[cfg(feature = "webgpu")]
use webgpu_traits::WebGPUMsg;
use webrender_api::ImageKey;
use webrender_api::units::DevicePixel;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct NewPipelineInfo {
pub parent_info: Option<PipelineId>,
pub new_pipeline_id: PipelineId,
pub browsing_context_id: BrowsingContextId,
pub webview_id: WebViewId,
pub opener: Option<BrowsingContextId>,
pub load_data: LoadData,
pub viewport_details: ViewportDetails,
pub user_content_manager_id: Option<UserContentManagerId>,
pub theme: Theme,
pub target_snapshot_params: TargetSnapshotParams,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum DiscardBrowsingContext {
Yes,
No,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub enum DocumentActivity {
Inactive,
Active,
FullyActive,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum ProgressiveWebMetricType {
FirstPaint,
FirstContentfulPaint,
LargestContentfulPaint {
area: usize,
url: Option<ServoUrl>,
},
TimeToInteractive,
}
impl ProgressiveWebMetricType {
pub fn area(&self) -> usize {
match self {
ProgressiveWebMetricType::LargestContentfulPaint { area, .. } => *area,
_ => 0,
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub enum UpdatePipelineIdReason {
Navigation,
Traversal,
}
#[derive(Deserialize, IntoStaticStr, Serialize)]
pub enum ScriptThreadMessage {
SpawnPipeline(NewPipelineInfo),
StopDelayingLoadEventsMode(PipelineId),
Resize(PipelineId, ViewportDetails, WindowSizeType),
ThemeChange(PipelineId, Theme),
ResizeInactive(PipelineId, ViewportDetails),
ExitFullScreen(PipelineId),
UnloadDocument(PipelineId),
ExitPipeline(WebViewId, PipelineId, DiscardBrowsingContext),
ExitScriptThread,
SendInputEvent(WebViewId, PipelineId, ConstellationInputEvent),
RefreshCursor(PipelineId),
GetTitle(PipelineId),
GetDocumentOrigin(PipelineId, GenericSender<Option<String>>),
SetDocumentActivity(PipelineId, DocumentActivity),
SetThrottled(WebViewId, PipelineId, bool),
SetThrottledInContainingIframe(WebViewId, PipelineId, BrowsingContextId, bool),
NavigateIframe(
PipelineId,
BrowsingContextId,
LoadData,
NavigationHistoryBehavior,
TargetSnapshotParams,
),
PostMessage {
target: PipelineId,
source_webview: WebViewId,
source_with_ancestry: Vec<BrowsingContextId>,
target_origin: Option<ImmutableOrigin>,
source_origin: ImmutableOrigin,
data: Box<StructuredSerializedData>,
},
UpdatePipelineId(
PipelineId,
BrowsingContextId,
WebViewId,
PipelineId,
UpdatePipelineIdReason,
),
UpdateHistoryState(PipelineId, Option<HistoryStateId>, ServoUrl),
RemoveHistoryStates(PipelineId, Vec<HistoryStateId>),
FocusIFrame(PipelineId, BrowsingContextId, FocusSequenceNumber),
FocusDocument(PipelineId, FocusSequenceNumber),
Unfocus(PipelineId, FocusSequenceNumber),
WebDriverScriptCommand(PipelineId, WebDriverScriptCommand),
TickAllAnimations(Vec<WebViewId>),
WebFontLoaded(PipelineId),
DispatchIFrameLoadEvent {
target: BrowsingContextId,
parent: PipelineId,
child: PipelineId,
},
DispatchStorageEvent(
PipelineId,
WebStorageType,
ServoUrl,
Option<String>,
Option<String>,
Option<String>,
),
ReportCSSError(PipelineId, String, u32, u32, String),
Reload(PipelineId),
PaintMetric(
PipelineId,
ProgressiveWebMetricType,
CrossProcessInstant,
bool,
),
MediaSessionAction(PipelineId, MediaSessionActionType),
#[cfg(feature = "webgpu")]
SetWebGPUPort(GenericReceiver<WebGPUMsg>),
SetScrollStates(PipelineId, ScrollStateUpdate),
EvaluateJavaScript(WebViewId, PipelineId, JavaScriptEvaluationId, String),
SendImageKeysBatch(PipelineId, Vec<ImageKey>),
PreferencesUpdated(Vec<(String, PrefValue)>),
NoLongerWaitingOnAsychronousImageUpdates(PipelineId),
ForwardKeyboardScroll(PipelineId, KeyboardScroll),
RequestScreenshotReadiness(WebViewId, PipelineId),
EmbedderControlResponse(EmbedderControlId, EmbedderControlResponse),
SetUserContents(UserContentManagerId, UserContents),
DestroyUserContentManager(UserContentManagerId),
AccessibilityTreeUpdate(WebViewId, accesskit::TreeUpdate),
UpdatePinchZoomInfos(PipelineId, PinchZoomInfos),
SetAccessibilityActive(PipelineId, bool),
TriggerGarbageCollection,
}
impl fmt::Debug for ScriptThreadMessage {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let variant_string: &'static str = self.into();
write!(formatter, "ConstellationControlMsg::{variant_string}")
}
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum DocumentState {
Idle,
Pending,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ConstellationInputEvent {
pub hit_test_result: Option<PaintHitTestResult>,
pub pressed_mouse_buttons: u16,
pub active_keyboard_modifiers: Modifiers,
pub event: InputEventAndId,
}
#[derive(Deserialize, Serialize)]
pub struct InitialScriptState {
pub id: ScriptEventLoopId,
pub namespace_request_sender: GenericSender<PipelineNamespaceRequest>,
pub constellation_to_script_sender: GenericSender<ScriptThreadMessage>,
pub constellation_to_script_receiver: GenericReceiver<ScriptThreadMessage>,
pub script_to_constellation_sender: ScriptToConstellationSender,
pub script_to_embedder_sender: ScriptToEmbedderChan,
pub system_font_service: SystemFontServiceProxySender,
pub resource_threads: ResourceThreads,
pub storage_threads: StorageThreads,
#[cfg(feature = "bluetooth")]
pub bluetooth_sender: GenericSender<BluetoothRequest>,
pub time_profiler_sender: profile_traits::time::ProfilerChan,
pub memory_profiler_sender: mem::ProfilerChan,
pub devtools_server_sender: Option<GenericCallback<ScriptToDevtoolsControlMsg>>,
pub pipeline_namespace_id: PipelineNamespaceId,
pub webgl_chan: Option<WebGLPipeline>,
pub webxr_registry: Option<webxr_api::Registry>,
pub cross_process_paint_api: CrossProcessPaintApi,
pub player_context: WindowGLContext,
pub privileged_urls: Vec<ServoUrl>,
pub user_contents_for_manager_id: FxHashMap<UserContentManagerId, UserContents>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum PaintWorkletError {
Timeout,
WorkletNotFound,
}
impl From<RecvTimeoutError> for PaintWorkletError {
fn from(_: RecvTimeoutError) -> PaintWorkletError {
PaintWorkletError::Timeout
}
}
pub trait Painter: SpeculativePainter {
fn draw_a_paint_image(
&self,
size: Size2D<f32, CSSPixel>,
zoom: Scale<f32, CSSPixel, DevicePixel>,
properties: Vec<(Atom, String)>,
arguments: Vec<String>,
) -> Result<DrawAPaintImageResult, PaintWorkletError>;
}
impl fmt::Debug for dyn Painter {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_tuple("Painter")
.field(&format_args!(".."))
.finish()
}
}
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct DrawAPaintImageResult {
pub width: u32,
pub height: u32,
pub format: PixelFormat,
pub image_key: Option<ImageKey>,
pub missing_image_urls: Vec<ServoUrl>,
}