/* * Copyright (c) 2022, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include namespace Web::Bindings { template<> void Intrinsics::create_web_prototype_and_constructor(JS::Realm& realm) { auto prototype = heap().allocate(realm, realm).release_allocated_value_but_fixme_should_propagate_errors(); m_prototypes.set("HeadersIterator"sv, prototype); } } namespace Web::Fetch { WebIDL::ExceptionOr> HeadersIterator::create(Headers const& headers, JS::Object::PropertyKind iteration_kind) { return MUST_OR_THROW_OOM(headers.heap().allocate(headers.realm(), headers, iteration_kind)); } HeadersIterator::HeadersIterator(Headers const& headers, JS::Object::PropertyKind iteration_kind) : PlatformObject(headers.realm()) , m_headers(headers) , m_iteration_kind(iteration_kind) { } HeadersIterator::~HeadersIterator() = default; JS::ThrowCompletionOr HeadersIterator::initialize(JS::Realm& realm) { MUST_OR_THROW_OOM(Base::initialize(realm)); set_prototype(&Bindings::ensure_web_prototype(realm, "HeadersIterator")); return {}; } void HeadersIterator::visit_edges(JS::Cell::Visitor& visitor) { Base::visit_edges(visitor); visitor.visit(m_headers); } // https://webidl.spec.whatwg.org/#es-iterable, Step 2 JS::ThrowCompletionOr HeadersIterator::next() { // The value pairs to iterate over are the return value of running sort and combine with this’s header list. auto value_pairs_to_iterate_over = [&]() -> JS::ThrowCompletionOr> { auto headers_or_error = m_headers->m_header_list->sort_and_combine(); if (headers_or_error.is_error()) return vm().throw_completion(JS::ErrorType::NotEnoughMemoryToAllocate); return headers_or_error.release_value(); }; auto pairs = TRY(value_pairs_to_iterate_over()); if (m_index >= pairs.size()) return create_iterator_result_object(vm(), JS::js_undefined(), true); auto const& pair = pairs[m_index++]; StringView pair_name { pair.name }; StringView pair_value { pair.value }; switch (m_iteration_kind) { case JS::Object::PropertyKind::Key: return create_iterator_result_object(vm(), MUST_OR_THROW_OOM(JS::PrimitiveString::create(vm(), pair_name)), false); case JS::Object::PropertyKind::Value: return create_iterator_result_object(vm(), MUST_OR_THROW_OOM(JS::PrimitiveString::create(vm(), pair_value)), false); case JS::Object::PropertyKind::KeyAndValue: { auto array = JS::Array::create_from(realm(), { MUST_OR_THROW_OOM(JS::PrimitiveString::create(vm(), pair_name)), MUST_OR_THROW_OOM(JS::PrimitiveString::create(vm(), pair_value)) }); return create_iterator_result_object(vm(), array, false); } default: VERIFY_NOT_REACHED(); } } }