Skip to content

Acid 3 numbered test 43 failure #7398

@shannonbooth

Description

@shannonbooth

I reduced to the following test page

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Acid3 Test 43 Minimized</title>
    <style>
        #test-input { position: absolute; z-index: 0; }
        #test-input:checked { z-index: 1; }
    </style>
</head>
<body>
    <div id="status">Testing...</div>

    <script>
        const status = document.getElementById('status');
        
        try {
            // 1. Create a radio button
            const input = document.createElement('input');
            input.id = 'test-input';
            input.type = 'radio';
            document.body.appendChild(input);

            // 2. Set it to checked (z-index should be 1)
            input.checked = true;
            let zIndex = getComputedStyle(input).zIndex;
            if (zIndex !== "1") throw new Error("Initial :checked state failed");

            // 3. Trigger the bug: Change type to 'text'
            // Text inputs cannot be :checked. The z-index must revert to 0.
            input.type = 'text';
            zIndex = getComputedStyle(input).zIndex;

            if (zIndex === "0") {
                status.innerHTML = "<span style='color: green;'>PASS: Selector state updated on type change.</span>";
            } else {
                throw new Error("FAIL: Text field still matches :checked (z-index is " + zIndex + ")");
            }
        } catch (e) {
            status.innerHTML = "<span style='color: red; font-weight: bold;'>" + e.message + "</span>";
        }
    </script>
</body>
</html>

Two issues here:

  1. We need to invalidate :checked if type attribute changes for an input element (patch attached below)
  2. Even with that, z-index is not being updated based on :checked (This seems like the fundamental issue here, still trying to investigate)
diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp
index 8c6c57509f4..8e481cc26f4 100644
--- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp
@@ -1534,6 +1534,16 @@ void HTMLInputElement::type_attribute_changed(TypeAttributeState old_state, Type
     auto new_value_attribute_mode = value_attribute_mode_for_type_state(new_state);
     auto old_value_attribute_mode = value_attribute_mode_for_type_state(old_state);
 
+    if (checked_applies(old_state) != checked_applies(new_state)) {
+        invalidate_style(
+            DOM::StyleInvalidationReason::HTMLInputElementSetChecked,
+            {
+                { .type = CSS::InvalidationSet::Property::Type::PseudoClass, .value = CSS::PseudoClass::Checked },
+                { .type = CSS::InvalidationSet::Property::Type::PseudoClass, .value = CSS::PseudoClass::Unchecked },
+            },
+            {});
+    }
+
     // 1. If the previous state of the element's type attribute put the value IDL attribute in the value mode, and the element's
     //    value is not the empty string, and the new state of the element's type attribute puts the value IDL attribute in either
     //    the default mode or the default/on mode, then set the element's value content attribute to the element's value.
@@ -3273,9 +3283,9 @@ bool HTMLInputElement::required_applies() const
 }
 
 // https://html.spec.whatwg.org/multipage/input.html#do-not-apply
-bool HTMLInputElement::checked_applies() const
+bool HTMLInputElement::checked_applies(TypeAttributeState type_state)
 {
-    switch (type_state()) {
+    switch (type_state) {
     case TypeAttributeState::Checkbox:
     case TypeAttributeState::RadioButton:
         return true;
@@ -3284,6 +3294,11 @@ bool HTMLInputElement::checked_applies() const
     }
 }
 
+bool HTMLInputElement::checked_applies() const
+{
+    return checked_applies(type_state());
+}
+
 bool HTMLInputElement::has_selectable_text() const
 {
     // Potential FIXME: Date, Month, Week, Time and LocalDateAndTime are rendered as a basic text input for now,

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions