Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions components/config/prefs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ mod gen {
allowed_in_nonsecure_contexts: bool,
}
},
resize_observer: {
enabled: bool,
},
script: {
asynch: bool,
},
Expand Down
1 change: 1 addition & 0 deletions components/script/dom/bindings/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ pub fn throw_dom_exception(cx: SafeJSContext, global: &GlobalScope, result: Erro
}

/// A struct encapsulating information about a runtime script error.
#[derive(Default)]
pub struct ErrorInfo {
/// The error message.
pub message: String,
Expand Down
72 changes: 70 additions & 2 deletions components/script/dom/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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};
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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(),
}
}

Expand Down
2 changes: 1 addition & 1 deletion components/script/dom/domrectreadonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl DOMRectReadOnly {
}
}

fn new(
pub fn new(
global: &GlobalScope,
proto: Option<HandleObject>,
x: f64,
Expand Down
3 changes: 3 additions & 0 deletions components/script/dom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,9 @@ pub mod range;
pub mod raredata;
pub mod readablestream;
pub mod request;
pub mod resizeobserver;
pub mod resizeobserverentry;
pub mod resizeobserversize;
pub mod response;
pub mod rtcdatachannel;
pub mod rtcdatachannelevent;
Expand Down
3 changes: 3 additions & 0 deletions components/script/dom/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2110,6 +2110,8 @@ impl Node {
MutationObserver::queue_a_mutation_record(parent, mutation);
}
node.owner_doc().remove_script_and_layout_blocker();

ScriptThread::note_rendering_opportunity(window_from_node(parent).pipeline_id());
}

/// <https://dom.spec.whatwg.org/#concept-node-replace-all>
Expand Down Expand Up @@ -2233,6 +2235,7 @@ impl Node {
MutationObserver::queue_a_mutation_record(parent, mutation);
}
parent.owner_doc().remove_script_and_layout_blocker();
ScriptThread::note_rendering_opportunity(window_from_node(parent).pipeline_id());
}

/// <https://dom.spec.whatwg.org/#concept-node-clone>
Expand Down
Loading