-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LibHTML: Start working on a simple HTML library.
I'd like to have rich text, and we might as well use HTML for that. :^)
- Loading branch information
1 parent
01d1aee
commit a67e823
Showing
19 changed files
with
329 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*.o | ||
*.d | ||
libhtml.a | ||
tho |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include <LibHTML/Document.h> | ||
|
||
Document::Document() | ||
: ParentNode(NodeType::DOCUMENT_NODE) | ||
{ | ||
} | ||
|
||
Document::~Document() | ||
{ | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#pragma once | ||
|
||
#include <AK/AKString.h> | ||
#include <LibHTML/ParentNode.h> | ||
|
||
class Document : public ParentNode { | ||
public: | ||
Document(); | ||
virtual ~Document() override; | ||
|
||
private: | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#include <LibHTML/Document.h> | ||
#include <LibHTML/Dump.h> | ||
#include <LibHTML/Element.h> | ||
#include <LibHTML/Text.h> | ||
#include <stdio.h> | ||
|
||
void dump_tree(Node& node) | ||
{ | ||
static int indent = 0; | ||
for (int i = 0; i < indent; ++i) | ||
printf(" "); | ||
if (node.is_document()) { | ||
printf("*Document*\n"); | ||
} else if (node.is_element()) { | ||
printf("<%s>\n", static_cast<Element&>(node).tag_name().characters()); | ||
} else if (node.is_text()) { | ||
printf("\"%s\"\n", static_cast<Text&>(node).data().characters()); | ||
} | ||
++indent; | ||
if (node.is_parent_node()) { | ||
static_cast<ParentNode&>(node).for_each_child([](Node& child) { | ||
dump_tree(child); | ||
}); | ||
} | ||
--indent; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#pragma once | ||
|
||
class Node; | ||
|
||
void dump_tree(Node&); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#include <LibHTML/Element.h> | ||
|
||
Element::Element(const String& tag_name) | ||
: ParentNode(NodeType::ELEMENT_NODE) | ||
, m_tag_name(tag_name) | ||
{ | ||
} | ||
|
||
Element::~Element() | ||
{ | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#pragma once | ||
|
||
#include <LibHTML/ParentNode.h> | ||
#include <AK/AKString.h> | ||
|
||
class Attribute { | ||
public: | ||
Attribute(const String& name, const String& value) | ||
: m_name(name) | ||
, m_value(value) | ||
{ | ||
} | ||
|
||
private: | ||
String m_name; | ||
String m_value; | ||
}; | ||
|
||
class Element : public ParentNode { | ||
public: | ||
explicit Element(const String& tag_name); | ||
virtual ~Element() override; | ||
|
||
const String& tag_name() const { return m_tag_name; } | ||
|
||
private: | ||
String m_tag_name; | ||
Vector<Attribute> m_attributes; | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
include ../Makefile.common | ||
|
||
LIBHTML_OBJS = \ | ||
Node.o \ | ||
ParentNode.o \ | ||
Element.o \ | ||
Document.o \ | ||
Text.o \ | ||
Parser.o \ | ||
Dump.o | ||
|
||
TEST_OBJS = test.o | ||
TEST_PROGRAM = tho | ||
|
||
OBJS = $(LIBHTML_OBJS) $(TEST_OBJS) | ||
|
||
LIBRARY = libhtml.a | ||
DEFINES += -DUSERLAND | ||
|
||
all: $(LIBRARY) $(TEST_PROGRAM) | ||
|
||
$(TEST_PROGRAM): $(TEST_OBJS) $(LIBRARY) | ||
$(LD) -o $@ $(LDFLAGS) -L. $(TEST_OBJS) -lhtml -lgui -lcore -lc | ||
|
||
$(LIBRARY): $(LIBHTML_OBJS) | ||
@echo "LIB $@"; $(AR) rcs $@ $(LIBHTML_OBJS) | ||
|
||
.cpp.o: | ||
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< | ||
|
||
-include $(OBJS:%.o=%.d) | ||
|
||
clean: | ||
@echo "CLEAN"; rm -f $(TEST_PROGRAM) $(LIBRARY) $(OBJS) *.d | ||
|
||
install: $(LIBRARY) | ||
mkdir -p ../Root/usr/include/LibHTML | ||
# Copy headers | ||
rsync -r -a --include '*/' --include '*.h' --exclude '*' . ../Root/usr/include/LibHTML | ||
# Install the library | ||
cp $(LIBRARY) ../Root/usr/lib | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#include <AK/Retained.h> | ||
#include <LibHTML/Node.h> | ||
|
||
Node::Node(NodeType type) | ||
: m_type(type) | ||
{ | ||
} | ||
|
||
Node::~Node() | ||
{ | ||
} | ||
|
||
void Node::retain() | ||
{ | ||
ASSERT(m_retain_count); | ||
++m_retain_count; | ||
} | ||
|
||
void Node::release() | ||
{ | ||
ASSERT(m_retain_count); | ||
if (!--m_retain_count) | ||
delete this; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#pragma once | ||
|
||
#include <AK/Retained.h> | ||
#include <AK/Vector.h> | ||
|
||
enum class NodeType : unsigned { | ||
INVALID = 0, | ||
ELEMENT_NODE = 1, | ||
TEXT_NODE = 3, | ||
DOCUMENT_NODE = 9, | ||
}; | ||
|
||
class Node { | ||
public: | ||
virtual ~Node(); | ||
|
||
void retain(); | ||
void release(); | ||
int retain_count() const { return m_retain_count; } | ||
|
||
NodeType type() const { return m_type; } | ||
bool is_element() const { return type() == NodeType::ELEMENT_NODE; } | ||
bool is_text() const { return type() == NodeType::TEXT_NODE; } | ||
bool is_document() const { return type() == NodeType::DOCUMENT_NODE; } | ||
bool is_parent_node() const { return is_element() || is_document(); } | ||
|
||
Node* next_sibling() { return m_next_sibling; } | ||
Node* previous_sibling() { return m_previous_sibling; } | ||
void set_next_sibling(Node* node) { m_next_sibling = node; } | ||
void set_previous_sibling(Node* node) { m_previous_sibling = node; } | ||
|
||
protected: | ||
explicit Node(NodeType); | ||
|
||
int m_retain_count { 1 }; | ||
NodeType m_type { NodeType::INVALID }; | ||
Vector<Node*> m_children; | ||
Node* m_next_sibling { nullptr }; | ||
Node* m_previous_sibling { nullptr }; | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include <LibHTML/ParentNode.h> | ||
|
||
void ParentNode::append_child(Retained<Node> node) | ||
{ | ||
if (m_last_child) | ||
m_last_child->set_next_sibling(node.ptr()); | ||
m_last_child = &node.leak_ref(); | ||
if (!m_first_child) | ||
m_first_child = m_last_child; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#pragma once | ||
|
||
#include <LibHTML/Node.h> | ||
|
||
class ParentNode : public Node { | ||
public: | ||
void append_child(Retained<Node>); | ||
|
||
Node* first_child() { return m_first_child; } | ||
Node* last_child() { return m_last_child; } | ||
|
||
template<typename F> void for_each_child(F); | ||
|
||
protected: | ||
explicit ParentNode(NodeType type) | ||
: Node(type) | ||
{ | ||
} | ||
|
||
private: | ||
Node* m_first_child { nullptr }; | ||
Node* m_last_child { nullptr }; | ||
}; | ||
|
||
template<typename F> | ||
inline void ParentNode::for_each_child(F func) | ||
{ | ||
for (auto* node = first_child(); node; node = node->next_sibling()) { | ||
func(*node); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#include <LibHTML/Element.h> | ||
#include <LibHTML/Parser.h> | ||
#include <LibHTML/Text.h> | ||
|
||
static Retained<Element> create_element(const String& tag_name) | ||
{ | ||
return adopt(*new Element(tag_name)); | ||
} | ||
|
||
Retained<Document> parse(const String& html) | ||
{ | ||
auto doc = adopt(*new Document); | ||
|
||
auto head = create_element("head"); | ||
auto title = create_element("title"); | ||
auto title_text = adopt(*new Text("Page Title")); | ||
title->append_child(title_text); | ||
head->append_child(title); | ||
|
||
doc->append_child(head); | ||
|
||
auto body = create_element("body"); | ||
auto h1 = create_element("h1"); | ||
auto h1_text = adopt(*new Text("Hello World!")); | ||
|
||
h1->append_child(h1_text); | ||
body->append_child(h1); | ||
doc->append_child(body); | ||
|
||
return doc; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#pragma once | ||
|
||
#include <AK/Retained.h> | ||
#include <LibHTML/Document.h> | ||
|
||
Retained<Document> parse(const String& html); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#include <LibHTML/Text.h> | ||
|
||
Text::Text(const String& data) | ||
: Node(NodeType::TEXT_NODE) | ||
, m_data(data) | ||
{ | ||
} | ||
|
||
Text::~Text() | ||
{ | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#pragma once | ||
|
||
#include <AK/AKString.h> | ||
#include <LibHTML/Node.h> | ||
|
||
class Text final : public Node { | ||
public: | ||
explicit Text(const String&); | ||
virtual ~Text() override; | ||
|
||
const String& data() const { return m_data; } | ||
|
||
private: | ||
String m_data; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include <LibHTML/Dump.h> | ||
#include <LibHTML/Element.h> | ||
#include <LibHTML/Parser.h> | ||
|
||
int main() | ||
{ | ||
String html = "<html><head><title>my page</title></head><body><h1>Hi there</h1><p>Hello World!</p></body></html>"; | ||
auto doc = parse(html); | ||
dump_tree(doc); | ||
} |