diff --git a/servo/components/layout/traversal.rs b/servo/components/layout/traversal.rs index 692d956f0007..bd07e1f72bbc 100644 --- a/servo/components/layout/traversal.rs +++ b/servo/components/layout/traversal.rs @@ -65,7 +65,14 @@ impl<'lc, 'ln> DomTraversalContext> for RecalcStyleAndConst } } - fn process_preorder(&self, node: ServoLayoutNode<'ln>) { recalc_style_at(&self.context, self.root, node); } + fn process_preorder(&self, node: ServoLayoutNode<'ln>) { + // FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML + // parser. + node.initialize_data(); + + recalc_style_at(&self.context, self.root, node); + } + fn process_postorder(&self, node: ServoLayoutNode<'ln>) { construct_flows_at(&self.context, self.root, node); } } diff --git a/servo/components/layout/wrapper.rs b/servo/components/layout/wrapper.rs index 303c9f76943d..3c18e909baef 100644 --- a/servo/components/layout/wrapper.rs +++ b/servo/components/layout/wrapper.rs @@ -120,6 +120,19 @@ impl<'ln> ServoLayoutNode<'ln> { chain: self.chain, } } + + pub fn initialize_data(self) { + if unsafe { self.borrow_data_unchecked() }.is_none() { + let ptr: NonOpaqueStyleAndLayoutData = + Box::into_raw(box RefCell::new(PrivateLayoutData::new())); + let opaque = OpaqueStyleAndLayoutData { + ptr: unsafe { NonZero::new(ptr as *mut ()) } + }; + unsafe { + self.node.init_style_and_layout_data(opaque); + } + } + } } impl<'ln> TNode for ServoLayoutNode<'ln> { @@ -158,20 +171,6 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { OpaqueNodeMethods::from_jsmanaged(unsafe { self.get_jsmanaged() }) } - fn initialize_data(self) { - let has_data = unsafe { self.borrow_data_unchecked().is_some() }; - if !has_data { - let ptr: NonOpaqueStyleAndLayoutData = - Box::into_raw(box RefCell::new(PrivateLayoutData::new())); - let opaque = OpaqueStyleAndLayoutData { - ptr: unsafe { NonZero::new(ptr as *mut ()) } - }; - unsafe { - self.node.init_style_and_layout_data(opaque); - } - } - } - fn layout_parent_node(self, reflow_root: OpaqueNode) -> Option> { if self.opaque() == reflow_root { None diff --git a/servo/components/style/dom.rs b/servo/components/style/dom.rs index badd4f310658..7d10b3949899 100644 --- a/servo/components/style/dom.rs +++ b/servo/components/style/dom.rs @@ -86,12 +86,6 @@ pub trait TNode : Sized + Copy + Clone { /// Converts self into an `OpaqueNode`. fn opaque(&self) -> OpaqueNode; - /// Initializes style and layout data for the node. No-op if the data is already - /// initialized. - /// - /// FIXME(pcwalton): Do this as part of fragment building instead of in a traversal. - fn initialize_data(self); - /// While doing a reflow, the node at the root has no parent, as far as we're /// concerned. This method returns `None` at the reflow root. fn layout_parent_node(self, reflow_root: OpaqueNode) -> Option; diff --git a/servo/components/style/traversal.rs b/servo/components/style/traversal.rs index 386af02e5ef7..1afdcbb34c72 100644 --- a/servo/components/style/traversal.rs +++ b/servo/components/style/traversal.rs @@ -125,12 +125,6 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C, where N: TNode, C: StyleContext<'a, ::Impl>, ::Impl: SelectorImplExt + 'a { - // Initialize layout data. - // - // FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML - // parser. - node.initialize_data(); - // Get the parent node. let parent_opt = match node.parent_node() { Some(parent) if parent.is_element() => Some(parent), diff --git a/servo/ports/geckolib/traversal.rs b/servo/ports/geckolib/traversal.rs index 4e10d8c8fc85..f400377aeca9 100644 --- a/servo/ports/geckolib/traversal.rs +++ b/servo/ports/geckolib/traversal.rs @@ -80,7 +80,14 @@ impl<'lc, 'ln> DomTraversalContext> for RecalcStyleOnly<'lc> { } } - fn process_preorder(&self, node: GeckoNode<'ln>) { recalc_style_at(&self.context, self.root, node); } + fn process_preorder(&self, node: GeckoNode<'ln>) { + // FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML + // parser. + node.initialize_data(); + + recalc_style_at(&self.context, self.root, node); + } + fn process_postorder(&self, _: GeckoNode<'ln>) {} } diff --git a/servo/ports/geckolib/wrapper.rs b/servo/ports/geckolib/wrapper.rs index b36e8fd74634..7a4125717c5e 100644 --- a/servo/ports/geckolib/wrapper.rs +++ b/servo/ports/geckolib/wrapper.rs @@ -81,6 +81,15 @@ impl<'ln> GeckoNode<'ln> { Gecko_GetNodeData(self.node) as NonOpaqueStyleData } } + + pub fn initialize_data(self) { + unsafe { + if self.get_node_data().is_null() { + let ptr: NonOpaqueStyleData = Box::into_raw(box RefCell::new(PrivateStyleData::new())); + Gecko_SetNodeData(self.node, ptr as *mut ServoNodeData); + } + } + } } #[derive(Clone, Copy)] @@ -132,15 +141,6 @@ impl<'ln> TNode for GeckoNode<'ln> { OpaqueNode(ptr) } - fn initialize_data(self) { - unsafe { - if self.get_node_data().is_null() { - let ptr: NonOpaqueStyleData = Box::into_raw(box RefCell::new(PrivateStyleData::new())); - Gecko_SetNodeData(self.node, ptr as *mut ServoNodeData); - } - } - } - fn layout_parent_node(self, reflow_root: OpaqueNode) -> Option> { if self.opaque() == reflow_root { None