mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Merge 0a91273a97
into 8d086b9fe5
This commit is contained in:
commit
80bf6cddd8
7 changed files with 340 additions and 27 deletions
|
@ -1086,6 +1086,11 @@ impl Document {
|
|||
|
||||
// https://html.spec.whatwg.org/multipage/#current-document-readiness
|
||||
pub(crate) fn set_ready_state(&self, state: DocumentReadyState, can_gc: CanGc) {
|
||||
let window = self.window();
|
||||
let performance = window.Performance();
|
||||
let now = (*performance.Now()).floor() as u64;
|
||||
let timing = performance.Timing();
|
||||
|
||||
match state {
|
||||
DocumentReadyState::Loading => {
|
||||
if self.window().is_top_level() {
|
||||
|
@ -1095,6 +1100,11 @@ impl Document {
|
|||
));
|
||||
self.send_to_embedder(EmbedderMsg::Status(self.webview_id(), None));
|
||||
}
|
||||
timing.update_dom_loading(now);
|
||||
},
|
||||
DocumentReadyState::Interactive => {
|
||||
update_with_current_instant(&self.dom_interactive);
|
||||
timing.update_dom_interactive(now);
|
||||
},
|
||||
DocumentReadyState::Complete => {
|
||||
if self.window().is_top_level() {
|
||||
|
@ -1104,8 +1114,8 @@ impl Document {
|
|||
));
|
||||
}
|
||||
update_with_current_instant(&self.dom_complete);
|
||||
timing.update_dom_complete(now);
|
||||
},
|
||||
DocumentReadyState::Interactive => update_with_current_instant(&self.dom_interactive),
|
||||
};
|
||||
|
||||
self.ready_state.set(state);
|
||||
|
@ -2987,6 +2997,10 @@ impl Document {
|
|||
if document.browsing_context().is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let performance = window.Performance();
|
||||
let timing = performance.Timing();
|
||||
|
||||
let event = Event::new(
|
||||
window.upcast(),
|
||||
atom!("load"),
|
||||
|
@ -2996,12 +3010,16 @@ impl Document {
|
|||
);
|
||||
event.set_trusted(true);
|
||||
|
||||
let start_time = (*performance.Now()).floor() as u64;
|
||||
timing.update_load_event_start(start_time);
|
||||
|
||||
// http://w3c.github.io/navigation-timing/#widl-PerformanceNavigationTiming-loadEventStart
|
||||
update_with_current_instant(&document.load_event_start);
|
||||
|
||||
debug!("About to dispatch load for {:?}", document.url());
|
||||
window.dispatch_event_with_target_override(&event, CanGc::note());
|
||||
|
||||
timing.update_load_event_end((*performance.Now()).floor() as u64);
|
||||
// http://w3c.github.io/navigation-timing/#widl-PerformanceNavigationTiming-loadEventEnd
|
||||
update_with_current_instant(&document.load_event_end);
|
||||
|
||||
|
@ -3243,20 +3261,25 @@ impl Document {
|
|||
"Complete before DOMContentLoaded?"
|
||||
);
|
||||
|
||||
update_with_current_instant(&self.dom_content_loaded_event_start);
|
||||
|
||||
// Step 4.1.
|
||||
let document = Trusted::new(self);
|
||||
self.owner_global()
|
||||
.task_manager()
|
||||
.dom_manipulation_task_source()
|
||||
.queue(
|
||||
task!(fire_dom_content_loaded_event: move || {
|
||||
let document = document.root();
|
||||
document.upcast::<EventTarget>().fire_bubbling_event(atom!("DOMContentLoaded"), CanGc::note());
|
||||
update_with_current_instant(&document.dom_content_loaded_event_end);
|
||||
})
|
||||
);
|
||||
.queue(task!(fire_dom_content_loaded_event: move || {
|
||||
let document = document.root();
|
||||
|
||||
let window = document.window();
|
||||
let performance = window.Performance();
|
||||
let timing = performance.Timing();
|
||||
|
||||
update_with_current_instant(&document.dom_content_loaded_event_start);
|
||||
timing.update_dom_content_loaded_event_start((*performance.Now()).floor() as u64);
|
||||
document.upcast::<EventTarget>().fire_bubbling_event(atom!("DOMContentLoaded"), CanGc::note());
|
||||
timing.update_dom_content_loaded_event_end((*performance.Now()).floor() as u64);
|
||||
|
||||
update_with_current_instant(&document.dom_content_loaded_event_end);
|
||||
}));
|
||||
|
||||
// html parsing has finished - set dom content loaded
|
||||
self.interactive_time
|
||||
|
|
|
@ -484,6 +484,7 @@ pub(crate) mod performanceobserver;
|
|||
pub(crate) mod performanceobserverentrylist;
|
||||
pub(crate) mod performancepainttiming;
|
||||
pub(crate) mod performanceresourcetiming;
|
||||
pub(crate) mod performancetiming;
|
||||
pub(crate) mod permissions;
|
||||
pub(crate) mod permissionstatus;
|
||||
pub(crate) mod plugin;
|
||||
|
|
|
@ -19,7 +19,7 @@ use crate::dom::bindings::error::{Error, Fallible};
|
|||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::num::Finite;
|
||||
use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
|
@ -27,8 +27,8 @@ use crate::dom::performanceentry::PerformanceEntry;
|
|||
use crate::dom::performancemark::PerformanceMark;
|
||||
use crate::dom::performancemeasure::PerformanceMeasure;
|
||||
use crate::dom::performancenavigation::PerformanceNavigation;
|
||||
use crate::dom::performancenavigationtiming::PerformanceNavigationTiming;
|
||||
use crate::dom::performanceobserver::PerformanceObserver as DOMPerformanceObserver;
|
||||
use crate::dom::performancetiming::PerformanceTiming;
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
|
@ -148,10 +148,23 @@ pub(crate) struct Performance {
|
|||
resource_timing_buffer_current_size: Cell<usize>,
|
||||
resource_timing_buffer_pending_full_event: Cell<bool>,
|
||||
resource_timing_secondary_entries: DomRefCell<VecDeque<DomRoot<PerformanceEntry>>>,
|
||||
timing: Dom<PerformanceTiming>,
|
||||
navigation: Dom<PerformanceNavigation>,
|
||||
}
|
||||
|
||||
impl Performance {
|
||||
fn new_inherited(time_origin: CrossProcessInstant) -> Performance {
|
||||
fn time_origin_to_millis(time_origin: CrossProcessInstant) -> u64 {
|
||||
(time_origin - CrossProcessInstant::epoch()).whole_milliseconds() as u64
|
||||
}
|
||||
|
||||
fn new_inherited(
|
||||
global: &GlobalScope,
|
||||
time_origin: CrossProcessInstant,
|
||||
can_gc: CanGc,
|
||||
) -> Performance {
|
||||
let nav_start = Self::time_origin_to_millis(time_origin);
|
||||
let timing = PerformanceTiming::new(global, nav_start, can_gc);
|
||||
let navigation = PerformanceNavigation::new(global, can_gc);
|
||||
Performance {
|
||||
eventtarget: EventTarget::new_inherited(),
|
||||
buffer: DomRefCell::new(PerformanceEntryList::new(Vec::new())),
|
||||
|
@ -162,6 +175,8 @@ impl Performance {
|
|||
resource_timing_buffer_current_size: Cell::new(0),
|
||||
resource_timing_buffer_pending_full_event: Cell::new(false),
|
||||
resource_timing_secondary_entries: DomRefCell::new(VecDeque::new()),
|
||||
timing: Dom::from_ref(&*timing),
|
||||
navigation: Dom::from_ref(&*navigation),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,7 +186,7 @@ impl Performance {
|
|||
can_gc: CanGc,
|
||||
) -> DomRoot<Performance> {
|
||||
reflect_dom_object(
|
||||
Box::new(Performance::new_inherited(navigation_start)),
|
||||
Box::new(Performance::new_inherited(global, navigation_start, can_gc)),
|
||||
global,
|
||||
can_gc,
|
||||
)
|
||||
|
@ -433,21 +448,13 @@ impl Performance {
|
|||
impl PerformanceMethods<crate::DomTypeHolder> for Performance {
|
||||
// FIXME(avada): this should be deprecated in the future, but some sites still use it
|
||||
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html#performance-timing-attribute
|
||||
fn Timing(&self) -> DomRoot<PerformanceNavigationTiming> {
|
||||
let entries = self.GetEntriesByType(DOMString::from("navigation"));
|
||||
if !entries.is_empty() {
|
||||
return DomRoot::from_ref(
|
||||
entries[0]
|
||||
.downcast::<PerformanceNavigationTiming>()
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
unreachable!("Are we trying to expose Performance.timing in workers?");
|
||||
fn Timing(&self) -> DomRoot<PerformanceTiming> {
|
||||
DomRoot::from_ref(&*self.timing)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performance-navigation
|
||||
fn Navigation(&self) -> DomRoot<PerformanceNavigation> {
|
||||
PerformanceNavigation::new(&self.global(), CanGc::note())
|
||||
DomRoot::from_ref(&*self.navigation)
|
||||
}
|
||||
|
||||
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HighResolutionTime/Overview.html#dom-performance-now
|
||||
|
|
253
components/script/dom/performancetiming.rs
Normal file
253
components/script/dom/performancetiming.rs
Normal file
|
@ -0,0 +1,253 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::PerformanceTimingBinding::PerformanceTimingMethods;
|
||||
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
#[dom_struct]
|
||||
pub(crate) struct PerformanceTiming {
|
||||
reflector_: Reflector,
|
||||
navigation_start: Cell<u64>,
|
||||
unload_event_start: Cell<u64>,
|
||||
unload_event_end: Cell<u64>,
|
||||
redirect_start: Cell<u64>,
|
||||
redirect_end: Cell<u64>,
|
||||
fetch_start: Cell<u64>,
|
||||
domain_lookup_start: Cell<u64>,
|
||||
domain_lookup_end: Cell<u64>,
|
||||
connect_start: Cell<u64>,
|
||||
connect_end: Cell<u64>,
|
||||
secure_connection_start: Cell<u64>,
|
||||
request_start: Cell<u64>,
|
||||
response_start: Cell<u64>,
|
||||
response_end: Cell<u64>,
|
||||
dom_loading: Cell<u64>,
|
||||
dom_interactive: Cell<u64>,
|
||||
dom_content_loaded_event_start: Cell<u64>,
|
||||
dom_content_loaded_event_end: Cell<u64>,
|
||||
dom_complete: Cell<u64>,
|
||||
load_event_start: Cell<u64>,
|
||||
load_event_end: Cell<u64>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl PerformanceTiming {
|
||||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
navigation_start: u64,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<PerformanceTiming> {
|
||||
reflect_dom_object(
|
||||
Box::new(PerformanceTiming {
|
||||
reflector_: Reflector::new(),
|
||||
navigation_start: Cell::new(navigation_start),
|
||||
unload_event_start: Cell::new(0),
|
||||
unload_event_end: Cell::new(0),
|
||||
redirect_start: Cell::new(0),
|
||||
redirect_end: Cell::new(0),
|
||||
fetch_start: Cell::new(0),
|
||||
domain_lookup_start: Cell::new(0),
|
||||
domain_lookup_end: Cell::new(0),
|
||||
connect_start: Cell::new(0),
|
||||
connect_end: Cell::new(0),
|
||||
secure_connection_start: Cell::new(0),
|
||||
request_start: Cell::new(0),
|
||||
response_start: Cell::new(0),
|
||||
response_end: Cell::new(0),
|
||||
dom_loading: Cell::new(0),
|
||||
dom_interactive: Cell::new(0),
|
||||
dom_content_loaded_event_start: Cell::new(0),
|
||||
dom_content_loaded_event_end: Cell::new(0),
|
||||
dom_complete: Cell::new(0),
|
||||
load_event_start: Cell::new(0),
|
||||
load_event_end: Cell::new(0),
|
||||
}),
|
||||
global,
|
||||
can_gc,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn update_unload_event_start(&self, value: u64) {
|
||||
self.unload_event_start.set(value);
|
||||
}
|
||||
|
||||
pub(crate) fn update_unload_event_end(&self, value: u64) {
|
||||
self.unload_event_end.set(value);
|
||||
}
|
||||
|
||||
pub(crate) fn update_redirect_start(&self, value: u64) {
|
||||
self.redirect_start.set(value);
|
||||
}
|
||||
|
||||
pub(crate) fn update_redirect_end(&self, value: u64) {
|
||||
self.redirect_end.set(value);
|
||||
}
|
||||
|
||||
pub(crate) fn update_fetch_start(&self, value: u64) {
|
||||
self.fetch_start.set(value);
|
||||
}
|
||||
|
||||
pub(crate) fn update_domain_lookup_start(&self, value: u64) {
|
||||
self.domain_lookup_start.set(value);
|
||||
}
|
||||
|
||||
pub(crate) fn update_domain_lookup_end(&self, value: u64) {
|
||||
self.domain_lookup_end.set(value);
|
||||
}
|
||||
|
||||
pub(crate) fn update_connect_start(&self, value: u64) {
|
||||
self.connect_start.set(value);
|
||||
}
|
||||
|
||||
pub(crate) fn update_connect_end(&self, value: u64) {
|
||||
self.connect_end.set(value);
|
||||
}
|
||||
pub(crate) fn update_secure_connection_start(&self, value: u64) {
|
||||
self.secure_connection_start.set(value);
|
||||
}
|
||||
pub(crate) fn update_request_start(&self, value: u64) {
|
||||
self.request_start.set(value);
|
||||
}
|
||||
pub(crate) fn update_response_start(&self, value: u64) {
|
||||
self.response_start.set(value);
|
||||
}
|
||||
pub(crate) fn update_response_end(&self, value: u64) {
|
||||
self.response_end.set(value);
|
||||
}
|
||||
pub(crate) fn update_dom_loading(&self, value: u64) {
|
||||
self.dom_loading.set(value);
|
||||
}
|
||||
pub(crate) fn update_dom_interactive(&self, value: u64) {
|
||||
self.dom_interactive.set(value);
|
||||
}
|
||||
pub(crate) fn update_dom_content_loaded_event_start(&self, value: u64) {
|
||||
self.dom_content_loaded_event_start.set(value);
|
||||
}
|
||||
pub(crate) fn update_dom_content_loaded_event_end(&self, value: u64) {
|
||||
self.dom_content_loaded_event_end.set(value);
|
||||
}
|
||||
pub(crate) fn update_dom_complete(&self, value: u64) {
|
||||
self.dom_complete.set(value);
|
||||
}
|
||||
pub(crate) fn update_load_event_start(&self, value: u64) {
|
||||
self.load_event_start.set(value);
|
||||
}
|
||||
pub(crate) fn update_load_event_end(&self, value: u64) {
|
||||
self.load_event_end.set(value);
|
||||
}
|
||||
}
|
||||
|
||||
impl PerformanceTimingMethods<crate::DomTypeHolder> for PerformanceTiming {
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-navigationstart
|
||||
fn NavigationStart(&self) -> u64 {
|
||||
self.navigation_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-unloadeventstart
|
||||
fn UnloadEventStart(&self) -> u64 {
|
||||
self.unload_event_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-unloadeventend
|
||||
fn UnloadEventEnd(&self) -> u64 {
|
||||
self.unload_event_end.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-redirectstart
|
||||
fn RedirectStart(&self) -> u64 {
|
||||
self.redirect_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-redirectend
|
||||
fn RedirectEnd(&self) -> u64 {
|
||||
self.redirect_end.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-fetchstart
|
||||
fn FetchStart(&self) -> u64 {
|
||||
self.fetch_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-domainlookupstart
|
||||
fn DomainLookupStart(&self) -> u64 {
|
||||
self.domain_lookup_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-domainlookupend
|
||||
fn DomainLookupEnd(&self) -> u64 {
|
||||
self.domain_lookup_end.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-connectstart
|
||||
fn ConnectStart(&self) -> u64 {
|
||||
self.connect_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-connectend
|
||||
fn ConnectEnd(&self) -> u64 {
|
||||
self.connect_end.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing#dom-performancetiming-secureconnectionstart
|
||||
fn SecureConnectionStart(&self) -> u64 {
|
||||
self.secure_connection_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-requeststart
|
||||
fn RequestStart(&self) -> u64 {
|
||||
self.request_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-responsestart
|
||||
fn ResponseStart(&self) -> u64 {
|
||||
self.response_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-responseend
|
||||
fn ResponseEnd(&self) -> u64 {
|
||||
self.response_end.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-domloading
|
||||
fn DomLoading(&self) -> u64 {
|
||||
self.dom_loading.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-dominteractive
|
||||
fn DomInteractive(&self) -> u64 {
|
||||
self.dom_interactive.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-domcontentloadedeventstart
|
||||
fn DomContentLoadedEventStart(&self) -> u64 {
|
||||
self.dom_content_loaded_event_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-domcontentloadedeventend
|
||||
fn DomContentLoadedEventEnd(&self) -> u64 {
|
||||
self.dom_content_loaded_event_end.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-domcomplete
|
||||
fn DomComplete(&self) -> u64 {
|
||||
self.dom_complete.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-loadeventstart
|
||||
fn LoadEventStart(&self) -> u64 {
|
||||
self.load_event_start.get()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#dom-performancetiming-loadeventend
|
||||
fn LoadEventEnd(&self) -> u64 {
|
||||
self.load_event_end.get()
|
||||
}
|
||||
}
|
|
@ -185,7 +185,6 @@ impl WindowProxy {
|
|||
assert!(!js_proxy.is_null());
|
||||
|
||||
// Create a new browsing context.
|
||||
|
||||
let current = Some(window.upcast::<GlobalScope>().pipeline_id());
|
||||
let window_proxy = Box::new(WindowProxy::new_inherited(
|
||||
browsing_context_id,
|
||||
|
|
|
@ -47,7 +47,7 @@ partial interface Performance {
|
|||
[Exposed=Window]
|
||||
partial interface Performance {
|
||||
[SameObject]
|
||||
readonly attribute PerformanceNavigationTiming timing;
|
||||
readonly attribute PerformanceTiming timing;
|
||||
[SameObject]
|
||||
readonly attribute PerformanceNavigation navigation;
|
||||
};
|
||||
|
|
30
components/script_bindings/webidls/PerformanceTiming.webidl
Normal file
30
components/script_bindings/webidls/PerformanceTiming.webidl
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// https://w3c.github.io/navigation-timing/#the-performancetiming-interface
|
||||
|
||||
[Exposed=Window]
|
||||
interface PerformanceTiming {
|
||||
readonly attribute unsigned long long navigationStart;
|
||||
readonly attribute unsigned long long unloadEventStart;
|
||||
readonly attribute unsigned long long unloadEventEnd;
|
||||
readonly attribute unsigned long long redirectStart;
|
||||
readonly attribute unsigned long long redirectEnd;
|
||||
readonly attribute unsigned long long fetchStart;
|
||||
readonly attribute unsigned long long domainLookupStart;
|
||||
readonly attribute unsigned long long domainLookupEnd;
|
||||
readonly attribute unsigned long long connectStart;
|
||||
readonly attribute unsigned long long connectEnd;
|
||||
readonly attribute unsigned long long secureConnectionStart;
|
||||
readonly attribute unsigned long long requestStart;
|
||||
readonly attribute unsigned long long responseStart;
|
||||
readonly attribute unsigned long long responseEnd;
|
||||
readonly attribute unsigned long long domLoading;
|
||||
readonly attribute unsigned long long domInteractive;
|
||||
readonly attribute unsigned long long domContentLoadedEventStart;
|
||||
readonly attribute unsigned long long domContentLoadedEventEnd;
|
||||
readonly attribute unsigned long long domComplete;
|
||||
readonly attribute unsigned long long loadEventStart;
|
||||
readonly attribute unsigned long long loadEventEnd;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue