aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/document.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/document.rs')
-rw-r--r--components/script/dom/document.rs72
1 files changed, 70 insertions, 2 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index d2c97bdc5de..5c0fb4e2c7c 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -26,7 +26,7 @@ use euclid::default::{Point2D, Rect, Size2D};
use html5ever::{local_name, namespace_url, ns, LocalName, Namespace, QualName};
use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcSender};
-use js::rust::HandleObject;
+use js::rust::{HandleObject, HandleValue};
use keyboard_types::{Code, Key, KeyState};
use lazy_static::lazy_static;
use metrics::{
@@ -93,7 +93,7 @@ use crate::dom::bindings::codegen::Bindings::WindowBinding::{
FrameRequestCallback, ScrollBehavior, WindowMethods,
};
use crate::dom::bindings::codegen::UnionTypes::{NodeOrString, StringOrElementCreationOptions};
-use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
+use crate::dom::bindings::error::{Error, ErrorInfo, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
@@ -155,6 +155,7 @@ use crate::dom::pagetransitionevent::PageTransitionEvent;
use crate::dom::processinginstruction::ProcessingInstruction;
use crate::dom::promise::Promise;
use crate::dom::range::Range;
+use crate::dom::resizeobserver::{ResizeObservationDepth, ResizeObserver};
use crate::dom::selection::Selection;
use crate::dom::servoparser::ServoParser;
use crate::dom::shadowroot::ShadowRoot;
@@ -456,6 +457,15 @@ pub struct Document {
#[no_trace]
#[ignore_malloc_size_of = "AnimationTickType contains data from an outside crate"]
pending_animation_ticks: DomRefCell<AnimationTickType>,
+ /// <https://drafts.csswg.org/resize-observer/#dom-document-resizeobservers-slot>
+ ///
+ /// Note: we are storing, but never removing, resize observers.
+ /// The lifetime of resize observers is specified at
+ /// <https://drafts.csswg.org/resize-observer/#lifetime>.
+ /// But implementing it comes with known problems:
+ /// - <https://bugzilla.mozilla.org/show_bug.cgi?id=1596992>
+ /// - <https://github.com/w3c/csswg-drafts/issues/4518>
+ resize_observers: DomRefCell<Vec<Dom<ResizeObserver>>>,
}
#[derive(JSTraceable, MallocSizeOf)]
@@ -2920,6 +2930,63 @@ impl Document {
pub fn name_map(&self) -> Ref<HashMapTracedValues<Atom, Vec<Dom<Element>>>> {
self.name_map.borrow()
}
+
+ /// <https://drafts.csswg.org/resize-observer/#dom-resizeobserver-resizeobserver>
+ pub(crate) fn add_resize_observer(&self, resize_observer: &ResizeObserver) {
+ self.resize_observers
+ .borrow_mut()
+ .push(Dom::from_ref(resize_observer));
+ }
+
+ /// <https://drafts.csswg.org/resize-observer/#gather-active-observations-h>
+ /// <https://drafts.csswg.org/resize-observer/#has-active-resize-observations>
+ pub(crate) fn gather_active_resize_observations_at_depth(
+ &self,
+ depth: &ResizeObservationDepth,
+ ) -> bool {
+ let mut has_active_resize_observations = false;
+ for observer in self.resize_observers.borrow_mut().iter_mut() {
+ observer.gather_active_resize_observations_at_depth(
+ depth,
+ &mut has_active_resize_observations,
+ );
+ }
+ has_active_resize_observations
+ }
+
+ /// <https://drafts.csswg.org/resize-observer/#broadcast-active-resize-observations>
+ pub(crate) fn broadcast_active_resize_observations(&self) -> ResizeObservationDepth {
+ let mut shallowest = ResizeObservationDepth::max();
+ // Breaking potential re-borrow cycle on `resize_observers`:
+ // broadcasting resize observations calls into a JS callback,
+ // which can add new observers.
+ for observer in self
+ .resize_observers
+ .borrow()
+ .iter()
+ .map(|obs| DomRoot::from_ref(&**obs))
+ {
+ observer.broadcast_active_resize_observations(&mut shallowest);
+ }
+ shallowest
+ }
+
+ /// <https://drafts.csswg.org/resize-observer/#has-skipped-observations-h>
+ pub(crate) fn has_skipped_resize_observations(&self) -> bool {
+ self.resize_observers
+ .borrow()
+ .iter()
+ .any(|observer| observer.has_skipped_resize_observations())
+ }
+
+ /// <https://drafts.csswg.org/resize-observer/#deliver-resize-loop-error-notification>
+ pub(crate) fn deliver_resize_loop_error_notification(&self) {
+ let global_scope = self.window.upcast::<GlobalScope>();
+ let mut error_info: ErrorInfo = Default::default();
+ error_info.message =
+ "ResizeObserver loop completed with undelivered notifications.".to_string();
+ global_scope.report_an_error(error_info, HandleValue::null());
+ }
}
fn is_character_value_key(key: &Key) -> bool {
@@ -3222,6 +3289,7 @@ impl Document {
pending_animation_ticks: Default::default(),
pending_compositor_events: Default::default(),
mouse_move_event_index: Default::default(),
+ resize_observers: Default::default(),
}
}