diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp
index 369c980f9f..e584051da2 100644
--- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp
@@ -158,15 +158,13 @@ void HTMLInputElement::adjust_computed_style(CSS::ComputedProperties& style)
style.set_property(CSS::PropertyID::LineHeight, CSS::CSSKeywordValue::create(CSS::Keyword::Normal));
}
-void HTMLInputElement::set_checked(bool checked, ChangeSource change_source)
+void HTMLInputElement::set_checked(bool checked)
{
- if (m_checked == checked)
- return;
-
// The dirty checkedness flag must be initially set to false when the element is created,
// and must be set to true whenever the user interacts with the control in a way that changes the checkedness.
- if (change_source == ChangeSource::User)
- m_dirty_checkedness = true;
+ m_dirty_checkedness = true;
+ if (m_checked == checked)
+ return;
m_checked = checked;
@@ -181,9 +179,9 @@ void HTMLInputElement::set_checked_binding(bool checked)
if (checked)
set_checked_within_group();
else
- set_checked(false, ChangeSource::Programmatic);
+ set_checked(false);
} else {
- set_checked(checked, ChangeSource::Programmatic);
+ set_checked(checked);
}
}
@@ -1249,16 +1247,13 @@ void HTMLInputElement::did_lose_focus()
void HTMLInputElement::form_associated_element_attribute_changed(FlyString const& name, Optional const& value, Optional const&)
{
if (name == HTML::AttributeNames::checked) {
- if (!value.has_value()) {
- // When the checked content attribute is removed, if the control does not have dirty checkedness,
- // the user agent must set the checkedness of the element to false.
- if (!m_dirty_checkedness)
- set_checked(false, ChangeSource::Programmatic);
- } else {
- // When the checked content attribute is added, if the control does not have dirty checkedness,
- // the user agent must set the checkedness of the element to true
- if (!m_dirty_checkedness)
- set_checked(true, ChangeSource::Programmatic);
+ // https://html.spec.whatwg.org/multipage/input.html#the-input-element:concept-input-checked-dirty-2
+ // When the checked content attribute is added, if the control does not have dirty checkedness, the user agent must set the checkedness of the element to true;
+ // when the checked content attribute is removed, if the control does not have dirty checkedness, the user agent must set the checkedness of the element to false.
+ if (!m_dirty_checkedness) {
+ set_checked(value.has_value());
+ // set_checked() sets the dirty checkedness flag. We reset it here sinceit shouldn't be set when updating the attribute value
+ m_dirty_checkedness = false;
}
} else if (name == HTML::AttributeNames::type) {
auto new_type_attribute_state = parse_type_attribute(value.value_or(String {}));
@@ -1757,7 +1752,7 @@ void HTMLInputElement::set_checked_within_group()
if (checked())
return;
- set_checked(true, ChangeSource::User);
+ set_checked(true);
// No point iterating the tree if we have an empty name.
if (!name().has_value() || name()->is_empty())
@@ -1765,7 +1760,7 @@ void HTMLInputElement::set_checked_within_group()
root().for_each_in_inclusive_subtree_of_type([&](auto& element) {
if (element.checked() && &element != this && is_in_same_radio_button_group(*this, element))
- element.set_checked(false, ChangeSource::User);
+ element.set_checked(false);
return TraversalDecision::Continue;
});
}
@@ -1781,7 +1776,7 @@ void HTMLInputElement::legacy_pre_activation_behavior()
// false, false if it is true) and set this element's indeterminate IDL
// attribute to false.
if (type_state() == TypeAttributeState::Checkbox) {
- set_checked(!checked(), ChangeSource::User);
+ set_checked(!checked());
set_indeterminate(false);
}
@@ -1809,7 +1804,7 @@ void HTMLInputElement::legacy_cancelled_activation_behavior()
// element's checkedness and the element's indeterminate IDL attribute back
// to the values they had before the legacy-pre-activation behavior was run.
if (type_state() == TypeAttributeState::Checkbox) {
- set_checked(m_before_legacy_pre_activation_behavior_checked, ChangeSource::Programmatic);
+ set_checked(m_before_legacy_pre_activation_behavior_checked);
set_indeterminate(m_before_legacy_pre_activation_behavior_indeterminate);
}
@@ -1834,7 +1829,7 @@ void HTMLInputElement::legacy_cancelled_activation_behavior()
}
if (!did_reselect_previous_element)
- set_checked(false, ChangeSource::User);
+ set_checked(false);
}
}
diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.h b/Libraries/LibWeb/HTML/HTMLInputElement.h
index 1c1ae78def..44538ed3e9 100644
--- a/Libraries/LibWeb/HTML/HTMLInputElement.h
+++ b/Libraries/LibWeb/HTML/HTMLInputElement.h
@@ -88,11 +88,7 @@ public:
Optional placeholder_value() const;
bool checked() const { return m_checked; }
- enum class ChangeSource {
- Programmatic,
- User,
- };
- void set_checked(bool, ChangeSource = ChangeSource::Programmatic);
+ void set_checked(bool);
bool checked_binding() const { return checked(); }
void set_checked_binding(bool);
diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/cloning-steps.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/cloning-steps.txt
new file mode 100644
index 0000000000..bcb6eae248
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/cloning-steps.txt
@@ -0,0 +1,73 @@
+Harness status: OK
+
+Found 68 tests
+
+68 Pass
+Pass input element's value should be cloned
+Pass input element's dirty value flag should be cloned, so setAttribute doesn't affect the cloned input's value
+Pass input[type=button] element's indeterminateness should be cloned
+Pass input[type=button] element's checkedness should be cloned
+Pass input[type=button] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=checkbox] element's indeterminateness should be cloned
+Pass input[type=checkbox] element's checkedness should be cloned
+Pass input[type=checkbox] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=color] element's indeterminateness should be cloned
+Pass input[type=color] element's checkedness should be cloned
+Pass input[type=color] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=date] element's indeterminateness should be cloned
+Pass input[type=date] element's checkedness should be cloned
+Pass input[type=date] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=datetime-local] element's indeterminateness should be cloned
+Pass input[type=datetime-local] element's checkedness should be cloned
+Pass input[type=datetime-local] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=email] element's indeterminateness should be cloned
+Pass input[type=email] element's checkedness should be cloned
+Pass input[type=email] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=file] element's indeterminateness should be cloned
+Pass input[type=file] element's checkedness should be cloned
+Pass input[type=file] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=hidden] element's indeterminateness should be cloned
+Pass input[type=hidden] element's checkedness should be cloned
+Pass input[type=hidden] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=image] element's indeterminateness should be cloned
+Pass input[type=image] element's checkedness should be cloned
+Pass input[type=image] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=month] element's indeterminateness should be cloned
+Pass input[type=month] element's checkedness should be cloned
+Pass input[type=month] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=number] element's indeterminateness should be cloned
+Pass input[type=number] element's checkedness should be cloned
+Pass input[type=number] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=password] element's indeterminateness should be cloned
+Pass input[type=password] element's checkedness should be cloned
+Pass input[type=password] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=radio] element's indeterminateness should be cloned
+Pass input[type=radio] element's checkedness should be cloned
+Pass input[type=radio] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=range] element's indeterminateness should be cloned
+Pass input[type=range] element's checkedness should be cloned
+Pass input[type=range] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=reset] element's indeterminateness should be cloned
+Pass input[type=reset] element's checkedness should be cloned
+Pass input[type=reset] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=search] element's indeterminateness should be cloned
+Pass input[type=search] element's checkedness should be cloned
+Pass input[type=search] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=submit] element's indeterminateness should be cloned
+Pass input[type=submit] element's checkedness should be cloned
+Pass input[type=submit] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=tel] element's indeterminateness should be cloned
+Pass input[type=tel] element's checkedness should be cloned
+Pass input[type=tel] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=text] element's indeterminateness should be cloned
+Pass input[type=text] element's checkedness should be cloned
+Pass input[type=text] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=time] element's indeterminateness should be cloned
+Pass input[type=time] element's checkedness should be cloned
+Pass input[type=time] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=url] element's indeterminateness should be cloned
+Pass input[type=url] element's checkedness should be cloned
+Pass input[type=url] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
+Pass input[type=week] element's indeterminateness should be cloned
+Pass input[type=week] element's checkedness should be cloned
+Pass input[type=week] element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/cloning-steps.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/cloning-steps.html
new file mode 100644
index 0000000000..3e7ccb9b39
--- /dev/null
+++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/cloning-steps.html
@@ -0,0 +1,64 @@
+
+
+Cloning of input elements
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/input-types.js b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/input-types.js
new file mode 100644
index 0000000000..4456751052
--- /dev/null
+++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/input-types.js
@@ -0,0 +1,24 @@
+export default [
+ "button",
+ "checkbox",
+ "color",
+ "date",
+ "datetime-local",
+ "email",
+ "file",
+ "hidden",
+ "image",
+ "month",
+ "number",
+ "password",
+ "radio",
+ "range",
+ "reset",
+ "search",
+ "submit",
+ "tel",
+ "text",
+ "time",
+ "url",
+ "week",
+];