Bug 613659 - Implement box-decoration-break in the style system. r=cam
authorMats Palmgren <matspal@gmail.com>
Thu, 17 Apr 2014 12:11:07 +0000
changeset 179443 8576639616bb14d0e5bfc88e994333884aeadf96
parent 179442 28e35ed195ab75f2bdb3d899292258f01fe4912a
child 179444 ff492cb2c8824ffd4a82b05191e73a2f2307eb1d
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewerscam
bugs613659
milestone31.0a1
Bug 613659 - Implement box-decoration-break in the style system. r=cam
layout/style/nsCSSKeywordList.h
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleConsts.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
modules/libpref/src/init/all.js
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -203,16 +203,17 @@ CSS_KEY(captiontext, captiontext)
 CSS_KEY(cell, cell)
 CSS_KEY(center, center)
 CSS_KEY(ch, ch)
 CSS_KEY(character-variant, character_variant)
 CSS_KEY(circle, circle)
 CSS_KEY(cjk-decimal, cjk_decimal)
 CSS_KEY(cjk-ideographic, cjk_ideographic)
 CSS_KEY(clip, clip)
+CSS_KEY(clone, clone)
 CSS_KEY(close-quote, close_quote)
 CSS_KEY(closest-corner, closest_corner)
 CSS_KEY(closest-side, closest_side)
 CSS_KEY(cm, cm)
 CSS_KEY(col-resize, col_resize)
 CSS_KEY(collapse, collapse)
 CSS_KEY(color, color)
 CSS_KEY(color-burn, color_burn)
@@ -491,16 +492,17 @@ CSS_KEY(show, show)
 CSS_KEY(sideways, sideways)
 CSS_KEY(simp-chinese-formal, simp_chinese_formal)
 CSS_KEY(simp-chinese-informal, simp_chinese_informal)
 CSS_KEY(simplified, simplified)
 CSS_KEY(skew, skew)
 CSS_KEY(skewx, skewx)
 CSS_KEY(skewy, skewy)
 CSS_KEY(slashed-zero, slashed_zero)
+CSS_KEY(slice, slice)
 CSS_KEY(small, small)
 CSS_KEY(small-caps, small_caps)
 CSS_KEY(small-caption, small_caption)
 CSS_KEY(smaller, smaller)
 CSS_KEY(soft, soft)
 CSS_KEY(soft-light, soft_light)
 CSS_KEY(solid, solid)
 CSS_KEY(space-around, space_around)
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1361,16 +1361,26 @@ CSS_PROP_POSITION(
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
         CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
     "",
     VARIANT_AHLP | VARIANT_CALC,
     nullptr,
     offsetof(nsStylePosition, mOffset),
     eStyleAnimType_Sides_Bottom)
 CSS_PROP_BORDER(
+    box-decoration-break,
+    box_decoration_break,
+    BoxDecorationBreak,
+    CSS_PROPERTY_PARSE_VALUE,
+    "layout.css.box-decoration-break.enabled",
+    VARIANT_HK,
+    kBoxDecorationBreakKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_BORDER(
     box-shadow,
     box_shadow,
     BoxShadow,
     CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
         CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
         CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
         // NOTE: some components must be nonnegative
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -791,16 +791,22 @@ const KTableValue nsCSSProps::kBorderWid
 };
 
 const KTableValue nsCSSProps::kBoxPropSourceKTable[] = {
   eCSSKeyword_physical,     NS_BOXPROP_SOURCE_PHYSICAL,
   eCSSKeyword_logical,      NS_BOXPROP_SOURCE_LOGICAL,
   eCSSKeyword_UNKNOWN,-1
 };
 
+const KTableValue nsCSSProps::kBoxDecorationBreakKTable[] = {
+  eCSSKeyword_slice, NS_STYLE_BOX_DECORATION_BREAK_SLICE,
+  eCSSKeyword_clone, NS_STYLE_BOX_DECORATION_BREAK_CLONE,
+  eCSSKeyword_UNKNOWN,-1
+};
+
 const KTableValue nsCSSProps::kBoxShadowTypeKTable[] = {
   eCSSKeyword_inset, NS_STYLE_BOX_SHADOW_INSET,
   eCSSKeyword_UNKNOWN,-1
 };
 
 const KTableValue nsCSSProps::kBoxSizingKTable[] = {
   eCSSKeyword_content_box,  NS_STYLE_BOX_SIZING_CONTENT,
   eCSSKeyword_border_box,   NS_STYLE_BOX_SIZING_BORDER,
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -515,16 +515,17 @@ public:
   static const KTableValue kBlendModeKTable[];
   static const KTableValue kBorderCollapseKTable[];
   static const KTableValue kBorderColorKTable[];
   static const KTableValue kBorderImageRepeatKTable[];
   static const KTableValue kBorderImageSliceKTable[];
   static const KTableValue kBorderStyleKTable[];
   static const KTableValue kBorderWidthKTable[];
   static const KTableValue kBoxAlignKTable[];
+  static const KTableValue kBoxDecorationBreakKTable[];
   static const KTableValue kBoxDirectionKTable[];
   static const KTableValue kBoxOrientKTable[];
   static const KTableValue kBoxPackKTable[];
   static const KTableValue kDominantBaselineKTable[];
   static const KTableValue kFillRuleKTable[];
   static const KTableValue kFilterFunctionKTable[];
   static const KTableValue kImageRenderingKTable[];
   static const KTableValue kShapeRenderingKTable[];
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -2976,16 +2976,26 @@ nsComputedDOMStyle::GetCSSShadowArray(ns
                                        nsCSSProps::kBoxShadowTypeKTable));
     }
   }
 
   return valueList;
 }
 
 CSSValue*
+nsComputedDOMStyle::DoGetBoxDecorationBreak()
+{
+  nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
+  val->SetIdent(
+    nsCSSProps::ValueToKeywordEnum(StyleBorder()->mBoxDecorationBreak,
+                                   nsCSSProps::kBoxDecorationBreakKTable));
+  return val;
+}
+
+CSSValue*
 nsComputedDOMStyle::DoGetBoxShadow()
 {
   return GetCSSShadowArray(StyleBorder()->mBoxShadow,
                            StyleColor()->mColor,
                            true);
 }
 
 CSSValue*
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -217,16 +217,17 @@ private:
    * To avoid a name conflict with nsIDOM*CSS2Properties, these are all
    * DoGetXXX instead of GetXXX.
    */
 
   mozilla::dom::CSSValue* DoGetAppearance();
 
   /* Box properties */
   mozilla::dom::CSSValue* DoGetBoxAlign();
+  mozilla::dom::CSSValue* DoGetBoxDecorationBreak();
   mozilla::dom::CSSValue* DoGetBoxDirection();
   mozilla::dom::CSSValue* DoGetBoxFlex();
   mozilla::dom::CSSValue* DoGetBoxOrdinalGroup();
   mozilla::dom::CSSValue* DoGetBoxOrient();
   mozilla::dom::CSSValue* DoGetBoxPack();
   mozilla::dom::CSSValue* DoGetBoxSizing();
 
   mozilla::dom::CSSValue* DoGetWidth();
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -6440,16 +6440,23 @@ nsRuleNode::ComputeBorderData(void* aSta
                               const nsRuleData* aRuleData,
                               nsStyleContext* aContext,
                               nsRuleNode* aHighestNode,
                               const RuleDetail aRuleDetail,
                               const bool aCanStoreInRuleTree)
 {
   COMPUTE_START_RESET(Border, (mPresContext), border, parentBorder)
 
+  // box-decoration-break: enum, inherit, initial
+  SetDiscrete(*aRuleData->ValueForBoxDecorationBreak(),
+              border->mBoxDecorationBreak, canStoreInRuleTree,
+              SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
+              parentBorder->mBoxDecorationBreak,
+              NS_STYLE_BOX_DECORATION_BREAK_SLICE, 0, 0, 0, 0);
+
   // box-shadow: none, list, inherit, initial
   const nsCSSValue* boxShadowValue = aRuleData->ValueForBoxShadow();
   switch (boxShadowValue->GetUnit()) {
   case eCSSUnit_Null:
     break;
 
   case eCSSUnit_Initial:
   case eCSSUnit_Unset:
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -112,16 +112,20 @@ static inline mozilla::css::Side operato
 #define NS_STYLE_BOX_ALIGN_END         4
 
 // box-pack
 #define NS_STYLE_BOX_PACK_START        0
 #define NS_STYLE_BOX_PACK_CENTER       1
 #define NS_STYLE_BOX_PACK_END          2
 #define NS_STYLE_BOX_PACK_JUSTIFY      3
 
+// box-decoration-break
+#define NS_STYLE_BOX_DECORATION_BREAK_SLICE  0
+#define NS_STYLE_BOX_DECORATION_BREAK_CLONE  1
+
 // box-direction
 #define NS_STYLE_BOX_DIRECTION_NORMAL    0
 #define NS_STYLE_BOX_DIRECTION_REVERSE   1
 
 // box-orient
 #define NS_STYLE_BOX_ORIENT_HORIZONTAL 0
 #define NS_STYLE_BOX_ORIENT_VERTICAL   1
 
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -383,16 +383,17 @@ nsChangeHint nsStylePadding::CalcDiffere
 
 nsStyleBorder::nsStyleBorder(nsPresContext* aPresContext)
   : mBorderColors(nullptr),
     mBoxShadow(nullptr),
     mBorderImageFill(NS_STYLE_BORDER_IMAGE_SLICE_NOFILL),
     mBorderImageRepeatH(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH),
     mBorderImageRepeatV(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH),
     mFloatEdge(NS_STYLE_FLOAT_EDGE_CONTENT),
+    mBoxDecorationBreak(NS_STYLE_BOX_DECORATION_BREAK_SLICE),
     mComputedBorder(0, 0, 0, 0)
 {
   MOZ_COUNT_CTOR(nsStyleBorder);
 
   NS_FOR_CSS_HALF_CORNERS (corner) {
     mBorderRadius.Set(corner, nsStyleCoord(0, nsStyleCoord::CoordConstructor));
   }
 
@@ -434,16 +435,17 @@ nsStyleBorder::nsStyleBorder(const nsSty
     mBorderImageSource(aSrc.mBorderImageSource),
     mBorderImageSlice(aSrc.mBorderImageSlice),
     mBorderImageWidth(aSrc.mBorderImageWidth),
     mBorderImageOutset(aSrc.mBorderImageOutset),
     mBorderImageFill(aSrc.mBorderImageFill),
     mBorderImageRepeatH(aSrc.mBorderImageRepeatH),
     mBorderImageRepeatV(aSrc.mBorderImageRepeatV),
     mFloatEdge(aSrc.mFloatEdge),
+    mBoxDecorationBreak(aSrc.mBoxDecorationBreak),
     mComputedBorder(aSrc.mComputedBorder),
     mBorder(aSrc.mBorder),
     mTwipsPerPixel(aSrc.mTwipsPerPixel)
 {
   MOZ_COUNT_CTOR(nsStyleBorder);
   if (aSrc.mBorderColors) {
     EnsureBorderColors();
     for (int32_t i = 0; i < 4; i++)
@@ -523,17 +525,18 @@ nsChangeHint nsStyleBorder::CalcDifferen
   // Note that differences in mBorder don't affect rendering (which should only
   // use mComputedBorder), so don't need to be tested for here.
   // XXXbz we should be able to return a more specific change hint for
   // at least GetComputedBorder() differences...
   if (mTwipsPerPixel != aOther.mTwipsPerPixel ||
       GetComputedBorder() != aOther.GetComputedBorder() ||
       mFloatEdge != aOther.mFloatEdge ||
       mBorderImageOutset != aOther.mBorderImageOutset ||
-      (shadowDifference & nsChangeHint_NeedReflow))
+      (shadowDifference & nsChangeHint_NeedReflow) ||
+      mBoxDecorationBreak != aOther.mBoxDecorationBreak)
     return NS_STYLE_HINT_REFLOW;
 
   NS_FOR_CSS_SIDES(ix) {
     // See the explanation in nsChangeHint.h of
     // nsChangeHint_BorderStyleNoneChange .
     // Furthermore, even though we know *this* side is 0 width, just
     // assume a visual hint for some other change rather than bother
     // tracking this result through the rest of the function.
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -981,16 +981,17 @@ public:
   nsStyleSides   mBorderImageSlice;   // [reset] factor, percent
   nsStyleSides   mBorderImageWidth;   // [reset] length, factor, percent, auto
   nsStyleSides   mBorderImageOutset;  // [reset] length, factor
 
   uint8_t        mBorderImageFill;    // [reset]
   uint8_t        mBorderImageRepeatH; // [reset] see nsStyleConsts.h
   uint8_t        mBorderImageRepeatV; // [reset]
   uint8_t        mFloatEdge;          // [reset]
+  uint8_t        mBoxDecorationBreak; // [reset] see nsStyleConsts.h
 
 protected:
   // mComputedBorder holds the CSS2.1 computed border-width values.
   // In particular, these widths take into account the border-style
   // for the relevant side, and the values are rounded to the nearest
   // device pixel (which is not part of the definition of computed
   // values). The presence or absence of a border-image does not
   // affect border-width values.
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -5382,16 +5382,27 @@ if (SpecialPowers.getBoolPref("layout.cs
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "padding-box" ],
 		other_values: [ "content-box" ],
 		invalid_values: [ "none", "auto", "border-box", "0" ]
 	};
 }
 
+if (SpecialPowers.getBoolPref("layout.css.box-decoration-break.enabled")) {
+	gCSSProperties["box-decoration-break"] = {
+		domProp: "boxDecorationBreak",
+		inherited: false,
+		type: CSS_TYPE_LONGHAND,
+		initial_values: [ "slice" ],
+		other_values: [ "clone" ],
+		invalid_values: [ "auto",  "none",  "1px" ]
+	};
+}
+
 if (SpecialPowers.getBoolPref("layout.css.unset-value.enabled")) {
   gCSSProperties["animation-direction"].invalid_values.push("normal, unset");
   gCSSProperties["animation-name"].invalid_values.push("bounce, unset", "unset, bounce");
   gCSSProperties["-moz-border-bottom-colors"].invalid_values.push("red unset", "unset red");
   gCSSProperties["-moz-border-left-colors"].invalid_values.push("red unset", "unset red");
   gCSSProperties["border-radius"].invalid_values.push("unset 2px", "unset / 2px", "2px unset", "2px / unset");
   gCSSProperties["border-bottom-left-radius"].invalid_values.push("unset 2px", "2px unset");
   gCSSProperties["border-bottom-right-radius"].invalid_values.push("unset 2px", "2px unset");
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1895,16 +1895,19 @@ pref("layout.css.unset-value.enabled", t
 pref("layout.css.all-shorthand.enabled", true);
 
 // Is support for CSS variables enabled?
 pref("layout.css.variables.enabled", true);
 
 // Is support for CSS overflow-clip-box enabled for non-UA sheets?
 pref("layout.css.overflow-clip-box.enabled", false);
 
+// Is support for CSS box-decoration-break enabled?
+pref("layout.css.box-decoration-break.enabled", false);
+
 // pref for which side vertical scrollbars should be on
 // 0 = end-side in UI direction
 // 1 = end-side in document/content direction
 // 2 = right
 // 3 = left
 pref("layout.scrollbar.side", 0);
 
 // pref to stop overlay scrollbars from fading out, for testing purposes