Sfoglia il codice sorgente

LibWeb: Add {,de}serialization steps for DOMQuad

Kenneth Myhra 1 anno fa
parent
commit
5397340724

+ 2 - 0
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

+ 4 - 0
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"),

+ 61 - 0
Userland/Libraries/LibWeb/Geometry/DOMQuad.cpp

@@ -16,6 +16,11 @@ JS::NonnullGCPtr<DOMQuad> DOMQuad::construct_impl(JS::Realm& realm, DOMPointInit
     return realm.heap().allocate<DOMQuad>(realm, realm, p1, p2, p3, p4);
 }
 
+JS::NonnullGCPtr<DOMQuad> DOMQuad::create(JS::Realm& realm)
+{
+    return realm.heap().allocate<DOMQuad>(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<DOMRect> DOMQuad::get_bounds() const
     return bounds;
 }
 
+// https://drafts.fxtf.org/geometry/#structured-serialization
+WebIDL::ExceptionOr<void> 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<void> DOMQuad::deserialization_steps(ReadonlySpan<u32> 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<DOMPoint>(deserialized_record.value.value().as_object()))
+        m_p1 = dynamic_cast<DOMPoint&>(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<DOMPoint>(deserialized_record.value.value().as_object()))
+        m_p2 = dynamic_cast<DOMPoint&>(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<DOMPoint>(deserialized_record.value.value().as_object()))
+        m_p3 = dynamic_cast<DOMPoint&>(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<DOMPoint>(deserialized_record.value.value().as_object()))
+        m_p4 = dynamic_cast<DOMPoint&>(deserialized_record.value.release_value().as_object());
+    position = deserialized_record.position;
+
+    return {};
+}
+
 void DOMQuad::initialize(JS::Realm& realm)
 {
     Base::initialize(realm);

+ 9 - 1
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<DOMQuad> construct_impl(JS::Realm&, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4);
+    static JS::NonnullGCPtr<DOMQuad> create(JS::Realm& realm);
 
     virtual ~DOMQuad() override;
 
@@ -41,8 +44,13 @@ public:
 
     JS::NonnullGCPtr<DOMRect> get_bounds() const;
 
+    virtual StringView interface_name() const override { return "DOMQuad"sv; }
+    virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord&, bool for_storage, HTML::SerializationMemory&) override;
+    virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> 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;

+ 3 - 0
Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp

@@ -40,6 +40,7 @@
 #include <LibWeb/Geometry/DOMMatrixReadOnly.h>
 #include <LibWeb/Geometry/DOMPoint.h>
 #include <LibWeb/Geometry/DOMPointReadOnly.h>
+#include <LibWeb/Geometry/DOMQuad.h>
 #include <LibWeb/Geometry/DOMRect.h>
 #include <LibWeb/Geometry/DOMRectReadOnly.h>
 #include <LibWeb/HTML/MessagePort.h>
@@ -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();
     }