diff --git a/Tests/LibWeb/Text/expected/HTML/StructuredClone-serializable-objects.txt b/Tests/LibWeb/Text/expected/HTML/StructuredClone-serializable-objects.txt index c383c69d915..47cd8c76daa 100644 --- a/Tests/LibWeb/Text/expected/HTML/StructuredClone-serializable-objects.txt +++ b/Tests/LibWeb/Text/expected/HTML/StructuredClone-serializable-objects.txt @@ -20,6 +20,8 @@ instanceOf DOMRectReadOnly: true DOMRectReadOnly: {"x":10,"y":20,"width":30,"height":40,"top":20,"right":40,"bottom":60,"left":10} instanceOf DOMRect: true DOMRect: {"x":10,"y":20,"width":30,"height":40,"top":20,"right":40,"bottom":60,"left":10} +instanceOf DOMQuad: true +DOMQuad: {"p1":{"x":10,"y":20,"z":30,"w":40},"p2":{"x":50,"y":60,"z":70,"w":80},"p3":{"x":90,"y":100,"z":110,"w":120},"p4":{"x":130,"y":140,"z":150,"w":160}} instanceOf CryptoKey: true CryptoKey.type: "secret" CryptoKey.extractable: false diff --git a/Tests/LibWeb/Text/input/HTML/StructuredClone-serializable-objects.html b/Tests/LibWeb/Text/input/HTML/StructuredClone-serializable-objects.html index 9c1726c06a0..85a410264f7 100644 --- a/Tests/LibWeb/Text/input/HTML/StructuredClone-serializable-objects.html +++ b/Tests/LibWeb/Text/input/HTML/StructuredClone-serializable-objects.html @@ -43,6 +43,10 @@ println(`instanceOf DOMRect: ${domRect instanceof DOMRect}`); println(`DOMRect: ${JSON.stringify(domRect)}`); + let domQuad = structuredClone(new DOMQuad(new DOMPoint(10, 20, 30, 40), new DOMPoint(50, 60, 70, 80), new DOMPoint(90, 100, 110, 120), new DOMPoint(130, 140, 150, 160))); + println(`instanceOf DOMQuad: ${domQuad instanceof DOMQuad}`); + println(`DOMQuad: ${JSON.stringify(domQuad)}`); + let cryptoKey = await window.crypto.subtle.importKey( "raw", new TextEncoder().encode("password"), diff --git a/Userland/Libraries/LibWeb/Geometry/DOMQuad.cpp b/Userland/Libraries/LibWeb/Geometry/DOMQuad.cpp index 1cc24aea643..548f1440776 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMQuad.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMQuad.cpp @@ -16,6 +16,11 @@ JS::NonnullGCPtr DOMQuad::construct_impl(JS::Realm& realm, DOMPointInit return realm.heap().allocate(realm, realm, p1, p2, p3, p4); } +JS::NonnullGCPtr DOMQuad::create(JS::Realm& realm) +{ + return realm.heap().allocate(realm, realm); +} + 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)) @@ -25,6 +30,15 @@ DOMQuad::DOMQuad(JS::Realm& realm, DOMPointInit const& p1, DOMPointInit const& p { } +DOMQuad::DOMQuad(JS::Realm& realm) + : PlatformObject(realm) + , m_p1(DOMPoint::create(realm)) + , m_p2(DOMPoint::create(realm)) + , m_p3(DOMPoint::create(realm)) + , m_p4(DOMPoint::create(realm)) +{ +} + DOMQuad::~DOMQuad() = default; // https://drafts.fxtf.org/geometry/#dom-domquad-fromrect @@ -84,6 +98,53 @@ JS::NonnullGCPtr DOMQuad::get_bounds() const return bounds; } +// https://drafts.fxtf.org/geometry/#structured-serialization +WebIDL::ExceptionOr DOMQuad::serialization_steps(HTML::SerializationRecord& serialzied, bool for_storage, HTML::SerializationMemory& memory) +{ + auto& vm = this->vm(); + // 1. Set serialized.[[P1]] to the sub-serialization of value’s point 1. + serialzied.extend(TRY(HTML::structured_serialize_internal(vm, m_p1, for_storage, memory))); + // 2. Set serialized.[[P2]] to the sub-serialization of value’s point 2. + serialzied.extend(TRY(HTML::structured_serialize_internal(vm, m_p2, for_storage, memory))); + // 3. Set serialized.[[P3]] to the sub-serialization of value’s point 3. + serialzied.extend(TRY(HTML::structured_serialize_internal(vm, m_p3, for_storage, memory))); + // 4. Set serialized.[[P4]] to the sub-serialization of value’s point 4. + serialzied.extend(TRY(HTML::structured_serialize_internal(vm, m_p4, for_storage, memory))); + + return {}; +} + +// https://drafts.fxtf.org/geometry/#structured-serialization +WebIDL::ExceptionOr DOMQuad::deserialization_steps(ReadonlySpan const& serialized, size_t& position, HTML::DeserializationMemory& memory) +{ + auto& realm = this->realm(); + // 1. Set value’s point 1 to the sub-deserialization of serialized.[[P1]]. + auto deserialized_record = TRY(HTML::structured_deserialize_internal(vm(), serialized, realm, memory, position)); + if (deserialized_record.value.has_value() && is(deserialized_record.value.value().as_object())) + m_p1 = dynamic_cast(deserialized_record.value.release_value().as_object()); + position = deserialized_record.position; + + // 2. Set value’s point 2 to the sub-deserialization of serialized.[[P2]]. + deserialized_record = TRY(HTML::structured_deserialize_internal(vm(), serialized, realm, memory, position)); + if (deserialized_record.value.has_value() && is(deserialized_record.value.value().as_object())) + m_p2 = dynamic_cast(deserialized_record.value.release_value().as_object()); + position = deserialized_record.position; + + // 3. Set value’s point 3 to the sub-deserialization of serialized.[[P3]]. + deserialized_record = TRY(HTML::structured_deserialize_internal(vm(), serialized, realm, memory, position)); + if (deserialized_record.value.has_value() && is(deserialized_record.value.value().as_object())) + m_p3 = dynamic_cast(deserialized_record.value.release_value().as_object()); + position = deserialized_record.position; + + // 4. Set value’s point 4 to the sub-deserialization of serialized.[[P4]]. + deserialized_record = TRY(HTML::structured_deserialize_internal(vm(), serialized, realm, memory, position)); + if (deserialized_record.value.has_value() && is(deserialized_record.value.value().as_object())) + m_p4 = dynamic_cast(deserialized_record.value.release_value().as_object()); + position = deserialized_record.position; + + return {}; +} + void DOMQuad::initialize(JS::Realm& realm) { Base::initialize(realm); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMQuad.h b/Userland/Libraries/LibWeb/Geometry/DOMQuad.h index 686b2f7fa22..61d6957baf9 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMQuad.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMQuad.h @@ -22,12 +22,15 @@ struct DOMQuadInit { }; // https://drafts.fxtf.org/geometry/#domquad -class DOMQuad : public Bindings::PlatformObject { +class DOMQuad + : public Bindings::PlatformObject + , public Bindings::Serializable { WEB_PLATFORM_OBJECT(DOMQuad, Bindings::PlatformObject); JS_DECLARE_ALLOCATOR(DOMQuad); public: static JS::NonnullGCPtr construct_impl(JS::Realm&, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4); + static JS::NonnullGCPtr create(JS::Realm& realm); virtual ~DOMQuad() override; @@ -41,8 +44,13 @@ public: JS::NonnullGCPtr get_bounds() const; + virtual StringView interface_name() const override { return "DOMQuad"sv; } + virtual WebIDL::ExceptionOr serialization_steps(HTML::SerializationRecord&, bool for_storage, HTML::SerializationMemory&) override; + virtual WebIDL::ExceptionOr deserialization_steps(ReadonlySpan const&, size_t& position, HTML::DeserializationMemory&) override; + private: DOMQuad(JS::Realm&, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4); + explicit DOMQuad(JS::Realm&); virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp index e39a7d824d4..ec6d096498e 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -987,6 +988,8 @@ private: return Geometry::DOMRect::create(realm); if (interface_name == "CryptoKey"sv) return Crypto::CryptoKey::create(realm); + if (interface_name == "DOMQuad"sv) + return Geometry::DOMQuad::create(realm); VERIFY_NOT_REACHED(); }