diff --git a/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt b/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt index d3eebbfa88..3955abadde 100644 --- a/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt +++ b/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt @@ -5,4 +5,5 @@ false This is a String object 9007199254740991 1692748800000 +/abc/gimsuy ERROR: DataCloneError: Cannot serialize Symbol \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html b/Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html index 512ef6c7e5..0ba2a843e5 100644 --- a/Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html +++ b/Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html @@ -8,6 +8,7 @@ println(structuredClone(new String("This is a String object"))); println(structuredClone(BigInt("0x1fffffffffffff"))); println(structuredClone(Date.UTC(2023, 7, 23))); + println(structuredClone(/abc/gimsuy)); try { structuredClone(Symbol("foo")); diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp index 61f3ece718..96bb3b60e0 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,8 @@ enum ValueTag { DateObject, + RegExpObject, + // TODO: Define many more types // This tag or higher are understood to be errors @@ -171,7 +174,20 @@ public: m_serialized.append(bit_cast(&date_value), 2); } - // 12 - 24: FIXME: Serialize other data types + // 12. Otherwise, if value has a [[RegExpMatcher]] internal slot, then set serialized to + // { [[Type]]: "RegExp", [[RegExpMatcher]]: value.[[RegExpMatcher]], [[OriginalSource]]: value.[[OriginalSource]], + // [[OriginalFlags]]: value.[[OriginalFlags]] }. + else if (value.is_object() && is(value.as_object())) { + m_serialized.append(ValueTag::RegExpObject); + auto& regexp_object = static_cast(value.as_object()); + // Note: A Regex object is perfectly happy to be reconstructed with just the source+flags + // In the future, we could optimize the work being done on the deserialize step by serializing + // more of the internal state (the [[RegExpMatcher]] internal slot) + TRY(serialize_string(m_serialized, TRY_OR_THROW_OOM(m_vm, String::from_deprecated_string(regexp_object.pattern())))); + TRY(serialize_string(m_serialized, TRY_OR_THROW_OOM(m_vm, String::from_deprecated_string(regexp_object.flags())))); + } + + // 13 - 24: FIXME: Serialize other data types else { return throw_completion(WebIDL::DataCloneError::create(*m_vm.current_realm(), "Unsupported type"_fly_string)); } @@ -301,6 +317,12 @@ public: m_memory.append(JS::Date::create(*realm, value)); break; } + case ValueTag::RegExpObject: { + auto pattern = TRY(deserialize_string_primitive(m_vm, m_vector, position)); + auto flags = TRY(deserialize_string_primitive(m_vm, m_vector, position)); + m_memory.append(TRY(JS::regexp_create(m_vm, move(pattern), move(flags)))); + break; + } default: m_error = "Unsupported type"_fly_string; break;