/src/serenity/Userland/Libraries/LibWeb/HTML/HTMLFormControlsCollection.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2023, Shannon Booth <shannon@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <LibWeb/Bindings/HTMLFormControlsCollectionPrototype.h> |
8 | | #include <LibWeb/Bindings/Intrinsics.h> |
9 | | #include <LibWeb/DOM/Element.h> |
10 | | #include <LibWeb/DOM/HTMLCollection.h> |
11 | | #include <LibWeb/DOM/ParentNode.h> |
12 | | #include <LibWeb/HTML/HTMLFormControlsCollection.h> |
13 | | #include <LibWeb/HTML/RadioNodeList.h> |
14 | | |
15 | | namespace Web::HTML { |
16 | | |
17 | | JS_DEFINE_ALLOCATOR(HTMLFormControlsCollection); |
18 | | |
19 | | JS::NonnullGCPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(DOM::ParentNode& root, Scope scope, Function<bool(DOM::Element const&)> filter) |
20 | 0 | { |
21 | 0 | return root.heap().allocate<HTMLFormControlsCollection>(root.realm(), root, scope, move(filter)); |
22 | 0 | } |
23 | | |
24 | | HTMLFormControlsCollection::HTMLFormControlsCollection(DOM::ParentNode& root, Scope scope, Function<bool(DOM::Element const&)> filter) |
25 | 0 | : DOM::HTMLCollection(root, scope, move(filter)) |
26 | 0 | { |
27 | 0 | } |
28 | | |
29 | 0 | HTMLFormControlsCollection::~HTMLFormControlsCollection() = default; |
30 | | |
31 | | void HTMLFormControlsCollection::initialize(JS::Realm& realm) |
32 | 0 | { |
33 | 0 | Base::initialize(realm); |
34 | 0 | WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLFormControlsCollection); |
35 | 0 | } |
36 | | |
37 | | // https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-htmlformcontrolscollection-nameditem |
38 | | Variant<Empty, DOM::Element*, JS::Handle<RadioNodeList>> HTMLFormControlsCollection::named_item_or_radio_node_list(FlyString const& name) const |
39 | 0 | { |
40 | | // 1. If name is the empty string, return null and stop the algorithm. |
41 | 0 | if (name.is_empty()) |
42 | 0 | return {}; |
43 | | |
44 | | // 2. If, at the time the method is called, there is exactly one node in the collection that has either an id attribute or a name attribute equal to name, then return that node and stop the algorithm. |
45 | | // 3. Otherwise, if there are no nodes in the collection that have either an id attribute or a name attribute equal to name, then return null and stop the algorithm. |
46 | 0 | DOM::Element* matching_element = nullptr; |
47 | 0 | bool multiple_matching = false; |
48 | |
|
49 | 0 | auto collection = collect_matching_elements(); |
50 | 0 | for (auto const& element : collection) { |
51 | 0 | if (element->id() != name && element->name() != name) |
52 | 0 | continue; |
53 | | |
54 | 0 | if (matching_element) { |
55 | 0 | multiple_matching = true; |
56 | 0 | break; |
57 | 0 | } |
58 | | |
59 | 0 | matching_element = element; |
60 | 0 | } |
61 | |
|
62 | 0 | if (!matching_element) |
63 | 0 | return {}; |
64 | | |
65 | 0 | if (!multiple_matching) |
66 | 0 | return matching_element; |
67 | | |
68 | | // 4. Otherwise, create a new RadioNodeList object representing a live view of the HTMLFormControlsCollection object, further filtered so that the only nodes in the |
69 | | // RadioNodeList object are those that have either an id attribute or a name attribute equal to name. The nodes in the RadioNodeList object must be sorted in tree |
70 | | // order. Return that RadioNodeList object. |
71 | 0 | return JS::make_handle(RadioNodeList::create(realm(), root(), DOM::LiveNodeList::Scope::Descendants, [name](auto const& node) { |
72 | 0 | if (!is<DOM::Element>(node)) |
73 | 0 | return false; |
74 | | |
75 | 0 | auto const& element = verify_cast<DOM::Element>(node); |
76 | 0 | return element.id() == name || element.name() == name; |
77 | 0 | })); |
78 | 0 | } |
79 | | |
80 | | JS::Value HTMLFormControlsCollection::named_item_value(FlyString const& name) const |
81 | 0 | { |
82 | 0 | return named_item_or_radio_node_list(name).visit( |
83 | 0 | [](Empty) -> JS::Value { return JS::js_undefined(); }, |
84 | 0 | [](auto const& value) -> JS::Value { return value; }); Unexecuted instantiation: HTMLFormControlsCollection.cpp:JS::Value Web::HTML::HTMLFormControlsCollection::named_item_value(AK::FlyString const&) const::$_1::operator()<Web::DOM::Element*>(Web::DOM::Element* const&) const Unexecuted instantiation: HTMLFormControlsCollection.cpp:JS::Value Web::HTML::HTMLFormControlsCollection::named_item_value(AK::FlyString const&) const::$_1::operator()<JS::Handle<Web::HTML::RadioNodeList> >(JS::Handle<Web::HTML::RadioNodeList> const&) const |
85 | 0 | } |
86 | | |
87 | | } |