| Index: third_party/WebKit/Source/core/css/cssom/CSSTranslation.cpp
|
| diff --git a/third_party/WebKit/Source/core/css/cssom/CSSTranslation.cpp b/third_party/WebKit/Source/core/css/cssom/CSSTranslation.cpp
|
| index 7948a0d3c782639172897ca405924f8b57fd416a..1df7c3b63a74d4cd739609264a79471cefa64102 100644
|
| --- a/third_party/WebKit/Source/core/css/cssom/CSSTranslation.cpp
|
| +++ b/third_party/WebKit/Source/core/css/cssom/CSSTranslation.cpp
|
| @@ -8,16 +8,98 @@
|
| #include "core/css/CSSPrimitiveValue.h"
|
| #include "core/css/cssom/CSSNumericValue.h"
|
| #include "core/css/cssom/CSSStyleValue.h"
|
| +#include "core/geometry/DOMMatrix.h"
|
|
|
| namespace blink {
|
|
|
| +namespace {
|
| +
|
| +bool IsLengthOrPercent(const CSSNumericValue* value) {
|
| + return (value->GetType() == CSSStyleValue::StyleValueType::kLengthType ||
|
| + value->GetType() == CSSStyleValue::StyleValueType::kPercentType);
|
| +}
|
| +
|
| +bool IsLengthValue(const CSSValue& value) {
|
| + return value.IsPrimitiveValue() && ToCSSPrimitiveValue(value).IsLength();
|
| +}
|
| +
|
| +CSSTranslation* FromCSSTranslate(const CSSFunctionValue& value) {
|
| + DCHECK_GT(value.length(), 0UL);
|
| + DCHECK(IsLengthValue(value.Item(0)));
|
| +
|
| + CSSNumericValue* x =
|
| + CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(0)));
|
| + if (!x)
|
| + return nullptr;
|
| +
|
| + if (value.length() == 1) {
|
| + return CSSTranslation::Create(
|
| + x, CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kPixels));
|
| + }
|
| +
|
| + DCHECK_EQ(value.length(), 2UL);
|
| + DCHECK(IsLengthValue(value.Item(1)));
|
| +
|
| + CSSNumericValue* y =
|
| + CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(1)));
|
| + if (!y)
|
| + return nullptr;
|
| + return CSSTranslation::Create(x, y);
|
| +}
|
| +
|
| +CSSTranslation* FromCSSTranslateXYZ(const CSSFunctionValue& value) {
|
| + DCHECK_EQ(value.length(), 1UL);
|
| + DCHECK(IsLengthValue(value.Item(0)));
|
| +
|
| + CSSNumericValue* length =
|
| + CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(0)));
|
| + if (!length)
|
| + return nullptr;
|
| +
|
| + switch (value.FunctionType()) {
|
| + case CSSValueTranslateX:
|
| + return CSSTranslation::Create(
|
| + length,
|
| + CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kPixels));
|
| + case CSSValueTranslateY:
|
| + return CSSTranslation::Create(
|
| + CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kPixels),
|
| + length);
|
| + case CSSValueTranslateZ:
|
| + return CSSTranslation::Create(
|
| + CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kPixels),
|
| + CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kPixels),
|
| + length);
|
| + default:
|
| + NOTREACHED();
|
| + return nullptr;
|
| + }
|
| +}
|
| +
|
| +CSSTranslation* FromCSSTranslate3D(const CSSFunctionValue& value) {
|
| + DCHECK_EQ(value.length(), 3UL);
|
| + DCHECK(IsLengthValue(value.Item(0)));
|
| + DCHECK(IsLengthValue(value.Item(1)));
|
| + DCHECK(IsLengthValue(value.Item(2)));
|
| +
|
| + CSSNumericValue* x =
|
| + CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(0)));
|
| + CSSNumericValue* y =
|
| + CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(1)));
|
| + CSSNumericValue* z =
|
| + CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(2)));
|
| + if (!x || !y || !z)
|
| + return nullptr;
|
| +
|
| + return CSSTranslation::Create(x, y, z);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| CSSTranslation* CSSTranslation::Create(CSSNumericValue* x,
|
| CSSNumericValue* y,
|
| ExceptionState& exception_state) {
|
| - if ((x->GetType() != CSSStyleValue::StyleValueType::kLengthType &&
|
| - x->GetType() != CSSStyleValue::StyleValueType::kPercentType) ||
|
| - (y->GetType() != CSSStyleValue::StyleValueType::kLengthType &&
|
| - y->GetType() != CSSStyleValue::StyleValueType::kPercentType)) {
|
| + if (!IsLengthOrPercent(x) || !IsLengthOrPercent(y)) {
|
| exception_state.ThrowTypeError(
|
| "Must pass length or percentage to X and Y of CSSTranslation");
|
| return nullptr;
|
| @@ -31,10 +113,7 @@ CSSTranslation* CSSTranslation::Create(CSSNumericValue* x,
|
| CSSNumericValue* y,
|
| CSSNumericValue* z,
|
| ExceptionState& exception_state) {
|
| - if ((x->GetType() != CSSStyleValue::StyleValueType::kLengthType &&
|
| - x->GetType() != CSSStyleValue::StyleValueType::kPercentType) ||
|
| - (y->GetType() != CSSStyleValue::StyleValueType::kLengthType &&
|
| - y->GetType() != CSSStyleValue::StyleValueType::kPercentType)) {
|
| + if (!IsLengthOrPercent(x) || !IsLengthOrPercent(y)) {
|
| exception_state.ThrowTypeError(
|
| "Must pass length or percentage to X and Y of CSSTranslation");
|
| return nullptr;
|
| @@ -51,6 +130,40 @@ CSSTranslation* CSSTranslation::Create(CSSNumericValue* x,
|
| return new CSSTranslation(x, y, z, false /* is2D */);
|
| }
|
|
|
| +CSSTranslation* CSSTranslation::Create(CSSNumericValue* x, CSSNumericValue* y) {
|
| + DCHECK(IsLengthOrPercent(x));
|
| + DCHECK(IsLengthOrPercent(y));
|
| + return new CSSTranslation(
|
| + x, y, CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kPixels),
|
| + true /* is2D */);
|
| +}
|
| +
|
| +CSSTranslation* CSSTranslation::Create(CSSNumericValue* x,
|
| + CSSNumericValue* y,
|
| + CSSNumericValue* z) {
|
| + DCHECK(IsLengthOrPercent(x));
|
| + DCHECK(IsLengthOrPercent(y));
|
| + DCHECK_EQ(z->GetType(), CSSStyleValue::StyleValueType::kLengthType);
|
| + DCHECK(!z->ContainsPercent());
|
| + return new CSSTranslation(x, y, z, false /* is2D */);
|
| +}
|
| +
|
| +CSSTranslation* CSSTranslation::FromCSSValue(const CSSFunctionValue& value) {
|
| + switch (value.FunctionType()) {
|
| + case CSSValueTranslateX:
|
| + case CSSValueTranslateY:
|
| + case CSSValueTranslateZ:
|
| + return FromCSSTranslateXYZ(value);
|
| + case CSSValueTranslate:
|
| + return FromCSSTranslate(value);
|
| + case CSSValueTranslate3d:
|
| + return FromCSSTranslate3D(value);
|
| + default:
|
| + NOTREACHED();
|
| + return nullptr;
|
| + }
|
| +}
|
| +
|
| void CSSTranslation::setX(CSSNumericValue* x, ExceptionState& exception_state) {
|
| if (x->GetType() != CSSStyleValue::StyleValueType::kLengthType &&
|
| x->GetType() != CSSStyleValue::StyleValueType::kPercentType) {
|
| @@ -72,11 +185,11 @@ void CSSTranslation::setY(CSSNumericValue* y, ExceptionState& exception_state) {
|
| }
|
|
|
| void CSSTranslation::setZ(CSSNumericValue* z, ExceptionState& exception_state) {
|
| - if (z && z->GetType() != CSSStyleValue::StyleValueType::kLengthType) {
|
| + if (z->GetType() != CSSStyleValue::StyleValueType::kLengthType) {
|
| exception_state.ThrowTypeError("Must pass length to Z of CSSTranslation");
|
| return;
|
| }
|
| - if (z && z->ContainsPercent()) {
|
| + if (z->ContainsPercent()) {
|
| exception_state.ThrowTypeError(
|
| "CSSTranslation does not support z CSSNumericValue with percent units");
|
| return;
|
| @@ -84,6 +197,20 @@ void CSSTranslation::setZ(CSSNumericValue* z, ExceptionState& exception_state) {
|
| z_ = z;
|
| }
|
|
|
| +DOMMatrix* CSSTranslation::AsMatrix() const {
|
| + CSSUnitValue* x = x_->to(CSSPrimitiveValue::UnitType::kPixels);
|
| + CSSUnitValue* y = y_->to(CSSPrimitiveValue::UnitType::kPixels);
|
| + CSSUnitValue* z = z_->to(CSSPrimitiveValue::UnitType::kPixels);
|
| + // TODO(meade): What should happen when the translation contains relative
|
| + // lengths here?
|
| + // https://github.com/w3c/css-houdini-drafts/issues/421
|
| + if (!x || !y || !z)
|
| + return nullptr;
|
| +
|
| + DOMMatrix* matrix = DOMMatrix::Create();
|
| + return matrix->translate(x->value(), y->value(), z->value());
|
| +}
|
| +
|
| CSSFunctionValue* CSSTranslation::ToCSSValue() const {
|
| CSSFunctionValue* result = CSSFunctionValue::Create(
|
| is2D() ? CSSValueTranslate : CSSValueTranslate3d);
|
|
|