diff --git a/components/style/gecko/generated/pseudo_element_definition.rs b/components/style/gecko/generated/pseudo_element_definition.rs index 46da69d1e9b..485d4a023f0 100644 --- a/components/style/gecko/generated/pseudo_element_definition.rs +++ b/components/style/gecko/generated/pseudo_element_definition.rs @@ -362,7 +362,7 @@ impl PseudoElement { /// Whether this pseudo-element is an anonymous box. #[inline] - fn is_anon_box(&self) -> bool { + pub fn is_anon_box(&self) -> bool { match *self { PseudoElement::MozText => true, PseudoElement::OofPlaceholder => true, diff --git a/components/style/gecko/pseudo_element_definition.mako.rs b/components/style/gecko/pseudo_element_definition.mako.rs index e4a5025314b..fd11fd6abb4 100644 --- a/components/style/gecko/pseudo_element_definition.mako.rs +++ b/components/style/gecko/pseudo_element_definition.mako.rs @@ -57,7 +57,7 @@ impl PseudoElement { /// Whether this pseudo-element is an anonymous box. #[inline] - fn is_anon_box(&self) -> bool { + pub fn is_anon_box(&self) -> bool { match *self { % for pseudo in PSEUDOS: % if pseudo.is_anon_box(): diff --git a/components/style/properties/computed_value_flags.rs b/components/style/properties/computed_value_flags.rs index 3363fd76869..ef903bf775f 100644 --- a/components/style/properties/computed_value_flags.rs +++ b/components/style/properties/computed_value_flags.rs @@ -37,5 +37,12 @@ bitflags! { /// A flag used to mark styles under a relevant link that is also /// visited. const IS_RELEVANT_LINK_VISITED = 1 << 3, + + /// A flag used to mark styles which are a pseudo-element or under one. + const IS_IN_PSEUDO_ELEMENT_SUBTREE = 1 << 4, + + /// A flag used to mark styles which are in a display: none subtree, or + /// under one. + const IS_IN_DISPLAY_NONE_SUBTREE = 1 << 5, } } diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 2a5696628ed..93e653b0813 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2497,14 +2497,15 @@ pub struct StyleBuilder<'a> { /// a subtree. parent_style: Option<<&'a ComputedValues>, - /// The pseudo-element this style will represent. - pseudo: Option<<&'a PseudoElement>, - /// The rule node representing the ordered list of rules matched for this /// node. rules: Option, custom_properties: Option>, + + /// The pseudo-element this style will represent. + pseudo: Option<<&'a PseudoElement>, + /// The writing mode flags. /// /// TODO(emilio): Make private. @@ -2701,6 +2702,11 @@ impl<'a> StyleBuilder<'a> { self.visited_style.is_some() } + /// Returns whether we're a pseudo-elements style. + pub fn is_pseudo_element(&self) -> bool { + self.pseudo.map_or(false, |p| !p.is_anon_box()) + } + /// Returns the style we're getting reset properties from. pub fn default_style(&self) -> &'a ComputedValues { self.reset_style diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index 95ef6b0169f..12060f3e738 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -145,6 +145,11 @@ impl PseudoElement { self.cascade_type() == PseudoElementCascadeType::Lazy } + /// Whether this pseudo-element is for an anonymous box. + pub fn is_anon_box(&self) -> bool { + self.is_precomputed() + } + /// Whether this pseudo-element is precomputed. #[inline] pub fn is_precomputed(&self) -> bool { diff --git a/components/style/style_adjuster.rs b/components/style/style_adjuster.rs index 03b15916b23..1c93e6bae58 100644 --- a/components/style/style_adjuster.rs +++ b/components/style/style_adjuster.rs @@ -85,6 +85,22 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { } } + /// Compute a few common flags for both text and element's style. + pub fn set_bits(&mut self) { + use properties::computed_value_flags::IS_IN_DISPLAY_NONE_SUBTREE; + use properties::computed_value_flags::IS_IN_PSEUDO_ELEMENT_SUBTREE; + + if self.style.inherited_flags().contains(IS_IN_DISPLAY_NONE_SUBTREE) || + self.style.get_box().clone_display() == display::none { + self.style.flags.insert(IS_IN_DISPLAY_NONE_SUBTREE); + } + + if self.style.inherited_flags().contains(IS_IN_PSEUDO_ELEMENT_SUBTREE) || + self.style.is_pseudo_element() { + self.style.flags.insert(IS_IN_PSEUDO_ELEMENT_SUBTREE); + } + } + /// Adjust the style for text style. /// /// The adjustments here are a subset of the adjustments generally, because @@ -94,6 +110,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { #[cfg(feature = "gecko")] pub fn adjust_for_text(&mut self) { self.adjust_for_text_combine_upright(); + self.set_bits(); } /// Change writing mode of the text frame for text-combine-upright. @@ -522,5 +539,6 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { { self.adjust_for_ruby(layout_parent_style, flags); } + self.set_bits(); } } diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 779396574aa..c36631be287 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -1766,6 +1766,7 @@ pub extern "C" fn Servo_ComputedValues_Inherit( #[no_mangle] pub extern "C" fn Servo_ComputedValues_GetStyleBits(values: ServoStyleContextBorrowed) -> u64 { use style::properties::computed_value_flags::*; + // FIXME(emilio): We could do this more efficiently I'm quite sure. let flags = values.flags; let mut result = 0; if flags.contains(IS_RELEVANT_LINK_VISITED) { @@ -1780,6 +1781,12 @@ pub extern "C" fn Servo_ComputedValues_GetStyleBits(values: ServoStyleContextBor if flags.contains(IS_TEXT_COMBINED) { result |= structs::NS_STYLE_IS_TEXT_COMBINED as u64; } + if flags.contains(IS_IN_PSEUDO_ELEMENT_SUBTREE) { + result |= structs::NS_STYLE_HAS_PSEUDO_ELEMENT_DATA as u64; + } + if flags.contains(IS_IN_DISPLAY_NONE_SUBTREE) { + result |= structs::NS_STYLE_IN_DISPLAY_NONE_SUBTREE as u64; + } result }