Bug 1408310 - Part 5: Use Servo CSS parser for DOMMatrix on Stylo. draft
authorBoris Chiou <boris.chiou@gmail.com>
Mon, 27 Nov 2017 14:27:56 +0800
changeset 703608 97723086e40fcf30131506ba8847180eacec730d
parent 703607 50ef50b6abd05a753e5d6432e89341d8d56c0d9d
child 741834 74df5d02e8e75fb9dfc0b13b3328531c66b453e2
push id90886
push userbmo:boris.chiou@gmail.com
push dateMon, 27 Nov 2017 07:09:53 +0000
bugs1408310
milestone59.0a1
Bug 1408310 - Part 5: Use Servo CSS parser for DOMMatrix on Stylo. We convert a _simplified_ specified transform list into a gfx matrix by Servo backend. The _simplified_ means DOMMatrix only accepts a transform list without any relative lengths, percentage, or other keywords; otherwise, we throw a SyntaxError DOMException. MozReview-Commit-ID: K8d30W0i60b
dom/base/DOMMatrix.cpp
layout/style/ServoBindingList.h
testing/web-platform/meta/css/geometry/DOMMatrix-001.html.ini
--- a/dom/base/DOMMatrix.cpp
+++ b/dom/base/DOMMatrix.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/dom/DOMMatrix.h"
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/DOMMatrixBinding.h"
 #include "mozilla/dom/DOMPoint.h"
 #include "mozilla/dom/DOMPointBinding.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/ToJSValue.h"
+#include "mozilla/ServoBindings.h"
 #include "nsCSSParser.h"
 #include "nsStyleTransformMatrix.h"
 
 #include <math.h>
 
 namespace mozilla {
 namespace dom {
 
@@ -667,48 +668,59 @@ DOMMatrix::InvertSelf()
 DOMMatrix*
 DOMMatrix::SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv)
 {
   // An empty string is a no-op.
   if (aTransformList.IsEmpty()) {
     return this;
   }
 
-  nsCSSValue value;
-  nsCSSParser parser;
-  bool parseSuccess = parser.ParseTransformProperty(aTransformList,
-                                                    true,
-                                                    value);
-  if (!parseSuccess) {
-    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-    return nullptr;
-  }
+  gfx::Matrix4x4 transform;
+  bool contains3dTransform = false;
+  if (mIsServo) {
+    bool status = Servo_ParseTransformIntoMatrix(&aTransformList,
+                                                 &contains3dTransform,
+                                                 &transform.components);
+    if (!status) {
+      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+      return nullptr;
+    }
+  } else {
+    nsCSSValue value;
+    nsCSSParser parser;
+    bool parseSuccess = parser.ParseTransformProperty(aTransformList,
+                                                      true,
+                                                      value);
+    if (!parseSuccess) {
+      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+      return nullptr;
+    }
 
-  // A value of "none" results in a 2D identity matrix.
-  if (value.GetUnit() == eCSSUnit_None) {
-    mMatrix3D = nullptr;
-    mMatrix2D = new gfx::Matrix();
-    return this;
+    // A value of "none" results in a 2D identity matrix.
+    if (value.GetUnit() == eCSSUnit_None) {
+      mMatrix3D = nullptr;
+      mMatrix2D = new gfx::Matrix();
+      return this;
+    }
+
+    // A value other than a transform-list is a syntax error.
+    if (value.GetUnit() != eCSSUnit_SharedList) {
+      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+      return nullptr;
+    }
+
+    RuleNodeCacheConditions dummy;
+    nsStyleTransformMatrix::TransformReferenceBox dummyBox;
+    transform = nsStyleTransformMatrix::ReadTransforms(
+                    value.GetSharedListValue()->mHead,
+                    nullptr, nullptr, dummy, dummyBox,
+                    nsPresContext::AppUnitsPerCSSPixel(),
+                    &contains3dTransform);
   }
 
-  // A value other than a transform-list is a syntax error.
-  if (value.GetUnit() != eCSSUnit_SharedList) {
-    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-    return nullptr;
-  }
-
-  RuleNodeCacheConditions dummy;
-  nsStyleTransformMatrix::TransformReferenceBox dummyBox;
-  bool contains3dTransform = false;
-  gfx::Matrix4x4 transform = nsStyleTransformMatrix::ReadTransforms(
-                               value.GetSharedListValue()->mHead,
-                               nullptr, nullptr, dummy, dummyBox,
-                               nsPresContext::AppUnitsPerCSSPixel(),
-                               &contains3dTransform);
-
   if (!contains3dTransform) {
     mMatrix3D = nullptr;
     mMatrix2D = new gfx::Matrix();
 
     SetA(transform._11);
     SetB(transform._12);
     SetC(transform._21);
     SetD(transform._22);
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -743,15 +743,22 @@ SERVO_BINDING_FUNC(Servo_IsValidCSSColor
 SERVO_BINDING_FUNC(Servo_ComputeColor, bool,
                    RawServoStyleSetBorrowedOrNull set,
                    nscolor current_color,
                    const nsAString* value,
                    nscolor* result_color);
 SERVO_BINDING_FUNC(Servo_ParseIntersectionObserverRootMargin, bool,
                    const nsAString* value,
                    nsCSSRect* result);
+// Returning false means the parsed transform contains relative lengths or
+// percentage value, so we cannot compute the matrix. In this case, we keep
+// |result| and |contains_3d_transform| as-is.
+SERVO_BINDING_FUNC(Servo_ParseTransformIntoMatrix, bool,
+                   const nsAString* value,
+                   bool* contains_3d_transform,
+                   RawGeckoGfxMatrix4x4* result);
 
 // AddRef / Release functions
 #define SERVO_ARC_TYPE(name_, type_)                                \
   SERVO_BINDING_FUNC(Servo_##name_##_AddRef, void, type_##Borrowed) \
   SERVO_BINDING_FUNC(Servo_##name_##_Release, void, type_##Borrowed)
 #include "mozilla/ServoArcTypeList.h"
 #undef SERVO_ARC_TYPE
--- a/testing/web-platform/meta/css/geometry/DOMMatrix-001.html.ini
+++ b/testing/web-platform/meta/css/geometry/DOMMatrix-001.html.ini
@@ -197,17 +197,19 @@
 
   [new DOMMatrixReadOnly(matrix)]
     expected: FAIL
 
   [new DOMMatrixReadOnly("scale(2, 2), translateX(5px) translateY(5px)")]
     expected: FAIL
 
   [new DOMMatrix("scale(2) translateX(calc(2 * 2.5px)) translateY(5px)")]
-    expected: FAIL
+    expected:
+      if stylo: PASS
+      FAIL
 
   [new DOMMatrix("scale(2) translateX(5px) translateY(5px) rotate(5deg) rotate(-5deg)")]
     expected: FAIL
 
   [new DOMMatrixReadOnly("scale(2, 2) translateX(5px) translateY(5px)")]
     expected: FAIL
 
   [new DOMMatrixReadOnly("scale(2)translateX(5px)translateY(5px)")]