aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/script/dom/document.rs72
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/visibilitystateentry.rs73
-rw-r--r--components/script/dom/webidls/Document.webidl3
-rw-r--r--components/script/dom/webidls/VisibilityStateEntry.webidl13
5 files changed, 154 insertions, 8 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index ddf95e976cf..4f6d2ab0354 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -67,7 +67,6 @@ use url::Host;
use uuid::Uuid;
use webrender_api::units::DeviceIntRect;
-use super::bindings::trace::{HashMapTracedValues, NoTrace};
use crate::animation_timeline::AnimationTimeline;
use crate::animations::Animations;
use crate::document_loader::{DocumentLoader, LoadType};
@@ -77,7 +76,7 @@ use crate::dom::bindings::callback::ExceptionHandling;
use crate::dom::bindings::cell::{ref_filter_map, DomRefCell, Ref, RefMut};
use crate::dom::bindings::codegen::Bindings::BeforeUnloadEventBinding::BeforeUnloadEvent_Binding::BeforeUnloadEventMethods;
use crate::dom::bindings::codegen::Bindings::DocumentBinding::{
- DocumentMethods, DocumentReadyState, NamedPropertyValue,
+ DocumentMethods, DocumentReadyState, DocumentVisibilityState, NamedPropertyValue,
};
use crate::dom::bindings::codegen::Bindings::EventBinding::Event_Binding::EventMethods;
use crate::dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElement_Binding::HTMLIFrameElementMethods;
@@ -100,6 +99,7 @@ use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject};
use crate::dom::bindings::root::{Dom, DomRoot, DomSlice, LayoutDom, MutNullableDom};
use crate::dom::bindings::str::{DOMString, USVString};
+use crate::dom::bindings::trace::{HashMapTracedValues, NoTrace};
use crate::dom::bindings::xmlname::XMLName::Invalid;
use crate::dom::bindings::xmlname::{
namespace_from_domstring, validate_and_extract, xml_name_type,
@@ -153,6 +153,7 @@ use crate::dom::node::{
use crate::dom::nodeiterator::NodeIterator;
use crate::dom::nodelist::NodeList;
use crate::dom::pagetransitionevent::PageTransitionEvent;
+use crate::dom::performanceentry::PerformanceEntry;
use crate::dom::processinginstruction::ProcessingInstruction;
use crate::dom::promise::Promise;
use crate::dom::range::Range;
@@ -167,6 +168,7 @@ use crate::dom::touch::Touch;
use crate::dom::touchevent::TouchEvent;
use crate::dom::touchlist::TouchList;
use crate::dom::treewalker::TreeWalker;
+use crate::dom::types::VisibilityStateEntry;
use crate::dom::uievent::UIEvent;
use crate::dom::virtualmethods::vtable_for;
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
@@ -470,6 +472,8 @@ pub struct Document {
/// The set of all fonts loaded by this document.
/// <https://drafts.csswg.org/css-font-loading/#font-face-source>
fonts: MutNullableDom<FontFaceSet>,
+ /// <https://html.spec.whatwg.org/multipage/#visibility-state>
+ visibility_state: Cell<DocumentVisibilityState>,
}
#[derive(JSTraceable, MallocSizeOf)]
@@ -708,8 +712,9 @@ impl Document {
return;
}
- // html.spec.whatwg.org/multipage/#history-traversal
- // Step 4.6
+ // This step used to be Step 4.6 in html.spec.whatwg.org/multipage/#history-traversal
+ // But it's now Step 4 in https://html.spec.whatwg.org/multipage/#reactivate-a-document
+ // TODO: See #32687 for more information.
let document = Trusted::new(self);
self.window
.task_manager()
@@ -722,9 +727,12 @@ impl Document {
if document.page_showing.get() {
return;
}
- // Step 4.6.2
+ // Step 4.6.2 Set document's page showing flag to true.
document.page_showing.set(true);
- // Step 4.6.4
+ // Step 4.6.3 Update the visibility state of document to "visible".
+ document.update_visibility_state(DocumentVisibilityState::Visible);
+ // Step 4.6.4 Fire a page transition event named pageshow at document's relevant
+ // global object with true.
let event = PageTransitionEvent::new(
window,
atom!("pageshow"),
@@ -2220,9 +2228,12 @@ impl Document {
// TODO: Step 1, increase the event loop's termination nesting level by 1.
// Step 2
self.incr_ignore_opens_during_unload_counter();
- // Step 3-6
+ // Step 3-6 If oldDocument's page showing is true:
if self.page_showing.get() {
+ // Set oldDocument's page showing to false.
self.page_showing.set(false);
+ // Fire a page transition event named pagehide at oldDocument's relevant global object with oldDocument's
+ // salvageable state.
let event = PageTransitionEvent::new(
&self.window,
atom!("pagehide"),
@@ -2233,7 +2244,8 @@ impl Document {
let event = event.upcast::<Event>();
event.set_trusted(true);
let _ = self.window.dispatch_event_with_target_override(event);
- // TODO Step 6, document visibility steps.
+ // Step 6 Update the visibility state of oldDocument to "hidden".
+ self.update_visibility_state(DocumentVisibilityState::Hidden);
}
// Step 7
if !self.fired_unload.get() {
@@ -3297,6 +3309,7 @@ impl Document {
mouse_move_event_index: Default::default(),
resize_observers: Default::default(),
fonts: Default::default(),
+ visibility_state: Cell::new(DocumentVisibilityState::Hidden),
}
}
@@ -4083,6 +4096,39 @@ impl Document {
pub(crate) fn set_declarative_refresh(&self, refresh: DeclarativeRefresh) {
*self.declarative_refresh.borrow_mut() = Some(refresh);
}
+
+ /// <https://html.spec.whatwg.org/multipage/#visibility-state>
+ fn update_visibility_state(&self, visibility_state: DocumentVisibilityState) {
+ // Step 1 If document's visibility state equals visibilityState, then return.
+ if self.visibility_state.get() == visibility_state {
+ return;
+ }
+ // Step 2 Set document's visibility state to visibilityState.
+ self.visibility_state.set(visibility_state);
+ // Step 3 Queue a new VisibilityStateEntry whose visibility state is visibilityState and whose timestamp is
+ // the current high resolution time given document's relevant global object.
+ let entry = VisibilityStateEntry::new(
+ &self.global(),
+ visibility_state,
+ *self.global().performance().Now(),
+ );
+ self.window
+ .Performance()
+ .queue_entry(entry.upcast::<PerformanceEntry>());
+
+ // Step 4 Run the screen orientation change steps with document.
+ // TODO ScreenOrientation hasn't implemented yet
+
+ // Step 5 Run the view transition page visibility change steps with document.
+ // TODO ViewTransition hasn't implemented yet
+
+ // Step 6 Run any page visibility change steps which may be defined in other specifications, with visibility
+ // state and document. Any other specs' visibility steps will go here.
+
+ // Step 7 Fire an event named visibilitychange at document, with its bubbles attribute initialized to true.
+ self.upcast::<EventTarget>()
+ .fire_bubbling_event(atom!("visibilitychange"));
+ }
}
impl ProfilerMetadataFactory for Document {
@@ -5376,6 +5422,16 @@ impl DocumentMethods for Document {
self.fonts
.or_init(|| FontFaceSet::new(&self.global(), None))
}
+
+ /// <https://html.spec.whatwg.org/multipage/#dom-document-hidden>
+ fn Hidden(&self) -> bool {
+ self.visibility_state.get() == DocumentVisibilityState::Hidden
+ }
+
+ /// <https://html.spec.whatwg.org/multipage/#dom-document-visibilitystate>
+ fn VisibilityState(&self) -> DocumentVisibilityState {
+ self.visibility_state.get()
+ }
}
fn update_with_current_time_ms(marker: &Cell<u64>) {
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index a4c4f2f3230..76723e8f2ce 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -580,6 +580,7 @@ pub mod vertexarrayobject;
pub mod videotrack;
pub mod videotracklist;
pub mod virtualmethods;
+pub mod visibilitystateentry;
pub mod vttcue;
pub mod vttregion;
pub mod webgl2renderingcontext;
diff --git a/components/script/dom/visibilitystateentry.rs b/components/script/dom/visibilitystateentry.rs
new file mode 100644
index 00000000000..9dcf74a58e6
--- /dev/null
+++ b/components/script/dom/visibilitystateentry.rs
@@ -0,0 +1,73 @@
+/* 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::ops::Deref;
+
+use dom_struct::dom_struct;
+
+use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentVisibilityState;
+use crate::dom::bindings::codegen::Bindings::PerformanceEntryBinding::PerformanceEntryMethods;
+use crate::dom::bindings::codegen::Bindings::VisibilityStateEntryBinding::VisibilityStateEntryMethods;
+use crate::dom::bindings::num::Finite;
+use crate::dom::bindings::reflector::reflect_dom_object;
+use crate::dom::bindings::root::DomRoot;
+use crate::dom::bindings::str::DOMString;
+use crate::dom::globalscope::GlobalScope;
+use crate::dom::performanceentry::PerformanceEntry;
+
+#[dom_struct]
+pub struct VisibilityStateEntry {
+ entry: PerformanceEntry,
+}
+
+impl VisibilityStateEntry {
+ #[allow(crown::unrooted_must_root)]
+ fn new_inherited(state: DocumentVisibilityState, timestamp: f64) -> VisibilityStateEntry {
+ let name = match state {
+ DocumentVisibilityState::Visible => DOMString::from("visible"),
+ DocumentVisibilityState::Hidden => DOMString::from("hidden"),
+ };
+ VisibilityStateEntry {
+ entry: PerformanceEntry::new_inherited(
+ name,
+ DOMString::from("visibility-state"),
+ timestamp,
+ 0.,
+ ),
+ }
+ }
+
+ pub fn new(
+ global: &GlobalScope,
+ state: DocumentVisibilityState,
+ timestamp: f64,
+ ) -> DomRoot<VisibilityStateEntry> {
+ reflect_dom_object(
+ Box::new(VisibilityStateEntry::new_inherited(state, timestamp)),
+ global,
+ )
+ }
+}
+
+impl VisibilityStateEntryMethods for VisibilityStateEntry {
+ /// <https://html.spec.whatwg.org/multipage/#visibilitystateentry-name>
+ fn Name(&self) -> DOMString {
+ self.entry.Name()
+ }
+
+ /// <https://html.spec.whatwg.org/multipage/#visibilitystateentry-entrytype>
+ fn EntryType(&self) -> DOMString {
+ self.entry.EntryType()
+ }
+
+ /// <https://html.spec.whatwg.org/multipage/#visibilitystateentry-starttime>
+ fn StartTime(&self) -> Finite<f64> {
+ self.entry.StartTime()
+ }
+
+ /// <https://html.spec.whatwg.org/multipage/#visibilitystateentry-duration>
+ fn Duration(&self) -> u32 {
+ *self.entry.Duration().deref() as u32
+ }
+}
diff --git a/components/script/dom/webidls/Document.webidl b/components/script/dom/webidls/Document.webidl
index 00cc5d81506..6131dbd15c7 100644
--- a/components/script/dom/webidls/Document.webidl
+++ b/components/script/dom/webidls/Document.webidl
@@ -78,6 +78,7 @@ Document includes NonElementParentNode;
Document includes ParentNode;
enum DocumentReadyState { "loading", "interactive", "complete" };
+enum DocumentVisibilityState { "visible", "hidden" };
dictionary ElementCreationOptions {
DOMString is;
@@ -144,6 +145,8 @@ partial /*sealed*/ interface Document {
// boolean queryCommandState(DOMString commandId);
boolean queryCommandSupported(DOMString commandId);
// DOMString queryCommandValue(DOMString commandId);
+ readonly attribute boolean hidden;
+ readonly attribute DocumentVisibilityState visibilityState;
// special event handler IDL attributes that only apply to Document objects
[LegacyLenientThis] attribute EventHandler onreadystatechange;
diff --git a/components/script/dom/webidls/VisibilityStateEntry.webidl b/components/script/dom/webidls/VisibilityStateEntry.webidl
new file mode 100644
index 00000000000..12e85541be5
--- /dev/null
+++ b/components/script/dom/webidls/VisibilityStateEntry.webidl
@@ -0,0 +1,13 @@
+/* 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://html.spec.whatwg.org/multipage/#visibilitystateentry
+
+[Exposed=(Window)]
+interface VisibilityStateEntry : PerformanceEntry {
+ readonly attribute DOMString name; // shadows inherited name
+ readonly attribute DOMString entryType; // shadows inherited entryType
+ readonly attribute DOMHighResTimeStamp startTime; // shadows inherited startTime
+ readonly attribute unsigned long duration; // shadows inherited duration
+};