Skip to main content

browser_protocol/performancetimeline/
mod.rs

1//! Reporting of performance timeline events, as specified in
2//! https://w3c.github.io/performance-timeline/#dom-performanceobserver.
3
4
5use serde::{Serialize, Deserialize};
6use serde_json::Value as JsonValue;
7use std::borrow::Cow;
8
9/// See https://github.com/WICG/LargestContentfulPaint and largest_contentful_paint.idl
10
11#[derive(Debug, Clone, Serialize, Deserialize, Default)]
12#[serde(rename_all = "camelCase")]
13pub struct LargestContentfulPaint<'a> {
14    renderTime: crate::network::TimeSinceEpoch,
15    loadTime: crate::network::TimeSinceEpoch,
16    /// The number of pixels being painted.
17    size: f64,
18    /// The id attribute of the element, if available.
19    #[serde(skip_serializing_if = "Option::is_none")]
20    elementId: Option<Cow<'a, str>>,
21    /// The URL of the image (may be trimmed).
22    #[serde(skip_serializing_if = "Option::is_none")]
23    url: Option<Cow<'a, str>>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    nodeId: Option<crate::dom::BackendNodeId>,
26}
27
28impl<'a> LargestContentfulPaint<'a> {
29    pub fn builder(renderTime: crate::network::TimeSinceEpoch, loadTime: crate::network::TimeSinceEpoch, size: f64) -> LargestContentfulPaintBuilder<'a> {
30        LargestContentfulPaintBuilder {
31            renderTime: renderTime,
32            loadTime: loadTime,
33            size: size,
34            elementId: None,
35            url: None,
36            nodeId: None,
37        }
38    }
39    pub fn renderTime(&self) -> &crate::network::TimeSinceEpoch { &self.renderTime }
40    pub fn loadTime(&self) -> &crate::network::TimeSinceEpoch { &self.loadTime }
41    pub fn size(&self) -> f64 { self.size }
42    pub fn elementId(&self) -> Option<&str> { self.elementId.as_deref() }
43    pub fn url(&self) -> Option<&str> { self.url.as_deref() }
44    pub fn nodeId(&self) -> Option<&crate::dom::BackendNodeId> { self.nodeId.as_ref() }
45}
46
47
48pub struct LargestContentfulPaintBuilder<'a> {
49    renderTime: crate::network::TimeSinceEpoch,
50    loadTime: crate::network::TimeSinceEpoch,
51    size: f64,
52    elementId: Option<Cow<'a, str>>,
53    url: Option<Cow<'a, str>>,
54    nodeId: Option<crate::dom::BackendNodeId>,
55}
56
57impl<'a> LargestContentfulPaintBuilder<'a> {
58    /// The id attribute of the element, if available.
59    pub fn elementId(mut self, elementId: impl Into<Cow<'a, str>>) -> Self { self.elementId = Some(elementId.into()); self }
60    /// The URL of the image (may be trimmed).
61    pub fn url(mut self, url: impl Into<Cow<'a, str>>) -> Self { self.url = Some(url.into()); self }
62    pub fn nodeId(mut self, nodeId: crate::dom::BackendNodeId) -> Self { self.nodeId = Some(nodeId); self }
63    pub fn build(self) -> LargestContentfulPaint<'a> {
64        LargestContentfulPaint {
65            renderTime: self.renderTime,
66            loadTime: self.loadTime,
67            size: self.size,
68            elementId: self.elementId,
69            url: self.url,
70            nodeId: self.nodeId,
71        }
72    }
73}
74
75
76#[derive(Debug, Clone, Serialize, Deserialize, Default)]
77#[serde(rename_all = "camelCase")]
78pub struct LayoutShiftAttribution {
79    previousRect: crate::dom::Rect,
80    currentRect: crate::dom::Rect,
81    #[serde(skip_serializing_if = "Option::is_none")]
82    nodeId: Option<crate::dom::BackendNodeId>,
83}
84
85impl LayoutShiftAttribution {
86    pub fn builder(previousRect: crate::dom::Rect, currentRect: crate::dom::Rect) -> LayoutShiftAttributionBuilder {
87        LayoutShiftAttributionBuilder {
88            previousRect: previousRect,
89            currentRect: currentRect,
90            nodeId: None,
91        }
92    }
93    pub fn previousRect(&self) -> &crate::dom::Rect { &self.previousRect }
94    pub fn currentRect(&self) -> &crate::dom::Rect { &self.currentRect }
95    pub fn nodeId(&self) -> Option<&crate::dom::BackendNodeId> { self.nodeId.as_ref() }
96}
97
98
99pub struct LayoutShiftAttributionBuilder {
100    previousRect: crate::dom::Rect,
101    currentRect: crate::dom::Rect,
102    nodeId: Option<crate::dom::BackendNodeId>,
103}
104
105impl LayoutShiftAttributionBuilder {
106    pub fn nodeId(mut self, nodeId: crate::dom::BackendNodeId) -> Self { self.nodeId = Some(nodeId); self }
107    pub fn build(self) -> LayoutShiftAttribution {
108        LayoutShiftAttribution {
109            previousRect: self.previousRect,
110            currentRect: self.currentRect,
111            nodeId: self.nodeId,
112        }
113    }
114}
115
116/// See https://wicg.github.io/layout-instability/#sec-layout-shift and layout_shift.idl
117
118#[derive(Debug, Clone, Serialize, Deserialize, Default)]
119#[serde(rename_all = "camelCase")]
120pub struct LayoutShift {
121    /// Score increment produced by this event.
122    value: f64,
123    hadRecentInput: bool,
124    lastInputTime: crate::network::TimeSinceEpoch,
125    sources: Vec<LayoutShiftAttribution>,
126}
127
128impl LayoutShift {
129    pub fn builder(value: f64, hadRecentInput: bool, lastInputTime: crate::network::TimeSinceEpoch, sources: Vec<LayoutShiftAttribution>) -> LayoutShiftBuilder {
130        LayoutShiftBuilder {
131            value: value,
132            hadRecentInput: hadRecentInput,
133            lastInputTime: lastInputTime,
134            sources: sources,
135        }
136    }
137    pub fn value(&self) -> f64 { self.value }
138    pub fn hadRecentInput(&self) -> bool { self.hadRecentInput }
139    pub fn lastInputTime(&self) -> &crate::network::TimeSinceEpoch { &self.lastInputTime }
140    pub fn sources(&self) -> &[LayoutShiftAttribution] { &self.sources }
141}
142
143
144pub struct LayoutShiftBuilder {
145    value: f64,
146    hadRecentInput: bool,
147    lastInputTime: crate::network::TimeSinceEpoch,
148    sources: Vec<LayoutShiftAttribution>,
149}
150
151impl LayoutShiftBuilder {
152    pub fn build(self) -> LayoutShift {
153        LayoutShift {
154            value: self.value,
155            hadRecentInput: self.hadRecentInput,
156            lastInputTime: self.lastInputTime,
157            sources: self.sources,
158        }
159    }
160}
161
162
163#[derive(Debug, Clone, Serialize, Deserialize, Default)]
164#[serde(rename_all = "camelCase")]
165pub struct TimelineEvent<'a> {
166    /// Identifies the frame that this event is related to. Empty for non-frame targets.
167    frameId: crate::page::FrameId<'a>,
168    /// The event type, as specified in https://w3c.github.io/performance-timeline/#dom-performanceentry-entrytype
169    /// This determines which of the optional "details" fields is present.
170    #[serde(rename = "type")]
171    type_: Cow<'a, str>,
172    /// Name may be empty depending on the type.
173    name: Cow<'a, str>,
174    /// Time in seconds since Epoch, monotonically increasing within document lifetime.
175    time: crate::network::TimeSinceEpoch,
176    /// Event duration, if applicable.
177    #[serde(skip_serializing_if = "Option::is_none")]
178    duration: Option<f64>,
179    #[serde(skip_serializing_if = "Option::is_none")]
180    lcpDetails: Option<LargestContentfulPaint<'a>>,
181    #[serde(skip_serializing_if = "Option::is_none")]
182    layoutShiftDetails: Option<LayoutShift>,
183}
184
185impl<'a> TimelineEvent<'a> {
186    pub fn builder(frameId: crate::page::FrameId<'a>, type_: impl Into<Cow<'a, str>>, name: impl Into<Cow<'a, str>>, time: crate::network::TimeSinceEpoch) -> TimelineEventBuilder<'a> {
187        TimelineEventBuilder {
188            frameId: frameId,
189            type_: type_.into(),
190            name: name.into(),
191            time: time,
192            duration: None,
193            lcpDetails: None,
194            layoutShiftDetails: None,
195        }
196    }
197    pub fn frameId(&self) -> &crate::page::FrameId<'a> { &self.frameId }
198    pub fn type_(&self) -> &str { self.type_.as_ref() }
199    pub fn name(&self) -> &str { self.name.as_ref() }
200    pub fn time(&self) -> &crate::network::TimeSinceEpoch { &self.time }
201    pub fn duration(&self) -> Option<f64> { self.duration }
202    pub fn lcpDetails(&self) -> Option<&LargestContentfulPaint<'a>> { self.lcpDetails.as_ref() }
203    pub fn layoutShiftDetails(&self) -> Option<&LayoutShift> { self.layoutShiftDetails.as_ref() }
204}
205
206
207pub struct TimelineEventBuilder<'a> {
208    frameId: crate::page::FrameId<'a>,
209    type_: Cow<'a, str>,
210    name: Cow<'a, str>,
211    time: crate::network::TimeSinceEpoch,
212    duration: Option<f64>,
213    lcpDetails: Option<LargestContentfulPaint<'a>>,
214    layoutShiftDetails: Option<LayoutShift>,
215}
216
217impl<'a> TimelineEventBuilder<'a> {
218    /// Event duration, if applicable.
219    pub fn duration(mut self, duration: f64) -> Self { self.duration = Some(duration); self }
220    pub fn lcpDetails(mut self, lcpDetails: LargestContentfulPaint<'a>) -> Self { self.lcpDetails = Some(lcpDetails); self }
221    pub fn layoutShiftDetails(mut self, layoutShiftDetails: LayoutShift) -> Self { self.layoutShiftDetails = Some(layoutShiftDetails); self }
222    pub fn build(self) -> TimelineEvent<'a> {
223        TimelineEvent {
224            frameId: self.frameId,
225            type_: self.type_,
226            name: self.name,
227            time: self.time,
228            duration: self.duration,
229            lcpDetails: self.lcpDetails,
230            layoutShiftDetails: self.layoutShiftDetails,
231        }
232    }
233}
234
235/// Previously buffered events would be reported before method returns.
236/// See also: timelineEventAdded
237
238#[derive(Debug, Clone, Serialize, Deserialize, Default)]
239#[serde(rename_all = "camelCase")]
240pub struct EnableParams<'a> {
241    /// The types of event to report, as specified in
242    /// https://w3c.github.io/performance-timeline/#dom-performanceentry-entrytype
243    /// The specified filter overrides any previous filters, passing empty
244    /// filter disables recording.
245    /// Note that not all types exposed to the web platform are currently supported.
246    eventTypes: Vec<Cow<'a, str>>,
247}
248
249impl<'a> EnableParams<'a> {
250    pub fn builder(eventTypes: Vec<Cow<'a, str>>) -> EnableParamsBuilder<'a> {
251        EnableParamsBuilder {
252            eventTypes: eventTypes,
253        }
254    }
255    pub fn eventTypes(&self) -> &[Cow<'a, str>] { &self.eventTypes }
256}
257
258
259pub struct EnableParamsBuilder<'a> {
260    eventTypes: Vec<Cow<'a, str>>,
261}
262
263impl<'a> EnableParamsBuilder<'a> {
264    pub fn build(self) -> EnableParams<'a> {
265        EnableParams {
266            eventTypes: self.eventTypes,
267        }
268    }
269}
270
271impl<'a> EnableParams<'a> { pub const METHOD: &'static str = "PerformanceTimeline.enable"; }
272
273impl<'a> crate::CdpCommand<'a> for EnableParams<'a> {
274    const METHOD: &'static str = "PerformanceTimeline.enable";
275    type Response = crate::EmptyReturns;
276}