Add a 'dom lifetime to GetLayoutData

This commit is contained in:
Anthony Ramine 2020-03-26 13:17:46 +01:00
parent 2d055cbf6b
commit 04af32128c
15 changed files with 130 additions and 125 deletions

View file

@ -181,12 +181,15 @@ pub struct InlineBlockSplit {
impl InlineBlockSplit { impl InlineBlockSplit {
/// Flushes the given accumulator to the new split and makes a new accumulator to hold any /// Flushes the given accumulator to the new split and makes a new accumulator to hold any
/// subsequent fragments. /// subsequent fragments.
fn new<ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>( fn new<'dom, ConcreteThreadSafeLayoutNode>(
fragment_accumulator: &mut InlineFragmentsAccumulator, fragment_accumulator: &mut InlineFragmentsAccumulator,
node: &ConcreteThreadSafeLayoutNode, node: &ConcreteThreadSafeLayoutNode,
style_context: &SharedStyleContext, style_context: &SharedStyleContext,
flow: FlowRef, flow: FlowRef,
) -> InlineBlockSplit { ) -> InlineBlockSplit
where
ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>,
{
fragment_accumulator.enclosing_node.as_mut().expect( fragment_accumulator.enclosing_node.as_mut().expect(
"enclosing_node is None; Are {ib} splits being generated outside of an inline node?" "enclosing_node is None; Are {ib} splits being generated outside of an inline node?"
).flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT); ).flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT);
@ -272,13 +275,10 @@ impl InlineFragmentsAccumulator {
} }
} }
fn from_inline_node<N>( fn from_inline_node<'dom>(
node: &N, node: &impl ThreadSafeLayoutNode<'dom>,
style_context: &SharedStyleContext, style_context: &SharedStyleContext,
) -> InlineFragmentsAccumulator ) -> InlineFragmentsAccumulator {
where
N: ThreadSafeLayoutNode,
{
InlineFragmentsAccumulator { InlineFragmentsAccumulator {
fragments: IntermediateInlineFragments::new(), fragments: IntermediateInlineFragments::new(),
enclosing_node: Some(InlineFragmentNodeInfo { enclosing_node: Some(InlineFragmentNodeInfo {
@ -305,12 +305,12 @@ impl InlineFragmentsAccumulator {
.push_descendants(fragments.absolute_descendants); .push_descendants(fragments.absolute_descendants);
} }
fn to_intermediate_inline_fragments<N>( fn to_intermediate_inline_fragments<'dom, N>(
self, self,
context: &SharedStyleContext, context: &SharedStyleContext,
) -> IntermediateInlineFragments ) -> IntermediateInlineFragments
where where
N: ThreadSafeLayoutNode, N: ThreadSafeLayoutNode<'dom>,
{ {
let InlineFragmentsAccumulator { let InlineFragmentsAccumulator {
mut fragments, mut fragments,
@ -366,7 +366,7 @@ impl InlineFragmentsAccumulator {
} }
/// An object that knows how to create flows. /// An object that knows how to create flows.
pub struct FlowConstructor<'a, N: ThreadSafeLayoutNode> { pub struct FlowConstructor<'a, N> {
/// The layout context. /// The layout context.
pub layout_context: &'a LayoutContext<'a>, pub layout_context: &'a LayoutContext<'a>,
/// Satisfy the compiler about the unused parameters, which we use to improve the ergonomics of /// 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>, phantom2: PhantomData<N>,
} }
impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> impl<'a, 'dom, ConcreteThreadSafeLayoutNode> FlowConstructor<'a, ConcreteThreadSafeLayoutNode>
FlowConstructor<'a, ConcreteThreadSafeLayoutNode> where
ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>,
{ {
/// Creates a new flow constructor. /// Creates a new flow constructor.
pub fn new(layout_context: &'a LayoutContext<'a>) -> Self { 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> for FlowConstructor<'a, ConcreteThreadSafeLayoutNode>
where where
ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>,
{ {
// Construct Flow based on 'display', 'position', and 'float' values. // Construct Flow based on 'display', 'position', and 'float' values.
// //
@ -1988,9 +1990,9 @@ trait NodeUtils {
fn get_construction_result(self) -> ConstructionResult; fn get_construction_result(self) -> ConstructionResult;
} }
impl<ConcreteThreadSafeLayoutNode> NodeUtils for ConcreteThreadSafeLayoutNode impl<'dom, ConcreteThreadSafeLayoutNode> NodeUtils for ConcreteThreadSafeLayoutNode
where where
ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>,
{ {
fn is_replaced_content(&self) -> bool { fn is_replaced_content(&self) -> bool {
match self.type_id() { match self.type_id() {

View file

@ -411,10 +411,10 @@ impl ImageFragmentInfo {
/// ///
/// FIXME(pcwalton): The fact that image fragments store the cache in the fragment makes little /// FIXME(pcwalton): The fact that image fragments store the cache in the fragment makes little
/// sense to me. /// sense to me.
pub fn new<N: ThreadSafeLayoutNode>( pub fn new<'dom>(
url: Option<ServoUrl>, url: Option<ServoUrl>,
density: Option<f64>, density: Option<f64>,
node: &N, node: &impl ThreadSafeLayoutNode<'dom>,
layout_context: &LayoutContext, layout_context: &LayoutContext,
) -> ImageFragmentInfo { ) -> ImageFragmentInfo {
// First use any image data present in the element... // First use any image data present in the element...
@ -488,7 +488,7 @@ pub struct IframeFragmentInfo {
impl IframeFragmentInfo { impl IframeFragmentInfo {
/// Creates the information specific to an iframe fragment. /// 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 browsing_context_id = node.iframe_browsing_context_id();
let pipeline_id = node.iframe_pipeline_id(); let pipeline_id = node.iframe_pipeline_id();
IframeFragmentInfo { IframeFragmentInfo {
@ -642,7 +642,7 @@ pub struct TableColumnFragmentInfo {
impl TableColumnFragmentInfo { impl TableColumnFragmentInfo {
/// Create the information specific to an table column fragment. /// 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 element = node.as_element().unwrap();
let span = element let span = element
.get_attr(&ns!(), &local_name!("span")) .get_attr(&ns!(), &local_name!("span"))
@ -663,8 +663,8 @@ pub struct TruncatedFragmentInfo {
impl Fragment { impl Fragment {
/// Constructs a new `Fragment` instance. /// Constructs a new `Fragment` instance.
pub fn new<N: ThreadSafeLayoutNode>( pub fn new<'dom>(
node: &N, node: &impl ThreadSafeLayoutNode<'dom>,
specific: SpecificFragmentInfo, specific: SpecificFragmentInfo,
ctx: &LayoutContext, ctx: &LayoutContext,
) -> Fragment { ) -> Fragment {

View file

@ -688,9 +688,9 @@ pub fn process_client_rect_query(
iterator.client_rect iterator.client_rect
} }
pub fn process_node_scroll_id_request<N: LayoutNode>( pub fn process_node_scroll_id_request<'dom>(
id: PipelineId, id: PipelineId,
requested_node: N, requested_node: impl LayoutNode<'dom>,
) -> ExternalScrollId { ) -> ExternalScrollId {
let layout_node = requested_node.to_threadsafe(); let layout_node = requested_node.to_threadsafe();
layout_node.generate_scroll_id(id) 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. /// Return the resolved value of property for a given (pseudo)element.
/// <https://drafts.csswg.org/cssom/#resolved-value> /// <https://drafts.csswg.org/cssom/#resolved-value>
pub fn process_resolved_style_request<'a, N>( pub fn process_resolved_style_request<'dom>(
context: &LayoutContext, context: &LayoutContext,
node: N, node: impl LayoutNode<'dom>,
pseudo: &Option<PseudoElement>, pseudo: &Option<PseudoElement>,
property: &PropertyId, property: &PropertyId,
layout_root: &mut dyn Flow, layout_root: &mut dyn Flow,
) -> String ) -> String {
where
N: LayoutNode,
{
use style::stylist::RuleInclusion; use style::stylist::RuleInclusion;
use style::traversal::resolve_style; use style::traversal::resolve_style;
@ -797,15 +794,12 @@ where
} }
/// The primary resolution logic, which assumes that the element is styled. /// The primary resolution logic, which assumes that the element is styled.
fn process_resolved_style_request_internal<'a, N>( fn process_resolved_style_request_internal<'dom>(
requested_node: N, requested_node: impl LayoutNode<'dom>,
pseudo: &Option<PseudoElement>, pseudo: &Option<PseudoElement>,
property: &PropertyId, property: &PropertyId,
layout_root: &mut dyn Flow, layout_root: &mut dyn Flow,
) -> String ) -> String {
where
N: LayoutNode,
{
let layout_el = requested_node.to_threadsafe().as_element().unwrap(); let layout_el = requested_node.to_threadsafe().as_element().unwrap();
let layout_el = match *pseudo { let layout_el = match *pseudo {
Some(PseudoElement::Before) => layout_el.get_before_pseudo(), Some(PseudoElement::Before) => layout_el.get_before_pseudo(),
@ -851,12 +845,15 @@ where
// There are probably other quirks. // There are probably other quirks.
let applies = true; let applies = true;
fn used_value_for_position_property<N: LayoutNode>( fn used_value_for_position_property<'dom, N>(
layout_el: <N::ConcreteThreadSafeLayoutNode as ThreadSafeLayoutNode>::ConcreteThreadSafeLayoutElement, layout_el: <N::ConcreteThreadSafeLayoutNode as ThreadSafeLayoutNode<'dom>>::ConcreteThreadSafeLayoutElement,
layout_root: &mut dyn Flow, layout_root: &mut dyn Flow,
requested_node: N, requested_node: N,
longhand_id: LonghandId, longhand_id: LonghandId,
) -> String { ) -> String
where
N: LayoutNode<'dom>,
{
let maybe_data = layout_el.borrow_layout_data(); let maybe_data = layout_el.borrow_layout_data();
let position = maybe_data.map_or(Point2D::zero(), |data| { let position = maybe_data.map_or(Point2D::zero(), |data| {
match (*data).flow_construction_result { 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 element = requested_node.as_element().unwrap();
let data = element.borrow_data(); let data = element.borrow_data();
@ -982,8 +979,8 @@ enum InnerTextItem {
} }
// https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute // https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute
pub fn process_element_inner_text_query<N: LayoutNode>( pub fn process_element_inner_text_query<'dom>(
node: N, node: impl LayoutNode<'dom>,
indexable_text: &IndexableText, indexable_text: &IndexableText,
) -> String { ) -> String {
// Step 1. // 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 // https://html.spec.whatwg.org/multipage/#inner-text-collection-steps
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn inner_text_collection_steps<N: LayoutNode>( fn inner_text_collection_steps<'dom>(
node: N, node: impl LayoutNode<'dom>,
indexable_text: &IndexableText, indexable_text: &IndexableText,
results: &mut Vec<InnerTextItem>, results: &mut Vec<InnerTextItem>,
) { ) {

View file

@ -61,8 +61,8 @@ impl TableCellFlow {
} }
} }
pub fn from_node_fragment_and_visibility_flag<N: ThreadSafeLayoutNode>( pub fn from_node_fragment_and_visibility_flag<'dom>(
node: &N, node: &impl ThreadSafeLayoutNode<'dom>,
fragment: Fragment, fragment: Fragment,
visible: bool, visible: bool,
) -> TableCellFlow { ) -> TableCellFlow {

View file

@ -38,10 +38,10 @@ impl<'a> RecalcStyleAndConstructFlows<'a> {
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
impl<'a, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a> impl<'a, 'dom, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a>
where where
E: TElement, E: TElement,
E::ConcreteNode: LayoutNode, E::ConcreteNode: LayoutNode<'dom>,
E::FontMetricsProvider: Send, E::FontMetricsProvider: Send,
{ {
fn process_preorder<F>( fn process_preorder<F>(
@ -175,7 +175,10 @@ pub trait InorderFlowTraversal {
} }
/// A bottom-up, parallelizable traversal. /// 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. /// The operation to perform. Return true to continue or false to stop.
fn process(&mut self, node: &ConcreteThreadSafeLayoutNode); 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. /// The flow construction traversal, which builds flows for styled nodes.
#[inline] #[inline]
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn construct_flows_at<N>(context: &LayoutContext, node: N) fn construct_flows_at<'dom>(context: &LayoutContext, node: impl LayoutNode<'dom>) {
where
N: LayoutNode,
{
debug!("construct_flows_at: {:?}", node); debug!("construct_flows_at: {:?}", node);
// Construct flows for this node. // Construct flows for this node.

View file

@ -47,7 +47,10 @@ pub trait LayoutNodeLayoutData {
fn flow_debug_id(self) -> usize; 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>> { fn borrow_layout_data(&self) -> Option<AtomicRef<LayoutData>> {
self.get_raw_data().map(|d| d.layout_data.borrow()) self.get_raw_data().map(|d| d.layout_data.borrow())
} }
@ -66,7 +69,10 @@ pub trait GetRawData {
fn get_raw_data(&self) -> Option<&StyleAndLayoutData>; 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> { fn get_raw_data(&self) -> Option<&StyleAndLayoutData> {
self.get_style_and_layout_data().map(|opaque| { self.get_style_and_layout_data().map(|opaque| {
let container = opaque.ptr.as_ptr() as *mut StyleAndLayoutData; let container = opaque.ptr.as_ptr() as *mut StyleAndLayoutData;
@ -98,7 +104,10 @@ pub trait ThreadSafeLayoutNodeHelpers {
fn restyle_damage(self) -> RestyleDamage; 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 { fn flags(self) -> LayoutDataFlags {
self.borrow_layout_data().as_ref().unwrap().flags self.borrow_layout_data().as_ref().unwrap().flags
} }

View file

@ -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 is_element(self) -> bool;
fn as_text(self) -> Option<String>; 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 impl<'dom, T> NodeExt<'dom> for T
where where
T: 'dom + Copy + LayoutNode + Send + Sync, T: 'dom + Copy + LayoutNode<'dom> + Send + Sync,
{ {
fn is_element(self) -> bool { fn is_element(self) -> bool {
self.to_threadsafe().as_element().is_some() self.to_threadsafe().as_element().is_some()

View file

@ -50,7 +50,7 @@ pub struct FragmentTreeRoot {
impl BoxTreeRoot { impl BoxTreeRoot {
pub fn construct<'dom, Node>(context: &LayoutContext, root_element: Node) -> Self pub fn construct<'dom, Node>(context: &LayoutContext, root_element: Node) -> Self
where 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); let (contains_floats, boxes) = construct_for_root_element(&context, root_element);
Self(BlockFormattingContext { Self(BlockFormattingContext {

View file

@ -192,9 +192,9 @@ pub fn process_node_geometry_request(
fragment_tree_root.get_border_dimensions_for_node(requested_node) 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, id: PipelineId,
requested_node: N, requested_node: impl LayoutNode<'dom>,
) -> ExternalScrollId { ) -> ExternalScrollId {
let layout_node = requested_node.to_threadsafe(); let layout_node = requested_node.to_threadsafe();
layout_node.generate_scroll_id(id) 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. /// Return the resolved value of property for a given (pseudo)element.
/// <https://drafts.csswg.org/cssom/#resolved-value> /// <https://drafts.csswg.org/cssom/#resolved-value>
pub fn process_resolved_style_request<'a, N>( pub fn process_resolved_style_request<'dom>(
_context: &LayoutContext, _context: &LayoutContext,
_node: N, _node: impl LayoutNode<'dom>,
_pseudo: &Option<PseudoElement>, _pseudo: &Option<PseudoElement>,
_property: &PropertyId, _property: &PropertyId,
) -> String ) -> String {
where
N: LayoutNode,
{
"".to_owned() "".to_owned()
} }
@ -223,12 +220,12 @@ pub fn process_offset_parent_query(_requested_node: OpaqueNode) -> OffsetParentR
OffsetParentResponse::empty() 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) StyleResponse(None)
} }
// https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute // 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() "".to_owned()
} }

View file

@ -30,10 +30,10 @@ impl<'a> RecalcStyle<'a> {
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
impl<'a, E> DomTraversal<E> for RecalcStyle<'a> impl<'a, 'dom, E> DomTraversal<E> for RecalcStyle<'a>
where where
E: TElement, E: TElement,
E::ConcreteNode: LayoutNode, E::ConcreteNode: LayoutNode<'dom>,
E::FontMetricsProvider: Send, E::FontMetricsProvider: Send,
{ {
fn process_preorder<F>( fn process_preorder<F>(

View file

@ -11,7 +11,10 @@ pub trait GetRawData {
fn get_raw_data(&self) -> Option<&StyleAndLayoutData>; 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> { fn get_raw_data(&self) -> Option<&StyleAndLayoutData> {
self.get_style_and_layout_data().map(|opaque| { self.get_style_and_layout_data().map(|opaque| {
let container = opaque.ptr.as_ptr() as *mut StyleAndLayoutData; let container = opaque.ptr.as_ptr() as *mut StyleAndLayoutData;

View file

@ -308,7 +308,7 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
} }
} }
impl<'ln> LayoutNode for ServoLayoutNode<'ln> { impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> {
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'ln>; type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'ln>;
fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode { fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode {
@ -342,25 +342,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> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
unsafe { self.get_jsmanaged().get_style_and_layout_data() } 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> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
self.as_node().get_style_and_layout_data() 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> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
self.node.get_style_and_layout_data() 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> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
self.element.as_node().get_style_and_layout_data() self.element.as_node().get_style_and_layout_data()
} }
@ -1049,7 +1049,7 @@ 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> { unsafe fn dangerous_first_child(&self) -> Option<Self> {
self.get_jsmanaged() self.get_jsmanaged()
.first_child_ref() .first_child_ref()
@ -1099,7 +1099,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 ConcreteNode = ServoLayoutNode<'ln>;
type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'ln>; type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'ln>;
type ConcreteElement = ServoLayoutElement<'ln>; type ConcreteElement = ServoLayoutElement<'ln>;
@ -1255,14 +1255,14 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
} }
} }
pub struct ThreadSafeLayoutNodeChildrenIterator<ConcreteNode: ThreadSafeLayoutNode> { pub struct ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> {
current_node: Option<ConcreteNode>, current_node: Option<ConcreteNode>,
parent_node: ConcreteNode, parent_node: ConcreteNode,
} }
impl<ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> impl<'dom, ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<ConcreteNode>
where where
ConcreteNode: DangerousThreadSafeLayoutNode, ConcreteNode: DangerousThreadSafeLayoutNode<'dom>,
{ {
pub fn new(parent: ConcreteNode) -> Self { pub fn new(parent: ConcreteNode) -> Self {
let first_child: Option<ConcreteNode> = match parent.get_pseudo_element_type() { let first_child: Option<ConcreteNode> = match parent.get_pseudo_element_type() {
@ -1282,9 +1282,9 @@ where
} }
} }
impl<ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> impl<'dom, ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNode>
where where
ConcreteNode: DangerousThreadSafeLayoutNode, ConcreteNode: DangerousThreadSafeLayoutNode<'dom>,
{ {
type Item = ConcreteNode; type Item = ConcreteNode;
fn next(&mut self) -> Option<ConcreteNode> { fn next(&mut self) -> Option<ConcreteNode> {
@ -1366,7 +1366,7 @@ pub struct ServoThreadSafeLayoutElement<'le> {
pseudo: PseudoElementType, pseudo: PseudoElementType,
} }
impl<'le> ThreadSafeLayoutElement for ServoThreadSafeLayoutElement<'le> { impl<'le> ThreadSafeLayoutElement<'le> for ServoThreadSafeLayoutElement<'le> {
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'le>; type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'le>;
type ConcreteElement = ServoLayoutElement<'le>; type ConcreteElement = ServoLayoutElement<'le>;

View file

@ -1039,7 +1039,7 @@ impl LayoutThread {
self.stylist.set_quirks_mode(quirks_mode); 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 result = node.mutate_layout_data()?.flow_construction_result.get();
let mut flow = match result { let mut flow = match result {

View file

@ -315,7 +315,7 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
} }
} }
impl<'ln> LayoutNode for ServoLayoutNode<'ln> { impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> {
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'ln>; type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'ln>;
fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode { fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode {
@ -349,25 +349,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> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
unsafe { self.get_jsmanaged().get_style_and_layout_data() } 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> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
self.as_node().get_style_and_layout_data() 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> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
self.node.get_style_and_layout_data() 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> { fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
self.element.as_node().get_style_and_layout_data() self.element.as_node().get_style_and_layout_data()
} }
@ -1056,7 +1056,7 @@ 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> { unsafe fn dangerous_first_child(&self) -> Option<Self> {
self.get_jsmanaged() self.get_jsmanaged()
.first_child_ref() .first_child_ref()
@ -1106,7 +1106,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 ConcreteNode = ServoLayoutNode<'ln>;
type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'ln>; type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'ln>;
type ConcreteElement = ServoLayoutElement<'ln>; type ConcreteElement = ServoLayoutElement<'ln>;
@ -1262,14 +1262,14 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
} }
} }
pub struct ThreadSafeLayoutNodeChildrenIterator<ConcreteNode: ThreadSafeLayoutNode> { pub struct ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> {
current_node: Option<ConcreteNode>, current_node: Option<ConcreteNode>,
parent_node: ConcreteNode, parent_node: ConcreteNode,
} }
impl<ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> impl<'dom, ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<ConcreteNode>
where where
ConcreteNode: DangerousThreadSafeLayoutNode, ConcreteNode: DangerousThreadSafeLayoutNode<'dom>,
{ {
pub fn new(parent: ConcreteNode) -> Self { pub fn new(parent: ConcreteNode) -> Self {
let first_child: Option<ConcreteNode> = match parent.get_pseudo_element_type() { let first_child: Option<ConcreteNode> = match parent.get_pseudo_element_type() {
@ -1289,9 +1289,9 @@ where
} }
} }
impl<ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNode> impl<'dom, ConcreteNode> Iterator for ThreadSafeLayoutNodeChildrenIterator<ConcreteNode>
where where
ConcreteNode: DangerousThreadSafeLayoutNode, ConcreteNode: DangerousThreadSafeLayoutNode<'dom>,
{ {
type Item = ConcreteNode; type Item = ConcreteNode;
fn next(&mut self) -> Option<ConcreteNode> { fn next(&mut self) -> Option<ConcreteNode> {
@ -1373,7 +1373,7 @@ pub struct ServoThreadSafeLayoutElement<'le> {
pseudo: PseudoElementType, pseudo: PseudoElementType,
} }
impl<'le> ThreadSafeLayoutElement for ServoThreadSafeLayoutElement<'le> { impl<'le> ThreadSafeLayoutElement<'le> for ServoThreadSafeLayoutElement<'le> {
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'le>; type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'le>;
type ConcreteElement = ServoLayoutElement<'le>; type ConcreteElement = ServoLayoutElement<'le>;

View file

@ -78,14 +78,14 @@ impl PseudoElementType {
} }
/// Trait to abstract access to layout data across various data structures. /// 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>; 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 /// 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`. /// only ever see these and must never see instances of `LayoutDom`.
pub trait LayoutNode: Debug + GetLayoutData + TNode { pub trait LayoutNode<'dom>: Debug + GetLayoutData<'dom> + TNode {
type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode; type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'dom>;
fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode; fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode;
/// Returns the type ID of this node. /// Returns the type ID of this node.
@ -109,16 +109,13 @@ pub trait LayoutNode: Debug + GetLayoutData + TNode {
fn is_connected(&self) -> bool; fn is_connected(&self) -> bool;
} }
pub struct ReverseChildrenIterator<ConcreteNode> pub struct ReverseChildrenIterator<ConcreteNode> {
where
ConcreteNode: LayoutNode,
{
current: Option<ConcreteNode>, current: Option<ConcreteNode>,
} }
impl<ConcreteNode> Iterator for ReverseChildrenIterator<ConcreteNode> impl<'dom, ConcreteNode> Iterator for ReverseChildrenIterator<ConcreteNode>
where where
ConcreteNode: LayoutNode, ConcreteNode: LayoutNode<'dom>,
{ {
type Item = ConcreteNode; type Item = ConcreteNode;
fn next(&mut self) -> Option<ConcreteNode> { fn next(&mut self) -> Option<ConcreteNode> {
@ -128,16 +125,13 @@ where
} }
} }
pub struct TreeIterator<ConcreteNode> pub struct TreeIterator<ConcreteNode> {
where
ConcreteNode: LayoutNode,
{
stack: Vec<ConcreteNode>, stack: Vec<ConcreteNode>,
} }
impl<ConcreteNode> TreeIterator<ConcreteNode> impl<'dom, ConcreteNode> TreeIterator<ConcreteNode>
where where
ConcreteNode: LayoutNode, ConcreteNode: LayoutNode<'dom>,
{ {
fn new(root: ConcreteNode) -> TreeIterator<ConcreteNode> { fn new(root: ConcreteNode) -> TreeIterator<ConcreteNode> {
let mut stack = vec![]; let mut stack = vec![];
@ -150,9 +144,9 @@ where
} }
} }
impl<ConcreteNode> Iterator for TreeIterator<ConcreteNode> impl<'dom, ConcreteNode> Iterator for TreeIterator<ConcreteNode>
where where
ConcreteNode: LayoutNode, ConcreteNode: LayoutNode<'dom>,
{ {
type Item = ConcreteNode; type Item = ConcreteNode;
fn next(&mut self) -> Option<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 /// 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. /// node does not allow any parents or siblings of nodes to be accessed, to avoid races.
pub trait ThreadSafeLayoutNode: pub trait ThreadSafeLayoutNode<'dom>:
Clone + Copy + Debug + GetLayoutData + NodeInfo + PartialEq + Sized Clone + Copy + Debug + GetLayoutData<'dom> + NodeInfo + PartialEq + Sized
{ {
type ConcreteNode: LayoutNode<ConcreteThreadSafeLayoutNode = Self>; type ConcreteNode: LayoutNode<'dom, ConcreteThreadSafeLayoutNode = Self>;
type ConcreteElement: TElement; type ConcreteElement: TElement;
type ConcreteThreadSafeLayoutElement: ThreadSafeLayoutElement<ConcreteThreadSafeLayoutNode = Self> type ConcreteThreadSafeLayoutElement: ThreadSafeLayoutElement<'dom, ConcreteThreadSafeLayoutNode = Self>
+ ::selectors::Element<Impl = SelectorImpl>; + ::selectors::Element<Impl = SelectorImpl>;
type ChildrenIterator: Iterator<Item = Self> + Sized; 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. // 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! // It can be used to violate thread-safety, so don't use it elsewhere in layout!
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub trait DangerousThreadSafeLayoutNode: ThreadSafeLayoutNode { pub trait DangerousThreadSafeLayoutNode<'dom>: ThreadSafeLayoutNode<'dom> {
unsafe fn dangerous_first_child(&self) -> Option<Self>; unsafe fn dangerous_first_child(&self) -> Option<Self>;
unsafe fn dangerous_next_sibling(&self) -> Option<Self>; unsafe fn dangerous_next_sibling(&self) -> Option<Self>;
} }
pub trait ThreadSafeLayoutElement: pub trait ThreadSafeLayoutElement<'dom>:
Clone + Copy + Sized + Debug + ::selectors::Element<Impl = SelectorImpl> + GetLayoutData 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 /// This type alias is just a work-around to avoid writing
/// ///