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
--- 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)")]