Bladeren bron

LibHTML: Implement basic HTMLElement.title support

We now show a tooltip for the hovered node's enclosing HTML element's
title attribute, if one is present.

This patch also adds HTMLHeadingElement. The tags h1-h6 will now create
the right kind of objects.
Andreas Kling 5 jaren geleden
bovenliggende
commit
f38b0f667e

+ 5 - 0
Libraries/LibHTML/DOM/HTMLElement.h

@@ -6,4 +6,9 @@ class HTMLElement : public Element {
 public:
     HTMLElement(Document&, const String& tag_name);
     virtual ~HTMLElement() override;
+
+    String title() const { return attribute("title"); }
+
+private:
+    virtual bool is_html_element() const final { return true; }
 };

+ 7 - 0
Libraries/LibHTML/DOM/Node.cpp

@@ -81,3 +81,10 @@ const HTMLAnchorElement* Node::enclosing_link_element() const
         return static_cast<const HTMLAnchorElement*>(this);
     return parent() ? parent()->enclosing_link_element() : nullptr;
 }
+
+const HTMLElement* Node::enclosing_html_element() const
+{
+    if (is_html_element())
+        return static_cast<const HTMLElement*>(this);
+    return parent() ? parent()->enclosing_html_element() : nullptr;
+}

+ 4 - 0
Libraries/LibHTML/DOM/Node.h

@@ -14,6 +14,7 @@ enum class NodeType : unsigned {
 };
 
 class Document;
+class HTMLElement;
 class HTMLAnchorElement;
 class ParentNode;
 class LayoutNode;
@@ -39,6 +40,9 @@ public:
     const Document& document() const { return m_document; }
 
     const HTMLAnchorElement* enclosing_link_element() const;
+    const HTMLElement* enclosing_html_element() const;
+
+    virtual bool is_html_element() const { return false; }
 
 protected:
     Node(Document&, NodeType);

+ 12 - 3
Libraries/LibHTML/HtmlView.cpp

@@ -1,3 +1,4 @@
+#include <LibGUI/GApplication.h>
 #include <LibGUI/GPainter.h>
 #include <LibGUI/GScrollBar.h>
 #include <LibHTML/DOM/Element.h>
@@ -90,8 +91,8 @@ void HtmlView::mousemove_event(GMouseEvent& event)
     auto result = m_layout_root->hit_test(event.position());
     if (result.layout_node) {
         auto* node = result.layout_node->node();
+        hovered_node_changed = node != m_document->hovered_node();
         m_document->set_hovered_node(const_cast<Node*>(node));
-        hovered_node_changed = node == m_document->hovered_node();
         if (node) {
             dbg() << "HtmlView: mousemove: " << node->tag_name() << "{" << node << "}";
             if (auto* link = node->enclosing_link_element()) {
@@ -99,8 +100,16 @@ void HtmlView::mousemove_event(GMouseEvent& event)
             }
         }
     }
-    if (hovered_node_changed)
+    if (hovered_node_changed) {
         update();
+        auto* hovered_html_element = m_document->hovered_node() ? m_document->hovered_node()->enclosing_html_element() : nullptr;
+        if (hovered_html_element && !hovered_html_element->title().is_null()) {
+            auto screen_position = screen_relative_rect().location().translated(event.position());
+            GApplication::the().show_tooltip(hovered_html_element->title(), screen_position.translated(4, 4));
+        } else {
+            GApplication::the().hide_tooltip();
+        }
+    }
     event.accept();
 }
 
@@ -113,8 +122,8 @@ void HtmlView::mousedown_event(GMouseEvent& event)
     auto result = m_layout_root->hit_test(event.position());
     if (result.layout_node) {
         auto* node = result.layout_node->node();
+        hovered_node_changed = node != m_document->hovered_node();
         m_document->set_hovered_node(const_cast<Node*>(node));
-        hovered_node_changed = node == m_document->hovered_node();
         if (node) {
             dbg() << "HtmlView: mousedown: " << node->tag_name() << "{" << node << "}";
             if (auto* link = node->enclosing_link_element()) {