LibWeb: Add initial version of pointer-events CSS property

This commit is contained in:
huwdp 2021-10-05 19:47:13 +01:00 committed by Linus Groh
parent fe5c2b7bb9
commit ec43f7a2b0
Notes: sideshowbarker 2024-07-18 02:53:04 +09:00
7 changed files with 53 additions and 7 deletions

View file

@ -33,6 +33,7 @@ public:
static CSS::AlignItems align_items() { return CSS::AlignItems::FlexStart; }
static CSS::Overflow overflow() { return CSS::Overflow::Visible; }
static CSS::BoxSizing box_sizing() { return CSS::BoxSizing::ContentBox; }
static CSS::PointerEvents pointer_events() { return CSS::PointerEvents::Auto; }
};
struct BorderData {
@ -64,6 +65,7 @@ public:
CSS::Float float_() const { return m_noninherited.float_; }
CSS::Clear clear() const { return m_noninherited.clear; }
CSS::Cursor cursor() const { return m_inherited.cursor; }
CSS::PointerEvents pointer_events() const { return m_inherited.pointer_events; }
CSS::Display display() const { return m_noninherited.display; }
Optional<int> const& z_index() const { return m_noninherited.z_index; }
CSS::TextAlign text_align() const { return m_inherited.text_align; }
@ -129,6 +131,7 @@ protected:
struct {
Color color { InitialValues::color() };
CSS::Cursor cursor { InitialValues::cursor() };
CSS::PointerEvents pointer_events { InitialValues::pointer_events() };
CSS::TextAlign text_align { InitialValues::text_align() };
CSS::TextTransform text_transform { InitialValues::text_transform() };
CSS::WhiteSpace white_space { InitialValues::white_space() };
@ -189,6 +192,7 @@ class MutableComputedValues final : public ComputedValues {
public:
void set_color(const Color& color) { m_inherited.color = color; }
void set_cursor(CSS::Cursor cursor) { m_inherited.cursor = cursor; }
void set_pointer_events(CSS::PointerEvents value) { m_inherited.pointer_events = value; }
void set_background_color(const Color& color) { m_noninherited.background_color = color; }
void set_background_repeat_x(CSS::Repeat repeat) { m_noninherited.background_repeat_x = repeat; }
void set_background_repeat_y(CSS::Repeat repeat) { m_noninherited.background_repeat_y = repeat; }

View file

@ -1073,7 +1073,11 @@
},
"pointer-events": {
"inherited": true,
"initial": "auto"
"initial": "auto",
"valid-identifiers": [
"auto",
"none"
]
},
"position": {
"inherited": false,

View file

@ -355,6 +355,22 @@ Optional<CSS::TextAlign> StyleProperties::text_align() const
}
}
Optional<CSS::PointerEvents> StyleProperties::pointer_events() const
{
auto value = property(CSS::PropertyID::PointerEvents);
if (!value.has_value())
return {};
switch (value.value()->to_identifier()) {
case CSS::ValueID::Auto:
return CSS::PointerEvents::Auto;
case CSS::ValueID::None:
return CSS::PointerEvents::None;
default:
return {};
}
}
Optional<CSS::WhiteSpace> StyleProperties::white_space() const
{
auto value = property(CSS::PropertyID::WhiteSpace);

View file

@ -67,6 +67,7 @@ public:
Optional<CSS::Repeat> background_repeat_y() const;
Optional<CSS::BoxShadowData> box_shadow() const;
CSS::BoxSizing box_sizing() const;
Optional<CSS::PointerEvents> pointer_events() const;
Vector<CSS::Transformation> transformations() const;

View file

@ -211,6 +211,11 @@ enum class WhiteSpace {
PreWrap,
};
enum class PointerEvents {
Auto,
None
};
class StyleValue : public RefCounted<StyleValue> {
public:
virtual ~StyleValue();

View file

@ -312,6 +312,10 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style)
if (cursor.has_value())
computed_values.set_cursor(cursor.value());
auto pointer_events = specified_style.pointer_events();
if (pointer_events.has_value())
computed_values.set_pointer_events(pointer_events.value());
auto text_decoration_line = specified_style.text_decoration_line();
if (text_decoration_line.has_value())
computed_values.set_text_decoration_line(text_decoration_line.value());

View file

@ -184,10 +184,16 @@ bool EventHandler::handle_mousedown(const Gfx::IntPoint& position, unsigned butt
}
NonnullRefPtr document = *m_frame.active_document();
// TODO: Allow selecting element behind if one on top has pointer-events set to none.
auto result = layout_root()->hit_test(position, Layout::HitTestType::Exact);
auto pointer_events = result.layout_node->computed_values().pointer_events();
if (pointer_events == CSS::PointerEvents::None)
return false;
RefPtr<DOM::Node> node;
{
auto result = layout_root()->hit_test(position, Layout::HitTestType::Exact);
if (!result.layout_node)
return false;
@ -306,6 +312,10 @@ bool EventHandler::handle_mousemove(const Gfx::IntPoint& position, unsigned butt
return false;
}
auto pointer_events = result.layout_node->computed_values().pointer_events();
if (pointer_events == CSS::PointerEvents::None)
return false;
hovered_node_changed = node != document.hovered_node();
document.set_hovered_node(node);
if (node) {
@ -313,11 +323,13 @@ bool EventHandler::handle_mousemove(const Gfx::IntPoint& position, unsigned butt
if (hovered_link_element)
is_hovering_link = true;
auto cursor = result.layout_node->computed_values().cursor();
if (node->is_text() && cursor == CSS::Cursor::Auto)
hovered_node_cursor = Gfx::StandardCursor::IBeam;
else
hovered_node_cursor = cursor_css_to_gfx(cursor);
if (node->is_text()) {
auto cursor = result.layout_node->computed_values().cursor();
if (cursor == CSS::Cursor::Auto)
hovered_node_cursor = Gfx::StandardCursor::IBeam;
else
hovered_node_cursor = cursor_css_to_gfx(cursor);
}
auto offset = compute_mouse_event_offset(position, *result.layout_node);
node->dispatch_event(UIEvents::MouseEvent::create(UIEvents::EventNames::mousemove, offset.x(), offset.y(), position.x(), position.y()));