From 58f1a6e72177b93f53f9c0d2badc8f3520c9567a Mon Sep 17 00:00:00 2001 From: aniebietafia Date: Thu, 27 Mar 2025 13:58:19 +0100 Subject: [PATCH 1/3] Replace some uses of window.global() with upcast. Signed-off-by: aniebietafia --- components/script/dom/windowproxy.rs | 2 +- components/script/script_thread.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index acd96b4e55a..d008c76f905 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -184,7 +184,7 @@ impl WindowProxy { assert!(!js_proxy.is_null()); // Create a new browsing context. - let current = Some(window.global().pipeline_id()); + let current = Some(window.upcast::().pipeline_id()); let window_proxy = Box::new(WindowProxy::new_inherited( browsing_context_id, webview_id, diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 2e934217815..39cf325a079 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -2530,7 +2530,7 @@ impl ScriptThread { // FIXME: synchronously talks to constellation. // send the required info as part of postmessage instead. let source = match self.remote_window_proxy( - &window.global(), + window.upcast::(), source_browsing_context, source_pipeline_id, None, From 732f66aefb4c7dc2b94998fa4ac0878db4d2bacd Mon Sep 17 00:00:00 2001 From: aniebietafia Date: Thu, 10 Apr 2025 12:06:42 +0100 Subject: [PATCH 2/3] Performance.timing should be a PerformanceTiming object. Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object Signed-off-by: aniebietafia --- components/script/dom/document.rs | 51 +++- components/script/dom/mod.rs | 1 + components/script/dom/performance.rs | 33 +- components/script/dom/performancetiming.rs | 282 ++++++++++++++++++ .../webidls/Performance.webidl | 2 +- .../webidls/PerformanceTiming.webidl | 30 ++ 6 files changed, 374 insertions(+), 25 deletions(-) create mode 100644 components/script/dom/performancetiming.rs create mode 100644 components/script_bindings/webidls/PerformanceTiming.webidl diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 339220d3d64..dc1a3eb50d3 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1059,6 +1059,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() { @@ -1068,6 +1073,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() { @@ -1077,8 +1087,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); @@ -2746,6 +2756,11 @@ impl Document { if document.browsing_context().is_none() { return; } + + let performance = window.Performance(); + let timing = performance.Timing(); + let start_time = (*performance.Now()).floor() as u64; + let event = Event::new( window.upcast(), atom!("load"), @@ -2755,6 +2770,10 @@ impl Document { ); event.set_trusted(true); + timing.update_load_event_start(start_time); + window.upcast::().dispatch_event(&event, CanGc::note()); + timing.update_load_event_end((*performance.Now()).floor() as u64); + // http://w3c.github.io/navigation-timing/#widl-PerformanceNavigationTiming-loadEventStart update_with_current_instant(&document.load_event_start); @@ -2997,20 +3016,34 @@ 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::().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(); + let start_time = (*performance.Now()).floor() as u64; + + let event = Event::new( + window.upcast(), + atom!("DOMContentLoaded"), + EventBubbles::Bubbles, + EventCancelable::NotCancelable, + CanGc::note(), ); + event.set_trusted(true); + + timing.update_dom_content_loaded_event_start(start_time); + window.upcast::().dispatch_event(&event, 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 diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 4581ea56135..fbf35b28479 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -479,6 +479,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; diff --git a/components/script/dom/performance.rs b/components/script/dom/performance.rs index 7d4021ea801..8a66c79d23e 100644 --- a/components/script/dom/performance.rs +++ b/components/script/dom/performance.rs @@ -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,19 @@ pub(crate) struct Performance { resource_timing_buffer_current_size: Cell, resource_timing_buffer_pending_full_event: Cell, resource_timing_secondary_entries: DomRefCell>>, + timing: Dom, + navigation: Dom, } 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) -> Performance { + let nav_start = Self::time_origin_to_millis(time_origin); + let timing = PerformanceTiming::new(global, nav_start); + let navigation = PerformanceNavigation::new(global, CanGc::note()); Performance { eventtarget: EventTarget::new_inherited(), buffer: DomRefCell::new(PerformanceEntryList::new(Vec::new())), @@ -162,6 +171,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 +182,7 @@ impl Performance { can_gc: CanGc, ) -> DomRoot { reflect_dom_object( - Box::new(Performance::new_inherited(navigation_start)), + Box::new(Performance::new_inherited(global, navigation_start)), global, can_gc, ) @@ -433,21 +444,13 @@ impl Performance { impl PerformanceMethods 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 { - let entries = self.GetEntriesByType(DOMString::from("navigation")); - if !entries.is_empty() { - return DomRoot::from_ref( - entries[0] - .downcast::() - .unwrap(), - ); - } - unreachable!("Are we trying to expose Performance.timing in workers?"); + fn Timing(&self) -> DomRoot { + DomRoot::from_ref(&*self.timing) } // https://w3c.github.io/navigation-timing/#dom-performance-navigation fn Navigation(&self) -> DomRoot { - 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 diff --git a/components/script/dom/performancetiming.rs b/components/script/dom/performancetiming.rs new file mode 100644 index 00000000000..3fe7b59b971 --- /dev/null +++ b/components/script/dom/performancetiming.rs @@ -0,0 +1,282 @@ +/* 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 struct PerformanceTiming { + reflector_: Reflector, + navigation_start: Cell, + unload_event_start: Cell, + unload_event_end: Cell, + redirect_start: Cell, + redirect_end: Cell, + fetch_start: Cell, + domain_lookup_start: Cell, + domain_lookup_end: Cell, + connect_start: Cell, + connect_end: Cell, + secure_connection_start: Cell, + request_start: Cell, + response_start: Cell, + response_end: Cell, + dom_loading: Cell, + dom_interactive: Cell, + dom_content_loaded_event_start: Cell, + dom_content_loaded_event_end: Cell, + dom_complete: Cell, + load_event_start: Cell, + load_event_end: Cell, +} + +#[derive(Default)] +pub struct PerformanceTimingBuilder { + navigation_start: u64, + unload_event_start: u64, + unload_event_end: u64, + redirect_start: u64, + redirect_end: u64, + fetch_start: u64, + domain_lookup_start: u64, + domain_lookup_end: u64, + connect_start: u64, + connect_end: u64, + secure_connection_start: u64, + request_start: u64, + response_start: u64, + response_end: u64, + dom_loading: u64, + dom_interactive: u64, + dom_content_loaded_event_start: u64, + dom_content_loaded_event_end: u64, + dom_complete: u64, + load_event_start: u64, + load_event_end: u64, +} + +#[allow(dead_code)] +impl PerformanceTiming { + pub fn new_inherited(config: PerformanceTimingBuilder) -> PerformanceTiming { + PerformanceTiming { + reflector_: Reflector::new(), + navigation_start: Cell::new(config.navigation_start), + unload_event_start: Cell::new(config.unload_event_start), + unload_event_end: Cell::new(config.unload_event_end), + redirect_start: Cell::new(config.redirect_start), + redirect_end: Cell::new(config.redirect_end), + fetch_start: Cell::new(config.fetch_start), + domain_lookup_start: Cell::new(config.domain_lookup_start), + domain_lookup_end: Cell::new(config.domain_lookup_end), + connect_start: Cell::new(config.connect_start), + connect_end: Cell::new(config.connect_end), + secure_connection_start: Cell::new(config.secure_connection_start), + request_start: Cell::new(config.request_start), + response_start: Cell::new(config.response_start), + response_end: Cell::new(config.response_end), + dom_loading: Cell::new(config.dom_loading), + dom_interactive: Cell::new(config.dom_interactive), + dom_content_loaded_event_start: Cell::new(config.dom_content_loaded_event_start), + dom_content_loaded_event_end: Cell::new(config.dom_content_loaded_event_end), + dom_complete: Cell::new(config.dom_complete), + load_event_start: Cell::new(config.load_event_start), + load_event_end: Cell::new(config.load_event_end), + } + } + + pub fn new(global: &GlobalScope, navigation_start: u64) -> DomRoot { + let config = PerformanceTimingBuilder { + navigation_start, + ..Default::default() + }; + reflect_dom_object( + Box::new(PerformanceTiming::new_inherited(config)), + global, + CanGc::note(), + ) + } + + pub fn update_unload_event_start(&self, value: u64) { + self.unload_event_start.set(value); + } + + pub fn update_unload_event_end(&self, value: u64) { + self.unload_event_end.set(value); + } + + pub fn update_redirect_start(&self, value: u64) { + self.redirect_start.set(value); + } + + pub fn update_redirect_end(&self, value: u64) { + self.redirect_end.set(value); + } + + pub fn update_fetch_start(&self, value: u64) { + self.fetch_start.set(value); + } + + pub fn update_domain_lookup_start(&self, value: u64) { + self.domain_lookup_start.set(value); + } + + pub fn update_domain_lookup_end(&self, value: u64) { + self.domain_lookup_end.set(value); + } + + pub fn update_connect_start(&self, value: u64) { + self.connect_start.set(value); + } + + pub fn update_connect_end(&self, value: u64) { + self.connect_end.set(value); + } + pub fn update_secure_connection_start(&self, value: u64) { + self.secure_connection_start.set(value); + } + pub fn update_request_start(&self, value: u64) { + self.request_start.set(value); + } + pub fn update_response_start(&self, value: u64) { + self.response_start.set(value); + } + pub fn update_response_end(&self, value: u64) { + self.response_end.set(value); + } + pub fn update_dom_loading(&self, value: u64) { + self.dom_loading.set(value); + } + pub fn update_dom_interactive(&self, value: u64) { + self.dom_interactive.set(value); + } + pub fn update_dom_content_loaded_event_start(&self, value: u64) { + self.dom_content_loaded_event_start.set(value); + } + pub fn update_dom_content_loaded_event_end(&self, value: u64) { + self.dom_content_loaded_event_end.set(value); + } + pub fn update_dom_complete(&self, value: u64) { + self.dom_complete.set(value); + } + pub fn update_load_event_start(&self, value: u64) { + self.load_event_start.set(value); + } + pub fn update_load_event_end(&self, value: u64) { + self.load_event_end.set(value); + } +} + +impl PerformanceTimingMethods 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() + } +} diff --git a/components/script_bindings/webidls/Performance.webidl b/components/script_bindings/webidls/Performance.webidl index 46f751cb4ab..98574ac0078 100644 --- a/components/script_bindings/webidls/Performance.webidl +++ b/components/script_bindings/webidls/Performance.webidl @@ -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; }; diff --git a/components/script_bindings/webidls/PerformanceTiming.webidl b/components/script_bindings/webidls/PerformanceTiming.webidl new file mode 100644 index 00000000000..bc9fb0134b1 --- /dev/null +++ b/components/script_bindings/webidls/PerformanceTiming.webidl @@ -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; +}; From c52a45323ff8daf9a90e5414c39cb000861a2192 Mon Sep 17 00:00:00 2001 From: aniebietafia Date: Tue, 6 May 2025 16:56:18 +0100 Subject: [PATCH 3/3] Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object. Signed-off-by: aniebietafia Performance.timing should be a PerformanceTiming object Signed-off-by: aniebietafia --- components/script/dom/document.rs | 20 +--- components/script/dom/performance.rs | 12 +- components/script/dom/performancetiming.rs | 131 ++++++++------------- 3 files changed, 64 insertions(+), 99 deletions(-) diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index dc1a3eb50d3..44ffded1100 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -2759,7 +2759,6 @@ impl Document { let performance = window.Performance(); let timing = performance.Timing(); - let start_time = (*performance.Now()).floor() as u64; let event = Event::new( window.upcast(), @@ -2770,9 +2769,8 @@ impl Document { ); event.set_trusted(true); + let start_time = (*performance.Now()).floor() as u64; timing.update_load_event_start(start_time); - window.upcast::().dispatch_event(&event, CanGc::note()); - timing.update_load_event_end((*performance.Now()).floor() as u64); // http://w3c.github.io/navigation-timing/#widl-PerformanceNavigationTiming-loadEventStart update_with_current_instant(&document.load_event_start); @@ -2780,6 +2778,7 @@ impl Document { 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); @@ -3027,19 +3026,10 @@ impl Document { let window = document.window(); let performance = window.Performance(); let timing = performance.Timing(); - let start_time = (*performance.Now()).floor() as u64; - let event = Event::new( - window.upcast(), - atom!("DOMContentLoaded"), - EventBubbles::Bubbles, - EventCancelable::NotCancelable, - CanGc::note(), - ); - event.set_trusted(true); - - timing.update_dom_content_loaded_event_start(start_time); - window.upcast::().dispatch_event(&event, CanGc::note()); + update_with_current_instant(&document.dom_content_loaded_event_start); + timing.update_dom_content_loaded_event_start((*performance.Now()).floor() as u64); + document.upcast::().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); diff --git a/components/script/dom/performance.rs b/components/script/dom/performance.rs index 8a66c79d23e..322213b7196 100644 --- a/components/script/dom/performance.rs +++ b/components/script/dom/performance.rs @@ -157,10 +157,14 @@ impl Performance { (time_origin - CrossProcessInstant::epoch()).whole_milliseconds() as u64 } - fn new_inherited(global: &GlobalScope, time_origin: CrossProcessInstant) -> Performance { + 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); - let navigation = PerformanceNavigation::new(global, CanGc::note()); + 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())), @@ -182,7 +186,7 @@ impl Performance { can_gc: CanGc, ) -> DomRoot { reflect_dom_object( - Box::new(Performance::new_inherited(global, navigation_start)), + Box::new(Performance::new_inherited(global, navigation_start, can_gc)), global, can_gc, ) diff --git a/components/script/dom/performancetiming.rs b/components/script/dom/performancetiming.rs index 3fe7b59b971..4ef80ebde7d 100644 --- a/components/script/dom/performancetiming.rs +++ b/components/script/dom/performancetiming.rs @@ -13,7 +13,7 @@ use crate::dom::globalscope::GlobalScope; use crate::script_runtime::CanGc; #[dom_struct] -pub struct PerformanceTiming { +pub(crate) struct PerformanceTiming { reflector_: Reflector, navigation_start: Cell, unload_event_start: Cell, @@ -38,138 +38,109 @@ pub struct PerformanceTiming { load_event_end: Cell, } -#[derive(Default)] -pub struct PerformanceTimingBuilder { - navigation_start: u64, - unload_event_start: u64, - unload_event_end: u64, - redirect_start: u64, - redirect_end: u64, - fetch_start: u64, - domain_lookup_start: u64, - domain_lookup_end: u64, - connect_start: u64, - connect_end: u64, - secure_connection_start: u64, - request_start: u64, - response_start: u64, - response_end: u64, - dom_loading: u64, - dom_interactive: u64, - dom_content_loaded_event_start: u64, - dom_content_loaded_event_end: u64, - dom_complete: u64, - load_event_start: u64, - load_event_end: u64, -} - #[allow(dead_code)] impl PerformanceTiming { - pub fn new_inherited(config: PerformanceTimingBuilder) -> PerformanceTiming { - PerformanceTiming { - reflector_: Reflector::new(), - navigation_start: Cell::new(config.navigation_start), - unload_event_start: Cell::new(config.unload_event_start), - unload_event_end: Cell::new(config.unload_event_end), - redirect_start: Cell::new(config.redirect_start), - redirect_end: Cell::new(config.redirect_end), - fetch_start: Cell::new(config.fetch_start), - domain_lookup_start: Cell::new(config.domain_lookup_start), - domain_lookup_end: Cell::new(config.domain_lookup_end), - connect_start: Cell::new(config.connect_start), - connect_end: Cell::new(config.connect_end), - secure_connection_start: Cell::new(config.secure_connection_start), - request_start: Cell::new(config.request_start), - response_start: Cell::new(config.response_start), - response_end: Cell::new(config.response_end), - dom_loading: Cell::new(config.dom_loading), - dom_interactive: Cell::new(config.dom_interactive), - dom_content_loaded_event_start: Cell::new(config.dom_content_loaded_event_start), - dom_content_loaded_event_end: Cell::new(config.dom_content_loaded_event_end), - dom_complete: Cell::new(config.dom_complete), - load_event_start: Cell::new(config.load_event_start), - load_event_end: Cell::new(config.load_event_end), - } - } - - pub fn new(global: &GlobalScope, navigation_start: u64) -> DomRoot { - let config = PerformanceTimingBuilder { - navigation_start, - ..Default::default() - }; + pub fn new( + global: &GlobalScope, + navigation_start: u64, + can_gc: CanGc, + ) -> DomRoot { reflect_dom_object( - Box::new(PerformanceTiming::new_inherited(config)), + 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, - CanGc::note(), + can_gc, ) } - pub fn update_unload_event_start(&self, value: u64) { + pub(crate) fn update_unload_event_start(&self, value: u64) { self.unload_event_start.set(value); } - pub fn update_unload_event_end(&self, value: u64) { + pub(crate) fn update_unload_event_end(&self, value: u64) { self.unload_event_end.set(value); } - pub fn update_redirect_start(&self, value: u64) { + pub(crate) fn update_redirect_start(&self, value: u64) { self.redirect_start.set(value); } - pub fn update_redirect_end(&self, value: u64) { + pub(crate) fn update_redirect_end(&self, value: u64) { self.redirect_end.set(value); } - pub fn update_fetch_start(&self, value: u64) { + pub(crate) fn update_fetch_start(&self, value: u64) { self.fetch_start.set(value); } - pub fn update_domain_lookup_start(&self, value: u64) { + pub(crate) fn update_domain_lookup_start(&self, value: u64) { self.domain_lookup_start.set(value); } - pub fn update_domain_lookup_end(&self, value: u64) { + pub(crate) fn update_domain_lookup_end(&self, value: u64) { self.domain_lookup_end.set(value); } - pub fn update_connect_start(&self, value: u64) { + pub(crate) fn update_connect_start(&self, value: u64) { self.connect_start.set(value); } - pub fn update_connect_end(&self, value: u64) { + pub(crate) fn update_connect_end(&self, value: u64) { self.connect_end.set(value); } - pub fn update_secure_connection_start(&self, value: u64) { + pub(crate) fn update_secure_connection_start(&self, value: u64) { self.secure_connection_start.set(value); } - pub fn update_request_start(&self, value: u64) { + pub(crate) fn update_request_start(&self, value: u64) { self.request_start.set(value); } - pub fn update_response_start(&self, value: u64) { + pub(crate) fn update_response_start(&self, value: u64) { self.response_start.set(value); } - pub fn update_response_end(&self, value: u64) { + pub(crate) fn update_response_end(&self, value: u64) { self.response_end.set(value); } - pub fn update_dom_loading(&self, value: u64) { + pub(crate) fn update_dom_loading(&self, value: u64) { self.dom_loading.set(value); } - pub fn update_dom_interactive(&self, value: u64) { + pub(crate) fn update_dom_interactive(&self, value: u64) { self.dom_interactive.set(value); } - pub fn update_dom_content_loaded_event_start(&self, value: u64) { + pub(crate) fn update_dom_content_loaded_event_start(&self, value: u64) { self.dom_content_loaded_event_start.set(value); } - pub fn update_dom_content_loaded_event_end(&self, value: u64) { + pub(crate) fn update_dom_content_loaded_event_end(&self, value: u64) { self.dom_content_loaded_event_end.set(value); } - pub fn update_dom_complete(&self, value: u64) { + pub(crate) fn update_dom_complete(&self, value: u64) { self.dom_complete.set(value); } - pub fn update_load_event_start(&self, value: u64) { + pub(crate) fn update_load_event_start(&self, value: u64) { self.load_event_start.set(value); } - pub fn update_load_event_end(&self, value: u64) { + pub(crate) fn update_load_event_end(&self, value: u64) { self.load_event_end.set(value); } }