Bug 1383868 part 2 - Use the new -moz-adjustment property to handle fieldset-content fixup in stylo. r?bz draft
authorXidorn Quan <me@upsuper.org>
Thu, 14 Sep 2017 19:59:27 +1000
changeset 664757 e10ed2219c8e6ee3b782a21b1f11cbf4069b32aa
parent 664756 c0f8cdb8160354d355560ec177ce5c55dbcc55dc
child 664758 35491cf5612702ecdde51a0a2751059942011eed
push id79792
push userxquan@mozilla.com
push dateThu, 14 Sep 2017 10:03:54 +0000
reviewersbz
bugs1383868
milestone57.0a1
Bug 1383868 part 2 - Use the new -moz-adjustment property to handle fieldset-content fixup in stylo. r?bz MozReview-Commit-ID: IxAOr8Ugwus
layout/style/nsCSSKeywordList.h
layout/style/nsCSSProps.cpp
layout/style/nsStyleConsts.h
layout/style/res/forms.css
servo/components/style/gecko/pseudo_element.rs
servo/components/style/properties/longhand/box.mako.rs
servo/components/style/properties/properties.mako.rs
servo/components/style/style_adjuster.rs
servo/ports/geckolib/glue.rs
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -263,16 +263,17 @@ CSS_KEY(expanded, expanded)
 CSS_KEY(extends, extends)
 CSS_KEY(extra-condensed, extra_condensed)
 CSS_KEY(extra-expanded, extra_expanded)
 CSS_KEY(ew-resize, ew_resize)
 CSS_KEY(fallback, fallback)
 CSS_KEY(fantasy, fantasy)
 CSS_KEY(farthest-side, farthest_side)
 CSS_KEY(farthest-corner, farthest_corner)
+CSS_KEY(fieldset-content, fieldset_content)
 CSS_KEY(fill, fill)
 CSS_KEY(filled, filled)
 CSS_KEY(fill-box, fill_box)
 CSS_KEY(first, first)
 CSS_KEY(fit-content, fit_content)
 CSS_KEY(fixed, fixed)
 CSS_KEY(flat, flat)
 CSS_KEY(flex, flex)
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -710,16 +710,17 @@ nsCSSProps::GetStringValue(nsCSSCounterD
     return sNullStr;
   }
 }
 
 /***************************************************************************/
 
 const KTableEntry nsCSSProps::kAdjustmentKTable[] = {
   { eCSSKeyword_none, StyleAdjustment::None },
+  { eCSSKeyword_fieldset_content, StyleAdjustment::FieldsetContent },
   { eCSSKeyword_UNKNOWN, -1 }
 };
 
 const KTableEntry nsCSSProps::kAnimationDirectionKTable[] = {
   { eCSSKeyword_normal, static_cast<uint32_t>(dom::PlaybackDirection::Normal) },
   { eCSSKeyword_reverse, static_cast<uint32_t>(dom::PlaybackDirection::Reverse) },
   { eCSSKeyword_alternate, static_cast<uint32_t>(dom::PlaybackDirection::Alternate) },
   { eCSSKeyword_alternate_reverse, static_cast<uint32_t>(dom::PlaybackDirection::Alternate_reverse) },
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -15,16 +15,18 @@
 // XXX fold this into nsStyleContext and group by nsStyleXXX struct
 
 namespace mozilla {
 
 // -moz-adjustment
 enum class StyleAdjustment : uint8_t {
   // No special adjustment applied.
   None,
+  // Apply adjustment for ::-moz-fieldset-content.
+  FieldsetContent,
 };
 
 // Basic shapes
 enum class StyleBasicShapeType : uint8_t {
   Polygon,
   Circle,
   Ellipse,
   Inset,
--- a/layout/style/res/forms.css
+++ b/layout/style/res/forms.css
@@ -7,16 +7,17 @@
  **/
 
 
 @namespace url(http://www.w3.org/1999/xhtml); /* set default namespace to HTML */
 @namespace xul url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
 
 *|*::-moz-fieldset-content {
   display: block; /* nsRuleNode::ComputeDisplayData overrules this in some cases */
+  -moz-adjustment: fieldset-content;
   unicode-bidi: inherit;
   text-overflow: inherit;
   overflow: inherit;
   overflow-clip-box: inherit;
   /* Need to inherit border-radius too, so when the fieldset has rounded
      borders we don't leak out the corners for hit-testing purposes. */
   border-radius: inherit;
   padding: inherit;
--- a/servo/components/style/gecko/pseudo_element.rs
+++ b/servo/components/style/gecko/pseudo_element.rs
@@ -100,22 +100,16 @@ impl PseudoElement {
     }
 
     /// Whether this pseudo-element is ::first-line.
     #[inline]
     pub fn is_first_line(&self) -> bool {
         *self == PseudoElement::FirstLine
     }
 
-    /// 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/longhand/box.mako.rs
+++ b/servo/components/style/properties/longhand/box.mako.rs
@@ -195,17 +195,17 @@
 </%helpers:longhand>
 
 ${helpers.single_keyword("-moz-top-layer", "none top",
                          gecko_constant_prefix="NS_STYLE_TOP_LAYER",
                          gecko_ffi_name="mTopLayer", need_clone=True,
                          products="gecko", animation_value_type="none", internal=True,
                          spec="Internal (not web-exposed)")}
 
-${helpers.single_keyword("-moz-adjustment", "none",
+${helpers.single_keyword("-moz-adjustment", "none fieldset-content",
                          gecko_enum_prefix="StyleAdjustment",
                          gecko_ffi_name="mAdjustment", need_clone=True,
                          products="gecko", animation_value_type="none", internal=True,
                          spec="Internal (not web-exposed)")}
 
 ${helpers.single_keyword("position", "static absolute relative fixed sticky",
                          animation_value_type="discrete",
                          flags="CREATES_STACKING_CONTEXT ABSPOS_CB",
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -2966,26 +2966,23 @@ bitflags! {
         /// that it may affect global state, like the Device's root font-size.
         const IS_ROOT_ELEMENT = 1 << 3,
 
         /// Whether to convert display:contents into display:inline.  This
         /// is used by Gecko to prevent display:contents on generated
         /// content.
         const PROHIBIT_DISPLAY_CONTENTS = 1 << 4,
 
-        /// Whether we're styling the ::-moz-fieldset-content anonymous box.
-        const IS_FIELDSET_CONTENT = 1 << 5,
-
         /// Whether we're computing the style of a link, either visited or
         /// unvisited.
-        const IS_LINK = 1 << 6,
+        const IS_LINK = 1 << 5,
 
         /// Whether we're computing the style of a link element that happens to
         /// be visited.
-        const IS_VISITED_LINK = 1 << 7,
+        const IS_VISITED_LINK = 1 << 6,
     }
 }
 
 /// 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
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! A struct to encapsulate all the style fixups and flags propagations
 //! a computed style needs in order for it to adhere to the CSS spec.
 
 use app_units::Au;
 use properties::{self, CascadeFlags, ComputedValues};
 use properties::{IS_ROOT_ELEMENT, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, StyleBuilder};
+use properties::longhands::_moz_adjustment::computed_value::T as adjustment;
 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;
 
 /// A struct that implements all the adjustment methods.
 ///
 /// NOTE(emilio): If new adjustments are introduced that depend on reset
@@ -338,21 +339,20 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
     ///
     /// NOTE(emilio): We don't need to handle the display change for this case
     /// in matching.rs because anonymous box restyling works separately to the
     /// normal cascading process.
     #[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;
+        match self.style.get_box().clone__moz_adjustment() {
+            adjustment::fieldset_content => {},
+            _ => return,
         }
         debug_assert_eq!(self.style.get_box().clone_display(), display::block);
         // TODO We actually want 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 |
@@ -556,17 +556,17 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
         &mut self,
         layout_parent_style: &ComputedValues,
         flags: CascadeFlags,
     ) {
         self.adjust_for_visited(flags);
         #[cfg(feature = "gecko")]
         {
             self.adjust_for_prohibited_display_contents(flags);
-            self.adjust_for_fieldset_content(layout_parent_style, flags);
+            self.adjust_for_fieldset_content(layout_parent_style);
         }
         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
@@ -104,17 +104,17 @@ use style::gecko_bindings::structs::nsre
 use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasFFI, HasArcFFI};
 use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
 use style::gecko_bindings::sugar::refptr::RefPtr;
 use style::gecko_properties::style_structs;
 use style::invalidation::element::restyle_hints;
 use style::media_queries::{Device, MediaList, parse_media_query_list};
 use style::parser::{ParserContext, self};
 use style::properties::{CascadeFlags, ComputedValues, Importance};
-use style::properties::{IS_FIELDSET_CONTENT, IS_LINK, IS_VISITED_LINK, LonghandIdSet};
+use style::properties::{IS_LINK, IS_VISITED_LINK, LonghandIdSet};
 use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyId, ShorthandId};
 use style::properties::{SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, SourcePropertyDeclaration, StyleBuilder};
 use style::properties::PROHIBIT_DISPLAY_CONTENTS;
 use style::properties::animated_properties::{AnimatableLonghand, AnimationValue};
 use style::properties::animated_properties::compare_property_priority;
 use style::properties::parse_one_declaration_into;
 use style::rule_tree::{CascadeLevel, StyleSource};
 use style::selector_parser::PseudoElementCascadeType;
@@ -1669,20 +1669,17 @@ pub extern "C" fn Servo_ComputedValues_G
     let global_style_data = &*GLOBAL_STYLE_DATA;
     let guard = global_style_data.shared_lock.read();
     let guards = StylesheetGuards::same(&guard);
     let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
     let atom = Atom::from(pseudo_tag);
     let pseudo = PseudoElement::from_anon_box_atom(&atom)
         .expect("Not an anon box pseudo?");
 
-    let mut cascade_flags = SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
-    if pseudo.is_fieldset_content() {
-        cascade_flags.insert(IS_FIELDSET_CONTENT);
-    }
+    let cascade_flags = SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
     let metrics = get_metrics_provider_for_product();
 
     // If the pseudo element is PageContent, we should append the precomputed
     // pseudo element declerations with specified page rules.
     let page_decls = match pseudo {
         PseudoElement::PageContent => {
             let mut declarations = vec![];
             let iter = data.extra_style_data.iter_origins_rev();
@@ -3141,21 +3138,18 @@ pub extern "C" fn Servo_ReparentStyle(st
                 cascade_flags.insert(IS_VISITED_LINK);
             }
         };
 
         if element.is_native_anonymous() {
             cascade_flags.insert(PROHIBIT_DISPLAY_CONTENTS);
         }
     }
-    if let Some(pseudo) = pseudo.as_ref() {
+    if pseudo.is_some() {
         cascade_flags.insert(PROHIBIT_DISPLAY_CONTENTS);
-        if pseudo.is_fieldset_content() {
-            cascade_flags.insert(IS_FIELDSET_CONTENT);
-        }
     }
 
     doc_data.stylist
         .compute_style_with_inputs(&inputs,
                                    pseudo.as_ref(),
                                    &StylesheetGuards::same(&guard),
                                    parent_style,
                                    parent_style_ignoring_first_line,