summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Base/home/anon/www/hover.html13
-rw-r--r--Base/home/anon/www/welcome.html1
-rw-r--r--Libraries/LibHTML/CSS/Default.css4
-rw-r--r--Libraries/LibHTML/CSS/SelectorEngine.cpp23
-rw-r--r--Libraries/LibHTML/DOM/Document.cpp10
-rw-r--r--Libraries/LibHTML/DOM/Document.h2
6 files changed, 52 insertions, 1 deletions
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 @@
+<html>
+ <head>
+ <title>Hover test!</title>
+<style>
+a:hover {
+ color: red;
+}
+</style>
+ </head>
+ <body>
+ <a href="hover.html">this is a link</a>
+ </body>
+</html>
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 {
<li><a href="link.html">link element</a></li>
<li><a href="blink.html">blink element</a></li>
<li><a href="br.html">br element</a></li>
+ <li><a href="hover.html">hover element</a></li>
<li><a href="http://www.serenityos.org/">www.serenityos.org</a></li>
</ul>
</body>
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 <LibHTML/CSS/SelectorEngine.h>
+#include <LibHTML/DOM/Document.h>
#include <LibHTML/DOM/Element.h>
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<const LayoutDocument*>(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; }