Browse Source

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 10 months ago
parent
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);