diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index cad48e36a64..1f715399d4a 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -825,6 +825,14 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { self.node.type_id() } + fn style_for_text_node(&self) -> Arc { + debug_assert!(self.is_text_node()); + let parent = self.node.parent_node().unwrap(); + let parent_data = parent.get_style_data().unwrap().borrow(); + let parent_style = &parent_data.current_styles().primary; + ComputedValues::style_for_child_text_node(parent_style) + } + fn debug_id(self) -> usize { self.node.debug_id() } diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs index 5ea15926f97..a4463070689 100644 --- a/components/script_layout_interface/wrapper_traits.rs +++ b/components/script_layout_interface/wrapper_traits.rs @@ -165,6 +165,16 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { /// `type_id` does. fn type_id_without_excluding_pseudo_elements(&self) -> LayoutNodeType; + /// Returns the style for a text node. This is computed on the fly from the + /// parent style to avoid traversing text nodes in the style system. + /// + /// Note that this does require accessing the parent, which this interface + /// technically forbids. But accessing the parent is only unsafe insofar as + /// it can be used to reach siblings and cousins. A simple immutable borrow + /// of the parent data is fine, since the bottom-up traversal will not process + /// the parent until all the children have been processed. + fn style_for_text_node(&self) -> Arc; + #[inline] fn is_element_or_elements_pseudo(&self) -> bool { match self.type_id_without_excluding_pseudo_elements() { @@ -187,7 +197,8 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { #[inline] fn get_before_pseudo(&self) -> Option { - if self.get_style_data() + if self.is_element() && + self.get_style_data() .unwrap() .borrow() .current_styles().pseudos @@ -200,7 +211,8 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { #[inline] fn get_after_pseudo(&self) -> Option { - if self.get_style_data() + if self.is_element() && + self.get_style_data() .unwrap() .borrow() .current_styles().pseudos @@ -248,8 +260,11 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { fn style(&self, context: &SharedStyleContext) -> Arc { match self.get_pseudo_element_type() { PseudoElementType::Normal => { - self.get_style_data().unwrap().borrow() - .current_styles().primary.clone() + match self.type_id().unwrap() { + LayoutNodeType::Text => self.style_for_text_node(), + LayoutNodeType::Element(_) => self.get_style_data().unwrap().borrow() + .current_styles().primary.clone(), + } }, other => { // Precompute non-eagerly-cascaded pseudo-element styles if not @@ -308,6 +323,10 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { /// element style is precomputed, not from general layout itself. #[inline] fn resolved_style(&self) -> Arc { + if self.is_text_node() { + return self.style_for_text_node(); + } + let data = self.get_style_data().unwrap().borrow(); match self.get_pseudo_element_type() { PseudoElementType::Normal @@ -319,6 +338,10 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { #[inline] fn selected_style(&self, _context: &SharedStyleContext) -> Arc { + if self.is_text_node() { + return self.style_for_text_node(); + } + let data = self.get_style_data().unwrap().borrow(); data.current_styles().pseudos .get(&PseudoElement::Selection)