mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibWeb/CSS: Implement CSSSkew
Equivalent to the skew() transform function. +39 WPT subtests.
This commit is contained in:
parent
456946368e
commit
161e384521
|
|
@ -138,6 +138,7 @@ set(SOURCES
|
|||
CSS/CSSRule.cpp
|
||||
CSS/CSSRuleList.cpp
|
||||
CSS/CSSScale.cpp
|
||||
CSS/CSSSkew.cpp
|
||||
CSS/CSSStyleDeclaration.cpp
|
||||
CSS/CSSStyleProperties.cpp
|
||||
CSS/CSSStyleRule.cpp
|
||||
|
|
|
|||
139
Libraries/LibWeb/CSS/CSSSkew.cpp
Normal file
139
Libraries/LibWeb/CSS/CSSSkew.cpp
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "CSSSkew.h"
|
||||
#include <LibWeb/Bindings/CSSSkewPrototype.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/CSS/CSSNumericValue.h>
|
||||
#include <LibWeb/CSS/CSSUnitValue.h>
|
||||
#include <LibWeb/Geometry/DOMMatrix.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(CSSSkew);
|
||||
|
||||
GC::Ref<CSSSkew> CSSSkew::create(JS::Realm& realm, GC::Ref<CSSNumericValue> ax, GC::Ref<CSSNumericValue> ay)
|
||||
{
|
||||
return realm.create<CSSSkew>(realm, ax, ay);
|
||||
}
|
||||
|
||||
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssskew-cssskew
|
||||
WebIDL::ExceptionOr<GC::Ref<CSSSkew>> CSSSkew::construct_impl(JS::Realm& realm, GC::Ref<CSSNumericValue> ax, GC::Ref<CSSNumericValue> ay)
|
||||
{
|
||||
// The CSSSkew(ax, ay) constructor must, when invoked, perform the following steps:
|
||||
|
||||
// 1. If ax or ay do not match <angle>, throw a TypeError.
|
||||
if (!ax->type().matches_angle({}))
|
||||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "CSSSkew ax component doesn't match <angle>"sv };
|
||||
if (!ay->type().matches_angle({}))
|
||||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "CSSSkew ay component doesn't match <angle>"sv };
|
||||
|
||||
// 2. Return a new CSSSkew object with its ax and ay internal slots set to ax and ay, and its is2D internal slot
|
||||
// set to true.
|
||||
return CSSSkew::create(realm, ax, ay);
|
||||
}
|
||||
|
||||
CSSSkew::CSSSkew(JS::Realm& realm, GC::Ref<CSSNumericValue> ax, GC::Ref<CSSNumericValue> ay)
|
||||
: CSSTransformComponent(realm, Is2D::Yes)
|
||||
, m_ax(ax)
|
||||
, m_ay(ay)
|
||||
{
|
||||
}
|
||||
|
||||
CSSSkew::~CSSSkew() = default;
|
||||
|
||||
void CSSSkew::initialize(JS::Realm& realm)
|
||||
{
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSSkew);
|
||||
Base::initialize(realm);
|
||||
}
|
||||
|
||||
void CSSSkew::visit_edges(Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_ax);
|
||||
visitor.visit(m_ay);
|
||||
}
|
||||
|
||||
// https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssskew
|
||||
WebIDL::ExceptionOr<Utf16String> CSSSkew::to_string() const
|
||||
{
|
||||
// 1. Let s initially be "skew(".
|
||||
StringBuilder builder { StringBuilder::Mode::UTF16 };
|
||||
builder.append("skew("sv);
|
||||
|
||||
// 2. Serialize this’s ax internal slot, and append it to s.
|
||||
builder.append(m_ax->to_string());
|
||||
|
||||
// 3. If this’s ay internal slot is a CSSUnitValue with a value of 0, then append ")" to s and return s.
|
||||
if (auto* ay_unit_value = as_if<CSSUnitValue>(*m_ay); ay_unit_value && ay_unit_value->value() == 0) {
|
||||
builder.append(")"sv);
|
||||
return builder.to_utf16_string();
|
||||
}
|
||||
|
||||
// 4. Otherwise, append ", " to s.
|
||||
builder.append(", "sv);
|
||||
|
||||
// 5. Serialize this’s ay internal slot, and append it to s.
|
||||
builder.append(m_ay->to_string());
|
||||
|
||||
// 6. Append ")" to s, and return s.
|
||||
builder.append(")"sv);
|
||||
return builder.to_utf16_string();
|
||||
}
|
||||
|
||||
// https://drafts.css-houdini.org/css-typed-om-1/#dom-csstransformcomponent-tomatrix
|
||||
WebIDL::ExceptionOr<GC::Ref<Geometry::DOMMatrix>> CSSSkew::to_matrix() const
|
||||
{
|
||||
// 1. Let matrix be a new DOMMatrix object, initialized to this’s equivalent 4x4 transform matrix, as defined in
|
||||
// CSS Transforms 1 § 12. Mathematical Description of Transform Functions, and with its is2D internal slot set
|
||||
// to the same value as this’s is2D internal slot.
|
||||
// NOTE: Recall that the is2D flag affects what transform, and thus what equivalent matrix, a
|
||||
// CSSTransformComponent represents.
|
||||
// As the entries of such a matrix are defined relative to the px unit, if any <length>s in this involved in
|
||||
// generating the matrix are not compatible units with px (such as relative lengths or percentages), throw a
|
||||
// TypeError.
|
||||
auto matrix = Geometry::DOMMatrix::create(realm());
|
||||
|
||||
// NB: to() throws a TypeError if the conversion can't be done.
|
||||
auto ax_rad = TRY(m_ax->to("rad"_fly_string))->value();
|
||||
auto ay_rad = TRY(m_ay->to("rad"_fly_string))->value();
|
||||
|
||||
matrix->set_m21(tanf(ax_rad));
|
||||
matrix->set_m12(tanf(ay_rad));
|
||||
|
||||
// 2. Return matrix.
|
||||
return matrix;
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> CSSSkew::set_ax(GC::Ref<CSSNumericValue> ax)
|
||||
{
|
||||
// AD-HOC: Not specced. https://github.com/w3c/css-houdini-drafts/issues/1153
|
||||
// WPT expects this to throw for invalid values.
|
||||
if (!ax->type().matches_angle({}))
|
||||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "CSSSkew ax component doesn't match <angle>"sv };
|
||||
m_ax = ax;
|
||||
return {};
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> CSSSkew::set_ay(GC::Ref<CSSNumericValue> ay)
|
||||
{
|
||||
// AD-HOC: Not specced. https://github.com/w3c/css-houdini-drafts/issues/1153
|
||||
// WPT expects this to throw for invalid values.
|
||||
if (!ay->type().matches_angle({}))
|
||||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "CSSSkew ay component doesn't match <angle>"sv };
|
||||
m_ay = ay;
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssskew-is2d
|
||||
void CSSSkew::set_is_2d(bool)
|
||||
{
|
||||
// The is2D attribute of a CSSSkew, CSSSkewX, or CSSSkewY object must, on setting, do nothing.
|
||||
}
|
||||
|
||||
}
|
||||
45
Libraries/LibWeb/CSS/CSSSkew.h
Normal file
45
Libraries/LibWeb/CSS/CSSSkew.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/CSS/CSSTransformComponent.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
// https://drafts.css-houdini.org/css-typed-om-1/#cssskew
|
||||
class CSSSkew final : public CSSTransformComponent {
|
||||
WEB_PLATFORM_OBJECT(CSSSkew, CSSTransformComponent);
|
||||
GC_DECLARE_ALLOCATOR(CSSSkew);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<CSSSkew> create(JS::Realm&, GC::Ref<CSSNumericValue> ax, GC::Ref<CSSNumericValue> ay);
|
||||
static WebIDL::ExceptionOr<GC::Ref<CSSSkew>> construct_impl(JS::Realm&, GC::Ref<CSSNumericValue> ax, GC::Ref<CSSNumericValue> ay);
|
||||
|
||||
virtual ~CSSSkew() override;
|
||||
|
||||
virtual WebIDL::ExceptionOr<Utf16String> to_string() const override;
|
||||
|
||||
virtual WebIDL::ExceptionOr<GC::Ref<Geometry::DOMMatrix>> to_matrix() const override;
|
||||
|
||||
GC::Ref<CSSNumericValue> ax() const { return m_ax; }
|
||||
GC::Ref<CSSNumericValue> ay() const { return m_ay; }
|
||||
WebIDL::ExceptionOr<void> set_ax(GC::Ref<CSSNumericValue> value);
|
||||
WebIDL::ExceptionOr<void> set_ay(GC::Ref<CSSNumericValue> value);
|
||||
|
||||
virtual void set_is_2d(bool value) override;
|
||||
|
||||
private:
|
||||
explicit CSSSkew(JS::Realm&, GC::Ref<CSSNumericValue> ax, GC::Ref<CSSNumericValue> ay);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
GC::Ref<CSSNumericValue> m_ax;
|
||||
GC::Ref<CSSNumericValue> m_ay;
|
||||
};
|
||||
|
||||
}
|
||||
10
Libraries/LibWeb/CSS/CSSSkew.idl
Normal file
10
Libraries/LibWeb/CSS/CSSSkew.idl
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#import <CSS/CSSNumericValue.idl>
|
||||
#import <CSS/CSSTransformComponent.idl>
|
||||
|
||||
// https://drafts.css-houdini.org/css-typed-om-1/#cssskew
|
||||
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
|
||||
interface CSSSkew : CSSTransformComponent {
|
||||
constructor(CSSNumericValue ax, CSSNumericValue ay);
|
||||
attribute CSSNumericValue ax;
|
||||
attribute CSSNumericValue ay;
|
||||
};
|
||||
|
|
@ -263,6 +263,7 @@ class CSSRotate;
|
|||
class CSSRule;
|
||||
class CSSRuleList;
|
||||
class CSSScale;
|
||||
class CSSSkew;
|
||||
class CSSStyleDeclaration;
|
||||
class CSSStyleProperties;
|
||||
class CSSStyleRule;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ libweb_js_bindings(CSS/CSSRotate)
|
|||
libweb_js_bindings(CSS/CSSRule)
|
||||
libweb_js_bindings(CSS/CSSRuleList)
|
||||
libweb_js_bindings(CSS/CSSScale)
|
||||
libweb_js_bindings(CSS/CSSSkew)
|
||||
libweb_js_bindings(CSS/CSSStyleDeclaration)
|
||||
libweb_js_bindings(CSS/CSSStyleProperties)
|
||||
libweb_js_bindings(CSS/CSSStyleRule)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ CSSRotate
|
|||
CSSRule
|
||||
CSSRuleList
|
||||
CSSScale
|
||||
CSSSkew
|
||||
CSSStyleDeclaration
|
||||
CSSStyleProperties
|
||||
CSSStyleRule
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ Harness status: OK
|
|||
|
||||
Found 545 tests
|
||||
|
||||
324 Pass
|
||||
221 Fail
|
||||
332 Pass
|
||||
213 Fail
|
||||
Pass idl_test setup
|
||||
Pass idl_test validation
|
||||
Pass Partial interface Element: original interface defined
|
||||
|
|
@ -326,14 +326,14 @@ Fail CSSScale interface: scale must inherit property "y" with the proper type
|
|||
Fail CSSScale interface: scale must inherit property "z" with the proper type
|
||||
Fail CSSTransformComponent interface: scale must inherit property "is2D" with the proper type
|
||||
Fail CSSTransformComponent interface: scale must inherit property "toMatrix()" with the proper type
|
||||
Fail CSSSkew interface: existence and properties of interface object
|
||||
Fail CSSSkew interface object length
|
||||
Fail CSSSkew interface object name
|
||||
Fail CSSSkew interface: existence and properties of interface prototype object
|
||||
Fail CSSSkew interface: existence and properties of interface prototype object's "constructor" property
|
||||
Fail CSSSkew interface: existence and properties of interface prototype object's @@unscopables property
|
||||
Fail CSSSkew interface: attribute ax
|
||||
Fail CSSSkew interface: attribute ay
|
||||
Pass CSSSkew interface: existence and properties of interface object
|
||||
Pass CSSSkew interface object length
|
||||
Pass CSSSkew interface object name
|
||||
Pass CSSSkew interface: existence and properties of interface prototype object
|
||||
Pass CSSSkew interface: existence and properties of interface prototype object's "constructor" property
|
||||
Pass CSSSkew interface: existence and properties of interface prototype object's @@unscopables property
|
||||
Pass CSSSkew interface: attribute ax
|
||||
Pass CSSSkew interface: attribute ay
|
||||
Fail CSSSkew must be primary interface of skew
|
||||
Fail Stringification of skew
|
||||
Fail CSSSkew interface: skew must inherit property "ax" with the proper type
|
||||
|
|
|
|||
|
|
@ -2,34 +2,34 @@ Harness status: OK
|
|||
|
||||
Found 30 tests
|
||||
|
||||
30 Fail
|
||||
Fail Constructing a CSSSkew with a keyword throws a TypeError
|
||||
Fail Constructing a CSSSkew with a double throws a TypeError
|
||||
Fail Constructing a CSSSkew with a unitless zero throws a TypeError
|
||||
Fail Constructing a CSSSkew with a string angle throws a TypeError
|
||||
Fail Constructing a CSSSkew with a number CSSUnitValue throws a TypeError
|
||||
Fail Constructing a CSSSkew with a time dimension CSSUnitValue throws a TypeError
|
||||
Fail Constructing a CSSSkew with a CSSMathValue of length type throws a TypeError
|
||||
Fail Updating CSSSkew.ax with a keyword throws a TypeError
|
||||
Fail Updating CSSSkew.ax with a double throws a TypeError
|
||||
Fail Updating CSSSkew.ax with a unitless zero throws a TypeError
|
||||
Fail Updating CSSSkew.ax with a string angle throws a TypeError
|
||||
Fail Updating CSSSkew.ax with a number CSSUnitValue throws a TypeError
|
||||
Fail Updating CSSSkew.ax with a time dimension CSSUnitValue throws a TypeError
|
||||
Fail Updating CSSSkew.ax with a CSSMathValue of length type throws a TypeError
|
||||
Fail Updating CSSSkew.ay with a keyword throws a TypeError
|
||||
Fail Updating CSSSkew.ay with a double throws a TypeError
|
||||
Fail Updating CSSSkew.ay with a unitless zero throws a TypeError
|
||||
Fail Updating CSSSkew.ay with a string angle throws a TypeError
|
||||
Fail Updating CSSSkew.ay with a number CSSUnitValue throws a TypeError
|
||||
Fail Updating CSSSkew.ay with a time dimension CSSUnitValue throws a TypeError
|
||||
Fail Updating CSSSkew.ay with a CSSMathValue of length type throws a TypeError
|
||||
Fail CSSSkew can be constructed from an angle CSSUnitValue and an angle CSSUnitValue
|
||||
Fail CSSSkew can be constructed from an angle CSSUnitValue and a CSSMathValue of angle type
|
||||
Fail CSSSkew can be constructed from a CSSMathValue of angle type and an angle CSSUnitValue
|
||||
Fail CSSSkew can be constructed from a CSSMathValue of angle type and a CSSMathValue of angle type
|
||||
Fail CSSSkew.ax can be updated to an angle CSSUnitValue
|
||||
Fail CSSSkew.ax can be updated to a CSSMathValue of angle type
|
||||
Fail CSSSkew.ay can be updated to an angle CSSUnitValue
|
||||
Fail CSSSkew.ay can be updated to a CSSMathValue of angle type
|
||||
Fail Modifying CSSSkew.is2D is a no-op
|
||||
30 Pass
|
||||
Pass Constructing a CSSSkew with a keyword throws a TypeError
|
||||
Pass Constructing a CSSSkew with a double throws a TypeError
|
||||
Pass Constructing a CSSSkew with a unitless zero throws a TypeError
|
||||
Pass Constructing a CSSSkew with a string angle throws a TypeError
|
||||
Pass Constructing a CSSSkew with a number CSSUnitValue throws a TypeError
|
||||
Pass Constructing a CSSSkew with a time dimension CSSUnitValue throws a TypeError
|
||||
Pass Constructing a CSSSkew with a CSSMathValue of length type throws a TypeError
|
||||
Pass Updating CSSSkew.ax with a keyword throws a TypeError
|
||||
Pass Updating CSSSkew.ax with a double throws a TypeError
|
||||
Pass Updating CSSSkew.ax with a unitless zero throws a TypeError
|
||||
Pass Updating CSSSkew.ax with a string angle throws a TypeError
|
||||
Pass Updating CSSSkew.ax with a number CSSUnitValue throws a TypeError
|
||||
Pass Updating CSSSkew.ax with a time dimension CSSUnitValue throws a TypeError
|
||||
Pass Updating CSSSkew.ax with a CSSMathValue of length type throws a TypeError
|
||||
Pass Updating CSSSkew.ay with a keyword throws a TypeError
|
||||
Pass Updating CSSSkew.ay with a double throws a TypeError
|
||||
Pass Updating CSSSkew.ay with a unitless zero throws a TypeError
|
||||
Pass Updating CSSSkew.ay with a string angle throws a TypeError
|
||||
Pass Updating CSSSkew.ay with a number CSSUnitValue throws a TypeError
|
||||
Pass Updating CSSSkew.ay with a time dimension CSSUnitValue throws a TypeError
|
||||
Pass Updating CSSSkew.ay with a CSSMathValue of length type throws a TypeError
|
||||
Pass CSSSkew can be constructed from an angle CSSUnitValue and an angle CSSUnitValue
|
||||
Pass CSSSkew can be constructed from an angle CSSUnitValue and a CSSMathValue of angle type
|
||||
Pass CSSSkew can be constructed from a CSSMathValue of angle type and an angle CSSUnitValue
|
||||
Pass CSSSkew can be constructed from a CSSMathValue of angle type and a CSSMathValue of angle type
|
||||
Pass CSSSkew.ax can be updated to an angle CSSUnitValue
|
||||
Pass CSSSkew.ax can be updated to a CSSMathValue of angle type
|
||||
Pass CSSSkew.ay can be updated to an angle CSSUnitValue
|
||||
Pass CSSSkew.ay can be updated to a CSSMathValue of angle type
|
||||
Pass Modifying CSSSkew.is2D is a no-op
|
||||
|
|
@ -2,12 +2,12 @@ Harness status: OK
|
|||
|
||||
Found 8 tests
|
||||
|
||||
3 Pass
|
||||
5 Fail
|
||||
4 Pass
|
||||
4 Fail
|
||||
Pass CSSTranslate.toMatrix() returns correct matrix
|
||||
Pass CSSRotate.toMatrix() returns correct matrix
|
||||
Pass CSSScale.toMatrix() returns correct matrix
|
||||
Fail CSSSkew.toMatrix() returns correct matrix
|
||||
Pass CSSSkew.toMatrix() returns correct matrix
|
||||
Fail CSSSkewX.toMatrix() returns correct matrix
|
||||
Fail CSSSkewY.toMatrix() returns correct matrix
|
||||
Fail CSSPerspective.toMatrix() returns correct matrix
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user