mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-05 07:41:01 +00:00
LibWeb+LibWebView+WebContent: Return a named enum from UI event handlers
UI event handlers currently return a boolean where false means the event was cancelled by a script on the page, or otherwise dropped. It has been a point of confusion for some time now, as it's not particularly clear what should be returned in some special cases, or how the UI process should handle the response. This adds an enumeration with a few states that indicate exactly how the WebContent process handled the event. This should remove all ambiguity, and let us properly handle these states going forward. There should be no behavior change with this patch. It's meant to only introduce the enum, not change any of our decisions based on the result.
This commit is contained in:
parent
a64d182583
commit
541968b30d
Notes:
github-actions[bot]
2024-09-12 21:39:29 +00:00
Author: https://github.com/trflynn89
Commit: 541968b30d
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1383
Reviewed-by: https://github.com/awesomekling ✅
15 changed files with 200 additions and 161 deletions
|
@ -71,7 +71,7 @@ static bool is_primitive_type(ByteString const& type)
|
||||||
static bool is_simple_type(ByteString const& type)
|
static bool is_simple_type(ByteString const& type)
|
||||||
{
|
{
|
||||||
// Small types that it makes sense just to pass by value.
|
// Small types that it makes sense just to pass by value.
|
||||||
return type.is_one_of("AK::CaseSensitivity", "Gfx::Color", "Web::DevicePixels", "Gfx::IntPoint", "Gfx::FloatPoint", "Web::DevicePixelPoint", "Gfx::IntSize", "Gfx::FloatSize", "Web::DevicePixelSize", "Core::File::OpenMode", "Web::Cookie::Source", "Web::HTML::AllowMultipleFiles", "Web::HTML::AudioPlayState", "Web::HTML::HistoryHandlingBehavior");
|
return type.is_one_of("AK::CaseSensitivity", "Gfx::Color", "Web::DevicePixels", "Gfx::IntPoint", "Gfx::FloatPoint", "Web::DevicePixelPoint", "Gfx::IntSize", "Gfx::FloatSize", "Web::DevicePixelSize", "Core::File::OpenMode", "Web::Cookie::Source", "Web::EventResult", "Web::HTML::AllowMultipleFiles", "Web::HTML::AudioPlayState", "Web::HTML::HistoryHandlingBehavior");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_primitive_or_simple_type(ByteString const& type)
|
static bool is_primitive_or_simple_type(ByteString const& type)
|
||||||
|
|
|
@ -23,7 +23,7 @@ void DragAndDropEventHandler::visit_edges(JS::Cell::Visitor& visitor) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dnd.html#drag-and-drop-processing-model
|
// https://html.spec.whatwg.org/multipage/dnd.html#drag-and-drop-processing-model
|
||||||
bool DragAndDropEventHandler::handle_drag_start(
|
EventResult DragAndDropEventHandler::handle_drag_start(
|
||||||
JS::Realm& realm,
|
JS::Realm& realm,
|
||||||
CSSPixelPoint screen_position,
|
CSSPixelPoint screen_position,
|
||||||
CSSPixelPoint page_offset,
|
CSSPixelPoint page_offset,
|
||||||
|
@ -154,7 +154,7 @@ bool DragAndDropEventHandler::handle_drag_start(
|
||||||
// If the event is canceled, then the drag-and-drop operation should not occur; return.
|
// If the event is canceled, then the drag-and-drop operation should not occur; return.
|
||||||
if (drag_event->cancelled()) {
|
if (drag_event->cancelled()) {
|
||||||
reset();
|
reset();
|
||||||
return false;
|
return EventResult::Cancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: 10. Fire a pointer event at the source node named pointercancel, and fire any other follow-up events as
|
// FIXME: 10. Fire a pointer event at the source node named pointercancel, and fire any other follow-up events as
|
||||||
|
@ -169,11 +169,11 @@ bool DragAndDropEventHandler::handle_drag_start(
|
||||||
// as distances in CSS pixels from the left side and from the top side of the image respectively.
|
// as distances in CSS pixels from the left side and from the top side of the image respectively.
|
||||||
// 2. The drag data store default feedback.
|
// 2. The drag data store default feedback.
|
||||||
|
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dnd.html#drag-and-drop-processing-model:queue-a-task
|
// https://html.spec.whatwg.org/multipage/dnd.html#drag-and-drop-processing-model:queue-a-task
|
||||||
bool DragAndDropEventHandler::handle_drag_move(
|
EventResult DragAndDropEventHandler::handle_drag_move(
|
||||||
JS::Realm& realm,
|
JS::Realm& realm,
|
||||||
JS::NonnullGCPtr<DOM::Document> document,
|
JS::NonnullGCPtr<DOM::Document> document,
|
||||||
JS::NonnullGCPtr<DOM::Node> node,
|
JS::NonnullGCPtr<DOM::Node> node,
|
||||||
|
@ -186,7 +186,7 @@ bool DragAndDropEventHandler::handle_drag_move(
|
||||||
unsigned modifiers)
|
unsigned modifiers)
|
||||||
{
|
{
|
||||||
if (!has_ongoing_drag_and_drop_operation())
|
if (!has_ongoing_drag_and_drop_operation())
|
||||||
return false;
|
return EventResult::Cancelled;
|
||||||
|
|
||||||
auto fire_a_drag_and_drop_event = [&](JS::GCPtr<DOM::EventTarget> target, FlyString const& name, JS::GCPtr<DOM::EventTarget> related_target = nullptr) {
|
auto fire_a_drag_and_drop_event = [&](JS::GCPtr<DOM::EventTarget> target, FlyString const& name, JS::GCPtr<DOM::EventTarget> related_target = nullptr) {
|
||||||
return this->fire_a_drag_and_drop_event(realm, target, name, screen_position, page_offset, client_offset, offset, button, buttons, modifiers, related_target);
|
return this->fire_a_drag_and_drop_event(realm, target, name, screen_position, page_offset, client_offset, offset, button, buttons, modifiers, related_target);
|
||||||
|
@ -320,10 +320,10 @@ bool DragAndDropEventHandler::handle_drag_move(
|
||||||
if (drag_event->cancelled())
|
if (drag_event->cancelled())
|
||||||
return handle_drag_end(realm, Cancelled::Yes, screen_position, page_offset, client_offset, offset, button, buttons, modifiers);
|
return handle_drag_end(realm, Cancelled::Yes, screen_position, page_offset, client_offset, offset, button, buttons, modifiers);
|
||||||
|
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DragAndDropEventHandler::handle_drag_leave(
|
EventResult DragAndDropEventHandler::handle_drag_leave(
|
||||||
JS::Realm& realm,
|
JS::Realm& realm,
|
||||||
CSSPixelPoint screen_position,
|
CSSPixelPoint screen_position,
|
||||||
CSSPixelPoint page_offset,
|
CSSPixelPoint page_offset,
|
||||||
|
@ -336,7 +336,7 @@ bool DragAndDropEventHandler::handle_drag_leave(
|
||||||
return handle_drag_end(realm, Cancelled::Yes, screen_position, page_offset, client_offset, offset, button, buttons, modifiers);
|
return handle_drag_end(realm, Cancelled::Yes, screen_position, page_offset, client_offset, offset, button, buttons, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DragAndDropEventHandler::handle_drop(
|
EventResult DragAndDropEventHandler::handle_drop(
|
||||||
JS::Realm& realm,
|
JS::Realm& realm,
|
||||||
CSSPixelPoint screen_position,
|
CSSPixelPoint screen_position,
|
||||||
CSSPixelPoint page_offset,
|
CSSPixelPoint page_offset,
|
||||||
|
@ -350,7 +350,7 @@ bool DragAndDropEventHandler::handle_drop(
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dnd.html#drag-and-drop-processing-model:event-dnd-drag-3
|
// https://html.spec.whatwg.org/multipage/dnd.html#drag-and-drop-processing-model:event-dnd-drag-3
|
||||||
bool DragAndDropEventHandler::handle_drag_end(
|
EventResult DragAndDropEventHandler::handle_drag_end(
|
||||||
JS::Realm& realm,
|
JS::Realm& realm,
|
||||||
Cancelled cancelled,
|
Cancelled cancelled,
|
||||||
CSSPixelPoint screen_position,
|
CSSPixelPoint screen_position,
|
||||||
|
@ -362,7 +362,7 @@ bool DragAndDropEventHandler::handle_drag_end(
|
||||||
unsigned modifiers)
|
unsigned modifiers)
|
||||||
{
|
{
|
||||||
if (!has_ongoing_drag_and_drop_operation())
|
if (!has_ongoing_drag_and_drop_operation())
|
||||||
return false;
|
return EventResult::Cancelled;
|
||||||
|
|
||||||
auto fire_a_drag_and_drop_event = [&](JS::GCPtr<DOM::EventTarget> target, FlyString const& name, JS::GCPtr<DOM::EventTarget> related_target = nullptr) {
|
auto fire_a_drag_and_drop_event = [&](JS::GCPtr<DOM::EventTarget> target, FlyString const& name, JS::GCPtr<DOM::EventTarget> related_target = nullptr) {
|
||||||
return this->fire_a_drag_and_drop_event(realm, target, name, screen_position, page_offset, client_offset, offset, button, buttons, modifiers, related_target);
|
return this->fire_a_drag_and_drop_event(realm, target, name, screen_position, page_offset, client_offset, offset, button, buttons, modifiers, related_target);
|
||||||
|
@ -456,7 +456,7 @@ bool DragAndDropEventHandler::handle_drag_end(
|
||||||
else if (!dropped || m_current_drag_operation == HTML::DataTransferEffect::none) {
|
else if (!dropped || m_current_drag_operation == HTML::DataTransferEffect::none) {
|
||||||
// The drag was canceled. If the platform conventions dictate that this be represented to the user (e.g. by
|
// The drag was canceled. If the platform conventions dictate that this be represented to the user (e.g. by
|
||||||
// animating the dragged selection going back to the source of the drag-and-drop operation), then do so.
|
// animating the dragged selection going back to the source of the drag-and-drop operation), then do so.
|
||||||
return false;
|
return EventResult::Cancelled;
|
||||||
}
|
}
|
||||||
// -> Otherwise
|
// -> Otherwise
|
||||||
else {
|
else {
|
||||||
|
@ -464,7 +464,7 @@ bool DragAndDropEventHandler::handle_drag_end(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dnd.html#fire-a-dnd-event
|
// https://html.spec.whatwg.org/multipage/dnd.html#fire-a-dnd-event
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <LibJS/Heap/GCPtr.h>
|
#include <LibJS/Heap/GCPtr.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
#include <LibWeb/HTML/DragDataStore.h>
|
#include <LibWeb/HTML/DragDataStore.h>
|
||||||
|
#include <LibWeb/Page/EventResult.h>
|
||||||
#include <LibWeb/PixelUnits.h>
|
#include <LibWeb/PixelUnits.h>
|
||||||
|
|
||||||
namespace Web {
|
namespace Web {
|
||||||
|
@ -20,17 +21,17 @@ public:
|
||||||
|
|
||||||
bool has_ongoing_drag_and_drop_operation() const { return !m_drag_data_store.is_null(); }
|
bool has_ongoing_drag_and_drop_operation() const { return !m_drag_data_store.is_null(); }
|
||||||
|
|
||||||
bool handle_drag_start(JS::Realm&, CSSPixelPoint screen_position, CSSPixelPoint page_offset, CSSPixelPoint client_offset, CSSPixelPoint offset, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files);
|
EventResult handle_drag_start(JS::Realm&, CSSPixelPoint screen_position, CSSPixelPoint page_offset, CSSPixelPoint client_offset, CSSPixelPoint offset, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files);
|
||||||
bool handle_drag_move(JS::Realm&, JS::NonnullGCPtr<DOM::Document>, JS::NonnullGCPtr<DOM::Node>, CSSPixelPoint screen_position, CSSPixelPoint page_offset, CSSPixelPoint client_offset, CSSPixelPoint offset, unsigned button, unsigned buttons, unsigned modifiers);
|
EventResult handle_drag_move(JS::Realm&, JS::NonnullGCPtr<DOM::Document>, JS::NonnullGCPtr<DOM::Node>, CSSPixelPoint screen_position, CSSPixelPoint page_offset, CSSPixelPoint client_offset, CSSPixelPoint offset, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
bool handle_drag_leave(JS::Realm&, CSSPixelPoint screen_position, CSSPixelPoint page_offset, CSSPixelPoint client_offset, CSSPixelPoint offset, unsigned button, unsigned buttons, unsigned modifiers);
|
EventResult handle_drag_leave(JS::Realm&, CSSPixelPoint screen_position, CSSPixelPoint page_offset, CSSPixelPoint client_offset, CSSPixelPoint offset, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
bool handle_drop(JS::Realm&, CSSPixelPoint screen_position, CSSPixelPoint page_offset, CSSPixelPoint client_offset, CSSPixelPoint offset, unsigned button, unsigned buttons, unsigned modifiers);
|
EventResult handle_drop(JS::Realm&, CSSPixelPoint screen_position, CSSPixelPoint page_offset, CSSPixelPoint client_offset, CSSPixelPoint offset, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Cancelled {
|
enum class Cancelled {
|
||||||
No,
|
No,
|
||||||
Yes,
|
Yes,
|
||||||
};
|
};
|
||||||
bool handle_drag_end(JS::Realm&, Cancelled, CSSPixelPoint screen_position, CSSPixelPoint page_offset, CSSPixelPoint client_offset, CSSPixelPoint offset, unsigned button, unsigned buttons, unsigned modifiers);
|
EventResult handle_drag_end(JS::Realm&, Cancelled, CSSPixelPoint screen_position, CSSPixelPoint page_offset, CSSPixelPoint client_offset, CSSPixelPoint offset, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
|
|
||||||
JS::NonnullGCPtr<HTML::DragEvent> fire_a_drag_and_drop_event(
|
JS::NonnullGCPtr<HTML::DragEvent> fire_a_drag_and_drop_event(
|
||||||
JS::Realm&,
|
JS::Realm&,
|
||||||
|
|
|
@ -165,27 +165,27 @@ Painting::PaintableBox const* EventHandler::paint_root() const
|
||||||
return m_navigable->active_document()->paintable_box();
|
return m_navigable->active_document()->paintable_box();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers, int wheel_delta_x, int wheel_delta_y)
|
EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers, int wheel_delta_x, int wheel_delta_y)
|
||||||
{
|
{
|
||||||
if (should_ignore_device_input_event())
|
if (should_ignore_device_input_event())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (!m_navigable->active_document())
|
if (!m_navigable->active_document())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
if (!m_navigable->active_document()->is_fully_active())
|
if (!m_navigable->active_document()->is_fully_active())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto position = viewport_position;
|
auto position = viewport_position;
|
||||||
|
|
||||||
m_navigable->active_document()->update_layout();
|
m_navigable->active_document()->update_layout();
|
||||||
|
|
||||||
if (!paint_root())
|
if (!paint_root())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (modifiers & UIEvents::KeyModifier::Mod_Shift)
|
if (modifiers & UIEvents::KeyModifier::Mod_Shift)
|
||||||
swap(wheel_delta_x, wheel_delta_y);
|
swap(wheel_delta_x, wheel_delta_y);
|
||||||
|
|
||||||
bool handled_event = false;
|
auto handled_event = EventResult::Dropped;
|
||||||
|
|
||||||
JS::GCPtr<Painting::Paintable> paintable;
|
JS::GCPtr<Painting::Paintable> paintable;
|
||||||
if (auto result = target_for_mouse_position(position); result.has_value())
|
if (auto result = target_for_mouse_position(position); result.has_value())
|
||||||
|
@ -196,12 +196,13 @@ bool EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSSPixelPo
|
||||||
while (containing_block) {
|
while (containing_block) {
|
||||||
auto handled_scroll_event = containing_block->handle_mousewheel({}, position, buttons, modifiers, wheel_delta_x, wheel_delta_y);
|
auto handled_scroll_event = containing_block->handle_mousewheel({}, position, buttons, modifiers, wheel_delta_x, wheel_delta_y);
|
||||||
if (handled_scroll_event)
|
if (handled_scroll_event)
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
|
|
||||||
containing_block = containing_block->containing_block();
|
containing_block = containing_block->containing_block();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paintable->handle_mousewheel({}, position, buttons, modifiers, wheel_delta_x, wheel_delta_y))
|
if (paintable->handle_mousewheel({}, position, buttons, modifiers, wheel_delta_x, wheel_delta_y))
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
|
|
||||||
auto node = dom_node_for_event_dispatch(*paintable);
|
auto node = dom_node_for_event_dispatch(*paintable);
|
||||||
|
|
||||||
|
@ -211,13 +212,13 @@ bool EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSSPixelPo
|
||||||
auto& iframe = static_cast<HTML::HTMLIFrameElement&>(*node);
|
auto& iframe = static_cast<HTML::HTMLIFrameElement&>(*node);
|
||||||
auto position_in_iframe = position.translated(compute_mouse_event_offset({}, paintable->layout_node()));
|
auto position_in_iframe = position.translated(compute_mouse_event_offset({}, paintable->layout_node()));
|
||||||
iframe.content_navigable()->event_handler().handle_mousewheel(position_in_iframe, screen_position, button, buttons, modifiers, wheel_delta_x, wheel_delta_y);
|
iframe.content_navigable()->event_handler().handle_mousewheel(position_in_iframe, screen_position, button, buttons, modifiers, wheel_delta_x, wheel_delta_y);
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for the first parent of the hit target that's an element.
|
// Search for the first parent of the hit target that's an element.
|
||||||
Layout::Node* layout_node;
|
Layout::Node* layout_node;
|
||||||
if (!parent_element_for_event_dispatch(*paintable, node, layout_node))
|
if (!parent_element_for_event_dispatch(*paintable, node, layout_node))
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto offset = compute_mouse_event_offset(position, *layout_node);
|
auto offset = compute_mouse_event_offset(position, *layout_node);
|
||||||
auto client_offset = compute_mouse_event_client_offset(position);
|
auto client_offset = compute_mouse_event_client_offset(position);
|
||||||
|
@ -226,31 +227,29 @@ bool EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSSPixelPo
|
||||||
m_navigable->active_window()->scroll_by(wheel_delta_x, wheel_delta_y);
|
m_navigable->active_window()->scroll_by(wheel_delta_x, wheel_delta_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
handled_event = true;
|
handled_event = EventResult::Handled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return handled_event;
|
return handled_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||||
{
|
{
|
||||||
if (should_ignore_device_input_event())
|
if (should_ignore_device_input_event())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (!m_navigable->active_document())
|
if (!m_navigable->active_document())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
if (!m_navigable->active_document()->is_fully_active())
|
if (!m_navigable->active_document()->is_fully_active())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto position = viewport_position;
|
auto position = viewport_position;
|
||||||
|
|
||||||
m_navigable->active_document()->update_layout();
|
m_navigable->active_document()->update_layout();
|
||||||
|
|
||||||
if (!paint_root())
|
if (!paint_root())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
bool handled_event = false;
|
|
||||||
|
|
||||||
JS::GCPtr<Painting::Paintable> paintable;
|
JS::GCPtr<Painting::Paintable> paintable;
|
||||||
if (auto result = target_for_mouse_position(position); result.has_value())
|
if (auto result = target_for_mouse_position(position); result.has_value())
|
||||||
|
@ -258,15 +257,18 @@ bool EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPixelPoint
|
||||||
|
|
||||||
if (paintable && paintable->wants_mouse_events()) {
|
if (paintable && paintable->wants_mouse_events()) {
|
||||||
if (paintable->handle_mouseup({}, position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
if (paintable->handle_mouseup({}, position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
||||||
return false;
|
return EventResult::Cancelled;
|
||||||
|
|
||||||
// Things may have changed as a consequence of Layout::Node::handle_mouseup(). Hit test again.
|
// Things may have changed as a consequence of Layout::Node::handle_mouseup(). Hit test again.
|
||||||
if (!paint_root())
|
if (!paint_root())
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
|
|
||||||
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::Exact); result.has_value())
|
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::Exact); result.has_value())
|
||||||
paintable = result->paintable;
|
paintable = result->paintable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto handled_event = EventResult::Dropped;
|
||||||
|
|
||||||
if (paintable) {
|
if (paintable) {
|
||||||
auto node = dom_node_for_event_dispatch(*paintable);
|
auto node = dom_node_for_event_dispatch(*paintable);
|
||||||
|
|
||||||
|
@ -274,7 +276,7 @@ bool EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPixelPoint
|
||||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||||
return content_navigable->event_handler().handle_mouseup(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
return content_navigable->event_handler().handle_mouseup(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for the first parent of the hit target that's an element.
|
// Search for the first parent of the hit target that's an element.
|
||||||
|
@ -290,7 +292,7 @@ bool EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPixelPoint
|
||||||
auto client_offset = compute_mouse_event_client_offset(position);
|
auto client_offset = compute_mouse_event_client_offset(position);
|
||||||
auto page_offset = compute_mouse_event_page_offset(client_offset);
|
auto page_offset = compute_mouse_event_page_offset(client_offset);
|
||||||
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mouseup, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mouseup, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||||
handled_event = true;
|
handled_event = EventResult::Handled;
|
||||||
|
|
||||||
bool run_activation_behavior = false;
|
bool run_activation_behavior = false;
|
||||||
if (node.ptr() == m_mousedown_target) {
|
if (node.ptr() == m_mousedown_target) {
|
||||||
|
@ -364,22 +366,22 @@ after_node_use:
|
||||||
return handled_event;
|
return handled_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||||
{
|
{
|
||||||
if (should_ignore_device_input_event())
|
if (should_ignore_device_input_event())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (!m_navigable->active_document())
|
if (!m_navigable->active_document())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
if (!m_navigable->active_document()->is_fully_active())
|
if (!m_navigable->active_document()->is_fully_active())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto position = viewport_position;
|
auto position = viewport_position;
|
||||||
|
|
||||||
m_navigable->active_document()->update_layout();
|
m_navigable->active_document()->update_layout();
|
||||||
|
|
||||||
if (!paint_root())
|
if (!paint_root())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
JS::NonnullGCPtr<DOM::Document> document = *m_navigable->active_document();
|
JS::NonnullGCPtr<DOM::Document> document = *m_navigable->active_document();
|
||||||
JS::GCPtr<DOM::Node> node;
|
JS::GCPtr<DOM::Node> node;
|
||||||
|
@ -389,7 +391,7 @@ bool EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSPixelPoi
|
||||||
if (auto result = target_for_mouse_position(position); result.has_value())
|
if (auto result = target_for_mouse_position(position); result.has_value())
|
||||||
paintable = result->paintable;
|
paintable = result->paintable;
|
||||||
else
|
else
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto pointer_events = paintable->computed_values().pointer_events();
|
auto pointer_events = paintable->computed_values().pointer_events();
|
||||||
// FIXME: Handle other values for pointer-events.
|
// FIXME: Handle other values for pointer-events.
|
||||||
|
@ -400,16 +402,16 @@ bool EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSPixelPoi
|
||||||
|
|
||||||
if (paintable->wants_mouse_events()) {
|
if (paintable->wants_mouse_events()) {
|
||||||
if (paintable->handle_mousedown({}, position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
if (paintable->handle_mousedown({}, position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
||||||
return false;
|
return EventResult::Cancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||||
return content_navigable->event_handler().handle_mousedown(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
return content_navigable->event_handler().handle_mousedown(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_navigable->page().set_focused_navigable({}, m_navigable);
|
m_navigable->page().set_focused_navigable({}, m_navigable);
|
||||||
|
@ -419,7 +421,7 @@ bool EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSPixelPoi
|
||||||
// "The topmost event target MUST be the element highest in the rendering order which is capable of being an event target." (https://www.w3.org/TR/uievents/#topmost-event-target)
|
// "The topmost event target MUST be the element highest in the rendering order which is capable of being an event target." (https://www.w3.org/TR/uievents/#topmost-event-target)
|
||||||
Layout::Node* layout_node;
|
Layout::Node* layout_node;
|
||||||
if (!parent_element_for_event_dispatch(*paintable, node, layout_node))
|
if (!parent_element_for_event_dispatch(*paintable, node, layout_node))
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
m_mousedown_target = node.ptr();
|
m_mousedown_target = node.ptr();
|
||||||
auto offset = compute_mouse_event_offset(position, *layout_node);
|
auto offset = compute_mouse_event_offset(position, *layout_node);
|
||||||
|
@ -430,7 +432,7 @@ bool EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSPixelPoi
|
||||||
|
|
||||||
// NOTE: Dispatching an event may have disturbed the world.
|
// NOTE: Dispatching an event may have disturbed the world.
|
||||||
if (!paint_root() || paint_root() != node->document().paintable_box())
|
if (!paint_root() || paint_root() != node->document().paintable_box())
|
||||||
return true;
|
return EventResult::Accepted;
|
||||||
|
|
||||||
if (button == UIEvents::MouseButton::Primary) {
|
if (button == UIEvents::MouseButton::Primary) {
|
||||||
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::TextCursor); result.has_value()) {
|
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::TextCursor); result.has_value()) {
|
||||||
|
@ -472,25 +474,26 @@ bool EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSPixelPoi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 buttons, u32 modifiers)
|
EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 buttons, u32 modifiers)
|
||||||
{
|
{
|
||||||
if (should_ignore_device_input_event())
|
if (should_ignore_device_input_event())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (!m_navigable->active_document())
|
if (!m_navigable->active_document())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
if (!m_navigable->active_document()->is_fully_active())
|
if (!m_navigable->active_document()->is_fully_active())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto position = viewport_position;
|
auto position = viewport_position;
|
||||||
|
|
||||||
m_navigable->active_document()->update_layout();
|
m_navigable->active_document()->update_layout();
|
||||||
|
|
||||||
if (!paint_root())
|
if (!paint_root())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto& document = *m_navigable->active_document();
|
auto& document = *m_navigable->active_document();
|
||||||
auto& realm = document.realm();
|
auto& realm = document.realm();
|
||||||
|
@ -512,7 +515,7 @@ bool EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSPixelPoi
|
||||||
if (paintable->wants_mouse_events()) {
|
if (paintable->wants_mouse_events()) {
|
||||||
document.set_hovered_node(paintable->dom_node());
|
document.set_hovered_node(paintable->dom_node());
|
||||||
if (paintable->handle_mousemove({}, position, buttons, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
if (paintable->handle_mousemove({}, position, buttons, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
|
||||||
return false;
|
return EventResult::Cancelled;
|
||||||
|
|
||||||
// FIXME: It feels a bit aggressive to always update the cursor like this.
|
// FIXME: It feels a bit aggressive to always update the cursor like this.
|
||||||
m_navigable->page().client().page_did_request_cursor_change(Gfx::StandardCursor::None);
|
m_navigable->page().client().page_did_request_cursor_change(Gfx::StandardCursor::None);
|
||||||
|
@ -523,7 +526,7 @@ bool EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSPixelPoi
|
||||||
if (node && is<HTML::HTMLIFrameElement>(*node)) {
|
if (node && is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||||
return content_navigable->event_handler().handle_mousemove(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, buttons, modifiers);
|
return content_navigable->event_handler().handle_mousemove(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, buttons, modifiers);
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const cursor = paintable->computed_values().cursor();
|
auto const cursor = paintable->computed_values().cursor();
|
||||||
|
@ -564,12 +567,13 @@ bool EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSPixelPoi
|
||||||
|
|
||||||
bool continue_ = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousemove, screen_position, page_offset, client_offset, offset, movement, 1, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
bool continue_ = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousemove, screen_position, page_offset, client_offset, offset, movement, 1, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||||
if (!continue_)
|
if (!continue_)
|
||||||
return false;
|
return EventResult::Cancelled;
|
||||||
|
|
||||||
// NOTE: Dispatching an event may have disturbed the world.
|
// NOTE: Dispatching an event may have disturbed the world.
|
||||||
if (!paint_root() || paint_root() != node->document().paintable_box())
|
if (!paint_root() || paint_root() != node->document().paintable_box())
|
||||||
return true;
|
return EventResult::Accepted;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_in_mouse_selection) {
|
if (m_in_mouse_selection) {
|
||||||
auto hit = paint_root()->hit_test(position, Painting::HitTestType::TextCursor);
|
auto hit = paint_root()->hit_test(position, Painting::HitTestType::TextCursor);
|
||||||
auto should_set_cursor_position = true;
|
auto should_set_cursor_position = true;
|
||||||
|
@ -610,18 +614,18 @@ bool EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSPixelPoi
|
||||||
page.client().page_did_unhover_link();
|
page.client().page_did_unhover_link();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||||
{
|
{
|
||||||
if (should_ignore_device_input_event())
|
if (should_ignore_device_input_event())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (!m_navigable->active_document())
|
if (!m_navigable->active_document())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
if (!m_navigable->active_document()->is_fully_active())
|
if (!m_navigable->active_document()->is_fully_active())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto& document = *m_navigable->active_document();
|
auto& document = *m_navigable->active_document();
|
||||||
|
|
||||||
|
@ -631,18 +635,18 @@ bool EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CSSPixelP
|
||||||
document.update_layout();
|
document.update_layout();
|
||||||
|
|
||||||
if (!paint_root())
|
if (!paint_root())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
JS::GCPtr<Painting::Paintable> paintable;
|
JS::GCPtr<Painting::Paintable> paintable;
|
||||||
if (auto result = target_for_mouse_position(position); result.has_value())
|
if (auto result = target_for_mouse_position(position); result.has_value())
|
||||||
paintable = result->paintable;
|
paintable = result->paintable;
|
||||||
else
|
else
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto pointer_events = paintable->computed_values().pointer_events();
|
auto pointer_events = paintable->computed_values().pointer_events();
|
||||||
// FIXME: Handle other values for pointer-events.
|
// FIXME: Handle other values for pointer-events.
|
||||||
if (pointer_events == CSS::PointerEvents::None)
|
if (pointer_events == CSS::PointerEvents::None)
|
||||||
return false;
|
return EventResult::Cancelled;
|
||||||
|
|
||||||
auto node = dom_node_for_event_dispatch(*paintable);
|
auto node = dom_node_for_event_dispatch(*paintable);
|
||||||
|
|
||||||
|
@ -651,19 +655,19 @@ bool EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CSSPixelP
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||||
return content_navigable->event_handler().handle_doubleclick(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
return content_navigable->event_handler().handle_doubleclick(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for the first parent of the hit target that's an element.
|
// Search for the first parent of the hit target that's an element.
|
||||||
// "The topmost event target MUST be the element highest in the rendering order which is capable of being an event target." (https://www.w3.org/TR/uievents/#topmost-event-target)
|
// "The topmost event target MUST be the element highest in the rendering order which is capable of being an event target." (https://www.w3.org/TR/uievents/#topmost-event-target)
|
||||||
Layout::Node* layout_node;
|
Layout::Node* layout_node;
|
||||||
if (!parent_element_for_event_dispatch(*paintable, node, layout_node))
|
if (!parent_element_for_event_dispatch(*paintable, node, layout_node))
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto offset = compute_mouse_event_offset(position, *layout_node);
|
auto offset = compute_mouse_event_offset(position, *layout_node);
|
||||||
auto client_offset = compute_mouse_event_client_offset(position);
|
auto client_offset = compute_mouse_event_client_offset(position);
|
||||||
|
@ -672,15 +676,15 @@ bool EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CSSPixelP
|
||||||
|
|
||||||
// NOTE: Dispatching an event may have disturbed the world.
|
// NOTE: Dispatching an event may have disturbed the world.
|
||||||
if (!paint_root() || paint_root() != node->document().paintable_box())
|
if (!paint_root() || paint_root() != node->document().paintable_box())
|
||||||
return true;
|
return EventResult::Accepted;
|
||||||
|
|
||||||
if (button == UIEvents::MouseButton::Primary) {
|
if (button == UIEvents::MouseButton::Primary) {
|
||||||
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::TextCursor); result.has_value()) {
|
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::TextCursor); result.has_value()) {
|
||||||
if (!result->paintable->dom_node())
|
if (!result->paintable->dom_node())
|
||||||
return true;
|
return EventResult::Accepted;
|
||||||
|
|
||||||
if (!is<Painting::TextPaintable>(*result->paintable))
|
if (!is<Painting::TextPaintable>(*result->paintable))
|
||||||
return true;
|
return EventResult::Accepted;
|
||||||
|
|
||||||
auto& hit_paintable = static_cast<Painting::TextPaintable const&>(*result->paintable);
|
auto& hit_paintable = static_cast<Painting::TextPaintable const&>(*result->paintable);
|
||||||
|
|
||||||
auto& hit_dom_node = const_cast<DOM::Text&>(verify_cast<DOM::Text>(*hit_paintable.dom_node()));
|
auto& hit_dom_node = const_cast<DOM::Text&>(verify_cast<DOM::Text>(*hit_paintable.dom_node()));
|
||||||
|
@ -701,36 +705,36 @@ bool EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CSSPixelP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventHandler::handle_drag_and_drop_event(DragEvent::Type type, CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers, Vector<HTML::SelectedFile> files)
|
EventResult EventHandler::handle_drag_and_drop_event(DragEvent::Type type, CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers, Vector<HTML::SelectedFile> files)
|
||||||
{
|
{
|
||||||
if (!m_navigable->active_document())
|
if (!m_navigable->active_document())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
if (!m_navigable->active_document()->is_fully_active())
|
if (!m_navigable->active_document()->is_fully_active())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto& document = *m_navigable->active_document();
|
auto& document = *m_navigable->active_document();
|
||||||
document.update_layout();
|
document.update_layout();
|
||||||
|
|
||||||
if (!paint_root())
|
if (!paint_root())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
JS::GCPtr<Painting::Paintable> paintable;
|
JS::GCPtr<Painting::Paintable> paintable;
|
||||||
if (auto result = target_for_mouse_position(viewport_position); result.has_value())
|
if (auto result = target_for_mouse_position(viewport_position); result.has_value())
|
||||||
paintable = result->paintable;
|
paintable = result->paintable;
|
||||||
else
|
else
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto node = dom_node_for_event_dispatch(*paintable);
|
auto node = dom_node_for_event_dispatch(*paintable);
|
||||||
if (!node)
|
if (!node)
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||||
return content_navigable->event_handler().handle_drag_and_drop_event(type, viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers, move(files));
|
return content_navigable->event_handler().handle_drag_and_drop_event(type, viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers, move(files));
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto offset = compute_mouse_event_offset(viewport_position, paintable->layout_node());
|
auto offset = compute_mouse_event_offset(viewport_position, paintable->layout_node());
|
||||||
|
@ -806,13 +810,13 @@ constexpr bool should_ignore_keydown_event(u32 code_point, u32 modifiers)
|
||||||
return code_point == 0 || code_point == 27;
|
return code_point == 0 || code_point == 27;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventHandler::fire_keyboard_event(FlyString const& event_name, HTML::Navigable& navigable, UIEvents::KeyCode key, u32 modifiers, u32 code_point)
|
EventResult EventHandler::fire_keyboard_event(FlyString const& event_name, HTML::Navigable& navigable, UIEvents::KeyCode key, u32 modifiers, u32 code_point)
|
||||||
{
|
{
|
||||||
JS::GCPtr<DOM::Document> document = navigable.active_document();
|
JS::GCPtr<DOM::Document> document = navigable.active_document();
|
||||||
if (!document)
|
if (!document)
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
if (!document->is_fully_active())
|
if (!document->is_fully_active())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (JS::GCPtr<DOM::Element> focused_element = document->focused_element()) {
|
if (JS::GCPtr<DOM::Element> focused_element = document->focused_element()) {
|
||||||
if (is<HTML::NavigableContainer>(*focused_element)) {
|
if (is<HTML::NavigableContainer>(*focused_element)) {
|
||||||
|
@ -822,33 +826,31 @@ bool EventHandler::fire_keyboard_event(FlyString const& event_name, HTML::Naviga
|
||||||
}
|
}
|
||||||
|
|
||||||
auto event = UIEvents::KeyboardEvent::create_from_platform_event(document->realm(), event_name, key, modifiers, code_point);
|
auto event = UIEvents::KeyboardEvent::create_from_platform_event(document->realm(), event_name, key, modifiers, code_point);
|
||||||
return focused_element->dispatch_event(event);
|
return focused_element->dispatch_event(event) ? EventResult::Accepted : EventResult::Cancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: De-duplicate this. This is just to prevent wasting a KeyboardEvent allocation when recursing into an (i)frame.
|
// FIXME: De-duplicate this. This is just to prevent wasting a KeyboardEvent allocation when recursing into an (i)frame.
|
||||||
auto event = UIEvents::KeyboardEvent::create_from_platform_event(document->realm(), event_name, key, modifiers, code_point);
|
auto event = UIEvents::KeyboardEvent::create_from_platform_event(document->realm(), event_name, key, modifiers, code_point);
|
||||||
|
|
||||||
if (JS::GCPtr<HTML::HTMLElement> body = document->body())
|
JS::GCPtr target = document->body() ?: &document->root();
|
||||||
return body->dispatch_event(event);
|
return target->dispatch_event(event) ? EventResult::Accepted : EventResult::Cancelled;
|
||||||
|
|
||||||
return document->root().dispatch_event(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code_point)
|
EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code_point)
|
||||||
{
|
{
|
||||||
if (!m_navigable->active_document())
|
if (!m_navigable->active_document())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
if (!m_navigable->active_document()->is_fully_active())
|
if (!m_navigable->active_document()->is_fully_active())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
JS::NonnullGCPtr<DOM::Document> document = *m_navigable->active_document();
|
JS::NonnullGCPtr<DOM::Document> document = *m_navigable->active_document();
|
||||||
if (!document->layout_node())
|
if (!document->layout_node())
|
||||||
return false;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
if (key == UIEvents::KeyCode::Key_Tab) {
|
if (key == UIEvents::KeyCode::Key_Tab) {
|
||||||
if (modifiers & UIEvents::KeyModifier::Mod_Shift)
|
if (modifiers & UIEvents::KeyModifier::Mod_Shift)
|
||||||
return focus_previous_element();
|
return focus_previous_element() ? EventResult::Handled : EventResult::Dropped;
|
||||||
return focus_next_element();
|
return focus_next_element() ? EventResult::Handled : EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/interaction.html#close-requests
|
// https://html.spec.whatwg.org/multipage/interaction.html#close-requests
|
||||||
|
@ -858,7 +860,7 @@ bool EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code
|
||||||
|
|
||||||
// 8. If closedSomething is true, then return.
|
// 8. If closedSomething is true, then return.
|
||||||
if (closed_something)
|
if (closed_something)
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
|
|
||||||
// 9. Alternative processing: Otherwise, there was nothing watching for a close request. The user agent may
|
// 9. Alternative processing: Otherwise, there was nothing watching for a close request. The user agent may
|
||||||
// instead interpret this interaction as some other action, instead of interpreting it as a close request.
|
// instead interpret this interaction as some other action, instead of interpreting it as a close request.
|
||||||
|
@ -886,27 +888,28 @@ bool EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code
|
||||||
if (key == UIEvents::KeyCode::Key_Backspace || key == UIEvents::KeyCode::Key_Delete) {
|
if (key == UIEvents::KeyCode::Key_Backspace || key == UIEvents::KeyCode::Key_Delete) {
|
||||||
clear_selection();
|
clear_selection();
|
||||||
m_edit_event_handler->handle_delete(document, *range);
|
m_edit_event_handler->handle_delete(document, *range);
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Text editing shortcut keys (copy/paste etc.) should be handled here.
|
// FIXME: Text editing shortcut keys (copy/paste etc.) should be handled here.
|
||||||
if (!should_ignore_keydown_event(code_point, modifiers)) {
|
if (!should_ignore_keydown_event(code_point, modifiers)) {
|
||||||
clear_selection();
|
clear_selection();
|
||||||
m_edit_event_handler->handle_delete(document, *range);
|
m_edit_event_handler->handle_delete(document, *range);
|
||||||
m_edit_event_handler->handle_insert(document, JS::NonnullGCPtr { *document->cursor_position() }, code_point);
|
m_edit_event_handler->handle_insert(document, JS::NonnullGCPtr { *document->cursor_position() }, code_point);
|
||||||
document->increment_cursor_position_offset();
|
document->increment_cursor_position_offset();
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* element = m_navigable->active_document()->focused_element(); is<HTML::HTMLMediaElement>(element)) {
|
if (auto* element = m_navigable->active_document()->focused_element(); is<HTML::HTMLMediaElement>(element)) {
|
||||||
auto& media_element = static_cast<HTML::HTMLMediaElement&>(*element);
|
auto& media_element = static_cast<HTML::HTMLMediaElement&>(*element);
|
||||||
if (media_element.handle_keydown({}, key, modifiers).release_value_but_fixme_should_propagate_errors())
|
if (media_element.handle_keydown({}, key, modifiers).release_value_but_fixme_should_propagate_errors())
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool continue_ = fire_keyboard_event(UIEvents::EventNames::keydown, m_navigable, key, modifiers, code_point);
|
auto dispatch_result = fire_keyboard_event(UIEvents::EventNames::keydown, m_navigable, key, modifiers, code_point);
|
||||||
if (!continue_)
|
if (dispatch_result != EventResult::Accepted)
|
||||||
return false;
|
return dispatch_result;
|
||||||
|
|
||||||
if (document->cursor_position()) {
|
if (document->cursor_position()) {
|
||||||
auto& node = *document->cursor_position()->node();
|
auto& node = *document->cursor_position()->node();
|
||||||
|
@ -914,20 +917,21 @@ bool EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code
|
||||||
if (key == UIEvents::KeyCode::Key_Backspace && node.is_editable()) {
|
if (key == UIEvents::KeyCode::Key_Backspace && node.is_editable()) {
|
||||||
if (!document->decrement_cursor_position_offset()) {
|
if (!document->decrement_cursor_position_offset()) {
|
||||||
// FIXME: Move to the previous node and delete the last character there.
|
// FIXME: Move to the previous node and delete the last character there.
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_edit_event_handler->handle_delete_character_after(document, *document->cursor_position());
|
m_edit_event_handler->handle_delete_character_after(document, *document->cursor_position());
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == UIEvents::KeyCode::Key_Delete && node.is_editable()) {
|
if (key == UIEvents::KeyCode::Key_Delete && node.is_editable()) {
|
||||||
if (document->cursor_position()->offset_is_at_end_of_node()) {
|
if (document->cursor_position()->offset_is_at_end_of_node()) {
|
||||||
// FIXME: Move to the next node and delete the first character there.
|
// FIXME: Move to the next node and delete the first character there.
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_edit_event_handler->handle_delete_character_after(document, *document->cursor_position());
|
m_edit_event_handler->handle_delete_character_after(document, *document->cursor_position());
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(AK_OS_MACOS)
|
#if defined(AK_OS_MACOS)
|
||||||
|
@ -977,7 +981,7 @@ bool EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == UIEvents::KeyCode::Key_Home || key == UIEvents::KeyCode::Key_End) {
|
if (key == UIEvents::KeyCode::Key_Home || key == UIEvents::KeyCode::Key_End) {
|
||||||
|
@ -997,7 +1001,7 @@ bool EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code
|
||||||
}
|
}
|
||||||
|
|
||||||
document->set_cursor_position(DOM::Position::create(realm, node, cursor_edge));
|
document->set_cursor_position(DOM::Position::create(realm, node, cursor_edge));
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == UIEvents::KeyCode::Key_Return && node.is_editable()) {
|
if (key == UIEvents::KeyCode::Key_Return && node.is_editable()) {
|
||||||
|
@ -1014,11 +1018,11 @@ bool EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code
|
||||||
if (input_element) {
|
if (input_element) {
|
||||||
if (auto* form = input_element->form()) {
|
if (auto* form = input_element->form()) {
|
||||||
form->implicitly_submit_form().release_value_but_fixme_should_propagate_errors();
|
form->implicitly_submit_form().release_value_but_fixme_should_propagate_errors();
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
input_element->commit_pending_changes();
|
input_element->commit_pending_changes();
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,7 +1030,7 @@ bool EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code
|
||||||
if (!should_ignore_keydown_event(code_point, modifiers) && node.is_editable()) {
|
if (!should_ignore_keydown_event(code_point, modifiers) && node.is_editable()) {
|
||||||
m_edit_event_handler->handle_insert(document, JS::NonnullGCPtr { *document->cursor_position() }, code_point);
|
m_edit_event_handler->handle_insert(document, JS::NonnullGCPtr { *document->cursor_position() }, code_point);
|
||||||
document->increment_cursor_position_offset();
|
document->increment_cursor_position_offset();
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1045,7 +1049,7 @@ bool EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code
|
||||||
key == UIEvents::KeyCode::Key_Up ? document->scroll_to_the_beginning_of_the_document() : document->window()->scroll_by(0, INT64_MAX);
|
key == UIEvents::KeyCode::Key_Up ? document->scroll_to_the_beginning_of_the_document() : document->window()->scroll_by(0, INT64_MAX);
|
||||||
else
|
else
|
||||||
document->window()->scroll_by(0, key == UIEvents::KeyCode::Key_Up ? -arrow_key_scroll_distance : arrow_key_scroll_distance);
|
document->window()->scroll_by(0, key == UIEvents::KeyCode::Key_Up ? -arrow_key_scroll_distance : arrow_key_scroll_distance);
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
case UIEvents::KeyCode::Key_Left:
|
case UIEvents::KeyCode::Key_Left:
|
||||||
case UIEvents::KeyCode::Key_Right:
|
case UIEvents::KeyCode::Key_Right:
|
||||||
if (modifiers > UIEvents::KeyModifier::Mod_Alt && modifiers != (UIEvents::KeyModifier::Mod_Alt | UIEvents::KeyModifier::Mod_AltGr))
|
if (modifiers > UIEvents::KeyModifier::Mod_Alt && modifiers != (UIEvents::KeyModifier::Mod_Alt | UIEvents::KeyModifier::Mod_AltGr))
|
||||||
|
@ -1054,30 +1058,30 @@ bool EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code
|
||||||
document->page().traverse_the_history_by_delta(key == UIEvents::KeyCode::Key_Left ? -1 : 1);
|
document->page().traverse_the_history_by_delta(key == UIEvents::KeyCode::Key_Left ? -1 : 1);
|
||||||
else
|
else
|
||||||
document->window()->scroll_by(key == UIEvents::KeyCode::Key_Left ? -arrow_key_scroll_distance : arrow_key_scroll_distance, 0);
|
document->window()->scroll_by(key == UIEvents::KeyCode::Key_Left ? -arrow_key_scroll_distance : arrow_key_scroll_distance, 0);
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
case UIEvents::KeyCode::Key_PageUp:
|
case UIEvents::KeyCode::Key_PageUp:
|
||||||
case UIEvents::KeyCode::Key_PageDown:
|
case UIEvents::KeyCode::Key_PageDown:
|
||||||
if (modifiers > UIEvents::KeyModifier::Mod_None)
|
if (modifiers > UIEvents::KeyModifier::Mod_None)
|
||||||
break;
|
break;
|
||||||
document->window()->scroll_by(0, key == UIEvents::KeyCode::Key_PageUp ? -page_scroll_distance : page_scroll_distance);
|
document->window()->scroll_by(0, key == UIEvents::KeyCode::Key_PageUp ? -page_scroll_distance : page_scroll_distance);
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
case UIEvents::KeyCode::Key_Home:
|
case UIEvents::KeyCode::Key_Home:
|
||||||
document->scroll_to_the_beginning_of_the_document();
|
document->scroll_to_the_beginning_of_the_document();
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
case UIEvents::KeyCode::Key_End:
|
case UIEvents::KeyCode::Key_End:
|
||||||
document->window()->scroll_by(0, INT64_MAX);
|
document->window()->scroll_by(0, INT64_MAX);
|
||||||
return true;
|
return EventResult::Handled;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Work out and implement the difference between this and keydown.
|
// FIXME: Work out and implement the difference between this and keydown.
|
||||||
return !fire_keyboard_event(UIEvents::EventNames::keypress, m_navigable, key, modifiers, code_point);
|
return fire_keyboard_event(UIEvents::EventNames::keypress, m_navigable, key, modifiers, code_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventHandler::handle_keyup(UIEvents::KeyCode key, u32 modifiers, u32 code_point)
|
EventResult EventHandler::handle_keyup(UIEvents::KeyCode key, u32 modifiers, u32 code_point)
|
||||||
{
|
{
|
||||||
return !fire_keyboard_event(UIEvents::EventNames::keyup, m_navigable, key, modifiers, code_point);
|
return fire_keyboard_event(UIEvents::EventNames::keyup, m_navigable, key, modifiers, code_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandler::handle_paste(String const& text)
|
void EventHandler::handle_paste(String const& text)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <LibJS/Heap/GCPtr.h>
|
#include <LibJS/Heap/GCPtr.h>
|
||||||
#include <LibUnicode/Forward.h>
|
#include <LibUnicode/Forward.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
|
#include <LibWeb/Page/EventResult.h>
|
||||||
#include <LibWeb/Page/InputEvent.h>
|
#include <LibWeb/Page/InputEvent.h>
|
||||||
#include <LibWeb/PixelUnits.h>
|
#include <LibWeb/PixelUnits.h>
|
||||||
#include <LibWeb/UIEvents/KeyCode.h>
|
#include <LibWeb/UIEvents/KeyCode.h>
|
||||||
|
@ -25,16 +26,16 @@ public:
|
||||||
explicit EventHandler(Badge<HTML::Navigable>, HTML::Navigable&);
|
explicit EventHandler(Badge<HTML::Navigable>, HTML::Navigable&);
|
||||||
~EventHandler();
|
~EventHandler();
|
||||||
|
|
||||||
bool handle_mouseup(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
EventResult handle_mouseup(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
bool handle_mousedown(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
EventResult handle_mousedown(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
bool handle_mousemove(CSSPixelPoint, CSSPixelPoint screen_position, unsigned buttons, unsigned modifiers);
|
EventResult handle_mousemove(CSSPixelPoint, CSSPixelPoint screen_position, unsigned buttons, unsigned modifiers);
|
||||||
bool handle_mousewheel(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, int wheel_delta_x, int wheel_delta_y);
|
EventResult handle_mousewheel(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, int wheel_delta_x, int wheel_delta_y);
|
||||||
bool handle_doubleclick(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
EventResult handle_doubleclick(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
|
|
||||||
bool handle_drag_and_drop_event(DragEvent::Type, CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files);
|
EventResult handle_drag_and_drop_event(DragEvent::Type, CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files);
|
||||||
|
|
||||||
bool handle_keydown(UIEvents::KeyCode, unsigned modifiers, u32 code_point);
|
EventResult handle_keydown(UIEvents::KeyCode, unsigned modifiers, u32 code_point);
|
||||||
bool handle_keyup(UIEvents::KeyCode, unsigned modifiers, u32 code_point);
|
EventResult handle_keyup(UIEvents::KeyCode, unsigned modifiers, u32 code_point);
|
||||||
|
|
||||||
void set_mouse_event_tracking_paintable(Painting::Paintable*);
|
void set_mouse_event_tracking_paintable(Painting::Paintable*);
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ private:
|
||||||
bool focus_next_element();
|
bool focus_next_element();
|
||||||
bool focus_previous_element();
|
bool focus_previous_element();
|
||||||
|
|
||||||
bool fire_keyboard_event(FlyString const& event_name, HTML::Navigable&, UIEvents::KeyCode, unsigned modifiers, u32 code_point);
|
EventResult fire_keyboard_event(FlyString const& event_name, HTML::Navigable&, UIEvents::KeyCode, unsigned modifiers, u32 code_point);
|
||||||
CSSPixelPoint compute_mouse_event_client_offset(CSSPixelPoint event_page_position) const;
|
CSSPixelPoint compute_mouse_event_client_offset(CSSPixelPoint event_page_position) const;
|
||||||
CSSPixelPoint compute_mouse_event_page_offset(CSSPixelPoint event_client_offset) const;
|
CSSPixelPoint compute_mouse_event_page_offset(CSSPixelPoint event_client_offset) const;
|
||||||
CSSPixelPoint compute_mouse_event_movement(CSSPixelPoint event_client_offset) const;
|
CSSPixelPoint compute_mouse_event_movement(CSSPixelPoint event_client_offset) const;
|
||||||
|
|
28
Userland/Libraries/LibWeb/Page/EventResult.h
Normal file
28
Userland/Libraries/LibWeb/Page/EventResult.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Web {
|
||||||
|
|
||||||
|
enum class EventResult {
|
||||||
|
// The event is allowed to continue. It was not cancelled by the page, nor handled explicitly by the WebContent
|
||||||
|
// process. The UI process is allowed to further process the event.
|
||||||
|
Accepted,
|
||||||
|
|
||||||
|
// The event was accepted, and was handled explicitly by the WebContent process. The UI process should not further
|
||||||
|
// process the event.
|
||||||
|
Handled,
|
||||||
|
|
||||||
|
// The event was not accepted by the WebContent process (e.g. because the document is no longer active, or a
|
||||||
|
// drag-and-drop is active).
|
||||||
|
Dropped,
|
||||||
|
|
||||||
|
// The event was cancelled by the page (e.g. by way of e.preventDefault()).
|
||||||
|
Cancelled,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -186,42 +186,42 @@ DevicePixelRect Page::rounded_device_rect(CSSPixelRect rect) const
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Page::handle_mouseup(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers)
|
EventResult Page::handle_mouseup(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers)
|
||||||
{
|
{
|
||||||
return top_level_traversable()->event_handler().handle_mouseup(device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers);
|
return top_level_traversable()->event_handler().handle_mouseup(device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Page::handle_mousedown(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers)
|
EventResult Page::handle_mousedown(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers)
|
||||||
{
|
{
|
||||||
return top_level_traversable()->event_handler().handle_mousedown(device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers);
|
return top_level_traversable()->event_handler().handle_mousedown(device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Page::handle_mousemove(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned buttons, unsigned modifiers)
|
EventResult Page::handle_mousemove(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned buttons, unsigned modifiers)
|
||||||
{
|
{
|
||||||
return top_level_traversable()->event_handler().handle_mousemove(device_to_css_point(position), device_to_css_point(screen_position), buttons, modifiers);
|
return top_level_traversable()->event_handler().handle_mousemove(device_to_css_point(position), device_to_css_point(screen_position), buttons, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Page::handle_mousewheel(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, DevicePixels wheel_delta_x, DevicePixels wheel_delta_y)
|
EventResult Page::handle_mousewheel(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, DevicePixels wheel_delta_x, DevicePixels wheel_delta_y)
|
||||||
{
|
{
|
||||||
return top_level_traversable()->event_handler().handle_mousewheel(device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers, wheel_delta_x.value(), wheel_delta_y.value());
|
return top_level_traversable()->event_handler().handle_mousewheel(device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers, wheel_delta_x.value(), wheel_delta_y.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Page::handle_doubleclick(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers)
|
EventResult Page::handle_doubleclick(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers)
|
||||||
{
|
{
|
||||||
return top_level_traversable()->event_handler().handle_doubleclick(device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers);
|
return top_level_traversable()->event_handler().handle_doubleclick(device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Page::handle_drag_and_drop_event(DragEvent::Type type, DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files)
|
EventResult Page::handle_drag_and_drop_event(DragEvent::Type type, DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files)
|
||||||
{
|
{
|
||||||
return top_level_traversable()->event_handler().handle_drag_and_drop_event(type, device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers, move(files));
|
return top_level_traversable()->event_handler().handle_drag_and_drop_event(type, device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers, move(files));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Page::handle_keydown(UIEvents::KeyCode key, unsigned modifiers, u32 code_point)
|
EventResult Page::handle_keydown(UIEvents::KeyCode key, unsigned modifiers, u32 code_point)
|
||||||
{
|
{
|
||||||
return focused_navigable().event_handler().handle_keydown(key, modifiers, code_point);
|
return focused_navigable().event_handler().handle_keydown(key, modifiers, code_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Page::handle_keyup(UIEvents::KeyCode key, unsigned modifiers, u32 code_point)
|
EventResult Page::handle_keyup(UIEvents::KeyCode key, unsigned modifiers, u32 code_point)
|
||||||
{
|
{
|
||||||
return focused_navigable().event_handler().handle_keyup(key, modifiers, code_point);
|
return focused_navigable().event_handler().handle_keyup(key, modifiers, code_point);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <LibWeb/HTML/TokenizedFeatures.h>
|
#include <LibWeb/HTML/TokenizedFeatures.h>
|
||||||
#include <LibWeb/HTML/WebViewHints.h>
|
#include <LibWeb/HTML/WebViewHints.h>
|
||||||
#include <LibWeb/Loader/FileRequest.h>
|
#include <LibWeb/Loader/FileRequest.h>
|
||||||
|
#include <LibWeb/Page/EventResult.h>
|
||||||
#include <LibWeb/Page/InputEvent.h>
|
#include <LibWeb/Page/InputEvent.h>
|
||||||
#include <LibWeb/PixelUnits.h>
|
#include <LibWeb/PixelUnits.h>
|
||||||
#include <LibWeb/UIEvents/KeyCode.h>
|
#include <LibWeb/UIEvents/KeyCode.h>
|
||||||
|
@ -91,16 +92,16 @@ public:
|
||||||
DevicePixelRect enclosing_device_rect(CSSPixelRect) const;
|
DevicePixelRect enclosing_device_rect(CSSPixelRect) const;
|
||||||
DevicePixelRect rounded_device_rect(CSSPixelRect) const;
|
DevicePixelRect rounded_device_rect(CSSPixelRect) const;
|
||||||
|
|
||||||
bool handle_mouseup(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
EventResult handle_mouseup(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
bool handle_mousedown(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
EventResult handle_mousedown(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
bool handle_mousemove(DevicePixelPoint, DevicePixelPoint screen_position, unsigned buttons, unsigned modifiers);
|
EventResult handle_mousemove(DevicePixelPoint, DevicePixelPoint screen_position, unsigned buttons, unsigned modifiers);
|
||||||
bool handle_mousewheel(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, DevicePixels wheel_delta_x, DevicePixels wheel_delta_y);
|
EventResult handle_mousewheel(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, DevicePixels wheel_delta_x, DevicePixels wheel_delta_y);
|
||||||
bool handle_doubleclick(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
EventResult handle_doubleclick(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
|
|
||||||
bool handle_drag_and_drop_event(DragEvent::Type, DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files);
|
EventResult handle_drag_and_drop_event(DragEvent::Type, DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files);
|
||||||
|
|
||||||
bool handle_keydown(UIEvents::KeyCode, unsigned modifiers, u32 code_point);
|
EventResult handle_keydown(UIEvents::KeyCode, unsigned modifiers, u32 code_point);
|
||||||
bool handle_keyup(UIEvents::KeyCode, unsigned modifiers, u32 code_point);
|
EventResult handle_keyup(UIEvents::KeyCode, unsigned modifiers, u32 code_point);
|
||||||
|
|
||||||
Gfx::Palette palette() const;
|
Gfx::Palette palette() const;
|
||||||
CSSPixelRect web_exposed_screen_area() const;
|
CSSPixelRect web_exposed_screen_area() const;
|
||||||
|
|
|
@ -147,11 +147,11 @@ void ViewImplementation::enqueue_input_event(Web::InputEvent event)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewImplementation::did_finish_handling_input_event(Badge<WebContentClient>, bool event_was_accepted)
|
void ViewImplementation::did_finish_handling_input_event(Badge<WebContentClient>, Web::EventResult event_result)
|
||||||
{
|
{
|
||||||
auto event = m_pending_input_events.dequeue();
|
auto event = m_pending_input_events.dequeue();
|
||||||
|
|
||||||
if (event_was_accepted)
|
if (event_result == Web::EventResult::Handled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Here we handle events that were not consumed or cancelled by the WebContent. Propagate the event back
|
// Here we handle events that were not consumed or cancelled by the WebContent. Propagate the event back
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <LibWeb/HTML/ColorPickerUpdateState.h>
|
#include <LibWeb/HTML/ColorPickerUpdateState.h>
|
||||||
#include <LibWeb/HTML/FileFilter.h>
|
#include <LibWeb/HTML/FileFilter.h>
|
||||||
#include <LibWeb/HTML/SelectItem.h>
|
#include <LibWeb/HTML/SelectItem.h>
|
||||||
|
#include <LibWeb/Page/EventResult.h>
|
||||||
#include <LibWeb/Page/InputEvent.h>
|
#include <LibWeb/Page/InputEvent.h>
|
||||||
#include <LibWebView/Forward.h>
|
#include <LibWebView/Forward.h>
|
||||||
#include <LibWebView/WebContentClient.h>
|
#include <LibWebView/WebContentClient.h>
|
||||||
|
@ -61,7 +62,7 @@ public:
|
||||||
float device_pixel_ratio() const { return m_device_pixel_ratio; }
|
float device_pixel_ratio() const { return m_device_pixel_ratio; }
|
||||||
|
|
||||||
void enqueue_input_event(Web::InputEvent);
|
void enqueue_input_event(Web::InputEvent);
|
||||||
void did_finish_handling_input_event(Badge<WebContentClient>, bool event_was_accepted);
|
void did_finish_handling_input_event(Badge<WebContentClient>, Web::EventResult event_result);
|
||||||
|
|
||||||
void set_preferred_color_scheme(Web::CSS::PreferredColorScheme);
|
void set_preferred_color_scheme(Web::CSS::PreferredColorScheme);
|
||||||
void set_preferred_contrast(Web::CSS::PreferredContrast);
|
void set_preferred_contrast(Web::CSS::PreferredContrast);
|
||||||
|
|
|
@ -589,10 +589,10 @@ void WebContentClient::did_request_select_dropdown(u64 page_id, Gfx::IntPoint co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContentClient::did_finish_handling_input_event(u64 page_id, bool event_was_accepted)
|
void WebContentClient::did_finish_handling_input_event(u64 page_id, Web::EventResult event_result)
|
||||||
{
|
{
|
||||||
if (auto view = view_for_page_id(page_id); view.has_value())
|
if (auto view = view_for_page_id(page_id); view.has_value())
|
||||||
view->did_finish_handling_input_event({}, event_was_accepted);
|
view->did_finish_handling_input_event({}, event_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContentClient::did_change_theme_color(u64 page_id, Gfx::Color color)
|
void WebContentClient::did_change_theme_color(u64 page_id, Gfx::Color color)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <LibWeb/HTML/FileFilter.h>
|
#include <LibWeb/HTML/FileFilter.h>
|
||||||
#include <LibWeb/HTML/SelectItem.h>
|
#include <LibWeb/HTML/SelectItem.h>
|
||||||
#include <LibWeb/HTML/WebViewHints.h>
|
#include <LibWeb/HTML/WebViewHints.h>
|
||||||
|
#include <LibWeb/Page/EventResult.h>
|
||||||
#include <WebContent/WebContentClientEndpoint.h>
|
#include <WebContent/WebContentClientEndpoint.h>
|
||||||
#include <WebContent/WebContentServerEndpoint.h>
|
#include <WebContent/WebContentServerEndpoint.h>
|
||||||
|
|
||||||
|
@ -105,7 +106,7 @@ private:
|
||||||
virtual void did_request_color_picker(u64 page_id, Color const& current_color) override;
|
virtual void did_request_color_picker(u64 page_id, Color const& current_color) override;
|
||||||
virtual void did_request_file_picker(u64 page_id, Web::HTML::FileFilter const& accepted_file_types, Web::HTML::AllowMultipleFiles) override;
|
virtual void did_request_file_picker(u64 page_id, Web::HTML::FileFilter const& accepted_file_types, Web::HTML::AllowMultipleFiles) override;
|
||||||
virtual void did_request_select_dropdown(u64 page_id, Gfx::IntPoint content_position, i32 minimum_width, Vector<Web::HTML::SelectItem> const& items) override;
|
virtual void did_request_select_dropdown(u64 page_id, Gfx::IntPoint content_position, i32 minimum_width, Vector<Web::HTML::SelectItem> const& items) override;
|
||||||
virtual void did_finish_handling_input_event(u64 page_id, bool event_was_accepted) override;
|
virtual void did_finish_handling_input_event(u64 page_id, Web::EventResult event_result) override;
|
||||||
virtual void did_finish_text_test(u64 page_id) override;
|
virtual void did_finish_text_test(u64 page_id) override;
|
||||||
virtual void did_find_in_page(u64 page_id, size_t current_match_index, Optional<size_t> const& total_match_count) override;
|
virtual void did_find_in_page(u64 page_id, size_t current_match_index, Optional<size_t> const& total_match_count) override;
|
||||||
virtual void did_change_theme_color(u64 page_id, Gfx::Color color) override;
|
virtual void did_change_theme_color(u64 page_id, Gfx::Color color) override;
|
||||||
|
|
|
@ -185,7 +185,7 @@ void ConnectionFromClient::process_next_input_event()
|
||||||
if (!page.has_value())
|
if (!page.has_value())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto handled = event.event.visit(
|
auto result = event.event.visit(
|
||||||
[&](Web::KeyEvent const& event) {
|
[&](Web::KeyEvent const& event) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case Web::KeyEvent::Type::KeyDown:
|
case Web::KeyEvent::Type::KeyDown:
|
||||||
|
@ -214,10 +214,10 @@ void ConnectionFromClient::process_next_input_event()
|
||||||
return page->page().handle_drag_and_drop_event(event.type, event.position, event.screen_position, event.button, event.buttons, event.modifiers, move(event.files));
|
return page->page().handle_drag_and_drop_event(event.type, event.position, event.screen_position, event.button, event.buttons, event.modifiers, move(event.files));
|
||||||
});
|
});
|
||||||
|
|
||||||
// We have to notify the client about coalesced events, so we do that by saying none of them were handled by the web page->
|
// We have to notify the client about coalesced events, so we do that by saying none of them were handled by the web page.
|
||||||
for (size_t i = 0; i < event.coalesced_event_count; ++i)
|
for (size_t i = 0; i < event.coalesced_event_count; ++i)
|
||||||
report_finished_handling_input_event(event.page_id, false);
|
report_finished_handling_input_event(event.page_id, Web::EventResult::Dropped);
|
||||||
report_finished_handling_input_event(event.page_id, handled);
|
report_finished_handling_input_event(event.page_id, result);
|
||||||
|
|
||||||
if (!m_input_event_queue.is_empty())
|
if (!m_input_event_queue.is_empty())
|
||||||
m_input_event_queue_timer->start();
|
m_input_event_queue_timer->start();
|
||||||
|
@ -273,9 +273,9 @@ void ConnectionFromClient::enqueue_input_event(QueuedInputEvent event)
|
||||||
m_input_event_queue_timer->start();
|
m_input_event_queue_timer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionFromClient::report_finished_handling_input_event(u64 page_id, bool event_was_handled)
|
void ConnectionFromClient::report_finished_handling_input_event(u64 page_id, Web::EventResult event_result)
|
||||||
{
|
{
|
||||||
async_did_finish_handling_input_event(page_id, event_was_handled);
|
async_did_finish_handling_input_event(page_id, event_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, ByteString const& argument)
|
void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, ByteString const& argument)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <LibWeb/CSS/PreferredMotion.h>
|
#include <LibWeb/CSS/PreferredMotion.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
#include <LibWeb/Loader/FileRequest.h>
|
#include <LibWeb/Loader/FileRequest.h>
|
||||||
|
#include <LibWeb/Page/EventResult.h>
|
||||||
#include <LibWeb/Page/InputEvent.h>
|
#include <LibWeb/Page/InputEvent.h>
|
||||||
#include <LibWeb/Platform/Timer.h>
|
#include <LibWeb/Platform/Timer.h>
|
||||||
#include <LibWebView/Forward.h>
|
#include <LibWebView/Forward.h>
|
||||||
|
@ -150,7 +151,7 @@ private:
|
||||||
|
|
||||||
virtual void system_time_zone_changed() override;
|
virtual void system_time_zone_changed() override;
|
||||||
|
|
||||||
void report_finished_handling_input_event(u64 page_id, bool event_was_handled);
|
void report_finished_handling_input_event(u64 page_id, Web::EventResult event_was_handled);
|
||||||
|
|
||||||
NonnullOwnPtr<PageHost> m_page_host;
|
NonnullOwnPtr<PageHost> m_page_host;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <LibWeb/HTML/SelectedFile.h>
|
#include <LibWeb/HTML/SelectedFile.h>
|
||||||
#include <LibWeb/HTML/SelectItem.h>
|
#include <LibWeb/HTML/SelectItem.h>
|
||||||
#include <LibWeb/HTML/WebViewHints.h>
|
#include <LibWeb/HTML/WebViewHints.h>
|
||||||
|
#include <LibWeb/Page/EventResult.h>
|
||||||
#include <LibWeb/Page/Page.h>
|
#include <LibWeb/Page/Page.h>
|
||||||
#include <LibWebView/Attribute.h>
|
#include <LibWebView/Attribute.h>
|
||||||
#include <LibWebView/ProcessHandle.h>
|
#include <LibWebView/ProcessHandle.h>
|
||||||
|
@ -81,7 +82,7 @@ endpoint WebContentClient
|
||||||
did_request_color_picker(u64 page_id, Color current_color) =|
|
did_request_color_picker(u64 page_id, Color current_color) =|
|
||||||
did_request_file_picker(u64 page_id, Web::HTML::FileFilter accepted_file_types, Web::HTML::AllowMultipleFiles allow_multiple_files) =|
|
did_request_file_picker(u64 page_id, Web::HTML::FileFilter accepted_file_types, Web::HTML::AllowMultipleFiles allow_multiple_files) =|
|
||||||
did_request_select_dropdown(u64 page_id, Gfx::IntPoint content_position, i32 minimum_width, Vector<Web::HTML::SelectItem> items) =|
|
did_request_select_dropdown(u64 page_id, Gfx::IntPoint content_position, i32 minimum_width, Vector<Web::HTML::SelectItem> items) =|
|
||||||
did_finish_handling_input_event(u64 page_id, bool event_was_accepted) =|
|
did_finish_handling_input_event(u64 page_id, Web::EventResult event_result) =|
|
||||||
did_change_theme_color(u64 page_id, Gfx::Color color) =|
|
did_change_theme_color(u64 page_id, Gfx::Color color) =|
|
||||||
did_insert_clipboard_entry(u64 page_id, String data, String presentation_style, String mime_type) =|
|
did_insert_clipboard_entry(u64 page_id, String data, String presentation_style, String mime_type) =|
|
||||||
did_update_navigation_buttons_state(u64 page_id, bool back_enabled, bool forward_enabled) =|
|
did_update_navigation_buttons_state(u64 page_id, bool back_enabled, bool forward_enabled) =|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue