mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
servo: Merge #18283 - User Timing API (from ferjm:user.timing.api); r=jdm
- [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #18109 - [X] There are tests for these changes. I enabled the peformance-timeline API WPTs but some of them are still failing because of implementation bugs or missing APIs (Resource Timing, for instance) the tests are dependent of. I'll file issues to fix them. Source-Repo: https://github.com/servo/servo Source-Revision: 1e93749941d2e3569c7c907832658c57ffb18c72 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 4344c6a1c60484c840cbd3be4112d0c3a710b523
This commit is contained in:
parent
9c94a5b109
commit
383681557d
@ -595,3 +595,42 @@ macro_rules! rooted_vec {
|
||||
let mut $name = $crate::dom::bindings::trace::RootedVec::from_iter(&mut root, $iter);
|
||||
}
|
||||
}
|
||||
|
||||
/// DOM struct implementation for simple interfaces inheriting from PerformanceEntry.
|
||||
macro_rules! impl_performance_entry_struct(
|
||||
($binding:ident, $struct:ident, $type:expr) => (
|
||||
use dom::bindings::codegen::Bindings::$binding;
|
||||
use dom::bindings::js::Root;
|
||||
use dom::bindings::reflector::reflect_dom_object;
|
||||
use dom::bindings::str::DOMString;
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom::performanceentry::PerformanceEntry;
|
||||
use dom_struct::dom_struct;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct $struct {
|
||||
entry: PerformanceEntry,
|
||||
}
|
||||
|
||||
impl $struct {
|
||||
fn new_inherited(name: DOMString, start_time: f64, duration: f64)
|
||||
-> $struct {
|
||||
$struct {
|
||||
entry: PerformanceEntry::new_inherited(name,
|
||||
DOMString::from($type),
|
||||
start_time,
|
||||
duration)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn new(global: &GlobalScope,
|
||||
name: DOMString,
|
||||
start_time: f64,
|
||||
duration: f64) -> Root<$struct> {
|
||||
let entry = $struct::new_inherited(name, start_time, duration);
|
||||
reflect_dom_object(box entry, global, $binding::Wrap)
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
|
@ -399,6 +399,8 @@ pub mod paintsize;
|
||||
pub mod paintworkletglobalscope;
|
||||
pub mod performance;
|
||||
pub mod performanceentry;
|
||||
pub mod performancemark;
|
||||
pub mod performancemeasure;
|
||||
pub mod performanceobserver;
|
||||
pub mod performanceobserverentrylist;
|
||||
pub mod performancepainttiming;
|
||||
|
@ -6,6 +6,7 @@ use dom::bindings::cell::DOMRefCell;
|
||||
use dom::bindings::codegen::Bindings::PerformanceBinding;
|
||||
use dom::bindings::codegen::Bindings::PerformanceBinding::{DOMHighResTimeStamp, PerformanceMethods};
|
||||
use dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceEntryList as DOMPerformanceEntryList;
|
||||
use dom::bindings::error::{Error, Fallible};
|
||||
use dom::bindings::inheritance::Castable;
|
||||
use dom::bindings::js::{JS, Root};
|
||||
use dom::bindings::num::Finite;
|
||||
@ -13,6 +14,8 @@ use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
|
||||
use dom::bindings::str::DOMString;
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom::performanceentry::PerformanceEntry;
|
||||
use dom::performancemark::PerformanceMark;
|
||||
use dom::performancemeasure::PerformanceMeasure;
|
||||
use dom::performanceobserver::PerformanceObserver as DOMPerformanceObserver;
|
||||
use dom::performancetiming::PerformanceTiming;
|
||||
use dom::window::Window;
|
||||
@ -21,6 +24,30 @@ use std::cell::Cell;
|
||||
use std::cmp::Ordering;
|
||||
use time;
|
||||
|
||||
const INVALID_ENTRY_NAMES: &'static [&'static str] = &[
|
||||
"navigationStart",
|
||||
"unloadEventStart",
|
||||
"unloadEventEnd",
|
||||
"redirectStart",
|
||||
"redirectEnd",
|
||||
"fetchStart",
|
||||
"domainLookupStart",
|
||||
"domainLookupEnd",
|
||||
"connectStart",
|
||||
"connectEnd",
|
||||
"secureConnectionStart",
|
||||
"requestStart",
|
||||
"responseStart",
|
||||
"responseEnd",
|
||||
"domLoading",
|
||||
"domInteractive",
|
||||
"domContentLoadedEventStart",
|
||||
"domContentLoadedEventEnd",
|
||||
"domComplete",
|
||||
"loadEventStart",
|
||||
"loadEventEnd",
|
||||
];
|
||||
|
||||
/// Implementation of a list of PerformanceEntry items shared by the
|
||||
/// Performance and PerformanceObserverEntryList interfaces implementations.
|
||||
#[derive(HeapSizeOf, JSTraceable)]
|
||||
@ -44,6 +71,25 @@ impl PerformanceEntryList {
|
||||
res.sort_by(|a, b| a.start_time().partial_cmp(&b.start_time()).unwrap_or(Ordering::Equal));
|
||||
res
|
||||
}
|
||||
|
||||
pub fn clear_entries_by_name_and_type(&mut self, name: Option<DOMString>,
|
||||
entry_type: Option<DOMString>) {
|
||||
self.entries.retain(|e|
|
||||
name.as_ref().map_or(true, |name_| *e.name() == *name_) &&
|
||||
entry_type.as_ref().map_or(true, |type_| *e.entry_type() == *type_)
|
||||
);
|
||||
}
|
||||
|
||||
fn get_last_entry_start_time_with_name_and_type(&self, name: DOMString,
|
||||
entry_type: DOMString) -> f64 {
|
||||
match self.entries.iter()
|
||||
.rev()
|
||||
.find(|e| *e.entry_type() == *entry_type &&
|
||||
*e.name() == *name) {
|
||||
Some(entry) => entry.start_time(),
|
||||
None => 0.,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for PerformanceEntryList {
|
||||
@ -145,9 +191,6 @@ impl Performance {
|
||||
///
|
||||
/// Algorithm spec:
|
||||
/// https://w3c.github.io/performance-timeline/#queue-a-performanceentry
|
||||
///
|
||||
/// XXX This should be called at some point by the User Timing, Resource
|
||||
/// Timing, Server Timing and Paint Timing APIs.
|
||||
pub fn queue_entry(&self, entry: &PerformanceEntry,
|
||||
add_to_performance_entries_buffer: bool) {
|
||||
// Steps 1-3.
|
||||
@ -202,6 +245,14 @@ impl Performance {
|
||||
o.notify();
|
||||
}
|
||||
}
|
||||
|
||||
fn now(&self) -> f64 {
|
||||
let nav_start = match self.timing {
|
||||
Some(ref timing) => timing.navigation_start_precise(),
|
||||
None => self.navigation_start_precise,
|
||||
};
|
||||
(time::precise_time_ns() as f64 - nav_start) / 1000000 as f64
|
||||
}
|
||||
}
|
||||
|
||||
impl PerformanceMethods for Performance {
|
||||
@ -215,12 +266,7 @@ impl PerformanceMethods for Performance {
|
||||
|
||||
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HighResolutionTime/Overview.html#dom-performance-now
|
||||
fn Now(&self) -> DOMHighResTimeStamp {
|
||||
let nav_start = match self.timing {
|
||||
Some(ref timing) => timing.navigation_start_precise(),
|
||||
None => self.navigation_start_precise,
|
||||
};
|
||||
let now = (time::precise_time_ns() as f64 - nav_start) / 1000000 as f64;
|
||||
Finite::wrap(now)
|
||||
Finite::wrap(self.now())
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/performance-timeline-2/#dom-performance-getentries
|
||||
@ -238,4 +284,72 @@ impl PerformanceMethods for Performance {
|
||||
-> Vec<Root<PerformanceEntry>> {
|
||||
self.entries.borrow().get_entries_by_name_and_type(Some(name), entry_type)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/user-timing/#dom-performance-mark
|
||||
fn Mark(&self, mark_name: DOMString) -> Fallible<()> {
|
||||
let global = self.global();
|
||||
// Step 1.
|
||||
if global.is::<Window>() && INVALID_ENTRY_NAMES.contains(&mark_name.as_ref()) {
|
||||
return Err(Error::Syntax);
|
||||
}
|
||||
|
||||
// Steps 2 to 6.
|
||||
let entry = PerformanceMark::new(&global,
|
||||
mark_name,
|
||||
self.now(),
|
||||
0.);
|
||||
// Steps 7 and 8.
|
||||
self.queue_entry(&entry.upcast::<PerformanceEntry>(),
|
||||
true /* buffer performance entry */);
|
||||
|
||||
// Step 9.
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// https://w3c.github.io/user-timing/#dom-performance-clearmarks
|
||||
fn ClearMarks(&self, mark_name: Option<DOMString>) {
|
||||
self.entries.borrow_mut().clear_entries_by_name_and_type(mark_name,
|
||||
Some(DOMString::from("mark")));
|
||||
}
|
||||
|
||||
// https://w3c.github.io/user-timing/#dom-performance-measure
|
||||
fn Measure(&self,
|
||||
measure_name: DOMString,
|
||||
start_mark: Option<DOMString>,
|
||||
end_mark: Option<DOMString>) -> Fallible<()> {
|
||||
// Steps 1 and 2.
|
||||
let end_time = match end_mark {
|
||||
Some(name) =>
|
||||
self.entries.borrow().get_last_entry_start_time_with_name_and_type(
|
||||
DOMString::from("mark"), name),
|
||||
None => self.now(),
|
||||
};
|
||||
|
||||
// Step 3.
|
||||
let start_time = match start_mark {
|
||||
Some(name) =>
|
||||
self.entries.borrow().get_last_entry_start_time_with_name_and_type(
|
||||
DOMString::from("mark"), name),
|
||||
None => 0.,
|
||||
};
|
||||
|
||||
// Steps 4 to 8.
|
||||
let entry = PerformanceMeasure::new(&self.global(),
|
||||
measure_name,
|
||||
start_time,
|
||||
end_time - start_time);
|
||||
|
||||
// Step 9 and 10.
|
||||
self.queue_entry(&entry.upcast::<PerformanceEntry>(),
|
||||
true /* buffer performance entry */);
|
||||
|
||||
// Step 11.
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// https://w3c.github.io/user-timing/#dom-performance-clearmeasures
|
||||
fn ClearMeasures(&self, measure_name: Option<DOMString>) {
|
||||
self.entries.borrow_mut().clear_entries_by_name_and_type(measure_name,
|
||||
Some(DOMString::from("measure")));
|
||||
}
|
||||
}
|
||||
|
7
servo/components/script/dom/performancemark.rs
Normal file
7
servo/components/script/dom/performancemark.rs
Normal file
@ -0,0 +1,7 @@
|
||||
/* 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
impl_performance_entry_struct!(PerformanceMarkBinding,
|
||||
PerformanceMark,
|
||||
"mark");
|
7
servo/components/script/dom/performancemeasure.rs
Normal file
7
servo/components/script/dom/performancemeasure.rs
Normal file
@ -0,0 +1,7 @@
|
||||
/* 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
impl_performance_entry_struct!(PerformanceMeasureBinding,
|
||||
PerformanceMeasure,
|
||||
"measure");
|
@ -22,8 +22,8 @@ use std::rc::Rc;
|
||||
|
||||
/// List of allowed performance entry types.
|
||||
const VALID_ENTRY_TYPES: &'static [&'static str] = &[
|
||||
// "mark", XXX User Timing API
|
||||
// "measure", XXX User Timing API
|
||||
"mark", // User Timing API
|
||||
"measure", // User Timing API
|
||||
// "resource", XXX Resource Timing API
|
||||
// "server", XXX Server Timing API
|
||||
"paint", // Paint Timing API
|
||||
|
@ -28,3 +28,14 @@ partial interface Performance {
|
||||
PerformanceEntryList getEntriesByName(DOMString name,
|
||||
optional DOMString type);
|
||||
};
|
||||
|
||||
// https://w3c.github.io/user-timing/#extensions-performance-interface
|
||||
[Exposed=(Window,Worker)]
|
||||
partial interface Performance {
|
||||
[Throws]
|
||||
void mark(DOMString markName);
|
||||
void clearMarks(optional DOMString markName);
|
||||
[Throws]
|
||||
void measure(DOMString measureName, optional DOMString startMark, optional DOMString endMark);
|
||||
void clearMeasures(optional DOMString measureName);
|
||||
};
|
||||
|
11
servo/components/script/dom/webidls/PerformanceMark.webidl
Normal file
11
servo/components/script/dom/webidls/PerformanceMark.webidl
Normal file
@ -0,0 +1,11 @@
|
||||
/* 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 http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://w3c.github.io/user-timing/#performancemark
|
||||
*/
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface PerformanceMark : PerformanceEntry {
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
/* 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 http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://w3c.github.io/user-timing/#performancemeasure
|
||||
*/
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface PerformanceMeasure : PerformanceEntry {
|
||||
};
|
Loading…
Reference in New Issue
Block a user