Coverage Report

Created: 2026-02-14 08:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibWeb/Fetch/HeadersIterator.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#include <LibJS/Runtime/Array.h>
8
#include <LibJS/Runtime/Iterator.h>
9
#include <LibWeb/Bindings/HeadersIteratorPrototype.h>
10
#include <LibWeb/Bindings/Intrinsics.h>
11
#include <LibWeb/Fetch/HeadersIterator.h>
12
13
namespace Web::Bindings {
14
15
template<>
16
void Intrinsics::create_web_prototype_and_constructor<HeadersIteratorPrototype>(JS::Realm& realm)
17
0
{
18
0
    auto prototype = heap().allocate<HeadersIteratorPrototype>(realm, realm);
19
0
    m_prototypes.set("HeadersIterator"_fly_string, prototype);
20
0
}
21
22
}
23
24
namespace Web::Fetch {
25
26
JS_DEFINE_ALLOCATOR(HeadersIterator);
27
28
JS::NonnullGCPtr<HeadersIterator> HeadersIterator::create(Headers const& headers, JS::Object::PropertyKind iteration_kind)
29
0
{
30
0
    return headers.heap().allocate<HeadersIterator>(headers.realm(), headers, iteration_kind);
31
0
}
32
33
HeadersIterator::HeadersIterator(Headers const& headers, JS::Object::PropertyKind iteration_kind)
34
0
    : PlatformObject(headers.realm())
35
0
    , m_headers(headers)
36
0
    , m_iteration_kind(iteration_kind)
37
0
{
38
0
}
39
40
0
HeadersIterator::~HeadersIterator() = default;
41
42
void HeadersIterator::initialize(JS::Realm& realm)
43
0
{
44
0
    Base::initialize(realm);
45
0
    WEB_SET_PROTOTYPE_FOR_INTERFACE(HeadersIterator);
46
0
}
47
48
void HeadersIterator::visit_edges(JS::Cell::Visitor& visitor)
49
0
{
50
0
    Base::visit_edges(visitor);
51
0
    visitor.visit(m_headers);
52
0
}
53
54
// https://webidl.spec.whatwg.org/#es-iterable, Step 2
55
JS::NonnullGCPtr<JS::Object> HeadersIterator::next()
56
0
{
57
    // The value pairs to iterate over are the return value of running sort and combine with this’s header list.
58
0
    auto value_pairs_to_iterate_over = [&]() {
59
0
        return m_headers->m_header_list->sort_and_combine();
60
0
    };
61
62
0
    auto pairs = value_pairs_to_iterate_over();
63
64
0
    if (m_index >= pairs.size())
65
0
        return create_iterator_result_object(vm(), JS::js_undefined(), true);
66
67
0
    auto const& pair = pairs[m_index++];
68
0
    StringView pair_name { pair.name };
69
0
    StringView pair_value { pair.value };
70
71
0
    switch (m_iteration_kind) {
72
0
    case JS::Object::PropertyKind::Key:
73
0
        return create_iterator_result_object(vm(), JS::PrimitiveString::create(vm(), pair_name), false);
74
0
    case JS::Object::PropertyKind::Value:
75
0
        return create_iterator_result_object(vm(), JS::PrimitiveString::create(vm(), pair_value), false);
76
0
    case JS::Object::PropertyKind::KeyAndValue: {
77
0
        auto array = JS::Array::create_from(realm(), { JS::PrimitiveString::create(vm(), pair_name), JS::PrimitiveString::create(vm(), pair_value) });
78
0
        return create_iterator_result_object(vm(), array, false);
79
0
    }
80
0
    default:
81
0
        VERIFY_NOT_REACHED();
82
0
    }
83
0
}
84
85
}