diff options
author | Pu Xingyu <pu.stshine@gmail.com> | 2017-03-23 21:03:41 +0800 |
---|---|---|
committer | Pu Xingyu <pu.stshine@gmail.com> | 2017-04-01 14:05:11 +0800 |
commit | 951c0506909ac5e6e180a97329a47c41ab6c458b (patch) | |
tree | 6bc3fc93ab50814651eaf025bbe9f207058f6e7e /components/layout/construct.rs | |
parent | 1677d479f61351ad22149eb577de6713a16b9908 (diff) | |
download | servo-951c0506909ac5e6e180a97329a47c41ab6c458b.tar.gz servo-951c0506909ac5e6e180a97329a47c41ab6c458b.zip |
Use empty pseudo to cascade only inheritable properties for text
Since for nested inline elements non-inheritable properties are
properly stored in the inline context of an inline fragment, so get
rid of them on the style.
Diffstat (limited to 'components/layout/construct.rs')
-rw-r--r-- | components/layout/construct.rs | 98 |
1 files changed, 40 insertions, 58 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 7dd4da8ada4..089209551ac 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -51,7 +51,7 @@ use style::computed_values::content::ContentItem; use style::computed_values::position; use style::context::SharedStyleContext; use style::logical_geometry::Direction; -use style::properties::{self, ServoComputedValues}; +use style::properties::ServoComputedValues; use style::selector_parser::{PseudoElement, RestyleDamage}; use style::servo::restyle_damage::{BUBBLE_ISIZES, RECONSTRUCT_FLOW}; use style::values::Either; @@ -178,7 +178,7 @@ impl InlineBlockSplit { predecessors: mem::replace( fragment_accumulator, InlineFragmentsAccumulator::from_inline_node( - node, style_context)).to_intermediate_inline_fragments(), + node, style_context)).to_intermediate_inline_fragments(style_context), flow: flow, }; @@ -273,7 +273,8 @@ impl InlineFragmentsAccumulator { self.fragments.absolute_descendants.push_descendants(fragments.absolute_descendants); } - fn to_intermediate_inline_fragments(self) -> IntermediateInlineFragments { + fn to_intermediate_inline_fragments(self, context: &SharedStyleContext) + -> IntermediateInlineFragments { let InlineFragmentsAccumulator { mut fragments, enclosing_node, @@ -299,9 +300,9 @@ impl InlineFragmentsAccumulator { if let Some((start, end)) = bidi_control_chars { fragments.fragments.push_front( - control_chars_to_fragment(&enclosing_node, start, restyle_damage)); + control_chars_to_fragment(&enclosing_node, context, start, restyle_damage)); fragments.fragments.push_back( - control_chars_to_fragment(&enclosing_node, end, restyle_damage)); + control_chars_to_fragment(&enclosing_node, context, end, restyle_damage)); } } fragments @@ -340,7 +341,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> } /// Builds the fragment for the given block or subclass thereof. - fn build_fragment_for_block(&mut self, node: &ConcreteThreadSafeLayoutNode) -> Fragment { + fn build_fragment_for_block(&self, node: &ConcreteThreadSafeLayoutNode) -> Fragment { let specific_fragment_info = match node.type_id() { Some(LayoutNodeType::Element(LayoutElementType::HTMLIFrameElement)) => { SpecificFragmentInfo::Iframe(IframeFragmentInfo::new(node)) @@ -399,7 +400,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> absolute_descendants: &mut AbsoluteDescendants, legalizer: &mut Legalizer, node: &ConcreteThreadSafeLayoutNode) { - let mut fragments = fragment_accumulator.to_intermediate_inline_fragments(); + let mut fragments = fragment_accumulator.to_intermediate_inline_fragments(self.style_context()); if fragments.is_empty() { return }; @@ -546,14 +547,12 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> ConstructionResult::ConstructionItem(ConstructionItem::Whitespace( whitespace_node, whitespace_pseudo, - mut whitespace_style, + whitespace_style, whitespace_damage)) => { // Add whitespace results. They will be stripped out later on when // between block elements, and retained when between inline elements. let fragment_info = SpecificFragmentInfo::UnscannedText( box UnscannedTextFragmentInfo::new(" ".to_owned(), None)); - properties::modify_style_for_replaced_content(&mut whitespace_style); - properties::modify_style_for_text(&mut whitespace_style); let fragment = Fragment::from_opaque_node_and_style(whitespace_node, whitespace_pseudo, whitespace_style, @@ -644,7 +643,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> /// `<textarea>`. fn build_flow_for_block_like(&mut self, flow: FlowRef, node: &ConcreteThreadSafeLayoutNode) -> ConstructionResult { - let mut initial_fragments = IntermediateInlineFragments::new(); + let mut fragments = IntermediateInlineFragments::new(); let node_is_input_or_text_area = node.type_id() == Some(LayoutNodeType::Element(LayoutElementType::HTMLInputElement)) || node.type_id() == Some(LayoutNodeType::Element(LayoutElementType::HTMLTextAreaElement)); @@ -658,17 +657,18 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> } } - let mut style = node.style(self.style_context()); + let context = self.style_context(); + let mut style = node.style(context); + style = context.stylist.style_for_anonymous( + &context.guards, &PseudoElement::ServoText, &style); if node_is_input_or_text_area { - let context = self.style_context(); - style = context.stylist.style_for_anonymous_box( + style = context.stylist.style_for_anonymous( &context.guards, &PseudoElement::ServoInputText, &style) } - self.create_fragments_for_node_text_content(&mut initial_fragments, node, &style) + self.create_fragments_for_node_text_content(&mut fragments, node, &style) } - - self.build_flow_for_block_starting_with_fragments(flow, node, initial_fragments) + self.build_flow_for_block_starting_with_fragments(flow, node, fragments) } /// Pushes fragments appropriate for the content of the given node onto the given list. @@ -682,13 +682,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> return } - let mut style = (*style).clone(); - match node.get_pseudo_element_type() { - PseudoElementType::Before(_) | - PseudoElementType::After(_) => {} - _ => properties::modify_style_for_text(&mut style) - } - + let style = (*style).clone(); let selected_style = node.selected_style(); match text_content { @@ -824,13 +818,11 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> ConstructionResult::ConstructionItem(ConstructionItem::Whitespace( whitespace_node, whitespace_pseudo, - mut whitespace_style, + whitespace_style, whitespace_damage)) => { // Instantiate the whitespace fragment. let fragment_info = SpecificFragmentInfo::UnscannedText( box UnscannedTextFragmentInfo::new(" ".to_owned(), None)); - properties::modify_style_for_replaced_content(&mut whitespace_style); - properties::modify_style_for_text(&mut whitespace_style); let fragment = Fragment::from_opaque_node_and_style(whitespace_node, whitespace_pseudo, @@ -852,12 +844,9 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> // An empty inline box needs at least one fragment to draw its background and borders. let info = SpecificFragmentInfo::UnscannedText( box UnscannedTextFragmentInfo::new(String::new(), None)); - let mut modified_style = node_style.clone(); - properties::modify_style_for_replaced_content(&mut modified_style); - properties::modify_style_for_text(&mut modified_style); let fragment = Fragment::from_opaque_node_and_style(node.opaque(), node.get_pseudo_element_type().strip(), - modified_style, + node_style.clone(), node.selected_style(), node.restyle_damage(), info); @@ -880,7 +869,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let construction_item = ConstructionItem::InlineFragments( InlineFragmentsConstructionResult { splits: opt_inline_block_splits, - fragments: fragment_accumulator.to_intermediate_inline_fragments(), + fragments: fragment_accumulator.to_intermediate_inline_fragments(self.style_context()), }); ConstructionResult::ConstructionItem(construction_item) } else { @@ -897,31 +886,27 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> self.set_flow_construction_result(&kid, ConstructionResult::None) } + let context = self.style_context(); + let style = node.style(context); // If this node is ignorable whitespace, bail out now. - if node.is_ignorable_whitespace(self.style_context()) { + if node.is_ignorable_whitespace(context) { return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace( node.opaque(), node.get_pseudo_element_type().strip(), - node.style(self.style_context()), + context.stylist.style_for_anonymous( + &context.guards, &PseudoElement::ServoText, &style), node.restyle_damage())) } - // Modify the style as necessary. (See the comment in - // `properties::modify_style_for_replaced_content()`.) - let mut style = node.style(self.style_context()); - match node.get_pseudo_element_type() { - PseudoElementType::Before(_) | - PseudoElementType::After(_) => {} - _ => properties::modify_style_for_replaced_content(&mut style) - } - // If this is generated content, then we need to initialize the accumulator with the // fragment corresponding to that content. Otherwise, just initialize with the ordinary // fragment that needs to be generated for this inline node. let mut fragments = IntermediateInlineFragments::new(); match (node.get_pseudo_element_type(), node.type_id()) { (_, Some(LayoutNodeType::Text)) => { - self.create_fragments_for_node_text_content(&mut fragments, node, &style) + let text_style = context.stylist.style_for_anonymous( + &context.guards, &PseudoElement::ServoText, &style); + self.create_fragments_for_node_text_content(&mut fragments, node, &text_style) } (PseudoElementType::Normal, _) => { fragments.fragments.push_back(self.build_fragment_for_block(node)); @@ -952,7 +937,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let context = self.style_context(); let style = node.style(context); - let style = context.stylist.style_for_anonymous_box( + let style = context.stylist.style_for_anonymous( &context.guards, &PseudoElement::ServoInlineBlockWrapper, &style); let fragment_info = SpecificFragmentInfo::InlineBlock(InlineBlockFragmentInfo::new( block_flow)); @@ -970,7 +955,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult { splits: LinkedList::new(), - fragments: fragment_accumulator.to_intermediate_inline_fragments(), + fragments: fragment_accumulator.to_intermediate_inline_fragments(context), }); ConstructionResult::ConstructionItem(construction_item) } @@ -990,7 +975,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> InlineAbsoluteHypotheticalFragmentInfo::new(block_flow)); let style_context = self.style_context(); let style = node.style(style_context); - let style = style_context.stylist.style_for_anonymous_box( + let style = style_context.stylist.style_for_anonymous( &style_context.guards, &PseudoElement::ServoInlineAbsolute, &style); let fragment = Fragment::from_opaque_node_and_style(node.opaque(), PseudoElementType::Normal, @@ -1006,7 +991,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult { splits: LinkedList::new(), - fragments: fragment_accumulator.to_intermediate_inline_fragments(), + fragments: fragment_accumulator.to_intermediate_inline_fragments(style_context), }); ConstructionResult::ConstructionItem(construction_item) } @@ -1103,7 +1088,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> { let context = self.style_context(); table_style = node.style(context); - wrapper_style = context.stylist.style_for_anonymous_box( + wrapper_style = context.stylist.style_for_anonymous( &context.guards, &PseudoElement::ServoTableWrapper, &table_style); } let wrapper_fragment = @@ -1370,7 +1355,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let mut set_has_newly_constructed_flow_flag = false; let result = { - let mut style = node.style(self.style_context()); + let style = node.style(self.style_context()); let damage = node.restyle_damage(); let mut data = node.mutate_layout_data().unwrap(); @@ -1441,9 +1426,6 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> return false } _ => { - if node.is_replaced_content() { - properties::modify_style_for_replaced_content(&mut style); - } fragment.repair_style(&style); set_has_newly_constructed_flow_flag = true; } @@ -1845,17 +1827,17 @@ fn bidi_control_chars(style: &Arc<ServoComputedValues>) -> Option<(&'static str, } fn control_chars_to_fragment(node: &InlineFragmentNodeInfo, + context: &SharedStyleContext, text: &str, restyle_damage: RestyleDamage) -> Fragment { let info = SpecificFragmentInfo::UnscannedText( box UnscannedTextFragmentInfo::new(String::from(text), None)); - let mut style = node.style.clone(); - properties::modify_style_for_replaced_content(&mut style); - properties::modify_style_for_text(&mut style); + let text_style = context.stylist.style_for_anonymous( + &context.guards, &PseudoElement::ServoText, &node.style); Fragment::from_opaque_node_and_style(node.address, node.pseudo, - style.clone(), + text_style, node.selected_style.clone(), restyle_damage, info) @@ -2085,7 +2067,7 @@ impl Legalizer { let reference_block = reference.as_block(); let mut new_style = reference_block.fragment.style.clone(); for pseudo in pseudos { - new_style = context.stylist.style_for_anonymous_box(&context.guards, pseudo, &new_style) + new_style = context.stylist.style_for_anonymous(&context.guards, pseudo, &new_style) } let fragment = reference_block.fragment .create_similar_anonymous_fragment(new_style, |