浏览代码

LibWeb: Don't crash on clicking a label with an associated text input

Previously, we assumed that all label control paintables were of type
`LabelablePaintable`. This caused a crash when clicking on a label with
a text input control.
Tim Ledbetter 1 年之前
父节点
当前提交
7d192ed8c1

+ 1 - 0
Tests/LibWeb/Text/expected/HTML/click-label-to-focus-text-input.txt

@@ -0,0 +1 @@
+Label   Text input focused

+ 18 - 0
Tests/LibWeb/Text/input/HTML/click-label-to-focus-text-input.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+body {
+    margin: 0;
+}
+</style>
+<label id="lbl">Label<input id="textInput" type="text"></label>
+<script src="../include.js"></script>
+<script>
+    asyncTest((done) => {
+        textInput.addEventListener("focusin", () => {
+            println("Text input focused");
+            done();
+        });
+    
+        internals.click(10, 10);
+    });
+</script>

+ 3 - 3
Userland/Libraries/LibWeb/Layout/Label.cpp

@@ -29,7 +29,7 @@ void Label::handle_mousedown_on_label(Badge<Painting::TextPaintable>, CSSPixelPo
     if (button != GUI::MouseButton::Primary)
         return;
 
-    if (auto control = dom_node().control(); control && control->paintable()) {
+    if (auto control = dom_node().control(); control && is<Painting::LabelablePaintable>(control->paintable())) {
         auto& labelable_paintable = verify_cast<Painting::LabelablePaintable>(*control->paintable());
         labelable_paintable.handle_associated_label_mousedown({});
     }
@@ -42,7 +42,7 @@ void Label::handle_mouseup_on_label(Badge<Painting::TextPaintable>, CSSPixelPoin
     if (!m_tracking_mouse || button != GUI::MouseButton::Primary)
         return;
 
-    if (auto control = dom_node().control(); control && control->paintable()) {
+    if (auto control = dom_node().control(); control && is<Painting::LabelablePaintable>(control->paintable())) {
         bool is_inside_control = control->paintable_box()->absolute_rect().contains(position);
         bool is_inside_label = paintable_box()->absolute_rect().contains(position);
         if (is_inside_control || is_inside_label) {
@@ -59,7 +59,7 @@ void Label::handle_mousemove_on_label(Badge<Painting::TextPaintable>, CSSPixelPo
     if (!m_tracking_mouse)
         return;
 
-    if (auto control = dom_node().control(); control && control->paintable()) {
+    if (auto control = dom_node().control(); control && is<Painting::LabelablePaintable>(control->paintable())) {
         bool is_inside_control = control->paintable_box()->absolute_rect().contains(position);
         bool is_inside_label = paintable_box()->absolute_rect().contains(position);
         auto& labelable_paintable = verify_cast<Painting::LabelablePaintable>(*control->paintable());