diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/Geometry/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibWeb/Geometry/BUILD.gn index b30b84f2834..38fef51294c 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/Geometry/BUILD.gn +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/Geometry/BUILD.gn @@ -6,6 +6,7 @@ source_set("Geometry") { "DOMMatrixReadOnly.cpp", "DOMPoint.cpp", "DOMPointReadOnly.cpp", + "DOMQuad.cpp", "DOMRect.cpp", "DOMRectList.cpp", "DOMRectReadOnly.cpp", diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni b/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni index ae24b2fd683..94ea9265558 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni @@ -85,6 +85,7 @@ standard_idl_files = [ "//Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl", "//Userland/Libraries/LibWeb/Geometry/DOMPoint.idl", "//Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.idl", + "//Userland/Libraries/LibWeb/Geometry/DOMQuad.idl", "//Userland/Libraries/LibWeb/Geometry/DOMRect.idl", "//Userland/Libraries/LibWeb/Geometry/DOMRectList.idl", "//Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.idl", diff --git a/Tests/LibWeb/Text/expected/geometry/domquad.txt b/Tests/LibWeb/Text/expected/geometry/domquad.txt new file mode 100644 index 00000000000..cdabfafbaed --- /dev/null +++ b/Tests/LibWeb/Text/expected/geometry/domquad.txt @@ -0,0 +1,4 @@ +1. {"p1":{"x":0,"y":0,"z":0,"w":1},"p2":{"x":100,"y":0,"z":0,"w":1},"p3":{"x":100,"y":100,"z":0,"w":1},"p4":{"x":0,"y":100,"z":0,"w":1}} +2. {"p1":{"x":0,"y":0,"z":0,"w":1},"p2":{"x":100,"y":0,"z":0,"w":1},"p3":{"x":100,"y":100,"z":0,"w":1},"p4":{"x":0,"y":100,"z":0,"w":1}} +3. {"p1":{"x":0,"y":0,"z":0,"w":1},"p2":{"x":100,"y":0,"z":0,"w":1},"p3":{"x":100,"y":100,"z":0,"w":1},"p4":{"x":0,"y":100,"z":0,"w":1}} +4. {"x":0,"y":0,"width":100,"height":100,"top":0,"right":100,"bottom":100,"left":0} diff --git a/Tests/LibWeb/Text/input/geometry/domquad.html b/Tests/LibWeb/Text/input/geometry/domquad.html new file mode 100644 index 00000000000..c8c4ddc6807 --- /dev/null +++ b/Tests/LibWeb/Text/input/geometry/domquad.html @@ -0,0 +1,36 @@ + + diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 805b473b84a..138e169f342 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -222,6 +222,7 @@ set(SOURCES Geometry/DOMMatrixReadOnly.cpp Geometry/DOMPoint.cpp Geometry/DOMPointReadOnly.cpp + Geometry/DOMQuad.cpp Geometry/DOMRect.cpp Geometry/DOMRectList.cpp Geometry/DOMRectReadOnly.cpp diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index f905f2cfb81..44332d29093 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -302,6 +302,7 @@ class DOMMatrix; class DOMMatrixReadOnly; class DOMPoint; class DOMPointReadOnly; +class DOMQuad; class DOMRect; class DOMRectList; class DOMRectReadOnly; diff --git a/Userland/Libraries/LibWeb/Geometry/DOMQuad.cpp b/Userland/Libraries/LibWeb/Geometry/DOMQuad.cpp new file mode 100644 index 00000000000..d5d59ec6bca --- /dev/null +++ b/Userland/Libraries/LibWeb/Geometry/DOMQuad.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2023, Bastiaan van der Plaat + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Web::Geometry { + +JS::NonnullGCPtr DOMQuad::construct_impl(JS::Realm& realm, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4) +{ + return realm.heap().allocate(realm, realm, p1, p2, p3, p4); +} + +DOMQuad::DOMQuad(JS::Realm& realm, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4) + : PlatformObject(realm) + , m_p1(DOMPoint::from_point(realm.vm(), p1)) + , m_p2(DOMPoint::from_point(realm.vm(), p2)) + , m_p3(DOMPoint::from_point(realm.vm(), p3)) + , m_p4(DOMPoint::from_point(realm.vm(), p4)) +{ +} + +DOMQuad::~DOMQuad() = default; + +// https://drafts.fxtf.org/geometry/#dom-domquad-fromrect +JS::NonnullGCPtr DOMQuad::from_rect(JS::VM& vm, DOMRectInit const& other) +{ + // The fromRect(other) static method on DOMQuad must create a DOMQuad from the DOMRectInit dictionary other. + return construct_impl(*vm.current_realm(), { other.x, other.y }, + { other.x + other.width, other.y }, + { other.x + other.width, other.y + other.height }, + { other.x, other.y + other.height }); +} + +// https://drafts.fxtf.org/geometry/#dom-domquad-fromquad +JS::NonnullGCPtr DOMQuad::from_quad(JS::VM& vm, DOMQuadInit const& other) +{ + // The fromQuad(other) static method on DOMQuad must create a DOMQuad from the DOMQuadInit dictionary other. + return construct_impl(*vm.current_realm(), other.p1, other.p2, other.p3, other.p4); +} + +// https://drafts.fxtf.org/geometry/#dom-domquad-getbounds +JS::NonnullGCPtr DOMQuad::get_bounds() const +{ + // 1. Let bounds be a DOMRect object. + auto bounds = DOMRect::create(realm(), {}); + + // 2. Let left be the NaN-safe minimum of point 1’s x coordinate, point 2’s x coordinate, point 3’s x coordinate and point 4’s x coordinate. + auto left = min(m_p1->x(), min(m_p2->x(), min(m_p3->x(), m_p4->x()))); + + // 3. Let top be the NaN-safe minimum of point 1’s y coordinate, point 2’s y coordinate, point 3’s y coordinate and point 4’s y coordinate. + auto top = min(m_p1->y(), min(m_p2->y(), min(m_p3->y(), m_p4->y()))); + + // 4. Let right be the NaN-safe maximum of point 1’s x coordinate, point 2’s x coordinate, point 3’s x coordinate and point 4’s x coordinate. + auto right = max(m_p1->x(), max(m_p2->x(), max(m_p3->x(), m_p4->x()))); + + // 5. Let bottom be the NaN-safe maximum of point 1’s y coordinate, point 2’s y coordinate, point 3’s y coordinate and point 4’s y coordinate. + auto bottom = max(m_p1->y(), max(m_p2->y(), max(m_p3->y(), m_p4->y()))); + + // 6. Set x coordinate of bounds to left, y coordinate of bounds to top, width dimension of bounds to right - left and height dimension of bounds to bottom - top. + bounds->set_x(left); + bounds->set_y(top); + bounds->set_width(right - left); + bounds->set_height(bottom - top); + + // 7. Return bounds. + return bounds; +} + +void DOMQuad::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + set_prototype(&Bindings::ensure_web_prototype(realm, "DOMQuad")); +} + +void DOMQuad::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_p1.ptr()); + visitor.visit(m_p2.ptr()); + visitor.visit(m_p3.ptr()); + visitor.visit(m_p4.ptr()); +} + +} diff --git a/Userland/Libraries/LibWeb/Geometry/DOMQuad.h b/Userland/Libraries/LibWeb/Geometry/DOMQuad.h new file mode 100644 index 00000000000..33df0bfae98 --- /dev/null +++ b/Userland/Libraries/LibWeb/Geometry/DOMQuad.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023, Bastiaan van der Plaat + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace Web::Geometry { + +// https://drafts.fxtf.org/geometry/#dictdef-domquadinit +struct DOMQuadInit { + DOMPointInit p1; + DOMPointInit p2; + DOMPointInit p3; + DOMPointInit p4; +}; + +// https://drafts.fxtf.org/geometry/#domquad +class DOMQuad : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(DOMQuad, Bindings::PlatformObject); + +public: + static JS::NonnullGCPtr construct_impl(JS::Realm&, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4); + + virtual ~DOMQuad() override; + + static JS::NonnullGCPtr from_rect(JS::VM&, DOMRectInit const&); + static JS::NonnullGCPtr from_quad(JS::VM&, DOMQuadInit const&); + + JS::NonnullGCPtr p1() const { return m_p1; } + JS::NonnullGCPtr p2() const { return m_p2; } + JS::NonnullGCPtr p3() const { return m_p3; } + JS::NonnullGCPtr p4() const { return m_p4; } + + JS::NonnullGCPtr get_bounds() const; + +private: + DOMQuad(JS::Realm&, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4); + + virtual void initialize(JS::Realm&) override; + virtual void visit_edges(Cell::Visitor&) override; + + JS::NonnullGCPtr m_p1; + JS::NonnullGCPtr m_p2; + JS::NonnullGCPtr m_p3; + JS::NonnullGCPtr m_p4; +}; + +} diff --git a/Userland/Libraries/LibWeb/Geometry/DOMQuad.idl b/Userland/Libraries/LibWeb/Geometry/DOMQuad.idl new file mode 100644 index 00000000000..78018da940d --- /dev/null +++ b/Userland/Libraries/LibWeb/Geometry/DOMQuad.idl @@ -0,0 +1,28 @@ +#import +#import + +// https://drafts.fxtf.org/geometry/#domquad +[Exposed=(Window,Worker), Serializable] +interface DOMQuad { + constructor(optional DOMPointInit p1 = {}, optional DOMPointInit p2 = {}, + optional DOMPointInit p3 = {}, optional DOMPointInit p4 = {}); + + [NewObject] static DOMQuad fromRect(optional DOMRectInit other = {}); + [NewObject] static DOMQuad fromQuad(optional DOMQuadInit other = {}); + + [SameObject] readonly attribute DOMPoint p1; + [SameObject] readonly attribute DOMPoint p2; + [SameObject] readonly attribute DOMPoint p3; + [SameObject] readonly attribute DOMPoint p4; + [NewObject] DOMRect getBounds(); + + [Default] object toJSON(); +}; + +// https://drafts.fxtf.org/geometry/#dictdef-domquadinit +dictionary DOMQuadInit { + DOMPointInit p1; + DOMPointInit p2; + DOMPointInit p3; + DOMPointInit p4; +}; diff --git a/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.idl b/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.idl index aa4da63178c..5f1f881a99b 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.idl @@ -16,6 +16,8 @@ interface DOMRectReadOnly { readonly attribute double bottom; readonly attribute double left; + [Default] object toJSON(); + }; dictionary DOMRectInit { diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 0bdb3ea6897..67ef6ac2968 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -71,6 +71,7 @@ libweb_js_bindings(Geometry/DOMMatrix) libweb_js_bindings(Geometry/DOMMatrixReadOnly) libweb_js_bindings(Geometry/DOMPoint) libweb_js_bindings(Geometry/DOMPointReadOnly) +libweb_js_bindings(Geometry/DOMQuad) libweb_js_bindings(Geometry/DOMRect) libweb_js_bindings(Geometry/DOMRectList) libweb_js_bindings(Geometry/DOMRectReadOnly)