diff --git a/components/style/animation.rs b/components/style/animation.rs index 6eae69e8183..0a5a9921d2e 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -461,6 +461,7 @@ fn compute_style_for_animation_step(context: &SharedStyleContext, let computed = properties::apply_declarations(&context.stylist.device, /* is_root = */ false, + /* pseudo = */ None, iter, previous_style, previous_style, diff --git a/components/style/matching.rs b/components/style/matching.rs index 31641711e36..72b98a9d154 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -408,7 +408,8 @@ trait PrivateMatchMethods: TElement { font_metrics_provider: &FontMetricsProvider, rule_node: &StrongRuleNode, primary_style: &ComputedStyle, - inherit_mode: InheritMode) + inherit_mode: InheritMode, + pseudo: Option<&PseudoElement>) -> Arc { let mut cascade_info = CascadeInfo::new(); let mut cascade_flags = CascadeFlags::empty(); @@ -473,6 +474,7 @@ trait PrivateMatchMethods: TElement { let values = Arc::new(cascade(&shared_context.stylist.device, rule_node, + pseudo, &shared_context.guards, style_to_inherit_from, layout_parent_style, @@ -488,6 +490,7 @@ trait PrivateMatchMethods: TElement { fn cascade_internal(&self, context: &StyleContext, primary_style: &ComputedStyle, + pseudo: Option<&PseudoElement>, eager_pseudo_style: Option<&ComputedStyle>) -> Arc { // Grab the rule node. @@ -502,7 +505,8 @@ trait PrivateMatchMethods: TElement { &context.thread_local.font_metrics_provider, rule_node, primary_style, - inherit_mode) + inherit_mode, + pseudo) } /// Computes values and damage for the primary or pseudo style of an element, @@ -554,6 +558,7 @@ trait PrivateMatchMethods: TElement { } else { self.cascade_internal(context, primary_style, + None, None) } } @@ -562,6 +567,7 @@ trait PrivateMatchMethods: TElement { // work. self.cascade_internal(context, primary_style, + pseudo, pseudo_style.as_ref().map(|s| &**s)) } }; @@ -603,7 +609,8 @@ trait PrivateMatchMethods: TElement { #[cfg(feature = "gecko")] fn get_after_change_style(&self, context: &mut StyleContext, - primary_style: &ComputedStyle) + primary_style: &ComputedStyle, + pseudo: Option<&PseudoElement>) -> Option> { let rule_node = &primary_style.rules; let without_transition_rules = @@ -618,7 +625,8 @@ trait PrivateMatchMethods: TElement { &context.thread_local.font_metrics_provider, &without_transition_rules, primary_style, - InheritMode::FromParentElement)) + InheritMode::FromParentElement, + pseudo)) } #[cfg(feature = "gecko")] @@ -663,7 +671,7 @@ trait PrivateMatchMethods: TElement { let before_change_style = if self.might_need_transitions_update(old_values.as_ref().map(|s| &**s), new_values) { let after_change_style = if self.has_css_transitions() { - self.get_after_change_style(context, primary_style) + self.get_after_change_style(context, primary_style, None) } else { None }; @@ -1424,6 +1432,7 @@ pub trait MatchMethods : TElement { shared_context: &SharedStyleContext, font_metrics_provider: &FontMetricsProvider, primary_style: &ComputedStyle, + pseudo: Option<&PseudoElement>, pseudo_style: Option<&ComputedStyle>) -> Arc { let relevant_style = pseudo_style.unwrap_or(primary_style); @@ -1440,7 +1449,8 @@ pub trait MatchMethods : TElement { font_metrics_provider, &without_animation_rules, primary_style, - InheritMode::FromParentElement) + InheritMode::FromParentElement, + pseudo) } } diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 57385c98217..bbd2f51964d 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -1257,7 +1257,7 @@ ${helpers.single_keyword("ruby-position", "over under", // https://drafts.csswg.org/css-writing-modes-3/ ${helpers.single_keyword("text-combine-upright", "none all", - products="gecko", animation_value_type="none", + products="gecko", animation_value_type="none", need_clone=True, spec="https://drafts.csswg.org/css-writing-modes-3/#text-combine-upright")} // SVG 1.1: Section 11 - Painting: Filling, Stroking and Marker Symbols diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index fa6ed21a33b..60da6d89704 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -29,6 +29,7 @@ use logical_geometry::WritingMode; use media_queries::Device; use parser::{LengthParsingMode, Parse, ParserContext}; use properties::animated_properties::TransitionProperty; +use selector_parser::PseudoElement; #[cfg(feature = "servo")] use servo_config::prefs::PREFS; use shared_lock::StylesheetGuards; use style_traits::ToCss; @@ -2108,6 +2109,7 @@ bitflags! { /// pub fn cascade(device: &Device, rule_node: &StrongRuleNode, + pseudo: Option<<&PseudoElement>, guards: &StylesheetGuards, parent_style: Option<<&ComputedValues>, layout_parent_style: Option<<&ComputedValues>, @@ -2153,6 +2155,7 @@ pub fn cascade(device: &Device, }; apply_declarations(device, is_root_element, + pseudo, iter_declarations, inherited_style, layout_parent_style, @@ -2167,6 +2170,7 @@ pub fn cascade(device: &Device, #[allow(unused_mut)] // conditionally compiled code for "position" pub fn apply_declarations<'a, F, I>(device: &Device, is_root_element: bool, + pseudo: Option<<&PseudoElement>, iter_declarations: F, inherited_style: &ComputedValues, layout_parent_style: &ComputedValues, @@ -2373,7 +2377,7 @@ pub fn apply_declarations<'a, F, I>(device: &Device, let mut style = context.style; - StyleAdjuster::new(&mut style, is_root_element) + StyleAdjuster::new(&mut style, is_root_element, pseudo) .adjust(context.layout_parent_style, flags.contains(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP)); diff --git a/components/style/style_adjuster.rs b/components/style/style_adjuster.rs index 1cc2fa7470f..6cd90d11ed3 100644 --- a/components/style/style_adjuster.rs +++ b/components/style/style_adjuster.rs @@ -11,20 +11,23 @@ use properties::longhands::display::computed_value::T as display; use properties::longhands::float::computed_value::T as float; use properties::longhands::overflow_x::computed_value::T as overflow; use properties::longhands::position::computed_value::T as position; - +use selector_parser::PseudoElement; /// An unsized struct that implements all the adjustment methods. +#[allow(dead_code)] // `pseudo` field is currently unused by Servo pub struct StyleAdjuster<'a> { style: &'a mut ComputedValues, is_root_element: bool, + pseudo: Option<&'a PseudoElement>, } impl<'a> StyleAdjuster<'a> { /// Trivially constructs a new StyleAdjuster. - pub fn new(style: &'a mut ComputedValues, is_root_element: bool) -> Self { + pub fn new(style: &'a mut ComputedValues, is_root_element: bool, pseudo: Option<&'a PseudoElement>) -> Self { StyleAdjuster { style: style, is_root_element: is_root_element, + pseudo: pseudo, } } @@ -85,6 +88,26 @@ impl<'a> StyleAdjuster<'a> { } } + /// Change writing mode of text frame for text-combine-upright. + /// It is safe to look at the parent's style because we are looking at + /// inherited properties, and ::-moz-text never matches any rules. + #[cfg(feature = "gecko")] + fn adjust_for_text_combine_upright(&mut self, + layout_parent_style: &ComputedValues) { + if let Some(p) = self.pseudo { + if *p.as_atom() == atom!(":-moz-text") { + use computed_values::text_combine_upright::T as text_combine_upright; + use computed_values::writing_mode::T as writing_mode; + let parent_writing_mode = layout_parent_style.get_inheritedbox().clone_writing_mode(); + let parent_text_combine_upright = layout_parent_style.get_inheritedtext().clone_text_combine_upright(); + if parent_writing_mode != writing_mode::horizontal_tb && + parent_text_combine_upright == text_combine_upright::all { + self.style.mutate_inheritedbox().set_writing_mode(writing_mode::horizontal_tb); + } + } + } + } + /// https://drafts.csswg.org/css-writing-modes-3/#block-flow: /// /// If a box has a different writing-mode value than its containing @@ -223,10 +246,14 @@ impl<'a> StyleAdjuster<'a> { } } - /// Adjusts the style to account for display fixups. + /// Adjusts the style to account for various fixups that don't fit naturally into the cascade. pub fn adjust(mut self, layout_parent_style: &ComputedValues, skip_root_and_element_display_fixup: bool) { + #[cfg(feature = "gecko")] + { + self.adjust_for_text_combine_upright(layout_parent_style); + } self.adjust_for_top_layer(); self.blockify_if_necessary(layout_parent_style, skip_root_and_element_display_fixup); diff --git a/components/style/stylist.rs b/components/style/stylist.rs index bf008ba7574..2ce855b1121 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -411,6 +411,7 @@ impl Stylist { let computed = properties::cascade(&self.device, &rule_node, + Some(pseudo), guards, parent.map(|p| &**p), parent.map(|p| &**p), @@ -530,6 +531,7 @@ impl Stylist { let computed = properties::cascade(&self.device, &rule_node, + Some(pseudo), guards, Some(&**parent), Some(&**parent), @@ -874,6 +876,7 @@ impl Stylist { let metrics = get_metrics_provider_for_product(); Arc::new(properties::cascade(&self.device, &rule_node, + None, guards, Some(parent_style), Some(parent_style), diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 16e19ad7821..492b19eb9cc 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -466,7 +466,7 @@ pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawSe }; let provider = get_metrics_provider_for_product(); - element.get_base_style(shared_context, &provider, &styles.primary, pseudo_style) + element.get_base_style(shared_context, &provider, &styles.primary, pseudo.as_ref(), pseudo_style) .into_strong() }