Files
ladybird/Libraries/LibWeb/HTML/RadioNodeList.cpp
Shannon Booth fd44da6829 LibWeb/Bindings: Emit one bindings header and cpp per IDL
Previously, the LibWeb bindings generator would output multiple per
interface files like Prototype/Constructor/Namespace/GlobalMixin
depending on the contents of that IDL file.

This complicates the build system as it means that it does not know
what files will be generated without knowledge of the contents of that
IDL file.

Instead, for each IDL file only generate a single Bindings/<IDLFile>.h
and Bindings/<IDLFile>.cpp.
2026-04-21 07:36:13 +02:00

106 lines
3.9 KiB
C++

/*
* Copyright (c) 2023, Shannon Booth <shannon@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/RadioNodeList.h>
#include <LibWeb/DOM/Element.h>
#include <LibWeb/HTML/HTMLInputElement.h>
#include <LibWeb/HTML/RadioNodeList.h>
namespace Web::HTML {
GC_DEFINE_ALLOCATOR(RadioNodeList);
GC::Ref<RadioNodeList> RadioNodeList::create(JS::Realm& realm, DOM::Node const& root, Scope scope, Function<bool(DOM::Node const&)> filter)
{
return realm.create<RadioNodeList>(realm, root, scope, move(filter));
}
RadioNodeList::RadioNodeList(JS::Realm& realm, DOM::Node const& root, Scope scope, Function<bool(DOM::Node const&)> filter)
: DOM::LiveNodeList(realm, root, scope, move(filter))
{
}
RadioNodeList::~RadioNodeList() = default;
void RadioNodeList::initialize(JS::Realm& realm)
{
WEB_SET_PROTOTYPE_FOR_INTERFACE(RadioNodeList);
Base::initialize(realm);
}
static HTMLInputElement const* radio_button(DOM::Node const& node)
{
if (!is<HTMLInputElement>(node))
return nullptr;
auto const& input_element = as<HTMLInputElement>(node);
if (input_element.type_state() != HTMLInputElement::TypeAttributeState::RadioButton)
return nullptr;
return &input_element;
}
// https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-radionodelist-value
FlyString RadioNodeList::value() const
{
// 1. Let element be the first element in tree order represented by the RadioNodeList object that is an input element whose type
// attribute is in the Radio Button state and whose checkedness is true. Otherwise, let it be null.
auto* element = as<HTMLInputElement>(first_matching([](DOM::Node const& node) -> bool {
auto const* button = radio_button(node);
if (!button)
return false;
return button->checked();
}));
// 2. If element is null, return the empty string.
if (!element)
return String {};
// 3. If element is an element with no value attribute, return the string "on".
// 4. Otherwise, return the value of element's value attribute.
return element->get_attribute(AttributeNames::value).value_or("on"_string);
}
void RadioNodeList::set_value(FlyString const& value)
{
HTMLInputElement* element = nullptr;
// 1. If the new value is the string "on": let element be the first element in tree order represented by the RadioNodeList object
// that is an input element whose type attribute is in the Radio Button state and whose value content attribute is either absent,
// or present and equal to the new value, if any. If no such element exists, then instead let element be null.
if (value == "on"sv) {
element = as<HTMLInputElement>(first_matching([&value](auto const& node) {
auto const* button = radio_button(node);
if (!button)
return false;
auto const maybe_value = button->get_attribute(AttributeNames::value);
return !maybe_value.has_value() || maybe_value.value() == value;
}));
}
// 2. Otherwise: let element be the first element in tree order represented by the RadioNodeList object that is an input element whose
// type attribute is in the Radio Button state and whose value content attribute is present and equal to the new value, if any. If
// no such element exists, then instead let element be null.
else {
element = as<HTMLInputElement>(first_matching([&value](auto const& node) {
auto const* button = radio_button(node);
if (!button)
return false;
auto const maybe_value = button->get_attribute(AttributeNames::value);
return maybe_value.has_value() && maybe_value.value() == value;
}));
}
// 3. If element is not null, then set its checkedness to true.
if (element)
element->set_checked(true);
}
}