mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-15 14:51:52 +00:00
LibWeb: Implement WorkerGlobalScope.importScripts()
This method allows workers to synchronously import one or more scripts.
This commit is contained in:
parent
975a067f58
commit
bb923983fc
Notes:
sideshowbarker
2024-07-17 03:19:14 +09:00
Author: https://github.com/tcl3
Commit: bb923983fc
Pull-request: https://github.com/SerenityOS/serenity/pull/24423
Reviewed-by: https://github.com/alimpfard
8 changed files with 134 additions and 12 deletions
|
@ -1,9 +1,11 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2023, networkException <networkexception@serenityos.org>
|
||||
* Copyright (c) 2024, Tim Ledbetter <timledbetter@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibJS/Heap/HeapFunction.h>
|
||||
#include <LibJS/Runtime/ModuleRequest.h>
|
||||
#include <LibTextCodec/Decoder.h>
|
||||
|
@ -423,6 +425,83 @@ WebIDL::ExceptionOr<void> fetch_classic_worker_script(URL::URL const& url, Envir
|
|||
return {};
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-worker-imported-script
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<ClassicScript>> fetch_a_classic_worker_imported_script(URL::URL const& url, HTML::EnvironmentSettingsObject& settings_object, PerformTheFetchHook perform_fetch)
|
||||
{
|
||||
auto& realm = settings_object.realm();
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. Let response be null.
|
||||
JS::GCPtr<Fetch::Infrastructure::Response> response = nullptr;
|
||||
|
||||
// 2. Let bodyBytes be null.
|
||||
Fetch::Infrastructure::FetchAlgorithms::BodyBytes body_bytes;
|
||||
|
||||
// 3. Let request be a new request whose URL is url, client is settingsObject, destination is "script", initiator type is "other",
|
||||
// parser metadata is "not parser-inserted", and whose use-URL-credentials flag is set.
|
||||
auto request = Fetch::Infrastructure::Request::create(vm);
|
||||
request->set_url(url);
|
||||
request->set_client(&settings_object);
|
||||
request->set_destination(Fetch::Infrastructure::Request::Destination::Script);
|
||||
request->set_initiator_type(Fetch::Infrastructure::Request::InitiatorType::Other);
|
||||
request->set_parser_metadata(Fetch::Infrastructure::Request::ParserMetadata::NotParserInserted);
|
||||
request->set_use_url_credentials(true);
|
||||
|
||||
auto process_response_consume_body = [&response, &body_bytes](JS::NonnullGCPtr<Fetch::Infrastructure::Response> res, Fetch::Infrastructure::FetchAlgorithms::BodyBytes bb) {
|
||||
// 1. Set bodyBytes to bb.
|
||||
body_bytes = move(bb);
|
||||
|
||||
// 2. Set response to res.
|
||||
response = res;
|
||||
};
|
||||
|
||||
// 4. If performFetch was given, run performFetch with request, isTopLevel, and with processResponseConsumeBody as defined below.
|
||||
if (perform_fetch) {
|
||||
TRY(perform_fetch->function()(request, TopLevelModule::Yes, move(process_response_consume_body)));
|
||||
}
|
||||
// Otherwise, fetch request with processResponseConsumeBody set to processResponseConsumeBody as defined below.
|
||||
else {
|
||||
Fetch::Infrastructure::FetchAlgorithms::Input fetch_algorithms_input {};
|
||||
fetch_algorithms_input.process_response_consume_body = move(process_response_consume_body);
|
||||
TRY(Fetch::Fetching::fetch(realm, request, Fetch::Infrastructure::FetchAlgorithms::create(vm, move(fetch_algorithms_input))));
|
||||
}
|
||||
|
||||
// 5. Pause until response is not null.
|
||||
auto& event_loop = settings_object.responsible_event_loop();
|
||||
event_loop.spin_until([&]() {
|
||||
return response;
|
||||
});
|
||||
|
||||
// 6. Set response to response's unsafe response.
|
||||
response = response->unsafe_response();
|
||||
|
||||
// 7. If any of the following are true:
|
||||
// - bodyBytes is null or failure;
|
||||
// - response's status is not an ok status; or
|
||||
// - the result of extracting a MIME type from response's header list is not a JavaScript MIME type,
|
||||
// then throw a "NetworkError" DOMException.
|
||||
if (body_bytes.template has<Empty>() || body_bytes.template has<Fetch::Infrastructure::FetchAlgorithms::ConsumeBodyFailureTag>()
|
||||
|| !Fetch::Infrastructure::is_ok_status(response->status())
|
||||
|| !response->header_list()->extract_mime_type().has_value() || !response->header_list()->extract_mime_type()->is_javascript()) {
|
||||
return WebIDL::NetworkError::create(realm, "Network error"_fly_string);
|
||||
}
|
||||
|
||||
// 8. Let sourceText be the result of UTF-8 decoding bodyBytes.
|
||||
auto decoder = TextCodec::decoder_for("UTF-8"sv);
|
||||
VERIFY(decoder.has_value());
|
||||
auto source_text = TextCodec::convert_input_to_utf8_using_given_decoder_unless_there_is_a_byte_order_mark(*decoder, body_bytes.get<ByteBuffer>()).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
// 9. Let mutedErrors be true if response was CORS-cross-origin, and false otherwise.
|
||||
auto muted_errors = response->is_cors_cross_origin() ? ClassicScript::MutedErrors::Yes : ClassicScript::MutedErrors::No;
|
||||
|
||||
// 10. Let script be the result of creating a classic script given sourceText, settingsObject, response's URL, the default classic script fetch options, and mutedErrors.
|
||||
auto response_url = response->url().value_or({});
|
||||
auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object, response_url, 1, muted_errors);
|
||||
|
||||
// 11. Return script.
|
||||
return script;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree
|
||||
WebIDL::ExceptionOr<void> fetch_module_worker_script_graph(URL::URL const& url, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination destination, EnvironmentSettingsObject& settings_object, PerformTheFetchHook perform_fetch, OnFetchScriptComplete on_complete)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue