Adjust display value for ::-moz-fieldset-content when parent is flex/grid. r?emilio draft
authorXidorn Quan <me@upsuper.org>
Thu, 13 Jul 2017 14:15:16 +1000
changeset 608692 db50aae4aa58c27c40e5db6535a828ace5164abd
parent 608691 11bccc339eb65a33b26da72979a7d09b2ed516b1
child 608693 f9f7fa5eca8685fa9c5c58b3c4e0babbb062dda3
push id68376
push userxquan@mozilla.com
push dateFri, 14 Jul 2017 02:09:01 +0000
reviewersemilio
milestone56.0a1
Adjust display value for ::-moz-fieldset-content when parent is flex/grid. r?emilio MozReview-Commit-ID: 927IwbTAK2c
servo/components/style/gecko/pseudo_element.rs
servo/components/style/properties/properties.mako.rs
servo/components/style/style_adjuster.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/gecko/pseudo_element.rs
+++ b/servo/components/style/gecko/pseudo_element.rs
@@ -78,16 +78,22 @@ impl PseudoElement {
     }
 
     /// Whether this pseudo-element is ::first-letter.
     #[inline]
     pub fn is_first_letter(&self) -> bool {
         *self == PseudoElement::FirstLetter
     }
 
+    /// Whether this pseudo-element is ::-moz-fieldset-content.
+    #[inline]
+    pub fn is_fieldset_content(&self) -> bool {
+        *self == PseudoElement::FieldsetContent
+    }
+
     /// Whether this pseudo-element is lazily-cascaded.
     #[inline]
     pub fn is_lazy(&self) -> bool {
         !self.is_eager() && !self.is_precomputed()
     }
 
     /// Whether this pseudo-element is web-exposed.
     pub fn exposed_in_non_ua_sheets(&self) -> bool {
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -2543,16 +2543,19 @@ bitflags! {
         /// This affects some style adjustments, like blockification, and means
         /// that it may affect global state, like the Device's root font-size.
         const IS_ROOT_ELEMENT = 0x08,
 
         /// Whether to convert display:contents into display:inline.  This
         /// is used by Gecko to prevent display:contents on generated
         /// content.
         const PROHIBIT_DISPLAY_CONTENTS = 0x10,
+
+        /// Whether we're styling the ::-moz-fieldset-content anonymous box.
+        const IS_FIELDSET_CONTENT = 0x20,
     }
 }
 
 /// Performs the CSS cascade, computing new styles for an element from its parent style.
 ///
 /// The arguments are:
 ///
 ///   * `device`: Used to get the initial viewport and other external state.
--- a/servo/components/style/style_adjuster.rs
+++ b/servo/components/style/style_adjuster.rs
@@ -284,16 +284,40 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
         if !flags.contains(PROHIBIT_DISPLAY_CONTENTS) ||
            self.style.get_box().clone_display() != display::contents {
             return;
         }
 
         self.style.mutate_box().set_display(display::inline);
     }
 
+    /// If a <fieldset> has grid/flex display type, we need to inherit
+    /// this type into its ::-moz-fieldset-content anonymous box.
+    #[cfg(feature = "gecko")]
+    fn adjust_for_fieldset_content(&mut self, layout_parent_style: &ComputedValues,
+                                   flags: CascadeFlags) {
+        use properties::IS_FIELDSET_CONTENT;
+        if !flags.contains(IS_FIELDSET_CONTENT) {
+            return;
+        }
+        debug_assert_eq!(self.style.get_box().clone_display(), display::block);
+        // TODO We actually wants style from parent rather than layout
+        // parent, so that this fixup doesn't happen incorrectly when
+        // when <fieldset> has "display: contents".
+        let parent_display = layout_parent_style.get_box().clone_display();
+        let new_display = match parent_display {
+            display::flex | display::inline_flex => Some(display::flex),
+            display::grid | display::inline_grid => Some(display::grid),
+            _ => None,
+        };
+        if let Some(new_display) = new_display {
+            self.style.mutate_box().set_display(new_display);
+        }
+    }
+
     /// -moz-center, -moz-left and -moz-right are used for HTML's alignment.
     ///
     /// This is covering the <div align="right"><table>...</table></div> case.
     ///
     /// In this case, we don't want to inherit the text alignment into the
     /// table.
     #[cfg(feature = "gecko")]
     fn adjust_for_table_text_align(&mut self) {
@@ -318,16 +342,17 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
     /// When comparing to Gecko, this is similar to the work done by
     /// `nsStyleContext::ApplyStyleFixups`.
     pub fn adjust(&mut self,
                   layout_parent_style: &ComputedValues,
                   flags: CascadeFlags) {
         #[cfg(feature = "gecko")]
         {
             self.adjust_for_prohibited_display_contents(flags);
+            self.adjust_for_fieldset_content(layout_parent_style, flags);
         }
         self.adjust_for_top_layer();
         self.blockify_if_necessary(layout_parent_style, flags);
         self.adjust_for_position();
         self.adjust_for_overflow();
         #[cfg(feature = "gecko")]
         {
             self.adjust_for_table_text_align();
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -87,17 +87,17 @@ use style::gecko_bindings::sugar::owners
 use style::gecko_bindings::sugar::refptr::RefPtr;
 use style::gecko_properties::{self, style_structs};
 use style::invalidation::element::restyle_hints::{self, RestyleHint};
 use style::media_queries::{MediaList, parse_media_query_list};
 use style::parallel;
 use style::parser::ParserContext;
 use style::properties::{CascadeFlags, ComputedValues, Importance, SourcePropertyDeclaration};
 use style::properties::{LonghandIdSet, PropertyDeclaration, PropertyDeclarationBlock, PropertyId, StyleBuilder};
-use style::properties::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
+use style::properties::{IS_FIELDSET_CONTENT, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP};
 use style::properties::animated_properties::{Animatable, AnimatableLonghand, AnimationValue};
 use style::properties::parse_one_declaration_into;
 use style::rule_tree::StyleSource;
 use style::selector_parser::PseudoElementCascadeType;
 use style::sequential;
 use style::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked};
 use style::string_cache::Atom;
 use style::style_adjuster::StyleAdjuster;
@@ -1514,16 +1514,19 @@ pub extern "C" fn Servo_ComputedValues_G
         .expect("Not an anon box pseudo?");
 
 
     let maybe_parent = ComputedValues::arc_from_borrowed(&parent_style_or_null);
     let mut cascade_flags = CascadeFlags::empty();
     if skip_display_fixup {
         cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP);
     }
+    if pseudo.is_fieldset_content() {
+        cascade_flags.insert(IS_FIELDSET_CONTENT);
+    }
     let metrics = get_metrics_provider_for_product();
     data.stylist.precomputed_values_for_pseudo(&guards, &pseudo, maybe_parent,
                                                cascade_flags, &metrics)
         .into_strong()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,