Bug 1264317 - Make the basic shape clip-path clipping use nsCSSValue::Array instead of nsCSSValueList. r=dholbert
authorJonathan Watt <jwatt@jwatt.org>
Mon, 11 Apr 2016 08:23:12 +0100
changeset 293310 dc8cdaac96f3a9c68d80e5fbbef18f05097e751c
parent 293309 73f507eb28770e6e99e72546dab27f0959cfa3c5
child 293311 b0628853f89996c5ddab16df37dbdebdc4bbc3d7
push id18749
push usercbook@mozilla.com
push dateFri, 15 Apr 2016 12:01:19 +0000
treeherderfx-team@8f7045b63b07 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1264317
milestone48.0a1
Bug 1264317 - Make the basic shape clip-path clipping use nsCSSValue::Array instead of nsCSSValueList. r=dholbert
layout/style/nsCSSParser.cpp
layout/style/nsRuleNode.cpp
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -15836,51 +15836,50 @@ bool CSSParserImpl::ParseClipPath()
   if (!ParseSingleTokenVariant(value, VARIANT_HUO, nullptr)) {
     if (!nsLayoutUtils::CSSClipPathShapesEnabled()) {
       // With CSS Clip Path Shapes disabled, we should only accept
       // SVG clipPath reference and none.
       REPORT_UNEXPECTED_TOKEN(PEExpectedNoneOrURL);
       return false;
     }
 
-    nsCSSValueList* cur = value.SetListValue();
-
     nsCSSValue referenceBox;
     bool hasBox = ParseEnum(referenceBox, nsCSSProps::kClipShapeSizingKTable);
 
+    const bool boxCameFirst = hasBox;
+
     nsCSSValue basicShape;
     bool basicShapeConsumedTokens = false;
     bool hasShape = ParseBasicShape(basicShape, &basicShapeConsumedTokens);
 
     // Parsing wasn't successful if ParseBasicShape consumed tokens but failed
     // or if the token was neither a reference box nor a basic shape.
     if ((!hasShape && basicShapeConsumedTokens) || (!hasBox && !hasShape)) {
       return false;
     }
 
-    // We need to preserve the specified order of arguments for inline style.
-    if (hasBox) {
-      cur->mValue = referenceBox;
-    }
-
-    if (hasShape) {
-      if (hasBox) {
-        cur->mNext = new nsCSSValueList;
-        cur = cur->mNext;
-      }
-      cur->mValue = basicShape;
-    }
-
     // Check if the second argument is a reference box if the first wasn't.
-    if (!hasBox &&
-        ParseEnum(referenceBox, nsCSSProps::kClipShapeSizingKTable)) {
-        cur->mNext = new nsCSSValueList;
-        cur = cur->mNext;
-        cur->mValue = referenceBox;
-    }
+    if (!hasBox) {
+      hasBox = ParseEnum(referenceBox, nsCSSProps::kClipShapeSizingKTable);
+    }
+
+    RefPtr<nsCSSValue::Array> fullValue =
+      nsCSSValue::Array::Create((hasBox && hasShape) ? 2 : 1);
+
+    if (hasBox && hasShape) {
+      fullValue->Item(boxCameFirst ? 0 : 1) = referenceBox;
+      fullValue->Item(boxCameFirst ? 1 : 0) = basicShape;
+    } else if (hasBox) {
+      fullValue->Item(0) = referenceBox;
+    } else {
+      MOZ_ASSERT(hasShape, "should've bailed if we got neither box nor shape");
+      fullValue->Item(0) = basicShape;
+    }
+
+    value.SetArrayValue(fullValue, eCSSUnit_Array);
   }
 
   AppendValue(eCSSProperty_clip_path, value);
   return true;
 }
 
 bool CSSParserImpl::ParseTransformOrigin(bool aPerspective)
 {
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -9354,30 +9354,36 @@ nsRuleNode::ComputeSVGData(void* aStartS
 
 void
 nsRuleNode::SetStyleClipPathToCSSValue(nsStyleClipPath* aStyleClipPath,
                                        const nsCSSValue* aValue,
                                        nsStyleContext* aStyleContext,
                                        nsPresContext* aPresContext,
                                        RuleNodeCacheConditions& aConditions)
 {
-  MOZ_ASSERT(aValue->GetUnit() != eCSSUnit_ListDep ||
-             aValue->GetUnit() != eCSSUnit_List,
+  MOZ_ASSERT(aValue->GetUnit() == eCSSUnit_Array,
              "expected a basic shape or reference box");
 
-  const nsCSSValueList* cur = aValue->GetListValue();
+  const nsCSSValue::Array* array = aValue->GetArrayValue();
+  MOZ_ASSERT(array->Count() == 1 || array->Count() == 2,
+             "Expect one or both of a shape function and geometry-box");
 
   uint8_t sizingBox = NS_STYLE_CLIP_SHAPE_SIZING_NOBOX;
   RefPtr<nsStyleBasicShape> basicShape;
-  for (unsigned i = 0; i < 2; ++i) {
-    if (!cur) {
-      break;
-    }
-    if (cur->mValue.GetUnit() == eCSSUnit_Function) {
-      nsCSSValue::Array* shapeFunction = cur->mValue.GetArrayValue();
+  for (size_t i = 0; i < array->Count(); ++i) {
+    if (array->Item(i).GetUnit() == eCSSUnit_Enumerated) {
+      int32_t type = array->Item(i).GetIntValue();
+      if (type > NS_STYLE_CLIP_SHAPE_SIZING_VIEW ||
+          type < NS_STYLE_CLIP_SHAPE_SIZING_NOBOX) {
+        NS_NOTREACHED("unexpected reference box");
+        return;
+      }
+      sizingBox = (uint8_t)type;
+    } else if (array->Item(i).GetUnit() == eCSSUnit_Function) {
+      nsCSSValue::Array* shapeFunction = array->Item(i).GetArrayValue();
       nsCSSKeyword functionName =
         (nsCSSKeyword)shapeFunction->Item(0).GetIntValue();
       if (functionName == eCSSKeyword_polygon) {
         MOZ_ASSERT(!basicShape, "did not expect value");
         basicShape = new nsStyleBasicShape(nsStyleBasicShape::ePolygon);
         MOZ_ASSERT(shapeFunction->Count() > 1,
                    "polygon has wrong number of arguments");
         size_t j = 1;
@@ -9504,29 +9510,20 @@ nsRuleNode::SetStyleClipPathToCSSValue(n
           NS_FOR_CSS_HALF_CORNERS(j) {
             insetRadius.Set(j, zero);
           }
         }
       } else {
         NS_NOTREACHED("unexpected basic shape function");
         return;
       }
-    } else if (cur->mValue.GetUnit() == eCSSUnit_Enumerated) {
-      int32_t type = cur->mValue.GetIntValue();
-      if (type > NS_STYLE_CLIP_SHAPE_SIZING_VIEW ||
-          type < NS_STYLE_CLIP_SHAPE_SIZING_NOBOX) {
-        NS_NOTREACHED("unexpected reference box");
-        return;
-      }
-      sizingBox = (uint8_t)type;
     } else {
       NS_NOTREACHED("unexpected value");
       return;
     }
-    cur = cur->mNext;
   }
 
   if (basicShape) {
     aStyleClipPath->SetBasicShape(basicShape, sizingBox);
   } else {
     aStyleClipPath->SetSizingBox(sizingBox);
   }
 }
@@ -9651,18 +9648,17 @@ nsRuleNode::ComputeSVGResetData(void* aS
     case eCSSUnit_URL: {
       svgReset->mClipPath = nsStyleClipPath();
       nsIURI* url = clipPathValue->GetURLValue();
       if (url) {
         svgReset->mClipPath.SetURL(url);
       }
       break;
     }
-    case eCSSUnit_List:
-    case eCSSUnit_ListDep: {
+    case eCSSUnit_Array: {
       svgReset->mClipPath = nsStyleClipPath();
       SetStyleClipPathToCSSValue(&svgReset->mClipPath, clipPathValue, aContext,
                                  mPresContext, conditions);
       break;
     }
     default:
       NS_NOTREACHED("unexpected unit");
   }