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 179037 8576639616bb
parent 179036 28e35ed195ab
child 179038 ff492cb2c882
push id42418
push usermpalmgren@mozilla.com
push dateThu, 17 Apr 2014 12:11:22 +0000
treeherdermozilla-inbound@28734b1d45d5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscam
bugs613659
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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