diff --git a/components/layout/layout_impl.rs b/components/layout/layout_impl.rs index 43fa3f5a132..15820ad574b 100644 --- a/components/layout/layout_impl.rs +++ b/components/layout/layout_impl.rs @@ -495,6 +495,10 @@ impl Layout for LayoutThread { .as_mut() .and_then(|tree| tree.compositor_info.scroll_tree.scroll_offset(id)) } + + fn needs_new_display_list(&self) -> bool { + self.need_new_display_list.get() + } } impl LayoutThread { diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index c95c9d736ce..190069962d2 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -1097,13 +1097,8 @@ impl CanvasState { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor - pub(crate) fn set_shadow_color( - &self, - canvas: Option<&HTMLCanvasElement>, - value: DOMString, - can_gc: CanGc, - ) { - if let Ok(rgba) = parse_color(canvas, &value, can_gc) { + pub(crate) fn set_shadow_color(&self, canvas: Option<&HTMLCanvasElement>, value: DOMString) { + if let Ok(rgba) = parse_color(canvas, &value) { self.state.borrow_mut().shadow_color = rgba; } } @@ -1130,11 +1125,10 @@ impl CanvasState { &self, canvas: Option<&HTMLCanvasElement>, value: StringOrCanvasGradientOrCanvasPattern, - can_gc: CanGc, ) { match value { StringOrCanvasGradientOrCanvasPattern::String(string) => { - if let Ok(rgba) = parse_color(canvas, &string, can_gc) { + if let Ok(rgba) = parse_color(canvas, &string) { self.state.borrow_mut().stroke_style = CanvasFillOrStrokeStyle::Color(rgba); } }, @@ -1174,11 +1168,10 @@ impl CanvasState { &self, canvas: Option<&HTMLCanvasElement>, value: StringOrCanvasGradientOrCanvasPattern, - can_gc: CanGc, ) { match value { StringOrCanvasGradientOrCanvasPattern::String(string) => { - if let Ok(rgba) = parse_color(canvas, &string, can_gc) { + if let Ok(rgba) = parse_color(canvas, &string) { self.state.borrow_mut().fill_style = CanvasFillOrStrokeStyle::Color(rgba); } }, @@ -1383,7 +1376,6 @@ impl CanvasState { x: f64, y: f64, max_width: Option, - can_gc: CanGc, ) { if !x.is_finite() || !y.is_finite() { return; @@ -1392,11 +1384,7 @@ impl CanvasState { return; } if self.state.borrow().font_style.is_none() { - self.set_font( - canvas, - CanvasContextState::DEFAULT_FONT_STYLE.into(), - can_gc, - ) + self.set_font(canvas, CanvasContextState::DEFAULT_FONT_STYLE.into()) } let is_rtl = match self.state.borrow().direction { @@ -1429,11 +1417,7 @@ impl CanvasState { can_gc: CanGc, ) -> DomRoot { if self.state.borrow().font_style.is_none() { - self.set_font( - canvas, - CanvasContextState::DEFAULT_FONT_STYLE.into(), - can_gc, - ); + self.set_font(canvas, CanvasContextState::DEFAULT_FONT_STYLE.into()); } let (sender, receiver) = ipc::channel::().unwrap(); @@ -1463,23 +1447,17 @@ impl CanvasState { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-font - pub(crate) fn set_font( - &self, - canvas: Option<&HTMLCanvasElement>, - value: DOMString, - can_gc: CanGc, - ) { + pub(crate) fn set_font(&self, canvas: Option<&HTMLCanvasElement>, value: DOMString) { let canvas = match canvas { Some(element) => element, None => return, // offscreen canvas doesn't have a placeholder canvas }; let node = canvas.upcast::(); let window = canvas.owner_window(); - let resolved_font_style = - match window.resolved_font_style_query(node, value.to_string(), can_gc) { - Some(value) => value, - None => return, // syntax error - }; + let resolved_font_style = match window.resolved_font_style_query(node, value.to_string()) { + Some(value) => value, + None => return, // syntax error + }; self.state.borrow_mut().font_style = Some((*resolved_font_style).clone()); } @@ -2204,7 +2182,6 @@ impl Drop for CanvasState { pub(crate) fn parse_color( canvas: Option<&HTMLCanvasElement>, string: &str, - can_gc: CanGc, ) -> Result { let mut input = ParserInput::new(string); let mut parser = Parser::new(&mut input); @@ -2233,8 +2210,8 @@ pub(crate) fn parse_color( None => AbsoluteColor::BLACK, Some(canvas) => { let canvas_element = canvas.upcast::(); - match canvas_element.style(can_gc) { - Some(ref s) if canvas_element.has_css_layout_box(can_gc) => { + match canvas_element.style() { + Some(ref s) if canvas_element.has_css_layout_box() => { s.get_inherited_text().color }, _ => AbsoluteColor::BLACK, diff --git a/components/script/devtools.rs b/components/script/devtools.rs index 945470194e2..37554210cf4 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -216,7 +216,7 @@ pub(crate) fn handle_get_attribute_style( let name = style.Item(i); NodeStyle { name: name.to_string(), - value: style.GetPropertyValue(name.clone(), can_gc).to_string(), + value: style.GetPropertyValue(name.clone()).to_string(), priority: style.GetPropertyPriority(name).to_string(), } }) @@ -259,7 +259,7 @@ pub(crate) fn handle_get_stylesheet_style( let name = style.Item(i); NodeStyle { name: name.to_string(), - value: style.GetPropertyValue(name.clone(), can_gc).to_string(), + value: style.GetPropertyValue(name.clone()).to_string(), priority: style.GetPropertyPriority(name).to_string(), } }) @@ -315,7 +315,6 @@ pub(crate) fn handle_get_computed_style( pipeline: PipelineId, node_id: String, reply: IpcSender>>, - can_gc: CanGc, ) { let node = match find_node_by_unique_id(documents, pipeline, &node_id) { None => return reply.send(None).unwrap(), @@ -333,9 +332,7 @@ pub(crate) fn handle_get_computed_style( let name = computed_style.Item(i); NodeStyle { name: name.to_string(), - value: computed_style - .GetPropertyValue(name.clone(), can_gc) - .to_string(), + value: computed_style.GetPropertyValue(name.clone()).to_string(), priority: computed_style.GetPropertyPriority(name).to_string(), } }) @@ -375,7 +372,7 @@ pub(crate) 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, can_gc), + auto_margins: determine_auto_margins(&node), margin_top: String::from(computed_style.MarginTop()), margin_right: String::from(computed_style.MarginRight()), margin_bottom: String::from(computed_style.MarginBottom()), @@ -394,8 +391,8 @@ pub(crate) fn handle_get_layout( .unwrap(); } -fn determine_auto_margins(node: &Node, can_gc: CanGc) -> AutoMargins { - let style = node.style(can_gc).unwrap(); +fn determine_auto_margins(node: &Node) -> AutoMargins { + let style = node.style().unwrap(); let margin = style.get_margin(); AutoMargins { top: margin.margin_top.is_auto(), diff --git a/components/script/dom/canvasgradient.rs b/components/script/dom/canvasgradient.rs index 5eb1318d707..c6f0c52cb8c 100644 --- a/components/script/dom/canvasgradient.rs +++ b/components/script/dom/canvasgradient.rs @@ -57,12 +57,12 @@ impl CanvasGradient { impl CanvasGradientMethods for CanvasGradient { // https://html.spec.whatwg.org/multipage/#dom-canvasgradient-addcolorstop - fn AddColorStop(&self, offset: Finite, color: DOMString, can_gc: CanGc) -> ErrorResult { + fn AddColorStop(&self, offset: Finite, color: DOMString) -> ErrorResult { if *offset < 0f64 || *offset > 1f64 { return Err(Error::IndexSize); } - let color = match parse_color(None, &color, can_gc) { + let color = match parse_color(None, &color) { Ok(color) => color, Err(_) => return Err(Error::Syntax), }; diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index d6c94ccc1cb..2e12f93eafb 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -327,15 +327,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingCo } // https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext - fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option, can_gc: CanGc) { - self.canvas_state.fill_text( - self.canvas.canvas().as_deref(), - text, - x, - y, - max_width, - can_gc, - ); + fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option) { + self.canvas_state + .fill_text(self.canvas.canvas().as_deref(), text, x, y, max_width); self.mark_as_dirty(); } @@ -355,9 +349,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingCo } // https://html.spec.whatwg.org/multipage/#dom-context-2d-font - fn SetFont(&self, value: DOMString, can_gc: CanGc) { + fn SetFont(&self, value: DOMString) { self.canvas_state - .set_font(self.canvas.canvas().as_deref(), value, can_gc) + .set_font(self.canvas.canvas().as_deref(), value) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign @@ -504,9 +498,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingCo } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { + fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { self.canvas_state - .set_stroke_style(self.canvas.canvas().as_deref(), value, can_gc) + .set_stroke_style(self.canvas.canvas().as_deref(), value) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle @@ -515,9 +509,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingCo } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { + fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { self.canvas_state - .set_fill_style(self.canvas.canvas().as_deref(), value, can_gc) + .set_fill_style(self.canvas.canvas().as_deref(), value) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata @@ -715,8 +709,8 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingCo } // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor - fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) { + fn SetShadowColor(&self, value: DOMString) { self.canvas_state - .set_shadow_color(self.canvas.canvas().as_deref(), value, can_gc) + .set_shadow_color(self.canvas.canvas().as_deref(), value) } } diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index de4b87cb2ca..2cb2f979088 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -204,7 +204,7 @@ macro_rules! css_properties( $id.enabled_for_all_content(), "Someone forgot a #[Pref] annotation" ); - self.get_property_value($id, CanGc::note()) + self.get_property_value($id) } fn $setter(&self, value: DOMString) -> ErrorResult { debug_assert!( @@ -268,7 +268,7 @@ impl CSSStyleDeclaration { ) } - fn get_computed_style(&self, property: PropertyId, can_gc: CanGc) -> DOMString { + fn get_computed_style(&self, property: PropertyId) -> DOMString { match self.owner { CSSStyleOwner::CSSRule(..) => { panic!("get_computed_style called on CSSStyleDeclaration with a CSSRule owner") @@ -280,20 +280,20 @@ impl CSSStyleDeclaration { } let addr = node.to_trusted_node_address(); node.owner_window() - .resolved_style_query(addr, self.pseudo, property, can_gc) + .resolved_style_query(addr, self.pseudo, property) }, CSSStyleOwner::Null => DOMString::new(), } } - fn get_property_value(&self, id: PropertyId, can_gc: CanGc) -> DOMString { + fn get_property_value(&self, id: PropertyId) -> DOMString { if matches!(self.owner, CSSStyleOwner::Null) { return DOMString::new(); } if self.readonly { // Readonly style declarations are used for getComputedStyle. - return self.get_computed_style(id, can_gc); + return self.get_computed_style(id); } let mut string = String::new(); @@ -431,12 +431,12 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { } // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue - fn GetPropertyValue(&self, property: DOMString, can_gc: CanGc) -> DOMString { + fn GetPropertyValue(&self, property: DOMString) -> DOMString { let id = match PropertyId::parse_enabled_for_all_content(&property) { Ok(id) => id, Err(..) => return DOMString::new(), }; - self.get_property_value(id, can_gc) + self.get_property_value(id) } // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority @@ -502,8 +502,8 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { } // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-cssfloat - fn CssFloat(&self, can_gc: CanGc) -> DOMString { - self.get_property_value(PropertyId::NonCustom(LonghandId::Float.into()), can_gc) + fn CssFloat(&self) -> DOMString { + self.get_property_value(PropertyId::NonCustom(LonghandId::Float.into())) } // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-cssfloat diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 6c659550411..88325f10654 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1034,7 +1034,7 @@ 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. /// - pub(crate) fn check_and_scroll_fragment(&self, fragment: &str, can_gc: CanGc) { + pub(crate) fn check_and_scroll_fragment(&self, fragment: &str) { let target = self.find_fragment_node(fragment); // Step 1 @@ -1047,9 +1047,7 @@ 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::() - .bounding_content_box_or_zero(can_gc); + let rect = element.upcast::().bounding_content_box_or_zero(); // 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 @@ -1073,7 +1071,7 @@ impl Document { if let Some((x, y)) = point { self.window - .scroll(x as f64, y as f64, ScrollBehavior::Instant, can_gc) + .scroll(x as f64, y as f64, ScrollBehavior::Instant) } } @@ -1349,7 +1347,7 @@ impl Document { // Notify the embedder to display an input method. if let Some(kind) = elem.input_method_type() { - let rect = elem.upcast::().bounding_content_box_or_zero(can_gc); + let rect = elem.upcast::().bounding_content_box_or_zero(); 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()), @@ -2886,7 +2884,7 @@ impl Document { // We finished loading the page, so if the `Window` is still waiting for // the first layout, allow it. if self.has_browsing_context && self.is_fully_active() { - self.window().allow_layout_if_necessary(can_gc); + self.window().allow_layout_if_necessary(); } // Deferred scripts have to wait for page to finish loading, @@ -3124,7 +3122,7 @@ impl Document { update_with_current_instant(&document.load_event_end); if let Some(fragment) = document.url().fragment() { - document.check_and_scroll_fragment(fragment, CanGc::note()); + document.check_and_scroll_fragment(fragment); } })); @@ -3658,6 +3656,31 @@ impl Document { self.webgpu_contexts.clone() } + /// Whether or not this [`Document`] needs a rendering update, due to changed + /// contents or pending events. + pub(crate) fn needs_rendering_update(&self) -> bool { + if !self.is_fully_active() { + return false; + } + if !self.window().layout_blocked() && + (!self.restyle_reason().is_empty() || + self.window().layout().needs_new_display_list()) + { + return true; + } + if self.has_pending_input_events() { + return true; + } + if self.has_pending_scroll_events() { + return true; + } + if self.window().has_unhandled_resize_event() { + return true; + } + + false + } + /// An implementation of step 22 from /// : /// @@ -3665,7 +3688,7 @@ impl Document { // > doc and its node navigable to reflect the current state. // // Returns true if a reflow occured. - pub(crate) fn update_the_rendering(&self, can_gc: CanGc) -> bool { + pub(crate) fn update_the_rendering(&self) -> bool { self.update_animating_images(); // All dirty canvases are flushed before updating the rendering. @@ -3701,10 +3724,40 @@ impl Document { } self.window() - .reflow(ReflowGoal::UpdateTheRendering, can_gc) + .reflow(ReflowGoal::UpdateTheRendering) .reflow_issued } + /// From : + /// + /// > A FontFaceSet is pending on the environment if any of the following are true: + /// > - the document is still loading + /// > - the document has pending stylesheet requests + /// > - the document has pending layout operations which might cause the user agent to request + /// > a font, or which depend on recently-loaded fonts + /// + /// Returns true if the promise was fulfilled. + pub(crate) fn maybe_fulfill_font_ready_promise(&self, can_gc: CanGc) -> bool { + if !self.is_fully_active() { + return false; + } + + let fonts = self.Fonts(can_gc); + if !fonts.waiting_to_fullfill_promise() { + return false; + } + if self.window().font_context().web_fonts_still_loading() != 0 { + return false; + } + if self.ReadyState() != DocumentReadyState::Complete { + return false; + } + if !self.restyle_reason().is_empty() { + return false; + } + fonts.fulfill_ready_promise_if_needed(can_gc) + } + pub(crate) fn id_map(&self) -> Ref>>> { self.id_map.borrow() } @@ -3720,19 +3773,22 @@ impl Document { .push(Dom::from_ref(resize_observer)); } + /// Whether or not this [`Document`] has any active [`ResizeObserver`]. + pub(crate) fn has_resize_observers(&self) -> bool { + !self.resize_observers.borrow().is_empty() + } + /// /// 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 @@ -4431,6 +4487,18 @@ impl Document { mem::take(&mut *self.pending_input_events.borrow_mut()) } + /// Whether or not this [`Document`] has any pending input events to be processed during + /// "update the rendering." + pub(crate) fn has_pending_input_events(&self) -> bool { + !self.pending_input_events.borrow().is_empty() + } + + /// Whether or not this [`Document`] has any pending scroll events to be processed during + /// "update the rendering." + fn has_pending_scroll_events(&self) -> bool { + !self.pending_scroll_event_targets.borrow().is_empty() + } + pub(crate) fn set_csp_list(&self, csp_list: Option) { self.policy_container.borrow_mut().set_csp_list(csp_list); } @@ -6524,39 +6592,27 @@ impl DocumentMethods for Document { ); // https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint - fn ElementFromPoint( - &self, - x: Finite, - y: Finite, - can_gc: CanGc, - ) -> Option> { + fn ElementFromPoint(&self, x: Finite, y: Finite) -> Option> { 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, - y: Finite, - can_gc: CanGc, - ) -> Vec> { + fn ElementsFromPoint(&self, x: Finite, y: Finite) -> Vec> { self.document_or_shadow_root.elements_from_point( x, y, self.GetDocumentElement(), self.has_browsing_context, - can_gc, ) } /// - fn GetScrollingElement(&self, can_gc: CanGc) -> Option> { + fn GetScrollingElement(&self) -> Option> { // Step 1. If the Document is in quirks mode, follow these steps: if self.quirks_mode() == QuirksMode::Quirks { // Step 1.1. If the body element exists, @@ -6565,7 +6621,7 @@ impl DocumentMethods for Document { // and it is not potentially scrollable, return the body element and abort these steps. // For this purpose, a value of overflow:clip on the the body element’s parent element // must be treated as overflow:hidden. - if !e.is_potentially_scrollable_body_for_scrolling_element(can_gc) { + if !e.is_potentially_scrollable_body_for_scrolling_element() { return Some(DomRoot::from_ref(e)); } } diff --git a/components/script/dom/documentorshadowroot.rs b/components/script/dom/documentorshadowroot.rs index 1de7f574944..0e617712d34 100644 --- a/components/script/dom/documentorshadowroot.rs +++ b/components/script/dom/documentorshadowroot.rs @@ -35,7 +35,6 @@ use crate::dom::shadowroot::ShadowRoot; use crate::dom::stylesheetlist::StyleSheetListOwner; use crate::dom::types::CSSStyleSheet; use crate::dom::window::Window; -use crate::script_runtime::CanGc; use crate::stylesheet_set::StylesheetSetRef; /// Stylesheet could be constructed by a CSSOM object CSSStylesheet or parsed @@ -141,10 +140,8 @@ impl DocumentOrShadowRoot { &self, client_point: &Point2D, query_type: NodesFromPointQueryType, - can_gc: CanGc, ) -> Vec { - self.window - .layout_reflow(QueryMsg::NodesFromPointQuery, can_gc); + self.window.layout_reflow(QueryMsg::NodesFromPointQuery); self.window .layout() .query_nodes_from_point(*client_point, query_type) @@ -158,7 +155,6 @@ impl DocumentOrShadowRoot { y: Finite, document_element: Option>, has_browsing_context: bool, - can_gc: CanGc, ) -> Option> { let x = *x as f32; let y = *y as f32; @@ -174,7 +170,7 @@ impl DocumentOrShadowRoot { } match self - .nodes_from_point(point, NodesFromPointQueryType::Topmost, can_gc) + .nodes_from_point(point, NodesFromPointQueryType::Topmost) .first() { Some(address) => { @@ -206,7 +202,6 @@ impl DocumentOrShadowRoot { y: Finite, document_element: Option>, has_browsing_context: bool, - can_gc: CanGc, ) -> Vec> { let x = *x as f32; let y = *y as f32; @@ -223,7 +218,7 @@ impl DocumentOrShadowRoot { } // Step 1 and Step 3 - let nodes = self.nodes_from_point(point, NodesFromPointQueryType::All, can_gc); + let nodes = self.nodes_from_point(point, NodesFromPointQueryType::All); let mut elements: Vec> = nodes .iter() .flat_map(|&untrusted_node_address| { diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 00d1e0a62c6..cbfbf630eb4 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -464,34 +464,30 @@ 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(crate) fn style(&self, can_gc: CanGc) -> Option> { - self.upcast::().style(can_gc) + pub(crate) fn style(&self) -> Option> { + self.upcast::().style() } // https://drafts.csswg.org/cssom-view/#css-layout-box - pub(crate) fn has_css_layout_box(&self, can_gc: CanGc) -> bool { - self.style(can_gc) + pub(crate) fn has_css_layout_box(&self) -> bool { + self.style() .is_some_and(|s| !s.get_box().clone_display().is_none()) } /// - pub(crate) fn is_potentially_scrollable_body(&self, can_gc: CanGc) -> bool { - self.is_potentially_scrollable_body_shared_logic(false, can_gc) + pub(crate) fn is_potentially_scrollable_body(&self) -> bool { + self.is_potentially_scrollable_body_shared_logic(false) } /// - pub(crate) fn is_potentially_scrollable_body_for_scrolling_element( - &self, - can_gc: CanGc, - ) -> bool { - self.is_potentially_scrollable_body_shared_logic(true, can_gc) + pub(crate) fn is_potentially_scrollable_body_for_scrolling_element(&self) -> bool { + self.is_potentially_scrollable_body_shared_logic(true) } /// fn is_potentially_scrollable_body_shared_logic( &self, treat_overflow_clip_on_parent_as_hidden: bool, - can_gc: CanGc, ) -> bool { let node = self.upcast::(); debug_assert!( @@ -502,14 +498,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(can_gc) { + if !self.has_css_layout_box() { 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(can_gc) { + if let Some(style) = parent.style() { let mut overflow_x = style.get_box().clone_overflow_x(); let mut overflow_y = style.get_box().clone_overflow_y(); @@ -532,7 +528,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(can_gc) { + if let Some(style) = self.style() { if !style.get_box().clone_overflow_x().is_scrollable() && !style.get_box().clone_overflow_y().is_scrollable() { @@ -544,18 +540,17 @@ impl Element { } // https://drafts.csswg.org/cssom-view/#scrolling-box - fn has_scrolling_box(&self, can_gc: CanGc) -> bool { + fn has_scrolling_box(&self) -> bool { // TODO: scrolling mechanism, such as scrollbar (We don't have scrollbar yet) // self.has_scrolling_mechanism() - self.style(can_gc).is_some_and(|style| { + self.style().is_some_and(|style| { style.get_box().clone_overflow_x().is_scrollable() || style.get_box().clone_overflow_y().is_scrollable() }) } - 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 has_overflow(&self) -> bool { + self.ScrollHeight() > self.ClientHeight() || self.ScrollWidth() > self.ClientWidth() } pub(crate) fn shadow_root(&self) -> Option> { @@ -2477,7 +2472,7 @@ impl Element { // https://drafts.csswg.org/cssom-view/#dom-element-scroll // TODO(stevennovaryo): Need to update the scroll API to follow the spec since it is quite outdated. - pub(crate) fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior, can_gc: CanGc) { + pub(crate) fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior) { // 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 }; @@ -2501,7 +2496,7 @@ impl Element { // Step 7 if *self.root_element() == *self { if doc.quirks_mode() != QuirksMode::Quirks { - win.scroll(x, y, behavior, can_gc); + win.scroll(x, y, behavior); } return; @@ -2510,22 +2505,19 @@ impl Element { // Step 9 if doc.GetBody().as_deref() == self.downcast::() && doc.quirks_mode() == QuirksMode::Quirks && - !self.is_potentially_scrollable_body(can_gc) + !self.is_potentially_scrollable_body() { - win.scroll(x, y, behavior, can_gc); + win.scroll(x, y, behavior); return; } // Step 10 - if !self.has_css_layout_box(can_gc) || - !self.has_scrolling_box(can_gc) || - !self.has_overflow(can_gc) - { + if !self.has_css_layout_box() || !self.has_scrolling_box() || !self.has_overflow() { return; } // Step 11 - win.scroll_an_element(self, x, y, behavior, can_gc); + win.scroll_an_element(self, x, y, behavior); } /// @@ -3058,7 +3050,7 @@ impl ElementMethods for Element { // https://drafts.csswg.org/cssom-view/#dom-element-getclientrects fn GetClientRects(&self, can_gc: CanGc) -> DomRoot { let win = self.owner_window(); - let raw_rects = self.upcast::().content_boxes(can_gc); + let raw_rects = self.upcast::().content_boxes(); let rects: Vec> = raw_rects .iter() .map(|rect| { @@ -3078,7 +3070,7 @@ impl ElementMethods for Element { // https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect fn GetBoundingClientRect(&self, can_gc: CanGc) -> DomRoot { let win = self.owner_window(); - let rect = self.upcast::().bounding_content_box_or_zero(can_gc); + let rect = self.upcast::().bounding_content_box_or_zero(); DOMRect::new( win.upcast(), rect.origin.x.to_f64_px(), @@ -3090,52 +3082,47 @@ impl ElementMethods for Element { } // https://drafts.csswg.org/cssom-view/#dom-element-scroll - fn Scroll(&self, options: &ScrollToOptions, can_gc: CanGc) { + fn Scroll(&self, options: &ScrollToOptions) { // Step 1 - 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); + let left = options.left.unwrap_or(self.ScrollLeft()); + let top = options.top.unwrap_or(self.ScrollTop()); + self.scroll(left, top, options.parent.behavior); } // https://drafts.csswg.org/cssom-view/#dom-element-scroll - fn Scroll_(&self, x: f64, y: f64, can_gc: CanGc) { - self.scroll(x, y, ScrollBehavior::Auto, can_gc); + fn Scroll_(&self, x: f64, y: f64) { + self.scroll(x, y, ScrollBehavior::Auto); } // https://drafts.csswg.org/cssom-view/#dom-element-scrollto - fn ScrollTo(&self, options: &ScrollToOptions, can_gc: CanGc) { - self.Scroll(options, can_gc); + fn ScrollTo(&self, options: &ScrollToOptions) { + self.Scroll(options); } // https://drafts.csswg.org/cssom-view/#dom-element-scrollto - fn ScrollTo_(&self, x: f64, y: f64, can_gc: CanGc) { - self.Scroll_(x, y, can_gc); + fn ScrollTo_(&self, x: f64, y: f64) { + self.Scroll_(x, y); } // https://drafts.csswg.org/cssom-view/#dom-element-scrollby - fn ScrollBy(&self, options: &ScrollToOptions, can_gc: CanGc) { + fn ScrollBy(&self, options: &ScrollToOptions) { // Step 2 let delta_left = options.left.unwrap_or(0.0f64); let delta_top = options.top.unwrap_or(0.0f64); - 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, - ); + let left = self.ScrollLeft(); + let top = self.ScrollTop(); + self.scroll(left + delta_left, top + delta_top, options.parent.behavior); } // https://drafts.csswg.org/cssom-view/#dom-element-scrollby - 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); + fn ScrollBy_(&self, x: f64, y: f64) { + let left = self.ScrollLeft(); + let top = self.ScrollTop(); + self.scroll(left + x, top + y, ScrollBehavior::Auto); } // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop - fn ScrollTop(&self, can_gc: CanGc) -> f64 { + fn ScrollTop(&self) -> f64 { let node = self.upcast::(); // Step 1 @@ -3165,24 +3152,24 @@ impl ElementMethods for Element { // Step 7 if doc.GetBody().as_deref() == self.downcast::() && doc.quirks_mode() == QuirksMode::Quirks && - !self.is_potentially_scrollable_body(can_gc) + !self.is_potentially_scrollable_body() { return win.ScrollY() as f64; } // Step 8 - if !self.has_css_layout_box(can_gc) { + if !self.has_css_layout_box() { return 0.0; } // Step 9 - let point = win.scroll_offset_query(node, can_gc); + let point = win.scroll_offset_query(node); point.y.abs() as f64 } // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop // TODO(stevennovaryo): Need to update the scroll API to follow the spec since it is quite outdated. - fn SetScrollTop(&self, y_: f64, can_gc: CanGc) { + fn SetScrollTop(&self, y_: f64) { let behavior = ScrollBehavior::Auto; // Step 1, 2 @@ -3207,7 +3194,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, can_gc); + win.scroll(win.ScrollX() as f64, y, behavior); } return; @@ -3216,26 +3203,23 @@ impl ElementMethods for Element { // Step 9 if doc.GetBody().as_deref() == self.downcast::() && doc.quirks_mode() == QuirksMode::Quirks && - !self.is_potentially_scrollable_body(can_gc) + !self.is_potentially_scrollable_body() { - win.scroll(win.ScrollX() as f64, y, behavior, can_gc); + win.scroll(win.ScrollX() as f64, y, behavior); return; } // Step 10 - if !self.has_css_layout_box(can_gc) || - !self.has_scrolling_box(can_gc) || - !self.has_overflow(can_gc) - { + if !self.has_css_layout_box() || !self.has_scrolling_box() || !self.has_overflow() { return; } // Step 11 - win.scroll_an_element(self, self.ScrollLeft(can_gc), y, behavior, can_gc); + win.scroll_an_element(self, self.ScrollLeft(), y, behavior); } // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop - fn ScrollLeft(&self, can_gc: CanGc) -> f64 { + fn ScrollLeft(&self) -> f64 { let node = self.upcast::(); // Step 1 @@ -3265,23 +3249,23 @@ impl ElementMethods for Element { // Step 7 if doc.GetBody().as_deref() == self.downcast::() && doc.quirks_mode() == QuirksMode::Quirks && - !self.is_potentially_scrollable_body(can_gc) + !self.is_potentially_scrollable_body() { return win.ScrollX() as f64; } // Step 8 - if !self.has_css_layout_box(can_gc) { + if !self.has_css_layout_box() { return 0.0; } // Step 9 - let point = win.scroll_offset_query(node, can_gc); + let point = win.scroll_offset_query(node); point.x.abs() as f64 } // https://drafts.csswg.org/cssom-view/#dom-element-scrollleft - fn SetScrollLeft(&self, x_: f64, can_gc: CanGc) { + fn SetScrollLeft(&self, x_: f64) { let behavior = ScrollBehavior::Auto; // Step 1, 2 @@ -3309,59 +3293,56 @@ impl ElementMethods for Element { return; } - win.scroll(x, win.ScrollY() as f64, behavior, can_gc); + win.scroll(x, win.ScrollY() as f64, behavior); return; } // Step 9 if doc.GetBody().as_deref() == self.downcast::() && doc.quirks_mode() == QuirksMode::Quirks && - !self.is_potentially_scrollable_body(can_gc) + !self.is_potentially_scrollable_body() { - win.scroll(x, win.ScrollY() as f64, behavior, can_gc); + win.scroll(x, win.ScrollY() as f64, behavior); return; } // Step 10 - if !self.has_css_layout_box(can_gc) || - !self.has_scrolling_box(can_gc) || - !self.has_overflow(can_gc) - { + if !self.has_css_layout_box() || !self.has_scrolling_box() || !self.has_overflow() { return; } // Step 11 - win.scroll_an_element(self, x, self.ScrollTop(can_gc), behavior, can_gc); + win.scroll_an_element(self, x, self.ScrollTop(), behavior); } // https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth - fn ScrollWidth(&self, can_gc: CanGc) -> i32 { - self.upcast::().scroll_area(can_gc).size.width + fn ScrollWidth(&self) -> i32 { + self.upcast::().scroll_area().size.width } // https://drafts.csswg.org/cssom-view/#dom-element-scrollheight - fn ScrollHeight(&self, can_gc: CanGc) -> i32 { - self.upcast::().scroll_area(can_gc).size.height + fn ScrollHeight(&self) -> i32 { + self.upcast::().scroll_area().size.height } // https://drafts.csswg.org/cssom-view/#dom-element-clienttop - fn ClientTop(&self, can_gc: CanGc) -> i32 { - self.client_rect(can_gc).origin.y + fn ClientTop(&self) -> i32 { + self.client_rect().origin.y } // https://drafts.csswg.org/cssom-view/#dom-element-clientleft - fn ClientLeft(&self, can_gc: CanGc) -> i32 { - self.client_rect(can_gc).origin.x + fn ClientLeft(&self) -> i32 { + self.client_rect().origin.x } // https://drafts.csswg.org/cssom-view/#dom-element-clientwidth - fn ClientWidth(&self, can_gc: CanGc) -> i32 { - self.client_rect(can_gc).size.width + fn ClientWidth(&self) -> i32 { + self.client_rect().size.width } // https://drafts.csswg.org/cssom-view/#dom-element-clientheight - fn ClientHeight(&self, can_gc: CanGc) -> i32 { - self.client_rect(can_gc).size.height + fn ClientHeight(&self) -> i32 { + self.client_rect().size.height } /// @@ -4777,7 +4758,7 @@ impl SelectorsElement for SelectorWrapper<'_> { } impl Element { - fn client_rect(&self, can_gc: CanGc) -> Rect { + fn client_rect(&self) -> Rect { let doc = self.node.owner_doc(); if let Some(rect) = self @@ -4791,7 +4772,7 @@ impl Element { } } - let mut rect = self.upcast::().client_rect(can_gc); + let mut rect = self.upcast::().client_rect(); let in_quirks_mode = doc.quirks_mode() == QuirksMode::Quirks; if (in_quirks_mode && doc.GetBody().as_deref() == self.downcast::()) || diff --git a/components/script/dom/fontfaceset.rs b/components/script/dom/fontfaceset.rs index 084f9b4d5a0..1d0dde66dea 100644 --- a/components/script/dom/fontfaceset.rs +++ b/components/script/dom/fontfaceset.rs @@ -69,10 +69,17 @@ impl FontFaceSet { } } - pub(crate) fn fulfill_ready_promise_if_needed(&self, can_gc: CanGc) { - if !self.promise.is_fulfilled() { - self.promise.resolve_native(self, can_gc); + /// Fulfill the font ready promise, returning true if it was not already fulfilled beforehand. + pub(crate) fn fulfill_ready_promise_if_needed(&self, can_gc: CanGc) -> bool { + if self.promise.is_fulfilled() { + return false; } + self.promise.resolve_native(self, can_gc); + true + } + + pub(crate) fn waiting_to_fullfill_promise(&self) -> bool { + !self.promise.is_fulfilled() } } diff --git a/components/script/dom/history.rs b/components/script/dom/history.rs index 4b51f3e62d2..149c9f66834 100644 --- a/components/script/dom/history.rs +++ b/components/script/dom/history.rs @@ -101,7 +101,7 @@ impl History { // Step 8 if let Some(fragment) = url.fragment() { - document.check_and_scroll_fragment(fragment, can_gc); + document.check_and_scroll_fragment(fragment); } // Step 11 diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index 5a59c9254a0..514126b214b 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -319,7 +319,7 @@ impl Activatable for HTMLAnchorElement { } //https://html.spec.whatwg.org/multipage/#the-a-element:activation-behaviour - fn activation_behavior(&self, event: &Event, target: &EventTarget, can_gc: CanGc) { + fn activation_behavior(&self, event: &Event, target: &EventTarget, _: CanGc) { let element = self.as_element(); let mouse_event = event.downcast::().unwrap(); let mut ismap_suffix = None; @@ -329,7 +329,7 @@ impl Activatable for HTMLAnchorElement { if let Some(element) = target.downcast::() { if target.is::() && element.has_attribute(&local_name!("ismap")) { let target_node = element.upcast::(); - let rect = target_node.bounding_content_box_or_zero(can_gc); + let rect = target_node.bounding_content_box_or_zero(); ismap_suffix = Some(format!( "?{},{}", mouse_event.ClientX().to_f32().unwrap() - rect.origin.x.to_f32_px(), diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index b5edc6bd7c9..8ef1fc8a767 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -116,18 +116,18 @@ impl HTMLElement { /// `.outerText` in JavaScript.` /// /// - pub(crate) fn get_inner_outer_text(&self, can_gc: CanGc) -> DOMString { + pub(crate) fn get_inner_outer_text(&self) -> DOMString { let node = self.upcast::(); let window = node.owner_window(); let element = self.as_element(); // Step 1. - let element_not_rendered = !node.is_connected() || !element.has_css_layout_box(can_gc); + let element_not_rendered = !node.is_connected() || !element.has_css_layout_box(); if element_not_rendered { return node.GetTextContent().unwrap(); } - window.layout_reflow(QueryMsg::ElementInnerOuterTextQuery, can_gc); + window.layout_reflow(QueryMsg::ElementInnerOuterTextQuery); let text = window .layout() .query_element_inner_outer_text(node.to_trusted_node_address()); @@ -438,65 +438,65 @@ impl HTMLElementMethods for HTMLElement { } /// - fn GetOffsetParent(&self, can_gc: CanGc) -> Option> { + fn GetOffsetParent(&self) -> Option> { if self.is_body_element() || self.is::() { return None; } let node = self.upcast::(); let window = self.owner_window(); - let (element, _) = window.offset_parent_query(node, can_gc); + let (element, _) = window.offset_parent_query(node); element } // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsettop - fn OffsetTop(&self, can_gc: CanGc) -> i32 { + fn OffsetTop(&self) -> i32 { if self.is_body_element() { return 0; } let node = self.upcast::(); let window = self.owner_window(); - let (_, rect) = window.offset_parent_query(node, can_gc); + let (_, rect) = window.offset_parent_query(node); rect.origin.y.to_nearest_px() } // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetleft - fn OffsetLeft(&self, can_gc: CanGc) -> i32 { + fn OffsetLeft(&self) -> i32 { if self.is_body_element() { return 0; } let node = self.upcast::(); let window = self.owner_window(); - let (_, rect) = window.offset_parent_query(node, can_gc); + let (_, rect) = window.offset_parent_query(node); rect.origin.x.to_nearest_px() } // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetwidth - fn OffsetWidth(&self, can_gc: CanGc) -> i32 { + fn OffsetWidth(&self) -> i32 { let node = self.upcast::(); let window = self.owner_window(); - let (_, rect) = window.offset_parent_query(node, can_gc); + let (_, rect) = window.offset_parent_query(node); rect.size.width.to_nearest_px() } // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetheight - fn OffsetHeight(&self, can_gc: CanGc) -> i32 { + fn OffsetHeight(&self) -> i32 { let node = self.upcast::(); let window = self.owner_window(); - let (_, rect) = window.offset_parent_query(node, can_gc); + let (_, rect) = window.offset_parent_query(node); rect.size.height.to_nearest_px() } /// - fn InnerText(&self, can_gc: CanGc) -> DOMString { - self.get_inner_outer_text(can_gc) + fn InnerText(&self) -> DOMString { + self.get_inner_outer_text() } /// @@ -505,8 +505,8 @@ impl HTMLElementMethods for HTMLElement { } /// - fn GetOuterText(&self, can_gc: CanGc) -> Fallible { - Ok(self.get_inner_outer_text(can_gc)) + fn GetOuterText(&self) -> Fallible { + Ok(self.get_inner_outer_text()) } /// diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index ee6cd312e2e..0137f3c8ef1 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -210,7 +210,7 @@ impl HTMLIFrameElement { }; let viewport_details = window - .get_iframe_viewport_details_if_known(browsing_context_id, can_gc) + .get_iframe_viewport_details_if_known(browsing_context_id) .unwrap_or_else(|| ViewportDetails { hidpi_scale_factor: window.device_pixel_ratio(), ..Default::default() diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 3a38c851bcf..ac17f6094bd 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -1655,9 +1655,9 @@ impl HTMLImageElementMethods for HTMLImageElement { make_bool_setter!(SetIsMap, "ismap"); // https://html.spec.whatwg.org/multipage/#dom-img-width - fn Width(&self, can_gc: CanGc) -> u32 { + fn Width(&self) -> u32 { let node = self.upcast::(); - match node.bounding_content_box(can_gc) { + match node.bounding_content_box() { Some(rect) => rect.size.width.to_px() as u32, None => self.NaturalWidth(), } @@ -1669,9 +1669,9 @@ impl HTMLImageElementMethods for HTMLImageElement { } // https://html.spec.whatwg.org/multipage/#dom-img-height - fn Height(&self, can_gc: CanGc) -> u32 { + fn Height(&self) -> u32 { let node = self.upcast::(); - match node.bounding_content_box(can_gc) { + match node.bounding_content_box() { 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 102d14653b7..a9966a425a6 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -2736,7 +2736,7 @@ impl HTMLInputElement { let (ipc_sender, ipc_receiver) = ipc::channel::>().expect("Failed to create IPC channel!"); let document = self.owner_document(); - let rect = self.upcast::().bounding_content_box_or_zero(can_gc); + let rect = self.upcast::().bounding_content_box_or_zero(); 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()), @@ -3074,11 +3074,8 @@ impl VirtualMethods for HTMLInputElement { // now. if let Some(point_in_target) = mouse_event.point_in_target() { let window = self.owner_window(); - let index = window.text_index_query( - self.upcast::(), - point_in_target.to_untyped(), - can_gc, - ); + let index = window + .text_index_query(self.upcast::(), point_in_target.to_untyped()); // Position the caret at the click position or at the end of the current // value. let edit_point_index = match index { diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 7a028504109..0ec0a30a9e4 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -1551,9 +1551,9 @@ impl HTMLScriptElementMethods for HTMLScriptElement { make_setter!(SetReferrerPolicy, "referrerpolicy"); /// - fn InnerText(&self, can_gc: CanGc) -> TrustedScriptOrString { + fn InnerText(&self) -> TrustedScriptOrString { // Step 1: Return the result of running get the text steps with this. - TrustedScriptOrString::String(self.upcast::().get_inner_outer_text(can_gc)) + TrustedScriptOrString::String(self.upcast::().get_inner_outer_text()) } /// diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index f7730913783..e4ca7a247be 100644 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -339,7 +339,7 @@ impl HTMLSelectElement { .or_else(|| self.list_of_options().next()) } - pub(crate) fn show_menu(&self, can_gc: CanGc) -> Option { + pub(crate) fn show_menu(&self) -> Option { let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); // Collect list of optgroups and options @@ -377,7 +377,7 @@ impl HTMLSelectElement { }) .collect(); - let rect = self.upcast::().bounding_content_box_or_zero(can_gc); + let rect = self.upcast::().bounding_content_box_or_zero(); 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()), @@ -782,7 +782,7 @@ impl Activatable for HTMLSelectElement { } fn activation_behavior(&self, _event: &Event, _target: &EventTarget, can_gc: CanGc) { - let Some(selected_value) = self.show_menu(can_gc) else { + let Some(selected_value) = self.show_menu() else { // The user did not select a value return; }; diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs index bb02f9451e3..c0938ed39f8 100644 --- a/components/script/dom/mouseevent.rs +++ b/components/script/dom/mouseevent.rs @@ -278,7 +278,7 @@ impl MouseEventMethods for MouseEvent { ) -> Fallible> { let bubbles = EventBubbles::from(init.parent.parent.parent.bubbles); let cancelable = EventCancelable::from(init.parent.parent.parent.cancelable); - let scroll_offset = window.scroll_offset(can_gc); + let scroll_offset = window.scroll_offset(); let page_point = Point2D::new( scroll_offset.x as i32 + init.clientX, scroll_offset.y as i32 + init.clientY, @@ -370,7 +370,7 @@ impl MouseEventMethods for MouseEvent { } /// - fn OffsetX(&self, can_gc: CanGc) -> i32 { + fn OffsetX(&self) -> i32 { // > The offsetX attribute must follow these steps: // > 1. If the event’s dispatch flag is set, return the x-coordinate of the position // > where the event occurred relative to the origin of the padding edge of the @@ -384,7 +384,7 @@ impl MouseEventMethods for MouseEvent { let Some(node) = target.downcast::() else { return 0; }; - return self.ClientX() - node.client_rect(can_gc).origin.x; + return self.ClientX() - node.client_rect().origin.x; } // > 2. Return the value of the event’s pageX attribute. @@ -392,7 +392,7 @@ impl MouseEventMethods for MouseEvent { } /// - fn OffsetY(&self, can_gc: CanGc) -> i32 { + fn OffsetY(&self) -> i32 { // > The offsetY attribute must follow these steps: // > 1. If the event’s dispatch flag is set, return the y-coordinate of the // > position where the event occurred relative to the origin of the padding edge of @@ -406,7 +406,7 @@ impl MouseEventMethods for MouseEvent { let Some(node) = target.downcast::() else { return 0; }; - return self.ClientY() - node.client_rect(can_gc).origin.y; + return self.ClientY() - node.client_rect().origin.y; } // 2. Return the value of the event’s pageY attribute. @@ -479,7 +479,6 @@ impl MouseEventMethods for MouseEvent { meta_key_arg: bool, button_arg: i16, related_target_arg: Option<&EventTarget>, - can_gc: CanGc, ) { if self.upcast::().dispatching() { return; @@ -498,7 +497,7 @@ impl MouseEventMethods for MouseEvent { .set(Point2D::new(client_x_arg, client_y_arg)); let global = self.global(); - let scroll_offset = global.as_window().scroll_offset(can_gc); + let scroll_offset = global.as_window().scroll_offset(); self.page_point.set(Point2D::new( scroll_offset.x as i32 + client_x_arg, scroll_offset.y as i32 + client_y_arg, diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index bc1589dee1c..aae644cc010 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -944,29 +944,29 @@ impl Node { /// Returns the rendered bounding content box if the element is rendered, /// and none otherwise. - pub(crate) fn bounding_content_box(&self, can_gc: CanGc) -> Option> { - self.owner_window().content_box_query(self, can_gc) + pub(crate) fn bounding_content_box(&self) -> Option> { + self.owner_window().content_box_query(self) } - pub(crate) fn bounding_content_box_or_zero(&self, can_gc: CanGc) -> Rect { - self.bounding_content_box(can_gc).unwrap_or_else(Rect::zero) + pub(crate) fn bounding_content_box_or_zero(&self) -> Rect { + self.bounding_content_box().unwrap_or_else(Rect::zero) } pub(crate) fn bounding_content_box_no_reflow(&self) -> Option> { self.owner_window().content_box_query_unchecked(self) } - pub(crate) fn content_boxes(&self, can_gc: CanGc) -> Vec> { - self.owner_window().content_boxes_query(self, can_gc) + pub(crate) fn content_boxes(&self) -> Vec> { + self.owner_window().content_boxes_query(self) } - pub(crate) fn client_rect(&self, can_gc: CanGc) -> Rect { - self.owner_window().client_rect_query(self, can_gc) + pub(crate) fn client_rect(&self) -> Rect { + self.owner_window().client_rect_query(self) } /// /// - pub(crate) fn scroll_area(&self, can_gc: CanGc) -> Rect { + pub(crate) fn scroll_area(&self) -> Rect { // "1. Let document be the element’s node document."" let document = self.owner_doc(); @@ -992,7 +992,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, can_gc); + let viewport_scrolling_area = window.scrolling_area_query(None); return Rect::new( viewport_scrolling_area.origin, viewport_scrolling_area.size.max(viewport), @@ -1002,7 +1002,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), can_gc) + window.scrolling_area_query(Some(self)) } /// @@ -1461,9 +1461,8 @@ impl Node { }) } - pub(crate) fn style(&self, can_gc: CanGc) -> Option> { - self.owner_window() - .layout_reflow(QueryMsg::StyleQuery, can_gc); + pub(crate) fn style(&self) -> Option> { + self.owner_window().layout_reflow(QueryMsg::StyleQuery); self.style_data .borrow() .as_ref() diff --git a/components/script/dom/offscreencanvasrenderingcontext2d.rs b/components/script/dom/offscreencanvasrenderingcontext2d.rs index 242e8312871..09c2f092cb2 100644 --- a/components/script/dom/offscreencanvasrenderingcontext2d.rs +++ b/components/script/dom/offscreencanvasrenderingcontext2d.rs @@ -161,8 +161,8 @@ impl OffscreenCanvasRenderingContext2DMethods } // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor - fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) { - self.context.SetShadowColor(value, can_gc) + fn SetShadowColor(&self, value: DOMString) { + self.context.SetShadowColor(value) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle @@ -171,8 +171,8 @@ impl OffscreenCanvasRenderingContext2DMethods } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { - self.context.SetStrokeStyle(value, can_gc) + fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { + self.context.SetStrokeStyle(value) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle @@ -181,8 +181,8 @@ impl OffscreenCanvasRenderingContext2DMethods } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { - self.context.SetFillStyle(value, can_gc) + fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { + self.context.SetFillStyle(value) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient @@ -269,8 +269,8 @@ impl OffscreenCanvasRenderingContext2DMethods } // https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext - fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option, can_gc: CanGc) { - self.context.FillText(text, x, y, max_width, can_gc) + fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option) { + self.context.FillText(text, x, y, max_width) } // https://html.spec.whatwg.org/multipage/#textmetrics @@ -284,8 +284,8 @@ impl OffscreenCanvasRenderingContext2DMethods } // https://html.spec.whatwg.org/multipage/#dom-context-2d-font - fn SetFont(&self, value: DOMString, can_gc: CanGc) { - self.context.SetFont(value, can_gc) + fn SetFont(&self, value: DOMString) { + self.context.SetFont(value) } // 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 3d5cc3b1f77..47bb205866f 100644 --- a/components/script/dom/paintrenderingcontext2d.rs +++ b/components/script/dom/paintrenderingcontext2d.rs @@ -343,8 +343,8 @@ impl PaintRenderingContext2DMethods for PaintRenderingCont } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { - self.canvas_state.set_stroke_style(None, value, can_gc) + fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { + self.canvas_state.set_stroke_style(None, value) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle @@ -353,8 +353,8 @@ impl PaintRenderingContext2DMethods for PaintRenderingCont } // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle - fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) { - self.canvas_state.set_fill_style(None, value, can_gc) + fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) { + self.canvas_state.set_fill_style(None, value) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient @@ -497,7 +497,7 @@ impl PaintRenderingContext2DMethods for PaintRenderingCont } // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor - fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) { - self.canvas_state.set_shadow_color(None, value, can_gc) + fn SetShadowColor(&self, value: DOMString) { + self.canvas_state.set_shadow_color(None, value) } } diff --git a/components/script/dom/pointerevent.rs b/components/script/dom/pointerevent.rs index 88238f64dd2..664737af6c2 100644 --- a/components/script/dom/pointerevent.rs +++ b/components/script/dom/pointerevent.rs @@ -233,7 +233,7 @@ impl PointerEventMethods for PointerEvent { ) -> DomRoot { let bubbles = EventBubbles::from(init.parent.parent.parent.parent.bubbles); let cancelable = EventCancelable::from(init.parent.parent.parent.parent.cancelable); - let scroll_offset = window.scroll_offset(can_gc); + let scroll_offset = window.scroll_offset(); let page_point = Point2D::new( scroll_offset.x as i32 + init.parent.clientX, scroll_offset.y as i32 + init.parent.clientY, diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index 59b4ef93035..3472c1897b8 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -329,7 +329,6 @@ impl Range { fn client_rects( &self, - can_gc: CanGc, ) -> impl Iterator> { // FIXME: For text nodes that are only partially selected, this should return the client // rect of the selected part, not the whole text node. @@ -341,7 +340,7 @@ impl Range { .following_nodes(document.upcast::()) .take_while(move |node| node != &end) .chain(iter::once(end_clone)) - .flat_map(move |node| node.content_boxes(can_gc)) + .flat_map(move |node| node.content_boxes()) } /// @@ -1153,7 +1152,7 @@ impl RangeMethods for Range { let window = start.owner_window(); let client_rects = self - .client_rects(can_gc) + .client_rects() .map(|rect| { DOMRect::new( window.upcast(), @@ -1174,7 +1173,7 @@ impl RangeMethods for Range { let window = self.start_container().owner_window(); // Step 1. Let list be the result of invoking getClientRects() on the same range this method was invoked on. - let list = self.client_rects(can_gc); + let list = self.client_rects(); // Step 2. If list is empty return a DOMRect object whose x, y, width and height members are zero. // Step 3. If all rectangles in list have zero width or height, return the first rectangle in list. diff --git a/components/script/dom/resizeobserver.rs b/components/script/dom/resizeobserver.rs index b685151c153..c56897009d9 100644 --- a/components/script/dom/resizeobserver.rs +++ b/components/script/dom/resizeobserver.rs @@ -81,7 +81,6 @@ impl ResizeObserver { &self, depth: &ResizeObservationDepth, has_active: &mut bool, - can_gc: CanGc, ) { // Step 2.1 Clear observer’s [[activeTargets]], and [[skippedTargets]]. // NOTE: This happens as part of Step 2.2 @@ -91,7 +90,7 @@ impl ResizeObserver { observation.state = Default::default(); // Step 2.2.1 If observation.isActive() is true - if let Some(size) = observation.is_active(target, can_gc) { + if let Some(size) = observation.is_active(target) { // Step 2.2.1.1 Let targetDepth be result of calculate depth for node for observation.target. let target_depth = calculate_depth_for_node(target); @@ -284,9 +283,9 @@ impl ResizeObservation { /// /// Returning an optional calculated size, instead of a boolean, /// to avoid recalculating the size in the subsequent broadcast. - fn is_active(&self, target: &Element, can_gc: CanGc) -> Option> { + fn is_active(&self, target: &Element) -> Option> { let last_reported_size = self.last_reported_sizes[0]; - let box_size = calculate_box_size(target, &self.observed_box, can_gc); + let box_size = calculate_box_size(target, &self.observed_box); 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 { Some(box_size) } else { None } @@ -301,18 +300,14 @@ fn calculate_depth_for_node(target: &Element) -> ResizeObservationDepth { } /// -fn calculate_box_size( - target: &Element, - observed_box: &ResizeObserverBoxOptions, - can_gc: CanGc, -) -> Rect { +fn calculate_box_size(target: &Element, observed_box: &ResizeObserverBoxOptions) -> Rect { match observed_box { ResizeObserverBoxOptions::Content_box => { // Note: only taking first fragment, // but the spec will expand to cover all fragments. target .upcast::() - .content_boxes(can_gc) + .content_boxes() .pop() .unwrap_or_else(Rect::zero) }, diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index aa88c142c08..79f58e6ad8f 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -659,9 +659,7 @@ impl ServoParser { assert!(!self.suspended.get()); assert!(!self.aborted.get()); - self.document - .window() - .reflow_if_reflow_timer_expired(can_gc); + self.document.window().reflow_if_reflow_timer_expired(); 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 7ab11d9e1d1..4832b26e571 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -370,12 +370,7 @@ impl ShadowRootMethods for ShadowRoot { } // https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint - fn ElementFromPoint( - &self, - x: Finite, - y: Finite, - can_gc: CanGc, - ) -> Option> { + fn ElementFromPoint(&self, x: Finite, y: Finite) -> Option> { // 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( @@ -383,7 +378,6 @@ impl ShadowRootMethods for ShadowRoot { y, None, self.document.has_browsing_context(), - can_gc, ) { Some(e) => { let retargeted_node = self @@ -396,18 +390,13 @@ impl ShadowRootMethods for ShadowRoot { } // https://drafts.csswg.org/cssom-view/#dom-document-elementsfrompoint - fn ElementsFromPoint( - &self, - x: Finite, - y: Finite, - can_gc: CanGc, - ) -> Vec> { + fn ElementsFromPoint(&self, x: Finite, y: Finite) -> Vec> { // 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(), can_gc) + .elements_from_point(x, y, None, self.document.has_browsing_context()) .iter() { let retargeted_node = self diff --git a/components/script/dom/wheelevent.rs b/components/script/dom/wheelevent.rs index 05d8cd2c03a..2c9bdb7a42d 100644 --- a/components/script/dom/wheelevent.rs +++ b/components/script/dom/wheelevent.rs @@ -204,7 +204,7 @@ impl WheelEventMethods for WheelEvent { ) -> Fallible> { let bubbles = EventBubbles::from(init.parent.parent.parent.parent.bubbles); let cancelable = EventCancelable::from(init.parent.parent.parent.parent.cancelable); - let scroll_offset = window.scroll_offset(can_gc); + let scroll_offset = window.scroll_offset(); let page_point = Point2D::::new( scroll_offset.x as i32 + init.parent.clientX, @@ -269,7 +269,6 @@ impl WheelEventMethods for WheelEvent { delta_y_arg: Finite, delta_z_arg: Finite, delta_mode_arg: u32, - can_gc: CanGc, ) { if self.upcast::().dispatching() { return; @@ -291,7 +290,6 @@ impl WheelEventMethods for WheelEvent { self.mouseevent.MetaKey(), self.mouseevent.Button(), self.mouseevent.GetRelatedTarget().as_deref(), - can_gc, ); self.delta_x.set(delta_x_arg); self.delta_y.set(delta_y_arg); diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 17bf449d0ef..0f52f3fd22e 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -1634,7 +1634,7 @@ impl WindowMethods for Window { /// fn ScrollX(&self) -> i32 { - self.scroll_offset(CanGc::note()).x as i32 + self.scroll_offset().x as i32 } // https://drafts.csswg.org/cssom-view/#dom-window-pagexoffset @@ -1644,7 +1644,7 @@ impl WindowMethods for Window { /// fn ScrollY(&self) -> i32 { - self.scroll_offset(CanGc::note()).y as i32 + self.scroll_offset().y as i32 } // https://drafts.csswg.org/cssom-view/#dom-window-pageyoffset @@ -1653,47 +1653,47 @@ impl WindowMethods for Window { } // https://drafts.csswg.org/cssom-view/#dom-window-scroll - fn Scroll(&self, options: &ScrollToOptions, can_gc: CanGc) { + fn Scroll(&self, options: &ScrollToOptions) { // 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, can_gc); + self.scroll(left, top, options.parent.behavior); } // https://drafts.csswg.org/cssom-view/#dom-window-scroll - fn Scroll_(&self, x: f64, y: f64, can_gc: CanGc) { - self.scroll(x, y, ScrollBehavior::Auto, can_gc); + fn Scroll_(&self, x: f64, y: f64) { + self.scroll(x, y, ScrollBehavior::Auto); } // https://drafts.csswg.org/cssom-view/#dom-window-scrollto fn ScrollTo(&self, options: &ScrollToOptions) { - self.Scroll(options, CanGc::note()); + self.Scroll(options); } // https://drafts.csswg.org/cssom-view/#dom-window-scrollto fn ScrollTo_(&self, x: f64, y: f64) { - self.scroll(x, y, ScrollBehavior::Auto, CanGc::note()); + self.scroll(x, y, ScrollBehavior::Auto); } // https://drafts.csswg.org/cssom-view/#dom-window-scrollby - fn ScrollBy(&self, options: &ScrollToOptions, can_gc: CanGc) { + fn ScrollBy(&self, options: &ScrollToOptions) { // Step 1 let x = options.left.unwrap_or(0.0f64); let y = options.top.unwrap_or(0.0f64); - self.ScrollBy_(x, y, can_gc); - self.scroll(x, y, options.parent.behavior, can_gc); + self.ScrollBy_(x, y); + self.scroll(x, y, options.parent.behavior); } // https://drafts.csswg.org/cssom-view/#dom-window-scrollby - fn ScrollBy_(&self, x: f64, y: f64, can_gc: CanGc) { - let scroll_offset = self.scroll_offset(can_gc); + fn ScrollBy_(&self, x: f64, y: f64) { + let scroll_offset = self.scroll_offset(); // Step 3 let left = x + scroll_offset.x as f64; // Step 4 let top = y + scroll_offset.y as f64; // Step 5 - self.scroll(left, top, ScrollBehavior::Auto, can_gc); + self.scroll(left, top, ScrollBehavior::Auto); } // https://drafts.csswg.org/cssom-view/#dom-window-resizeto @@ -2012,11 +2012,8 @@ impl WindowMethods for Window { } impl Window { - pub(crate) fn scroll_offset(&self, can_gc: CanGc) -> Vector2D { - self.scroll_offset_query_with_external_scroll_id( - self.pipeline_id().root_scroll_id(), - can_gc, - ) + pub(crate) fn scroll_offset(&self) -> Vector2D { + self.scroll_offset_query_with_external_scroll_id(self.pipeline_id().root_scroll_id()) } // https://heycam.github.io/webidl/#named-properties-object @@ -2114,7 +2111,7 @@ impl Window { } /// - pub(crate) fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior, can_gc: CanGc) { + pub(crate) fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior) { // Step 3 let xfinite = if x_.is_finite() { x_ } else { 0.0f64 }; let yfinite = if y_.is_finite() { y_ } else { 0.0f64 }; @@ -2127,7 +2124,7 @@ impl Window { // Step 7 & 8 // TODO: Consider `block-end` and `inline-end` overflow direction. - let scrolling_area = self.scrolling_area_query(None, can_gc); + let scrolling_area = self.scrolling_area_query(None); let x = xfinite .min(scrolling_area.width() as f64 - viewport.width as f64) .max(0.0f64); @@ -2137,7 +2134,7 @@ impl Window { // Step 10 //TODO handling ongoing smooth scrolling - let scroll_offset = self.scroll_offset(can_gc); + let scroll_offset = self.scroll_offset(); if x == scroll_offset.x as f64 && y == scroll_offset.y as f64 { return; } @@ -2153,7 +2150,6 @@ impl Window { self.pipeline_id().root_scroll_id(), behavior, None, - can_gc, ); } @@ -2165,7 +2161,6 @@ 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 @@ -2173,10 +2168,7 @@ impl Window { let WindowReflowResult { update_scroll_reflow_target_scrolled, .. - } = self.reflow( - ReflowGoal::UpdateScrollNode(scroll_id, Vector2D::new(x, y)), - can_gc, - ); + } = self.reflow(ReflowGoal::UpdateScrollNode(scroll_id, Vector2D::new(x, y))); // > If the scroll position did not change as a result of the user interaction or programmatic // > invocation, where no translations were applied as a result, then no scrollend event fires @@ -2218,9 +2210,15 @@ impl Window { /// /// NOTE: This method should almost never be called directly! Layout and rendering updates should /// happen as part of the HTML event loop via *update the rendering*. - fn force_reflow(&self, reflow_goal: ReflowGoal) -> WindowReflowResult { + pub(crate) fn reflow(&self, reflow_goal: ReflowGoal) -> WindowReflowResult { let document = self.Document(); - document.ensure_safe_to_run_script_or_layout(); + + // Never reflow inactive Documents. + if !document.is_fully_active() { + return WindowReflowResult::new_empty(); + } + + self.Document().ensure_safe_to_run_script_or_layout(); // If layouts are blocked, we block all layouts that are for display only. Other // layouts (for queries and scrolling) are not blocked, as they do not display @@ -2314,88 +2312,60 @@ impl Window { } } - /// Reflows the page if it's possible to do so and the page is dirty. Returns true if layout - /// actually happened and produced a new display list, false otherwise. - /// - /// NOTE: This method should almost never be called directly! Layout and rendering updates - /// should happen as part of the HTML event loop via *update the rendering*. Currerntly, the - /// only exceptions are script queries and scroll requests. - pub(crate) fn reflow(&self, reflow_goal: ReflowGoal, can_gc: CanGc) -> WindowReflowResult { - // Never reflow inactive Documents. - if !self.Document().is_fully_active() { - return WindowReflowResult::new_empty(); + pub(crate) fn maybe_send_idle_document_state_to_constellation(&self) { + if !opts::get().wait_for_stable_image { + return; } - // Count the pending web fonts before layout, in case a font loads during the layout. - let waiting_for_web_fonts_to_load = self.font_context.web_fonts_still_loading() != 0; - - self.Document().ensure_safe_to_run_script_or_layout(); - - let updating_the_rendering = reflow_goal == ReflowGoal::UpdateTheRendering; - let reflow_result = self.force_reflow(reflow_goal); + if self.has_sent_idle_message.get() { + return; + } let document = self.Document(); - 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: - // > A FontFaceSet is pending on the environment if any of the following are true: - // > - the document is still loading - // > - the document has pending stylesheet requests - // > - the document has pending layout operations which might cause the user agent to request - // > a font, or which depend on recently-loaded fonts - // - // Thus, we are queueing promise resolution here. This reflow should have been triggered by - // a "rendering opportunity" in `ScriptThread::handle_web_font_loaded, which should also - // make sure a microtask checkpoint happens, triggering the promise callback. - if !waiting_for_web_fonts_to_load && is_ready_state_complete { - font_face_set.fulfill_ready_promise_if_needed(can_gc); + if document.ReadyState() != DocumentReadyState::Complete { + return; + } + + // Checks if the html element has reftest-wait attribute present. + // See http://testthewebforward.org/docs/reftests.html + // and https://web-platform-tests.org/writing-tests/crashtest.html + if document.GetDocumentElement().is_some_and(|elem| { + elem.has_class(&atom!("reftest-wait"), CaseSensitivity::CaseSensitive) || + elem.has_class(&Atom::from("test-wait"), CaseSensitivity::CaseSensitive) + }) { + return; + } + + if self.font_context.web_fonts_still_loading() != 0 { + return; + } + + if !self.pending_layout_images.borrow().is_empty() || + !self.pending_images_for_rasterization.borrow().is_empty() + { + return; + } + + if self.Document().needs_rendering_update() { + return; } - // If writing a screenshot, check if the script has reached a state - // where it's safe to write the image. This means that: - // 1) The reflow is for display (otherwise it could be a query) - // 2) The html element doesn't contain the 'reftest-wait' class - // 3) The load event has fired. // When all these conditions are met, notify the constellation // that this pipeline is ready to write the image (from the script thread // perspective at least). - if opts::get().wait_for_stable_image && updating_the_rendering { - // Checks if the html element has reftest-wait attribute present. - // See http://testthewebforward.org/docs/reftests.html - // and https://web-platform-tests.org/writing-tests/crashtest.html - let html_element = document.GetDocumentElement(); - let reftest_wait = html_element.is_some_and(|elem| { - elem.has_class(&atom!("reftest-wait"), CaseSensitivity::CaseSensitive) || - elem.has_class(&Atom::from("test-wait"), CaseSensitivity::CaseSensitive) - }); - - let has_sent_idle_message = self.has_sent_idle_message.get(); - let no_pending_images = self.pending_layout_images.borrow().is_empty() && - self.pending_images_for_rasterization.borrow().is_empty(); - - if !has_sent_idle_message && - is_ready_state_complete && - !reftest_wait && - no_pending_images && - !waiting_for_web_fonts_to_load - { - debug!( - "{:?}: Sending DocumentState::Idle to Constellation", - self.pipeline_id() - ); - let event = ScriptToConstellationMessage::SetDocumentState(DocumentState::Idle); - self.send_to_constellation(event); - self.has_sent_idle_message.set(true); - } - } - - reflow_result + debug!( + "{:?}: Sending DocumentState::Idle to Constellation", + self.pipeline_id() + ); + self.send_to_constellation(ScriptToConstellationMessage::SetDocumentState( + DocumentState::Idle, + )); + self.has_sent_idle_message.set(true); } /// If parsing has taken a long time and reflows are still waiting for the `load` event, /// start allowing them. See . - pub(crate) fn reflow_if_reflow_timer_expired(&self, can_gc: CanGc) { + pub(crate) fn reflow_if_reflow_timer_expired(&self) { // Only trigger a long parsing time reflow if we are in the first parse of `` // and it started more than `INITIAL_REFLOW_DELAY` ago. if !matches!( @@ -2404,7 +2374,7 @@ impl Window { ) { return; } - self.allow_layout_if_necessary(can_gc); + self.allow_layout_if_necessary(); } /// Block layout for this `Window` until parsing is done. If parsing takes a long time, @@ -2423,7 +2393,7 @@ impl Window { /// Inform the [`Window`] that layout is allowed either because `load` has happened /// or because parsing the `` took so long that we cannot wait any longer. - pub(crate) fn allow_layout_if_necessary(&self, can_gc: CanGc) { + pub(crate) fn allow_layout_if_necessary(&self) { if matches!( self.layout_blocker.get(), LayoutBlocker::FiredLoadEventOrParsingTimerExpired @@ -2445,7 +2415,7 @@ impl Window { // iframe size updates. // // See - self.Document().update_the_rendering(can_gc); + self.Document().update_the_rendering(); } pub(crate) fn layout_blocked(&self) -> bool { @@ -2471,17 +2441,16 @@ impl Window { } /// Trigger a reflow that is required by a certain queries. - pub(crate) fn layout_reflow(&self, query_msg: QueryMsg, can_gc: CanGc) { - self.reflow(ReflowGoal::LayoutQuery(query_msg), can_gc); + pub(crate) fn layout_reflow(&self, query_msg: QueryMsg) { + self.reflow(ReflowGoal::LayoutQuery(query_msg)); } pub(crate) fn resolved_font_style_query( &self, node: &Node, value: String, - can_gc: CanGc, ) -> Option> { - self.layout_reflow(QueryMsg::ResolvedFontStyleQuery, can_gc); + self.layout_reflow(QueryMsg::ResolvedFontStyleQuery); let document = self.Document(); let animations = document.animations().sets.clone(); @@ -2500,20 +2469,20 @@ impl Window { .query_content_box(node.to_trusted_node_address()) } - pub(crate) fn content_box_query(&self, node: &Node, can_gc: CanGc) -> Option> { - self.layout_reflow(QueryMsg::ContentBox, can_gc); + pub(crate) fn content_box_query(&self, node: &Node) -> Option> { + self.layout_reflow(QueryMsg::ContentBox); self.content_box_query_unchecked(node) } - pub(crate) fn content_boxes_query(&self, node: &Node, can_gc: CanGc) -> Vec> { - self.layout_reflow(QueryMsg::ContentBoxes, can_gc); + pub(crate) fn content_boxes_query(&self, node: &Node) -> Vec> { + self.layout_reflow(QueryMsg::ContentBoxes); self.layout .borrow() .query_content_boxes(node.to_trusted_node_address()) } - pub(crate) fn client_rect_query(&self, node: &Node, can_gc: CanGc) -> UntypedRect { - self.layout_reflow(QueryMsg::ClientRectQuery, can_gc); + pub(crate) fn client_rect_query(&self, node: &Node) -> UntypedRect { + self.layout_reflow(QueryMsg::ClientRectQuery); self.layout .borrow() .query_client_rect(node.to_trusted_node_address()) @@ -2521,35 +2490,26 @@ 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(crate) fn scrolling_area_query( - &self, - node: Option<&Node>, - can_gc: CanGc, - ) -> UntypedRect { - self.layout_reflow(QueryMsg::ScrollingAreaOrOffsetQuery, can_gc); + pub(crate) fn scrolling_area_query(&self, node: Option<&Node>) -> UntypedRect { + self.layout_reflow(QueryMsg::ScrollingAreaOrOffsetQuery); self.layout .borrow() .query_scrolling_area(node.map(Node::to_trusted_node_address)) } - pub(crate) fn scroll_offset_query( - &self, - node: &Node, - can_gc: CanGc, - ) -> Vector2D { + pub(crate) fn scroll_offset_query(&self, node: &Node) -> Vector2D { let external_scroll_id = ExternalScrollId( combine_id_with_fragment_type(node.to_opaque().id(), FragmentType::FragmentBody), self.pipeline_id().into(), ); - self.scroll_offset_query_with_external_scroll_id(external_scroll_id, can_gc) + self.scroll_offset_query_with_external_scroll_id(external_scroll_id) } fn scroll_offset_query_with_external_scroll_id( &self, external_scroll_id: ExternalScrollId, - can_gc: CanGc, ) -> Vector2D { - self.layout_reflow(QueryMsg::ScrollingAreaOrOffsetQuery, can_gc); + self.layout_reflow(QueryMsg::ScrollingAreaOrOffsetQuery); self.scroll_offset_query_with_external_scroll_id_no_reflow(external_scroll_id) } @@ -2571,7 +2531,6 @@ impl Window { x_: f64, y_: f64, behavior: ScrollBehavior, - can_gc: CanGc, ) { let scroll_id = ExternalScrollId( combine_id_with_fragment_type( @@ -2590,7 +2549,6 @@ impl Window { scroll_id, behavior, Some(element), - can_gc, ); } @@ -2599,9 +2557,8 @@ impl Window { element: TrustedNodeAddress, pseudo: Option, property: PropertyId, - can_gc: CanGc, ) -> DOMString { - self.layout_reflow(QueryMsg::ResolvedStyleQuery, can_gc); + self.layout_reflow(QueryMsg::ResolvedStyleQuery); let document = self.Document(); let animations = document.animations().sets.clone(); @@ -2620,10 +2577,9 @@ impl Window { pub(crate) fn get_iframe_viewport_details_if_known( &self, browsing_context_id: BrowsingContextId, - can_gc: CanGc, ) -> Option { // Reflow might fail, but do a best effort to return the right size. - self.layout_reflow(QueryMsg::InnerWindowDimensionsQuery, can_gc); + self.layout_reflow(QueryMsg::InnerWindowDimensionsQuery); self.Document() .iframes() .get(browsing_context_id) @@ -2634,9 +2590,8 @@ impl Window { pub(crate) fn offset_parent_query( &self, node: &Node, - can_gc: CanGc, ) -> (Option>, UntypedRect) { - self.layout_reflow(QueryMsg::OffsetParentQuery, can_gc); + self.layout_reflow(QueryMsg::OffsetParentQuery); let response = self .layout .borrow() @@ -2652,9 +2607,8 @@ impl Window { &self, node: &Node, point_in_node: UntypedPoint2D, - can_gc: CanGc, ) -> Option { - self.layout_reflow(QueryMsg::TextIndexQuery, can_gc); + self.layout_reflow(QueryMsg::TextIndexQuery); self.layout .borrow() .query_text_indext(node.to_opaque(), point_in_node) @@ -2710,7 +2664,7 @@ impl Window { load_data.url.clone(), history_handling, )); - doc.check_and_scroll_fragment(fragment, can_gc); + doc.check_and_scroll_fragment(fragment); let this = Trusted::new(self); let old_url = doc.url().into_string(); let new_url = load_data.url.clone().into_string(); @@ -2832,6 +2786,11 @@ impl Window { self.unhandled_resize_event.borrow_mut().take() } + /// Whether or not this [`Window`] has any resize events that have not been processed. + pub(crate) fn has_unhandled_resize_event(&self) -> bool { + self.unhandled_resize_event.borrow().is_some() + } + pub(crate) fn set_viewport_size(&self, new_viewport_size: UntypedSize2D) { let new_viewport_size = Size2D::new( Au::from_f32_px(new_viewport_size.width), diff --git a/components/script/microtask.rs b/components/script/microtask.rs index 3f5969e7b7f..b034e8154a3 100644 --- a/components/script/microtask.rs +++ b/components/script/microtask.rs @@ -100,8 +100,6 @@ impl MicrotaskQueue { // Step 1 self.performing_a_microtask_checkpoint.set(true); - debug!("Now performing a microtask checkpoint"); - // Steps 2 while !self.microtask_queue.borrow().is_empty() { rooted_vec!(let mut pending_queue); diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 28d44487f13..3a527f7ef5c 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -200,7 +200,8 @@ type NodeIdSet = HashSet; #[cfg_attr(crown, allow(crown::unrooted_must_root))] pub struct ScriptThread { /// - last_render_opportunity_time: DomRefCell>, + last_render_opportunity_time: Cell>, + /// The documents for pipelines managed by this thread documents: DomRefCell, /// The window proxies known by this thread @@ -348,7 +349,7 @@ pub struct ScriptThread { /// [`ScriptThreadMessage::TickAllAnimations`] message or because the [`ScriptThread`] /// itself is managing animations the the timer fired triggering a [`ScriptThread`]-based /// animation tick. - has_pending_animation_tick: Arc, + needs_rendering_update: Arc, debugger_global: Dom, } @@ -600,8 +601,7 @@ impl ScriptThread { } pub(crate) fn set_has_pending_animation_tick(&self) { - self.has_pending_animation_tick - .store(true, Ordering::Relaxed); + self.needs_rendering_update.store(true, Ordering::Relaxed); } /// Step 13 of @@ -999,7 +999,7 @@ impl ScriptThread { layout_factory, relative_mouse_down_point: Cell::new(Point2D::zero()), scheduled_script_thread_animation_timer: Default::default(), - has_pending_animation_tick: Arc::new(AtomicBool::new(false)), + needs_rendering_update: Arc::new(AtomicBool::new(false)), debugger_global: debugger_global.as_traced(), } } @@ -1208,37 +1208,50 @@ impl ScriptThread { })); } + fn cancel_scheduled_update_the_rendering(&self) { + if let Some(timer_id) = self + .scheduled_script_thread_animation_timer + .borrow_mut() + .take() + { + self.timer_scheduler.borrow_mut().cancel_timer(timer_id); + } + } + + fn schedule_update_the_rendering_timer_if_necessary(&self, delay: Duration) { + if self + .scheduled_script_thread_animation_timer + .borrow() + .is_some() + { + return; + } + + debug!("Scheduling ScriptThread animation frame."); + let trigger_script_thread_animation = self.needs_rendering_update.clone(); + let timer_id = self.schedule_timer(TimerEventRequest { + callback: Box::new(move || { + trigger_script_thread_animation.store(true, Ordering::Relaxed); + }), + duration: delay, + }); + + *self.scheduled_script_thread_animation_timer.borrow_mut() = Some(timer_id); + } + /// /// /// Attempt to update the rendering and then do a microtask checkpoint if rendering was actually /// updated. pub(crate) fn update_the_rendering(&self, can_gc: CanGc) { - *self.last_render_opportunity_time.borrow_mut() = Some(Instant::now()); - - let is_animation_tick = self.has_pending_animation_tick.load(Ordering::Relaxed); - if is_animation_tick { - self.has_pending_animation_tick - .store(false, Ordering::Relaxed); - // If this is an animation tick, cancel any upcoming ScriptThread-based animation timer. - // This tick serves the purpose and we to limit animation ticks if some are coming from - // the renderer. - if let Some(timer_id) = self - .scheduled_script_thread_animation_timer - .borrow_mut() - .take() - { - self.timer_scheduler.borrow_mut().cancel_timer(timer_id); - } - } + self.last_render_opportunity_time.set(Some(Instant::now())); + self.cancel_scheduled_update_the_rendering(); + self.needs_rendering_update.store(false, Ordering::Relaxed); if !self.can_continue_running_inner() { return; } - let any_animations_running = self.documents.borrow().iter().any(|(_, document)| { - document.is_fully_active() && document.animations().running_animation_count() != 0 - }); - // TODO: The specification says to filter out non-renderable documents, // as well as those for which a rendering update would be unnecessary, // but this isn't happening here. @@ -1247,13 +1260,6 @@ impl ScriptThread { // has pending initial observation targets // https://w3c.github.io/IntersectionObserver/#pending-initial-observation - // If we aren't explicitly running rAFs, this update wasn't requested by the compositor, - // and we are running animations, then wait until the compositor tells us it is time to - // update the rendering via a TickAllAnimations message. - if !is_animation_tick && any_animations_running { - return; - } - // > 2. Let docs be all fully active Document objects whose relevant agent's event loop // > is eventLoop, sorted arbitrarily except that the following conditions must be // > met: @@ -1326,14 +1332,12 @@ impl ScriptThread { // > 14. For each doc of docs, run the animation frame callbacks for doc, passing // > in the relative high resolution time given frameTimestamp and doc's // > relevant global object as the timestamp. - if is_animation_tick { - document.run_the_animation_frame_callbacks(can_gc); - } + document.run_the_animation_frame_callbacks(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, can_gc) { + while document.gather_active_resize_observations_at_depth(&depth) { // Note: this will reflow the doc. depth = document.broadcast_active_resize_observations(can_gc); } @@ -1358,7 +1362,7 @@ impl ScriptThread { // > Step 22: For each doc of docs, update the rendering or user interface of // > doc and its node navigable to reflect the current state. - saw_any_reflows = document.update_the_rendering(can_gc) || saw_any_reflows; + saw_any_reflows = document.update_the_rendering() || saw_any_reflows; // TODO: Process top layer removals according to // https://drafts.csswg.org/css-position-4/#process-top-layer-removals. @@ -1368,106 +1372,90 @@ impl ScriptThread { // should be run in a task and a microtask checkpoint is always done when running tasks. self.perform_a_microtask_checkpoint(can_gc); - // If there are pending reflows, they were probably caused by the execution of - // the microtask checkpoint above and we should spin the event loop one more - // time to resolve them. - self.schedule_rendering_opportunity_if_necessary(); - - // If this was a animation update request, then potentially schedule a new - // animation update in the case that the compositor might not do it due to - // not receiving any display lists. - if is_animation_tick { - self.schedule_script_thread_animation_tick_if_necessary(saw_any_reflows); - } + self.maybe_schedule_rendering_opportunity_after_rendering_update(saw_any_reflows); } - // If there are any pending reflows and we are not having rendering opportunities - // driven by the compositor, then schedule the next rendering opportunity. - // - // TODO: This is a workaround until rendering opportunities can be triggered from a - // timer in the script thread. - fn schedule_rendering_opportunity_if_necessary(&self) { - // If any Document has active animations of rAFs, then we should be receiving - // regular rendering opportunities from the compositor (or fake animation frame - // ticks). In this case, don't schedule an opportunity, just wait for the next - // one. + fn maybe_schedule_rendering_opportunity_after_rendering_update(&self, saw_any_reflows: bool) { + // If there are any pending reflows and we are not having rendering opportunities + // immediately after running "update the rendering," run it one more time. if self.documents.borrow().iter().any(|(_, document)| { - document.is_fully_active() && - (document.animations().running_animation_count() != 0 || - document.has_active_request_animation_frame_callbacks()) + document.needs_rendering_update() || + (saw_any_reflows && document.has_resize_observers()) }) { - return; + self.cancel_scheduled_update_the_rendering(); + self.schedule_update_the_rendering_timer_if_necessary(Duration::ZERO); } - let Some((_, document)) = self.documents.borrow().iter().find(|(_, document)| { - document.is_fully_active() && - !document.window().layout_blocked() && - !document.restyle_reason().is_empty() - }) else { - return; - }; - - // Queues a task to update the rendering. - // - // - // Note: The specification says to queue a task using the navigable's active - // window, but then updates the rendering for all documents. - // - // This task is empty because any new IPC messages in the ScriptThread trigger a - // rendering update when animations are not running. - let _realm = enter_realm(&*document); - document - .owner_global() - .task_manager() - .rendering_task_source() - .queue_unconditionally(task!(update_the_rendering: move || { })); + if !saw_any_reflows && + self.documents.borrow().iter().any(|(_, document)| { + document.is_fully_active() && + !document.window().throttled() && + (document.animations().running_animation_count() != 0 || + document.has_active_request_animation_frame_callbacks()) + }) + { + const SCRIPT_THREAD_ANIMATION_TICK_DELAY: Duration = Duration::from_millis(30); + self.schedule_update_the_rendering_timer_if_necessary( + SCRIPT_THREAD_ANIMATION_TICK_DELAY, + ); + } } - /// The renderer triggers animation ticks based on the arrival and painting of new - /// display lists. In the case that a `WebView` is animating or has a - /// requestAnimationFrame callback, it may be that an animation tick reflow does - /// not change anything and thus does not send a new display list to the renderer. - /// If that's the case, we need to schedule a ScriptThread-based animation update - /// (to avoid waking the renderer up). - fn schedule_script_thread_animation_tick_if_necessary(&self, saw_any_reflows: bool) { - if saw_any_reflows { + fn maybe_schedule_rendering_opportunity_after_ipc_message(&self) { + // If no document needs a rendering update, exit early to avoid doing more work. + if !self + .documents + .borrow() + .iter() + .any(|(_, document)| document.needs_rendering_update()) + { return; } - // Always schedule a ScriptThread-based animation tick, unless none of the - // documents are active and have animations running and/or rAF callbacks. - if !self.documents.borrow().iter().any(|(_, document)| { - document.is_fully_active() && - !document.window().throttled() && - (document.animations().running_animation_count() != 0 || - document.has_active_request_animation_frame_callbacks()) - }) { - return; - } + // Wait 20 milliseconds between frames triggered by the script thread itself. This + // should, in theory, allow compositor-based ticks to arrive sooner. + const SCRIPT_THREAD_ANIMATION_TICK_DELAY: Duration = Duration::from_millis(20); + let time_since_last_rendering_opportunity = self + .last_render_opportunity_time + .get() + .map(|last_render_opportunity_time| Instant::now() - last_render_opportunity_time) + .unwrap_or(Duration::MAX) + .min(SCRIPT_THREAD_ANIMATION_TICK_DELAY); - /// The amount of time between ScriptThread animation ticks when nothing is - /// changing. In order to be more efficient, only tick at around 30 frames a - /// second, which also gives time for any renderer ticks to come in and cancel - /// this tick. A renderer tick might happen for a variety of reasons, such as a - /// Pipeline in another ScriptThread producing a display list. - const SCRIPT_THREAD_ANIMATION_TICK_DELAY: u64 = 30; + //eprintln!(" - scheduling update\n"); + //// If it's been more than the time of a single frame the last rendering opportunity, + //// just run it now. + //if time_since_last_rendering_opportunity > SCRIPT_THREAD_ANIMATION_TICK_DELAY { + // println!(" - running immediately"); + // self.update_the_rendering(can_gc); + // return; + //} - debug!("Scheduling ScriptThread animation frame."); - let trigger_script_thread_animation = self.has_pending_animation_tick.clone(); - let timer_id = self.schedule_timer(TimerEventRequest { - callback: Box::new(move || { - trigger_script_thread_animation.store(true, Ordering::Relaxed); - }), - duration: Duration::from_millis(SCRIPT_THREAD_ANIMATION_TICK_DELAY), - }); - - let mut scheduled_script_thread_animation_timer = - self.scheduled_script_thread_animation_timer.borrow_mut(); - assert!( - scheduled_script_thread_animation_timer.is_none(), - "Should never schedule a new timer when one is already scheduled." + self.schedule_update_the_rendering_timer_if_necessary( + SCRIPT_THREAD_ANIMATION_TICK_DELAY - time_since_last_rendering_opportunity, ); - *scheduled_script_thread_animation_timer = Some(timer_id); + } + + fn maybe_fulfill_font_ready_promises(&self, can_gc: CanGc) { + let mut sent_message = false; + for (_, document) in self.documents.borrow().iter() { + sent_message = document.maybe_fulfill_font_ready_promise(can_gc) || sent_message; + } + + if sent_message { + self.perform_a_microtask_checkpoint(can_gc); + } + } + + fn maybe_send_document_state_messages(&self) { + if !opts::get().wait_for_stable_image { + return; + } + for (_, document) in self.documents.borrow().iter() { + document + .window() + .maybe_send_idle_document_state_to_constellation(); + } } /// Handle incoming messages from other tasks and the task queue. @@ -1679,10 +1667,13 @@ impl ScriptThread { docs.clear(); } - // Update the rendering whenever we receive an IPC message. This may not actually do anything if - // we are running animations and the compositor hasn't requested a new frame yet via a TickAllAnimatons - // message. - self.update_the_rendering(can_gc); + if self.needs_rendering_update.load(Ordering::Relaxed) { + self.update_the_rendering(can_gc); + } + + self.maybe_fulfill_font_ready_promises(can_gc); + self.maybe_schedule_rendering_opportunity_after_ipc_message(); + self.maybe_send_document_state_messages(); true } @@ -2194,7 +2185,7 @@ impl ScriptThread { devtools::handle_get_selectors(&documents, id, node_id, reply, can_gc) }, DevtoolScriptControlMsg::GetComputedStyle(id, node_id, reply) => { - devtools::handle_get_computed_style(&documents, id, node_id, reply, can_gc) + devtools::handle_get_computed_style(&documents, id, node_id, reply) }, DevtoolScriptControlMsg::GetLayout(id, node_id, reply) => { devtools::handle_get_layout(&documents, id, node_id, reply, can_gc) @@ -2317,7 +2308,6 @@ impl ScriptThread { selector, partial, reply, - can_gc, ) }, WebDriverScriptCommand::FindElementsTagName(selector, reply) => { @@ -2359,7 +2349,6 @@ impl ScriptThread { selector, partial, reply, - can_gc, ), WebDriverScriptCommand::FindElementElementsTagName(selector, element_id, reply) => { webdriver_handlers::handle_find_element_elements_tag_name( @@ -2406,7 +2395,6 @@ impl ScriptThread { selector, partial, reply, - can_gc, ), WebDriverScriptCommand::FindShadowElementsTagName(selector, shadow_root_id, reply) => { webdriver_handlers::handle_find_shadow_elements_tag_name( @@ -2489,14 +2477,7 @@ impl ScriptThread { ) }, WebDriverScriptCommand::GetElementCSS(node_id, name, reply) => { - webdriver_handlers::handle_get_css( - &documents, - pipeline_id, - node_id, - name, - reply, - can_gc, - ) + 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, can_gc) @@ -2511,7 +2492,7 @@ impl ScriptThread { ) }, WebDriverScriptCommand::GetElementText(node_id, reply) => { - webdriver_handlers::handle_get_text(&documents, pipeline_id, node_id, reply, can_gc) + webdriver_handlers::handle_get_text(&documents, pipeline_id, node_id, reply) }, WebDriverScriptCommand::GetElementInViewCenterPoint(node_id, reply) => { webdriver_handlers::handle_get_element_in_view_center_point( diff --git a/components/script/task_manager.rs b/components/script/task_manager.rs index b81ec1e86f0..2c012416165 100644 --- a/components/script/task_manager.rs +++ b/components/script/task_manager.rs @@ -145,7 +145,6 @@ impl TaskManager { task_source_functions!(self, performance_timeline_task_source, PerformanceTimeline); task_source_functions!(self, port_message_queue, PortMessage); task_source_functions!(self, remote_event_task_source, RemoteEvent); - task_source_functions!(self, rendering_task_source, Rendering); task_source_functions!(self, timer_task_source, Timer); task_source_functions!(self, user_interaction_task_source, UserInteraction); task_source_functions!(self, websocket_task_source, WebSocket); diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 865aa01423d..3de4c44e959 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -194,14 +194,13 @@ fn matching_links( links: &NodeList, link_text: String, partial: bool, - can_gc: CanGc, ) -> impl Iterator + '_ { links .iter() .filter(move |node| { let content = node .downcast::() - .map(|element| element.InnerText(can_gc)) + .map(|element| element.InnerText()) .map_or("".to_owned(), String::from) .trim() .to_owned(); @@ -218,7 +217,6 @@ fn all_matching_links( root_node: &Node, link_text: String, partial: bool, - can_gc: CanGc, ) -> Result, ErrorStatus> { // // Step 7.2. If a DOMException, SyntaxError, XPathException, or other error occurs @@ -226,7 +224,7 @@ fn all_matching_links( root_node .query_selector_all(DOMString::from("a")) .map_err(|_| ErrorStatus::InvalidSelector) - .map(|nodes| matching_links(&nodes, link_text, partial, can_gc).collect()) + .map(|nodes| matching_links(&nodes, link_text, partial).collect()) } #[allow(unsafe_code)] @@ -749,7 +747,6 @@ pub(crate) fn handle_find_elements_link_text( selector: String, partial: bool, reply: IpcSender, ErrorStatus>>, - can_gc: CanGc, ) { match retrieve_document_and_check_root_existence(documents, pipeline) { Ok(document) => reply @@ -757,7 +754,6 @@ pub(crate) fn handle_find_elements_link_text( document.upcast::(), selector.clone(), partial, - can_gc, )) .unwrap(), Err(error) => reply.send(Err(error)).unwrap(), @@ -896,12 +892,11 @@ pub(crate) fn handle_find_element_elements_link_text( selector: String, partial: bool, reply: IpcSender, ErrorStatus>>, - can_gc: CanGc, ) { reply .send( get_known_element(documents, pipeline, element_id).and_then(|element| { - all_matching_links(element.upcast::(), selector.clone(), partial, can_gc) + all_matching_links(element.upcast::(), selector.clone(), partial) }), ) .unwrap(); @@ -986,17 +981,11 @@ pub(crate) fn handle_find_shadow_elements_link_text( selector: String, partial: bool, reply: IpcSender, ErrorStatus>>, - can_gc: CanGc, ) { reply .send( get_known_shadow_root(documents, pipeline, shadow_root_id).and_then(|shadow_root| { - all_matching_links( - shadow_root.upcast::(), - selector.clone(), - partial, - can_gc, - ) + all_matching_links(shadow_root.upcast::(), selector.clone(), partial) }), ) .unwrap(); @@ -1540,14 +1529,13 @@ pub(crate) fn handle_get_text( pipeline: PipelineId, node_id: String, reply: IpcSender>, - can_gc: CanGc, ) { reply .send( get_known_element(documents, pipeline, node_id).map(|element| { element .downcast::() - .map(|htmlelement| htmlelement.InnerText(can_gc).to_string()) + .map(|htmlelement| htmlelement.InnerText().to_string()) .unwrap_or_else(|| { element .upcast::() @@ -1652,7 +1640,6 @@ pub(crate) fn handle_get_css( node_id: String, name: String, reply: IpcSender>, - can_gc: CanGc, ) { reply .send( @@ -1661,7 +1648,7 @@ pub(crate) fn handle_get_css( String::from( window .GetComputedStyle(&element, None) - .GetPropertyValue(DOMString::from(name), can_gc), + .GetPropertyValue(DOMString::from(name)), ) }), ) @@ -1912,7 +1899,7 @@ fn is_element_in_view(element: &Element, document: &Document, can_gc: CanGc) -> // An element is said to have pointer events disabled // if the resolved value of its "pointer-events" style property is "none". let pointer_events_enabled = element - .style(can_gc) + .style() .is_none_or(|style| style.get_inherited_ui().pointer_events != PointerEvents::None); // An element is in view if it is a member of its own pointer-interactable paint tree, @@ -1939,7 +1926,6 @@ fn get_element_pointer_interactable_paint_tree( Some(center_point) => document.ElementsFromPoint( Finite::wrap(center_point.x as f64), Finite::wrap(center_point.y as f64), - can_gc, ), None => Vec::new(), } diff --git a/components/script_bindings/codegen/Bindings.conf b/components/script_bindings/codegen/Bindings.conf index e356cb52b53..60791a0b66e 100644 --- a/components/script_bindings/codegen/Bindings.conf +++ b/components/script_bindings/codegen/Bindings.conf @@ -80,12 +80,8 @@ DOMInterfaces = { 'canGc': ['GetSize'], }, -'CanvasGradient': { - 'canGc': ['AddColorStop'], -}, - 'CanvasRenderingContext2D': { - 'canGc': ['GetTransform','GetImageData', 'CreateImageData', 'CreateImageData_', 'SetFont', 'FillText', 'MeasureText', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor', 'CreateLinearGradient', 'CreatePattern', 'CreateRadialGradient'], + 'canGc': ['GetTransform','GetImageData', 'CreateImageData', 'CreateImageData_', 'MeasureText', 'CreateLinearGradient', 'CreatePattern', 'CreateRadialGradient'], }, 'CharacterData': { @@ -146,7 +142,7 @@ DOMInterfaces = { }, 'CSSStyleDeclaration': { - 'canGc': ['RemoveProperty', 'SetCssText', 'GetPropertyValue', 'SetProperty', 'CssFloat', 'SetCssFloat'] + 'canGc': ['RemoveProperty', 'SetCssText', 'SetProperty', 'SetCssFloat'] }, 'CustomElementRegistry': { @@ -172,7 +168,7 @@ DOMInterfaces = { 'Document': { 'additionalTraits': ["crate::interfaces::DocumentHelpers"], - 'canGc': ['Close', 'CreateElement', 'CreateElementNS', 'ImportNode', 'SetTitle', 'Write', 'Writeln', 'CreateEvent', 'CreateRange', 'Open', 'Open_', 'CreateComment', 'CreateAttribute', 'CreateAttributeNS', 'CreateDocumentFragment', 'CreateTextNode', 'CreateCDATASection', 'CreateProcessingInstruction', 'Prepend', 'Append', 'ReplaceChildren', 'SetBgColor', 'SetFgColor', 'Fonts', 'ElementFromPoint', 'ElementsFromPoint', 'GetScrollingElement', 'ExitFullscreen', 'CreateExpression', 'CreateNSResolver', 'Evaluate', 'StyleSheets', 'Implementation', 'GetElementsByTagName', 'GetElementsByTagNameNS', 'GetElementsByClassName', 'AdoptNode', 'CreateNodeIterator', 'SetBody', 'GetElementsByName', 'Images', 'Embeds', 'Plugins', 'Links', 'Forms', 'Scripts', 'Anchors', 'Applets', 'Children', 'GetSelection', 'NamedGetter', 'AdoptedStyleSheets'], + 'canGc': ['Close', 'CreateElement', 'CreateElementNS', 'ImportNode', 'SetTitle', 'Write', 'Writeln', 'CreateEvent', 'CreateRange', 'Open', 'Open_', 'CreateComment', 'CreateAttribute', 'CreateAttributeNS', 'CreateDocumentFragment', 'CreateTextNode', 'CreateCDATASection', 'CreateProcessingInstruction', 'Prepend', 'Append', 'ReplaceChildren', 'SetBgColor', 'SetFgColor', 'Fonts', 'ExitFullscreen', 'CreateExpression', 'CreateNSResolver', 'Evaluate', 'StyleSheets', 'Implementation', 'GetElementsByTagName', 'GetElementsByTagNameNS', 'GetElementsByClassName', 'AdoptNode', 'CreateNodeIterator', 'SetBody', 'GetElementsByName', 'Images', 'Embeds', 'Plugins', 'Links', 'Forms', 'Scripts', 'Anchors', 'Applets', 'Children', 'GetSelection', 'NamedGetter', 'AdoptedStyleSheets'], }, 'DissimilarOriginWindow': { @@ -236,7 +232,7 @@ DOMInterfaces = { }, 'Element': { - 'canGc': ['SetHTMLUnsafe', 'SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect', 'InsertAdjacentText', 'ToggleAttribute', 'SetAttribute', 'SetAttributeNS', 'SetId','SetClassName','Prepend','Append','ReplaceChildren','Before','After','ReplaceWith', 'SetRole', 'SetAriaAtomic', 'SetAriaAutoComplete', 'SetAriaBrailleLabel', 'SetAriaBrailleRoleDescription', 'SetAriaBusy', 'SetAriaChecked', 'SetAriaColCount', 'SetAriaColIndex', 'SetAriaColIndexText', 'SetAriaColSpan', 'SetAriaCurrent', 'SetAriaDescription', 'SetAriaDisabled', 'SetAriaExpanded', 'SetAriaHasPopup', 'SetAriaHidden', 'SetAriaInvalid', 'SetAriaKeyShortcuts', 'SetAriaLabel', 'SetAriaLevel', 'SetAriaLive', 'SetAriaModal', 'SetAriaMultiLine', 'SetAriaMultiSelectable', 'SetAriaOrientation', 'SetAriaPlaceholder', 'SetAriaPosInSet', 'SetAriaPressed','SetAriaReadOnly', 'SetAriaRelevant', 'SetAriaRequired', 'SetAriaRoleDescription', 'SetAriaRowCount', 'SetAriaRowIndex', 'SetAriaRowIndexText', 'SetAriaRowSpan', 'SetAriaSelected', 'SetAriaSetSize','SetAriaSort', 'SetAriaValueMax', 'SetAriaValueMin', 'SetAriaValueNow', 'SetAriaValueText', 'SetScrollTop', 'SetScrollLeft', 'Scroll', 'Scroll_', 'ScrollBy', 'ScrollBy_', 'ScrollWidth', 'ScrollHeight', 'ScrollTop', 'ScrollLeft', 'ClientTop', 'ClientLeft', 'ClientWidth', 'ClientHeight', 'RequestFullscreen', 'GetHTML', 'GetInnerHTML', 'GetOuterHTML', 'ClassList', 'Attributes', 'SetAttributeNode', 'SetAttributeNodeNS', 'RemoveAttribute', 'RemoveAttributeNS', 'RemoveAttributeNode', 'GetElementsByTagName', 'GetElementsByTagNameNS', 'GetElementsByClassName', 'ScrollTo', 'ScrollTo_', 'Children', 'Remove', 'InsertAdjacentElement', 'AttachShadow'], + 'canGc': ['SetHTMLUnsafe', 'SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect', 'InsertAdjacentText', 'ToggleAttribute', 'SetAttribute', 'SetAttributeNS', 'SetId','SetClassName','Prepend','Append','ReplaceChildren','Before','After','ReplaceWith', 'SetRole', 'SetAriaAtomic', 'SetAriaAutoComplete', 'SetAriaBrailleLabel', 'SetAriaBrailleRoleDescription', 'SetAriaBusy', 'SetAriaChecked', 'SetAriaColCount', 'SetAriaColIndex', 'SetAriaColIndexText', 'SetAriaColSpan', 'SetAriaCurrent', 'SetAriaDescription', 'SetAriaDisabled', 'SetAriaExpanded', 'SetAriaHasPopup', 'SetAriaHidden', 'SetAriaInvalid', 'SetAriaKeyShortcuts', 'SetAriaLabel', 'SetAriaLevel', 'SetAriaLive', 'SetAriaModal', 'SetAriaMultiLine', 'SetAriaMultiSelectable', 'SetAriaOrientation', 'SetAriaPlaceholder', 'SetAriaPosInSet', 'SetAriaPressed','SetAriaReadOnly', 'SetAriaRelevant', 'SetAriaRequired', 'SetAriaRoleDescription', 'SetAriaRowCount', 'SetAriaRowIndex', 'SetAriaRowIndexText', 'SetAriaRowSpan', 'SetAriaSelected', 'SetAriaSetSize','SetAriaSort', 'SetAriaValueMax', 'SetAriaValueMin', 'SetAriaValueNow', 'SetAriaValueText', 'RequestFullscreen', 'GetHTML', 'GetInnerHTML', 'GetOuterHTML', 'ClassList', 'Attributes', 'SetAttributeNode', 'SetAttributeNodeNS', 'RemoveAttribute', 'RemoveAttributeNS', 'RemoveAttributeNode', 'GetElementsByTagName', 'GetElementsByTagNameNS', 'GetElementsByClassName', 'Children', 'Remove', 'InsertAdjacentElement', 'AttachShadow'], }, 'ElementInternals': { @@ -362,7 +358,7 @@ DOMInterfaces = { }, 'HTMLElement': { - 'canGc': ['AttachInternals', 'Focus', 'Blur', 'Click', 'SetInnerText', 'SetOuterText', "SetTranslate", 'SetAutofocus', 'GetOffsetParent', 'OffsetTop', 'OffsetLeft', 'OffsetWidth', 'OffsetHeight', 'InnerText', 'GetOuterText', 'GetOnerror', 'GetOnload', 'GetOnblur', 'GetOnfocus', 'GetOnresize', 'GetOnscroll', 'Style', 'Dataset'], + 'canGc': ['AttachInternals', 'Focus', 'Blur', 'Click', 'SetInnerText', 'SetOuterText', "SetTranslate", 'SetAutofocus', 'GetOnerror', 'GetOnload', 'GetOnblur', 'GetOnfocus', 'GetOnresize', 'GetOnscroll', 'Style', 'Dataset'], }, 'HTMLFieldSetElement': { @@ -386,7 +382,7 @@ DOMInterfaces = { }, 'HTMLImageElement': { - 'canGc': ['RequestSubmit', 'ReportValidity', 'Reset','SetRel', 'Width', 'Height', 'Decode', 'SetCrossOrigin', 'SetWidth', 'SetHeight', 'SetReferrerPolicy'], + 'canGc': ['RequestSubmit', 'ReportValidity', 'Reset','SetRel', 'Decode', 'SetCrossOrigin', 'SetWidth', 'SetHeight', 'SetReferrerPolicy'], }, 'HTMLInputElement': { @@ -427,7 +423,7 @@ DOMInterfaces = { }, 'HTMLScriptElement': { - 'canGc': ['InnerText', 'SetAsync', 'SetCrossOrigin', 'SetInnerText', 'SetSrc', 'SetText', 'SetTextContent'] + 'canGc': ['SetAsync', 'SetCrossOrigin', 'SetInnerText', 'SetSrc', 'SetText', 'SetTextContent'] }, 'HTMLSelectElement': { @@ -492,10 +488,6 @@ DOMInterfaces = { 'canGc': ['Ports'], }, -'MouseEvent': { - 'canGc': ['InitMouseEvent', 'OffsetX', 'OffsetY'], -}, - 'NavigationPreloadManager': { 'inRealms': ['Disable', 'Enable', 'GetState', 'SetHeaderValue'], 'canGc': ['Disable', 'Enable', 'GetState', 'SetHeaderValue'], @@ -528,11 +520,11 @@ DOMInterfaces = { }, 'OffscreenCanvasRenderingContext2D': { - 'canGc': ['CreateImageData', 'CreateImageData_', 'GetImageData', 'GetTransform', 'SetFont', 'FillText', 'MeasureText', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor', 'CreateLinearGradient', 'CreatePattern', 'CreateRadialGradient'], + 'canGc': ['CreateImageData', 'CreateImageData_', 'GetImageData', 'GetTransform', 'MeasureText', 'CreateLinearGradient', 'CreatePattern', 'CreateRadialGradient'], }, 'PaintRenderingContext2D': { - 'canGc': ['GetTransform', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'], + 'canGc': ['GetTransform'], }, 'Performance': { @@ -591,7 +583,7 @@ DOMInterfaces = { }, 'ShadowRoot': { - 'canGc': ['SetHTMLUnsafe', 'ElementFromPoint', 'ElementsFromPoint', 'SetInnerHTML', 'GetHTML', 'InnerHTML', 'AdoptedStyleSheets'], + 'canGc': ['SetHTMLUnsafe', 'SetInnerHTML', 'GetHTML', 'InnerHTML', 'AdoptedStyleSheets'], }, 'StaticRange': { @@ -654,12 +646,8 @@ DOMInterfaces = { 'additionalTraits': ['crate::interfaces::WebGL2RenderingContextHelpers'], }, -'WheelEvent': { - 'canGc': ['InitWheelEvent'], -}, - 'Window': { - 'canGc': ['Stop', 'Fetch', 'Scroll', 'Scroll_','ScrollBy', 'ScrollBy_', 'Stop', 'Fetch', 'Open', 'CreateImageBitmap', 'CreateImageBitmap_', 'TrustedTypes', 'WebdriverCallback', 'WebdriverException'], + 'canGc': ['Stop', 'Fetch', 'Stop', 'Fetch', 'Open', 'CreateImageBitmap', 'CreateImageBitmap_', 'TrustedTypes', 'WebdriverCallback', 'WebdriverException'], 'inRealms': ['Fetch', 'GetOpener', 'WebdriverCallback', 'WebdriverException'], 'additionalTraits': ['crate::interfaces::WindowHelpers'], }, diff --git a/components/shared/layout/lib.rs b/components/shared/layout/lib.rs index 7d182fe5fc4..1f93159982c 100644 --- a/components/shared/layout/lib.rs +++ b/components/shared/layout/lib.rs @@ -259,6 +259,9 @@ pub trait Layout { /// not exist in the tree. fn scroll_offset(&self, id: ExternalScrollId) -> Option; + /// Returns true if this layout needs to produce a new display list for rendering updates. + fn needs_new_display_list(&self) -> bool; + fn query_content_box(&self, node: TrustedNodeAddress) -> Option>; fn query_content_boxes(&self, node: TrustedNodeAddress) -> Vec>; fn query_client_rect(&self, node: TrustedNodeAddress) -> Rect; diff --git a/tests/wpt/meta/css/css-cascade/layer-statement-before-import.html.ini b/tests/wpt/meta/css/css-cascade/layer-statement-before-import.html.ini deleted file mode 100644 index 8fed2a8d383..00000000000 --- a/tests/wpt/meta/css/css-cascade/layer-statement-before-import.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[layer-statement-before-import.html] - [insert other rules before the first layer statement without imports] - expected: FAIL diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 014d6baa7d9..53a5ca705e1 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -12595,7 +12595,7 @@ ] ], "basic-transition.html": [ - "b80e8a666a6e6202b4ecafe628ef00ebcecfe168", + "c3461d3a5f9f1259296168742028db3bd4fc3668", [ null, {} @@ -12623,7 +12623,7 @@ ] ], "transition-raf.html": [ - "c38404503408e04b3c75b42df18ec3a7ec0819f5", + "aa3ed54e3e08a190f227c87165523306aed5a6bc", [ null, {} @@ -12743,7 +12743,7 @@ ] ], "stylesheet_media_queries.html": [ - "49956367a16c3de98d173d4cf5692c05451340a0", + "d04eb4b23f107b1e4d127cf633d4155ab3bdf629", [ null, {} diff --git a/tests/wpt/mozilla/tests/css/animations/basic-transition.html b/tests/wpt/mozilla/tests/css/animations/basic-transition.html index b80e8a666a6..c3461d3a5f9 100644 --- a/tests/wpt/mozilla/tests/css/animations/basic-transition.html +++ b/tests/wpt/mozilla/tests/css/animations/basic-transition.html @@ -20,15 +20,26 @@ var div = document.getElementById('check-me'); var span = div.childNodes[0]; async_test(function(t) { window.addEventListener('load', function() { - assert_equals(getComputedStyle(div).getPropertyValue('background-color'), 'rgb(255, 0, 0)'); - div.id = "check-me-2"; - requestAnimationFrame(function() { - var test = new window.TestBinding(); + var test = new window.TestBinding(); + + div.addEventListener("transitionstart", () => { + // The transition should have just started so the current value of the style should + // not be the value expected after the transition. + assert_not_equals(getComputedStyle(div).getPropertyValue('background-color'), 'rgb(0, 0, 0)'); test.advanceClock(2000); - span.innerHTML = "a"; + }); + + div.addEventListener("transitionend", () => { + // The transition should be finished so the value of the style should be the final one. assert_equals(getComputedStyle(div).getPropertyValue('background-color'), 'rgb(0, 0, 0)'); t.done(); }); + + // The starting value should be the one set in the style. + assert_equals(getComputedStyle(div).getPropertyValue('background-color'), 'rgb(255, 0, 0)'); + + // Start the transition. + div.id = "check-me-2"; }) }) diff --git a/tests/wpt/mozilla/tests/css/animations/transition-raf.html b/tests/wpt/mozilla/tests/css/animations/transition-raf.html index c3840450340..aa3ed54e3e0 100644 --- a/tests/wpt/mozilla/tests/css/animations/transition-raf.html +++ b/tests/wpt/mozilla/tests/css/animations/transition-raf.html @@ -32,9 +32,12 @@ async_test(function(t) { window.addEventListener('load', function() { assert_equals(getComputedStyle(box).getPropertyValue('width'), '100px'); + + box.addEventListener("transitionstart", () => { + // Let the first restyle run at zero, then advance the clock. + test.advanceClock(500); + }); box.className = "expose"; - // Let the first restyle run at zero, then advance the clock. - setTimeout(function() { test.advanceClock(500) }, 0); }); }, "Transitions should work during RAF loop") diff --git a/tests/wpt/mozilla/tests/css/stylesheet_media_queries.html b/tests/wpt/mozilla/tests/css/stylesheet_media_queries.html index 49956367a16..d04eb4b23f1 100644 --- a/tests/wpt/mozilla/tests/css/stylesheet_media_queries.html +++ b/tests/wpt/mozilla/tests/css/stylesheet_media_queries.html @@ -14,8 +14,10 @@ window.onload = test.step_func(function() { assert_equals(frame.contentWindow.getComputedStyle(element).backgroundColor, "rgb(255, 0, 0)"); frame.width = "300"; frameDoc.documentElement.offsetWidth; // Force layout - window.requestAnimationFrame(test.step_func_done(function () { + window.requestAnimationFrame(() => { + window.requestAnimationFrame(test.step_func_done(function () { assert_equals(frame.contentWindow.getComputedStyle(element).backgroundColor, "rgb(0, 255, 0)"); - })); + })) + }); });