ソースを参照

LibWeb: Add serialization and deserilization steps to DOMException

This makes DOMException a Serializable object.
Kenneth Myhra 7 ヶ月 前
コミット
4c5019f89c

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

@@ -46,6 +46,7 @@
 #include <LibWeb/Geometry/DOMRectReadOnly.h>
 #include <LibWeb/Geometry/DOMRectReadOnly.h>
 #include <LibWeb/HTML/MessagePort.h>
 #include <LibWeb/HTML/MessagePort.h>
 #include <LibWeb/HTML/StructuredSerialize.h>
 #include <LibWeb/HTML/StructuredSerialize.h>
+#include <LibWeb/WebIDL/DOMException.h>
 #include <LibWeb/WebIDL/ExceptionOr.h>
 #include <LibWeb/WebIDL/ExceptionOr.h>
 
 
 namespace Web::HTML {
 namespace Web::HTML {
@@ -985,6 +986,8 @@ private:
             return FileAPI::File::create(realm);
             return FileAPI::File::create(realm);
         if (interface_name == "FileList"sv)
         if (interface_name == "FileList"sv)
             return FileAPI::FileList::create(realm);
             return FileAPI::FileList::create(realm);
+        if (interface_name == "DOMException"sv)
+            return WebIDL::DOMException::create(realm);
         if (interface_name == "DOMMatrixReadOnly"sv)
         if (interface_name == "DOMMatrixReadOnly"sv)
             return Geometry::DOMMatrixReadOnly::create(realm);
             return Geometry::DOMMatrixReadOnly::create(realm);
         if (interface_name == "DOMMatrix"sv)
         if (interface_name == "DOMMatrix"sv)

+ 41 - 0
Libraries/LibWeb/WebIDL/DOMException.cpp

@@ -6,6 +6,7 @@
 
 
 #include <LibWeb/Bindings/DOMExceptionPrototype.h>
 #include <LibWeb/Bindings/DOMExceptionPrototype.h>
 #include <LibWeb/Bindings/Intrinsics.h>
 #include <LibWeb/Bindings/Intrinsics.h>
+#include <LibWeb/HTML/StructuredSerialize.h>
 #include <LibWeb/WebIDL/DOMException.h>
 #include <LibWeb/WebIDL/DOMException.h>
 
 
 namespace Web::WebIDL {
 namespace Web::WebIDL {
@@ -17,6 +18,11 @@ GC::Ref<DOMException> DOMException::create(JS::Realm& realm, FlyString name, Str
     return realm.create<DOMException>(realm, move(name), move(message));
     return realm.create<DOMException>(realm, move(name), move(message));
 }
 }
 
 
+GC::Ref<DOMException> DOMException::create(JS::Realm& realm)
+{
+    return realm.create<DOMException>(realm);
+}
+
 GC::Ref<DOMException> DOMException::construct_impl(JS::Realm& realm, String message, FlyString name)
 GC::Ref<DOMException> DOMException::construct_impl(JS::Realm& realm, String message, FlyString name)
 {
 {
     return realm.create<DOMException>(realm, move(name), move(message));
     return realm.create<DOMException>(realm, move(name), move(message));
@@ -29,6 +35,11 @@ DOMException::DOMException(JS::Realm& realm, FlyString name, String message)
 {
 {
 }
 }
 
 
+DOMException::DOMException(JS::Realm& realm)
+    : PlatformObject(realm)
+{
+}
+
 DOMException::~DOMException() = default;
 DOMException::~DOMException() = default;
 
 
 void DOMException::initialize(JS::Realm& realm)
 void DOMException::initialize(JS::Realm& realm)
@@ -37,4 +48,34 @@ void DOMException::initialize(JS::Realm& realm)
     WEB_SET_PROTOTYPE_FOR_INTERFACE(DOMException);
     WEB_SET_PROTOTYPE_FOR_INTERFACE(DOMException);
 }
 }
 
 
+ExceptionOr<void> DOMException::serialization_steps(HTML::SerializationRecord& record, bool, HTML::SerializationMemory&)
+{
+    auto& vm = this->vm();
+
+    // 1. Set serialized.[[Name]] to value’s name.
+    TRY(HTML::serialize_string(vm, record, m_name.to_string()));
+
+    // 2. Set serialized.[[Message]] to value’s message.
+    TRY(HTML::serialize_string(vm, record, m_message.to_string()));
+
+    // FIXME: 3. User agents should attach a serialized representation of any interesting accompanying data which are not yet specified, notably the stack property, to serialized.
+
+    return {};
+}
+
+ExceptionOr<void> DOMException::deserialization_steps(ReadonlySpan<u32> const& record, size_t& position, HTML::DeserializationMemory&)
+{
+    auto& vm = this->vm();
+
+    // 1. Set value’s name to serialized.[[Name]].
+    m_name = TRY(HTML::deserialize_string(vm, record, position));
+
+    // 2. Set value’s message to serialized.[[Message]].
+    m_message = TRY(HTML::deserialize_string(vm, record, position));
+
+    // FIXME: 3. If any other data is attached to serialized, then deserialize and attach it to value.
+
+    return {};
+}
+
 }
 }

+ 12 - 1
Libraries/LibWeb/WebIDL/DOMException.h

@@ -9,6 +9,8 @@
 #include <AK/Diagnostics.h>
 #include <AK/Diagnostics.h>
 #include <AK/String.h>
 #include <AK/String.h>
 #include <LibWeb/Bindings/PlatformObject.h>
 #include <LibWeb/Bindings/PlatformObject.h>
+#include <LibWeb/Bindings/Serializable.h>
+#include <LibWeb/Forward.h>
 #include <LibWeb/HTML/Scripting/Environments.h>
 #include <LibWeb/HTML/Scripting/Environments.h>
 
 
 namespace Web::WebIDL {
 namespace Web::WebIDL {
@@ -89,12 +91,15 @@ static u16 get_legacy_code_for_name(FlyString const& name)
 }
 }
 
 
 // https://webidl.spec.whatwg.org/#idl-DOMException
 // https://webidl.spec.whatwg.org/#idl-DOMException
-class DOMException final : public Bindings::PlatformObject {
+class DOMException final
+    : public Bindings::PlatformObject
+    , public Bindings::Serializable {
     WEB_PLATFORM_OBJECT(DOMException, Bindings::PlatformObject);
     WEB_PLATFORM_OBJECT(DOMException, Bindings::PlatformObject);
     GC_DECLARE_ALLOCATOR(DOMException);
     GC_DECLARE_ALLOCATOR(DOMException);
 
 
 public:
 public:
     static GC::Ref<DOMException> create(JS::Realm& realm, FlyString name, String message);
     static GC::Ref<DOMException> create(JS::Realm& realm, FlyString name, String message);
+    static GC::Ref<DOMException> create(JS::Realm& realm);
 
 
     // JS constructor has message first, name second
     // JS constructor has message first, name second
     // FIXME: This is a completely pointless footgun, let's use the same order for both factories.
     // FIXME: This is a completely pointless footgun, let's use the same order for both factories.
@@ -106,8 +111,14 @@ public:
     FlyString const& message() const { return m_message; }
     FlyString const& message() const { return m_message; }
     u16 code() const { return get_legacy_code_for_name(m_name); }
     u16 code() const { return get_legacy_code_for_name(m_name); }
 
 
+    virtual StringView interface_name() const override { return "DOMException"sv; }
+
+    virtual ExceptionOr<void> serialization_steps(HTML::SerializationRecord& record, bool for_storage, HTML::SerializationMemory&) override;
+    virtual ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const& record, size_t& position, HTML::DeserializationMemory&) override;
+
 protected:
 protected:
     DOMException(JS::Realm&, FlyString name, String message);
     DOMException(JS::Realm&, FlyString name, String message);
+    explicit DOMException(JS::Realm&);
 
 
     virtual void initialize(JS::Realm&) override;
     virtual void initialize(JS::Realm&) override;
 
 

+ 2 - 0
Tests/LibWeb/Text/expected/HTML/StructuredClone-serializable-objects.txt

@@ -27,3 +27,5 @@ CryptoKey.type: "secret"
 CryptoKey.extractable: false
 CryptoKey.extractable: false
 CryptoKey.algorithm: {"name":"PBKDF2"}
 CryptoKey.algorithm: {"name":"PBKDF2"}
 CryptoKey.usages: ["deriveKey","deriveBits"]
 CryptoKey.usages: ["deriveKey","deriveBits"]
+instanceOf DOMException: true
+DOMException: Index out of bounds - IndexSizeError

+ 4 - 0
Tests/LibWeb/Text/input/HTML/StructuredClone-serializable-objects.html

@@ -61,6 +61,10 @@
         println(`CryptoKey.algorithm: ${JSON.stringify(clonedCryptoKey.algorithm)}`);
         println(`CryptoKey.algorithm: ${JSON.stringify(clonedCryptoKey.algorithm)}`);
         println(`CryptoKey.usages: ${JSON.stringify(clonedCryptoKey.usages)}`);
         println(`CryptoKey.usages: ${JSON.stringify(clonedCryptoKey.usages)}`);
 
 
+        let domException = structuredClone(new DOMException("Index out of bounds", "IndexSizeError"));
+        println(`instanceOf DOMException: ${domException instanceof DOMException}`);
+        println(`DOMException: ${domException.message} - ${domException.name}`);
+
         done();
         done();
     });
     });
 </script>
 </script>