diff options
author | Martin Robinson <mrobinson@igalia.com> | 2024-05-20 15:04:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-20 13:04:32 +0000 |
commit | 53c0726ef431d32c6f71a1a1eee23019782bd68b (patch) | |
tree | baf1f1eecf68a26645451eca895af208a70760ee /components/script/dom | |
parent | 2af6fe0b30a275e5fd8a43eca4126d82639fbaa9 (diff) | |
download | servo-53c0726ef431d32c6f71a1a1eee23019782bd68b.tar.gz servo-53c0726ef431d32c6f71a1a1eee23019782bd68b.zip |
script: Have `Document` own `Layout` (#32316)
Have `Document` own `Layout`. This makes it impossible to have a
`Document` without `Layout`, which was true, but now the compiler checks
it. In addition, `Layout` is now released when the `Document` is,
avoiding leaking the entire `Layout`.
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/document.rs | 37 | ||||
-rw-r--r-- | components/script/dom/documentorshadowroot.rs | 4 | ||||
-rw-r--r-- | components/script/dom/htmlelement.rs | 4 | ||||
-rw-r--r-- | components/script/dom/htmlimageelement.rs | 6 | ||||
-rw-r--r-- | components/script/dom/mediaquerylist.rs | 4 | ||||
-rw-r--r-- | components/script/dom/window.rs | 93 |
6 files changed, 64 insertions, 84 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index f58f9472958..d2c97bdc5de 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -58,7 +58,6 @@ use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use style::attr::AttrValue; use style::context::QuirksMode; use style::invalidation::element::restyle_hints::RestyleHint; -use style::media_queries::Device; use style::selector_parser::Snapshot; use style::shared_lock::SharedRwLock as StyleSharedRwLock; use style::str::{split_html_space_chars, str_join}; @@ -851,9 +850,7 @@ impl Document { let old_mode = self.quirks_mode.replace(new_mode); if old_mode != new_mode { - let _ = self - .window - .with_layout(move |layout| layout.set_quirks_mode(new_mode)); + self.window.layout_mut().set_quirks_mode(new_mode); } } @@ -3526,16 +3523,6 @@ impl Document { have_changed } - /// Runs the given closure using the Stylo `Device` suitable for media query evaluation. - /// - /// TODO: This can just become a getter when each Layout is more strongly associated with - /// its given Document and Window. - pub fn with_device<T>(&self, call: impl FnOnce(&Device) -> T) -> T { - self.window - .with_layout(move |layout| call(layout.device())) - .unwrap() - } - pub fn salvageable(&self) -> bool { self.salvageable.get() } @@ -3899,12 +3886,10 @@ impl Document { let cloned_stylesheet = sheet.clone(); let insertion_point2 = insertion_point.clone(); - let _ = self.window.with_layout(move |layout| { - layout.add_stylesheet( - cloned_stylesheet, - insertion_point2.as_ref().map(|s| s.sheet.clone()), - ); - }); + self.window.layout_mut().add_stylesheet( + cloned_stylesheet, + insertion_point2.as_ref().map(|s| s.sheet.clone()), + ); DocumentOrShadowRoot::add_stylesheet( owner, @@ -3917,18 +3902,18 @@ impl Document { /// Given a stylesheet, load all web fonts from it in Layout. pub fn load_web_fonts_from_stylesheet(&self, stylesheet: Arc<Stylesheet>) { - let _ = self.window.with_layout(move |layout| { - layout.load_web_fonts_from_stylesheet(stylesheet); - }); + self.window + .layout() + .load_web_fonts_from_stylesheet(stylesheet); } /// Remove a stylesheet owned by `owner` from the list of document sheets. #[allow(crown::unrooted_must_root)] // Owner needs to be rooted already necessarily. pub fn remove_stylesheet(&self, owner: &Element, stylesheet: &Arc<Stylesheet>) { let cloned_stylesheet = stylesheet.clone(); - let _ = self - .window - .with_layout(|layout| layout.remove_stylesheet(cloned_stylesheet)); + self.window + .layout_mut() + .remove_stylesheet(cloned_stylesheet); DocumentOrShadowRoot::remove_stylesheet( owner, diff --git a/components/script/dom/documentorshadowroot.rs b/components/script/dom/documentorshadowroot.rs index 25ada1eddae..560f8c43e3d 100644 --- a/components/script/dom/documentorshadowroot.rs +++ b/components/script/dom/documentorshadowroot.rs @@ -91,8 +91,8 @@ impl DocumentOrShadowRoot { }; self.window - .with_layout(|layout| layout.query_nodes_from_point(*client_point, query_type)) - .unwrap_or_default() + .layout() + .query_nodes_from_point(*client_point, query_type) } #[allow(unsafe_code)] diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index 63143a7d2fa..9e4cc20ccf9 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -462,8 +462,8 @@ impl HTMLElementMethods for HTMLElement { window.layout_reflow(QueryMsg::ElementInnerTextQuery); let text = window - .with_layout(|layout| layout.query_element_inner_text(node.to_trusted_node_address())) - .unwrap_or_default(); + .layout() + .query_element_inner_text(node.to_trusted_node_address()); DOMString::from(text) } diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 301c4e17b22..80c016b6b9d 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -670,7 +670,8 @@ impl HTMLImageElement { ) -> Au { let document = document_from_node(self); let quirks_mode = document.quirks_mode(); - document.with_device(move |device| source_size_list.evaluate(device, quirks_mode)) + let result = source_size_list.evaluate(document.window().layout().device(), quirks_mode); + result } /// <https://html.spec.whatwg.org/multipage/#matches-the-environment> @@ -696,7 +697,8 @@ impl HTMLImageElement { let mut parserInput = ParserInput::new(&media_query); let mut parser = Parser::new(&mut parserInput); let media_list = MediaList::parse(&context, &mut parser); - document.with_device(move |device| media_list.evaluate(device, quirks_mode)) + let result = media_list.evaluate(document.window().layout().device(), quirks_mode); + result } /// <https://html.spec.whatwg.org/multipage/#normalise-the-source-densities> diff --git a/components/script/dom/mediaquerylist.rs b/components/script/dom/mediaquerylist.rs index 685e66f0390..16675e1ed98 100644 --- a/components/script/dom/mediaquerylist.rs +++ b/components/script/dom/mediaquerylist.rs @@ -73,8 +73,8 @@ impl MediaQueryList { pub fn evaluate(&self) -> bool { let quirks_mode = self.document.quirks_mode(); - self.document - .with_device(move |device| self.media_query_list.evaluate(device, quirks_mode)) + self.media_query_list + .evaluate(self.document.window().layout().device(), quirks_mode) } } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index fcba7ffcbeb..5dbbc3f2377 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::borrow::{Cow, ToOwned}; -use std::cell::Cell; +use std::cell::{Cell, RefCell, RefMut}; use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::default::Default; @@ -193,6 +193,9 @@ pub struct Window { #[ignore_malloc_size_of = "trait objects are hard"] script_chan: MainThreadScriptChan, task_manager: TaskManager, + #[no_trace] + #[ignore_malloc_size_of = "TODO: Add MallocSizeOf support to layout"] + layout: RefCell<Box<dyn Layout>>, navigator: MutNullableDom<Navigator>, #[ignore_malloc_size_of = "Arc"] #[no_trace] @@ -365,6 +368,14 @@ impl Window { &self.task_manager } + pub fn layout(&self) -> Ref<Box<dyn Layout>> { + self.layout.borrow() + } + + pub fn layout_mut(&self) -> RefMut<Box<dyn Layout>> { + self.layout.borrow_mut() + } + pub fn get_exists_mut_observer(&self) -> bool { self.exists_mut_observer.get() } @@ -1877,7 +1888,7 @@ impl Window { animations: document.animations().sets.clone(), }; - let _ = self.with_layout(move |layout| layout.reflow(reflow)); + self.layout.borrow_mut().reflow(reflow); let complete = match join_port.try_recv() { Err(TryRecvError::Empty) => { @@ -1988,10 +1999,7 @@ impl Window { elem.has_class(&atom!("reftest-wait"), CaseSensitivity::CaseSensitive) }); - let pending_web_fonts = self - .with_layout(move |layout| layout.waiting_for_web_fonts_to_load()) - .unwrap(); - + let pending_web_fonts = self.layout.borrow().waiting_for_web_fonts_to_load(); let has_sent_idle_message = self.has_sent_idle_message.get(); let is_ready_state_complete = document.ReadyState() == DocumentReadyState::Complete; let pending_images = !self.pending_layout_images.borrow().is_empty(); @@ -2022,10 +2030,7 @@ impl Window { return; } - let epoch = self - .with_layout(move |layout| layout.current_epoch()) - .unwrap(); - + let epoch = self.layout.borrow().current_epoch(); debug!( "{:?}: Updating constellation epoch: {epoch:?}", self.pipeline_id() @@ -2049,39 +2054,34 @@ impl Window { } let document = self.Document(); - self.with_layout(|layout| { - layout.query_resolved_font_style( - node.to_trusted_node_address(), - &value, - document.animations().sets.clone(), - document.current_animation_timeline_value(), - ) - }) - .unwrap() + let animations = document.animations().sets.clone(); + self.layout.borrow().query_resolved_font_style( + node.to_trusted_node_address(), + &value, + animations, + document.current_animation_timeline_value(), + ) } pub fn content_box_query(&self, node: &Node) -> Option<UntypedRect<Au>> { if !self.layout_reflow(QueryMsg::ContentBox) { return None; } - self.with_layout(|layout| layout.query_content_box(node.to_opaque())) - .unwrap_or(None) + self.layout.borrow().query_content_box(node.to_opaque()) } pub fn content_boxes_query(&self, node: &Node) -> Vec<UntypedRect<Au>> { if !self.layout_reflow(QueryMsg::ContentBoxes) { return vec![]; } - self.with_layout(|layout| layout.query_content_boxes(node.to_opaque())) - .unwrap_or_default() + self.layout.borrow().query_content_boxes(node.to_opaque()) } pub fn client_rect_query(&self, node: &Node) -> UntypedRect<i32> { if !self.layout_reflow(QueryMsg::ClientRectQuery) { return Rect::zero(); } - self.with_layout(|layout| layout.query_client_rect(node.to_opaque())) - .unwrap_or_default() + self.layout.borrow().query_client_rect(node.to_opaque()) } /// Find the scroll area of the given node, if it is not None. If the node @@ -2091,8 +2091,7 @@ impl Window { if !self.layout_reflow(QueryMsg::ScrollingAreaQuery) { return Rect::zero(); } - self.with_layout(|layout| layout.query_scrolling_area(opaque)) - .unwrap_or_default() + self.layout.borrow().query_scrolling_area(opaque) } pub fn scroll_offset_query(&self, node: &Node) -> Vector2D<f32, LayoutPixel> { @@ -2136,18 +2135,14 @@ impl Window { } let document = self.Document(); - DOMString::from( - self.with_layout(|layout| { - layout.query_resolved_style( - element, - pseudo, - property, - document.animations().sets.clone(), - document.current_animation_timeline_value(), - ) - }) - .unwrap(), - ) + let animations = document.animations().sets.clone(); + DOMString::from(self.layout.borrow().query_resolved_style( + element, + pseudo, + property, + animations, + document.current_animation_timeline_value(), + )) } pub fn inner_window_dimensions_query( @@ -2157,8 +2152,9 @@ impl Window { if !self.layout_reflow(QueryMsg::InnerWindowDimensionsQuery) { return None; } - self.with_layout(|layout| layout.query_inner_window_dimension(browsing_context)) - .unwrap() + self.layout + .borrow() + .query_inner_window_dimension(browsing_context) } #[allow(unsafe_code)] @@ -2167,9 +2163,7 @@ impl Window { return (None, Rect::zero()); } - let response = self - .with_layout(|layout| layout.query_offset_parent(node.to_opaque())) - .unwrap(); + let response = self.layout.borrow().query_offset_parent(node.to_opaque()); let element = response.node_address.and_then(|parent_node_address| { let node = unsafe { from_untrusted_node_address(parent_node_address) }; DomRoot::downcast(node) @@ -2185,8 +2179,9 @@ impl Window { if !self.layout_reflow(QueryMsg::TextIndexQuery) { return None; } - self.with_layout(|layout| layout.query_text_indext(node.to_opaque(), point_in_node)) - .unwrap() + self.layout + .borrow() + .query_text_indext(node.to_opaque(), point_in_node) } #[allow(unsafe_code)] @@ -2309,10 +2304,6 @@ impl Window { self.Document().url() } - pub fn with_layout<T>(&self, call: impl FnOnce(&mut dyn Layout) -> T) -> Result<T, ()> { - ScriptThread::with_layout(self.pipeline_id(), call) - } - pub fn windowproxy_handler(&self) -> WindowProxyHandler { WindowProxyHandler(self.dom_static.windowproxy_handler.0) } @@ -2517,6 +2508,7 @@ impl Window { runtime: Rc<Runtime>, script_chan: MainThreadScriptChan, task_manager: TaskManager, + layout: Box<dyn Layout>, image_cache_chan: Sender<ImageCacheMsg>, image_cache: Arc<dyn ImageCache>, resource_threads: ResourceThreads, @@ -2580,6 +2572,7 @@ impl Window { ), script_chan, task_manager, + layout: RefCell::new(layout), image_cache_chan, image_cache, navigator: Default::default(), |