diff options
author | chickenleaf <lashwinib@gmail.com> | 2024-10-21 17:58:56 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-21 12:28:56 +0000 |
commit | 9acb25521e433bdea49866e4ecb6a9f4e90b0663 (patch) | |
tree | 96c99cdf3e5f4c157dbfb08eff8240d9dff55bfc | |
parent | 66695d2f7ee25782d3edfca32b74ff14bc9faa84 (diff) | |
download | servo-9acb25521e433bdea49866e4ecb6a9f4e90b0663.tar.gz servo-9acb25521e433bdea49866e4ecb6a9f4e90b0663.zip |
CanGc changes from fontfaceset.rs (#33920)
* CanGc changes from fontfaceset.rs
Signed-off-by: L Ashwin B <lashwinib@gmail.com>
* Update components/script/dom/bindings/codegen/Bindings.conf
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
Signed-off-by: chickenleaf <lashwinib@gmail.com>
---------
Signed-off-by: L Ashwin B <lashwinib@gmail.com>
Signed-off-by: chickenleaf <lashwinib@gmail.com>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
32 files changed, 425 insertions, 274 deletions
diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index b426c2a1551..0d5e934a5e4 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -737,8 +737,13 @@ impl CanvasState { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor - pub fn set_shadow_color(&self, canvas: Option<&HTMLCanvasElement>, value: DOMString) { - if let Ok(rgba) = parse_color(canvas, &value) { + pub fn set_shadow_color( + &self, + canvas: Option<&HTMLCanvasElement>, + value: DOMString, + can_gc: CanGc, + ) { + if let Ok(rgba) = parse_color(canvas, &value, can_gc) { self.state.borrow_mut().shadow_color = rgba; self.send_canvas_2d_msg(Canvas2dMsg::SetShadowColor(rgba)) } @@ -766,10 +771,11 @@ impl CanvasState { &self, canvas: Option<&HTMLCanvasElement>, value: StringOrCanvasGradientOrCanvasPattern, + can_gc: CanGc, ) { match value { StringOrCanvasGradientOrCanvasPattern::String(string) => { - if let Ok(rgba) = parse_color(canvas, &string) { + if let Ok(rgba) = parse_color(canvas, &string, can_gc) { self.state.borrow_mut().stroke_style = CanvasFillOrStrokeStyle::Color(rgba); } }, @@ -809,10 +815,11 @@ impl CanvasState { &self, canvas: Option<&HTMLCanvasElement>, value: StringOrCanvasGradientOrCanvasPattern, + can_gc: CanGc, ) { match value { StringOrCanvasGradientOrCanvasPattern::String(string) => { - if let Ok(rgba) = parse_color(canvas, &string) { + if let Ok(rgba) = parse_color(canvas, &string, can_gc) { self.state.borrow_mut().fill_style = CanvasFillOrStrokeStyle::Color(rgba); } }, @@ -1002,6 +1009,7 @@ impl CanvasState { x: f64, y: f64, max_width: Option<f64>, + can_gc: CanGc, ) { if !x.is_finite() || !y.is_finite() { return; @@ -1010,7 +1018,11 @@ impl CanvasState { return; } if self.state.borrow().font_style.is_none() { - self.set_font(canvas, CanvasContextState::DEFAULT_FONT_STYLE.into()) + self.set_font( + canvas, + CanvasContextState::DEFAULT_FONT_STYLE.into(), + can_gc, + ) } let is_rtl = match self.state.borrow().direction { @@ -1036,9 +1048,14 @@ impl CanvasState { global: &GlobalScope, canvas: Option<&HTMLCanvasElement>, text: DOMString, + can_gc: CanGc, ) -> DomRoot<TextMetrics> { if self.state.borrow().font_style.is_none() { - self.set_font(canvas, CanvasContextState::DEFAULT_FONT_STYLE.into()); + self.set_font( + canvas, + CanvasContextState::DEFAULT_FONT_STYLE.into(), + can_gc, + ); } let (sender, receiver) = ipc::channel::<CanvasTextMetrics>().unwrap(); @@ -1063,17 +1080,18 @@ impl CanvasState { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-font - pub fn set_font(&self, canvas: Option<&HTMLCanvasElement>, value: DOMString) { + pub fn set_font(&self, canvas: Option<&HTMLCanvasElement>, value: DOMString, can_gc: CanGc) { let canvas = match canvas { Some(element) => element, None => return, // offscreen canvas doesn't have a placeholder canvas }; let node = canvas.upcast::<Node>(); let window = window_from_node(canvas); - let resolved_font_style = match window.resolved_font_style_query(node, value.to_string()) { - Some(value) => value, - None => return, // syntax error - }; + let resolved_font_style = + match window.resolved_font_style_query(node, value.to_string(), can_gc) { + Some(value) => value, + None => return, // syntax error + }; self.state.borrow_mut().font_style = Some((*resolved_font_style).clone()); self.send_canvas_2d_msg(Canvas2dMsg::SetFont((*resolved_font_style).clone())); } @@ -1717,7 +1735,11 @@ impl CanvasState { } } -pub fn parse_color(canvas: Option<&HTMLCanvasElement>, string: &str) -> Result<AbsoluteColor, ()> { +pub fn parse_color( + canvas: Option<&HTMLCanvasElement>, + string: &str, + can_gc: CanGc, +) -> Result<AbsoluteColor, ()> { let mut input = ParserInput::new(string); let mut parser = Parser::new(&mut input); let url = Url::parse("about:blank").unwrap().into(); @@ -1745,8 +1767,8 @@ pub fn parse_color(canvas: Option<&HTMLCanvasElement>, string: &str) -> Result<A None => AbsoluteColor::BLACK, Some(canvas) => { let canvas_element = canvas.upcast::<Element>(); - match canvas_element.style() { - Some(ref s) if canvas_element.has_css_layout_box() => { + match canvas_element.style(can_gc) { + Some(ref s) if canvas_element.has_css_layout_box(can_gc) => { s.get_inherited_text().color }, _ => AbsoluteColor::BLACK, diff --git a/components/script/devtools.rs b/components/script/devtools.rs index 95f4a245ce4..e02d413caf1 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -354,7 +354,7 @@ pub fn handle_get_layout( position: String::from(computed_style.Position()), z_index: String::from(computed_style.ZIndex()), box_sizing: String::from(computed_style.BoxSizing()), - auto_margins: determine_auto_margins(&node), + auto_margins: determine_auto_margins(&node, can_gc), margin_top: String::from(computed_style.MarginTop()), margin_right: String::from(computed_style.MarginRight()), margin_bottom: String::from(computed_style.MarginBottom()), @@ -373,8 +373,8 @@ pub fn handle_get_layout( .unwrap(); } -fn determine_auto_margins(node: &Node) -> AutoMargins { - let style = node.style().unwrap(); +fn determine_auto_margins(node: &Node, can_gc: CanGc) -> AutoMargins { + let style = node.style(can_gc).unwrap(); let margin = style.get_margin(); AutoMargins { top: margin.margin_top.is_auto(), diff --git a/components/script/dom/activation.rs b/components/script/dom/activation.rs index 796bb5b0381..8f325fb4e89 100644 --- a/components/script/dom/activation.rs +++ b/components/script/dom/activation.rs @@ -37,13 +37,21 @@ pub trait Activatable { self.as_element().set_active_state(true); let win = window_from_node(self.as_element()); - win.reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged); + win.reflow( + ReflowGoal::Full, + ReflowReason::ElementStateChanged, + CanGc::note(), + ); } fn exit_formal_activation_state(&self) { self.as_element().set_active_state(false); let win = window_from_node(self.as_element()); - win.reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged); + win.reflow( + ReflowGoal::Full, + ReflowReason::ElementStateChanged, + CanGc::note(), + ); } } diff --git a/components/script/dom/bindings/codegen/Bindings.conf b/components/script/dom/bindings/codegen/Bindings.conf index 3ea8afe6d45..896cf1f0314 100644 --- a/components/script/dom/bindings/codegen/Bindings.conf +++ b/components/script/dom/bindings/codegen/Bindings.conf @@ -58,7 +58,11 @@ DOMInterfaces = { }, 'CanvasRenderingContext2D': { - 'canGc': ['GetTransform','GetImageData', 'CreateImageData', 'CreateImageData_'], + 'canGc': ['GetTransform','GetImageData', 'CreateImageData', 'CreateImageData_', 'SetFont', 'FillText', 'MeasureText', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'], +}, + +'CanvasGradient': { + 'canGc': ['AddColorStop'], }, 'DOMImplementation': { @@ -90,7 +94,7 @@ DOMInterfaces = { }, 'Document': { - 'canGc': ['Close', 'CreateElement', 'CreateElementNS', 'ImportNode', 'SetTitle', 'Write', 'Writeln', 'CreateEvent', 'CreateRange', 'Open', 'Open_'], + 'canGc': ['Close', 'CreateElement', 'CreateElementNS', 'ImportNode', 'SetTitle', 'Write', 'Writeln', 'CreateEvent', 'CreateRange', 'Open', 'Open_', 'Fonts', 'ElementFromPoint', 'ElementsFromPoint'], }, 'DynamicModuleOwner': { @@ -98,7 +102,7 @@ DOMInterfaces = { }, 'Element': { - 'canGc': ['SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect'], + 'canGc': ['SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect', 'SetScrollTop', 'SetScrollLeft', 'Scroll', 'Scroll_', 'ScrollBy', 'ScrollBy_', 'ScrollWidth', 'ScrollHeight', 'ScrollTop', 'ScrollLeft', 'ClientTop', 'ClientLeft', 'ClientWidth', 'ClientHeight'], }, 'ElementInternals': { @@ -192,6 +196,14 @@ DOMInterfaces = { 'canGc': ['Content'], }, +'HTMLElement': { + 'canGc': ['GetOffsetParent', 'OffsetTop', 'OffsetLeft', 'OffsetWidth', 'OffsetHeight', 'InnerText', 'GetOuterText', 'Focus', 'Blur', 'Click'], +}, + +'HTMLImageElement': { + 'canGc': ['Width', 'Height'], +}, + 'HTMLTextAreaElement': { 'canGc': ['ReportValidity'], }, @@ -213,6 +225,9 @@ DOMInterfaces = { 'canGc': ['GetMetadata'], }, +'MouseEvent': { + 'canGc': ['OffsetX', 'OffsetY'], +}, 'MediaQueryList': { 'weakReferenceable': True, @@ -239,11 +254,11 @@ DOMInterfaces = { }, 'OffscreenCanvasRenderingContext2D': { - 'canGc': ['CreateImageData', 'CreateImageData_', 'GetImageData', 'GetTransform'], + 'canGc': ['CreateImageData', 'CreateImageData_', 'GetImageData', 'GetTransform', 'SetFont', 'FillText', 'MeasureText', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'], }, 'PaintRenderingContext2D': { - 'canGc': ['GetTransform'], + 'canGc': ['GetTransform', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'], }, 'Promise': { @@ -272,7 +287,6 @@ DOMInterfaces = { 'canGc': ['Collapse', 'CollapseToEnd', 'CollapseToStart', 'Extend', 'SelectAllChildren', 'SetBaseAndExtent', 'SetPosition'], }, - 'ServiceWorkerContainer': { 'inRealms': ['Register'], }, @@ -281,6 +295,10 @@ DOMInterfaces = { 'weakReferenceable': True, }, +'ShadowRoot': { + 'canGc': ['ElementFromPoint', 'ElementsFromPoint'], +}, + 'SubtleCrypto': { 'inRealms': ['Encrypt', 'Decrypt', 'GenerateKey', 'ImportKey', 'ExportKey'] }, @@ -305,7 +323,7 @@ DOMInterfaces = { }, 'Window': { - 'canGc': ['Stop', 'Fetch', 'Open'], + 'canGc': ['Stop', 'Fetch', 'Scroll', 'Scroll_','ScrollBy', 'ScrollBy_', 'Stop', 'Fetch', 'Open'], 'inRealms': ['Fetch', 'GetOpener'], }, diff --git a/components/script/dom/canvasgradient.rs b/components/script/dom/canvasgradient.rs index 20791998951..f1317dd0a90 100644 --- a/components/script/dom/canvasgradient.rs +++ b/components/script/dom/canvasgradient.rs @@ -16,6 +16,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::CanGc; // https://html.spec.whatwg.org/multipage/#canvasgradient #[dom_struct] @@ -48,12 +49,12 @@ impl CanvasGradient { impl CanvasGradientMethods for CanvasGradient { // https://html.spec.whatwg.org/multipage/#dom-canvasgradient-addcolorstop - fn AddColorStop(&self, offset: Finite<f64>, color: DOMString) -> ErrorResult { + fn AddColorStop(&self, offset: Finite<f64>, color: DOMString, can_gc: CanGc) -> ErrorResult { if *offset < 0f64 || *offset > 1f64 { return Err(Error::IndexSize); } - let color = match parse_color(None, &color) { + let color = match parse_color(None, &color, can_gc) { Ok(color) => color, Err(_) => return Err(Error::Syntax), }; diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 1f3420457fb..bc131b94eab 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -285,16 +285,16 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext - fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>) { + fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>, can_gc: CanGc) { self.canvas_state - .fill_text(self.canvas.as_deref(), text, x, y, max_width); + .fill_text(self.canvas.as_deref(), text, x, y, max_width, can_gc); self.mark_as_dirty(); } // https://html.spec.whatwg.org/multipage/#textmetrics - fn MeasureText(&self, text: DOMString) -> DomRoot<TextMetrics> { + fn MeasureText(&self, text: DOMString, can_gc: CanGc) -> DomRoot<TextMetrics> { self.canvas_state - .measure_text(&self.global(), self.canvas.as_deref(), text) + .measure_text(&self.global(), self.canvas.as_deref(), text, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-font @@ -303,8 +303,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-font - fn SetFont(&self, value: DOMString) { - self.canvas_state.set_font(self.canvas.as_deref(), value) + fn SetFont(&self, value: DOMString, can_gc: CanGc) { + self.canvas_state + .set_font(self.canvas.as_deref(), value, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign @@ -451,9 +452,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { + fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { self.canvas_state - .set_stroke_style(self.canvas.as_deref(), value) + .set_stroke_style(self.canvas.as_deref(), value, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle @@ -462,9 +463,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { + fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { self.canvas_state - .set_fill_style(self.canvas.as_deref(), value) + .set_fill_style(self.canvas.as_deref(), value, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata @@ -656,9 +657,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor - fn SetShadowColor(&self, value: DOMString) { + fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) { self.canvas_state - .set_shadow_color(self.canvas.as_deref(), value) + .set_shadow_color(self.canvas.as_deref(), value, can_gc) } } diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index b6efaa7f6c3..e660f15166f 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -30,6 +30,7 @@ use crate::dom::cssrule::CSSRule; use crate::dom::element::Element; use crate::dom::node::{document_from_node, stylesheets_owner_from_node, window_from_node, Node}; use crate::dom::window::Window; +use crate::script_runtime::CanGc; // http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface #[dom_struct] @@ -245,7 +246,7 @@ impl CSSStyleDeclaration { ) } - fn get_computed_style(&self, property: PropertyId) -> DOMString { + fn get_computed_style(&self, property: PropertyId, can_gc: CanGc) -> DOMString { match self.owner { CSSStyleOwner::CSSRule(..) => { panic!("get_computed_style called on CSSStyleDeclaration with a CSSRule owner") @@ -256,7 +257,7 @@ impl CSSStyleDeclaration { return DOMString::new(); } let addr = node.to_trusted_node_address(); - window_from_node(node).resolved_style_query(addr, self.pseudo, property) + window_from_node(node).resolved_style_query(addr, self.pseudo, property, can_gc) }, } } @@ -264,7 +265,7 @@ impl CSSStyleDeclaration { fn get_property_value(&self, id: PropertyId) -> DOMString { if self.readonly { // Readonly style declarations are used for getComputedStyle. - return self.get_computed_style(id); + return self.get_computed_style(id, CanGc::note()); } let mut string = String::new(); diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 25074c1e965..189352c35ce 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -694,7 +694,7 @@ impl Document { self.activity.get() != DocumentActivity::Inactive } - pub fn set_activity(&self, activity: DocumentActivity) { + pub fn set_activity(&self, activity: DocumentActivity, can_gc: CanGc) { // This function should only be called on documents with a browsing context assert!(self.has_browsing_context); if activity == self.activity.get() { @@ -716,8 +716,11 @@ impl Document { self.title_changed(); self.dirty_all_nodes(); - self.window() - .reflow(ReflowGoal::Full, ReflowReason::CachedPageNeededReflow); + self.window().reflow( + ReflowGoal::Full, + ReflowReason::CachedPageNeededReflow, + can_gc, + ); self.window().resume(); media.resume(&client_context_id); @@ -906,7 +909,7 @@ impl Document { } /// Reflows and disarms the timer if the reflow timer has expired. - pub fn reflow_if_reflow_timer_expired(&self) { + pub fn reflow_if_reflow_timer_expired(&self, can_gc: CanGc) { let Some(reflow_timeout) = self.reflow_timeout.get() else { return; }; @@ -917,7 +920,7 @@ impl Document { self.reflow_timeout.set(None); self.window - .reflow(ReflowGoal::Full, ReflowReason::RefreshTick); + .reflow(ReflowGoal::Full, ReflowReason::RefreshTick, can_gc); } /// Schedules a reflow to be kicked off at the given [`Duration`] in the future. This reflow @@ -1019,11 +1022,11 @@ impl Document { /// Scroll to the target element, and when we do not find a target /// and the fragment is empty or "top", scroll to the top. /// <https://html.spec.whatwg.org/multipage/#scroll-to-the-fragment-identifier> - pub fn check_and_scroll_fragment(&self, fragment: &str) { + pub fn check_and_scroll_fragment(&self, fragment: &str, can_gc: CanGc) { let target = self.find_fragment_node(fragment); // Step 1 - self.set_target_element(target.as_deref()); + self.set_target_element(target.as_deref(), can_gc); let point = target .as_ref() @@ -1032,7 +1035,9 @@ impl Document { // inside other scrollable containers. Ideally this should use an implementation of // `scrollIntoView` when that is available: // See https://github.com/servo/servo/issues/24059. - let rect = element.upcast::<Node>().bounding_content_box_or_zero(); + let rect = element + .upcast::<Node>() + .bounding_content_box_or_zero(can_gc); // In order to align with element edges, we snap to unscaled pixel boundaries, since // the paint thread currently does the same for drawing elements. This is important @@ -1056,7 +1061,7 @@ impl Document { if let Some((x, y)) = point { self.window - .scroll(x as f64, y as f64, ScrollBehavior::Instant) + .scroll(x as f64, y as f64, ScrollBehavior::Instant, can_gc) } } @@ -1188,7 +1193,7 @@ impl Document { // Notify the embedder to display an input method. if let Some(kind) = elem.input_method_type() { - let rect = elem.upcast::<Node>().bounding_content_box_or_zero(); + let rect = elem.upcast::<Node>().bounding_content_box_or_zero(can_gc); let rect = Rect::new( Point2D::new(rect.origin.x.to_px(), rect.origin.y.to_px()), Size2D::new(rect.size.width.to_px(), rect.size.height.to_px()), @@ -2088,7 +2093,7 @@ impl Document { } /// <https://html.spec.whatwg.org/multipage/#run-the-animation-frame-callbacks> - pub fn run_the_animation_frame_callbacks(&self) { + pub fn run_the_animation_frame_callbacks(&self, can_gc: CanGc) { rooted_vec!(let mut animation_frame_list); mem::swap( &mut *animation_frame_list, @@ -2107,9 +2112,11 @@ impl Document { self.running_animation_callbacks.set(false); - let spurious = !self - .window - .reflow(ReflowGoal::Full, ReflowReason::RequestAnimationFrame); + let spurious = !self.window.reflow( + ReflowGoal::Full, + ReflowReason::RequestAnimationFrame, + can_gc, + ); if spurious && !was_faking_animation_frames { // If the rAF callbacks did not mutate the DOM, then the @@ -2239,7 +2246,7 @@ impl Document { self.reflow_timeout.set(None); self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); self.window - .reflow(ReflowGoal::Full, ReflowReason::FirstLoad); + .reflow(ReflowGoal::Full, ReflowReason::FirstLoad, can_gc); } // Deferred scripts have to wait for page to finish loading, @@ -2471,7 +2478,7 @@ impl Document { update_with_current_instant(&document.load_event_end); if let Some(fragment) = document.url().fragment() { - document.check_and_scroll_fragment(fragment); + document.check_and_scroll_fragment(fragment, CanGc::note()); } }), self.window.upcast(), @@ -3048,12 +3055,14 @@ impl Document { pub(crate) fn gather_active_resize_observations_at_depth( &self, depth: &ResizeObservationDepth, + can_gc: CanGc, ) -> 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, + can_gc, ); } has_active_resize_observations @@ -3444,10 +3453,10 @@ impl Document { } /// As part of a `update_the_rendering` task, tick all pending animations. - pub fn tick_all_animations(&self, should_run_rafs: bool) { + pub fn tick_all_animations(&self, should_run_rafs: bool, can_gc: CanGc) { let tick_type = mem::take(&mut *self.pending_animation_ticks.borrow_mut()); if should_run_rafs { - self.run_the_animation_frame_callbacks(); + self.run_the_animation_frame_callbacks(can_gc); } if tick_type.contains(AnimationTickType::CSS_ANIMATIONS_AND_TRANSITIONS) { self.maybe_mark_animating_nodes_as_dirty(); @@ -3839,7 +3848,7 @@ impl Document { self.referrer_policy.get() } - pub fn set_target_element(&self, node: Option<&Element>) { + pub fn set_target_element(&self, node: Option<&Element>, can_gc: CanGc) { if let Some(ref element) = self.target_element.get() { element.set_target_state(false); } @@ -3851,7 +3860,7 @@ impl Document { } self.window - .reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged); + .reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged, can_gc); } pub fn incr_ignore_destructive_writes_counter(&self) { @@ -5280,22 +5289,34 @@ impl DocumentMethods for Document { ); // https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint - fn ElementFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Option<DomRoot<Element>> { + fn ElementFromPoint( + &self, + x: Finite<f64>, + y: Finite<f64>, + can_gc: CanGc, + ) -> Option<DomRoot<Element>> { self.document_or_shadow_root.element_from_point( x, y, self.GetDocumentElement(), self.has_browsing_context, + can_gc, ) } // https://drafts.csswg.org/cssom-view/#dom-document-elementsfrompoint - fn ElementsFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Vec<DomRoot<Element>> { + fn ElementsFromPoint( + &self, + x: Finite<f64>, + y: Finite<f64>, + can_gc: CanGc, + ) -> Vec<DomRoot<Element>> { self.document_or_shadow_root.elements_from_point( x, y, self.GetDocumentElement(), self.has_browsing_context, + can_gc, ) } @@ -5560,9 +5581,9 @@ impl DocumentMethods for Document { } // https://drafts.csswg.org/css-font-loading/#font-face-source - fn Fonts(&self) -> DomRoot<FontFaceSet> { + fn Fonts(&self, can_gc: CanGc) -> DomRoot<FontFaceSet> { self.fonts - .or_init(|| FontFaceSet::new(&self.global(), None)) + .or_init(|| FontFaceSet::new(&self.global(), None, can_gc)) } /// <https://html.spec.whatwg.org/multipage/#dom-document-hidden> @@ -5625,9 +5646,9 @@ pub struct FakeRequestAnimationFrameCallback { } impl FakeRequestAnimationFrameCallback { - pub fn invoke(self) { + pub fn invoke(self, can_gc: CanGc) { let document = self.document.root(); - document.run_the_animation_frame_callbacks(); + document.run_the_animation_frame_callbacks(can_gc); } } diff --git a/components/script/dom/documentorshadowroot.rs b/components/script/dom/documentorshadowroot.rs index e3eb4a34de1..7e9e58fe3a3 100644 --- a/components/script/dom/documentorshadowroot.rs +++ b/components/script/dom/documentorshadowroot.rs @@ -25,6 +25,7 @@ use crate::dom::element::Element; use crate::dom::htmlelement::HTMLElement; use crate::dom::node::{self, Node, VecPreOrderInsertionHelper}; use crate::dom::window::Window; +use crate::script_runtime::CanGc; use crate::stylesheet_set::StylesheetSetRef; #[derive(Clone, JSTraceable, MallocSizeOf)] @@ -90,8 +91,12 @@ impl DocumentOrShadowRoot { &self, client_point: &Point2D<f32>, query_type: NodesFromPointQueryType, + can_gc: CanGc, ) -> Vec<UntrustedNodeAddress> { - if !self.window.layout_reflow(QueryMsg::NodesFromPointQuery) { + if !self + .window + .layout_reflow(QueryMsg::NodesFromPointQuery, can_gc) + { return vec![]; }; @@ -108,6 +113,7 @@ impl DocumentOrShadowRoot { y: Finite<f64>, document_element: Option<DomRoot<Element>>, has_browsing_context: bool, + can_gc: CanGc, ) -> Option<DomRoot<Element>> { let x = *x as f32; let y = *y as f32; @@ -123,7 +129,7 @@ impl DocumentOrShadowRoot { } match self - .nodes_from_point(point, NodesFromPointQueryType::Topmost) + .nodes_from_point(point, NodesFromPointQueryType::Topmost, can_gc) .first() { Some(address) => { @@ -147,6 +153,7 @@ impl DocumentOrShadowRoot { y: Finite<f64>, document_element: Option<DomRoot<Element>>, has_browsing_context: bool, + can_gc: CanGc, ) -> Vec<DomRoot<Element>> { let x = *x as f32; let y = *y as f32; @@ -163,7 +170,7 @@ impl DocumentOrShadowRoot { } // Step 1 and Step 3 - let nodes = self.nodes_from_point(point, NodesFromPointQueryType::All); + let nodes = self.nodes_from_point(point, NodesFromPointQueryType::All, can_gc); let mut elements: Vec<DomRoot<Element>> = nodes .iter() .flat_map(|&untrusted_node_address| { diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 1a429b540b5..2bb4e0b86c0 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -423,18 +423,18 @@ impl Element { /// style will be `None` for elements in a `display: none` subtree. otherwise, the element has a /// layout box iff it doesn't have `display: none`. - pub fn style(&self) -> Option<Arc<ComputedValues>> { - self.upcast::<Node>().style() + pub fn style(&self, can_gc: CanGc) -> Option<Arc<ComputedValues>> { + self.upcast::<Node>().style(can_gc) } // https://drafts.csswg.org/cssom-view/#css-layout-box - pub fn has_css_layout_box(&self) -> bool { - self.style() + pub fn has_css_layout_box(&self, can_gc: CanGc) -> bool { + self.style(can_gc) .is_some_and(|s| !s.get_box().clone_display().is_none()) } // https://drafts.csswg.org/cssom-view/#potentially-scrollable - fn is_potentially_scrollable_body(&self) -> bool { + fn is_potentially_scrollable_body(&self, can_gc: CanGc) -> bool { let node = self.upcast::<Node>(); debug_assert!( node.owner_doc().GetBody().as_deref() == self.downcast::<HTMLElement>(), @@ -444,14 +444,14 @@ impl Element { // "An element body (which will be the body element) is potentially // scrollable if all of the following conditions are true: // - body has an associated box." - if !self.has_css_layout_box() { + if !self.has_css_layout_box(can_gc) { return false; } // " - body’s parent element’s computed value of the overflow-x or // overflow-y properties is neither visible nor clip." if let Some(parent) = node.GetParentElement() { - if let Some(style) = parent.style() { + if let Some(style) = parent.style(can_gc) { if !style.get_box().clone_overflow_x().is_scrollable() && !style.get_box().clone_overflow_y().is_scrollable() { @@ -462,7 +462,7 @@ impl Element { // " - body’s computed value of the overflow-x or overflow-y properties // is neither visible nor clip." - if let Some(style) = self.style() { + if let Some(style) = self.style(can_gc) { if !style.get_box().clone_overflow_x().is_scrollable() && !style.get_box().clone_overflow_y().is_scrollable() { @@ -474,17 +474,18 @@ impl Element { } // https://drafts.csswg.org/cssom-view/#scrolling-box - fn has_scrolling_box(&self) -> bool { + fn has_scrolling_box(&self, can_gc: CanGc) -> bool { // TODO: scrolling mechanism, such as scrollbar (We don't have scrollbar yet) // self.has_scrolling_mechanism() - self.style().is_some_and(|style| { + self.style(can_gc).is_some_and(|style| { style.get_box().clone_overflow_x().is_scrollable() || style.get_box().clone_overflow_y().is_scrollable() }) } - fn has_overflow(&self) -> bool { - self.ScrollHeight() > self.ClientHeight() || self.ScrollWidth() > self.ClientWidth() + fn has_overflow(&self, can_gc: CanGc) -> bool { + self.ScrollHeight(can_gc) > self.ClientHeight(can_gc) || + self.ScrollWidth(can_gc) > self.ClientWidth(can_gc) } fn shadow_root(&self) -> Option<DomRoot<ShadowRoot>> { @@ -1835,7 +1836,7 @@ impl Element { } // https://drafts.csswg.org/cssom-view/#dom-element-scroll - pub fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior) { + pub fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior, can_gc: CanGc) { // Step 1.2 or 2.3 let x = if x_.is_finite() { x_ } else { 0.0f64 }; let y = if y_.is_finite() { y_ } else { 0.0f64 }; @@ -1859,7 +1860,7 @@ impl Element { // Step 7 if *self.root_element() == *self { if doc.quirks_mode() != QuirksMode::Quirks { - win.scroll(x, y, behavior); + win.scroll(x, y, behavior, can_gc); } return; @@ -1868,19 +1869,22 @@ impl Element { // Step 9 if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() && doc.quirks_mode() == QuirksMode::Quirks && - !self.is_potentially_scrollable_body() + !self.is_potentially_scrollable_body(can_gc) { - win.scroll(x, y, behavior); + win.scroll(x, y, behavior, can_gc); return; } // Step 10 - if !self.has_css_layout_box() || !self.has_scrolling_box() || !self.has_overflow() { + if !self.has_css_layout_box(can_gc) || + !self.has_scrolling_box(can_gc) || + !self.has_overflow(can_gc) + { return; } // Step 11 - win.scroll_node(node, x, y, behavior); + win.scroll_node(node, x, y, behavior, can_gc); } // https://w3c.github.io/DOM-Parsing/#parsing @@ -2343,7 +2347,7 @@ impl ElementMethods for Element { // https://drafts.csswg.org/cssom-view/#dom-element-getclientrects fn GetClientRects(&self, can_gc: CanGc) -> Vec<DomRoot<DOMRect>> { let win = window_from_node(self); - let raw_rects = self.upcast::<Node>().content_boxes(); + let raw_rects = self.upcast::<Node>().content_boxes(can_gc); raw_rects .iter() .map(|rect| { @@ -2362,7 +2366,7 @@ impl ElementMethods for Element { // https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect fn GetBoundingClientRect(&self, can_gc: CanGc) -> DomRoot<DOMRect> { let win = window_from_node(self); - let rect = self.upcast::<Node>().bounding_content_box_or_zero(); + let rect = self.upcast::<Node>().bounding_content_box_or_zero(can_gc); DOMRect::new( win.upcast(), rect.origin.x.to_f64_px(), @@ -2374,47 +2378,52 @@ impl ElementMethods for Element { } // https://drafts.csswg.org/cssom-view/#dom-element-scroll - fn Scroll(&self, options: &ScrollToOptions) { + fn Scroll(&self, options: &ScrollToOptions, can_gc: CanGc) { // Step 1 - let left = options.left.unwrap_or(self.ScrollLeft()); - let top = options.top.unwrap_or(self.ScrollTop()); - self.scroll(left, top, options.parent.behavior); + let left = options.left.unwrap_or(self.ScrollLeft(can_gc)); + let top = options.top.unwrap_or(self.ScrollTop(can_gc)); + self.scroll(left, top, options.parent.behavior, can_gc); } // https://drafts.csswg.org/cssom-view/#dom-element-scroll - fn Scroll_(&self, x: f64, y: f64) { - self.scroll(x, y, ScrollBehavior::Auto); + fn Scroll_(&self, x: f64, y: f64, can_gc: CanGc) { + self.scroll(x, y, ScrollBehavior::Auto, can_gc); } // https://drafts.csswg.org/cssom-view/#dom-element-scrollto fn ScrollTo(&self, options: &ScrollToOptions) { - self.Scroll(options); + self.Scroll(options, CanGc::note()); } // https://drafts.csswg.org/cssom-view/#dom-element-scrollto fn ScrollTo_(&self, x: f64, y: f64) { - self.Scroll_(x, y); + self.Scroll_(x, y, CanGc::note()); } // https://drafts.csswg.org/cssom-view/#dom-element-scrollby - fn ScrollBy(&self, options: &ScrollToOptions) { + fn ScrollBy(&self, options: &ScrollToOptions, can_gc: CanGc) { // Step 2 let delta_left = options.left.unwrap_or(0.0f64); let delta_top = options.top.unwrap_or(0.0f64); - let left = self.ScrollLeft(); - let top = self.ScrollTop(); - self.scroll(left + delta_left, top + delta_top, options.parent.behavior); + let left = self.ScrollLeft(can_gc); + let top = self.ScrollTop(can_gc); + self.scroll( + left + delta_left, + top + delta_top, + options.parent.behavior, + can_gc, + ); } // https://drafts.csswg.org/cssom-view/#dom-element-scrollby - fn ScrollBy_(&self, x: f64, y: f64) { - let left = self.ScrollLeft(); - let top = self.ScrollTop(); - self.scroll(left + x, top + y, ScrollBehavior::Auto); + fn ScrollBy_(&self, x: f64, y: f64, can_gc: CanGc) { + let left = self.ScrollLeft(can_gc); + let top = self.ScrollTop(can_gc); + self.scroll(left + x, top + y, ScrollBehavior::Auto, can_gc); } // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop - fn ScrollTop(&self) -> f64 { + fn ScrollTop(&self, can_gc: CanGc) -> f64 { let node = self.upcast::<Node>(); // Step 1 @@ -2444,13 +2453,13 @@ impl ElementMethods for Element { // Step 7 if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() && doc.quirks_mode() == QuirksMode::Quirks && - !self.is_potentially_scrollable_body() + !self.is_potentially_scrollable_body(can_gc) { return win.ScrollY() as f64; } // Step 8 - if !self.has_css_layout_box() { + if !self.has_css_layout_box(can_gc) { return 0.0; } @@ -2460,7 +2469,7 @@ impl ElementMethods for Element { } // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop - fn SetScrollTop(&self, y_: f64) { + fn SetScrollTop(&self, y_: f64, can_gc: CanGc) { let behavior = ScrollBehavior::Auto; // Step 1, 2 @@ -2485,7 +2494,7 @@ impl ElementMethods for Element { // Step 7 if *self.root_element() == *self { if doc.quirks_mode() != QuirksMode::Quirks { - win.scroll(win.ScrollX() as f64, y, behavior); + win.scroll(win.ScrollX() as f64, y, behavior, can_gc); } return; @@ -2494,23 +2503,26 @@ impl ElementMethods for Element { // Step 9 if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() && doc.quirks_mode() == QuirksMode::Quirks && - !self.is_potentially_scrollable_body() + !self.is_potentially_scrollable_body(can_gc) { - win.scroll(win.ScrollX() as f64, y, behavior); + win.scroll(win.ScrollX() as f64, y, behavior, can_gc); return; } // Step 10 - if !self.has_css_layout_box() || !self.has_scrolling_box() || !self.has_overflow() { + if !self.has_css_layout_box(can_gc) || + !self.has_scrolling_box(can_gc) || + !self.has_overflow(can_gc) + { return; } // Step 11 - win.scroll_node(node, self.ScrollLeft(), y, behavior); + win.scroll_node(node, self.ScrollLeft(can_gc), y, behavior, can_gc); } // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop - fn ScrollLeft(&self) -> f64 { + fn ScrollLeft(&self, can_gc: CanGc) -> f64 { let node = self.upcast::<Node>(); // Step 1 @@ -2540,13 +2552,13 @@ impl ElementMethods for Element { // Step 7 if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() && doc.quirks_mode() == QuirksMode::Quirks && - !self.is_potentially_scrollable_body() + !self.is_potentially_scrollable_body(can_gc) { return win.ScrollX() as f64; } // Step 8 - if !self.has_css_layout_box() { + if !self.has_css_layout_box(can_gc) { return 0.0; } @@ -2556,7 +2568,7 @@ impl ElementMethods for Element { } // https://drafts.csswg.org/cssom-view/#dom-element-scrollleft - fn SetScrollLeft(&self, x_: f64) { + fn SetScrollLeft(&self, x_: f64, can_gc: CanGc) { let behavior = ScrollBehavior::Auto; // Step 1, 2 @@ -2584,56 +2596,59 @@ impl ElementMethods for Element { return; } - win.scroll(x, win.ScrollY() as f64, behavior); + win.scroll(x, win.ScrollY() as f64, behavior, can_gc); return; } // Step 9 if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() && doc.quirks_mode() == QuirksMode::Quirks && - !self.is_potentially_scrollable_body() + !self.is_potentially_scrollable_body(can_gc) { - win.scroll(x, win.ScrollY() as f64, behavior); + win.scroll(x, win.ScrollY() as f64, behavior, can_gc); return; } // Step 10 - if !self.has_css_layout_box() || !self.has_scrolling_box() || !self.has_overflow() { + if !self.has_css_layout_box(can_gc) || + !self.has_scrolling_box(can_gc) || + !self.has_overflow(can_gc) + { return; } // Step 11 - win.scroll_node(node, x, self.ScrollTop(), behavior); + win.scroll_node(node, x, self.ScrollTop(can_gc), behavior, can_gc); } // https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth - fn ScrollWidth(&self) -> i32 { - self.upcast::<Node>().scroll_area().size.width + fn ScrollWidth(&self, can_gc: CanGc) -> i32 { + self.upcast::<Node>().scroll_area(can_gc).size.width } // https://drafts.csswg.org/cssom-view/#dom-element-scrollheight - fn ScrollHeight(&self) -> i32 { - self.upcast::<Node>().scroll_area().size.height + fn ScrollHeight(&self, can_gc: CanGc) -> i32 { + self.upcast::<Node>().scroll_area(can_gc).size.height } // https://drafts.csswg.org/cssom-view/#dom-element-clienttop - fn ClientTop(&self) -> i32 { - self.client_rect().origin.y + fn ClientTop(&self, can_gc: CanGc) -> i32 { + self.client_rect(can_gc).origin.y } // https://drafts.csswg.org/cssom-view/#dom-element-clientleft - fn ClientLeft(&self) -> i32 { - self.client_rect().origin.x + fn ClientLeft(&self, can_gc: CanGc) -> i32 { + self.client_rect(can_gc).origin.x } // https://drafts.csswg.org/cssom-view/#dom-element-clientwidth - fn ClientWidth(&self) -> i32 { - self.client_rect().size.width + fn ClientWidth(&self, can_gc: CanGc) -> i32 { + self.client_rect(can_gc).size.width } // https://drafts.csswg.org/cssom-view/#dom-element-clientheight - fn ClientHeight(&self) -> i32 { - self.client_rect().size.height + fn ClientHeight(&self, can_gc: CanGc) -> i32 { + self.client_rect(can_gc).size.height } /// <https://w3c.github.io/DOM-Parsing/#widl-Element-innerHTML> @@ -3850,7 +3865,7 @@ impl SelectorsElement for DomRoot<Element> { } impl Element { - fn client_rect(&self) -> Rect<i32> { + fn client_rect(&self, can_gc: CanGc) -> Rect<i32> { let doc = self.node.owner_doc(); if let Some(rect) = self @@ -3867,7 +3882,7 @@ impl Element { } } - let mut rect = self.upcast::<Node>().client_rect(); + let mut rect = self.upcast::<Node>().client_rect(can_gc); let in_quirks_mode = doc.quirks_mode() == QuirksMode::Quirks; if (in_quirks_mode && doc.GetBody().as_deref() == self.downcast::<HTMLElement>()) || @@ -4329,9 +4344,11 @@ impl TaskOnce for ElementPerformFullscreenEnter { // Step 7.5 element.set_fullscreen_state(true); document.set_fullscreen_element(Some(&element)); - document - .window() - .reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged); + document.window().reflow( + ReflowGoal::Full, + ReflowReason::ElementStateChanged, + CanGc::note(), + ); // Step 7.6 document @@ -4366,9 +4383,11 @@ impl TaskOnce for ElementPerformFullscreenExit { // Step 9.6 element.set_fullscreen_state(false); - document - .window() - .reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged); + document.window().reflow( + ReflowGoal::Full, + ReflowReason::ElementStateChanged, + CanGc::note(), + ); document.set_fullscreen_element(None); diff --git a/components/script/dom/fontfaceset.rs b/components/script/dom/fontfaceset.rs index d9b05b29e60..fa2fae410d4 100644 --- a/components/script/dom/fontfaceset.rs +++ b/components/script/dom/fontfaceset.rs @@ -31,12 +31,12 @@ impl FontFaceSet { } } - pub fn new(global: &GlobalScope, proto: Option<HandleObject>) -> DomRoot<Self> { + pub fn new(global: &GlobalScope, proto: Option<HandleObject>, can_gc: CanGc) -> DomRoot<Self> { reflect_dom_object_with_proto( Box::new(FontFaceSet::new_inherited(global)), global, proto, - CanGc::note(), + can_gc, ) } diff --git a/components/script/dom/history.rs b/components/script/dom/history.rs index 47f1a983240..d53dbbffb60 100644 --- a/components/script/dom/history.rs +++ b/components/script/dom/history.rs @@ -94,7 +94,7 @@ impl History { // Step 8 if let Some(fragment) = url.fragment() { - document.check_and_scroll_fragment(fragment); + document.check_and_scroll_fragment(fragment, can_gc); } // Step 11 diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index 109c9751f7c..a38195030c0 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -604,7 +604,7 @@ impl Activatable for HTMLAnchorElement { if let Some(element) = target.downcast::<Element>() { if target.is::<HTMLImageElement>() && element.has_attribute(&local_name!("ismap")) { let target_node = element.upcast::<Node>(); - let rect = target_node.bounding_content_box_or_zero(); + let rect = target_node.bounding_content_box_or_zero(CanGc::note()); ismap_suffix = Some(format!( "?{},{}", mouse_event.ClientX().to_f32().unwrap() - rect.origin.x.to_f32_px(), diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs index 485f2a8ecde..485f2a8ecde 100755..100644 --- a/components/script/dom/htmlbuttonelement.rs +++ b/components/script/dom/htmlbuttonelement.rs diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index 7b68df015cc..d6f63e3ef72 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -113,18 +113,18 @@ impl HTMLElement { /// `.outerText` in JavaScript.` /// /// <https://html.spec.whatwg.org/multipage/#get-the-text-steps> - fn get_inner_outer_text(&self) -> DOMString { + fn get_inner_outer_text(&self, can_gc: CanGc) -> DOMString { let node = self.upcast::<Node>(); let window = window_from_node(node); let element = self.as_element(); // Step 1. - let element_not_rendered = !node.is_connected() || !element.has_css_layout_box(); + let element_not_rendered = !node.is_connected() || !element.has_css_layout_box(can_gc); if element_not_rendered { return node.GetTextContent().unwrap(); } - window.layout_reflow(QueryMsg::ElementInnerOuterTextQuery); + window.layout_reflow(QueryMsg::ElementInnerOuterTextQuery, can_gc); let text = window .layout() .query_element_inner_outer_text(node.to_trusted_node_address()); @@ -419,65 +419,65 @@ impl HTMLElementMethods for HTMLElement { } // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent - fn GetOffsetParent(&self) -> Option<DomRoot<Element>> { + fn GetOffsetParent(&self, can_gc: CanGc) -> Option<DomRoot<Element>> { if self.is::<HTMLBodyElement>() || self.is::<HTMLHtmlElement>() { return None; } let node = self.upcast::<Node>(); let window = window_from_node(self); - let (element, _) = window.offset_parent_query(node); + let (element, _) = window.offset_parent_query(node, can_gc); element } // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsettop - fn OffsetTop(&self) -> i32 { + fn OffsetTop(&self, can_gc: CanGc) -> i32 { if self.is::<HTMLBodyElement>() { return 0; } let node = self.upcast::<Node>(); let window = window_from_node(self); - let (_, rect) = window.offset_parent_query(node); + let (_, rect) = window.offset_parent_query(node, can_gc); rect.origin.y.to_nearest_px() } // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetleft - fn OffsetLeft(&self) -> i32 { + fn OffsetLeft(&self, can_gc: CanGc) -> i32 { if self.is::<HTMLBodyElement>() { return 0; } let node = self.upcast::<Node>(); let window = window_from_node(self); - let (_, rect) = window.offset_parent_query(node); + let (_, rect) = window.offset_parent_query(node, can_gc); rect.origin.x.to_nearest_px() } // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetwidth - fn OffsetWidth(&self) -> i32 { + fn OffsetWidth(&self, can_gc: CanGc) -> i32 { let node = self.upcast::<Node>(); let window = window_from_node(self); - let (_, rect) = window.offset_parent_query(node); + let (_, rect) = window.offset_parent_query(node, can_gc); rect.size.width.to_nearest_px() } // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetheight - fn OffsetHeight(&self) -> i32 { + fn OffsetHeight(&self, can_gc: CanGc) -> i32 { let node = self.upcast::<Node>(); let window = window_from_node(self); - let (_, rect) = window.offset_parent_query(node); + let (_, rect) = window.offset_parent_query(node, can_gc); rect.size.height.to_nearest_px() } /// <https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute> - fn InnerText(&self) -> DOMString { - self.get_inner_outer_text() + fn InnerText(&self, can_gc: CanGc) -> DOMString { + self.get_inner_outer_text(can_gc) } /// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps> @@ -491,8 +491,8 @@ impl HTMLElementMethods for HTMLElement { } /// <https://html.spec.whatwg.org/multipage/#dom-outertext> - fn GetOuterText(&self) -> Fallible<DOMString> { - Ok(self.get_inner_outer_text()) + fn GetOuterText(&self, can_gc: CanGc) -> Fallible<DOMString> { + Ok(self.get_inner_outer_text(can_gc)) } /// <https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute:dom-outertext-2> diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 1f391225357..c62e28aca71 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -193,7 +193,7 @@ impl HTMLIFrameElement { let window_size = WindowSizeData { initial_viewport: window - .inner_window_dimensions_query(browsing_context_id) + .inner_window_dimensions_query(browsing_context_id, can_gc) .unwrap_or_default(), device_pixel_ratio: window.device_pixel_ratio(), }; diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 6280f4b32b8..33f907d9985 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -1596,9 +1596,9 @@ impl HTMLImageElementMethods for HTMLImageElement { make_bool_setter!(SetIsMap, "ismap"); // https://html.spec.whatwg.org/multipage/#dom-img-width - fn Width(&self) -> u32 { + fn Width(&self, can_gc: CanGc) -> u32 { let node = self.upcast::<Node>(); - match node.bounding_content_box() { + match node.bounding_content_box(can_gc) { Some(rect) => rect.size.width.to_px() as u32, None => self.NaturalWidth(), } @@ -1610,9 +1610,9 @@ impl HTMLImageElementMethods for HTMLImageElement { } // https://html.spec.whatwg.org/multipage/#dom-img-height - fn Height(&self) -> u32 { + fn Height(&self, can_gc: CanGc) -> u32 { let node = self.upcast::<Node>(); - match node.bounding_content_box() { + match node.bounding_content_box(can_gc) { Some(rect) => rect.size.height.to_px() as u32, None => self.NaturalHeight(), } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 66e5b036f86..c1bf932350f 100755..100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -2517,7 +2517,11 @@ impl VirtualMethods for HTMLInputElement { // now. if let Some(point_in_target) = mouse_event.point_in_target() { let window = window_from_node(self); - let index = window.text_index_query(self.upcast::<Node>(), point_in_target); + let index = window.text_index_query( + self.upcast::<Node>(), + point_in_target, + CanGc::note(), + ); if let Some(i) = index { self.textinput.borrow_mut().set_edit_point_index(i); // trigger redraw diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs index 0518bdbab2c..0518bdbab2c 100755..100644 --- a/components/script/dom/htmlobjectelement.rs +++ b/components/script/dom/htmlobjectelement.rs diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index 7c53abfd17b..7c53abfd17b 100755..100644 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index dc1158775ba..dc1158775ba 100755..100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs index 5bab3406d2f..ceea0f5c46e 100644 --- a/components/script/dom/mouseevent.rs +++ b/components/script/dom/mouseevent.rs @@ -276,13 +276,13 @@ impl MouseEventMethods for MouseEvent { } // https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx - fn OffsetX(&self) -> i32 { + fn OffsetX(&self, can_gc: CanGc) -> i32 { let event = self.upcast::<Event>(); if event.dispatching() { match event.GetTarget() { Some(target) => { if let Some(node) = target.downcast::<Node>() { - let rect = node.client_rect(); + let rect = node.client_rect(can_gc); self.client_x.get() - rect.origin.x } else { self.offset_x.get() @@ -296,13 +296,13 @@ impl MouseEventMethods for MouseEvent { } // https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsety - fn OffsetY(&self) -> i32 { + fn OffsetY(&self, can_gc: CanGc) -> i32 { let event = self.upcast::<Event>(); if event.dispatching() { match event.GetTarget() { Some(target) => { if let Some(node) = target.downcast::<Node>() { - let rect = node.client_rect(); + let rect = node.client_rect(can_gc); self.client_y.get() - rect.origin.y } else { self.offset_y.get() diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 89876e8b3d9..4851728803e 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -793,25 +793,25 @@ impl Node { /// Returns the rendered bounding content box if the element is rendered, /// and none otherwise. - pub fn bounding_content_box(&self) -> Option<Rect<Au>> { - window_from_node(self).content_box_query(self) + pub fn bounding_content_box(&self, can_gc: CanGc) -> Option<Rect<Au>> { + window_from_node(self).content_box_query(self, can_gc) } - pub fn bounding_content_box_or_zero(&self) -> Rect<Au> { - self.bounding_content_box().unwrap_or_else(Rect::zero) + pub fn bounding_content_box_or_zero(&self, can_gc: CanGc) -> Rect<Au> { + self.bounding_content_box(can_gc).unwrap_or_else(Rect::zero) } - pub fn content_boxes(&self) -> Vec<Rect<Au>> { - window_from_node(self).content_boxes_query(self) + pub fn content_boxes(&self, can_gc: CanGc) -> Vec<Rect<Au>> { + window_from_node(self).content_boxes_query(self, can_gc) } - pub fn client_rect(&self) -> Rect<i32> { - window_from_node(self).client_rect_query(self) + pub fn client_rect(&self, can_gc: CanGc) -> Rect<i32> { + window_from_node(self).client_rect_query(self, can_gc) } /// <https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth> /// <https://drafts.csswg.org/cssom-view/#dom-element-scrollheight> - pub fn scroll_area(&self) -> Rect<i32> { + pub fn scroll_area(&self, can_gc: CanGc) -> Rect<i32> { // "1. Let document be the element’s node document."" let document = self.owner_doc(); @@ -837,7 +837,7 @@ impl Node { // element is not potentially scrollable, return max(viewport scrolling area // width, viewport width)." if (is_root && !in_quirks_mode) || (is_body_element && in_quirks_mode) { - let viewport_scrolling_area = window.scrolling_area_query(None); + let viewport_scrolling_area = window.scrolling_area_query(None, can_gc); return Rect::new( viewport_scrolling_area.origin, viewport_scrolling_area.size.max(viewport), @@ -847,7 +847,7 @@ impl Node { // "6. If the element does not have any associated box return zero and terminate // these steps." // "7. Return the width of the element’s scrolling area." - window.scrolling_area_query(Some(self)) + window.scrolling_area_query(Some(self), can_gc) } pub fn scroll_offset(&self) -> Vector2D<f32> { @@ -1270,8 +1270,8 @@ impl Node { }) } - pub fn style(&self) -> Option<Arc<ComputedValues>> { - if !window_from_node(self).layout_reflow(QueryMsg::StyleQuery) { + pub fn style(&self, can_gc: CanGc) -> Option<Arc<ComputedValues>> { + if !window_from_node(self).layout_reflow(QueryMsg::StyleQuery, can_gc) { return None; } self.style_data diff --git a/components/script/dom/offscreencanvasrenderingcontext2d.rs b/components/script/dom/offscreencanvasrenderingcontext2d.rs index a7e8ceeb209..23ed19b33e9 100644 --- a/components/script/dom/offscreencanvasrenderingcontext2d.rs +++ b/components/script/dom/offscreencanvasrenderingcontext2d.rs @@ -140,9 +140,9 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex } // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor - fn SetShadowColor(&self, value: DOMString) { + fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) { self.canvas_state - .set_shadow_color(self.htmlcanvas.as_deref(), value) + .set_shadow_color(self.htmlcanvas.as_deref(), value, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle @@ -151,9 +151,9 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { + fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { self.canvas_state - .set_stroke_style(self.htmlcanvas.as_deref(), value) + .set_stroke_style(self.htmlcanvas.as_deref(), value, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle @@ -162,9 +162,9 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { + fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { self.canvas_state - .set_fill_style(self.htmlcanvas.as_deref(), value) + .set_fill_style(self.htmlcanvas.as_deref(), value, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient @@ -250,15 +250,15 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex } // https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext - fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>) { + fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>, can_gc: CanGc) { self.canvas_state - .fill_text(self.htmlcanvas.as_deref(), text, x, y, max_width) + .fill_text(self.htmlcanvas.as_deref(), text, x, y, max_width, can_gc) } // https://html.spec.whatwg.org/multipage/#textmetrics - fn MeasureText(&self, text: DOMString) -> DomRoot<TextMetrics> { + fn MeasureText(&self, text: DOMString, can_gc: CanGc) -> DomRoot<TextMetrics> { self.canvas_state - .measure_text(&self.global(), self.htmlcanvas.as_deref(), text) + .measure_text(&self.global(), self.htmlcanvas.as_deref(), text, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-font @@ -267,9 +267,9 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex } // https://html.spec.whatwg.org/multipage/#dom-context-2d-font - fn SetFont(&self, value: DOMString) { + fn SetFont(&self, value: DOMString, can_gc: CanGc) { self.canvas_state - .set_font(self.htmlcanvas.as_deref(), value) + .set_font(self.htmlcanvas.as_deref(), value, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign diff --git a/components/script/dom/paintrenderingcontext2d.rs b/components/script/dom/paintrenderingcontext2d.rs index 9b867e80682..95c005dff30 100644 --- a/components/script/dom/paintrenderingcontext2d.rs +++ b/components/script/dom/paintrenderingcontext2d.rs @@ -304,8 +304,8 @@ impl PaintRenderingContext2DMethods for PaintRenderingContext2D { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { - self.context.SetStrokeStyle(value) + fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { + self.context.SetStrokeStyle(value, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle @@ -314,8 +314,8 @@ impl PaintRenderingContext2DMethods for PaintRenderingContext2D { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { - self.context.SetFillStyle(value) + fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { + self.context.SetFillStyle(value, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient @@ -427,7 +427,7 @@ impl PaintRenderingContext2DMethods for PaintRenderingContext2D { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor - fn SetShadowColor(&self, value: DOMString) { - self.context.SetShadowColor(value) + fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) { + self.context.SetShadowColor(value, can_gc) } } diff --git a/components/script/dom/resizeobserver.rs b/components/script/dom/resizeobserver.rs index 244c0adecc4..31e111cb2ad 100644 --- a/components/script/dom/resizeobserver.rs +++ b/components/script/dom/resizeobserver.rs @@ -75,10 +75,11 @@ impl ResizeObserver { &self, depth: &ResizeObservationDepth, has_active: &mut bool, + can_gc: CanGc, ) { for (observation, target) in self.observation_targets.borrow_mut().iter_mut() { observation.state = Default::default(); - if let Some(size) = observation.is_active(target) { + if let Some(size) = observation.is_active(target, can_gc) { let target_depth = calculate_depth_for_node(target); if target_depth > *depth { observation.state = ObservationState::Active(size).into(); @@ -251,9 +252,9 @@ impl ResizeObservation { /// <https://drafts.csswg.org/resize-observer/#dom-resizeobservation-isactive> /// Returning an optional calculated size, instead of a boolean, /// to avoid recalculating the size in the subsequent broadcast. - fn is_active(&self, target: &Element) -> Option<Rect<Au>> { + fn is_active(&self, target: &Element, can_gc: CanGc) -> Option<Rect<Au>> { let last_reported_size = self.last_reported_sizes.borrow()[0]; - let box_size = calculate_box_size(target, &self.observed_box.borrow()); + let box_size = calculate_box_size(target, &self.observed_box.borrow(), can_gc); let is_active = box_size.width().to_f64_px() != last_reported_size.inline_size() || box_size.height().to_f64_px() != last_reported_size.block_size(); if is_active { @@ -272,14 +273,18 @@ fn calculate_depth_for_node(target: &Element) -> ResizeObservationDepth { } /// <https://drafts.csswg.org/resize-observer/#calculate-box-size> -fn calculate_box_size(target: &Element, observed_box: &ResizeObserverBoxOptions) -> Rect<Au> { +fn calculate_box_size( + target: &Element, + observed_box: &ResizeObserverBoxOptions, + can_gc: CanGc, +) -> Rect<Au> { match observed_box { ResizeObserverBoxOptions::Content_box => { // Note: only taking first fragment, // but the spec will expand to cover all fragments. target .upcast::<Node>() - .content_boxes() + .content_boxes(can_gc) .pop() .unwrap_or_else(Rect::zero) }, diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index bd21a90c91b..17fddca3b87 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -588,7 +588,7 @@ impl ServoParser { assert!(!self.suspended.get()); assert!(!self.aborted.get()); - self.document.reflow_if_reflow_timer_expired(); + self.document.reflow_if_reflow_timer_expired(can_gc); let script = match feed(&self.tokenizer) { TokenizerResult::Done => return, TokenizerResult::Script(script) => script, diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs index 586fd1da22b..1db7f44ff63 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -26,6 +26,7 @@ use crate::dom::element::Element; use crate::dom::node::{Node, NodeDamage, NodeFlags, ShadowIncluding, UnbindContext}; use crate::dom::stylesheetlist::{StyleSheetList, StyleSheetListOwner}; use crate::dom::window::Window; +use crate::script_runtime::CanGc; use crate::stylesheet_set::StylesheetSetRef; /// Whether a shadow root hosts an User Agent widget. @@ -177,7 +178,12 @@ impl ShadowRootMethods for ShadowRoot { } // https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint - fn ElementFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Option<DomRoot<Element>> { + fn ElementFromPoint( + &self, + x: Finite<f64>, + y: Finite<f64>, + can_gc: CanGc, + ) -> Option<DomRoot<Element>> { // Return the result of running the retargeting algorithm with context object // and the original result as input. match self.document_or_shadow_root.element_from_point( @@ -185,6 +191,7 @@ impl ShadowRootMethods for ShadowRoot { y, None, self.document.has_browsing_context(), + can_gc, ) { Some(e) => { let retargeted_node = self.upcast::<Node>().retarget(e.upcast::<Node>()); @@ -195,13 +202,18 @@ impl ShadowRootMethods for ShadowRoot { } // https://drafts.csswg.org/cssom-view/#dom-document-elementsfrompoint - fn ElementsFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Vec<DomRoot<Element>> { + fn ElementsFromPoint( + &self, + x: Finite<f64>, + y: Finite<f64>, + can_gc: CanGc, + ) -> Vec<DomRoot<Element>> { // Return the result of running the retargeting algorithm with context object // and the original result as input let mut elements = Vec::new(); for e in self .document_or_shadow_root - .elements_from_point(x, y, None, self.document.has_browsing_context()) + .elements_from_point(x, y, None, self.document.has_browsing_context(), can_gc) .iter() { let retargeted_node = self.upcast::<Node>().retarget(e.upcast::<Node>()); diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 6f4b7152233..b0475a8a6df 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -1196,46 +1196,46 @@ impl WindowMethods for Window { } // https://drafts.csswg.org/cssom-view/#dom-window-scroll - fn Scroll(&self, options: &ScrollToOptions) { + fn Scroll(&self, options: &ScrollToOptions, can_gc: CanGc) { // Step 1 let left = options.left.unwrap_or(0.0f64); let top = options.top.unwrap_or(0.0f64); - self.scroll(left, top, options.parent.behavior); + self.scroll(left, top, options.parent.behavior, can_gc); } // https://drafts.csswg.org/cssom-view/#dom-window-scroll - fn Scroll_(&self, x: f64, y: f64) { - self.scroll(x, y, ScrollBehavior::Auto); + fn Scroll_(&self, x: f64, y: f64, can_gc: CanGc) { + self.scroll(x, y, ScrollBehavior::Auto, can_gc); } // https://drafts.csswg.org/cssom-view/#dom-window-scrollto fn ScrollTo(&self, options: &ScrollToOptions) { - self.Scroll(options); + self.Scroll(options, CanGc::note()); } // https://drafts.csswg.org/cssom-view/#dom-window-scrollto fn ScrollTo_(&self, x: f64, y: f64) { - self.scroll(x, y, ScrollBehavior::Auto); + self.scroll(x, y, ScrollBehavior::Auto, CanGc::note()); } // https://drafts.csswg.org/cssom-view/#dom-window-scrollby - fn ScrollBy(&self, options: &ScrollToOptions) { + fn ScrollBy(&self, options: &ScrollToOptions, can_gc: CanGc) { // Step 1 let x = options.left.unwrap_or(0.0f64); let y = options.top.unwrap_or(0.0f64); - self.ScrollBy_(x, y); - self.scroll(x, y, options.parent.behavior); + self.ScrollBy_(x, y, can_gc); + self.scroll(x, y, options.parent.behavior, can_gc); } // https://drafts.csswg.org/cssom-view/#dom-window-scrollby - fn ScrollBy_(&self, x: f64, y: f64) { + fn ScrollBy_(&self, x: f64, y: f64, can_gc: CanGc) { // Step 3 let left = x + self.ScrollX() as f64; // Step 4 let top = y + self.ScrollY() as f64; // Step 5 - self.scroll(left, top, ScrollBehavior::Auto); + self.scroll(left, top, ScrollBehavior::Auto, can_gc); } // https://drafts.csswg.org/cssom-view/#dom-window-resizeto @@ -1700,7 +1700,7 @@ impl Window { } /// <https://drafts.csswg.org/cssom-view/#dom-window-scroll> - pub fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior) { + pub fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior, can_gc: CanGc) { // Step 3 let xfinite = if x_.is_finite() { x_ } else { 0.0f64 }; let yfinite = if y_.is_finite() { y_ } else { 0.0f64 }; @@ -1713,7 +1713,7 @@ impl Window { // Step 7 & 8 // TODO: Consider `block-end` and `inline-end` overflow direction. - let scrolling_area = self.scrolling_area_query(None); + let scrolling_area = self.scrolling_area_query(None, can_gc); let x = xfinite .min(scrolling_area.width() as f64 - viewport.width as f64) .max(0.0f64); @@ -1739,6 +1739,7 @@ impl Window { self.upcast::<GlobalScope>().pipeline_id().root_scroll_id(), behavior, None, + can_gc, ); } @@ -1750,6 +1751,7 @@ impl Window { scroll_id: ExternalScrollId, _behavior: ScrollBehavior, _element: Option<&Element>, + can_gc: CanGc, ) { // TODO Step 1 // TODO(mrobinson, #18709): Add smooth scrolling support to WebRender so that we can @@ -1760,6 +1762,7 @@ impl Window { scroll_offset: Vector2D::new(-x, -y), }), ReflowReason::ScrollFromScript, + can_gc, ); } @@ -1960,7 +1963,7 @@ impl Window { /// that layout might hold if the first layout hasn't happened yet (which /// may happen in the only case a query reflow may bail out, that is, if the /// viewport size is not present). See #11223 for an example of that. - pub fn reflow(&self, reflow_goal: ReflowGoal, reason: ReflowReason) -> bool { + pub fn reflow(&self, reflow_goal: ReflowGoal, reason: ReflowReason, can_gc: CanGc) -> bool { // Fetch the pending web fonts before layout, in case a font loads during // the layout. let pending_web_fonts = self.layout.borrow().waiting_for_web_fonts_to_load(); @@ -1994,7 +1997,7 @@ impl Window { } let document = self.Document(); - let font_face_set = document.Fonts(); + let font_face_set = document.Fonts(can_gc); let is_ready_state_complete = document.ReadyState() == DocumentReadyState::Complete; // From https://drafts.csswg.org/css-font-loading/#font-face-set-ready: @@ -2069,12 +2072,21 @@ impl Window { receiver.recv().unwrap(); } - pub fn layout_reflow(&self, query_msg: QueryMsg) -> bool { - self.reflow(ReflowGoal::LayoutQuery(query_msg), ReflowReason::Query) + pub fn layout_reflow(&self, query_msg: QueryMsg, can_gc: CanGc) -> bool { + self.reflow( + ReflowGoal::LayoutQuery(query_msg), + ReflowReason::Query, + can_gc, + ) } - pub fn resolved_font_style_query(&self, node: &Node, value: String) -> Option<ServoArc<Font>> { - if !self.layout_reflow(QueryMsg::ResolvedFontStyleQuery) { + pub fn resolved_font_style_query( + &self, + node: &Node, + value: String, + can_gc: CanGc, + ) -> Option<ServoArc<Font>> { + if !self.layout_reflow(QueryMsg::ResolvedFontStyleQuery, can_gc) { return None; } @@ -2088,22 +2100,22 @@ impl Window { ) } - pub fn content_box_query(&self, node: &Node) -> Option<UntypedRect<Au>> { - if !self.layout_reflow(QueryMsg::ContentBox) { + pub fn content_box_query(&self, node: &Node, can_gc: CanGc) -> Option<UntypedRect<Au>> { + if !self.layout_reflow(QueryMsg::ContentBox, can_gc) { return None; } self.layout.borrow().query_content_box(node.to_opaque()) } - pub fn content_boxes_query(&self, node: &Node) -> Vec<UntypedRect<Au>> { - if !self.layout_reflow(QueryMsg::ContentBoxes) { + pub fn content_boxes_query(&self, node: &Node, can_gc: CanGc) -> Vec<UntypedRect<Au>> { + if !self.layout_reflow(QueryMsg::ContentBoxes, can_gc) { return vec![]; } self.layout.borrow().query_content_boxes(node.to_opaque()) } - pub fn client_rect_query(&self, node: &Node) -> UntypedRect<i32> { - if !self.layout_reflow(QueryMsg::ClientRectQuery) { + pub fn client_rect_query(&self, node: &Node, can_gc: CanGc) -> UntypedRect<i32> { + if !self.layout_reflow(QueryMsg::ClientRectQuery, can_gc) { return Rect::zero(); } self.layout.borrow().query_client_rect(node.to_opaque()) @@ -2111,9 +2123,9 @@ impl Window { /// Find the scroll area of the given node, if it is not None. If the node /// is None, find the scroll area of the viewport. - pub fn scrolling_area_query(&self, node: Option<&Node>) -> UntypedRect<i32> { + pub fn scrolling_area_query(&self, node: Option<&Node>, can_gc: CanGc) -> UntypedRect<i32> { let opaque = node.map(|node| node.to_opaque()); - if !self.layout_reflow(QueryMsg::ScrollingAreaQuery) { + if !self.layout_reflow(QueryMsg::ScrollingAreaQuery, can_gc) { return Rect::zero(); } self.layout.borrow().query_scrolling_area(opaque) @@ -2127,7 +2139,14 @@ impl Window { } // https://drafts.csswg.org/cssom-view/#element-scrolling-members - pub fn scroll_node(&self, node: &Node, x_: f64, y_: f64, behavior: ScrollBehavior) { + pub fn scroll_node( + &self, + node: &Node, + x_: f64, + y_: f64, + behavior: ScrollBehavior, + can_gc: CanGc, + ) { // The scroll offsets are immediatly updated since later calls // to topScroll and others may access the properties before // webrender has a chance to update the offsets. @@ -2146,6 +2165,7 @@ impl Window { scroll_id, behavior, None, + can_gc, ); } @@ -2154,8 +2174,9 @@ impl Window { element: TrustedNodeAddress, pseudo: Option<PseudoElement>, property: PropertyId, + can_gc: CanGc, ) -> DOMString { - if !self.layout_reflow(QueryMsg::ResolvedStyleQuery) { + if !self.layout_reflow(QueryMsg::ResolvedStyleQuery, can_gc) { return DOMString::new(); } @@ -2173,8 +2194,9 @@ impl Window { pub fn inner_window_dimensions_query( &self, browsing_context: BrowsingContextId, + can_gc: CanGc, ) -> Option<Size2D<f32, CSSPixel>> { - if !self.layout_reflow(QueryMsg::InnerWindowDimensionsQuery) { + if !self.layout_reflow(QueryMsg::InnerWindowDimensionsQuery, can_gc) { return None; } self.layout @@ -2183,8 +2205,12 @@ impl Window { } #[allow(unsafe_code)] - pub fn offset_parent_query(&self, node: &Node) -> (Option<DomRoot<Element>>, UntypedRect<Au>) { - if !self.layout_reflow(QueryMsg::OffsetParentQuery) { + pub fn offset_parent_query( + &self, + node: &Node, + can_gc: CanGc, + ) -> (Option<DomRoot<Element>>, UntypedRect<Au>) { + if !self.layout_reflow(QueryMsg::OffsetParentQuery, can_gc) { return (None, Rect::zero()); } @@ -2200,8 +2226,9 @@ impl Window { &self, node: &Node, point_in_node: UntypedPoint2D<f32>, + can_gc: CanGc, ) -> Option<usize> { - if !self.layout_reflow(QueryMsg::TextIndexQuery) { + if !self.layout_reflow(QueryMsg::TextIndexQuery, can_gc) { return None; } self.layout @@ -2252,7 +2279,7 @@ impl Window { load_data.url.clone(), replace, )); - doc.check_and_scroll_fragment(fragment); + doc.check_and_scroll_fragment(fragment, CanGc::note()); let this = Trusted::new(self); let old_url = doc.url().into_string(); let new_url = load_data.url.clone().into_string(); diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 52389732cb4..c974417c46c 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1727,12 +1727,12 @@ impl ScriptThread { // https://html.spec.whatwg.org/multipage/#context-lost-steps. // Run the animation frame callbacks. - document.tick_all_animations(should_run_rafs); + document.tick_all_animations(should_run_rafs, can_gc); // Run the resize observer steps. let _realm = enter_realm(&*document); let mut depth = Default::default(); - while document.gather_active_resize_observations_at_depth(&depth) { + while document.gather_active_resize_observations_at_depth(&depth, can_gc) { // Note: this will reflow the doc. depth = document.broadcast_active_resize_observations(can_gc); } @@ -1889,7 +1889,7 @@ impl ScriptThread { }, FromConstellation(ConstellationControlMsg::Viewport(id, rect)) => self .profile_event(ScriptThreadEventCategory::SetViewport, Some(id), || { - self.handle_viewport(id, rect); + self.handle_viewport(id, rect, can_gc); }), FromConstellation(ConstellationControlMsg::TickAllAnimations( pipeline_id, @@ -2067,13 +2067,17 @@ impl ScriptThread { let pending_reflows = window.get_pending_reflow_count(); if pending_reflows > 0 { - window.reflow(ReflowGoal::Full, ReflowReason::PendingReflow); + window.reflow(ReflowGoal::Full, ReflowReason::PendingReflow, can_gc); } else { // Reflow currently happens when explicitly invoked by code that // knows the document could have been modified. This should really // be driven by the compositor on an as-needed basis instead, to // minimize unnecessary work. - window.reflow(ReflowGoal::Full, ReflowReason::MissingExplicitReflow); + window.reflow( + ReflowGoal::Full, + ReflowReason::MissingExplicitReflow, + can_gc, + ); } } @@ -2554,7 +2558,7 @@ impl ScriptThread { self.collect_reports(chan) }, MainThreadScriptMsg::WorkletLoaded(pipeline_id) => { - self.handle_worklet_loaded(pipeline_id) + self.handle_worklet_loaded(pipeline_id, CanGc::note()) }, MainThreadScriptMsg::RegisterPaintWorklet { pipeline_id, @@ -2840,7 +2844,7 @@ impl ScriptThread { webdriver_handlers::handle_get_css(&documents, pipeline_id, node_id, name, reply) }, WebDriverScriptCommand::GetElementRect(node_id, reply) => { - webdriver_handlers::handle_get_rect(&documents, pipeline_id, node_id, reply) + webdriver_handlers::handle_get_rect(&documents, pipeline_id, node_id, reply, can_gc) }, WebDriverScriptCommand::GetBoundingClientRect(node_id, reply) => { webdriver_handlers::handle_get_bounding_client_rect( @@ -2918,11 +2922,11 @@ impl ScriptThread { } } - fn handle_viewport(&self, id: PipelineId, rect: Rect<f32>) { + fn handle_viewport(&self, id: PipelineId, rect: Rect<f32>, can_gc: CanGc) { let document = self.documents.borrow().find_document(id); if let Some(document) = document { if document.window().set_page_clip_rect_with_new_viewport(rect) { - self.rebuild_and_force_reflow(&document, ReflowReason::Viewport); + self.rebuild_and_force_reflow(&document, ReflowReason::Viewport, can_gc); } return; } @@ -3028,7 +3032,7 @@ impl ScriptThread { ); let document = self.documents.borrow().find_document(id); if let Some(document) = document { - document.set_activity(activity); + document.set_activity(activity, CanGc::note()); return; } let mut loads = self.incomplete_loads.borrow_mut(); @@ -3443,10 +3447,10 @@ impl ScriptThread { } /// Handles a worklet being loaded. Does nothing if the page no longer exists. - fn handle_worklet_loaded(&self, pipeline_id: PipelineId) { + fn handle_worklet_loaded(&self, pipeline_id: PipelineId, can_gc: CanGc) { let document = self.documents.borrow().find_document(pipeline_id); if let Some(document) = document { - self.rebuild_and_force_reflow(&document, ReflowReason::WorkletLoaded); + self.rebuild_and_force_reflow(&document, ReflowReason::WorkletLoaded, can_gc); } } @@ -3904,10 +3908,10 @@ impl ScriptThread { } /// Reflows non-incrementally, rebuilding the entire layout tree in the process. - fn rebuild_and_force_reflow(&self, document: &Document, reason: ReflowReason) { + fn rebuild_and_force_reflow(&self, document: &Document, reason: ReflowReason, can_gc: CanGc) { let window = window_from_node(document); document.dirty_all_nodes(); - window.reflow(ReflowGoal::Full, reason); + window.reflow(ReflowGoal::Full, reason, can_gc); } /// Queue compositor events for later dispatching as part of a diff --git a/components/script/timers.rs b/components/script/timers.rs index a5e491e9180..e4348a1b01f 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -95,7 +95,7 @@ impl OneshotTimerCallback { OneshotTimerCallback::EventSourceTimeout(callback) => callback.invoke(), OneshotTimerCallback::JsTimer(task) => task.invoke(this, js_timers), OneshotTimerCallback::TestBindingCallback(callback) => callback.invoke(), - OneshotTimerCallback::FakeRequestAnimationFrame(callback) => callback.invoke(), + OneshotTimerCallback::FakeRequestAnimationFrame(callback) => callback.invoke(can_gc), OneshotTimerCallback::RefreshRedirectDue(callback) => callback.invoke(can_gc), } } diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 489e071908c..a81f1828b76 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -388,8 +388,8 @@ fn get_element_in_view_center_point(element: &Element, can_gc: CanGc) -> Option< let width = rectangle.Width().round() as i64; let height = rectangle.Height().round() as i64; - let client_width = body.ClientWidth() as i64; - let client_height = body.ClientHeight() as i64; + let client_width = body.ClientWidth(can_gc) as i64; + let client_height = body.ClientHeight(can_gc) as i64; // Steps 2 - 5 let left = cmp::max(0, cmp::min(x, x + width)); @@ -881,6 +881,7 @@ pub fn handle_get_rect( pipeline: PipelineId, element_id: String, reply: IpcSender<Result<Rect<f64>, ErrorStatus>>, + can_gc: CanGc, ) { reply .send( @@ -892,15 +893,15 @@ pub fn handle_get_rect( let mut x = 0; let mut y = 0; - let mut offset_parent = html_element.GetOffsetParent(); + let mut offset_parent = html_element.GetOffsetParent(can_gc); // Step 2 while let Some(element) = offset_parent { offset_parent = match element.downcast::<HTMLElement>() { Some(elem) => { - x += elem.OffsetLeft(); - y += elem.OffsetTop(); - elem.GetOffsetParent() + x += elem.OffsetLeft(can_gc); + y += elem.OffsetTop(can_gc); + elem.GetOffsetParent(can_gc) }, None => None, }; @@ -909,8 +910,8 @@ pub fn handle_get_rect( Ok(Rect::new( Point2D::new(x as f64, y as f64), Size2D::new( - html_element.OffsetWidth() as f64, - html_element.OffsetHeight() as f64, + html_element.OffsetWidth(can_gc) as f64, + html_element.OffsetHeight(can_gc) as f64, ), )) }, |