/* * Copyright (c) 2022, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // NOTE: This file contains code generated by BindingsGenerator from the following input: // interface Dummy { // static Promise fetch(RequestInfo input, optional RequestInfo init = {}); // }; // This is because the spec defines the fetch() method as a 'partial interface mixin' on // WindowOrWorkerGlobalScope, which we don't support yet - and even if we did, the Window object is // not generated from IDL currently, so we couldn't add a mixin to it that way. The generated code // has _not_ been cleaned up manually, the only changes are: // - Adding only the necessary includes and 'using namespace' declarations // - Deferring to 'Fetch::fetch_impl()' at the very end instead of 'Fetch::Dummy::fetch()' // - Removing all empty lines, there's an excessive amount of them and this isn't supposed to be // readable code anyway // - Running clang-format :^) // Don't hesitate to sync it with updated output when making changes to BindingsGenerator! using namespace Web::DOM; using namespace Web::Fetch; using namespace Web::FileAPI; using namespace Web::Streams; using namespace Web::URL; namespace Web::Bindings { // NOLINTBEGIN JS::ThrowCompletionOr fetch(JS::VM& vm) { [[maybe_unused]] auto& realm = *vm.current_realm(); if (vm.argument_count() < 1) return vm.throw_completion(JS::ErrorType::BadArgCountOne, "fetch"); auto arg0 = vm.argument(0); auto arg0_to_variant = [&vm, &realm](JS::Value arg0) -> JS::ThrowCompletionOr, DeprecatedString>> { // These might be unused. (void)vm; (void)realm; if (arg0.is_object()) { [[maybe_unused]] auto& arg0_object = arg0.as_object(); if (is(arg0_object)) { if (is(arg0_object)) return JS::make_handle(static_cast(arg0_object)); } } return TRY(arg0.to_string(vm)); }; Variant, DeprecatedString> input = TRY(arg0_to_variant(arg0)); auto arg1 = vm.argument(1); if (!arg1.is_nullish() && !arg1.is_object()) return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "RequestInit"); RequestInit init {}; auto body_property_value = JS::js_undefined(); if (arg1.is_object()) body_property_value = TRY(arg1.as_object().get("body")); if (!body_property_value.is_undefined()) { auto body_property_value_to_variant = [&vm, &realm](JS::Value body_property_value) -> JS::ThrowCompletionOr, JS::Handle, JS::Handle, JS::Handle, DeprecatedString>> { // These might be unused. (void)vm; (void)realm; if (body_property_value.is_object()) { [[maybe_unused]] auto& body_property_value_object = body_property_value.as_object(); if (is(body_property_value_object)) { if (is(body_property_value_object)) return JS::make_handle(static_cast(body_property_value_object)); if (is(body_property_value_object)) return JS::make_handle(static_cast(body_property_value_object)); if (is(body_property_value_object)) return JS::make_handle(static_cast(body_property_value_object)); } if (is(body_property_value_object)) return JS::make_handle(body_property_value_object); } return TRY(body_property_value.to_string(vm)); }; Optional, JS::Handle, JS::Handle, JS::Handle, DeprecatedString>> body_value; if (!body_property_value.is_nullish()) body_value = TRY(body_property_value_to_variant(body_property_value)); init.body = body_value; } auto cache_property_value = JS::js_undefined(); if (arg1.is_object()) cache_property_value = TRY(arg1.as_object().get("cache")); if (!cache_property_value.is_undefined()) { RequestCache cache_value { RequestCache::Default }; if (!cache_property_value.is_undefined()) { auto cache_property_value_string = TRY(cache_property_value.to_string(vm)); if (cache_property_value_string == "only-if-cached"sv) cache_value = RequestCache::OnlyIfCached; else if (cache_property_value_string == "default"sv) cache_value = RequestCache::Default; else if (cache_property_value_string == "no-store"sv) cache_value = RequestCache::NoStore; else if (cache_property_value_string == "force-cache"sv) cache_value = RequestCache::ForceCache; else if (cache_property_value_string == "reload"sv) cache_value = RequestCache::Reload; else if (cache_property_value_string == "no-cache"sv) cache_value = RequestCache::NoCache; else return vm.throw_completion(JS::ErrorType::InvalidEnumerationValue, cache_property_value_string, "RequestCache"); } init.cache = cache_value; } auto credentials_property_value = JS::js_undefined(); if (arg1.is_object()) credentials_property_value = TRY(arg1.as_object().get("credentials")); if (!credentials_property_value.is_undefined()) { RequestCredentials credentials_value { RequestCredentials::Omit }; if (!credentials_property_value.is_undefined()) { auto credentials_property_value_string = TRY(credentials_property_value.to_string(vm)); if (credentials_property_value_string == "same-origin"sv) credentials_value = RequestCredentials::SameOrigin; else if (credentials_property_value_string == "include"sv) credentials_value = RequestCredentials::Include; else if (credentials_property_value_string == "omit"sv) credentials_value = RequestCredentials::Omit; else return vm.throw_completion(JS::ErrorType::InvalidEnumerationValue, credentials_property_value_string, "RequestCredentials"); } init.credentials = credentials_value; } auto duplex_property_value = JS::js_undefined(); if (arg1.is_object()) duplex_property_value = TRY(arg1.as_object().get("duplex")); if (!duplex_property_value.is_undefined()) { RequestDuplex duplex_value { RequestDuplex::Half }; if (!duplex_property_value.is_undefined()) { auto duplex_property_value_string = TRY(duplex_property_value.to_string(vm)); if (duplex_property_value_string == "half"sv) duplex_value = RequestDuplex::Half; else return vm.throw_completion(JS::ErrorType::InvalidEnumerationValue, duplex_property_value_string, "RequestDuplex"); } init.duplex = duplex_value; } auto headers_property_value = JS::js_undefined(); if (arg1.is_object()) headers_property_value = TRY(arg1.as_object().get("headers")); if (!headers_property_value.is_undefined()) { auto headers_property_value_to_variant = [&vm, &realm](JS::Value headers_property_value) -> JS::ThrowCompletionOr>, OrderedHashMap>> { // These might be unused. (void)vm; (void)realm; if (headers_property_value.is_object()) { [[maybe_unused]] auto& headers_property_value_object = headers_property_value.as_object(); auto* method = TRY(headers_property_value.get_method(vm, *vm.well_known_symbol_iterator())); if (method) { auto iterator1 = TRY(JS::get_iterator(vm, headers_property_value, JS::IteratorHint::Sync, method)); Vector> headers_value; for (;;) { auto* next1 = TRY(JS::iterator_step(vm, iterator1)); if (!next1) break; auto next_item1 = TRY(JS::iterator_value(vm, *next1)); if (!next_item1.is_object()) return vm.throw_completion(JS::ErrorType::NotAnObject, next_item1.to_string_without_side_effects()); auto* iterator_method1 = TRY(next_item1.get_method(vm, *vm.well_known_symbol_iterator())); if (!iterator_method1) return vm.throw_completion(JS::ErrorType::NotIterable, next_item1.to_string_without_side_effects()); auto iterator2 = TRY(JS::get_iterator(vm, next_item1, JS::IteratorHint::Sync, iterator_method1)); Vector sequence_item1; for (;;) { auto* next2 = TRY(JS::iterator_step(vm, iterator2)); if (!next2) break; auto next_item2 = TRY(JS::iterator_value(vm, *next2)); DeprecatedString sequence_item2; if (next_item2.is_null() && false) { sequence_item2 = DeprecatedString::empty(); } else { sequence_item2 = TRY(next_item2.to_string(vm)); } sequence_item1.append(sequence_item2); } headers_value.append(sequence_item1); } return headers_value; } OrderedHashMap record_union_type; auto record_keys1 = TRY(headers_property_value_object.internal_own_property_keys()); for (auto& key1 : record_keys1) { auto property_key1 = MUST(JS::PropertyKey::from_value(vm, key1)); auto descriptor1 = TRY(headers_property_value_object.internal_get_own_property(property_key1)); if (!descriptor1.has_value() || !descriptor1->enumerable.has_value() || !descriptor1->enumerable.value()) continue; DeprecatedString typed_key1; if (key1.is_null() && false) { typed_key1 = DeprecatedString::empty(); } else { typed_key1 = TRY(key1.to_string(vm)); } auto value1 = TRY(headers_property_value_object.get(property_key1)); DeprecatedString typed_value1; if (value1.is_null() && false) { typed_value1 = DeprecatedString::empty(); } else { typed_value1 = TRY(value1.to_string(vm)); } record_union_type.set(typed_key1, typed_value1); } return record_union_type; } return vm.throw_completion("No union types matched"); }; Optional>, OrderedHashMap>> headers_value; if (!headers_property_value.is_nullish()) headers_value = TRY(headers_property_value_to_variant(headers_property_value)); init.headers = headers_value; } auto integrity_property_value = JS::js_undefined(); if (arg1.is_object()) integrity_property_value = TRY(arg1.as_object().get("integrity")); if (!integrity_property_value.is_undefined()) { DeprecatedString integrity_value; if (!integrity_property_value.is_undefined()) { if (integrity_property_value.is_null() && false) integrity_value = DeprecatedString::empty(); else integrity_value = TRY(integrity_property_value.to_string(vm)); } init.integrity = integrity_value; } auto keepalive_property_value = JS::js_undefined(); if (arg1.is_object()) keepalive_property_value = TRY(arg1.as_object().get("keepalive")); if (!keepalive_property_value.is_undefined()) { Optional keepalive_value; if (!keepalive_property_value.is_undefined()) keepalive_value = keepalive_property_value.to_boolean(); init.keepalive = keepalive_value; } auto method_property_value = JS::js_undefined(); if (arg1.is_object()) method_property_value = TRY(arg1.as_object().get("method")); if (!method_property_value.is_undefined()) { DeprecatedString method_value; if (!method_property_value.is_undefined()) { if (method_property_value.is_null() && false) method_value = DeprecatedString::empty(); else method_value = TRY(method_property_value.to_string(vm)); } init.method = method_value; } auto mode_property_value = JS::js_undefined(); if (arg1.is_object()) mode_property_value = TRY(arg1.as_object().get("mode")); if (!mode_property_value.is_undefined()) { RequestMode mode_value { RequestMode::Navigate }; if (!mode_property_value.is_undefined()) { auto mode_property_value_string = TRY(mode_property_value.to_string(vm)); if (mode_property_value_string == "navigate"sv) mode_value = RequestMode::Navigate; else if (mode_property_value_string == "same-origin"sv) mode_value = RequestMode::SameOrigin; else if (mode_property_value_string == "no-cors"sv) mode_value = RequestMode::NoCors; else if (mode_property_value_string == "cors"sv) mode_value = RequestMode::Cors; else return vm.throw_completion(JS::ErrorType::InvalidEnumerationValue, mode_property_value_string, "RequestMode"); } init.mode = mode_value; } auto redirect_property_value = JS::js_undefined(); if (arg1.is_object()) redirect_property_value = TRY(arg1.as_object().get("redirect")); if (!redirect_property_value.is_undefined()) { RequestRedirect redirect_value { RequestRedirect::Follow }; if (!redirect_property_value.is_undefined()) { auto redirect_property_value_string = TRY(redirect_property_value.to_string(vm)); if (redirect_property_value_string == "follow"sv) redirect_value = RequestRedirect::Follow; else if (redirect_property_value_string == "manual"sv) redirect_value = RequestRedirect::Manual; else if (redirect_property_value_string == "error"sv) redirect_value = RequestRedirect::Error; else return vm.throw_completion(JS::ErrorType::InvalidEnumerationValue, redirect_property_value_string, "RequestRedirect"); } init.redirect = redirect_value; } auto referrer_property_value = JS::js_undefined(); if (arg1.is_object()) referrer_property_value = TRY(arg1.as_object().get("referrer")); if (!referrer_property_value.is_undefined()) { DeprecatedString referrer_value; if (!referrer_property_value.is_undefined()) { if (referrer_property_value.is_null() && false) referrer_value = DeprecatedString::empty(); else referrer_value = TRY(referrer_property_value.to_string(vm)); } init.referrer = referrer_value; } auto referrer_policy_property_value = JS::js_undefined(); if (arg1.is_object()) referrer_policy_property_value = TRY(arg1.as_object().get("referrerPolicy")); if (!referrer_policy_property_value.is_undefined()) { ReferrerPolicy referrer_policy_value { ReferrerPolicy::Empty }; if (!referrer_policy_property_value.is_undefined()) { auto referrer_policy_property_value_string = TRY(referrer_policy_property_value.to_string(vm)); if (referrer_policy_property_value_string == ""sv) referrer_policy_value = ReferrerPolicy::Empty; else if (referrer_policy_property_value_string == "same-origin"sv) referrer_policy_value = ReferrerPolicy::SameOrigin; else if (referrer_policy_property_value_string == "origin"sv) referrer_policy_value = ReferrerPolicy::Origin; else if (referrer_policy_property_value_string == "origin-when-cross-origin"sv) referrer_policy_value = ReferrerPolicy::OriginWhenCrossOrigin; else if (referrer_policy_property_value_string == "strict-origin"sv) referrer_policy_value = ReferrerPolicy::StrictOrigin; else if (referrer_policy_property_value_string == "no-referrer"sv) referrer_policy_value = ReferrerPolicy::NoReferrer; else if (referrer_policy_property_value_string == "unsafe-url"sv) referrer_policy_value = ReferrerPolicy::UnsafeUrl; else if (referrer_policy_property_value_string == "no-referrer-when-downgrade"sv) referrer_policy_value = ReferrerPolicy::NoReferrerWhenDowngrade; else if (referrer_policy_property_value_string == "strict-origin-when-cross-origin"sv) referrer_policy_value = ReferrerPolicy::StrictOriginWhenCrossOrigin; else return vm.throw_completion(JS::ErrorType::InvalidEnumerationValue, referrer_policy_property_value_string, "ReferrerPolicy"); } init.referrer_policy = referrer_policy_value; } auto signal_property_value = JS::js_undefined(); if (arg1.is_object()) signal_property_value = TRY(arg1.as_object().get("signal")); if (!signal_property_value.is_undefined()) { AbortSignal* signal_value = nullptr; if (!signal_property_value.is_nullish()) { if (!signal_property_value.is_object() || !is(signal_property_value.as_object())) return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "AbortSignal"); signal_value = &static_cast(signal_property_value.as_object()); } init.signal = signal_value; } auto window_property_value = JS::js_undefined(); if (arg1.is_object()) window_property_value = TRY(arg1.as_object().get("window")); if (!window_property_value.is_undefined()) { JS::Value window_value = JS::js_undefined(); if (!window_property_value.is_undefined()) window_value = window_property_value; init.window = window_value; } [[maybe_unused]] auto retval = TRY(throw_dom_exception_if_needed(vm, [&] { return Fetch::fetch_impl(vm, input, init); })); return retval; } // NOLINTEND }