summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-09-29 16:24:57 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-09-29 16:24:57 +0200
commitb94c7665a9ecbe6c5b5d81cd62d21787e6ff4d7e (patch)
tree9e8ece9b14bd4816f3d5955f2325ce644857fdbb
parent0c6af2d5b49a95567be168d942aea5b00c1d9f1b (diff)
downloadserenity-b94c7665a9ecbe6c5b5d81cd62d21787e6ff4d7e.zip
LibHTML: Add a way to get a Document's title
You can now query Document::title() to get a String containing whatever is inside the document's <title> tag. In support of this, this patch adds the <html>, <head> and <title> elements.
-rw-r--r--Libraries/LibHTML/DOM/Document.cpp29
-rw-r--r--Libraries/LibHTML/DOM/Document.h9
-rw-r--r--Libraries/LibHTML/DOM/HTMLHeadElement.cpp10
-rw-r--r--Libraries/LibHTML/DOM/HTMLHeadElement.h9
-rw-r--r--Libraries/LibHTML/DOM/HTMLHtmlElement.cpp10
-rw-r--r--Libraries/LibHTML/DOM/HTMLHtmlElement.h9
-rw-r--r--Libraries/LibHTML/DOM/HTMLTitleElement.cpp10
-rw-r--r--Libraries/LibHTML/DOM/HTMLTitleElement.h9
-rw-r--r--Libraries/LibHTML/DOM/Node.h9
-rw-r--r--Libraries/LibHTML/HtmlView.h1
-rw-r--r--Libraries/LibHTML/Makefile.shared3
-rw-r--r--Libraries/LibHTML/Parser/HTMLParser.cpp9
12 files changed, 116 insertions, 1 deletions
diff --git a/Libraries/LibHTML/DOM/Document.cpp b/Libraries/LibHTML/DOM/Document.cpp
index 766be050ba..22a9d0a910 100644
--- a/Libraries/LibHTML/DOM/Document.cpp
+++ b/Libraries/LibHTML/DOM/Document.cpp
@@ -1,6 +1,9 @@
#include <LibHTML/CSS/StyleResolver.h>
#include <LibHTML/DOM/Document.h>
#include <LibHTML/DOM/Element.h>
+#include <LibHTML/DOM/HTMLHeadElement.h>
+#include <LibHTML/DOM/HTMLHtmlElement.h>
+#include <LibHTML/DOM/HTMLTitleElement.h>
#include <LibHTML/Layout/LayoutDocument.h>
#include <stdio.h>
@@ -34,3 +37,29 @@ void Document::normalize()
this->donate_all_children_to(body);
this->append_child(html);
}
+
+const HTMLHtmlElement* Document::document_element() const
+{
+ return static_cast<const HTMLHtmlElement*>(first_child_with_tag_name("html"));
+}
+
+const HTMLHeadElement* Document::head() const
+{
+ auto* html = document_element();
+ if (!html)
+ return nullptr;
+ return static_cast<const HTMLHeadElement*>(html->first_child_with_tag_name("head"));
+}
+
+String Document::title() const
+{
+ auto* head_element = head();
+ if (!head_element)
+ return {};
+
+ auto* title_element = static_cast<const HTMLTitleElement*>(head_element->first_child_with_tag_name("title"));
+ if (!title_element)
+ return {};
+
+ return title_element->text_content();
+}
diff --git a/Libraries/LibHTML/DOM/Document.h b/Libraries/LibHTML/DOM/Document.h
index 1364cfb3c4..ce779e52f2 100644
--- a/Libraries/LibHTML/DOM/Document.h
+++ b/Libraries/LibHTML/DOM/Document.h
@@ -1,12 +1,14 @@
#pragma once
-#include <AK/String.h>
#include <AK/NonnullRefPtrVector.h>
#include <AK/OwnPtr.h>
+#include <AK/String.h>
#include <LibHTML/CSS/StyleResolver.h>
#include <LibHTML/CSS/StyleSheet.h>
#include <LibHTML/DOM/ParentNode.h>
+class HTMLHtmlElement;
+class HTMLHeadElement;
class LayoutNode;
class StyleResolver;
class StyleSheet;
@@ -29,6 +31,11 @@ public:
Node* hovered_node() { return m_hovered_node; }
const Node* hovered_node() const { return m_hovered_node; }
+ const HTMLHtmlElement* document_element() const;
+ const HTMLHeadElement* head() const;
+
+ String title() const;
+
private:
OwnPtr<StyleResolver> m_style_resolver;
NonnullRefPtrVector<StyleSheet> m_sheets;
diff --git a/Libraries/LibHTML/DOM/HTMLHeadElement.cpp b/Libraries/LibHTML/DOM/HTMLHeadElement.cpp
new file mode 100644
index 0000000000..2bad3da75d
--- /dev/null
+++ b/Libraries/LibHTML/DOM/HTMLHeadElement.cpp
@@ -0,0 +1,10 @@
+#include <LibHTML/DOM/HTMLHeadElement.h>
+
+HTMLHeadElement::HTMLHeadElement(Document& document, const String& tag_name)
+ : HTMLElement(document, tag_name)
+{
+}
+
+HTMLHeadElement::~HTMLHeadElement()
+{
+}
diff --git a/Libraries/LibHTML/DOM/HTMLHeadElement.h b/Libraries/LibHTML/DOM/HTMLHeadElement.h
new file mode 100644
index 0000000000..4586a26bf3
--- /dev/null
+++ b/Libraries/LibHTML/DOM/HTMLHeadElement.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <LibHTML/DOM/HTMLElement.h>
+
+class HTMLHeadElement : public HTMLElement {
+public:
+ HTMLHeadElement(Document&, const String& tag_name);
+ virtual ~HTMLHeadElement() override;
+};
diff --git a/Libraries/LibHTML/DOM/HTMLHtmlElement.cpp b/Libraries/LibHTML/DOM/HTMLHtmlElement.cpp
new file mode 100644
index 0000000000..cc12a426e8
--- /dev/null
+++ b/Libraries/LibHTML/DOM/HTMLHtmlElement.cpp
@@ -0,0 +1,10 @@
+#include <LibHTML/DOM/HTMLHtmlElement.h>
+
+HTMLHtmlElement::HTMLHtmlElement(Document& document, const String& tag_name)
+ : HTMLElement(document, tag_name)
+{
+}
+
+HTMLHtmlElement::~HTMLHtmlElement()
+{
+}
diff --git a/Libraries/LibHTML/DOM/HTMLHtmlElement.h b/Libraries/LibHTML/DOM/HTMLHtmlElement.h
new file mode 100644
index 0000000000..4ab5b78af6
--- /dev/null
+++ b/Libraries/LibHTML/DOM/HTMLHtmlElement.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <LibHTML/DOM/HTMLElement.h>
+
+class HTMLHtmlElement : public HTMLElement {
+public:
+ HTMLHtmlElement(Document&, const String& tag_name);
+ virtual ~HTMLHtmlElement() override;
+};
diff --git a/Libraries/LibHTML/DOM/HTMLTitleElement.cpp b/Libraries/LibHTML/DOM/HTMLTitleElement.cpp
new file mode 100644
index 0000000000..de4e6db20a
--- /dev/null
+++ b/Libraries/LibHTML/DOM/HTMLTitleElement.cpp
@@ -0,0 +1,10 @@
+#include <LibHTML/DOM/HTMLTitleElement.h>
+
+HTMLTitleElement::HTMLTitleElement(Document& document, const String& tag_name)
+ : HTMLElement(document, tag_name)
+{
+}
+
+HTMLTitleElement::~HTMLTitleElement()
+{
+}
diff --git a/Libraries/LibHTML/DOM/HTMLTitleElement.h b/Libraries/LibHTML/DOM/HTMLTitleElement.h
new file mode 100644
index 0000000000..4b0edf803a
--- /dev/null
+++ b/Libraries/LibHTML/DOM/HTMLTitleElement.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <LibHTML/DOM/HTMLElement.h>
+
+class HTMLTitleElement : public HTMLElement {
+public:
+ HTMLTitleElement(Document&, const String& tag_name);
+ virtual ~HTMLTitleElement() override;
+};
diff --git a/Libraries/LibHTML/DOM/Node.h b/Libraries/LibHTML/DOM/Node.h
index 25659e5a29..a49220d84c 100644
--- a/Libraries/LibHTML/DOM/Node.h
+++ b/Libraries/LibHTML/DOM/Node.h
@@ -46,6 +46,15 @@ public:
virtual bool is_html_element() const { return false; }
+ const Node* first_child_with_tag_name(const StringView& tag_name) const
+ {
+ for (auto* child = first_child(); child; child = child->next_sibling()) {
+ if (child->tag_name() == tag_name)
+ return child;
+ }
+ return nullptr;
+ }
+
protected:
Node(Document&, NodeType);
diff --git a/Libraries/LibHTML/HtmlView.h b/Libraries/LibHTML/HtmlView.h
index 8f62c3d8a6..ffa99578c2 100644
--- a/Libraries/LibHTML/HtmlView.h
+++ b/Libraries/LibHTML/HtmlView.h
@@ -13,6 +13,7 @@ public:
void set_document(Document*);
Function<void(const String&)> on_link_click;
+ Function<void(const String&)> on_title_change;
protected:
HtmlView(GWidget* parent = nullptr);
diff --git a/Libraries/LibHTML/Makefile.shared b/Libraries/LibHTML/Makefile.shared
index efa0f8ccd3..76329a0299 100644
--- a/Libraries/LibHTML/Makefile.shared
+++ b/Libraries/LibHTML/Makefile.shared
@@ -5,6 +5,9 @@ LIBHTML_OBJS = \
DOM/HTMLElement.o \
DOM/HTMLAnchorElement.o \
DOM/HTMLHeadingElement.o \
+ DOM/HTMLHeadElement.o \
+ DOM/HTMLHtmlElement.o \
+ DOM/HTMLTitleElement.o \
DOM/Document.o \
DOM/Text.o \
CSS/Selector.o \
diff --git a/Libraries/LibHTML/Parser/HTMLParser.cpp b/Libraries/LibHTML/Parser/HTMLParser.cpp
index d01df0c1de..940726c565 100644
--- a/Libraries/LibHTML/Parser/HTMLParser.cpp
+++ b/Libraries/LibHTML/Parser/HTMLParser.cpp
@@ -2,7 +2,10 @@
#include <AK/StringBuilder.h>
#include <LibHTML/DOM/Element.h>
#include <LibHTML/DOM/HTMLAnchorElement.h>
+#include <LibHTML/DOM/HTMLHeadElement.h>
#include <LibHTML/DOM/HTMLHeadingElement.h>
+#include <LibHTML/DOM/HTMLHtmlElement.h>
+#include <LibHTML/DOM/HTMLTitleElement.h>
#include <LibHTML/DOM/Text.h>
#include <LibHTML/Parser/HTMLParser.h>
#include <ctype.h>
@@ -13,6 +16,12 @@ static NonnullRefPtr<Element> create_element(Document& document, const String& t
auto lowercase_tag_name = tag_name.to_lowercase();
if (lowercase_tag_name == "a")
return adopt(*new HTMLAnchorElement(document, tag_name));
+ if (lowercase_tag_name == "html")
+ return adopt(*new HTMLHtmlElement(document, tag_name));
+ if (lowercase_tag_name == "head")
+ return adopt(*new HTMLHeadElement(document, tag_name));
+ if (lowercase_tag_name == "title")
+ return adopt(*new HTMLTitleElement(document, tag_name));
if (lowercase_tag_name == "h1"
|| lowercase_tag_name == "h2"
|| lowercase_tag_name == "h3"