diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp index 172e459d5f1..be3d860e750 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp @@ -1421,4 +1421,31 @@ WebIDL::ExceptionOr> store_a_record_into_an_object_store(JS::Realm& return key; } +// https://w3c.github.io/IndexedDB/#convert-a-value-to-a-key-range +WebIDL::ExceptionOr> convert_a_value_to_a_key_range(JS::Realm& realm, Optional value, bool null_disallowed) +{ + // 1. If value is a key range, return value. + if (value.has_value() && value->is_object() && is(value->as_object())) { + return GC::Ref(static_cast(value->as_object())); + } + + // 2. If value is undefined or is null, then throw a "DataError" DOMException if null disallowed flag is true, or return an unbounded key range otherwise. + if (!value.has_value() || (value.has_value() && (value->is_undefined() || value->is_null()))) { + if (null_disallowed) + return WebIDL::DataError::create(realm, "Value is undefined or null"_string); + + return IDBKeyRange::create(realm, {}, {}, false, false); + } + + // 3. Let key be the result of converting a value to a key with value. Rethrow any exceptions. + auto key = TRY(convert_a_value_to_a_key(realm, *value)); + + // 4. If key is invalid, throw a "DataError" DOMException. + if (key->is_invalid()) + return WebIDL::DataError::create(realm, "Value is invalid"_string); + + // 5. Return a key range containing only key. + return IDBKeyRange::create(realm, key, key, false, false); +} + } diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h index 53f8d25b92b..2bbb124fe65 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h +++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h @@ -41,5 +41,6 @@ void possibly_update_the_key_generator(GC::Ref, GC::Ref); void inject_a_key_into_a_value_using_a_key_path(JS::Realm&, JS::Value, GC::Ref, KeyPath const&); void delete_records_from_an_object_store(GC::Ref, GC::Ref); WebIDL::ExceptionOr> store_a_record_into_an_object_store(JS::Realm&, GC::Ref, JS::Value, GC::Ptr, bool); +WebIDL::ExceptionOr> convert_a_value_to_a_key_range(JS::Realm&, Optional, bool = false); }