#![crate_name = "devtools_traits"]
#![crate_type = "rlib"]
#![deny(unsafe_code)]
use std::collections::HashMap;
use std::net::TcpStream;
use std::time::{Duration, SystemTime};
use base::cross_process_instant::CrossProcessInstant;
use base::id::{BrowsingContextId, PipelineId};
use bitflags::bitflags;
use http::{HeaderMap, Method};
use ipc_channel::ipc::IpcSender;
use malloc_size_of_derive::MallocSizeOf;
use net_traits::http_status::HttpStatus;
use serde::{Deserialize, Serialize};
use servo_url::ServoUrl;
use uuid::Uuid;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DevtoolsPageInfo {
pub title: String,
pub url: ServoUrl,
}
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct CSSError {
pub filename: String,
pub line: u32,
pub column: u32,
pub msg: String,
}
#[derive(Debug)]
pub enum DevtoolsControlMsg {
FromChrome(ChromeToDevtoolsControlMsg),
FromScript(ScriptToDevtoolsControlMsg),
}
#[expect(clippy::large_enum_variant)]
#[derive(Debug)]
pub enum ChromeToDevtoolsControlMsg {
AddClient(TcpStream),
ServerExitMsg,
NetworkEvent(String, NetworkEvent),
}
#[derive(Debug, Deserialize, Serialize)]
pub enum NavigationState {
Start(ServoUrl),
Stop(PipelineId, DevtoolsPageInfo),
}
#[derive(Debug, Deserialize, Serialize)]
pub enum ScriptToDevtoolsControlMsg {
NewGlobal(
(BrowsingContextId, PipelineId, Option<WorkerId>),
IpcSender<DevtoolScriptControlMsg>,
DevtoolsPageInfo,
),
Navigate(BrowsingContextId, NavigationState),
ConsoleAPI(PipelineId, ConsoleMessage, Option<WorkerId>),
FramerateTick(String, f64),
ReportCSSError(PipelineId, CSSError),
ReportPageError(PipelineId, PageError),
TitleChanged(PipelineId, String),
}
#[derive(Debug, Deserialize, Serialize)]
pub enum EvaluateJSReply {
VoidValue,
NullValue,
BooleanValue(bool),
NumberValue(f64),
StringValue(String),
ActorValue { class: String, uuid: String },
}
#[derive(Debug, Deserialize, Serialize)]
pub struct AttrInfo {
pub namespace: String,
pub name: String,
pub value: String,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct NodeInfo {
pub unique_id: String,
#[serde(rename = "baseURI")]
pub base_uri: String,
pub parent: String,
pub node_type: u16,
pub node_name: String,
pub node_value: Option<String>,
pub num_children: usize,
pub attrs: Vec<AttrInfo>,
pub is_top_level_document: bool,
}
pub struct StartedTimelineMarker {
name: String,
start_time: CrossProcessInstant,
start_stack: Option<Vec<()>>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct TimelineMarker {
pub name: String,
pub start_time: CrossProcessInstant,
pub start_stack: Option<Vec<()>>,
pub end_time: CrossProcessInstant,
pub end_stack: Option<Vec<()>>,
}
#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub enum TimelineMarkerType {
Reflow,
DOMEvent,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct NodeStyle {
pub name: String,
pub value: String,
pub priority: String,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ComputedNodeLayout {
pub display: String,
pub position: String,
pub z_index: String,
pub box_sizing: String,
pub auto_margins: AutoMargins,
pub margin_top: String,
pub margin_right: String,
pub margin_bottom: String,
pub margin_left: String,
pub border_top_width: String,
pub border_right_width: String,
pub border_bottom_width: String,
pub border_left_width: String,
pub padding_top: String,
pub padding_right: String,
pub padding_bottom: String,
pub padding_left: String,
pub width: f32,
pub height: f32,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct AutoMargins {
pub top: bool,
pub right: bool,
pub bottom: bool,
pub left: bool,
}
#[derive(Debug, Deserialize, Serialize)]
pub enum DevtoolScriptControlMsg {
EvaluateJS(PipelineId, String, IpcSender<EvaluateJSReply>),
GetRootNode(PipelineId, IpcSender<Option<NodeInfo>>),
GetDocumentElement(PipelineId, IpcSender<Option<NodeInfo>>),
GetChildren(PipelineId, String, IpcSender<Option<Vec<NodeInfo>>>),
GetAttributeStyle(PipelineId, String, IpcSender<Option<Vec<NodeStyle>>>),
GetStylesheetStyle(
PipelineId,
String,
String,
usize,
IpcSender<Option<Vec<NodeStyle>>>,
),
GetSelectors(PipelineId, String, IpcSender<Option<Vec<(String, usize)>>>),
GetComputedStyle(PipelineId, String, IpcSender<Option<Vec<NodeStyle>>>),
GetLayout(PipelineId, String, IpcSender<Option<ComputedNodeLayout>>),
ModifyAttribute(PipelineId, String, Vec<AttrModification>),
ModifyRule(PipelineId, String, Vec<RuleModification>),
WantsLiveNotifications(PipelineId, bool),
SetTimelineMarkers(
PipelineId,
Vec<TimelineMarkerType>,
IpcSender<Option<TimelineMarker>>,
),
DropTimelineMarkers(PipelineId, Vec<TimelineMarkerType>),
RequestAnimationFrame(PipelineId, String),
Reload(PipelineId),
GetCssDatabase(IpcSender<HashMap<String, CssDatabaseProperty>>),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AttrModification {
pub attribute_name: String,
pub new_value: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RuleModification {
#[serde(rename = "type")]
pub type_: String,
pub index: u32,
pub name: String,
pub value: String,
pub priority: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum LogLevel {
Log,
Debug,
Info,
Warn,
Error,
Clear,
Trace,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ConsoleMessage {
pub message: String,
pub log_level: LogLevel,
pub filename: String,
pub line_number: usize,
pub column_number: usize,
pub stacktrace: Vec<StackFrame>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StackFrame {
pub filename: String,
#[serde(rename = "functionName")]
pub function_name: String,
#[serde(rename = "columnNumber")]
pub column_number: u32,
#[serde(rename = "lineNumber")]
pub line_number: u32,
}
bitflags! {
#[derive(Deserialize, Serialize)]
pub struct CachedConsoleMessageTypes: u8 {
const PAGE_ERROR = 1 << 0;
const CONSOLE_API = 1 << 1;
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PageError {
#[serde(rename = "_type")]
pub type_: String,
pub error_message: String,
pub source_name: String,
pub line_text: String,
pub line_number: u32,
pub column_number: u32,
pub category: String,
pub time_stamp: u64,
pub error: bool,
pub warning: bool,
pub exception: bool,
pub strict: bool,
pub private: bool,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ConsoleLog {
pub level: String,
pub filename: String,
pub line_number: u32,
pub column_number: u32,
pub time_stamp: u64,
pub arguments: Vec<String>,
pub stacktrace: Vec<StackFrame>,
}
#[derive(Debug, Deserialize, Serialize)]
pub enum CachedConsoleMessage {
PageError(PageError),
ConsoleLog(ConsoleLog),
}
#[derive(Debug, PartialEq)]
pub struct HttpRequest {
pub url: ServoUrl,
pub method: Method,
pub headers: HeaderMap,
pub body: Option<Vec<u8>>,
pub pipeline_id: PipelineId,
pub started_date_time: SystemTime,
pub time_stamp: i64,
pub connect_time: Duration,
pub send_time: Duration,
pub is_xhr: bool,
}
#[derive(Debug, PartialEq)]
pub struct HttpResponse {
pub headers: Option<HeaderMap>,
pub status: HttpStatus,
pub body: Option<Vec<u8>>,
pub pipeline_id: PipelineId,
}
#[derive(Debug)]
pub enum NetworkEvent {
HttpRequest(HttpRequest),
HttpResponse(HttpResponse),
}
impl TimelineMarker {
pub fn start(name: String) -> StartedTimelineMarker {
StartedTimelineMarker {
name,
start_time: CrossProcessInstant::now(),
start_stack: None,
}
}
}
impl StartedTimelineMarker {
pub fn end(self) -> TimelineMarker {
TimelineMarker {
name: self.name,
start_time: self.start_time,
start_stack: self.start_stack,
end_time: CrossProcessInstant::now(),
end_stack: None,
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub struct WorkerId(pub Uuid);
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CssDatabaseProperty {
pub is_inherited: bool,
pub values: Vec<String>,
pub supports: Vec<String>,
pub subproperties: Vec<String>,
}