Explorar el Código

LibWeb: Do not assume the shadow root has a host when updating selection

For example, if the shadow root was detached from the document in some
manner, its host will be null.
Timothy Flynn hace 10 meses
padre
commit
8fb2cc2be1

+ 1 - 0
Tests/LibWeb/Text/expected/DOM/FormAssociatedElement-selection-type-change.txt

@@ -0,0 +1 @@
+12389   PASS (didn't crash)

+ 17 - 0
Tests/LibWeb/Text/input/DOM/FormAssociatedElement-selection-type-change.html

@@ -0,0 +1,17 @@
+<input type="text" id="input" value="12389" />
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        let input = document.getElementById("input");
+
+        input.focus();
+        input.select();
+
+        input.type = "number";
+
+        const rect = input.getBoundingClientRect();
+        internals.click(rect.x + rect.width / 2, rect.y + rect.height / 2);
+
+        println("PASS (didn't crash)");
+    });
+</script>

+ 7 - 5
Userland/Libraries/LibWeb/Page/EventHandler.cpp

@@ -1138,7 +1138,9 @@ void EventHandler::update_selection_range_for_input_or_textarea()
     auto& root = node.root();
     if (!root.is_shadow_root())
         return;
-    auto& shadow_host = *root.parent_or_shadow_host();
+    auto* shadow_host = root.parent_or_shadow_host();
+    if (!shadow_host)
+        return;
 
     // Invoke "set the selection range" on the form associated element
     auto selection_start = range->start_offset();
@@ -1147,10 +1149,10 @@ void EventHandler::update_selection_range_for_input_or_textarea()
     auto direction = HTML::SelectionDirection::Forward;
 
     Optional<HTML::FormAssociatedTextControlElement&> target {};
-    if (is<HTML::HTMLInputElement>(shadow_host))
-        target = static_cast<HTML::HTMLInputElement&>(shadow_host);
-    else if (is<HTML::HTMLTextAreaElement>(shadow_host))
-        target = static_cast<HTML::HTMLTextAreaElement&>(shadow_host);
+    if (is<HTML::HTMLInputElement>(*shadow_host))
+        target = static_cast<HTML::HTMLInputElement&>(*shadow_host);
+    else if (is<HTML::HTMLTextAreaElement>(*shadow_host))
+        target = static_cast<HTML::HTMLTextAreaElement&>(*shadow_host);
 
     if (target.has_value())
         target.value().set_the_selection_range(selection_start, selection_end, direction);