diff options
44 files changed, 335 insertions, 432 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs index aabb2e69b67..7078e063978 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -181,12 +181,15 @@ pub struct InlineBlockSplit { impl InlineBlockSplit { /// Flushes the given accumulator to the new split and makes a new accumulator to hold any /// subsequent fragments. - fn new<ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>( + fn new<'dom, ConcreteThreadSafeLayoutNode>( fragment_accumulator: &mut InlineFragmentsAccumulator, node: &ConcreteThreadSafeLayoutNode, style_context: &SharedStyleContext, flow: FlowRef, - ) -> InlineBlockSplit { + ) -> InlineBlockSplit + where + ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>, + { fragment_accumulator.enclosing_node.as_mut().expect( "enclosing_node is None; Are {ib} splits being generated outside of an inline node?" ).flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT); @@ -272,13 +275,10 @@ impl InlineFragmentsAccumulator { } } - fn from_inline_node<N>( - node: &N, + fn from_inline_node<'dom>( + node: &impl ThreadSafeLayoutNode<'dom>, style_context: &SharedStyleContext, - ) -> InlineFragmentsAccumulator - where - N: ThreadSafeLayoutNode, - { + ) -> InlineFragmentsAccumulator { InlineFragmentsAccumulator { fragments: IntermediateInlineFragments::new(), enclosing_node: Some(InlineFragmentNodeInfo { @@ -305,12 +305,12 @@ impl InlineFragmentsAccumulator { .push_descendants(fragments.absolute_descendants); } - fn to_intermediate_inline_fragments<N>( + fn to_intermediate_inline_fragments<'dom, N>( self, context: &SharedStyleContext, ) -> IntermediateInlineFragments where - N: ThreadSafeLayoutNode, + N: ThreadSafeLayoutNode<'dom>, { let InlineFragmentsAccumulator { mut fragments, @@ -366,7 +366,7 @@ impl InlineFragmentsAccumulator { } /// An object that knows how to create flows. -pub struct FlowConstructor<'a, N: ThreadSafeLayoutNode> { +pub struct FlowConstructor<'a, N> { /// The layout context. pub layout_context: &'a LayoutContext<'a>, /// Satisfy the compiler about the unused parameters, which we use to improve the ergonomics of @@ -374,8 +374,9 @@ pub struct FlowConstructor<'a, N: ThreadSafeLayoutNode> { phantom2: PhantomData<N>, } -impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> - FlowConstructor<'a, ConcreteThreadSafeLayoutNode> +impl<'a, 'dom, ConcreteThreadSafeLayoutNode> FlowConstructor<'a, ConcreteThreadSafeLayoutNode> +where + ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>, { /// Creates a new flow constructor. pub fn new(layout_context: &'a LayoutContext<'a>) -> Self { @@ -1792,10 +1793,11 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> } } -impl<'a, ConcreteThreadSafeLayoutNode> PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode> +impl<'a, 'dom, ConcreteThreadSafeLayoutNode> + PostorderNodeMutTraversal<'dom, ConcreteThreadSafeLayoutNode> for FlowConstructor<'a, ConcreteThreadSafeLayoutNode> where - ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode, + ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>, { // Construct Flow based on 'display', 'position', and 'float' values. // @@ -1988,9 +1990,9 @@ trait NodeUtils { fn get_construction_result(self) -> ConstructionResult; } -impl<ConcreteThreadSafeLayoutNode> NodeUtils for ConcreteThreadSafeLayoutNode +impl<'dom, ConcreteThreadSafeLayoutNode> NodeUtils for ConcreteThreadSafeLayoutNode where - ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode, + ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>, { fn is_replaced_content(&self) -> bool { match self.type_id() { diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index d074c300e2f..289dc3f3094 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -411,10 +411,10 @@ impl ImageFragmentInfo { /// /// FIXME(pcwalton): The fact that image fragments store the cache in the fragment makes little /// sense to me. - pub fn new<N: ThreadSafeLayoutNode>( + pub fn new<'dom>( url: Option<ServoUrl>, density: Option<f64>, - node: &N, + node: &impl ThreadSafeLayoutNode<'dom>, layout_context: &LayoutContext, ) -> ImageFragmentInfo { // First use any image data present in the element... @@ -488,7 +488,7 @@ pub struct IframeFragmentInfo { impl IframeFragmentInfo { /// Creates the information specific to an iframe fragment. - pub fn new<N: ThreadSafeLayoutNode>(node: &N) -> IframeFragmentInfo { + pub fn new<'dom>(node: &impl ThreadSafeLayoutNode<'dom>) -> IframeFragmentInfo { let browsing_context_id = node.iframe_browsing_context_id(); let pipeline_id = node.iframe_pipeline_id(); IframeFragmentInfo { @@ -642,7 +642,7 @@ pub struct TableColumnFragmentInfo { impl TableColumnFragmentInfo { /// Create the information specific to an table column fragment. - pub fn new<N: ThreadSafeLayoutNode>(node: &N) -> TableColumnFragmentInfo { + pub fn new<'dom>(node: &impl ThreadSafeLayoutNode<'dom>) -> TableColumnFragmentInfo { let element = node.as_element().unwrap(); let span = element .get_attr(&ns!(), &local_name!("span")) @@ -663,8 +663,8 @@ pub struct TruncatedFragmentInfo { impl Fragment { /// Constructs a new `Fragment` instance. - pub fn new<N: ThreadSafeLayoutNode>( - node: &N, + pub fn new<'dom>( + node: &impl ThreadSafeLayoutNode<'dom>, specific: SpecificFragmentInfo, ctx: &LayoutContext, ) -> Fragment { diff --git a/components/layout/query.rs b/components/layout/query.rs index cda001c485c..cd3e75bf28c 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -688,9 +688,9 @@ pub fn process_client_rect_query( iterator.client_rect } -pub fn process_node_scroll_id_request<N: LayoutNode>( +pub fn process_node_scroll_id_request<'dom>( id: PipelineId, - requested_node: N, + requested_node: impl LayoutNode<'dom>, ) -> ExternalScrollId { let layout_node = requested_node.to_threadsafe(); layout_node.generate_scroll_id(id) @@ -747,16 +747,13 @@ pub fn process_node_scroll_area_request( /// Return the resolved value of property for a given (pseudo)element. /// <https://drafts.csswg.org/cssom/#resolved-value> -pub fn process_resolved_style_request<'a, N>( +pub fn process_resolved_style_request<'dom>( context: &LayoutContext, - node: N, + node: impl LayoutNode<'dom>, pseudo: &Option<PseudoElement>, property: &PropertyId, layout_root: &mut dyn Flow, -) -> String -where - N: LayoutNode, -{ +) -> String { use style::stylist::RuleInclusion; use style::traversal::resolve_style; @@ -797,15 +794,12 @@ where } /// The primary resolution logic, which assumes that the element is styled. -fn process_resolved_style_request_internal<'a, N>( - requested_node: N, +fn process_resolved_style_request_internal<'dom>( + requested_node: impl LayoutNode<'dom>, pseudo: &Option<PseudoElement>, property: &PropertyId, layout_root: &mut dyn Flow, -) -> String -where - N: LayoutNode, -{ +) -> String { let layout_el = requested_node.to_threadsafe().as_element().unwrap(); let layout_el = match *pseudo { Some(PseudoElement::Before) => layout_el.get_before_pseudo(), @@ -851,12 +845,15 @@ where // There are probably other quirks. let applies = true; - fn used_value_for_position_property<N: LayoutNode>( - layout_el: <N::ConcreteThreadSafeLayoutNode as ThreadSafeLayoutNode>::ConcreteThreadSafeLayoutElement, + fn used_value_for_position_property<'dom, N>( + layout_el: <N::ConcreteThreadSafeLayoutNode as ThreadSafeLayoutNode<'dom>>::ConcreteThreadSafeLayoutElement, layout_root: &mut dyn Flow, requested_node: N, longhand_id: LonghandId, - ) -> String { + ) -> String + where + N: LayoutNode<'dom>, + { let maybe_data = layout_el.borrow_layout_data(); let position = maybe_data.map_or(Point2D::zero(), |data| { match (*data).flow_construction_result { @@ -969,7 +966,7 @@ pub fn process_offset_parent_query( } } -pub fn process_style_query<N: LayoutNode>(requested_node: N) -> StyleResponse { +pub fn process_style_query<'dom>(requested_node: impl LayoutNode<'dom>) -> StyleResponse { let element = requested_node.as_element().unwrap(); let data = element.borrow_data(); @@ -982,8 +979,8 @@ enum InnerTextItem { } // https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute -pub fn process_element_inner_text_query<N: LayoutNode>( - node: N, +pub fn process_element_inner_text_query<'dom>( + node: impl LayoutNode<'dom>, indexable_text: &IndexableText, ) -> String { // Step 1. @@ -1027,8 +1024,8 @@ pub fn process_element_inner_text_query<N: LayoutNode>( // https://html.spec.whatwg.org/multipage/#inner-text-collection-steps #[allow(unsafe_code)] -fn inner_text_collection_steps<N: LayoutNode>( - node: N, +fn inner_text_collection_steps<'dom>( + node: impl LayoutNode<'dom>, indexable_text: &IndexableText, results: &mut Vec<InnerTextItem>, ) { diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index 89d83702f0e..b1fa1852650 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -61,8 +61,8 @@ impl TableCellFlow { } } - pub fn from_node_fragment_and_visibility_flag<N: ThreadSafeLayoutNode>( - node: &N, + pub fn from_node_fragment_and_visibility_flag<'dom>( + node: &impl ThreadSafeLayoutNode<'dom>, fragment: Fragment, visible: bool, ) -> TableCellFlow { diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index e968c184341..244531cee46 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -38,10 +38,10 @@ impl<'a> RecalcStyleAndConstructFlows<'a> { } #[allow(unsafe_code)] -impl<'a, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a> +impl<'a, 'dom, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a> where E: TElement, - E::ConcreteNode: LayoutNode, + E::ConcreteNode: LayoutNode<'dom>, E::FontMetricsProvider: Send, { fn process_preorder<F>( @@ -175,7 +175,10 @@ pub trait InorderFlowTraversal { } /// A bottom-up, parallelizable traversal. -pub trait PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> { +pub trait PostorderNodeMutTraversal<'dom, ConcreteThreadSafeLayoutNode> +where + ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>, +{ /// The operation to perform. Return true to continue or false to stop. fn process(&mut self, node: &ConcreteThreadSafeLayoutNode); } @@ -183,10 +186,7 @@ pub trait PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode: ThreadSafeLayo /// The flow construction traversal, which builds flows for styled nodes. #[inline] #[allow(unsafe_code)] -fn construct_flows_at<N>(context: &LayoutContext, node: N) -where - N: LayoutNode, -{ +fn construct_flows_at<'dom>(context: &LayoutContext, node: impl LayoutNode<'dom>) { debug!("construct_flows_at: {:?}", node); // Construct flows for this node. diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 063d7f3d25d..af8d6b6a0c7 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -47,7 +47,10 @@ pub trait LayoutNodeLayoutData { fn flow_debug_id(self) -> usize; } -impl<T: GetLayoutData> LayoutNodeLayoutData for T { +impl<'dom, T> LayoutNodeLayoutData for T +where + T: GetLayoutData<'dom>, +{ fn borrow_layout_data(&self) -> Option<AtomicRef<LayoutData>> { self.get_raw_data().map(|d| d.layout_data.borrow()) } @@ -66,7 +69,10 @@ pub trait GetRawData { fn get_raw_data(&self) -> Option<&StyleAndLayoutData>; } -impl<T: GetLayoutData> GetRawData for T { +impl<'dom, T> GetRawData for T +where + T: GetLayoutData<'dom>, +{ fn get_raw_data(&self) -> Option<&StyleAndLayoutData> { self.get_style_and_layout_data().map(|opaque| { let container = opaque.ptr.as_ptr() as *mut StyleAndLayoutData; @@ -98,7 +104,10 @@ pub trait ThreadSafeLayoutNodeHelpers { fn restyle_damage(self) -> RestyleDamage; } -impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T { +impl<'dom, T> ThreadSafeLayoutNodeHelpers for T +where + T: ThreadSafeLayoutNode<'dom>, +{ fn flags(self) -> LayoutDataFlags { self.borrow_layout_data().as_ref().unwrap().flags } diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs index d60e779e665..020282f50ff 100644 --- a/components/layout_2020/dom_traversal.rs +++ b/components/layout_2020/dom_traversal.rs @@ -349,7 +349,7 @@ impl Drop for BoxSlot<'_> { } } -pub(crate) trait NodeExt<'dom>: 'dom + Copy + LayoutNode + Send + Sync { +pub(crate) trait NodeExt<'dom>: 'dom + Copy + LayoutNode<'dom> + Send + Sync { fn is_element(self) -> bool; fn as_text(self) -> Option<String>; @@ -372,7 +372,7 @@ pub(crate) trait NodeExt<'dom>: 'dom + Copy + LayoutNode + Send + Sync { impl<'dom, T> NodeExt<'dom> for T where - T: 'dom + Copy + LayoutNode + Send + Sync, + T: 'dom + Copy + LayoutNode<'dom> + Send + Sync, { fn is_element(self) -> bool { self.to_threadsafe().as_element().is_some() diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index 975d5470636..adbcb26d4c9 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -50,7 +50,7 @@ pub struct FragmentTreeRoot { impl BoxTreeRoot { pub fn construct<'dom, Node>(context: &LayoutContext, root_element: Node) -> Self where - Node: 'dom + Copy + LayoutNode + Send + Sync, + Node: 'dom + Copy + LayoutNode<'dom> + Send + Sync, { let (contains_floats, boxes) = construct_for_root_element(&context, root_element); Self(BlockFormattingContext { diff --git a/components/layout_2020/query.rs b/components/layout_2020/query.rs index 45eb3b25ac0..fc4ac985253 100644 --- a/components/layout_2020/query.rs +++ b/components/layout_2020/query.rs @@ -192,9 +192,9 @@ pub fn process_node_geometry_request( fragment_tree_root.get_border_dimensions_for_node(requested_node) } -pub fn process_node_scroll_id_request<N: LayoutNode>( +pub fn process_node_scroll_id_request<'dom>( id: PipelineId, - requested_node: N, + requested_node: impl LayoutNode<'dom>, ) -> ExternalScrollId { let layout_node = requested_node.to_threadsafe(); layout_node.generate_scroll_id(id) @@ -207,15 +207,12 @@ pub fn process_node_scroll_area_request(_requested_node: OpaqueNode) -> Rect<i32 /// Return the resolved value of property for a given (pseudo)element. /// <https://drafts.csswg.org/cssom/#resolved-value> -pub fn process_resolved_style_request<'a, N>( +pub fn process_resolved_style_request<'dom>( _context: &LayoutContext, - _node: N, + _node: impl LayoutNode<'dom>, _pseudo: &Option<PseudoElement>, _property: &PropertyId, -) -> String -where - N: LayoutNode, -{ +) -> String { "".to_owned() } @@ -223,12 +220,12 @@ pub fn process_offset_parent_query(_requested_node: OpaqueNode) -> OffsetParentR OffsetParentResponse::empty() } -pub fn process_style_query<N: LayoutNode>(_requested_node: N) -> StyleResponse { +pub fn process_style_query<'dom>(_requested_node: impl LayoutNode<'dom>) -> StyleResponse { StyleResponse(None) } // https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute -pub fn process_element_inner_text_query<N: LayoutNode>(_node: N) -> String { +pub fn process_element_inner_text_query<'dom>(_node: impl LayoutNode<'dom>) -> String { "".to_owned() } diff --git a/components/layout_2020/traversal.rs b/components/layout_2020/traversal.rs index 97a9874a20b..b57fe2b63f1 100644 --- a/components/layout_2020/traversal.rs +++ b/components/layout_2020/traversal.rs @@ -30,10 +30,10 @@ impl<'a> RecalcStyle<'a> { } #[allow(unsafe_code)] -impl<'a, E> DomTraversal<E> for RecalcStyle<'a> +impl<'a, 'dom, E> DomTraversal<E> for RecalcStyle<'a> where E: TElement, - E::ConcreteNode: LayoutNode, + E::ConcreteNode: LayoutNode<'dom>, E::FontMetricsProvider: Send, { fn process_preorder<F>( diff --git a/components/layout_2020/wrapper.rs b/components/layout_2020/wrapper.rs index 02a0f8ceeee..504ab9af2cc 100644 --- a/components/layout_2020/wrapper.rs +++ b/components/layout_2020/wrapper.rs @@ -11,7 +11,10 @@ pub trait GetRawData { fn get_raw_data(&self) -> Option<&StyleAndLayoutData>; } -impl<T: GetLayoutData> GetRawData for T { +impl<'dom, T> GetRawData for T +where + T: GetLayoutData<'dom>, +{ fn get_raw_data(&self) -> Option<&StyleAndLayoutData> { self.get_style_and_layout_data().map(|opaque| { let container = opaque.ptr.as_ptr() as *mut StyleAndLayoutData; diff --git a/components/layout_thread/dom_wrapper.rs b/components/layout_thread/dom_wrapper.rs index c47635afedb..2f502352d27 100644 --- a/components/layout_thread/dom_wrapper.rs +++ b/components/layout_thread/dom_wrapper.rs @@ -39,7 +39,6 @@ use msg::constellation_msg::{BrowsingContextId, PipelineId}; use net_traits::image::base::{Image, ImageMetadata}; use range::Range; use script::layout_exports::NodeFlags; -use script::layout_exports::PendingRestyle; use script::layout_exports::ShadowRoot; use script::layout_exports::{ CharacterDataTypeId, DocumentFragmentTypeId, ElementTypeId, HTMLElementTypeId, NodeTypeId, @@ -71,7 +70,6 @@ use servo_url::ServoUrl; use std::fmt; use std::fmt::Debug; use std::hash::{Hash, Hasher}; -use std::marker::PhantomData; use std::ptr::NonNull; use std::sync::atomic::Ordering; use std::sync::Arc as StdArc; @@ -101,12 +99,9 @@ pub unsafe fn drop_style_and_layout_data(data: OpaqueStyleAndLayoutData) { } #[derive(Clone, Copy)] -pub struct ServoLayoutNode<'a> { +pub struct ServoLayoutNode<'dom> { /// The wrapped node. - node: LayoutDom<Node>, - - /// Being chained to a PhantomData prevents `LayoutNode`s from escaping. - chain: PhantomData<&'a ()>, + node: LayoutDom<'dom, Node>, } impl<'ln> Debug for ServoLayoutNode<'ln> { @@ -131,25 +126,14 @@ impl<'a> PartialEq for ServoLayoutNode<'a> { } impl<'ln> ServoLayoutNode<'ln> { - fn from_layout_js(n: LayoutDom<Node>) -> ServoLayoutNode<'ln> { - ServoLayoutNode { - node: n, - chain: PhantomData, - } + fn from_layout_js(n: LayoutDom<'ln, Node>) -> Self { + ServoLayoutNode { node: n } } - pub unsafe fn new(address: &TrustedNodeAddress) -> ServoLayoutNode { + pub unsafe fn new(address: &TrustedNodeAddress) -> Self { ServoLayoutNode::from_layout_js(LayoutDom::from_trusted_node_address(*address)) } - /// Creates a new layout node with the same lifetime as this layout node. - pub unsafe fn new_with_this_lifetime(&self, node: &LayoutDom<Node>) -> ServoLayoutNode<'ln> { - ServoLayoutNode { - node: *node, - chain: self.chain, - } - } - fn script_type_id(&self) -> NodeTypeId { unsafe { self.node.type_id_for_layout() } } @@ -167,12 +151,9 @@ impl<'ln> NodeInfo for ServoLayoutNode<'ln> { } #[derive(Clone, Copy, PartialEq)] -pub struct ServoShadowRoot<'a> { +pub struct ServoShadowRoot<'dom> { /// The wrapped shadow root. - shadow_root: LayoutDom<ShadowRoot>, - - /// Being chained to a PhantomData prevents `ShadowRoot`s from escaping. - chain: PhantomData<&'a ()>, + shadow_root: LayoutDom<'dom, ShadowRoot>, } impl<'lr> Debug for ServoShadowRoot<'lr> { @@ -206,11 +187,8 @@ impl<'lr> TShadowRoot for ServoShadowRoot<'lr> { } impl<'lr> ServoShadowRoot<'lr> { - fn from_layout_js(shadow_root: LayoutDom<ShadowRoot>) -> ServoShadowRoot<'lr> { - ServoShadowRoot { - shadow_root, - chain: PhantomData, - } + fn from_layout_js(shadow_root: LayoutDom<'lr, ShadowRoot>) -> Self { + ServoShadowRoot { shadow_root } } pub unsafe fn flush_stylesheets( @@ -233,40 +211,24 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { unsafe { self.node .composed_parent_node_ref() - .map(|node| self.new_with_this_lifetime(&node)) + .map(Self::from_layout_js) } } fn first_child(&self) -> Option<Self> { - unsafe { - self.node - .first_child_ref() - .map(|node| self.new_with_this_lifetime(&node)) - } + unsafe { self.node.first_child_ref().map(Self::from_layout_js) } } fn last_child(&self) -> Option<Self> { - unsafe { - self.node - .last_child_ref() - .map(|node| self.new_with_this_lifetime(&node)) - } + unsafe { self.node.last_child_ref().map(Self::from_layout_js) } } fn prev_sibling(&self) -> Option<Self> { - unsafe { - self.node - .prev_sibling_ref() - .map(|node| self.new_with_this_lifetime(&node)) - } + unsafe { self.node.prev_sibling_ref().map(Self::from_layout_js) } } fn next_sibling(&self) -> Option<Self> { - unsafe { - self.node - .next_sibling_ref() - .map(|node| self.new_with_this_lifetime(&node)) - } + unsafe { self.node.next_sibling_ref().map(Self::from_layout_js) } } fn owner_doc(&self) -> Self::ConcreteDocument { @@ -308,11 +270,11 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { } } -impl<'ln> LayoutNode for ServoLayoutNode<'ln> { +impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> { type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'ln>; fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode { - ServoThreadSafeLayoutNode::new(self) + ServoThreadSafeLayoutNode::new(*self) } fn type_id(&self) -> LayoutNodeType { @@ -342,25 +304,25 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> { } } -impl<'ln> GetLayoutData for ServoLayoutNode<'ln> { +impl<'ln> GetLayoutData<'ln> for ServoLayoutNode<'ln> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> { unsafe { self.get_jsmanaged().get_style_and_layout_data() } } } -impl<'le> GetLayoutData for ServoLayoutElement<'le> { +impl<'le> GetLayoutData<'le> for ServoLayoutElement<'le> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> { self.as_node().get_style_and_layout_data() } } -impl<'ln> GetLayoutData for ServoThreadSafeLayoutNode<'ln> { +impl<'ln> GetLayoutData<'ln> for ServoThreadSafeLayoutNode<'ln> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> { self.node.get_style_and_layout_data() } } -impl<'le> GetLayoutData for ServoThreadSafeLayoutElement<'le> { +impl<'le> GetLayoutData<'le> for ServoThreadSafeLayoutElement<'le> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> { self.element.as_node().get_style_and_layout_data() } @@ -369,16 +331,15 @@ impl<'le> GetLayoutData for ServoThreadSafeLayoutElement<'le> { impl<'ln> ServoLayoutNode<'ln> { /// Returns the interior of this node as a `LayoutDom`. This is highly unsafe for layout to /// call and as such is marked `unsafe`. - pub unsafe fn get_jsmanaged(&self) -> &LayoutDom<Node> { - &self.node + pub unsafe fn get_jsmanaged(&self) -> LayoutDom<'ln, Node> { + self.node } } // A wrapper around documents that ensures ayout can only ever access safe properties. #[derive(Clone, Copy)] -pub struct ServoLayoutDocument<'ld> { - document: LayoutDom<Document>, - chain: PhantomData<&'ld ()>, +pub struct ServoLayoutDocument<'dom> { + document: LayoutDom<'dom, Document>, } impl<'ld> TDocument for ServoLayoutDocument<'ld> { @@ -405,14 +366,6 @@ impl<'ld> ServoLayoutDocument<'ld> { .next() } - pub fn drain_pending_restyles(&self) -> Vec<(ServoLayoutElement<'ld>, PendingRestyle)> { - let elements = unsafe { self.document.drain_pending_restyles() }; - elements - .into_iter() - .map(|(el, snapshot)| (ServoLayoutElement::from_layout_js(el), snapshot)) - .collect() - } - pub fn needs_paint_from_layout(&self) { unsafe { self.document.needs_paint_from_layout() } } @@ -455,19 +408,15 @@ impl<'ld> ServoLayoutDocument<'ld> { } } - pub fn from_layout_js(doc: LayoutDom<Document>) -> ServoLayoutDocument<'ld> { - ServoLayoutDocument { - document: doc, - chain: PhantomData, - } + pub fn from_layout_js(doc: LayoutDom<'ld, Document>) -> Self { + ServoLayoutDocument { document: doc } } } /// A wrapper around elements that ensures layout can only ever access safe properties. #[derive(Clone, Copy)] -pub struct ServoLayoutElement<'le> { - element: LayoutDom<Element>, - chain: PhantomData<&'le ()>, +pub struct ServoLayoutElement<'dom> { + element: LayoutDom<'dom, Element>, } impl<'le> fmt::Debug for ServoLayoutElement<'le> { @@ -748,11 +697,8 @@ impl<'le> Hash for ServoLayoutElement<'le> { impl<'le> Eq for ServoLayoutElement<'le> {} impl<'le> ServoLayoutElement<'le> { - fn from_layout_js(el: LayoutDom<Element>) -> ServoLayoutElement<'le> { - ServoLayoutElement { - element: el, - chain: PhantomData, - } + fn from_layout_js(el: LayoutDom<'le, Element>) -> Self { + ServoLayoutElement { element: el } } #[inline] @@ -798,7 +744,7 @@ impl<'le> ServoLayoutElement<'le> { } } -fn as_element<'le>(node: LayoutDom<Node>) -> Option<ServoLayoutElement<'le>> { +fn as_element<'dom>(node: LayoutDom<'dom, Node>) -> Option<ServoLayoutElement<'dom>> { node.downcast().map(ServoLayoutElement::from_layout_js) } @@ -1049,33 +995,24 @@ impl<'a> PartialEq for ServoThreadSafeLayoutNode<'a> { } } -impl<'ln> DangerousThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { +impl<'ln> DangerousThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> { unsafe fn dangerous_first_child(&self) -> Option<Self> { self.get_jsmanaged() .first_child_ref() - .map(|node| self.new_with_this_lifetime(&node)) + .map(ServoLayoutNode::from_layout_js) + .map(Self::new) } unsafe fn dangerous_next_sibling(&self) -> Option<Self> { self.get_jsmanaged() .next_sibling_ref() - .map(|node| self.new_with_this_lifetime(&node)) + .map(ServoLayoutNode::from_layout_js) + .map(Self::new) } } impl<'ln> ServoThreadSafeLayoutNode<'ln> { - /// Creates a new layout node with the same lifetime as this layout node. - pub unsafe fn new_with_this_lifetime( - &self, - node: &LayoutDom<Node>, - ) -> ServoThreadSafeLayoutNode<'ln> { - ServoThreadSafeLayoutNode { - node: self.node.new_with_this_lifetime(node), - pseudo: PseudoElementType::Normal, - } - } - /// Creates a new `ServoThreadSafeLayoutNode` from the given `ServoLayoutNode`. - pub fn new<'a>(node: &ServoLayoutNode<'a>) -> ServoThreadSafeLayoutNode<'a> { + pub fn new(node: ServoLayoutNode<'ln>) -> Self { ServoThreadSafeLayoutNode { node: node.clone(), pseudo: PseudoElementType::Normal, @@ -1084,7 +1021,7 @@ impl<'ln> ServoThreadSafeLayoutNode<'ln> { /// Returns the interior of this node as a `LayoutDom`. This is highly unsafe for layout to /// call and as such is marked `unsafe`. - unsafe fn get_jsmanaged(&self) -> &LayoutDom<Node> { + unsafe fn get_jsmanaged(&self) -> LayoutDom<'ln, Node> { self.node.get_jsmanaged() } } @@ -1099,7 +1036,7 @@ impl<'ln> NodeInfo for ServoThreadSafeLayoutNode<'ln> { } } -impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { +impl<'ln> ThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> { type ConcreteNode = ServoLayoutNode<'ln>; type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'ln>; type ConcreteElement = ServoLayoutElement<'ln>; @@ -1255,14 +1192,14 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { } } -pub struct ThreadSafeLayoutNodeChildrenIterator<ConcreteNode: ThreadSafeLayoutNode> { +pub struct ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> { current_node: Option<ConcreteNode>, parent_node: ConcreteNode, } -impl<ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> +impl<'dom, ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> where - ConcreteNode: DangerousThreadSafeLayoutNode, + ConcreteNode: DangerousThreadSafeLayoutNode<'dom>, { pub fn new(parent: ConcreteNode) -> Self { let first_child: Option<ConcreteNode> = match parent.get_pseudo_element_type() { @@ -1282,9 +1219,9 @@ where } } -impl<ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> +impl<'dom, ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> where - ConcreteNode: DangerousThreadSafeLayoutNode, + ConcreteNode: DangerousThreadSafeLayoutNode<'dom>, { type Item = ConcreteNode; fn next(&mut self) -> Option<ConcreteNode> { @@ -1366,7 +1303,7 @@ pub struct ServoThreadSafeLayoutElement<'le> { pseudo: PseudoElementType, } -impl<'le> ThreadSafeLayoutElement for ServoThreadSafeLayoutElement<'le> { +impl<'le> ThreadSafeLayoutElement<'le> for ServoThreadSafeLayoutElement<'le> { type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'le>; type ConcreteElement = ServoLayoutElement<'le>; diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 60710009ff5..54f1ec8d656 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -1039,7 +1039,7 @@ impl LayoutThread { self.stylist.set_quirks_mode(quirks_mode); } - fn try_get_layout_root<N: LayoutNode>(&self, node: N) -> Option<FlowRef> { + fn try_get_layout_root<'dom>(&self, node: impl LayoutNode<'dom>) -> Option<FlowRef> { let result = node.mutate_layout_data()?.flow_construction_result.get(); let mut flow = match result { @@ -1450,17 +1450,19 @@ impl LayoutThread { guards.author.clone(), ); - let restyles = document.drain_pending_restyles(); + let restyles = std::mem::take(&mut data.pending_restyles); debug!("Draining restyles: {}", restyles.len()); let mut map = SnapshotMap::new(); let elements_with_snapshot: Vec<_> = restyles .iter() .filter(|r| r.1.snapshot.is_some()) - .map(|r| r.0) + .map(|r| unsafe { ServoLayoutNode::new(&r.0).as_element().unwrap() }) .collect(); for (el, restyle) in restyles { + let el = unsafe { ServoLayoutNode::new(&el).as_element().unwrap() }; + // Propagate the descendant bit up the ancestors. Do this before // the restyle calculation so that we can also do it for new // unstyled nodes, which the descendants bit helps us find. diff --git a/components/layout_thread_2020/dom_wrapper.rs b/components/layout_thread_2020/dom_wrapper.rs index e2bdc0f42a6..55277ea309c 100644 --- a/components/layout_thread_2020/dom_wrapper.rs +++ b/components/layout_thread_2020/dom_wrapper.rs @@ -39,7 +39,6 @@ use msg::constellation_msg::{BrowsingContextId, PipelineId}; use net_traits::image::base::{Image, ImageMetadata}; use range::Range; use script::layout_exports::NodeFlags; -use script::layout_exports::PendingRestyle; use script::layout_exports::ShadowRoot; use script::layout_exports::{ CharacterDataTypeId, DocumentFragmentTypeId, ElementTypeId, HTMLElementTypeId, NodeTypeId, @@ -71,7 +70,6 @@ use servo_url::ServoUrl; use std::fmt; use std::fmt::Debug; use std::hash::{Hash, Hasher}; -use std::marker::PhantomData; use std::ptr::NonNull; use std::sync::atomic::Ordering; use std::sync::Arc as StdArc; @@ -101,12 +99,9 @@ pub unsafe fn drop_style_and_layout_data(data: OpaqueStyleAndLayoutData) { } #[derive(Clone, Copy)] -pub struct ServoLayoutNode<'a> { +pub struct ServoLayoutNode<'dom> { /// The wrapped node. - node: LayoutDom<Node>, - - /// Being chained to a PhantomData prevents `LayoutNode`s from escaping. - chain: PhantomData<&'a ()>, + node: LayoutDom<'dom, Node>, } // Those are supposed to be sound, but they aren't because the entire system @@ -138,25 +133,14 @@ impl<'a> PartialEq for ServoLayoutNode<'a> { } impl<'ln> ServoLayoutNode<'ln> { - fn from_layout_js(n: LayoutDom<Node>) -> ServoLayoutNode<'ln> { - ServoLayoutNode { - node: n, - chain: PhantomData, - } + fn from_layout_js(n: LayoutDom<'ln, Node>) -> Self { + ServoLayoutNode { node: n } } - pub unsafe fn new(address: &TrustedNodeAddress) -> ServoLayoutNode { + pub unsafe fn new(address: &TrustedNodeAddress) -> Self { ServoLayoutNode::from_layout_js(LayoutDom::from_trusted_node_address(*address)) } - /// Creates a new layout node with the same lifetime as this layout node. - pub unsafe fn new_with_this_lifetime(&self, node: &LayoutDom<Node>) -> ServoLayoutNode<'ln> { - ServoLayoutNode { - node: *node, - chain: self.chain, - } - } - fn script_type_id(&self) -> NodeTypeId { unsafe { self.node.type_id_for_layout() } } @@ -174,12 +158,9 @@ impl<'ln> NodeInfo for ServoLayoutNode<'ln> { } #[derive(Clone, Copy, PartialEq)] -pub struct ServoShadowRoot<'a> { +pub struct ServoShadowRoot<'dom> { /// The wrapped shadow root. - shadow_root: LayoutDom<ShadowRoot>, - - /// Being chained to a PhantomData prevents `ShadowRoot`s from escaping. - chain: PhantomData<&'a ()>, + shadow_root: LayoutDom<'dom, ShadowRoot>, } impl<'lr> Debug for ServoShadowRoot<'lr> { @@ -213,11 +194,8 @@ impl<'lr> TShadowRoot for ServoShadowRoot<'lr> { } impl<'lr> ServoShadowRoot<'lr> { - fn from_layout_js(shadow_root: LayoutDom<ShadowRoot>) -> ServoShadowRoot<'lr> { - ServoShadowRoot { - shadow_root, - chain: PhantomData, - } + fn from_layout_js(shadow_root: LayoutDom<'lr, ShadowRoot>) -> Self { + ServoShadowRoot { shadow_root } } pub unsafe fn flush_stylesheets( @@ -240,40 +218,24 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { unsafe { self.node .composed_parent_node_ref() - .map(|node| self.new_with_this_lifetime(&node)) + .map(Self::from_layout_js) } } fn first_child(&self) -> Option<Self> { - unsafe { - self.node - .first_child_ref() - .map(|node| self.new_with_this_lifetime(&node)) - } + unsafe { self.node.first_child_ref().map(Self::from_layout_js) } } fn last_child(&self) -> Option<Self> { - unsafe { - self.node - .last_child_ref() - .map(|node| self.new_with_this_lifetime(&node)) - } + unsafe { self.node.last_child_ref().map(Self::from_layout_js) } } fn prev_sibling(&self) -> Option<Self> { - unsafe { - self.node - .prev_sibling_ref() - .map(|node| self.new_with_this_lifetime(&node)) - } + unsafe { self.node.prev_sibling_ref().map(Self::from_layout_js) } } fn next_sibling(&self) -> Option<Self> { - unsafe { - self.node - .next_sibling_ref() - .map(|node| self.new_with_this_lifetime(&node)) - } + unsafe { self.node.next_sibling_ref().map(Self::from_layout_js) } } fn owner_doc(&self) -> Self::ConcreteDocument { @@ -315,11 +277,11 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { } } -impl<'ln> LayoutNode for ServoLayoutNode<'ln> { +impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> { type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'ln>; fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode { - ServoThreadSafeLayoutNode::new(self) + ServoThreadSafeLayoutNode::new(*self) } fn type_id(&self) -> LayoutNodeType { @@ -349,25 +311,25 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> { } } -impl<'ln> GetLayoutData for ServoLayoutNode<'ln> { +impl<'ln> GetLayoutData<'ln> for ServoLayoutNode<'ln> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> { unsafe { self.get_jsmanaged().get_style_and_layout_data() } } } -impl<'le> GetLayoutData for ServoLayoutElement<'le> { +impl<'le> GetLayoutData<'le> for ServoLayoutElement<'le> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> { self.as_node().get_style_and_layout_data() } } -impl<'ln> GetLayoutData for ServoThreadSafeLayoutNode<'ln> { +impl<'ln> GetLayoutData<'ln> for ServoThreadSafeLayoutNode<'ln> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> { self.node.get_style_and_layout_data() } } -impl<'le> GetLayoutData for ServoThreadSafeLayoutElement<'le> { +impl<'le> GetLayoutData<'le> for ServoThreadSafeLayoutElement<'le> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> { self.element.as_node().get_style_and_layout_data() } @@ -376,16 +338,15 @@ impl<'le> GetLayoutData for ServoThreadSafeLayoutElement<'le> { impl<'ln> ServoLayoutNode<'ln> { /// Returns the interior of this node as a `LayoutDom`. This is highly unsafe for layout to /// call and as such is marked `unsafe`. - pub unsafe fn get_jsmanaged(&self) -> &LayoutDom<Node> { - &self.node + pub unsafe fn get_jsmanaged(&self) -> LayoutDom<'ln, Node> { + self.node } } // A wrapper around documents that ensures ayout can only ever access safe properties. #[derive(Clone, Copy)] -pub struct ServoLayoutDocument<'ld> { - document: LayoutDom<Document>, - chain: PhantomData<&'ld ()>, +pub struct ServoLayoutDocument<'dom> { + document: LayoutDom<'dom, Document>, } impl<'ld> TDocument for ServoLayoutDocument<'ld> { @@ -412,14 +373,6 @@ impl<'ld> ServoLayoutDocument<'ld> { .next() } - pub fn drain_pending_restyles(&self) -> Vec<(ServoLayoutElement<'ld>, PendingRestyle)> { - let elements = unsafe { self.document.drain_pending_restyles() }; - elements - .into_iter() - .map(|(el, snapshot)| (ServoLayoutElement::from_layout_js(el), snapshot)) - .collect() - } - pub fn needs_paint_from_layout(&self) { unsafe { self.document.needs_paint_from_layout() } } @@ -462,19 +415,15 @@ impl<'ld> ServoLayoutDocument<'ld> { } } - pub fn from_layout_js(doc: LayoutDom<Document>) -> ServoLayoutDocument<'ld> { - ServoLayoutDocument { - document: doc, - chain: PhantomData, - } + pub fn from_layout_js(doc: LayoutDom<'ld, Document>) -> Self { + ServoLayoutDocument { document: doc } } } /// A wrapper around elements that ensures layout can only ever access safe properties. #[derive(Clone, Copy)] -pub struct ServoLayoutElement<'le> { - element: LayoutDom<Element>, - chain: PhantomData<&'le ()>, +pub struct ServoLayoutElement<'dom> { + element: LayoutDom<'dom, Element>, } impl<'le> fmt::Debug for ServoLayoutElement<'le> { @@ -755,11 +704,8 @@ impl<'le> Hash for ServoLayoutElement<'le> { impl<'le> Eq for ServoLayoutElement<'le> {} impl<'le> ServoLayoutElement<'le> { - fn from_layout_js(el: LayoutDom<Element>) -> ServoLayoutElement<'le> { - ServoLayoutElement { - element: el, - chain: PhantomData, - } + fn from_layout_js(el: LayoutDom<'le, Element>) -> Self { + ServoLayoutElement { element: el } } #[inline] @@ -805,7 +751,7 @@ impl<'le> ServoLayoutElement<'le> { } } -fn as_element<'le>(node: LayoutDom<Node>) -> Option<ServoLayoutElement<'le>> { +fn as_element<'dom>(node: LayoutDom<'dom, Node>) -> Option<ServoLayoutElement<'dom>> { node.downcast().map(ServoLayoutElement::from_layout_js) } @@ -1056,33 +1002,24 @@ impl<'a> PartialEq for ServoThreadSafeLayoutNode<'a> { } } -impl<'ln> DangerousThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { +impl<'ln> DangerousThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> { unsafe fn dangerous_first_child(&self) -> Option<Self> { self.get_jsmanaged() .first_child_ref() - .map(|node| self.new_with_this_lifetime(&node)) + .map(ServoLayoutNode::from_layout_js) + .map(Self::new) } unsafe fn dangerous_next_sibling(&self) -> Option<Self> { self.get_jsmanaged() .next_sibling_ref() - .map(|node| self.new_with_this_lifetime(&node)) + .map(ServoLayoutNode::from_layout_js) + .map(Self::new) } } impl<'ln> ServoThreadSafeLayoutNode<'ln> { - /// Creates a new layout node with the same lifetime as this layout node. - pub unsafe fn new_with_this_lifetime( - &self, - node: &LayoutDom<Node>, - ) -> ServoThreadSafeLayoutNode<'ln> { - ServoThreadSafeLayoutNode { - node: self.node.new_with_this_lifetime(node), - pseudo: PseudoElementType::Normal, - } - } - /// Creates a new `ServoThreadSafeLayoutNode` from the given `ServoLayoutNode`. - pub fn new<'a>(node: &ServoLayoutNode<'a>) -> ServoThreadSafeLayoutNode<'a> { + pub fn new(node: ServoLayoutNode<'ln>) -> Self { ServoThreadSafeLayoutNode { node: node.clone(), pseudo: PseudoElementType::Normal, @@ -1091,7 +1028,7 @@ impl<'ln> ServoThreadSafeLayoutNode<'ln> { /// Returns the interior of this node as a `LayoutDom`. This is highly unsafe for layout to /// call and as such is marked `unsafe`. - unsafe fn get_jsmanaged(&self) -> &LayoutDom<Node> { + unsafe fn get_jsmanaged(&self) -> LayoutDom<'ln, Node> { self.node.get_jsmanaged() } } @@ -1106,7 +1043,7 @@ impl<'ln> NodeInfo for ServoThreadSafeLayoutNode<'ln> { } } -impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { +impl<'ln> ThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> { type ConcreteNode = ServoLayoutNode<'ln>; type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'ln>; type ConcreteElement = ServoLayoutElement<'ln>; @@ -1262,14 +1199,14 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { } } -pub struct ThreadSafeLayoutNodeChildrenIterator<ConcreteNode: ThreadSafeLayoutNode> { +pub struct ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> { current_node: Option<ConcreteNode>, parent_node: ConcreteNode, } -impl<ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> +impl<'dom, ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> where - ConcreteNode: DangerousThreadSafeLayoutNode, + ConcreteNode: DangerousThreadSafeLayoutNode<'dom>, { pub fn new(parent: ConcreteNode) -> Self { let first_child: Option<ConcreteNode> = match parent.get_pseudo_element_type() { @@ -1289,9 +1226,9 @@ where } } -impl<ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> +impl<'dom, ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> where - ConcreteNode: DangerousThreadSafeLayoutNode, + ConcreteNode: DangerousThreadSafeLayoutNode<'dom>, { type Item = ConcreteNode; fn next(&mut self) -> Option<ConcreteNode> { @@ -1373,7 +1310,7 @@ pub struct ServoThreadSafeLayoutElement<'le> { pseudo: PseudoElementType, } -impl<'le> ThreadSafeLayoutElement for ServoThreadSafeLayoutElement<'le> { +impl<'le> ThreadSafeLayoutElement<'le> for ServoThreadSafeLayoutElement<'le> { type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'le>; type ConcreteElement = ServoLayoutElement<'le>; diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index 5a76997b2ad..05663f7d68b 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -1096,16 +1096,19 @@ impl LayoutThread { guards.author.clone(), ); - let restyles = document.drain_pending_restyles(); + let restyles = std::mem::take(&mut data.pending_restyles); + debug!("Draining restyles: {}", restyles.len()); let mut map = SnapshotMap::new(); let elements_with_snapshot: Vec<_> = restyles .iter() .filter(|r| r.1.snapshot.is_some()) - .map(|r| r.0) + .map(|r| unsafe { ServoLayoutNode::new(&r.0).as_element().unwrap() }) .collect(); for (el, restyle) in restyles { + let el = unsafe { ServoLayoutNode::new(&el).as_element().unwrap() }; + // Propagate the descendant bit up the ancestors. Do this before // the restyle calculation so that we can also do it for new // unstyled nodes, which the descendants bit helps us find. diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 259a0d560c2..7dcc76e6caf 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -241,7 +241,7 @@ pub trait AttrHelpersForLayout { } #[allow(unsafe_code)] -impl AttrHelpersForLayout for LayoutDom<Attr> { +impl AttrHelpersForLayout for LayoutDom<'_, Attr> { #[inline] unsafe fn value_forever(&self) -> &'static AttrValue { // This transmute is used to cheat the lifetime restriction. diff --git a/components/script/dom/bindings/root.rs b/components/script/dom/bindings/root.rs index 0ba69687dba..b1739ac27c3 100644 --- a/components/script/dom/bindings/root.rs +++ b/components/script/dom/bindings/root.rs @@ -331,6 +331,7 @@ impl<T> Dom<T> { debug_assert!(thread_state::get().is_layout()); LayoutDom { ptr: self.ptr.clone(), + marker: PhantomData, } } } @@ -413,13 +414,17 @@ where /// An unrooted reference to a DOM object for use in layout. `Layout*Helpers` /// traits must be implemented on this. #[unrooted_must_root_lint::allow_unrooted_interior] -pub struct LayoutDom<T> { +pub struct LayoutDom<'dom, T> { ptr: ptr::NonNull<T>, + marker: PhantomData<&'dom T>, } -impl<T: Castable> LayoutDom<T> { +impl<'dom, T> LayoutDom<'dom, T> +where + T: Castable, +{ /// Cast a DOM object root upwards to one of the interfaces it derives from. - pub fn upcast<U>(&self) -> LayoutDom<U> + pub fn upcast<U>(&self) -> LayoutDom<'dom, U> where U: Castable, T: DerivedFrom<U>, @@ -428,11 +433,12 @@ impl<T: Castable> LayoutDom<T> { let ptr: *mut T = self.ptr.as_ptr(); LayoutDom { ptr: unsafe { ptr::NonNull::new_unchecked(ptr as *mut U) }, + marker: PhantomData, } } /// Cast a DOM object downwards to one of the interfaces it might implement. - pub fn downcast<U>(&self) -> Option<LayoutDom<U>> + pub fn downcast<U>(&self) -> Option<LayoutDom<'dom, U>> where U: DerivedFrom<T>, { @@ -442,6 +448,7 @@ impl<T: Castable> LayoutDom<T> { let ptr: *mut T = self.ptr.as_ptr(); Some(LayoutDom { ptr: ptr::NonNull::new_unchecked(ptr as *mut U), + marker: PhantomData, }) } else { None @@ -450,7 +457,10 @@ impl<T: Castable> LayoutDom<T> { } } -impl<T: DomObject> LayoutDom<T> { +impl<T> LayoutDom<'_, T> +where + T: DomObject, +{ /// Get the reflector. pub unsafe fn get_jsobject(&self) -> *mut JSObject { debug_assert!(thread_state::get().is_layout()); @@ -458,7 +468,7 @@ impl<T: DomObject> LayoutDom<T> { } } -impl<T> Copy for LayoutDom<T> {} +impl<T> Copy for LayoutDom<'_, T> {} impl<T> PartialEq for Dom<T> { fn eq(&self, other: &Dom<T>) -> bool { @@ -474,13 +484,13 @@ impl<'a, T: DomObject> PartialEq<&'a T> for Dom<T> { impl<T> Eq for Dom<T> {} -impl<T> PartialEq for LayoutDom<T> { - fn eq(&self, other: &LayoutDom<T>) -> bool { +impl<T> PartialEq for LayoutDom<'_, T> { + fn eq(&self, other: &Self) -> bool { self.ptr.as_ptr() == other.ptr.as_ptr() } } -impl<T> Eq for LayoutDom<T> {} +impl<T> Eq for LayoutDom<'_, T> {} impl<T> Hash for Dom<T> { fn hash<H: Hasher>(&self, state: &mut H) { @@ -488,7 +498,7 @@ impl<T> Hash for Dom<T> { } } -impl<T> Hash for LayoutDom<T> { +impl<T> Hash for LayoutDom<'_, T> { fn hash<H: Hasher>(&self, state: &mut H) { self.ptr.as_ptr().hash(state) } @@ -497,7 +507,7 @@ impl<T> Hash for LayoutDom<T> { impl<T> Clone for Dom<T> { #[inline] #[allow(unrooted_must_root)] - fn clone(&self) -> Dom<T> { + fn clone(&self) -> Self { debug_assert!(thread_state::get().is_script()); Dom { ptr: self.ptr.clone(), @@ -505,24 +515,26 @@ impl<T> Clone for Dom<T> { } } -impl<T> Clone for LayoutDom<T> { +impl<T> Clone for LayoutDom<'_, T> { #[inline] - fn clone(&self) -> LayoutDom<T> { + fn clone(&self) -> Self { debug_assert!(thread_state::get().is_layout()); LayoutDom { ptr: self.ptr.clone(), + marker: PhantomData, } } } -impl LayoutDom<Node> { +impl LayoutDom<'_, Node> { /// Create a new JS-owned value wrapped from an address known to be a /// `Node` pointer. - pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> LayoutDom<Node> { + pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> Self { debug_assert!(thread_state::get().is_layout()); let TrustedNodeAddress(addr) = inner; LayoutDom { ptr: ptr::NonNull::new_unchecked(addr as *const Node as *mut Node), + marker: PhantomData, } } } @@ -624,7 +636,7 @@ impl<T: DomObject> MutNullableDom<T> { #[allow(unrooted_must_root)] pub unsafe fn get_inner_as_layout(&self) -> Option<LayoutDom<T>> { debug_assert!(thread_state::get().is_layout()); - ptr::read(self.ptr.get()).map(|js| js.to_layout()) + (*self.ptr.get()).as_ref().map(|js| js.to_layout()) } /// Get a rooted value out of this object @@ -732,7 +744,10 @@ unsafe impl<T: DomObject> JSTraceable for DomOnceCell<T> { } } -impl<T: DomObject> LayoutDom<T> { +impl<'dom, T> LayoutDom<'dom, T> +where + T: 'dom + DomObject, +{ /// Returns an unsafe pointer to the interior of this JS object. This is /// the only method that be safely accessed from layout. (The fact that /// this is unsafe is what necessitates the layout wrappers.) diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 2d6b6c04379..c30fced7c4d 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -36,7 +36,6 @@ use crate::dom::bindings::reflector::{DomObject, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::bindings::utils::WindowProxyHandler; -use crate::dom::document::PendingRestyle; use crate::dom::gpubuffer::GPUBufferState; use crate::dom::htmlimageelement::SourceSet; use crate::dom::htmlmediaelement::{HTMLMediaElementFetchContext, MediaFrameRenderer}; @@ -96,6 +95,7 @@ use net_traits::storage_thread::StorageType; use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceFetchTiming, ResourceThreads}; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan as TimeProfilerChan; +use script_layout_interface::message::PendingRestyle; use script_layout_interface::rpc::LayoutRPC; use script_layout_interface::OpaqueStyleAndLayoutData; use script_traits::serializable::BlobImpl; diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index fc34cab49eb..d6c01c6a145 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -157,7 +157,7 @@ pub trait LayoutCanvasRenderingContext2DHelpers { unsafe fn get_canvas_id(&self) -> CanvasId; } -impl LayoutCanvasRenderingContext2DHelpers for LayoutDom<CanvasRenderingContext2D> { +impl LayoutCanvasRenderingContext2DHelpers for LayoutDom<'_, CanvasRenderingContext2D> { #[allow(unsafe_code)] unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> { (*self.unsafe_get()) diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs index 6baa6a855d9..81456cfb60b 100644 --- a/components/script/dom/characterdata.rs +++ b/components/script/dom/characterdata.rs @@ -286,7 +286,7 @@ pub trait LayoutCharacterDataHelpers { } #[allow(unsafe_code)] -impl LayoutCharacterDataHelpers for LayoutDom<CharacterData> { +impl LayoutCharacterDataHelpers for LayoutDom<'_, CharacterData> { #[inline] unsafe fn data_for_layout(&self) -> &str { &(*self.unsafe_get()).data.borrow_for_layout() diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 7c82334c8ef..f119429e01f 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -71,7 +71,7 @@ use crate::dom::location::Location; use crate::dom::messageevent::MessageEvent; use crate::dom::mouseevent::MouseEvent; use crate::dom::node::{self, document_from_node, window_from_node, CloneChildrenFlag}; -use crate::dom::node::{LayoutNodeHelpers, Node, NodeDamage, NodeFlags, ShadowIncluding}; +use crate::dom::node::{Node, NodeDamage, NodeFlags, ShadowIncluding}; use crate::dom::nodeiterator::NodeIterator; use crate::dom::nodelist::NodeList; use crate::dom::pagetransitionevent::PageTransitionEvent; @@ -133,7 +133,8 @@ use percent_encoding::percent_decode; use profile_traits::ipc as profile_ipc; use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType}; use ref_slice::ref_slice; -use script_layout_interface::message::{Msg, ReflowGoal}; +use script_layout_interface::message::{Msg, PendingRestyle, ReflowGoal}; +use script_layout_interface::TrustedNodeAddress; use script_traits::{AnimationState, DocumentActivity, MouseButton, MouseEventType}; use script_traits::{ MsDuration, ScriptMsg, TouchEventType, TouchId, UntrustedNodeAddress, WheelDelta, @@ -157,7 +158,7 @@ use style::attr::AttrValue; use style::context::QuirksMode; use style::invalidation::element::restyle_hints::RestyleHint; use style::media_queries::{Device, MediaType}; -use style::selector_parser::{RestyleDamage, Snapshot}; +use style::selector_parser::Snapshot; use style::shared_lock::SharedRwLock as StyleSharedRwLock; use style::str::{split_html_space_chars, str_join}; use style::stylesheet_set::DocumentStylesheetSet; @@ -201,29 +202,6 @@ pub enum IsHTMLDocument { NonHTMLDocument, } -#[derive(Debug, MallocSizeOf)] -pub struct PendingRestyle { - /// If this element had a state or attribute change since the last restyle, track - /// the original condition of the element. - pub snapshot: Option<Snapshot>, - - /// Any explicit restyles hints that have been accumulated for this element. - pub hint: RestyleHint, - - /// Any explicit restyles damage that have been accumulated for this element. - pub damage: RestyleDamage, -} - -impl PendingRestyle { - pub fn new() -> Self { - PendingRestyle { - snapshot: None, - hint: RestyleHint::empty(), - damage: RestyleDamage::empty(), - } - } -} - /// <https://dom.spec.whatwg.org/#document> #[dom_struct] pub struct Document { @@ -2629,7 +2607,6 @@ pub enum DocumentSource { #[allow(unsafe_code)] pub trait LayoutDocumentHelpers { unsafe fn is_html_document_for_layout(&self) -> bool; - unsafe fn drain_pending_restyles(&self) -> Vec<(LayoutDom<Element>, PendingRestyle)>; unsafe fn needs_paint_from_layout(&self); unsafe fn will_paint(&self); unsafe fn quirks_mode(&self) -> QuirksMode; @@ -2640,29 +2617,13 @@ pub trait LayoutDocumentHelpers { } #[allow(unsafe_code)] -impl LayoutDocumentHelpers for LayoutDom<Document> { +impl LayoutDocumentHelpers for LayoutDom<'_, Document> { #[inline] unsafe fn is_html_document_for_layout(&self) -> bool { (*self.unsafe_get()).is_html_document } #[inline] - #[allow(unrooted_must_root)] - unsafe fn drain_pending_restyles(&self) -> Vec<(LayoutDom<Element>, PendingRestyle)> { - let mut elements = (*self.unsafe_get()) - .pending_restyles - .borrow_mut_for_layout(); - // Elements were in a document when they were added to this list, but that - // may no longer be true when the next layout occurs. - let result = elements - .drain() - .map(|(k, v)| (k.to_layout(), v)) - .filter(|&(ref k, _)| k.upcast::<Node>().get_flag(NodeFlags::IS_CONNECTED)) - .collect(); - result - } - - #[inline] unsafe fn needs_paint_from_layout(&self) { (*self.unsafe_get()).needs_paint.set(true) } @@ -3602,6 +3563,16 @@ impl Document { (None, None) => ElementLookupResult::None, } } + + #[allow(unrooted_must_root)] + pub fn drain_pending_restyles(&self) -> Vec<(TrustedNodeAddress, PendingRestyle)> { + self.pending_restyles + .borrow_mut() + .drain() + .filter(|(k, _)| k.upcast::<Node>().get_flag(NodeFlags::IS_CONNECTED)) + .map(|(k, v)| (k.upcast::<Node>().to_trusted_node_address(), v)) + .collect() + } } impl Element { diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 9f20d31dbc6..70000fd95f7 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -567,11 +567,11 @@ pub trait RawLayoutElementHelpers { #[inline] #[allow(unsafe_code)] -pub unsafe fn get_attr_for_layout<'a>( - elem: &'a Element, +pub unsafe fn get_attr_for_layout<'dom>( + elem: &'dom Element, namespace: &Namespace, name: &LocalName, -) -> Option<LayoutDom<Attr>> { +) -> Option<LayoutDom<'dom, Attr>> { // cast to point to T in RefCell<T> directly let attrs = elem.attrs.borrow_for_layout(); attrs @@ -620,7 +620,7 @@ impl RawLayoutElementHelpers for Element { } } -pub trait LayoutElementHelpers { +pub trait LayoutElementHelpers<'dom> { #[allow(unsafe_code)] unsafe fn has_class_for_layout(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool; #[allow(unsafe_code)] @@ -646,10 +646,10 @@ pub trait LayoutElementHelpers { fn has_selector_flags(&self, flags: ElementSelectorFlags) -> bool; /// The shadow root this element is a host of. #[allow(unsafe_code)] - unsafe fn get_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>>; + unsafe fn get_shadow_root_for_layout(&self) -> Option<LayoutDom<'dom, ShadowRoot>>; } -impl LayoutElementHelpers for LayoutDom<Element> { +impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> { #[allow(unsafe_code)] #[inline] unsafe fn has_class_for_layout(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool { @@ -1095,7 +1095,7 @@ impl LayoutElementHelpers for LayoutDom<Element> { #[inline] #[allow(unsafe_code)] - unsafe fn get_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> { + unsafe fn get_shadow_root_for_layout(&self) -> Option<LayoutDom<'dom, ShadowRoot>> { (*self.unsafe_get()) .rare_data_for_layout() .as_ref()? diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs index cc2e20e68a9..0f3a0d51e15 100644 --- a/components/script/dom/htmlbodyelement.rs +++ b/components/script/dom/htmlbodyelement.rs @@ -99,7 +99,7 @@ pub trait HTMLBodyElementLayoutHelpers { fn get_background(&self) -> Option<ServoUrl>; } -impl HTMLBodyElementLayoutHelpers for LayoutDom<HTMLBodyElement> { +impl HTMLBodyElementLayoutHelpers for LayoutDom<'_, HTMLBodyElement> { #[allow(unsafe_code)] fn get_background_color(&self) -> Option<RGBA> { unsafe { diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 21a07120b77..208ee2d2bfa 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -120,7 +120,7 @@ pub trait LayoutHTMLCanvasElementHelpers { fn get_canvas_id_for_layout(&self) -> CanvasId; } -impl LayoutHTMLCanvasElementHelpers for LayoutDom<HTMLCanvasElement> { +impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> { #[allow(unsafe_code)] fn data(&self) -> HTMLCanvasData { unsafe { diff --git a/components/script/dom/htmlfontelement.rs b/components/script/dom/htmlfontelement.rs index fe7b52c1100..cb130530703 100644 --- a/components/script/dom/htmlfontelement.rs +++ b/components/script/dom/htmlfontelement.rs @@ -106,7 +106,7 @@ pub trait HTMLFontElementLayoutHelpers { fn get_size(&self) -> Option<u32>; } -impl HTMLFontElementLayoutHelpers for LayoutDom<HTMLFontElement> { +impl HTMLFontElementLayoutHelpers for LayoutDom<'_, HTMLFontElement> { #[allow(unsafe_code)] fn get_color(&self) -> Option<RGBA> { unsafe { diff --git a/components/script/dom/htmlhrelement.rs b/components/script/dom/htmlhrelement.rs index 557e4fbcc19..a53d30e700b 100644 --- a/components/script/dom/htmlhrelement.rs +++ b/components/script/dom/htmlhrelement.rs @@ -70,7 +70,7 @@ pub trait HTMLHRLayoutHelpers { fn get_width(&self) -> LengthOrPercentageOrAuto; } -impl HTMLHRLayoutHelpers for LayoutDom<HTMLHRElement> { +impl HTMLHRLayoutHelpers for LayoutDom<'_, HTMLHRElement> { #[allow(unsafe_code)] fn get_color(&self) -> Option<RGBA> { unsafe { diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 17e38aec157..16c5c1433b6 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -486,7 +486,7 @@ pub trait HTMLIFrameElementLayoutMethods { fn get_height(&self) -> LengthOrPercentageOrAuto; } -impl HTMLIFrameElementLayoutMethods for LayoutDom<HTMLIFrameElement> { +impl HTMLIFrameElementLayoutMethods for LayoutDom<'_, HTMLIFrameElement> { #[inline] #[allow(unsafe_code)] fn pipeline_id(&self) -> Option<PipelineId> { diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 3b4052e6b73..386a77041ac 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -1382,7 +1382,7 @@ pub trait LayoutHTMLImageElementHelpers { fn get_height(&self) -> LengthOrPercentageOrAuto; } -impl LayoutHTMLImageElementHelpers for LayoutDom<HTMLImageElement> { +impl LayoutHTMLImageElementHelpers for LayoutDom<'_, HTMLImageElement> { #[allow(unsafe_code)] unsafe fn image(&self) -> Option<Arc<Image>> { (*self.unsafe_get()) diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 083e977a566..05eca7b35eb 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -726,11 +726,14 @@ unsafe fn get_raw_textinput_value(input: LayoutDom<HTMLInputElement>) -> DOMStri .get_content() } -impl LayoutHTMLInputElementHelpers for LayoutDom<HTMLInputElement> { +impl LayoutHTMLInputElementHelpers for LayoutDom<'_, HTMLInputElement> { #[allow(unsafe_code)] unsafe fn value_for_layout(self) -> String { #[allow(unsafe_code)] - unsafe fn get_raw_attr_value(input: LayoutDom<HTMLInputElement>, default: &str) -> String { + unsafe fn get_raw_attr_value( + input: LayoutDom<'_, HTMLInputElement>, + default: &str, + ) -> String { let elem = input.upcast::<Element>(); let value = (*elem.unsafe_get()) .get_attr_val_for_layout(&ns!(), &local_name!("value")) diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index f8c686d34f2..f4833de4e51 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -2447,7 +2447,7 @@ pub trait LayoutHTMLMediaElementHelpers { fn data(&self) -> HTMLMediaData; } -impl LayoutHTMLMediaElementHelpers for LayoutDom<HTMLMediaElement> { +impl LayoutHTMLMediaElementHelpers for LayoutDom<'_, HTMLMediaElement> { #[allow(unsafe_code)] fn data(&self) -> HTMLMediaData { let media = unsafe { &*self.unsafe_get() }; diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs index 95ccde45d81..aa3db5733bc 100644 --- a/components/script/dom/htmltablecellelement.rs +++ b/components/script/dom/htmltablecellelement.rs @@ -105,7 +105,7 @@ pub trait HTMLTableCellElementLayoutHelpers { } #[allow(unsafe_code)] -impl HTMLTableCellElementLayoutHelpers for LayoutDom<HTMLTableCellElement> { +impl HTMLTableCellElementLayoutHelpers for LayoutDom<'_, HTMLTableCellElement> { fn get_background_color(&self) -> Option<RGBA> { unsafe { (&*self.upcast::<Element>().unsafe_get()) diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs index d25b81cb13f..5bdb7f75281 100644 --- a/components/script/dom/htmltableelement.rs +++ b/components/script/dom/htmltableelement.rs @@ -412,7 +412,7 @@ pub trait HTMLTableElementLayoutHelpers { fn get_width(&self) -> LengthOrPercentageOrAuto; } -impl HTMLTableElementLayoutHelpers for LayoutDom<HTMLTableElement> { +impl HTMLTableElementLayoutHelpers for LayoutDom<'_, HTMLTableElement> { #[allow(unsafe_code)] fn get_background_color(&self) -> Option<RGBA> { unsafe { diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs index a99ecea162e..9a6b5b875cc 100644 --- a/components/script/dom/htmltablerowelement.rs +++ b/components/script/dom/htmltablerowelement.rs @@ -150,7 +150,7 @@ pub trait HTMLTableRowElementLayoutHelpers { } #[allow(unsafe_code)] -impl HTMLTableRowElementLayoutHelpers for LayoutDom<HTMLTableRowElement> { +impl HTMLTableRowElementLayoutHelpers for LayoutDom<'_, HTMLTableRowElement> { fn get_background_color(&self) -> Option<RGBA> { unsafe { (&*self.upcast::<Element>().unsafe_get()) diff --git a/components/script/dom/htmltablesectionelement.rs b/components/script/dom/htmltablesectionelement.rs index 1410e0ee1a4..c680da2ad23 100644 --- a/components/script/dom/htmltablesectionelement.rs +++ b/components/script/dom/htmltablesectionelement.rs @@ -88,7 +88,7 @@ pub trait HTMLTableSectionElementLayoutHelpers { } #[allow(unsafe_code)] -impl HTMLTableSectionElementLayoutHelpers for LayoutDom<HTMLTableSectionElement> { +impl HTMLTableSectionElementLayoutHelpers for LayoutDom<'_, HTMLTableSectionElement> { fn get_background_color(&self) -> Option<RGBA> { unsafe { (&*self.upcast::<Element>().unsafe_get()) diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 0708b553442..8ee42bc2c86 100755 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -66,7 +66,7 @@ pub trait LayoutHTMLTextAreaElementHelpers { fn get_rows(self) -> u32; } -impl LayoutHTMLTextAreaElementHelpers for LayoutDom<HTMLTextAreaElement> { +impl LayoutHTMLTextAreaElementHelpers for LayoutDom<'_, HTMLTextAreaElement> { #[allow(unrooted_must_root)] #[allow(unsafe_code)] unsafe fn value_for_layout(self) -> String { diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 2d6b4b581f6..08fe3282be1 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -1304,17 +1304,17 @@ pub unsafe fn from_untrusted_node_address( } #[allow(unsafe_code)] -pub trait LayoutNodeHelpers { +pub trait LayoutNodeHelpers<'dom> { unsafe fn type_id_for_layout(&self) -> NodeTypeId; - unsafe fn composed_parent_node_ref(&self) -> Option<LayoutDom<Node>>; - unsafe fn first_child_ref(&self) -> Option<LayoutDom<Node>>; - unsafe fn last_child_ref(&self) -> Option<LayoutDom<Node>>; - unsafe fn prev_sibling_ref(&self) -> Option<LayoutDom<Node>>; - unsafe fn next_sibling_ref(&self) -> Option<LayoutDom<Node>>; + unsafe fn composed_parent_node_ref(&self) -> Option<LayoutDom<'dom, Node>>; + unsafe fn first_child_ref(&self) -> Option<LayoutDom<'dom, Node>>; + unsafe fn last_child_ref(&self) -> Option<LayoutDom<'dom, Node>>; + unsafe fn prev_sibling_ref(&self) -> Option<LayoutDom<'dom, Node>>; + unsafe fn next_sibling_ref(&self) -> Option<LayoutDom<'dom, Node>>; - unsafe fn owner_doc_for_layout(&self) -> LayoutDom<Document>; - unsafe fn containing_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>>; + unsafe fn owner_doc_for_layout(&self) -> LayoutDom<'dom, Document>; + unsafe fn containing_shadow_root_for_layout(&self) -> Option<LayoutDom<'dom, ShadowRoot>>; unsafe fn is_element_for_layout(&self) -> bool; unsafe fn get_flag(&self, flag: NodeFlags) -> bool; @@ -1339,7 +1339,7 @@ pub trait LayoutNodeHelpers { fn opaque(&self) -> OpaqueNode; } -impl LayoutNodeHelpers for LayoutDom<Node> { +impl<'dom> LayoutNodeHelpers<'dom> for LayoutDom<'dom, Node> { #[inline] #[allow(unsafe_code)] unsafe fn type_id_for_layout(&self) -> NodeTypeId { @@ -1354,7 +1354,7 @@ impl LayoutNodeHelpers for LayoutDom<Node> { #[inline] #[allow(unsafe_code)] - unsafe fn composed_parent_node_ref(&self) -> Option<LayoutDom<Node>> { + unsafe fn composed_parent_node_ref(&self) -> Option<LayoutDom<'dom, Node>> { let parent = (*self.unsafe_get()).parent_node.get_inner_as_layout(); if let Some(ref parent) = parent { if let Some(shadow_root) = parent.downcast::<ShadowRoot>() { @@ -1366,31 +1366,31 @@ impl LayoutNodeHelpers for LayoutDom<Node> { #[inline] #[allow(unsafe_code)] - unsafe fn first_child_ref(&self) -> Option<LayoutDom<Node>> { + unsafe fn first_child_ref(&self) -> Option<LayoutDom<'dom, Node>> { (*self.unsafe_get()).first_child.get_inner_as_layout() } #[inline] #[allow(unsafe_code)] - unsafe fn last_child_ref(&self) -> Option<LayoutDom<Node>> { + unsafe fn last_child_ref(&self) -> Option<LayoutDom<'dom, Node>> { (*self.unsafe_get()).last_child.get_inner_as_layout() } #[inline] #[allow(unsafe_code)] - unsafe fn prev_sibling_ref(&self) -> Option<LayoutDom<Node>> { + unsafe fn prev_sibling_ref(&self) -> Option<LayoutDom<'dom, Node>> { (*self.unsafe_get()).prev_sibling.get_inner_as_layout() } #[inline] #[allow(unsafe_code)] - unsafe fn next_sibling_ref(&self) -> Option<LayoutDom<Node>> { + unsafe fn next_sibling_ref(&self) -> Option<LayoutDom<'dom, Node>> { (*self.unsafe_get()).next_sibling.get_inner_as_layout() } #[inline] #[allow(unsafe_code)] - unsafe fn owner_doc_for_layout(&self) -> LayoutDom<Document> { + unsafe fn owner_doc_for_layout(&self) -> LayoutDom<'dom, Document> { (*self.unsafe_get()) .owner_doc .get_inner_as_layout() @@ -1399,7 +1399,7 @@ impl LayoutNodeHelpers for LayoutDom<Node> { #[inline] #[allow(unsafe_code)] - unsafe fn containing_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> { + unsafe fn containing_shadow_root_for_layout(&self) -> Option<LayoutDom<'dom, ShadowRoot>> { (*self.unsafe_get()) .rare_data_for_layout() .as_ref()? diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs index 2324a685042..71db09f4671 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -239,8 +239,8 @@ impl ShadowRootMethods for ShadowRoot { } #[allow(unsafe_code)] -pub trait LayoutShadowRootHelpers { - unsafe fn get_host_for_layout(&self) -> LayoutDom<Element>; +pub trait LayoutShadowRootHelpers<'dom> { + unsafe fn get_host_for_layout(&self) -> LayoutDom<'dom, Element>; unsafe fn get_style_data_for_layout<'a, E: TElement>( &self, ) -> &'a AuthorStyles<StyleSheetInDocument>; @@ -252,10 +252,10 @@ pub trait LayoutShadowRootHelpers { ); } -impl LayoutShadowRootHelpers for LayoutDom<ShadowRoot> { +impl<'dom> LayoutShadowRootHelpers<'dom> for LayoutDom<'dom, ShadowRoot> { #[inline] #[allow(unsafe_code)] - unsafe fn get_host_for_layout(&self) -> LayoutDom<Element> { + unsafe fn get_host_for_layout(&self) -> LayoutDom<'dom, Element> { (*self.unsafe_get()) .host .get_inner_as_layout() diff --git a/components/script/dom/svgsvgelement.rs b/components/script/dom/svgsvgelement.rs index 8671f8a9027..8c8c1dbb834 100644 --- a/components/script/dom/svgsvgelement.rs +++ b/components/script/dom/svgsvgelement.rs @@ -52,7 +52,7 @@ pub trait LayoutSVGSVGElementHelpers { fn data(&self) -> SVGSVGData; } -impl LayoutSVGSVGElementHelpers for LayoutDom<SVGSVGElement> { +impl LayoutSVGSVGElementHelpers for LayoutDom<'_, SVGSVGElement> { #[allow(unsafe_code, non_snake_case)] fn data(&self) -> SVGSVGData { unsafe { diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index 4571b26d9e2..03eb5e7abc2 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -3884,7 +3884,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } } -impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom<WebGL2RenderingContext> { +impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom<'_, WebGL2RenderingContext> { #[allow(unsafe_code)] unsafe fn canvas_data_source(&self) -> HTMLCanvasDataSource { let this = &*self.unsafe_get(); diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 983dc3a1633..8e76eb552a3 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -4450,7 +4450,7 @@ pub trait LayoutCanvasWebGLRenderingContextHelpers { unsafe fn canvas_data_source(&self) -> HTMLCanvasDataSource; } -impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom<WebGLRenderingContext> { +impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom<'_, WebGLRenderingContext> { #[allow(unsafe_code)] unsafe fn canvas_data_source(&self) -> HTMLCanvasDataSource { (*self.unsafe_get()).layout_handle() diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 1ea51a5c156..688ced4fda7 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -1617,13 +1617,14 @@ impl Window { reflow_info: Reflow { page_clip_rect: self.page_clip_rect.get(), }, - document: self.Document().upcast::<Node>().to_trusted_node_address(), + document: document.upcast::<Node>().to_trusted_node_address(), stylesheets_changed, window_size: self.window_size.get(), origin: self.origin().immutable().clone(), reflow_goal, script_join_chan: join_chan, - dom_count: self.Document().dom_count(), + dom_count: document.dom_count(), + pending_restyles: document.drain_pending_restyles(), }; self.layout_chan diff --git a/components/script/lib.rs b/components/script/lib.rs index 1962e9602d6..0df29eb6359 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -130,7 +130,7 @@ pub mod layout_exports { pub use crate::dom::bindings::inheritance::{HTMLElementTypeId, NodeTypeId, TextTypeId}; pub use crate::dom::bindings::root::LayoutDom; pub use crate::dom::characterdata::LayoutCharacterDataHelpers; - pub use crate::dom::document::{Document, LayoutDocumentHelpers, PendingRestyle}; + pub use crate::dom::document::{Document, LayoutDocumentHelpers}; pub use crate::dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers}; pub use crate::dom::node::NodeFlags; pub use crate::dom::node::{LayoutNodeHelpers, Node}; diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs index e48ac42f509..96c4a132368 100644 --- a/components/script_layout_interface/message.rs +++ b/components/script_layout_interface/message.rs @@ -23,8 +23,9 @@ use std::sync::atomic::AtomicBool; use std::sync::Arc; use style::context::QuirksMode; use style::dom::OpaqueNode; +use style::invalidation::element::restyle_hints::RestyleHint; use style::properties::PropertyId; -use style::selector_parser::PseudoElement; +use style::selector_parser::{PseudoElement, RestyleDamage, Snapshot}; use style::stylesheets::Stylesheet; /// Asynchronous messages that script can send to layout. @@ -218,6 +219,8 @@ pub struct ScriptReflow { pub dom_count: u32, /// The current window origin pub origin: ImmutableOrigin, + /// Restyle snapshot map. + pub pending_restyles: Vec<(TrustedNodeAddress, PendingRestyle)>, } pub struct LayoutThreadInit { @@ -234,3 +237,29 @@ pub struct LayoutThreadInit { pub layout_is_busy: Arc<AtomicBool>, pub window_size: WindowSizeData, } + +/// A pending restyle. +#[derive(Debug, MallocSizeOf)] +pub struct PendingRestyle { + /// If this element had a state or attribute change since the last restyle, track + /// the original condition of the element. + pub snapshot: Option<Snapshot>, + + /// Any explicit restyles hints that have been accumulated for this element. + pub hint: RestyleHint, + + /// Any explicit restyles damage that have been accumulated for this element. + pub damage: RestyleDamage, +} + +impl PendingRestyle { + /// Creates a new empty pending restyle. + #[inline] + pub fn new() -> Self { + PendingRestyle { + snapshot: None, + hint: RestyleHint::empty(), + damage: RestyleDamage::empty(), + } + } +} diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs index f5801649810..67b107a86d7 100644 --- a/components/script_layout_interface/wrapper_traits.rs +++ b/components/script_layout_interface/wrapper_traits.rs @@ -78,14 +78,14 @@ impl PseudoElementType { } /// Trait to abstract access to layout data across various data structures. -pub trait GetLayoutData { +pub trait GetLayoutData<'dom> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData>; } /// A wrapper so that layout can access only the methods that it should have access to. Layout must /// only ever see these and must never see instances of `LayoutDom`. -pub trait LayoutNode: Debug + GetLayoutData + TNode { - type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode; +pub trait LayoutNode<'dom>: Debug + GetLayoutData<'dom> + TNode { + type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>; fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode; /// Returns the type ID of this node. @@ -109,16 +109,13 @@ pub trait LayoutNode: Debug + GetLayoutData + TNode { fn is_connected(&self) -> bool; } -pub struct ReverseChildrenIterator<ConcreteNode> -where - ConcreteNode: LayoutNode, -{ +pub struct ReverseChildrenIterator<ConcreteNode> { current: Option<ConcreteNode>, } -impl<ConcreteNode> Iterator for ReverseChildrenIterator<ConcreteNode> +impl<'dom, ConcreteNode> Iterator for ReverseChildrenIterator<ConcreteNode> where - ConcreteNode: LayoutNode, + ConcreteNode: LayoutNode<'dom>, { type Item = ConcreteNode; fn next(&mut self) -> Option<ConcreteNode> { @@ -128,16 +125,13 @@ where } } -pub struct TreeIterator<ConcreteNode> -where - ConcreteNode: LayoutNode, -{ +pub struct TreeIterator<ConcreteNode> { stack: Vec<ConcreteNode>, } -impl<ConcreteNode> TreeIterator<ConcreteNode> +impl<'dom, ConcreteNode> TreeIterator<ConcreteNode> where - ConcreteNode: LayoutNode, + ConcreteNode: LayoutNode<'dom>, { fn new(root: ConcreteNode) -> TreeIterator<ConcreteNode> { let mut stack = vec![]; @@ -150,9 +144,9 @@ where } } -impl<ConcreteNode> Iterator for TreeIterator<ConcreteNode> +impl<'dom, ConcreteNode> Iterator for TreeIterator<ConcreteNode> where - ConcreteNode: LayoutNode, + ConcreteNode: LayoutNode<'dom>, { type Item = ConcreteNode; fn next(&mut self) -> Option<ConcreteNode> { @@ -164,13 +158,13 @@ where /// A thread-safe version of `LayoutNode`, used during flow construction. This type of layout /// node does not allow any parents or siblings of nodes to be accessed, to avoid races. -pub trait ThreadSafeLayoutNode: - Clone + Copy + Debug + GetLayoutData + NodeInfo + PartialEq + Sized +pub trait ThreadSafeLayoutNode<'dom>: + Clone + Copy + Debug + GetLayoutData<'dom> + NodeInfo + PartialEq + Sized { - type ConcreteNode: LayoutNode<ConcreteThreadSafeLayoutNode = Self>; + type ConcreteNode: LayoutNode<'dom, ConcreteThreadSafeLayoutNode = Self>; type ConcreteElement: TElement; - type ConcreteThreadSafeLayoutElement: ThreadSafeLayoutElement<ConcreteThreadSafeLayoutNode = Self> + type ConcreteThreadSafeLayoutElement: ThreadSafeLayoutElement<'dom, ConcreteThreadSafeLayoutNode = Self> + ::selectors::Element<Impl = SelectorImpl>; type ChildrenIterator: Iterator<Item = Self> + Sized; @@ -313,15 +307,18 @@ pub trait ThreadSafeLayoutNode: // This trait is only public so that it can be implemented by the gecko wrapper. // It can be used to violate thread-safety, so don't use it elsewhere in layout! #[allow(unsafe_code)] -pub trait DangerousThreadSafeLayoutNode: ThreadSafeLayoutNode { +pub trait DangerousThreadSafeLayoutNode<'dom>: ThreadSafeLayoutNode<'dom> { unsafe fn dangerous_first_child(&self) -> Option<Self>; unsafe fn dangerous_next_sibling(&self) -> Option<Self>; } -pub trait ThreadSafeLayoutElement: - Clone + Copy + Sized + Debug + ::selectors::Element<Impl = SelectorImpl> + GetLayoutData +pub trait ThreadSafeLayoutElement<'dom>: + Clone + Copy + Sized + Debug + ::selectors::Element<Impl = SelectorImpl> + GetLayoutData<'dom> { - type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<ConcreteThreadSafeLayoutElement = Self>; + type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode< + 'dom, + ConcreteThreadSafeLayoutElement = Self, + >; /// This type alias is just a work-around to avoid writing /// |