diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index c8ec1861e0..9931d02f08 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -137,7 +137,9 @@ set(SOURCES FontCache.cpp Geometry/DOMPoint.cpp Geometry/DOMPointReadOnly.cpp + Geometry/DOMRect.cpp Geometry/DOMRectList.cpp + Geometry/DOMRectReadOnly.cpp HTML/AttributeNames.cpp HTML/BrowsingContext.cpp HTML/BrowsingContextContainer.cpp diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index b289ad903c..18e3cb7884 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -561,7 +561,7 @@ bool Element::serializes_as_void() const } // https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect -NonnullRefPtr Element::get_bounding_client_rect() const +JS::NonnullGCPtr Element::get_bounding_client_rect() const { // // NOTE: Ensure that layout is up-to-date before looking at metrics. const_cast(document()).update_layout(); @@ -569,22 +569,22 @@ NonnullRefPtr Element::get_bounding_client_rect() const // FIXME: Support inline layout nodes as well. auto* paint_box = this->paint_box(); if (!paint_box) - return Geometry::DOMRect::create(0, 0, 0, 0); + return Geometry::DOMRect::create_with_global_object(window(), 0, 0, 0, 0); VERIFY(document().browsing_context()); auto viewport_offset = document().browsing_context()->viewport_scroll_offset(); - return Geometry::DOMRect::create(paint_box->absolute_rect().translated(-viewport_offset.x(), -viewport_offset.y())); + return Geometry::DOMRect::create(window(), paint_box->absolute_rect().translated(-viewport_offset.x(), -viewport_offset.y())); } // https://drafts.csswg.org/cssom-view/#dom-element-getclientrects -NonnullRefPtr Element::get_client_rects() const +JS::NonnullGCPtr Element::get_client_rects() const { - NonnullRefPtrVector rects; + Vector> rects; // 1. If the element on which it was invoked does not have an associated layout box return an empty DOMRectList object and stop this algorithm. if (!layout_node() || !layout_node()->is_box()) - return Geometry::DOMRectList::create(move(rects)); + return Geometry::DOMRectList::create(window(), move(rects)); // FIXME: 2. If the element has an associated SVG layout box return a DOMRectList object containing a single DOMRect object that describes // the bounding box of the element as defined by the SVG specification, applying the transforms that apply to the element and its ancestors. @@ -597,8 +597,8 @@ NonnullRefPtr Element::get_client_rects() const // - Replace each anonymous block box with its child box(es) and repeat this until no anonymous block boxes are left in the final list. auto bounding_rect = get_bounding_client_rect(); - rects.append(bounding_rect); - return Geometry::DOMRectList::create(move(rects)); + rects.append(*bounding_rect); + return Geometry::DOMRectList::create(window(), move(rects)); } int Element::client_top() const diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h index ed2cc60219..f1f51311c4 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.h +++ b/Userland/Libraries/LibWeb/DOM/Element.h @@ -125,8 +125,8 @@ public: bool is_void_element() const; bool serializes_as_void() const; - NonnullRefPtr get_bounding_client_rect() const; - NonnullRefPtr get_client_rects() const; + JS::NonnullGCPtr get_bounding_client_rect() const; + JS::NonnullGCPtr get_client_rects() const; virtual RefPtr create_layout_node(NonnullRefPtr); diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 0bc45acf27..d9a601427c 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -451,9 +451,6 @@ namespace Web::Bindings { class BlobWrapper; class CryptoWrapper; class DOMExceptionWrapper; -class DOMRectListWrapper; -class DOMRectReadOnlyWrapper; -class DOMRectWrapper; class FileWrapper; class HeadersWrapper; class HeadersIteratorWrapper; diff --git a/Userland/Libraries/LibWeb/Geometry/DOMRect.cpp b/Userland/Libraries/LibWeb/Geometry/DOMRect.cpp new file mode 100644 index 0000000000..202c13a9f5 --- /dev/null +++ b/Userland/Libraries/LibWeb/Geometry/DOMRect.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Web::Geometry { + +JS::NonnullGCPtr DOMRect::create_with_global_object(HTML::Window& window, double x, double y, double width, double height) +{ + return *window.heap().allocate(window.realm(), window, x, y, width, height); +} + +JS::NonnullGCPtr DOMRect::create(HTML::Window& window, Gfx::FloatRect const& rect) +{ + return create_with_global_object(window, rect.x(), rect.y(), rect.width(), rect.height()); +} + +DOMRect::DOMRect(HTML::Window& window, double x, double y, double width, double height) + : DOMRectReadOnly(window, x, y, width, height) +{ + set_prototype(&window.cached_web_prototype("DOMRect")); +} + +DOMRect::~DOMRect() = default; + +} diff --git a/Userland/Libraries/LibWeb/Geometry/DOMRect.h b/Userland/Libraries/LibWeb/Geometry/DOMRect.h index 057ea1ca36..6d82922b48 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMRect.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMRect.h @@ -11,25 +11,14 @@ namespace Web::Geometry { // https://drafts.fxtf.org/geometry/#DOMRect -class DOMRect final - : public DOMRectReadOnly { +class DOMRect final : public DOMRectReadOnly { + WEB_PLATFORM_OBJECT(DOMRect, DOMRectReadOnly); + public: - using WrapperType = Bindings::DOMRectWrapper; + static JS::NonnullGCPtr create_with_global_object(HTML::Window&, double x = 0, double y = 0, double width = 0, double height = 0); + static JS::NonnullGCPtr create(HTML::Window&, Gfx::FloatRect const&); - static NonnullRefPtr create_with_global_object(HTML::Window&, double x = 0, double y = 0, double width = 0, double height = 0) - { - return DOMRect::create(x, y, width, height); - } - - static NonnullRefPtr create(double x = 0, double y = 0, double width = 0, double height = 0) - { - return adopt_ref(*new DOMRect(x, y, width, height)); - } - - static NonnullRefPtr create(Gfx::FloatRect const& rect) - { - return adopt_ref(*new DOMRect(rect.x(), rect.y(), rect.width(), rect.height())); - } + virtual ~DOMRect() override; double x() const { return m_rect.x(); } double y() const { return m_rect.y(); } @@ -42,9 +31,9 @@ public: void set_height(double height) { m_rect.set_height(height); } private: - DOMRect(float x, float y, float width, float height) - : DOMRectReadOnly(x, y, width, height) - { - } + DOMRect(HTML::Window&, double x, double y, double width, double height); }; + } + +WRAPPER_HACK(DOMRect, Web::Geometry) diff --git a/Userland/Libraries/LibWeb/Geometry/DOMRectList.cpp b/Userland/Libraries/LibWeb/Geometry/DOMRectList.cpp index 0f49bb1240..c0888e5124 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMRectList.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMRectList.cpp @@ -4,16 +4,29 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include +#include namespace Web::Geometry { -DOMRectList::DOMRectList(NonnullRefPtrVector&& rects) - : m_rects(move(rects)) +JS::NonnullGCPtr DOMRectList::create(HTML::Window& window, Vector> rect_handles) +{ + Vector> rects; + for (auto& rect : rect_handles) + rects.append(*rect); + return *window.heap().allocate(window.realm(), window, move(rects)); +} + +DOMRectList::DOMRectList(HTML::Window& window, Vector> rects) + : Bindings::LegacyPlatformObject(window.cached_web_prototype("DOMRectList")) + , m_rects(move(rects)) { } +DOMRectList::~DOMRectList() = default; + // https://drafts.fxtf.org/geometry-1/#dom-domrectlist-length u32 DOMRectList::length() const { @@ -28,7 +41,7 @@ DOMRect const* DOMRectList::item(u32 index) const // Otherwise, the DOMRect object at index must be returned. Indices are zero-based. if (index >= m_rects.size()) return nullptr; - return &m_rects[index]; + return m_rects[index]; } bool DOMRectList::is_supported_property_index(u32 index) const @@ -36,4 +49,12 @@ bool DOMRectList::is_supported_property_index(u32 index) const return index < m_rects.size(); } +JS::Value DOMRectList::item_value(size_t index) const +{ + if (index >= m_rects.size()) + return JS::js_undefined(); + + return m_rects[index].ptr(); +} + } diff --git a/Userland/Libraries/LibWeb/Geometry/DOMRectList.h b/Userland/Libraries/LibWeb/Geometry/DOMRectList.h index 18cca279f0..c737ae2f07 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMRectList.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMRectList.h @@ -6,42 +6,33 @@ #pragma once -#include -#include -#include #include -#include -#include +#include #include namespace Web::Geometry { // https://drafts.fxtf.org/geometry-1/#DOMRectList -class DOMRectList final - : public RefCounted - , public Bindings::Wrappable { - AK_MAKE_NONCOPYABLE(DOMRectList); - AK_MAKE_NONMOVABLE(DOMRectList); +class DOMRectList final : public Bindings::LegacyPlatformObject { + WEB_PLATFORM_OBJECT(DOMRectList, Bindings::LegacyPlatformObject); public: - using WrapperType = Bindings::DOMRectListWrapper; + static JS::NonnullGCPtr create(HTML::Window&, Vector>); - static NonnullRefPtr create(NonnullRefPtrVector&& rects) - { - return adopt_ref(*new DOMRectList(move(rects))); - } - - ~DOMRectList() = default; + virtual ~DOMRectList() override; u32 length() const; DOMRect const* item(u32 index) const; - bool is_supported_property_index(u32) const; + virtual bool is_supported_property_index(u32) const override; + virtual JS::Value item_value(size_t index) const override; private: - DOMRectList(NonnullRefPtrVector&& rects); + DOMRectList(HTML::Window&, Vector>); - NonnullRefPtrVector m_rects; + Vector> m_rects; }; } + +WRAPPER_HACK(DOMRectList, Web::Geometry) diff --git a/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.cpp b/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.cpp new file mode 100644 index 0000000000..27d5a09c27 --- /dev/null +++ b/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Web::Geometry { + +JS::NonnullGCPtr DOMRectReadOnly::create_with_global_object(HTML::Window& window, double x, double y, double width, double height) +{ + return *window.heap().allocate(window.realm(), window, x, y, width, height); +} + +DOMRectReadOnly::DOMRectReadOnly(HTML::Window& window, double x, double y, double width, double height) + : PlatformObject(window.realm()) + , m_rect(x, y, width, height) +{ + set_prototype(&window.cached_web_prototype("DOMRectReadOnly")); +} + +DOMRectReadOnly::~DOMRectReadOnly() = default; + +} diff --git a/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.h b/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.h index 148ed1044f..1e0794917a 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMRectReadOnly.h @@ -6,29 +6,20 @@ #pragma once -#include #include -#include +#include #include namespace Web::Geometry { // https://drafts.fxtf.org/geometry/#domrectreadonly -class DOMRectReadOnly - : public RefCounted - , public Bindings::Wrappable { +class DOMRectReadOnly : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(DOMRectReadOnly, Bindings::PlatformObject); + public: - using WrapperType = Bindings::DOMRectReadOnlyWrapper; + static JS::NonnullGCPtr create_with_global_object(HTML::Window&, double x = 0, double y = 0, double width = 0, double height = 0); - static NonnullRefPtr create_with_global_object(HTML::Window&, double x = 0, double y = 0, double width = 0, double height = 0) - { - return DOMRectReadOnly::create(x, y, width, height); - } - - static NonnullRefPtr create(double x = 0, double y = 0, double width = 0, double height = 0) - { - return adopt_ref(*new DOMRectReadOnly(x, y, width, height)); - } + virtual ~DOMRectReadOnly() override; double x() const { return m_rect.x(); } double y() const { return m_rect.y(); } @@ -41,11 +32,10 @@ public: double left() const { return min(x(), x() + width()); } protected: - DOMRectReadOnly(float x, float y, float width, float height) - : m_rect(x, y, width, height) - { - } + DOMRectReadOnly(HTML::Window&, double x, double y, double width, double height); Gfx::FloatRect m_rect; }; } + +WRAPPER_HACK(DOMRectReadOnly, Web::Geometry) diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 702abe154a..45b7bbf5a3 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -58,9 +58,9 @@ libweb_js_wrapper(FileAPI/Blob) libweb_js_wrapper(FileAPI/File) libweb_js_wrapper(Geometry/DOMPoint NO_INSTANCE) libweb_js_wrapper(Geometry/DOMPointReadOnly NO_INSTANCE) -libweb_js_wrapper(Geometry/DOMRect) -libweb_js_wrapper(Geometry/DOMRectList) -libweb_js_wrapper(Geometry/DOMRectReadOnly) +libweb_js_wrapper(Geometry/DOMRect NO_INSTANCE) +libweb_js_wrapper(Geometry/DOMRectList NO_INSTANCE) +libweb_js_wrapper(Geometry/DOMRectReadOnly NO_INSTANCE) libweb_js_wrapper(HTML/CanvasGradient NO_INSTANCE) libweb_js_wrapper(HTML/CanvasRenderingContext2D NO_INSTANCE) libweb_js_wrapper(HTML/CloseEvent NO_INSTANCE)