Implement clip-path: path()

Extended StylePath to contain windRule.
Extended path CSS property parser to account for wind-rule, e.g.
path(oddeven, '...').
Pass through a zoom parameter when requesting a path for a ShapeClipPath.
Allow PathInterpolationFunction to try to handle clip-path animations,
when the shape is a path.

Patched the necessary bits to allow CSSPathValue in clip-path.

Unskipped relevant WPT tests, and added 3 new ones to handle page zoom.
Those tests use zoom css property, in lieu of page-zoom support in WPT

Bug: 880983
Change-Id: I0bf8d7a4ec746f656c33c0f99c37e0af1e3ff7e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2442797
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Reviewed-by: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#817421}
diff --git a/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc b/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
index ed8acf1..d549899 100644
--- a/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
@@ -537,6 +537,9 @@
     case BasicShape::kBasicShapePolygonType:
       return polygon_functions::ConvertBasicShape(To<BasicShapePolygon>(*shape),
                                                   zoom);
+    // Handled by PathInterpolationFunction.
+    case BasicShape::kStylePathType:
+      return nullptr;
     default:
       NOTREACHED();
       return nullptr;
diff --git a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc
index f6e7f98..1bb38aa 100644
--- a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc
@@ -33,12 +33,21 @@
       if (style.ShapeOutside()->CssBox() != CSSBoxType::kMissing)
         return nullptr;
       return style.ShapeOutside()->Shape();
-    case CSSPropertyID::kClipPath:
+    case CSSPropertyID::kClipPath: {
       if (!style.ClipPath())
         return nullptr;
-      if (style.ClipPath()->GetType() != ClipPathOperation::SHAPE)
+      auto* clip_path_operation =
+          DynamicTo<ShapeClipPathOperation>(style.ClipPath());
+      if (!clip_path_operation)
         return nullptr;
-      return To<ShapeClipPathOperation>(style.ClipPath())->GetBasicShape();
+      auto* shape = clip_path_operation->GetBasicShape();
+
+      // Path shape is handled by PathInterpolationType.
+      if (shape->GetType() == BasicShape::kStylePathType)
+        return nullptr;
+
+      return shape;
+    }
     default:
       NOTREACHED();
       return nullptr;
diff --git a/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc b/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc
index 0dbbc62..71ea57ec 100644
--- a/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc
+++ b/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc
@@ -343,6 +343,11 @@
             std::make_unique<CSSImageSliceInterpolationType>(used_property));
         break;
       case CSSPropertyID::kClipPath:
+        applicable_types->push_back(
+            std::make_unique<CSSBasicShapeInterpolationType>(used_property));
+        applicable_types->push_back(
+            std::make_unique<CSSPathInterpolationType>(used_property));
+        break;
       case CSSPropertyID::kShapeOutside:
         applicable_types->push_back(
             std::make_unique<CSSBasicShapeInterpolationType>(used_property));
diff --git a/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc
index 37c5b4d2..d60b395 100644
--- a/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/css/css_path_value.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/core/style/shape_clip_path_operation.h"
 
 namespace blink {
 
@@ -24,11 +25,13 @@
   switch (property.PropertyID()) {
     case CSSPropertyID::kD:
       return style.SvgStyle().D();
-    case CSSPropertyID::kOffsetPath: {
-      BasicShape* offset_path = style.OffsetPath();
-      if (!offset_path || offset_path->GetType() != BasicShape::kStylePathType)
+    case CSSPropertyID::kOffsetPath:
+      return DynamicTo<StylePath>(style.OffsetPath());
+    case CSSPropertyID::kClipPath: {
+      auto* shape = DynamicTo<ShapeClipPathOperation>(style.ClipPath());
+      if (!shape)
         return nullptr;
-      return To<StylePath>(style.OffsetPath());
+      return DynamicTo<StylePath>(shape->GetBasicShape());
     }
     default:
       NOTREACHED();
@@ -47,6 +50,9 @@
     case CSSPropertyID::kOffsetPath:
       style.SetOffsetPath(std::move(path));
       return;
+    case CSSPropertyID::kClipPath:
+      style.SetClipPath(ShapeClipPathOperation::Create(std::move(path)));
+      return;
     default:
       NOTREACHED();
       return;
@@ -59,15 +65,9 @@
     const InterpolableValue& interpolable_value,
     const NonInterpolableValue* non_interpolable_value,
     StyleResolverState& state) const {
-  std::unique_ptr<SVGPathByteStream> path_byte_stream =
-      PathInterpolationFunctions::AppliedValue(interpolable_value,
-                                               non_interpolable_value);
-  if (path_byte_stream->IsEmpty()) {
-    SetPath(CssProperty(), *state.Style(), nullptr);
-    return;
-  }
   SetPath(CssProperty(), *state.Style(),
-          StylePath::Create(std::move(path_byte_stream)));
+          PathInterpolationFunctions::AppliedValue(interpolable_value,
+                                                   non_interpolable_value));
 }
 
 void CSSPathInterpolationType::Composite(
@@ -125,13 +125,13 @@
 InterpolationValue CSSPathInterpolationType::MaybeConvertValue(
     const CSSValue& value,
     const StyleResolverState*,
-    ConversionCheckers& conversion_checkers) const {
+    ConversionCheckers&) const {
   auto* path_value = DynamicTo<cssvalue::CSSPathValue>(value);
-  if (!path_value) {
+  if (!path_value)
     return nullptr;
-  }
+
   return PathInterpolationFunctions::ConvertValue(
-      path_value->ByteStream(), PathInterpolationFunctions::ForceAbsolute);
+      path_value->GetStylePath(), PathInterpolationFunctions::ForceAbsolute);
 }
 
 InterpolationValue
diff --git a/third_party/blink/renderer/core/animation/path_interpolation_functions.cc b/third_party/blink/renderer/core/animation/path_interpolation_functions.cc
index 4331bcc..f3d696942e 100644
--- a/third_party/blink/renderer/core/animation/path_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/path_interpolation_functions.cc
@@ -24,20 +24,26 @@
   ~SVGPathNonInterpolableValue() override = default;
 
   static scoped_refptr<SVGPathNonInterpolableValue> Create(
-      Vector<SVGPathSegType>& path_seg_types) {
-    return base::AdoptRef(new SVGPathNonInterpolableValue(path_seg_types));
+      Vector<SVGPathSegType>& path_seg_types,
+      WindRule wind_rule = RULE_NONZERO) {
+    return base::AdoptRef(
+        new SVGPathNonInterpolableValue(path_seg_types, wind_rule));
   }
 
   const Vector<SVGPathSegType>& PathSegTypes() const { return path_seg_types_; }
+  WindRule GetWindRule() const { return wind_rule_; }
 
   DECLARE_NON_INTERPOLABLE_VALUE_TYPE();
 
  private:
-  SVGPathNonInterpolableValue(Vector<SVGPathSegType>& path_seg_types) {
+  SVGPathNonInterpolableValue(Vector<SVGPathSegType>& path_seg_types,
+                              WindRule wind_rule)
+      : wind_rule_(wind_rule) {
     path_seg_types_.swap(path_seg_types);
   }
 
   Vector<SVGPathSegType> path_seg_types_;
+  WindRule wind_rule_;
 };
 
 DEFINE_NON_INTERPOLABLE_VALUE_TYPE(SVGPathNonInterpolableValue);
@@ -58,9 +64,12 @@
 };
 
 InterpolationValue PathInterpolationFunctions::ConvertValue(
-    const SVGPathByteStream& byte_stream,
+    const StylePath* style_path,
     CoordinateConversion coordinateConversion) {
-  SVGPathByteStreamSource path_source(byte_stream);
+  if (!style_path)
+    return nullptr;
+
+  SVGPathByteStreamSource path_source(style_path->ByteStream());
   wtf_size_t length = 0;
   PathCoordinates current_coordinates;
   Vector<std::unique_ptr<InterpolableValue>> interpolable_path_segs;
@@ -86,19 +95,9 @@
   result->Set(kPathArgsIndex, std::move(path_args));
   result->Set(kPathNeutralIndex, std::make_unique<InterpolableNumber>(0));
 
-  return InterpolationValue(
-      std::move(result), SVGPathNonInterpolableValue::Create(path_seg_types));
-}
-
-InterpolationValue PathInterpolationFunctions::ConvertValue(
-    const StylePath* style_path,
-    CoordinateConversion coordinateConversion) {
-  if (style_path)
-    return ConvertValue(style_path->ByteStream(), coordinateConversion);
-
-  std::unique_ptr<SVGPathByteStream> empty_path =
-      std::make_unique<SVGPathByteStream>();
-  return ConvertValue(*empty_path, ForceAbsolute);
+  return InterpolationValue(std::move(result),
+                            SVGPathNonInterpolableValue::Create(
+                                path_seg_types, style_path->GetWindRule()));
 }
 
 class UnderlyingPathSegTypesChecker
@@ -108,13 +107,14 @@
 
   static std::unique_ptr<UnderlyingPathSegTypesChecker> Create(
       const InterpolationValue& underlying) {
-    return base::WrapUnique(
-        new UnderlyingPathSegTypesChecker(GetPathSegTypes(underlying)));
+    return base::WrapUnique(new UnderlyingPathSegTypesChecker(
+        GetPathSegTypes(underlying), GetWindRule(underlying)));
   }
 
  private:
-  UnderlyingPathSegTypesChecker(const Vector<SVGPathSegType>& path_seg_types)
-      : path_seg_types_(path_seg_types) {}
+  UnderlyingPathSegTypesChecker(const Vector<SVGPathSegType>& path_seg_types,
+                                WindRule wind_rule)
+      : path_seg_types_(path_seg_types), wind_rule_(wind_rule) {}
 
   static const Vector<SVGPathSegType>& GetPathSegTypes(
       const InterpolationValue& underlying) {
@@ -122,12 +122,19 @@
         .PathSegTypes();
   }
 
+  static WindRule GetWindRule(const InterpolationValue& underlying) {
+    return To<SVGPathNonInterpolableValue>(*underlying.non_interpolable_value)
+        .GetWindRule();
+  }
+
   bool IsValid(const InterpolationEnvironment&,
                const InterpolationValue& underlying) const final {
-    return path_seg_types_ == GetPathSegTypes(underlying);
+    return path_seg_types_ == GetPathSegTypes(underlying) &&
+           wind_rule_ == GetWindRule(underlying);
   }
 
   Vector<SVGPathSegType> path_seg_types_;
+  WindRule wind_rule_;
 };
 
 InterpolationValue PathInterpolationFunctions::MaybeConvertNeutral(
@@ -161,12 +168,15 @@
 PairwiseInterpolationValue PathInterpolationFunctions::MaybeMergeSingles(
     InterpolationValue&& start,
     InterpolationValue&& end) {
-  const Vector<SVGPathSegType>& start_types =
-      To<SVGPathNonInterpolableValue>(*start.non_interpolable_value)
-          .PathSegTypes();
-  const Vector<SVGPathSegType>& end_types =
-      To<SVGPathNonInterpolableValue>(*end.non_interpolable_value)
-          .PathSegTypes();
+  auto& start_path =
+      To<SVGPathNonInterpolableValue>(*start.non_interpolable_value);
+  auto& end_path = To<SVGPathNonInterpolableValue>(*end.non_interpolable_value);
+
+  if (start_path.GetWindRule() != end_path.GetWindRule())
+    return nullptr;
+
+  const Vector<SVGPathSegType>& start_types = start_path.PathSegTypes();
+  const Vector<SVGPathSegType>& end_types = end_path.PathSegTypes();
   if (start_types.size() == 0 || !PathSegTypesMatch(start_types, end_types))
     return nullptr;
 
@@ -201,18 +211,23 @@
       value.non_interpolable_value.get();
 }
 
-std::unique_ptr<SVGPathByteStream> PathInterpolationFunctions::AppliedValue(
+scoped_refptr<StylePath> PathInterpolationFunctions::AppliedValue(
     const InterpolableValue& interpolable_value,
     const NonInterpolableValue* non_interpolable_value) {
   std::unique_ptr<SVGPathByteStream> path_byte_stream =
       std::make_unique<SVGPathByteStream>();
+
+  auto* non_interpolable_path_value =
+      To<SVGPathNonInterpolableValue>(non_interpolable_value);
   InterpolatedSVGPathSource source(
       To<InterpolableList>(
           *To<InterpolableList>(interpolable_value).Get(kPathArgsIndex)),
-      To<SVGPathNonInterpolableValue>(non_interpolable_value)->PathSegTypes());
+      non_interpolable_path_value->PathSegTypes());
   SVGPathByteStreamBuilder builder(*path_byte_stream);
   svg_path_parser::ParsePath(source, builder);
-  return path_byte_stream;
+
+  return StylePath::Create(std::move(path_byte_stream),
+                           non_interpolable_path_value->GetWindRule());
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/path_interpolation_functions.h b/third_party/blink/renderer/core/animation/path_interpolation_functions.h
index a545f023..dddce78 100644
--- a/third_party/blink/renderer/core/animation/path_interpolation_functions.h
+++ b/third_party/blink/renderer/core/animation/path_interpolation_functions.h
@@ -20,18 +20,14 @@
  public:
   enum CoordinateConversion { PreserveCoordinates, ForceAbsolute };
 
-  static std::unique_ptr<SVGPathByteStream> AppliedValue(
-      const InterpolableValue&,
-      const NonInterpolableValue*);
+  static scoped_refptr<StylePath> AppliedValue(const InterpolableValue&,
+                                               const NonInterpolableValue*);
 
   static void Composite(UnderlyingValueOwner&,
                         double underlying_fraction,
                         const InterpolationType&,
                         const InterpolationValue&);
 
-  static InterpolationValue ConvertValue(const SVGPathByteStream&,
-                                         CoordinateConversion);
-
   static InterpolationValue ConvertValue(const StylePath*,
                                          CoordinateConversion);
 
diff --git a/third_party/blink/renderer/core/animation/svg_path_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_path_interpolation_type.cc
index 7fa8e96..9c256e7 100644
--- a/third_party/blink/renderer/core/animation/svg_path_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/svg_path_interpolation_type.cc
@@ -16,7 +16,7 @@
     return nullptr;
 
   return PathInterpolationFunctions::ConvertValue(
-      To<SVGPath>(svg_value).ByteStream(),
+      To<SVGPath>(svg_value).GetStylePath(),
       PathInterpolationFunctions::PreserveCoordinates);
 }
 
diff --git a/third_party/blink/renderer/core/css/basic_shape_functions.cc b/third_party/blink/renderer/core/css/basic_shape_functions.cc
index f6418d3..0ab751f 100644
--- a/third_party/blink/renderer/core/css/basic_shape_functions.cc
+++ b/third_party/blink/renderer/core/css/basic_shape_functions.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/renderer/core/css/css_basic_shape_values.h"
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
+#include "third_party/blink/renderer/core/css/css_path_value.h"
 #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h"
 #include "third_party/blink/renderer/core/css/css_ray_value.h"
 #include "third_party/blink/renderer/core/css/css_value_pair.h"
@@ -358,6 +359,9 @@
     StyleRay::RaySize size = KeywordToRaySize(ray_value->Size().GetValueID());
     bool contain = !!ray_value->Contain();
     basic_shape = StyleRay::Create(angle, size, contain);
+  } else if (const auto* path_value =
+                 DynamicTo<cssvalue::CSSPathValue>(basic_shape_value)) {
+    basic_shape = path_value->GetStylePath();
   } else {
     NOTREACHED();
   }
diff --git a/third_party/blink/renderer/core/css/css_path_value.cc b/third_party/blink/renderer/core/css/css_path_value.cc
index 3c1ae0b..d4f7425 100644
--- a/third_party/blink/renderer/core/css/css_path_value.cc
+++ b/third_party/blink/renderer/core/css/css_path_value.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/renderer/core/style/style_path.h"
 #include "third_party/blink/renderer/core/svg/svg_path_utilities.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
 namespace blink {
 
@@ -22,8 +23,9 @@
 }
 
 CSSPathValue::CSSPathValue(std::unique_ptr<SVGPathByteStream> path_byte_stream,
+                           WindRule wind_rule,
                            PathSerializationFormat serialization_format)
-    : CSSPathValue(StylePath::Create(std::move(path_byte_stream)),
+    : CSSPathValue(StylePath::Create(std::move(path_byte_stream), wind_rule),
                    serialization_format) {}
 
 namespace {
@@ -45,8 +47,14 @@
 }
 
 String CSSPathValue::CustomCSSText() const {
-  return "path(\"" +
-         BuildStringFromByteStream(ByteStream(), serialization_format_) + "\")";
+  StringBuilder result;
+  result.Append("path(");
+  if (style_path_->GetWindRule() == RULE_EVENODD)
+    result.Append("evenodd, ");
+  result.Append("\"");
+  result.Append(BuildStringFromByteStream(ByteStream(), serialization_format_));
+  result.Append("\")");
+  return result.ToString();
 }
 
 bool CSSPathValue::Equals(const CSSPathValue& other) const {
diff --git a/third_party/blink/renderer/core/css/css_path_value.h b/third_party/blink/renderer/core/css/css_path_value.h
index ee3d8128..2642b31 100644
--- a/third_party/blink/renderer/core/css/css_path_value.h
+++ b/third_party/blink/renderer/core/css/css_path_value.h
@@ -26,6 +26,7 @@
   explicit CSSPathValue(scoped_refptr<StylePath>,
                         PathSerializationFormat = kNoTransformation);
   explicit CSSPathValue(std::unique_ptr<SVGPathByteStream>,
+                        WindRule wind_rule = RULE_NONZERO,
                         PathSerializationFormat = kNoTransformation);
 
   StylePath* GetStylePath() const { return style_path_.get(); }
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
index c9dd2a0..a72cce67 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -4386,7 +4386,43 @@
   return false;
 }
 
-CSSValue* ConsumePath(CSSParserTokenRange& range) {
+std::unique_ptr<SVGPathByteStream> ConsumePathStringArg(
+    CSSParserTokenRange& args) {
+  if (args.Peek().GetType() != kStringToken)
+    return nullptr;
+
+  StringView path_string = args.ConsumeIncludingWhitespace().Value();
+  std::unique_ptr<SVGPathByteStream> byte_stream =
+      std::make_unique<SVGPathByteStream>();
+  if (BuildByteStreamFromString(path_string, *byte_stream) !=
+      SVGParseStatus::kNoError) {
+    return nullptr;
+  }
+
+  return byte_stream;
+}
+
+cssvalue::CSSPathValue* ConsumeBasicShapePath(CSSParserTokenRange& args) {
+  auto wind_rule = RULE_NONZERO;
+
+  if (IdentMatches<CSSValueID::kEvenodd, CSSValueID::kNonzero>(
+          args.Peek().Id())) {
+    wind_rule = args.ConsumeIncludingWhitespace().Id() == CSSValueID::kEvenodd
+                    ? RULE_EVENODD
+                    : RULE_NONZERO;
+    if (!ConsumeCommaIncludingWhitespace(args))
+      return nullptr;
+  }
+
+  auto byte_stream = ConsumePathStringArg(args);
+  if (!byte_stream || !args.AtEnd())
+    return nullptr;
+
+  return MakeGarbageCollected<cssvalue::CSSPathValue>(std::move(byte_stream),
+                                                      wind_rule);
+}
+
+CSSValue* ConsumePathFunction(CSSParserTokenRange& range) {
   // FIXME: Add support for <url>, <basic-shape>, <geometry-box>.
   if (range.Peek().FunctionId() != CSSValueID::kPath)
     return nullptr;
@@ -4394,16 +4430,9 @@
   CSSParserTokenRange function_range = range;
   CSSParserTokenRange function_args = ConsumeFunction(function_range);
 
-  if (function_args.Peek().GetType() != kStringToken)
+  auto byte_stream = ConsumePathStringArg(function_args);
+  if (!byte_stream || !function_args.AtEnd())
     return nullptr;
-  StringView path_string = function_args.ConsumeIncludingWhitespace().Value();
-  std::unique_ptr<SVGPathByteStream> byte_stream =
-      std::make_unique<SVGPathByteStream>();
-  if (BuildByteStreamFromString(path_string, *byte_stream) !=
-          SVGParseStatus::kNoError ||
-      !function_args.AtEnd()) {
-    return nullptr;
-  }
 
   range = function_range;
   if (byte_stream->IsEmpty())
@@ -4505,7 +4534,7 @@
   if (id == CSSValueID::kNone)
     return ConsumeIdent(range);
 
-  return ConsumePath(range);
+  return ConsumePathFunction(range);
 }
 
 CSSValue* ConsumeOffsetRotate(CSSParserTokenRange& range,
@@ -4574,7 +4603,8 @@
 }
 
 CSSValue* ConsumeBasicShape(CSSParserTokenRange& range,
-                            const CSSParserContext& context) {
+                            const CSSParserContext& context,
+                            AllowPathValue allow_path) {
   CSSValue* shape = nullptr;
   if (range.Peek().GetType() != kFunctionToken)
     return nullptr;
@@ -4589,6 +4619,8 @@
     shape = ConsumeBasicShapePolygon(args, context);
   else if (id == CSSValueID::kInset)
     shape = ConsumeBasicShapeInset(args, context);
+  else if (id == CSSValueID::kPath && allow_path == AllowPathValue::kAllow)
+    shape = ConsumeBasicShapePath(args);
   if (!shape || !args.AtEnd())
     return nullptr;
 
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
index b051a17..543a8615 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
@@ -45,6 +45,7 @@
 
 enum class AllowInsetAndSpread { kAllow, kForbid };
 enum class AllowTextValue { kAllow, kForbid };
+enum class AllowPathValue { kAllow, kForbid };
 enum class DefaultFill { kFill, kNoFill };
 enum class ParsingStyle { kLegacy, kNotLegacy };
 enum class TrackListType { kGridTemplate, kGridTemplateNoRepeat, kGridAuto };
@@ -416,7 +417,9 @@
 CSSValue* ConsumePathOrNone(CSSParserTokenRange&);
 CSSValue* ConsumeOffsetRotate(CSSParserTokenRange&, const CSSParserContext&);
 
-CSSValue* ConsumeBasicShape(CSSParserTokenRange&, const CSSParserContext&);
+CSSValue* ConsumeBasicShape(CSSParserTokenRange&,
+                            const CSSParserContext&,
+                            AllowPathValue);
 bool ConsumeRadii(CSSValue* horizontal_radii[4],
                   CSSValue* vertical_radii[4],
                   CSSParserTokenRange&,
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
index f7cdcad..41e88676 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -1455,7 +1455,8 @@
   if (cssvalue::CSSURIValue* url =
           css_parsing_utils::ConsumeUrl(range, context))
     return url;
-  return css_parsing_utils::ConsumeBasicShape(range, context);
+  return css_parsing_utils::ConsumeBasicShape(
+      range, context, css_parsing_utils::AllowPathValue::kAllow);
 }
 
 const CSSValue* ClipPath::CSSValueFromComputedStyleInternal(
@@ -5791,8 +5792,8 @@
     return image_value;
   CSSValueList* list = CSSValueList::CreateSpaceSeparated();
   CSSValue* box_value = css_parsing_utils::ConsumeShapeBox(range);
-  if (CSSValue* shape_value =
-          css_parsing_utils::ConsumeBasicShape(range, context)) {
+  if (CSSValue* shape_value = css_parsing_utils::ConsumeBasicShape(
+          range, context, css_parsing_utils::AllowPathValue::kForbid)) {
     list->Append(*shape_value);
     if (!box_value) {
       box_value = css_parsing_utils::ConsumeShapeBox(range);
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index df82a83a..35eb45c 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -147,8 +147,9 @@
 scoped_refptr<ClipPathOperation> StyleBuilderConverter::ConvertClipPath(
     StyleResolverState& state,
     const CSSValue& value) {
-  if (value.IsBasicShapeValue())
+  if (value.IsBasicShapeValue() || value.IsPathValue())
     return ShapeClipPathOperation::Create(BasicShapeForValue(state, value));
+
   if (const auto* url_value = DynamicTo<cssvalue::CSSURIValue>(value)) {
     SVGResource* resource =
         state.GetElementStyleResources().GetSVGResourceFromValue(
diff --git a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
index f002404..27e3f04 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
@@ -453,7 +453,7 @@
   if (clip_path_operation->GetType() == ClipPathOperation::SHAPE) {
     ShapeClipPathOperation& clip_path =
         To<ShapeClipPathOperation>(*clip_path_operation);
-    return clip_path.GetPath(reference_box)
+    return clip_path.GetPath(reference_box, 1)
         .Contains(location.TransformedPoint());
   }
   DCHECK_EQ(clip_path_operation->GetType(), ClipPathOperation::REFERENCE);
diff --git a/third_party/blink/renderer/core/paint/clip_path_clipper.cc b/third_party/blink/renderer/core/paint/clip_path_clipper.cc
index cd34316..efe54d6 100644
--- a/third_party/blink/renderer/core/paint/clip_path_clipper.cc
+++ b/third_party/blink/renderer/core/paint/clip_path_clipper.cc
@@ -75,7 +75,9 @@
     ShapeClipPathOperation& shape = To<ShapeClipPathOperation>(clip_path);
     if (!shape.IsValid())
       return base::nullopt;
-    FloatRect bounding_box = shape.GetPath(reference_box).BoundingRect();
+    auto zoom =
+        UsesZoomedReferenceBox(object) ? object.StyleRef().EffectiveZoom() : 1;
+    FloatRect bounding_box = shape.GetPath(reference_box, zoom).BoundingRect();
     bounding_box.Intersect(LayoutRect::InfiniteIntRect());
     return bounding_box;
   }
@@ -160,7 +162,10 @@
 
   DCHECK_EQ(clip_path.GetType(), ClipPathOperation::SHAPE);
   auto& shape = To<ShapeClipPathOperation>(clip_path);
-  return shape.GetPath(reference_box);
+  float zoom = uses_zoomed_reference_box
+                   ? clip_path_owner.StyleRef().EffectiveZoom()
+                   : 1;
+  return shape.GetPath(reference_box, zoom);
 }
 
 void ClipPathClipper::PaintClipPathAsMaskImage(
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc
index 32f79ae..d99f1d0d 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -2544,7 +2544,10 @@
   if (clip_path_operation->GetType() == ClipPathOperation::SHAPE) {
     ShapeClipPathOperation* clip_path =
         To<ShapeClipPathOperation>(clip_path_operation);
-    return !clip_path->GetPath(reference_box).Contains(point);
+    return !clip_path
+                ->GetPath(reference_box,
+                          GetLayoutObject().StyleRef().EffectiveZoom())
+                .Contains(point);
   }
   DCHECK_EQ(clip_path_operation->GetType(), ClipPathOperation::REFERENCE);
   LayoutSVGResourceClipper* clipper = GetSVGResourceAsType(clip_path_operation);
diff --git a/third_party/blink/renderer/core/style/basic_shapes.cc b/third_party/blink/renderer/core/style/basic_shapes.cc
index a2abd9c..a847bfc 100644
--- a/third_party/blink/renderer/core/style/basic_shapes.cc
+++ b/third_party/blink/renderer/core/style/basic_shapes.cc
@@ -64,7 +64,9 @@
                   std::max(center.Y(), height_delta));
 }
 
-void BasicShapeCircle::GetPath(Path& path, const FloatRect& bounding_box) {
+void BasicShapeCircle::GetPath(Path& path,
+                               const FloatRect& bounding_box,
+                               float) {
   DCHECK(path.IsEmpty());
   FloatPoint center =
       FloatPointForCenterCoordinate(center_x_, center_y_, bounding_box.Size());
@@ -97,7 +99,9 @@
   return std::max(center, width_or_height_delta);
 }
 
-void BasicShapeEllipse::GetPath(Path& path, const FloatRect& bounding_box) {
+void BasicShapeEllipse::GetPath(Path& path,
+                                const FloatRect& bounding_box,
+                                float) {
   DCHECK(path.IsEmpty());
   FloatPoint center =
       FloatPointForCenterCoordinate(center_x_, center_y_, bounding_box.Size());
@@ -110,7 +114,9 @@
                             radius_x * 2, radius_y * 2));
 }
 
-void BasicShapePolygon::GetPath(Path& path, const FloatRect& bounding_box) {
+void BasicShapePolygon::GetPath(Path& path,
+                                const FloatRect& bounding_box,
+                                float) {
   DCHECK(path.IsEmpty());
   DCHECK(!(values_.size() % 2));
   wtf_size_t length = values_.size();
@@ -140,7 +146,9 @@
   return wind_rule_ == other.wind_rule_ && values_ == other.values_;
 }
 
-void BasicShapeInset::GetPath(Path& path, const FloatRect& bounding_box) {
+void BasicShapeInset::GetPath(Path& path,
+                              const FloatRect& bounding_box,
+                              float) {
   DCHECK(path.IsEmpty());
   float left = FloatValueForLength(left_, bounding_box.Width());
   float top = FloatValueForLength(top_, bounding_box.Height());
diff --git a/third_party/blink/renderer/core/style/basic_shapes.h b/third_party/blink/renderer/core/style/basic_shapes.h
index d73aa6e..c7ec083 100644
--- a/third_party/blink/renderer/core/style/basic_shapes.h
+++ b/third_party/blink/renderer/core/style/basic_shapes.h
@@ -65,7 +65,7 @@
     return GetType() == other.GetType();
   }
 
-  virtual void GetPath(Path&, const FloatRect&) = 0;
+  virtual void GetPath(Path&, const FloatRect&, float zoom) = 0;
   virtual WindRule GetWindRule() const { return RULE_NONZERO; }
   virtual bool operator==(const BasicShape&) const = 0;
 
@@ -146,7 +146,7 @@
   void SetCenterY(BasicShapeCenterCoordinate center_y) { center_y_ = center_y; }
   void SetRadius(BasicShapeRadius radius) { radius_ = radius; }
 
-  void GetPath(Path&, const FloatRect&) override;
+  void GetPath(Path&, const FloatRect&, float) override;
   bool operator==(const BasicShape&) const override;
 
   ShapeType GetType() const override { return kBasicShapeCircleType; }
@@ -185,7 +185,7 @@
   void SetRadiusX(BasicShapeRadius radius_x) { radius_x_ = radius_x; }
   void SetRadiusY(BasicShapeRadius radius_y) { radius_y_ = radius_y; }
 
-  void GetPath(Path&, const FloatRect&) override;
+  void GetPath(Path&, const FloatRect&, float) override;
   bool operator==(const BasicShape&) const override;
 
   ShapeType GetType() const override { return kBasicShapeEllipseType; }
@@ -220,7 +220,7 @@
     values_.push_back(y);
   }
 
-  void GetPath(Path&, const FloatRect&) override;
+  void GetPath(Path&, const FloatRect&, float) override;
   bool operator==(const BasicShape&) const override;
 
   WindRule GetWindRule() const override { return wind_rule_; }
@@ -273,7 +273,7 @@
     bottom_left_radius_ = radius;
   }
 
-  void GetPath(Path&, const FloatRect&) override;
+  void GetPath(Path&, const FloatRect&, float) override;
   bool operator==(const BasicShape&) const override;
 
   ShapeType GetType() const override { return kBasicShapeInsetType; }
diff --git a/third_party/blink/renderer/core/style/shape_clip_path_operation.h b/third_party/blink/renderer/core/style/shape_clip_path_operation.h
index 03d4c447..ae51942 100644
--- a/third_party/blink/renderer/core/style/shape_clip_path_operation.h
+++ b/third_party/blink/renderer/core/style/shape_clip_path_operation.h
@@ -45,10 +45,10 @@
 
   const BasicShape* GetBasicShape() const { return shape_.get(); }
   bool IsValid() const { return shape_.get(); }
-  Path GetPath(const FloatRect& bounding_rect) const {
+  Path GetPath(const FloatRect& bounding_rect, float zoom) const {
     DCHECK(shape_);
     Path path;
-    shape_->GetPath(path, bounding_rect);
+    shape_->GetPath(path, bounding_rect, zoom);
     path.SetWindRule(shape_->GetWindRule());
     return path;
   }
diff --git a/third_party/blink/renderer/core/style/style_path.cc b/third_party/blink/renderer/core/style/style_path.cc
index 41ccc527..4bcf5b2a 100644
--- a/third_party/blink/renderer/core/style/style_path.cc
+++ b/third_party/blink/renderer/core/style/style_path.cc
@@ -13,20 +13,24 @@
 #include "third_party/blink/renderer/core/svg/svg_path_utilities.h"
 #include "third_party/blink/renderer/platform/graphics/path.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
 
 namespace blink {
 
-StylePath::StylePath(std::unique_ptr<SVGPathByteStream> path_byte_stream)
+StylePath::StylePath(std::unique_ptr<SVGPathByteStream> path_byte_stream,
+                     WindRule wind_rule)
     : byte_stream_(std::move(path_byte_stream)),
-      path_length_(std::numeric_limits<float>::quiet_NaN()) {
+      path_length_(std::numeric_limits<float>::quiet_NaN()),
+      wind_rule_(wind_rule) {
   DCHECK(byte_stream_);
 }
 
 StylePath::~StylePath() = default;
 
 scoped_refptr<StylePath> StylePath::Create(
-    std::unique_ptr<SVGPathByteStream> path_byte_stream) {
-  return base::AdoptRef(new StylePath(std::move(path_byte_stream)));
+    std::unique_ptr<SVGPathByteStream> path_byte_stream,
+    WindRule wind_rule) {
+  return base::AdoptRef(new StylePath(std::move(path_byte_stream), wind_rule));
 }
 
 const StylePath* StylePath::EmptyPath() {
@@ -62,12 +66,13 @@
   if (!IsSameType(o))
     return false;
   const StylePath& other = To<StylePath>(o);
-  return *byte_stream_ == *other.byte_stream_;
+  return wind_rule_ == other.wind_rule_ && *byte_stream_ == *other.byte_stream_;
 }
 
-void StylePath::GetPath(Path&, const FloatRect&) {
-  // Callers should use GetPath() overload, which avoids making a copy.
-  NOTREACHED();
+void StylePath::GetPath(Path& path, const FloatRect& offset_rect, float zoom) {
+  path = GetPath();
+  path.Transform(AffineTransform::Translation(offset_rect.X(), offset_rect.Y())
+                     .Scale(zoom));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/style/style_path.h b/third_party/blink/renderer/core/style/style_path.h
index b25f308..52d7b300 100644
--- a/third_party/blink/renderer/core/style/style_path.h
+++ b/third_party/blink/renderer/core/style/style_path.h
@@ -18,7 +18,8 @@
 
 class StylePath final : public BasicShape {
  public:
-  static scoped_refptr<StylePath> Create(std::unique_ptr<SVGPathByteStream>);
+  static scoped_refptr<StylePath> Create(std::unique_ptr<SVGPathByteStream>,
+                                         WindRule wind_rule = RULE_NONZERO);
   ~StylePath() override;
 
   static const StylePath* EmptyPath();
@@ -31,17 +32,20 @@
 
   CSSValue* ComputedCSSValue() const;
 
-  void GetPath(Path&, const FloatRect&) override;
+  void GetPath(Path&, const FloatRect&, float zoom) override;
+  WindRule GetWindRule() const override { return wind_rule_; }
+
   bool operator==(const BasicShape&) const override;
 
   ShapeType GetType() const override { return kStylePathType; }
 
  private:
-  explicit StylePath(std::unique_ptr<SVGPathByteStream>);
+  explicit StylePath(std::unique_ptr<SVGPathByteStream>, WindRule wind_rule);
 
   std::unique_ptr<SVGPathByteStream> byte_stream_;
   mutable std::unique_ptr<Path> path_;
   mutable float path_length_;
+  WindRule wind_rule_;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/style/style_ray.cc b/third_party/blink/renderer/core/style/style_ray.cc
index 3d6b5d6a..b8dc0fa 100644
--- a/third_party/blink/renderer/core/style/style_ray.cc
+++ b/third_party/blink/renderer/core/style/style_ray.cc
@@ -25,7 +25,7 @@
          contain_ == other.contain_;
 }
 
-void StyleRay::GetPath(Path&, const FloatRect&) {
+void StyleRay::GetPath(Path&, const FloatRect&, float) {
   // ComputedStyle::ApplyMotionPathTransform cannot call GetPath
   // for rays as they may have infinite length.
   NOTREACHED();
diff --git a/third_party/blink/renderer/core/style/style_ray.h b/third_party/blink/renderer/core/style/style_ray.h
index 636b4d6..7e3dd53 100644
--- a/third_party/blink/renderer/core/style/style_ray.h
+++ b/third_party/blink/renderer/core/style/style_ray.h
@@ -27,7 +27,7 @@
   RaySize Size() const { return size_; }
   bool Contain() const { return contain_; }
 
-  void GetPath(Path&, const FloatRect&) override;
+  void GetPath(Path&, const FloatRect&, float) override;
   bool operator==(const BasicShape&) const override;
 
   ShapeType GetType() const override { return kStyleRayType; }
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 2f6d8d5..e30501f 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2960,11 +2960,7 @@
 crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering.html [ Failure ]
 crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall.html [ Failure ]
 crbug.com/626703 external/wpt/speech-api/SpeechSynthesis-pause-resume.tentative.html [ Timeout ]
-crbug.com/880983 external/wpt/css/css-masking/clip-path/clip-path-path-interpolation-001.html [ Failure ]
-crbug.com/880983 external/wpt/css/css-masking/clip-path/clip-path-path-interpolation-002.html [ Failure ]
 crbug.com/891944 external/wpt/css/css-scrollbars/textarea-scrollbar-width-none.html [ Failure ]
-crbug.com/880983 external/wpt/css/css-masking/clip-path/clip-path-path-002.html [ Failure ]
-crbug.com/880983 external/wpt/css/css-masking/clip-path/clip-path-path-001.html [ Failure ]
 crbug.com/432153 external/wpt/css/css-masking/mask-image/mask-image-url-local-mask.html [ Failure ]
 crbug.com/432153 external/wpt/css/css-masking/mask-image/mask-image-url-image.html [ Failure ]
 crbug.com/432153 external/wpt/css/css-masking/mask-image/mask-image-url-remote-mask.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-path-interpolation-with-zoom.html b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-path-interpolation-with-zoom.html
new file mode 100644
index 0000000..4d54708
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-path-interpolation-with-zoom.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+  <title>CSS Masking: Test clip-path nonzero path interpolation with zoom</title>
+  <link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-path">
+  <link rel="match" href="reference/clip-path-path-interpolation-with-zoom-ref.html">
+  <meta name="assert" content="The clip-path property takes the basic shape
+	'path()' for clipping. Test the interpolation of nonzero
+        path function.">
+  <style>
+    @keyframes anim {
+      from {
+        clip-path: path(nonzero, 'M20,20h60 v60 h-60z M30,30 h40 v40 h-40z');
+      }
+      to {
+        clip-path: path(nonzero, 'M50,50h50 v50 h-50z M20,20 h50 v50 h-50z');
+      }
+    }
+    #rect {
+      width: 100px;
+      zoom: 3;
+      height: 100px;
+      background-color: green;
+      animation: anim 10s -5s paused linear;
+    }
+  </style>
+  <div id="rect"></div>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-path-with-zoom-hittest.html b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-path-with-zoom-hittest.html
new file mode 100644
index 0000000..30ceefcb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-path-with-zoom-hittest.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>CSS Masking: Test clip-path property hit-testing when the page is zoomed</title>
+<link rel="author" title="Noam Rosenthal" href="mailto:noam@webkit.org">
+<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-path">
+<meta name="assert" content="The zoomed path is hit-tested correctly">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+  #triangle {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+    clip-path: path(nonzero, 'M0 0, L100 0, L0 100, L 0 0');
+    zoom: 2;
+  }
+</style>
+<div id="triangle"></div>
+<script>
+  test(() => {
+    assert_equals(document.elementFromPoint(20, 20).id, 'triangle')
+    assert_equals(document.elementFromPoint(150, 20).id, 'triangle')
+    assert_equals(document.elementFromPoint(180, 180).tagName, 'BODY')
+  }, 'clip-path: path() hit-test takes zoom into account');
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-path-with-zoom.html b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-path-with-zoom.html
new file mode 100644
index 0000000..5879917f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-path-with-zoom.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>CSS Masking: Test clip-path property when the page is zoomed</title>
+<link rel="author" title="Noam Rosenthal" href="mailto:noam@webkit.org">
+<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-path">
+<link rel="match" href="reference/clip-path-path-with-zoom-ref.html">
+<meta name="assert" content="The path gets zoomed together with the content">
+<style>
+  #red {
+    position: absolute;
+    width: 100px;
+    height: 100px;
+    background: red;
+  }
+  #rect {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+    clip-path: path(nonzero, 'M0 0, L100 0, L0 100, L 0 0');
+    zoom: 2;
+  }
+</style>
+<div id="red"></div>
+<div id="rect"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/reference/clip-path-path-interpolation-with-zoom-ref.html b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/reference/clip-path-path-interpolation-with-zoom-ref.html
new file mode 100644
index 0000000..7e0d2a54
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/reference/clip-path-path-interpolation-with-zoom-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>CSS Masking: Test clip-path nonzero path interpolation with zoom</title>
+<style type="text/css">
+  #rect {
+    width: 300px;
+    height: 300px;
+    background-color: green;
+    clip-path: path('M105,105 H270 V270 H105Z M75,75 H210 V210 H75Z');
+  }
+
+</style>
+<div id="rect"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/reference/clip-path-path-with-zoom-ref.html b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/reference/clip-path-path-with-zoom-ref.html
new file mode 100644
index 0000000..ef91c619
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/reference/clip-path-path-with-zoom-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <title>CSS Masking: Test clip-path property when the page is zoomed</title>
+  <style>
+    #rect {
+      width: 200px;
+      height: 200px;
+      background: green;
+      clip-path: path(nonzero, 'M0 0, L200 0, L0 200');
+    }
+  </style>
+  <div id="rect"></div>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/parsing/clip-path-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-masking/parsing/clip-path-valid-expected.txt
index 1646361..60c4fb0 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-masking/parsing/clip-path-valid-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-masking/parsing/clip-path-valid-expected.txt
@@ -23,11 +23,11 @@
 PASS e.style['clip-path'] = "polygon(1% 2%)" should set the property value
 PASS e.style['clip-path'] = "polygon(nonzero, 1px 2px, 3em 4em)" should set the property value
 PASS e.style['clip-path'] = "polygon(evenodd, 1px 2px, 3em 4em, 5pt 6%)" should set the property value
-FAIL e.style['clip-path'] = "path(\"m 20 0 h -100\")" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "path(evenodd, \"M 20 20 h 60 v 60 h -60 Z M 30 30 h 40 v 40 h -40 Z\")" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "path(nonzero, \"M20,20h60 v60 h-60z M30,30 h40 v40 h-40z\")" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "path(\" \")" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "path(evenodd, \"\")" should set the property value assert_not_equals: property should be set got disallowed value ""
+PASS e.style['clip-path'] = "path(\"m 20 0 h -100\")" should set the property value
+PASS e.style['clip-path'] = "path(evenodd, \"M 20 20 h 60 v 60 h -60 Z M 30 30 h 40 v 40 h -40 Z\")" should set the property value
+PASS e.style['clip-path'] = "path(nonzero, \"M20,20h60 v60 h-60z M30,30 h40 v40 h-40z\")" should set the property value
+PASS e.style['clip-path'] = "path(\" \")" should set the property value
+PASS e.style['clip-path'] = "path(evenodd, \"\")" should set the property value
 FAIL e.style['clip-path'] = "border-box" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['clip-path'] = "padding-box" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['clip-path'] = "content-box" should set the property value assert_not_equals: property should be set got disallowed value ""