diff --git a/Libraries/LibWeb/Page/EventHandler.cpp b/Libraries/LibWeb/Page/EventHandler.cpp index 910f42fe3e9..b5e27638729 100644 --- a/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Libraries/LibWeb/Page/EventHandler.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -40,8 +41,6 @@ namespace Web { static GC::Ptr dom_node_for_event_dispatch(Painting::Paintable& paintable) { - if (auto node = paintable.mouse_event_target()) - return node; if (auto node = paintable.dom_node()) return node; auto* layout_parent = paintable.layout_node().parent(); @@ -53,6 +52,17 @@ static GC::Ptr dom_node_for_event_dispatch(Painting::Paintable& paint return nullptr; } +static DOM::Node* input_control_associated_with_ancestor_label_element(Painting::Paintable& paintable) +{ + if (is(paintable.layout_node())) { + auto const& label = verify_cast(paintable.layout_node()); + return label.dom_node().control().ptr(); + } + if (auto const* label = paintable.layout_node().first_ancestor_of_type()) + return label->dom_node().control().ptr(); + return nullptr; +} + static bool parent_element_for_event_dispatch(Painting::Paintable& paintable, GC::Ptr& node, Layout::Node*& layout_node) { auto* current_ancestor_node = node.ptr(); @@ -351,6 +361,12 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix } } } + + if (auto* input_control = input_control_associated_with_ancestor_label_element(*paintable)) { + if (button == UIEvents::MouseButton::Primary) { + input_control->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::click, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors()); + } + } } } @@ -434,10 +450,14 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP if (dom_node) { // See if we want to focus something. GC::Ptr focus_candidate; - for (auto candidate = node; candidate; candidate = candidate->parent_or_shadow_host()) { - if (candidate->is_focusable()) { - focus_candidate = candidate; - break; + if (auto* input_control = input_control_associated_with_ancestor_label_element(*paintable)) { + focus_candidate = input_control; + } else { + for (auto candidate = node; candidate; candidate = candidate->parent_or_shadow_host()) { + if (candidate->is_focusable()) { + focus_candidate = candidate; + break; + } } } diff --git a/Libraries/LibWeb/Painting/Paintable.h b/Libraries/LibWeb/Painting/Paintable.h index 738c85f00e3..12cccb5f557 100644 --- a/Libraries/LibWeb/Painting/Paintable.h +++ b/Libraries/LibWeb/Painting/Paintable.h @@ -179,7 +179,6 @@ public: virtual DispatchEventOfSameName handle_mousedown(Badge, CSSPixelPoint, unsigned button, unsigned modifiers); virtual DispatchEventOfSameName handle_mouseup(Badge, CSSPixelPoint, unsigned button, unsigned modifiers); virtual DispatchEventOfSameName handle_mousemove(Badge, CSSPixelPoint, unsigned buttons, unsigned modifiers); - virtual DOM::Node* mouse_event_target() const { return nullptr; } virtual bool handle_mousewheel(Badge, CSSPixelPoint, unsigned buttons, unsigned modifiers, int wheel_delta_x, int wheel_delta_y); diff --git a/Libraries/LibWeb/Painting/TextPaintable.cpp b/Libraries/LibWeb/Painting/TextPaintable.cpp index 8f01aadfdc1..f4b04daa8f1 100644 --- a/Libraries/LibWeb/Painting/TextPaintable.cpp +++ b/Libraries/LibWeb/Painting/TextPaintable.cpp @@ -30,13 +30,6 @@ bool TextPaintable::wants_mouse_events() const return layout_node().first_ancestor_of_type(); } -DOM::Node* TextPaintable::mouse_event_target() const -{ - if (auto const* label = layout_node().first_ancestor_of_type()) - return label->dom_node().control().ptr(); - return nullptr; -} - TextPaintable::DispatchEventOfSameName TextPaintable::handle_mousedown(Badge, CSSPixelPoint position, unsigned button, unsigned) { auto* label = layout_node().first_ancestor_of_type(); diff --git a/Libraries/LibWeb/Painting/TextPaintable.h b/Libraries/LibWeb/Painting/TextPaintable.h index 8db7af67b1b..11ec2a3cd47 100644 --- a/Libraries/LibWeb/Painting/TextPaintable.h +++ b/Libraries/LibWeb/Painting/TextPaintable.h @@ -21,7 +21,6 @@ public: Layout::TextNode const& layout_node() const { return static_cast(Paintable::layout_node()); } virtual bool wants_mouse_events() const override; - virtual DOM::Node* mouse_event_target() const override; virtual DispatchEventOfSameName handle_mousedown(Badge, CSSPixelPoint, unsigned button, unsigned modifiers) override; virtual DispatchEventOfSameName handle_mouseup(Badge, CSSPixelPoint, unsigned button, unsigned modifiers) override; virtual DispatchEventOfSameName handle_mousemove(Badge, CSSPixelPoint, unsigned button, unsigned modifiers) override; diff --git a/Tests/LibWeb/Text/expected/UIEvents/click-event-on-input-control-associated-with-label-element.txt b/Tests/LibWeb/Text/expected/UIEvents/click-event-on-input-control-associated-with-label-element.txt new file mode 100644 index 00000000000..ccfb60a7628 --- /dev/null +++ b/Tests/LibWeb/Text/expected/UIEvents/click-event-on-input-control-associated-with-label-element.txt @@ -0,0 +1,4 @@ +mouseup event on box +click event on box +click event on input#radio1 +click event on input#radio2 diff --git a/Tests/LibWeb/Text/input/UIEvents/click-event-on-input-control-associated-with-label-element.html b/Tests/LibWeb/Text/input/UIEvents/click-event-on-input-control-associated-with-label-element.html new file mode 100644 index 00000000000..cd0ab69f21a --- /dev/null +++ b/Tests/LibWeb/Text/input/UIEvents/click-event-on-input-control-associated-with-label-element.html @@ -0,0 +1,75 @@ + + + + + +
+ + +
+ + +