From 836e554c3046d578858d3f4d9687e5c2e2892db2 Mon Sep 17 00:00:00 2001 From: Pu Xingyu Date: Tue, 21 Mar 2017 01:39:54 +0800 Subject: [PATCH 1/4] Use Servo-specific pseudo element for InlineBlock fragment --- components/layout/construct.rs | 8 +++++--- components/style/properties/properties.mako.rs | 10 ---------- components/style/servo/selector_parser.rs | 11 ++++++++++- components/style/stylist.rs | 3 ++- resources/servo.css | 7 +++++++ 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 00cd46a079a..5533942e5a0 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -950,13 +950,15 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> _ => unreachable!() }; - let mut modified_style = node.style(self.style_context()); - properties::modify_style_for_outer_inline_block_fragment(&mut modified_style); + let context = self.style_context(); + let style = node.style(context); + let style = context.stylist.style_for_anonymous_box( + &context.guards, &PseudoElement::ServoInlineBlockWrapper, &style); let fragment_info = SpecificFragmentInfo::InlineBlock(InlineBlockFragmentInfo::new( block_flow)); let fragment = Fragment::from_opaque_node_and_style(node.opaque(), node.get_pseudo_element_type().strip(), - modified_style, + style, node.selected_style(), node.restyle_damage(), fragment_info); diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 9bb2b94749d..0dae0a7172d 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2544,16 +2544,6 @@ pub fn modify_border_style_for_inline_sides(style: &mut Arc, } } -/// Adjusts the `position` property as necessary for the outer fragment wrapper -/// of an inline-block. -#[cfg(feature = "servo")] -#[inline] -pub fn modify_style_for_outer_inline_block_fragment(style: &mut Arc) { - let mut style = Arc::make_mut(style); - let box_style = Arc::make_mut(&mut style.box_); - box_style.position = longhands::position::computed_value::T::static_ -} - /// Adjusts the `position` and `padding` properties as necessary to account for /// text. /// diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index c853ff9af12..311a15284aa 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -39,6 +39,7 @@ pub enum PseudoElement { ServoAnonymousTableRow, ServoAnonymousTableCell, ServoAnonymousBlock, + ServoInlineBlockWrapper, } impl ToCss for PseudoElement { @@ -57,6 +58,7 @@ impl ToCss for PseudoElement { ServoAnonymousTableRow => "::-servo-anonymous-table-row", ServoAnonymousTableCell => "::-servo-anonymous-table-cell", ServoAnonymousBlock => "::-servo-anonymous-block", + ServoInlineBlockWrapper => "::-servo-inline-block-wrapper", }) } } @@ -89,7 +91,8 @@ impl PseudoElement { PseudoElement::ServoAnonymousTable | PseudoElement::ServoAnonymousTableRow | PseudoElement::ServoAnonymousTableCell | - PseudoElement::ServoAnonymousBlock => PseudoElementCascadeType::Precomputed, + PseudoElement::ServoAnonymousBlock | + PseudoElement::ServoInlineBlockWrapper => PseudoElementCascadeType::Precomputed, } } } @@ -320,6 +323,12 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> { } ServoAnonymousBlock }, + "-servo-inline-block-wrapper" => { + if !self.in_user_agent_stylesheet() { + return Err(()) + } + ServoInlineBlockWrapper + }, _ => return Err(()) }; diff --git a/components/style/stylist.rs b/components/style/stylist.rs index f93d76a5879..6e2e8632f37 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -398,7 +398,8 @@ impl Stylist { PseudoElement::ServoAnonymousTableCell | PseudoElement::ServoAnonymousTableRow | PseudoElement::ServoAnonymousTableWrapper | - PseudoElement::ServoTableWrapper => true, + PseudoElement::ServoTableWrapper | + PseudoElement::ServoInlineBlockWrapper => true, PseudoElement::Before | PseudoElement::After | PseudoElement::Selection | diff --git a/resources/servo.css b/resources/servo.css index cc913977260..341a5ad077c 100644 --- a/resources/servo.css +++ b/resources/servo.css @@ -215,3 +215,10 @@ svg > * { height: auto; } +/* The outer fragment wrapper of an inline-block. */ +*|*::-servo-inline-block-wrapper { + position: static; + border: none; + padding: 0; + margin: 0; +} From 1677d479f61351ad22149eb577de6713a16b9908 Mon Sep 17 00:00:00 2001 From: Pu Xingyu Date: Tue, 21 Mar 2017 14:15:20 +0800 Subject: [PATCH 2/4] Use Servo-specific pseudo element for InlineAbsolute fragment --- components/layout/construct.rs | 5 +++-- components/style/properties/properties.mako.rs | 11 ----------- components/style/servo/selector_parser.rs | 13 ++++++++++++- components/style/stylist.rs | 3 ++- resources/servo.css | 8 ++++++++ 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 5533942e5a0..7dd4da8ada4 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -989,8 +989,9 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let fragment_info = SpecificFragmentInfo::InlineAbsoluteHypothetical( InlineAbsoluteHypotheticalFragmentInfo::new(block_flow)); let style_context = self.style_context(); - let mut style = node.style(style_context); - properties::modify_style_for_inline_absolute_hypothetical_fragment(&mut style); + let style = node.style(style_context); + let style = style_context.stylist.style_for_anonymous_box( + &style_context.guards, &PseudoElement::ServoInlineAbsolute, &style); let fragment = Fragment::from_opaque_node_and_style(node.opaque(), PseudoElementType::Normal, style, diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 0dae0a7172d..319fc9cecfa 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2582,17 +2582,6 @@ pub fn modify_style_for_text(style: &mut Arc) { } } -/// Adjusts the `clip` property so that an inline absolute hypothetical fragment -/// doesn't clip its children. -#[cfg(feature = "servo")] -pub fn modify_style_for_inline_absolute_hypothetical_fragment(style: &mut Arc) { - if !style.get_effects().clip.is_auto() { - let mut style = Arc::make_mut(style); - let effects_style = Arc::make_mut(&mut style.effects); - effects_style.clip = Either::auto() - } -} - #[macro_export] macro_rules! css_properties_accessors { ($macro_name: ident) => { diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index 311a15284aa..563e7b89c44 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -40,6 +40,7 @@ pub enum PseudoElement { ServoAnonymousTableCell, ServoAnonymousBlock, ServoInlineBlockWrapper, + ServoInlineAbsolute, } impl ToCss for PseudoElement { @@ -59,6 +60,7 @@ impl ToCss for PseudoElement { ServoAnonymousTableCell => "::-servo-anonymous-table-cell", ServoAnonymousBlock => "::-servo-anonymous-block", ServoInlineBlockWrapper => "::-servo-inline-block-wrapper", + ServoInlineAbsolute => "::-servo-inline-absolute", }) } } @@ -92,7 +94,8 @@ impl PseudoElement { PseudoElement::ServoAnonymousTableRow | PseudoElement::ServoAnonymousTableCell | PseudoElement::ServoAnonymousBlock | - PseudoElement::ServoInlineBlockWrapper => PseudoElementCascadeType::Precomputed, + PseudoElement::ServoInlineBlockWrapper | + PseudoElement::ServoInlineAbsolute => PseudoElementCascadeType::Precomputed, } } } @@ -329,6 +332,12 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> { } ServoInlineBlockWrapper }, + "-servo-input-absolute" => { + if !self.in_user_agent_stylesheet() { + return Err(()) + } + ServoInlineAbsolute + }, _ => return Err(()) }; @@ -368,6 +377,8 @@ impl SelectorImpl { fun(PseudoElement::ServoAnonymousTableRow); fun(PseudoElement::ServoAnonymousTableCell); fun(PseudoElement::ServoAnonymousBlock); + fun(PseudoElement::ServoInlineBlockWrapper); + fun(PseudoElement::ServoInlineAbsolute); } /// Returns the pseudo-class state flag for selector matching. diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 6e2e8632f37..e9533a7cb65 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -399,7 +399,8 @@ impl Stylist { PseudoElement::ServoAnonymousTableRow | PseudoElement::ServoAnonymousTableWrapper | PseudoElement::ServoTableWrapper | - PseudoElement::ServoInlineBlockWrapper => true, + PseudoElement::ServoInlineBlockWrapper | + PseudoElement::ServoInlineAbsolute => true, PseudoElement::Before | PseudoElement::After | PseudoElement::Selection | diff --git a/resources/servo.css b/resources/servo.css index 341a5ad077c..31e3c073e8e 100644 --- a/resources/servo.css +++ b/resources/servo.css @@ -222,3 +222,11 @@ svg > * { padding: 0; margin: 0; } + +/* The outer fragment wrapper of an inline absolute hypothetical fragment. */ +*|*::-servo-inline-absolute { + clip: auto; + border: none; + padding: 0; + margin: 0; +} From 951c0506909ac5e6e180a97329a47c41ab6c458b Mon Sep 17 00:00:00 2001 From: Pu Xingyu Date: Thu, 23 Mar 2017 21:03:41 +0800 Subject: [PATCH 3/4] 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. --- components/layout/construct.rs | 98 ++++++++----------- components/layout/fragment.rs | 49 +++------- components/script/layout_wrapper.rs | 11 +-- .../script_layout_interface/wrapper_traits.rs | 9 +- .../style/properties/properties.mako.rs | 81 --------------- components/style/servo/selector_parser.rs | 10 ++ components/style/stylist.rs | 11 ++- resources/servo.css | 6 ++ 8 files changed, 84 insertions(+), 191 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> /// `