#![deny(unsafe_code)]
pub mod wrapper_traits;
use std::any::Any;
use std::borrow::Cow;
use std::sync::atomic::AtomicIsize;
use std::sync::Arc;
use app_units::Au;
use atomic_refcell::AtomicRefCell;
use canvas_traits::canvas::{CanvasId, CanvasMsg};
use crossbeam_channel::Sender;
use euclid::default::{Point2D, Rect};
use euclid::Size2D;
use gfx::font_cache_thread::FontCacheThread;
use gfx_traits::Epoch;
use ipc_channel::ipc::IpcSender;
use libc::c_void;
use malloc_size_of_derive::MallocSizeOf;
use metrics::PaintTimeMetrics;
use msg::constellation_msg::{BrowsingContextId, PipelineId};
use net_traits::image_cache::{ImageCache, PendingImageId};
use profile_traits::mem::ReportsChan;
use profile_traits::time;
use script_traits::{
ConstellationControlMsg, InitialScriptState, LayoutControlMsg, LayoutMsg, LoadData, Painter,
ScrollState, UntrustedNodeAddress, WebrenderIpcSender, WindowSizeData,
};
use servo_arc::Arc as ServoArc;
use servo_url::{ImmutableOrigin, ServoUrl};
use style::animation::DocumentAnimationSet;
use style::context::QuirksMode;
use style::data::ElementData;
use style::dom::OpaqueNode;
use style::invalidation::element::restyle_hints::RestyleHint;
use style::media_queries::Device;
use style::properties::style_structs::Font;
use style::properties::PropertyId;
use style::selector_parser::{PseudoElement, RestyleDamage, Snapshot};
use style::stylesheets::Stylesheet;
use style::Atom;
use style_traits::CSSPixel;
use webrender_api::ImageKey;
pub type GenericLayoutData = dyn Any + Send + Sync;
#[derive(MallocSizeOf)]
pub struct StyleData {
#[ignore_malloc_size_of = "This probably should not be ignored"]
pub element_data: AtomicRefCell<ElementData>,
pub parallel: DomParallelInfo,
}
impl Default for StyleData {
fn default() -> Self {
Self {
element_data: AtomicRefCell::new(ElementData::default()),
parallel: DomParallelInfo::default(),
}
}
}
#[derive(Default, MallocSizeOf)]
pub struct DomParallelInfo {
pub children_to_process: AtomicIsize,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LayoutNodeType {
Element(LayoutElementType),
Text,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LayoutElementType {
Element,
HTMLBodyElement,
HTMLBRElement,
HTMLCanvasElement,
HTMLHtmlElement,
HTMLIFrameElement,
HTMLImageElement,
HTMLInputElement,
HTMLMediaElement,
HTMLObjectElement,
HTMLParagraphElement,
HTMLTableCellElement,
HTMLTableColElement,
HTMLTableElement,
HTMLTableRowElement,
HTMLTableSectionElement,
HTMLTextAreaElement,
SVGSVGElement,
}
pub enum HTMLCanvasDataSource {
WebGL(ImageKey),
Image(Option<IpcSender<CanvasMsg>>),
WebGPU(ImageKey),
}
pub struct HTMLCanvasData {
pub source: HTMLCanvasDataSource,
pub width: u32,
pub height: u32,
pub canvas_id: CanvasId,
}
pub struct SVGSVGData {
pub width: u32,
pub height: u32,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct TrustedNodeAddress(pub *const c_void);
#[allow(unsafe_code)]
unsafe impl Send for TrustedNodeAddress {}
pub enum PendingImageState {
Unrequested(ServoUrl),
PendingResponse,
}
pub struct PendingImage {
pub state: PendingImageState,
pub node: UntrustedNodeAddress,
pub id: PendingImageId,
pub origin: ImmutableOrigin,
}
pub struct HTMLMediaData {
pub current_frame: Option<(ImageKey, i32, i32)>,
}
pub struct LayoutConfig {
pub id: PipelineId,
pub url: ServoUrl,
pub is_iframe: bool,
pub constellation_chan: IpcSender<LayoutMsg>,
pub script_chan: IpcSender<ConstellationControlMsg>,
pub image_cache: Arc<dyn ImageCache>,
pub font_cache_thread: FontCacheThread,
pub time_profiler_chan: time::ProfilerChan,
pub webrender_api_sender: WebrenderIpcSender,
pub paint_time_metrics: PaintTimeMetrics,
pub window_size: WindowSizeData,
}
pub trait LayoutFactory: Send + Sync {
fn create(&self, config: LayoutConfig) -> Box<dyn Layout>;
}
pub trait Layout {
fn handle_constellation_msg(&mut self, msg: LayoutControlMsg);
fn handle_font_cache_msg(&mut self);
fn device(&self) -> &Device;
fn waiting_for_web_fonts_to_load(&self) -> bool;
fn current_epoch(&self) -> Epoch;
fn load_web_fonts_from_stylesheet(&self, stylesheet: ServoArc<Stylesheet>);
fn add_stylesheet(
&mut self,
stylesheet: ServoArc<Stylesheet>,
before_stylsheet: Option<ServoArc<Stylesheet>>,
);
fn exit_now(&mut self);
fn collect_reports(&self, reports_chan: ReportsChan);
fn set_quirks_mode(&mut self, quirks_mode: QuirksMode);
fn remove_stylesheet(&mut self, stylesheet: ServoArc<Stylesheet>);
fn reflow(&mut self, script_reflow: ScriptReflow);
fn register_paint_worklet_modules(
&mut self,
name: Atom,
properties: Vec<Atom>,
painter: Box<dyn Painter>,
);
fn query_content_box(&self, node: OpaqueNode) -> Option<Rect<Au>>;
fn query_content_boxes(&self, node: OpaqueNode) -> Vec<Rect<Au>>;
fn query_client_rect(&self, node: OpaqueNode) -> Rect<i32>;
fn query_element_inner_text(&self, node: TrustedNodeAddress) -> String;
fn query_inner_window_dimension(
&self,
context: BrowsingContextId,
) -> Option<Size2D<f32, CSSPixel>>;
fn query_nodes_from_point(
&self,
point: Point2D<f32>,
query_type: NodesFromPointQueryType,
) -> Vec<UntrustedNodeAddress>;
fn query_offset_parent(&self, node: OpaqueNode) -> OffsetParentResponse;
fn query_resolved_style(
&self,
node: TrustedNodeAddress,
pseudo: Option<PseudoElement>,
property_id: PropertyId,
animations: DocumentAnimationSet,
animation_timeline_value: f64,
) -> String;
fn query_resolved_font_style(
&self,
node: TrustedNodeAddress,
value: &str,
animations: DocumentAnimationSet,
animation_timeline_value: f64,
) -> Option<ServoArc<Font>>;
fn query_scrolling_area(&self, node: Option<OpaqueNode>) -> Rect<i32>;
fn query_text_indext(&self, node: OpaqueNode, point: Point2D<f32>) -> Option<usize>;
}
pub trait ScriptThreadFactory {
fn create(
state: InitialScriptState,
layout_factory: Arc<dyn LayoutFactory>,
font_cache_thread: FontCacheThread,
load_data: LoadData,
user_agent: Cow<'static, str>,
);
}
#[derive(Clone, Default)]
pub struct OffsetParentResponse {
pub node_address: Option<UntrustedNodeAddress>,
pub rect: Rect<Au>,
}
#[derive(Debug, PartialEq)]
pub enum NodesFromPointQueryType {
All,
Topmost,
}
#[derive(Debug, PartialEq)]
pub enum QueryMsg {
ContentBox,
ContentBoxes,
ClientRectQuery,
ScrollingAreaQuery,
OffsetParentQuery,
TextIndexQuery,
NodesFromPointQuery,
ResolvedStyleQuery,
StyleQuery,
ElementInnerTextQuery,
ResolvedFontStyleQuery,
InnerWindowDimensionsQuery,
}
#[derive(Debug, PartialEq)]
pub enum ReflowGoal {
Full,
TickAnimations,
LayoutQuery(QueryMsg, u64),
UpdateScrollNode(ScrollState),
}
impl ReflowGoal {
pub fn needs_display_list(&self) -> bool {
match *self {
ReflowGoal::Full | ReflowGoal::TickAnimations | ReflowGoal::UpdateScrollNode(_) => true,
ReflowGoal::LayoutQuery(ref querymsg, _) => match *querymsg {
QueryMsg::ElementInnerTextQuery |
QueryMsg::InnerWindowDimensionsQuery |
QueryMsg::NodesFromPointQuery |
QueryMsg::ResolvedStyleQuery |
QueryMsg::TextIndexQuery => true,
QueryMsg::ClientRectQuery |
QueryMsg::ContentBox |
QueryMsg::ContentBoxes |
QueryMsg::OffsetParentQuery |
QueryMsg::ResolvedFontStyleQuery |
QueryMsg::ScrollingAreaQuery |
QueryMsg::StyleQuery => false,
},
}
}
pub fn needs_display(&self) -> bool {
match *self {
ReflowGoal::Full | ReflowGoal::TickAnimations | ReflowGoal::UpdateScrollNode(_) => true,
ReflowGoal::LayoutQuery(ref querymsg, _) => match *querymsg {
QueryMsg::NodesFromPointQuery |
QueryMsg::TextIndexQuery |
QueryMsg::ElementInnerTextQuery => true,
QueryMsg::ContentBox |
QueryMsg::ContentBoxes |
QueryMsg::ClientRectQuery |
QueryMsg::ScrollingAreaQuery |
QueryMsg::ResolvedStyleQuery |
QueryMsg::ResolvedFontStyleQuery |
QueryMsg::OffsetParentQuery |
QueryMsg::InnerWindowDimensionsQuery |
QueryMsg::StyleQuery => false,
},
}
}
}
pub struct Reflow {
pub page_clip_rect: Rect<Au>,
}
#[derive(Default)]
pub struct ReflowComplete {
pub pending_images: Vec<PendingImage>,
}
pub struct ScriptReflow {
pub reflow_info: Reflow,
pub document: TrustedNodeAddress,
pub dirty_root: Option<TrustedNodeAddress>,
pub stylesheets_changed: bool,
pub window_size: WindowSizeData,
pub script_join_chan: Sender<ReflowComplete>,
pub reflow_goal: ReflowGoal,
pub dom_count: u32,
pub origin: ImmutableOrigin,
pub pending_restyles: Vec<(TrustedNodeAddress, PendingRestyle)>,
pub animation_timeline_value: f64,
pub animations: DocumentAnimationSet,
}
#[derive(Debug, Default, MallocSizeOf)]
pub struct PendingRestyle {
pub snapshot: Option<Snapshot>,
pub hint: RestyleHint,
pub damage: RestyleDamage,
}