diff --git a/Base/home/anon/www/hover.html b/Base/home/anon/www/hover.html new file mode 100644 index 0000000000..9ef4b42ab6 --- /dev/null +++ b/Base/home/anon/www/hover.html @@ -0,0 +1,13 @@ + + + Hover test! + + + + this is a link + + diff --git a/Base/home/anon/www/welcome.html b/Base/home/anon/www/welcome.html index 4fb6ab1d52..1f60a17eb9 100644 --- a/Base/home/anon/www/welcome.html +++ b/Base/home/anon/www/welcome.html @@ -32,6 +32,7 @@ h1 {
  • link element
  • blink element
  • br element
  • +
  • hover element
  • www.serenityos.org
  • diff --git a/Libraries/LibHTML/CSS/Default.css b/Libraries/LibHTML/CSS/Default.css index 103544b5b9..a03583a6e6 100644 --- a/Libraries/LibHTML/CSS/Default.css +++ b/Libraries/LibHTML/CSS/Default.css @@ -90,6 +90,10 @@ a { text-decoration: underline; } +a:hover { + color: red; +} + hr { margin-top: 4; margin-bottom: 4; diff --git a/Libraries/LibHTML/CSS/SelectorEngine.cpp b/Libraries/LibHTML/CSS/SelectorEngine.cpp index ef8ab33ab0..e8a55c94b1 100644 --- a/Libraries/LibHTML/CSS/SelectorEngine.cpp +++ b/Libraries/LibHTML/CSS/SelectorEngine.cpp @@ -1,10 +1,33 @@ #include +#include #include namespace SelectorEngine { +static bool matches_hover_pseudo_class(const Element& element) +{ + auto* hovered_node = element.document().hovered_node(); + if (!hovered_node) + return false; + if (&element == hovered_node) + return true; + return element.is_ancestor_of(*hovered_node); +} + bool matches(const Selector::Component& component, const Element& element) { + switch (component.pseudo_class) { + case Selector::Component::PseudoClass::None: + break; + case Selector::Component::PseudoClass::Link: + ASSERT_NOT_REACHED(); + break; + case Selector::Component::PseudoClass::Hover: + if (!matches_hover_pseudo_class(element)) + return false; + break; + } + switch (component.type) { case Selector::Component::Type::Id: return component.value == element.attribute("id"); diff --git a/Libraries/LibHTML/DOM/Document.cpp b/Libraries/LibHTML/DOM/Document.cpp index 492b1b231a..9c0586ec1c 100644 --- a/Libraries/LibHTML/DOM/Document.cpp +++ b/Libraries/LibHTML/DOM/Document.cpp @@ -195,3 +195,13 @@ const LayoutDocument* Document::layout_node() const { return static_cast(Node::layout_node()); } + +void Document::set_hovered_node(Node* node) +{ + if (m_hovered_node == node) + return; + + m_hovered_node = node; + invalidate_style(); +} + diff --git a/Libraries/LibHTML/DOM/Document.h b/Libraries/LibHTML/DOM/Document.h index 148d577417..5c9b42fb9d 100644 --- a/Libraries/LibHTML/DOM/Document.h +++ b/Libraries/LibHTML/DOM/Document.h @@ -38,7 +38,7 @@ public: virtual String tag_name() const override { return "#document"; } - void set_hovered_node(Node* node) { m_hovered_node = node; } + void set_hovered_node(Node*); Node* hovered_node() { return m_hovered_node; } const Node* hovered_node() const { return m_hovered_node; }