mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Auto merge of #18176 - rtbo:perf_observer_buffered, r=ferjm
PerformanceObserverInit.buffered Per #18108, add `buffered` flag in the `PerformanceObserverInit` dict. Per W3C spec, when `buffered` is set, `PerformanceObserver.observe()` method adds the entries buffered in the `Performance` instance into the observer's entry buffer. One step is the implementation of the [filter by name and type](https://w3c.github.io/performance-timeline/#filter-buffer-by-name-and-type) algorithm. Don't think that the sort operation is useful in this case, but the spec states that this algorithm is to be used. - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #18108 - [X] These changes do not require tests (yet) because the timeline API is not powered. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18176) <!-- Reviewable:end -->
This commit is contained in:
commit
ced303b9cb
4 changed files with 35 additions and 2 deletions
|
@ -18,6 +18,7 @@ use dom::window::Window;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use script_thread::{Runnable, ScriptThread};
|
use script_thread::{Runnable, ScriptThread};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use time;
|
use time;
|
||||||
|
|
||||||
/// Implementation of a list of PerformanceEntry items shared by the
|
/// Implementation of a list of PerformanceEntry items shared by the
|
||||||
|
@ -51,6 +52,16 @@ impl PerformanceEntryList {
|
||||||
entry_type.as_ref().map_or(true, |type_| *e.entry_type() == *type_)
|
entry_type.as_ref().map_or(true, |type_| *e.entry_type() == *type_)
|
||||||
).map(|e| e.clone()).collect()
|
).map(|e| e.clone()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_entries_by_name_and_type(&self, name: Option<DOMString>, entry_type: Option<DOMString>)
|
||||||
|
-> Vec<Root<PerformanceEntry>> {
|
||||||
|
let mut res = self.entries.iter().filter(|e|
|
||||||
|
name.as_ref().map_or(true, |name_| *e.name() == *name_) &&
|
||||||
|
entry_type.as_ref().map_or(true, |type_| *e.entry_type() == *type_)
|
||||||
|
).map(|e| e.clone()).collect::<Vec<Root<PerformanceEntry>>>();
|
||||||
|
res.sort_by(|a, b| a.start_time().partial_cmp(&b.start_time()).unwrap_or(Ordering::Equal));
|
||||||
|
res
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoIterator for PerformanceEntryList {
|
impl IntoIterator for PerformanceEntryList {
|
||||||
|
@ -106,7 +117,17 @@ impl Performance {
|
||||||
/// observed entry types.
|
/// observed entry types.
|
||||||
pub fn add_observer(&self,
|
pub fn add_observer(&self,
|
||||||
observer: &DOMPerformanceObserver,
|
observer: &DOMPerformanceObserver,
|
||||||
entry_types: Vec<DOMString>) {
|
entry_types: Vec<DOMString>,
|
||||||
|
buffered: bool) {
|
||||||
|
if buffered {
|
||||||
|
let entries = self.entries.borrow();
|
||||||
|
let mut new_entries = entry_types.iter()
|
||||||
|
.flat_map(|e| entries.get_entries_by_name_and_type(None, Some(e.clone())))
|
||||||
|
.collect::<DOMPerformanceEntryList>();
|
||||||
|
let mut obs_entries = observer.entries();
|
||||||
|
obs_entries.append(&mut new_entries);
|
||||||
|
observer.set_entries(obs_entries);
|
||||||
|
}
|
||||||
let mut observers = self.observers.borrow_mut();
|
let mut observers = self.observers.borrow_mut();
|
||||||
match observers.iter().position(|o| &(*o.observer) == observer) {
|
match observers.iter().position(|o| &(*o.observer) == observer) {
|
||||||
// If the observer is already in the list, we only update the observed
|
// If the observer is already in the list, we only update the observed
|
||||||
|
|
|
@ -51,6 +51,10 @@ impl PerformanceEntry {
|
||||||
pub fn name(&self) -> &DOMString {
|
pub fn name(&self) -> &DOMString {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn start_time(&self) -> f64 {
|
||||||
|
self.start_time
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PerformanceEntryMethods for PerformanceEntry {
|
impl PerformanceEntryMethods for PerformanceEntry {
|
||||||
|
|
|
@ -89,23 +89,30 @@ impl PerformanceObserver {
|
||||||
pub fn entries(&self) -> DOMPerformanceEntryList {
|
pub fn entries(&self) -> DOMPerformanceEntryList {
|
||||||
self.entries.borrow().clone()
|
self.entries.borrow().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_entries(&self, entries: DOMPerformanceEntryList) {
|
||||||
|
*self.entries.borrow_mut() = entries;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PerformanceObserverMethods for PerformanceObserver {
|
impl PerformanceObserverMethods for PerformanceObserver {
|
||||||
// https://w3c.github.io/performance-timeline/#dom-performanceobserver-observe()
|
// https://w3c.github.io/performance-timeline/#dom-performanceobserver-observe()
|
||||||
fn Observe(&self, options: &PerformanceObserverInit) -> Fallible<()> {
|
fn Observe(&self, options: &PerformanceObserverInit) -> Fallible<()> {
|
||||||
|
// step 1
|
||||||
// Make sure the client is asking to observe events from allowed entry types.
|
// Make sure the client is asking to observe events from allowed entry types.
|
||||||
let entry_types = options.entryTypes.iter()
|
let entry_types = options.entryTypes.iter()
|
||||||
.filter(|e| VALID_ENTRY_TYPES.contains(&e.as_ref()))
|
.filter(|e| VALID_ENTRY_TYPES.contains(&e.as_ref()))
|
||||||
.map(|e| e.clone())
|
.map(|e| e.clone())
|
||||||
.collect::<Vec<DOMString>>();
|
.collect::<Vec<DOMString>>();
|
||||||
|
// step 2
|
||||||
// There must be at least one valid entry type.
|
// There must be at least one valid entry type.
|
||||||
if entry_types.is_empty() {
|
if entry_types.is_empty() {
|
||||||
return Err((Error::Type("entryTypes cannot be empty".to_string())));
|
return Err((Error::Type("entryTypes cannot be empty".to_string())));
|
||||||
}
|
}
|
||||||
|
|
||||||
let performance = self.global().as_window().Performance();
|
let performance = self.global().as_window().Performance();
|
||||||
performance.add_observer(self, entry_types);
|
// step 3-4-5
|
||||||
|
performance.add_observer(self, entry_types, options.buffered);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
dictionary PerformanceObserverInit {
|
dictionary PerformanceObserverInit {
|
||||||
required sequence<DOMString> entryTypes;
|
required sequence<DOMString> entryTypes;
|
||||||
|
boolean buffered = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
callback PerformanceObserverCallback = void (PerformanceObserverEntryList entries, PerformanceObserver observer);
|
callback PerformanceObserverCallback = void (PerformanceObserverEntryList entries, PerformanceObserver observer);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue