diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 3c8d65e836..a2385507b1 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -206,6 +206,7 @@ set(SOURCES Fetch/Request.cpp Fetch/Response.cpp FileAPI/Blob.cpp + FileAPI/BlobURLStore.cpp FileAPI/File.cpp FileAPI/FileList.cpp FontCache.cpp diff --git a/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.cpp b/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.cpp new file mode 100644 index 0000000000..2f93f20d7f --- /dev/null +++ b/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace Web::FileAPI { + +BlobURLStore& blob_url_store() +{ + static HashMap store; + return store; +} + +// https://w3c.github.io/FileAPI/#unicodeBlobURL +ErrorOr generate_new_blob_url() +{ + // 1. Let result be the empty string. + StringBuilder result; + + // 2. Append the string "blob:" to result. + TRY(result.try_append("blob:"sv)); + + // 3. Let settings be the current settings object + auto& settings = HTML::current_settings_object(); + + // 4. Let origin be settings’s origin. + auto origin = settings.origin(); + + // 5. Let serialized be the ASCII serialization of origin. + auto serialized = origin.serialize(); + + // 6. If serialized is "null", set it to an implementation-defined value. + if (serialized == "null"sv) + serialized = "ladybird"sv; + + // 7. Append serialized to result. + TRY(result.try_append(serialized)); + + // 8. Append U+0024 SOLIDUS (/) to result. + TRY(result.try_append('/')); + + // 9. Generate a UUID [RFC4122] as a string and append it to result. + auto uuid = TRY(Crypto::generate_random_uuid()); + TRY(result.try_append(uuid)); + + // 10. Return result. + return result.to_string(); +} + +// https://w3c.github.io/FileAPI/#add-an-entry +ErrorOr add_entry_to_blob_url_store(JS::NonnullGCPtr object) +{ + // 1. Let store be the user agent’s blob URL store. + auto& store = blob_url_store(); + + // 2. Let url be the result of generating a new blob URL. + auto url = TRY(generate_new_blob_url()); + + // 3. Let entry be a new blob URL entry consisting of object and the current settings object. + BlobURLEntry entry { object, HTML::current_settings_object() }; + + // 4. Set store[url] to entry. + TRY(store.try_set(url, move(entry))); + + // 5. Return url. + return url; +} + +// https://w3c.github.io/FileAPI/#removeTheEntry +ErrorOr remove_entry_from_blob_url_store(StringView url) +{ + // 1. Let store be the user agent’s blob URL store; + auto& store = blob_url_store(); + + // 2. Let url string be the result of serializing url. + auto url_string = TRY(AK::URL { url }.to_string()); + + // 3. Remove store[url string]. + store.remove(url_string); + return {}; +} + +} diff --git a/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.h b/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.h new file mode 100644 index 0000000000..6e83cd076d --- /dev/null +++ b/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Web::FileAPI { + +// https://w3c.github.io/FileAPI/#blob-url-entry +struct BlobURLEntry { + JS::Handle object; // FIXME: This could also be a MediaSource after we implement MSE. + JS::Handle environment; +}; + +// https://w3c.github.io/FileAPI/#BlobURLStore +using BlobURLStore = HashMap; + +BlobURLStore& blob_url_store(); +ErrorOr generate_new_blob_url(); +ErrorOr add_entry_to_blob_url_store(JS::NonnullGCPtr object); +ErrorOr remove_entry_from_blob_url_store(StringView url); + +}