diff options
author | Andreas Kling <kling@serenityos.org> | 2020-03-07 10:32:51 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-07 10:32:51 +0100 |
commit | 830a57c6b23430c749395811761252d1999f3559 (patch) | |
tree | 0bccfa6bc0ec8a39af0dab20633257df3384a4b3 /Libraries/LibWeb/DOM | |
parent | 7a6c4a72d5a7da31dbbd5178a469ae37ef68eaea (diff) | |
download | serenity-830a57c6b23430c749395811761252d1999f3559.zip |
LibWeb: Rename directory LibHTML => LibWeb
Let's rename this to LibWeb since it aims to provide more parts of the
web platform than just HTML. :^)
Diffstat (limited to 'Libraries/LibWeb/DOM')
51 files changed, 3445 insertions, 0 deletions
diff --git a/Libraries/LibWeb/DOM/CharacterData.cpp b/Libraries/LibWeb/DOM/CharacterData.cpp new file mode 100644 index 0000000000..a7fa15eb1d --- /dev/null +++ b/Libraries/LibWeb/DOM/CharacterData.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/CharacterData.h> + +namespace Web { + +CharacterData::CharacterData(Document& document, NodeType type, const String& data) + : Node(document, type) + , m_data(data) +{ +} + +CharacterData::~CharacterData() +{ +} + +} diff --git a/Libraries/LibWeb/DOM/CharacterData.h b/Libraries/LibWeb/DOM/CharacterData.h new file mode 100644 index 0000000000..dece5fe338 --- /dev/null +++ b/Libraries/LibWeb/DOM/CharacterData.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <AK/String.h> +#include <LibWeb/DOM/Node.h> + +namespace Web { + +class CharacterData : public Node { +public: + virtual ~CharacterData() override; + + const String& data() const { return m_data; } + + virtual String text_content() const override { return m_data; } + +protected: + explicit CharacterData(Document&, NodeType, const String&); + +private: + String m_data; +}; + +template<> +inline bool is<CharacterData>(const Node& node) +{ + return node.is_character_data(); +} + +} diff --git a/Libraries/LibWeb/DOM/Comment.cpp b/Libraries/LibWeb/DOM/Comment.cpp new file mode 100644 index 0000000000..0bd30e008e --- /dev/null +++ b/Libraries/LibWeb/DOM/Comment.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/Comment.h> +#include <LibWeb/Layout/LayoutText.h> + +namespace Web { + +Comment::Comment(Document& document, const String& data) + : CharacterData(document, NodeType::COMMENT_NODE, data) +{ +} + +Comment::~Comment() +{ +} + +} diff --git a/Libraries/LibWeb/DOM/Comment.h b/Libraries/LibWeb/DOM/Comment.h new file mode 100644 index 0000000000..8530ad9191 --- /dev/null +++ b/Libraries/LibWeb/DOM/Comment.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <AK/String.h> +#include <LibWeb/DOM/CharacterData.h> + +namespace Web { + +class Comment final : public CharacterData { +public: + explicit Comment(Document&, const String&); + virtual ~Comment() override; + + virtual String tag_name() const override { return "#comment"; } +}; + +template<> +inline bool is<Comment>(const Node& node) +{ + return node.is_comment(); +} + +} diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp new file mode 100644 index 0000000000..6b2f11e81a --- /dev/null +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/FileSystemPath.h> +#include <AK/StringBuilder.h> +#include <LibCore/Timer.h> +#include <LibGUI/Application.h> +#include <LibWeb/CSS/StyleResolver.h> +#include <LibWeb/DOM/Document.h> +#include <LibWeb/DOM/DocumentType.h> +#include <LibWeb/DOM/Element.h> +#include <LibWeb/DOM/ElementFactory.h> +#include <LibWeb/DOM/HTMLBodyElement.h> +#include <LibWeb/DOM/HTMLHeadElement.h> +#include <LibWeb/DOM/HTMLHtmlElement.h> +#include <LibWeb/DOM/HTMLTitleElement.h> +#include <LibWeb/Frame.h> +#include <LibWeb/HtmlView.h> +#include <LibWeb/Layout/LayoutDocument.h> +#include <LibWeb/Layout/LayoutTreeBuilder.h> +#include <stdio.h> + +namespace Web { + +Document::Document() + : ParentNode(*this, NodeType::DOCUMENT_NODE) + , m_style_resolver(make<StyleResolver>(*this)) +{ + m_style_update_timer = Core::Timer::construct(); + m_style_update_timer->set_single_shot(true); + m_style_update_timer->set_interval(0); + m_style_update_timer->on_timeout = [this] { + update_style(); + }; +} + +Document::~Document() +{ +} + +void Document::schedule_style_update() +{ + if (m_style_update_timer->is_active()) + return; + m_style_update_timer->start(); +} + +bool Document::is_child_allowed(const Node& node) const +{ + switch (node.type()) { + case NodeType::DOCUMENT_NODE: + case NodeType::TEXT_NODE: + return false; + case NodeType::COMMENT_NODE: + return true; + case NodeType::DOCUMENT_TYPE_NODE: + return !first_child_of_type<DocumentType>(); + case NodeType::ELEMENT_NODE: + return !first_child_of_type<Element>(); + default: + return false; + } +} + +void Document::fixup() +{ + if (!first_child() || !is<DocumentType>(*first_child())) + prepend_child(adopt(*new DocumentType(*this))); + + if (is<HTMLHtmlElement>(first_child()->next_sibling())) + return; + + auto body = create_element(*this, "body"); + auto html = create_element(*this, "html"); + html->append_child(body); + this->donate_all_children_to(body); + this->append_child(html); +} + +const HTMLHtmlElement* Document::document_element() const +{ + return first_child_of_type<HTMLHtmlElement>(); +} + +const HTMLHeadElement* Document::head() const +{ + auto* html = document_element(); + if (!html) + return nullptr; + return html->first_child_of_type<HTMLHeadElement>(); +} + +const HTMLBodyElement* Document::body() const +{ + auto* html = document_element(); + if (!html) + return nullptr; + return html->first_child_of_type<HTMLBodyElement>(); +} + +String Document::title() const +{ + auto* head_element = head(); + if (!head_element) + return {}; + + auto* title_element = head_element->first_child_of_type<HTMLTitleElement>(); + if (!title_element) + return {}; + + return title_element->text_content(); +} + +void Document::attach_to_frame(Badge<Frame>, Frame& frame) +{ + m_frame = frame.make_weak_ptr(); + layout(); +} + +void Document::detach_from_frame(Badge<Frame>, Frame&) +{ + m_layout_root = nullptr; + m_frame = nullptr; +} + +Color Document::background_color(const Palette& palette) const +{ + auto default_color = palette.base(); + auto* body_element = body(); + if (!body_element) + return default_color; + + auto* body_layout_node = body_element->layout_node(); + if (!body_layout_node) + return default_color; + + auto background_color = body_layout_node->style().property(CSS::PropertyID::BackgroundColor); + if (!background_color.has_value() || !background_color.value()->is_color()) + return default_color; + + return background_color.value()->to_color(*this); +} + +RefPtr<Gfx::Bitmap> Document::background_image() const +{ + auto* body_element = body(); + if (!body_element) + return {}; + + auto* body_layout_node = body_element->layout_node(); + if (!body_layout_node) + return {}; + + auto background_image = body_layout_node->style().property(CSS::PropertyID::BackgroundImage); + if (!background_image.has_value() || !background_image.value()->is_image()) + return {}; + + auto& image_value = static_cast<const ImageStyleValue&>(*background_image.value()); + if (!image_value.bitmap()) + return {}; + + return *image_value.bitmap(); +} + +URL Document::complete_url(const String& string) const +{ + return m_url.complete_url(string); +} + +void Document::force_layout() +{ + m_layout_root = nullptr; + layout(); +} + +void Document::layout() +{ + if (!m_layout_root) { + LayoutTreeBuilder tree_builder; + m_layout_root = tree_builder.build(*this); + } + m_layout_root->layout(); + m_layout_root->set_needs_display(); +} + +void Document::update_style() +{ + for_each_in_subtree_of_type<Element>([&](auto& element) { + if (element.needs_style_update()) + element.recompute_style(); + return IterationDecision::Continue; + }); + update_layout(); +} + +void Document::update_layout() +{ + if (!frame()) + return; + + layout(); + if (on_layout_updated) + on_layout_updated(); +} + +RefPtr<LayoutNode> Document::create_layout_node(const StyleProperties*) const +{ + return adopt(*new LayoutDocument(*this, StyleProperties::create())); +} + +void Document::set_link_color(Color color) +{ + m_link_color = color; +} + +void Document::set_active_link_color(Color color) +{ + m_active_link_color = color; +} + +void Document::set_visited_link_color(Color color) +{ + m_visited_link_color = color; +} + +const LayoutDocument* Document::layout_node() const +{ + return static_cast<const LayoutDocument*>(Node::layout_node()); +} + +LayoutDocument* Document::layout_node() +{ + return static_cast<LayoutDocument*>(Node::layout_node()); +} + +void Document::set_inspected_node(Node* node) +{ + if (m_inspected_node == node) + return; + + if (m_inspected_node && m_inspected_node->layout_node()) + m_inspected_node->layout_node()->set_needs_display(); + + m_inspected_node = node; + + if (m_inspected_node && m_inspected_node->layout_node()) + m_inspected_node->layout_node()->set_needs_display(); +} + +void Document::set_hovered_node(Node* node) +{ + if (m_hovered_node == node) + return; + + RefPtr<Node> old_hovered_node = move(m_hovered_node); + m_hovered_node = node; + + invalidate_style(); +} + +const Element* Document::get_element_by_id(const String& id) const +{ + const Element* found_element = nullptr; + for_each_in_subtree_of_type<Element>([&](auto& element) { + if (element.attribute("id") == id) { + found_element = &element; + return IterationDecision::Break; + } + return IterationDecision::Continue; + }); + return found_element; +} + +Vector<const Element*> Document::get_elements_by_name(const String& name) const +{ + Vector<const Element*> elements; + for_each_in_subtree_of_type<Element>([&](auto& element) { + if (element.attribute("name") == name) + elements.append(&element); + return IterationDecision::Continue; + }); + return elements; +} + +Color Document::link_color() const +{ + if (m_link_color.has_value()) + return m_link_color.value(); + if (!frame()) + return Color::Blue; + return frame()->html_view()->palette().link(); +} + +Color Document::active_link_color() const +{ + if (m_active_link_color.has_value()) + return m_active_link_color.value(); + if (!frame()) + return Color::Red; + return frame()->html_view()->palette().active_link(); +} + +Color Document::visited_link_color() const +{ + if (m_visited_link_color.has_value()) + return m_visited_link_color.value(); + if (!frame()) + return Color::Magenta; + return frame()->html_view()->palette().visited_link(); +} + +} diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h new file mode 100644 index 0000000000..aa7d3e2014 --- /dev/null +++ b/Libraries/LibWeb/DOM/Document.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <AK/Function.h> +#include <AK/NonnullRefPtrVector.h> +#include <AK/OwnPtr.h> +#include <AK/String.h> +#include <AK/URL.h> +#include <AK/WeakPtr.h> +#include <LibCore/Forward.h> +#include <LibWeb/CSS/StyleResolver.h> +#include <LibWeb/CSS/StyleSheet.h> +#include <LibWeb/DOM/ParentNode.h> + +namespace Web { + +class Frame; +class HTMLBodyElement; +class HTMLHtmlElement; +class HTMLHeadElement; +class LayoutDocument; +class LayoutNode; +class StyleResolver; +class StyleSheet; + +class Document : public ParentNode { +public: + Document(); + virtual ~Document() override; + + void set_url(const URL& url) { m_url = url; } + const URL& url() const { return m_url; } + + URL complete_url(const String&) const; + + void fixup(); + + StyleResolver& style_resolver() { return *m_style_resolver; } + const StyleResolver& style_resolver() const { return *m_style_resolver; } + + void add_sheet(const StyleSheet& sheet) { m_sheets.append(sheet); } + const NonnullRefPtrVector<StyleSheet>& stylesheets() const { return m_sheets; } + + virtual String tag_name() const override { return "#document"; } + + void set_hovered_node(Node*); + Node* hovered_node() { return m_hovered_node; } + const Node* hovered_node() const { return m_hovered_node; } + + void set_inspected_node(Node*); + Node* inspected_node() { return m_inspected_node; } + const Node* inspected_node() const { return m_inspected_node; } + + const HTMLHtmlElement* document_element() const; + const HTMLHeadElement* head() const; + const HTMLBodyElement* body() const; + + String title() const; + + void attach_to_frame(Badge<Frame>, Frame&); + void detach_from_frame(Badge<Frame>, Frame&); + + Frame* frame() { return m_frame.ptr(); } + const Frame* frame() const { return m_frame.ptr(); } + + Color background_color(const Gfx::Palette&) const; + RefPtr<Gfx::Bitmap> background_image() const; + + Color link_color() const; + void set_link_color(Color); + + Color active_link_color() const; + void set_active_link_color(Color); + + Color visited_link_color() const; + void set_visited_link_color(Color); + + void layout(); + void force_layout(); + + void update_style(); + void update_layout(); + Function<void()> on_layout_updated; + + virtual bool is_child_allowed(const Node&) const override; + + const LayoutDocument* layout_node() const; + LayoutDocument* layout_node(); + + void schedule_style_update(); + + const Element* get_element_by_id(const String&) const; + Vector<const Element*> get_elements_by_name(const String&) const; + + const String& source() const { return m_source; } + void set_source(const String& source) { m_source = source; } + +private: + virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; + + OwnPtr<StyleResolver> m_style_resolver; + NonnullRefPtrVector<StyleSheet> m_sheets; + RefPtr<Node> m_hovered_node; + RefPtr<Node> m_inspected_node; + WeakPtr<Frame> m_frame; + URL m_url; + + RefPtr<LayoutDocument> m_layout_root; + + Optional<Color> m_link_color; + Optional<Color> m_active_link_color; + Optional<Color> m_visited_link_color; + + RefPtr<Core::Timer> m_style_update_timer; + + String m_source; +}; + +template<> +inline bool is<Document>(const Node& node) +{ + return node.is_document(); +} + +} diff --git a/Libraries/LibWeb/DOM/DocumentFragment.h b/Libraries/LibWeb/DOM/DocumentFragment.h new file mode 100644 index 0000000000..55e51feec4 --- /dev/null +++ b/Libraries/LibWeb/DOM/DocumentFragment.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/ParentNode.h> + +namespace Web { + +class DocumentFragment : public ParentNode { +public: + DocumentFragment(Document& document) + : ParentNode(document, NodeType::DOCUMENT_FRAGMENT_NODE) + { + } + + virtual String tag_name() const override { return "#document-fragment"; } +}; + +template<> +inline bool is<DocumentFragment>(const Node& node) +{ + return node.is_document_fragment(); +} + +} diff --git a/Libraries/LibWeb/DOM/DocumentType.cpp b/Libraries/LibWeb/DOM/DocumentType.cpp new file mode 100644 index 0000000000..c6481f7824 --- /dev/null +++ b/Libraries/LibWeb/DOM/DocumentType.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/DocumentType.h> + +namespace Web { + +DocumentType::DocumentType(Document& document) + : Node(document, NodeType::DOCUMENT_TYPE_NODE) +{ +} + +DocumentType::~DocumentType() +{ +} + +} diff --git a/Libraries/LibWeb/DOM/DocumentType.h b/Libraries/LibWeb/DOM/DocumentType.h new file mode 100644 index 0000000000..b863ecb98c --- /dev/null +++ b/Libraries/LibWeb/DOM/DocumentType.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/Node.h> + +namespace Web { + +class DocumentType final : public Node { +public: + explicit DocumentType(Document&); + virtual ~DocumentType() override; + + virtual String tag_name() const override { return "#doctype"; } +}; + +template<> +inline bool is<DocumentType>(const Node& node) +{ + return node.type() == NodeType::DOCUMENT_TYPE_NODE; +} + +} diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp new file mode 100644 index 0000000000..fc3674a32b --- /dev/null +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/CSS/StyleResolver.h> +#include <LibWeb/CSS/PropertyID.h> +#include <LibWeb/CSS/Length.h> +#include <LibWeb/DOM/Document.h> +#include <LibWeb/DOM/Element.h> +#include <LibWeb/Layout/LayoutBlock.h> +#include <LibWeb/Layout/LayoutInline.h> +#include <LibWeb/Layout/LayoutListItem.h> +#include <LibWeb/Layout/LayoutTable.h> +#include <LibWeb/Layout/LayoutTableCell.h> +#include <LibWeb/Layout/LayoutTableRow.h> +#include <LibWeb/Layout/LayoutTreeBuilder.h> + +namespace Web { + +Element::Element(Document& document, const String& tag_name) + : ParentNode(document, NodeType::ELEMENT_NODE) + , m_tag_name(tag_name) +{ +} + +Element::~Element() +{ +} + +Attribute* Element::find_attribute(const String& name) +{ + for (auto& attribute : m_attributes) { + if (attribute.name() == name) + return &attribute; + } + return nullptr; +} + +const Attribute* Element::find_attribute(const String& name) const +{ + for (auto& attribute : m_attributes) { + if (attribute.name() == name) + return &attribute; + } + return nullptr; +} + +String Element::attribute(const String& name) const +{ + if (auto* attribute = find_attribute(name)) + return attribute->value(); + return {}; +} + +void Element::set_attribute(const String& name, const String& value) +{ + if (auto* attribute = find_attribute(name)) + attribute->set_value(value); + else + m_attributes.empend(name, value); + + parse_attribute(name, value); +} + +void Element::set_attributes(Vector<Attribute>&& attributes) +{ + m_attributes = move(attributes); + + for (auto& attribute : m_attributes) + parse_attribute(attribute.name(), attribute.value()); +} + +bool Element::has_class(const StringView& class_name) const +{ + auto value = attribute("class"); + if (value.is_empty()) + return false; + auto parts = value.split_view(' '); + for (auto& part : parts) { + if (part == class_name) + return true; + } + return false; +} + +RefPtr<LayoutNode> Element::create_layout_node(const StyleProperties* parent_style) const +{ + auto style = document().style_resolver().resolve_style(*this, parent_style); + const_cast<Element&>(*this).m_resolved_style = style; + auto display = style->string_or_fallback(CSS::PropertyID::Display, "inline"); + + if (display == "none") + return nullptr; + if (display == "block") + return adopt(*new LayoutBlock(this, move(style))); + if (display == "inline") + return adopt(*new LayoutInline(*this, move(style))); + if (display == "list-item") + return adopt(*new LayoutListItem(*this, move(style))); + if (display == "table") + return adopt(*new LayoutTable(*this, move(style))); + if (display == "table-row") + return adopt(*new LayoutTableRow(*this, move(style))); + if (display == "table-cell") + return adopt(*new LayoutTableCell(*this, move(style))); + if (display == "inline-block") + return adopt(*new LayoutBlock(this, move(style))); + + ASSERT_NOT_REACHED(); +} + +void Element::parse_attribute(const String&, const String&) +{ +} + +enum class StyleDifference { + None, + NeedsRepaint, + NeedsRelayout, +}; + +static StyleDifference compute_style_difference(const StyleProperties& old_style, const StyleProperties& new_style, const Document& document) +{ + if (old_style == new_style) + return StyleDifference::None; + + bool needs_repaint = false; + bool needs_relayout = false; + + if (new_style.color_or_fallback(CSS::PropertyID::Color, document, Color::Black) != old_style.color_or_fallback(CSS::PropertyID::Color, document, Color::Black)) + needs_repaint = true; + else if (new_style.color_or_fallback(CSS::PropertyID::BackgroundColor, document, Color::Black) != old_style.color_or_fallback(CSS::PropertyID::BackgroundColor, document, Color::Black)) + needs_repaint = true; + + if (needs_relayout) + return StyleDifference::NeedsRelayout; + if (needs_repaint) + return StyleDifference::NeedsRepaint; + return StyleDifference::None; +} + +void Element::recompute_style() +{ + set_needs_style_update(false); + ASSERT(parent()); + auto* parent_layout_node = parent()->layout_node(); + if (!parent_layout_node) + return; + ASSERT(parent_layout_node); + auto style = document().style_resolver().resolve_style(*this, &parent_layout_node->style()); + m_resolved_style = style; + if (!layout_node()) { + if (style->string_or_fallback(CSS::PropertyID::Display, "inline") == "none") + return; + // We need a new layout tree here! + LayoutTreeBuilder tree_builder; + tree_builder.build(*this); + return; + } + auto diff = compute_style_difference(layout_node()->style(), *style, document()); + if (diff == StyleDifference::None) + return; + layout_node()->set_style(*style); + if (diff == StyleDifference::NeedsRelayout) { + ASSERT_NOT_REACHED(); + } + if (diff == StyleDifference::NeedsRepaint) { + layout_node()->set_needs_display(); + } +} + +NonnullRefPtr<StyleProperties> Element::computed_style() +{ + auto properties = m_resolved_style->clone(); + if (layout_node() && layout_node()->has_style()) { + CSS::PropertyID box_model_metrics[] = { + CSS::PropertyID::MarginTop, + CSS::PropertyID::MarginBottom, + CSS::PropertyID::MarginLeft, + CSS::PropertyID::MarginRight, + CSS::PropertyID::PaddingTop, + CSS::PropertyID::PaddingBottom, + CSS::PropertyID::PaddingLeft, + CSS::PropertyID::PaddingRight, + CSS::PropertyID::BorderTopWidth, + CSS::PropertyID::BorderBottomWidth, + CSS::PropertyID::BorderLeftWidth, + CSS::PropertyID::BorderRightWidth, + }; + for (CSS::PropertyID id : box_model_metrics) { + auto prop = layout_node()->style().property(id); + if (prop.has_value()) + properties->set_property(id, prop.value()); + } + } + return properties; +} + +} diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h new file mode 100644 index 0000000000..0e7af34ba8 --- /dev/null +++ b/Libraries/LibWeb/DOM/Element.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <AK/String.h> +#include <LibWeb/DOM/ParentNode.h> +#include <LibWeb/Layout/LayoutNode.h> + +namespace Web { + +class LayoutNodeWithStyle; + +class Attribute { +public: + Attribute(const String& name, const String& value) + : m_name(name) + , m_value(value) + { + } + + const String& name() const { return m_name; } + const String& value() const { return m_value; } + + void set_value(const String& value) { m_value = value; } + +private: + String m_name; + String m_value; +}; + +class Element : public ParentNode { +public: + Element(Document&, const String& tag_name); + virtual ~Element() override; + + virtual String tag_name() const final { return m_tag_name; } + + bool has_attribute(const String& name) const { return !attribute(name).is_null(); } + String attribute(const String& name) const; + void set_attribute(const String& name, const String& value); + + void set_attributes(Vector<Attribute>&&); + + template<typename Callback> + void for_each_attribute(Callback callback) const + { + for (auto& attribute : m_attributes) + callback(attribute.name(), attribute.value()); + } + + bool has_class(const StringView&) const; + + virtual void apply_presentational_hints(StyleProperties&) const {} + virtual void parse_attribute(const String& name, const String& value); + + void recompute_style(); + + LayoutNodeWithStyle* layout_node() { return static_cast<LayoutNodeWithStyle*>(Node::layout_node()); } + const LayoutNodeWithStyle* layout_node() const { return static_cast<const LayoutNodeWithStyle*>(Node::layout_node()); } + + String name() const { return attribute("name"); } + + const StyleProperties* resolved_style() const { return m_resolved_style.ptr(); } + NonnullRefPtr<StyleProperties> computed_style(); + +private: + RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; + + Attribute* find_attribute(const String& name); + const Attribute* find_attribute(const String& name) const; + + String m_tag_name; + Vector<Attribute> m_attributes; + + RefPtr<StyleProperties> m_resolved_style; +}; + +template<> +inline bool is<Element>(const Node& node) +{ + return node.is_element(); +} + +} diff --git a/Libraries/LibWeb/DOM/ElementFactory.cpp b/Libraries/LibWeb/DOM/ElementFactory.cpp new file mode 100644 index 0000000000..b2c362fa88 --- /dev/null +++ b/Libraries/LibWeb/DOM/ElementFactory.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/ElementFactory.h> +#include <LibWeb/DOM/HTMLAnchorElement.h> +#include <LibWeb/DOM/HTMLBRElement.h> +#include <LibWeb/DOM/HTMLBlinkElement.h> +#include <LibWeb/DOM/HTMLBodyElement.h> +#include <LibWeb/DOM/HTMLFontElement.h> +#include <LibWeb/DOM/HTMLFormElement.h> +#include <LibWeb/DOM/HTMLHRElement.h> +#include <LibWeb/DOM/HTMLHeadElement.h> +#include <LibWeb/DOM/HTMLHeadingElement.h> +#include <LibWeb/DOM/HTMLHtmlElement.h> +#include <LibWeb/DOM/HTMLImageElement.h> +#include <LibWeb/DOM/HTMLInputElement.h> +#include <LibWeb/DOM/HTMLLinkElement.h> +#include <LibWeb/DOM/HTMLStyleElement.h> +#include <LibWeb/DOM/HTMLTitleElement.h> + +namespace Web { + +NonnullRefPtr<Element> create_element(Document& document, const String& tag_name) +{ + auto lowercase_tag_name = tag_name.to_lowercase(); + if (lowercase_tag_name == "a") + return adopt(*new HTMLAnchorElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "html") + return adopt(*new HTMLHtmlElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "head") + return adopt(*new HTMLHeadElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "body") + return adopt(*new HTMLBodyElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "font") + return adopt(*new HTMLFontElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "hr") + return adopt(*new HTMLHRElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "style") + return adopt(*new HTMLStyleElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "title") + return adopt(*new HTMLTitleElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "link") + return adopt(*new HTMLLinkElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "img") + return adopt(*new HTMLImageElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "blink") + return adopt(*new HTMLBlinkElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "form") + return adopt(*new HTMLFormElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "input") + return adopt(*new HTMLInputElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "br") + return adopt(*new HTMLBRElement(document, lowercase_tag_name)); + if (lowercase_tag_name == "h1" + || lowercase_tag_name == "h2" + || lowercase_tag_name == "h3" + || lowercase_tag_name == "h4" + || lowercase_tag_name == "h5" + || lowercase_tag_name == "h6") { + return adopt(*new HTMLHeadingElement(document, lowercase_tag_name)); + } + return adopt(*new Element(document, lowercase_tag_name)); +} + +} diff --git a/Libraries/LibWeb/DOM/ElementFactory.h b/Libraries/LibWeb/DOM/ElementFactory.h new file mode 100644 index 0000000000..3c494e78cd --- /dev/null +++ b/Libraries/LibWeb/DOM/ElementFactory.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/Element.h> + +namespace Web { + +NonnullRefPtr<Element> create_element(Document&, const String& tag_name); + +} diff --git a/Libraries/LibWeb/DOM/HTMLAnchorElement.cpp b/Libraries/LibWeb/DOM/HTMLAnchorElement.cpp new file mode 100644 index 0000000000..5fffa52fdf --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLAnchorElement.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/HTMLAnchorElement.h> + +namespace Web { + +HTMLAnchorElement::HTMLAnchorElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLAnchorElement::~HTMLAnchorElement() +{ +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLAnchorElement.h b/Libraries/LibWeb/DOM/HTMLAnchorElement.h new file mode 100644 index 0000000000..89d20c7be4 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLAnchorElement.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLAnchorElement : public HTMLElement { +public: + HTMLAnchorElement(Document&, const String& tag_name); + virtual ~HTMLAnchorElement() override; + + String href() const { return attribute("href"); } +}; + +template<> +inline bool is<HTMLAnchorElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "a"; +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLBRElement.cpp b/Libraries/LibWeb/DOM/HTMLBRElement.cpp new file mode 100644 index 0000000000..f7667c44d6 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLBRElement.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/HTMLBRElement.h> +#include <LibWeb/Layout/LayoutBreak.h> + +namespace Web { + +HTMLBRElement::HTMLBRElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLBRElement::~HTMLBRElement() +{ +} + +RefPtr<LayoutNode> HTMLBRElement::create_layout_node(const StyleProperties*) const +{ + return adopt(*new LayoutBreak(*this)); +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLBRElement.h b/Libraries/LibWeb/DOM/HTMLBRElement.h new file mode 100644 index 0000000000..4dcf6ff185 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLBRElement.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLBRElement final : public HTMLElement { +public: + HTMLBRElement(Document&, const String& tag_name); + virtual ~HTMLBRElement() override; + + virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; +}; + +template<> +inline bool is<HTMLBRElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "br"; +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLBlinkElement.cpp b/Libraries/LibWeb/DOM/HTMLBlinkElement.cpp new file mode 100644 index 0000000000..51f8d96642 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLBlinkElement.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibCore/Timer.h> +#include <LibWeb/CSS/StyleProperties.h> +#include <LibWeb/CSS/StyleValue.h> +#include <LibWeb/DOM/HTMLBlinkElement.h> +#include <LibWeb/Layout/LayoutNode.h> + +namespace Web { + +HTMLBlinkElement::HTMLBlinkElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) + , m_timer(Core::Timer::construct()) +{ + m_timer->set_interval(500); + m_timer->on_timeout = [this] { blink(); }; + m_timer->start(); +} + +HTMLBlinkElement::~HTMLBlinkElement() +{ +} + +void HTMLBlinkElement::blink() +{ + if (!layout_node()) + return; + + layout_node()->set_visible(!layout_node()->is_visible()); + layout_node()->set_needs_display(); +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLBlinkElement.h b/Libraries/LibWeb/DOM/HTMLBlinkElement.h new file mode 100644 index 0000000000..63d85b5093 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLBlinkElement.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibCore/Forward.h> +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLBlinkElement : public HTMLElement { +public: + HTMLBlinkElement(Document&, const String& tag_name); + virtual ~HTMLBlinkElement() override; + +private: + void blink(); + + NonnullRefPtr<Core::Timer> m_timer; +}; + +} diff --git a/Libraries/LibWeb/DOM/HTMLBodyElement.cpp b/Libraries/LibWeb/DOM/HTMLBodyElement.cpp new file mode 100644 index 0000000000..a5fbd9dc90 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLBodyElement.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/CSS/StyleProperties.h> +#include <LibWeb/CSS/StyleValue.h> +#include <LibWeb/DOM/Document.h> +#include <LibWeb/DOM/HTMLBodyElement.h> + +namespace Web { + +HTMLBodyElement::HTMLBodyElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLBodyElement::~HTMLBodyElement() +{ +} + +void HTMLBodyElement::apply_presentational_hints(StyleProperties& style) const +{ + for_each_attribute([&](auto& name, auto& value) { + if (name.equals_ignoring_case("bgcolor")) { + auto color = Color::from_string(value); + if (color.has_value()) + style.set_property(CSS::PropertyID::BackgroundColor, ColorStyleValue::create(color.value())); + } else if (name.equals_ignoring_case("text")) { + auto color = Color::from_string(value); + if (color.has_value()) + style.set_property(CSS::PropertyID::Color, ColorStyleValue::create(color.value())); + } else if (name.equals_ignoring_case("background")) { + style.set_property(CSS::PropertyID::BackgroundImage, ImageStyleValue::create(document().complete_url(value), const_cast<Document&>(document()))); + } + }); +} + +void HTMLBodyElement::parse_attribute(const String& name, const String& value) +{ + if (name.equals_ignoring_case("link")) { + auto color = Color::from_string(value); + if (color.has_value()) + document().set_link_color(color.value()); + } else if (name.equals_ignoring_case("alink")) { + auto color = Color::from_string(value); + if (color.has_value()) + document().set_active_link_color(color.value()); + } else if (name.equals_ignoring_case("vlink")) { + auto color = Color::from_string(value); + if (color.has_value()) + document().set_visited_link_color(color.value()); + } +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLBodyElement.h b/Libraries/LibWeb/DOM/HTMLBodyElement.h new file mode 100644 index 0000000000..22296fa46c --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLBodyElement.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLBodyElement : public HTMLElement { +public: + HTMLBodyElement(Document&, const String& tag_name); + virtual ~HTMLBodyElement() override; + + virtual void parse_attribute(const String&, const String&) override; + virtual void apply_presentational_hints(StyleProperties&) const override; +}; + +template<> +inline bool is<HTMLBodyElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "body"; +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLElement.cpp b/Libraries/LibWeb/DOM/HTMLElement.cpp new file mode 100644 index 0000000000..030a442854 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLElement.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +HTMLElement::HTMLElement(Document& document, const String& tag_name) + : Element(document, tag_name) +{ +} + +HTMLElement::~HTMLElement() +{ +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLElement.h b/Libraries/LibWeb/DOM/HTMLElement.h new file mode 100644 index 0000000000..56d8329b42 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLElement.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/Element.h> + +namespace Web { + +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; } +}; + +template<> +inline bool is<HTMLElement>(const Node& node) +{ + return node.is_html_element(); +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLFontElement.cpp b/Libraries/LibWeb/DOM/HTMLFontElement.cpp new file mode 100644 index 0000000000..276daece4c --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLFontElement.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/CSS/StyleProperties.h> +#include <LibWeb/CSS/StyleValue.h> +#include <LibWeb/DOM/HTMLFontElement.h> + +namespace Web { + +HTMLFontElement::HTMLFontElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLFontElement::~HTMLFontElement() +{ +} + +void HTMLFontElement::apply_presentational_hints(StyleProperties& style) const +{ + for_each_attribute([&](auto& name, auto& value) { + if (name.equals_ignoring_case("color")) { + auto color = Color::from_string(value); + if (color.has_value()) + style.set_property(CSS::PropertyID::Color, ColorStyleValue::create(color.value())); + } + }); +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLFontElement.h b/Libraries/LibWeb/DOM/HTMLFontElement.h new file mode 100644 index 0000000000..57d0088426 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLFontElement.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLFontElement : public HTMLElement { +public: + HTMLFontElement(Document&, const String& tag_name); + virtual ~HTMLFontElement() override; + + virtual void apply_presentational_hints(StyleProperties&) const override; +}; + +} diff --git a/Libraries/LibWeb/DOM/HTMLFormElement.cpp b/Libraries/LibWeb/DOM/HTMLFormElement.cpp new file mode 100644 index 0000000000..f7092a73d0 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLFormElement.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/StringBuilder.h> +#include <LibWeb/DOM/HTMLFormElement.h> +#include <LibWeb/DOM/HTMLInputElement.h> +#include <LibWeb/Frame.h> +#include <LibWeb/HtmlView.h> + +namespace Web { + +HTMLFormElement::HTMLFormElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLFormElement::~HTMLFormElement() +{ +} + +void HTMLFormElement::submit() +{ + if (action().is_null()) { + dbg() << "Unsupported form action ''"; + return; + } + + if (method().to_lowercase() != "get") { + dbg() << "Unsupported form method '" << method() << "'"; + return; + } + + URL url(document().complete_url(action())); + + struct NameAndValue { + String name; + String value; + }; + + Vector<NameAndValue> parameters; + + for_each_in_subtree_of_type<HTMLInputElement>([&](auto& node) { + auto& input = to<HTMLInputElement>(node); + if (!input.name().is_null()) + parameters.append({ input.name(), input.value() }); + return IterationDecision::Continue; + }); + + StringBuilder builder; + for (size_t i = 0; i < parameters.size(); ++i) { + builder.append(parameters[i].name); + builder.append('='); + builder.append(parameters[i].value); + if (i != parameters.size() - 1) + builder.append('&'); + } + url.set_query(builder.to_string()); + + // FIXME: We shouldn't let the form just do this willy-nilly. + document().frame()->html_view()->load(url); +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLFormElement.h b/Libraries/LibWeb/DOM/HTMLFormElement.h new file mode 100644 index 0000000000..bd99ce5c07 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLFormElement.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLFormElement : public HTMLElement { +public: + HTMLFormElement(Document&, const String& tag_name); + virtual ~HTMLFormElement() override; + + String action() const { return attribute("action"); } + String method() const { return attribute("method"); } + + void submit(); +}; + +template<> +inline bool is<HTMLFormElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "form"; +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLHRElement.cpp b/Libraries/LibWeb/DOM/HTMLHRElement.cpp new file mode 100644 index 0000000000..7d4dbb4a3b --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLHRElement.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/HTMLHRElement.h> + +namespace Web { + +HTMLHRElement::HTMLHRElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLHRElement::~HTMLHRElement() +{ +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLHRElement.h b/Libraries/LibWeb/DOM/HTMLHRElement.h new file mode 100644 index 0000000000..48a57026f9 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLHRElement.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLHRElement : public HTMLElement { +public: + HTMLHRElement(Document&, const String& tag_name); + virtual ~HTMLHRElement() override; +}; + +} diff --git a/Libraries/LibWeb/DOM/HTMLHeadElement.cpp b/Libraries/LibWeb/DOM/HTMLHeadElement.cpp new file mode 100644 index 0000000000..6d828b269e --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLHeadElement.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/HTMLHeadElement.h> + +namespace Web { + +HTMLHeadElement::HTMLHeadElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLHeadElement::~HTMLHeadElement() +{ +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLHeadElement.h b/Libraries/LibWeb/DOM/HTMLHeadElement.h new file mode 100644 index 0000000000..5acb84ea91 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLHeadElement.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLHeadElement : public HTMLElement { +public: + HTMLHeadElement(Document&, const String& tag_name); + virtual ~HTMLHeadElement() override; +}; + +template<> +inline bool is<HTMLHeadElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "head"; +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLHeadingElement.cpp b/Libraries/LibWeb/DOM/HTMLHeadingElement.cpp new file mode 100644 index 0000000000..fab61fda51 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLHeadingElement.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/HTMLHeadingElement.h> + +namespace Web { + +HTMLHeadingElement::HTMLHeadingElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLHeadingElement::~HTMLHeadingElement() +{ +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLHeadingElement.h b/Libraries/LibWeb/DOM/HTMLHeadingElement.h new file mode 100644 index 0000000000..0a8ad9ec4f --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLHeadingElement.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLHeadingElement : public HTMLElement { +public: + HTMLHeadingElement(Document&, const String& tag_name); + virtual ~HTMLHeadingElement() override; +}; + +} diff --git a/Libraries/LibWeb/DOM/HTMLHtmlElement.cpp b/Libraries/LibWeb/DOM/HTMLHtmlElement.cpp new file mode 100644 index 0000000000..af1355cbde --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLHtmlElement.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/HTMLHtmlElement.h> + +namespace Web { + +HTMLHtmlElement::HTMLHtmlElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLHtmlElement::~HTMLHtmlElement() +{ +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLHtmlElement.h b/Libraries/LibWeb/DOM/HTMLHtmlElement.h new file mode 100644 index 0000000000..d926c3459d --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLHtmlElement.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLHtmlElement : public HTMLElement { +public: + HTMLHtmlElement(Document&, const String& tag_name); + virtual ~HTMLHtmlElement() override; +}; + +template<> +inline bool is<HTMLHtmlElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "html"; +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLImageElement.cpp b/Libraries/LibWeb/DOM/HTMLImageElement.cpp new file mode 100644 index 0000000000..f1db4428f9 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLImageElement.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibGfx/Bitmap.h> +#include <LibGfx/ImageDecoder.h> +#include <LibWeb/CSS/StyleResolver.h> +#include <LibWeb/DOM/Document.h> +#include <LibWeb/DOM/HTMLImageElement.h> +#include <LibWeb/Layout/LayoutImage.h> +#include <LibWeb/ResourceLoader.h> + +namespace Web { + +HTMLImageElement::HTMLImageElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLImageElement::~HTMLImageElement() +{ +} + +void HTMLImageElement::parse_attribute(const String& name, const String& value) +{ + if (name.equals_ignoring_case("src")) + load_image(value); +} + +void HTMLImageElement::load_image(const String& src) +{ + URL src_url = document().complete_url(src); + ResourceLoader::the().load(src_url, [this, weak_element = make_weak_ptr()](auto data) { + if (!weak_element) { + dbg() << "HTMLImageElement: Load completed after element destroyed."; + return; + } + if (data.is_null()) { + dbg() << "HTMLImageElement: Failed to load " << this->src(); + return; + } + + m_encoded_data = data; + m_image_decoder = Gfx::ImageDecoder::create(m_encoded_data.data(), m_encoded_data.size()); + document().update_layout(); + }); +} + +int HTMLImageElement::preferred_width() const +{ + bool ok = false; + int width = attribute("width").to_int(ok); + if (ok) + return width; + + if (m_image_decoder) + return m_image_decoder->width(); + + return 0; +} + +int HTMLImageElement::preferred_height() const +{ + bool ok = false; + int height = attribute("height").to_int(ok); + if (ok) + return height; + + if (m_image_decoder) + return m_image_decoder->height(); + + return 0; +} + +RefPtr<LayoutNode> HTMLImageElement::create_layout_node(const StyleProperties* parent_style) const +{ + auto style = document().style_resolver().resolve_style(*this, parent_style); + auto display = style->string_or_fallback(CSS::PropertyID::Display, "inline"); + if (display == "none") + return nullptr; + return adopt(*new LayoutImage(*this, move(style))); +} + +const Gfx::Bitmap* HTMLImageElement::bitmap() const +{ + if (!m_image_decoder) + return nullptr; + return m_image_decoder->bitmap(); +} + +void HTMLImageElement::set_volatile(Badge<LayoutDocument>, bool v) +{ + if (!m_image_decoder) + return; + if (v) { + m_image_decoder->set_volatile(); + return; + } + bool has_image = m_image_decoder->set_nonvolatile(); + if (has_image) + return; + m_image_decoder = Gfx::ImageDecoder::create(m_encoded_data.data(), m_encoded_data.size()); +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLImageElement.h b/Libraries/LibWeb/DOM/HTMLImageElement.h new file mode 100644 index 0000000000..f30f37d3a1 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLImageElement.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <AK/ByteBuffer.h> +#include <LibGfx/Forward.h> +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class LayoutDocument; + +class HTMLImageElement : public HTMLElement { +public: + HTMLImageElement(Document&, const String& tag_name); + virtual ~HTMLImageElement() override; + + virtual void parse_attribute(const String& name, const String& value) override; + + String alt() const { return attribute("alt"); } + String src() const { return attribute("src"); } + int preferred_width() const; + int preferred_height() const; + + const Gfx::Bitmap* bitmap() const; + const Gfx::ImageDecoder* image_decoder() const { return m_image_decoder; } + + void set_volatile(Badge<LayoutDocument>, bool); + +private: + void load_image(const String& src); + + virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; + + RefPtr<Gfx::ImageDecoder> m_image_decoder; + ByteBuffer m_encoded_data; +}; + +} diff --git a/Libraries/LibWeb/DOM/HTMLInputElement.cpp b/Libraries/LibWeb/DOM/HTMLInputElement.cpp new file mode 100644 index 0000000000..bd7194f251 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLInputElement.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibCore/ElapsedTimer.h> +#include <LibGUI/Button.h> +#include <LibGUI/TextBox.h> +#include <LibWeb/DOM/Document.h> +#include <LibWeb/DOM/HTMLFormElement.h> +#include <LibWeb/DOM/HTMLInputElement.h> +#include <LibWeb/Frame.h> +#include <LibWeb/HtmlView.h> +#include <LibWeb/Layout/LayoutWidget.h> + +namespace Web { + +HTMLInputElement::HTMLInputElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLInputElement::~HTMLInputElement() +{ +} + +RefPtr<LayoutNode> HTMLInputElement::create_layout_node(const StyleProperties*) const +{ + ASSERT(document().frame()); + auto& frame = *document().frame(); + ASSERT(frame.html_view()); + auto& html_view = const_cast<HtmlView&>(*frame.html_view()); + + RefPtr<GUI::Widget> widget; + if (type() == "submit") { + auto& button = html_view.add<GUI::Button>(value()); + int text_width = Gfx::Font::default_font().width(value()); + button.set_relative_rect(0, 0, text_width + 20, 20); + button.on_click = [this] { + if (auto* form = first_ancestor_of_type<HTMLFormElement>()) { + // FIXME: Remove this const_cast once we have a non-const first_ancestor_of_type. + const_cast<HTMLFormElement*>(form)->submit(); + } + }; + widget = button; + } else { + auto& text_box = html_view.add<GUI::TextBox>(); + text_box.set_text(value()); + text_box.on_change = [this] { + auto& widget = to<LayoutWidget>(layout_node())->widget(); + const_cast<HTMLInputElement*>(this)->set_attribute("value", static_cast<const GUI::TextBox&>(widget).text()); + }; + int text_width = Gfx::Font::default_font().width(value()); + text_box.set_relative_rect(0, 0, text_width + 20, 20); + widget = text_box; + } + + return adopt(*new LayoutWidget(*this, *widget)); +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLInputElement.h b/Libraries/LibWeb/DOM/HTMLInputElement.h new file mode 100644 index 0000000000..f54d6efa6b --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLInputElement.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLInputElement : public HTMLElement { +public: + HTMLInputElement(Document&, const String& tag_name); + virtual ~HTMLInputElement() override; + + virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; + + String type() const { return attribute("type"); } + String value() const { return attribute("value"); } + String name() const { return attribute("name"); } +}; + +template<> +inline bool is<HTMLInputElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "input"; +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLLinkElement.cpp b/Libraries/LibWeb/DOM/HTMLLinkElement.cpp new file mode 100644 index 0000000000..f2bd9e8aed --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLLinkElement.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/ByteBuffer.h> +#include <AK/URL.h> +#include <LibCore/File.h> +#include <LibWeb/DOM/Document.h> +#include <LibWeb/DOM/HTMLLinkElement.h> +#include <LibWeb/Parser/CSSParser.h> +#include <LibWeb/ResourceLoader.h> + +namespace Web { + +HTMLLinkElement::HTMLLinkElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLLinkElement::~HTMLLinkElement() +{ +} + +void HTMLLinkElement::inserted_into(Node&) +{ + if (rel() == "stylesheet") { + URL url = document().complete_url(href()); + ResourceLoader::the().load(url, [&](auto data) { + if (data.is_null()) { + dbg() << "HTMLLinkElement: Failed to load stylesheet: " << href(); + return; + } + auto sheet = parse_css(data); + if (!sheet) { + dbg() << "HTMLLinkElement: Failed to parse stylesheet: " << href(); + return; + } + document().add_sheet(*sheet); + document().update_style(); + }); + } +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLLinkElement.h b/Libraries/LibWeb/DOM/HTMLLinkElement.h new file mode 100644 index 0000000000..ad005b4e93 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLLinkElement.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLLinkElement final : public HTMLElement { +public: + HTMLLinkElement(Document&, const String& tag_name); + virtual ~HTMLLinkElement() override; + + virtual void inserted_into(Node&) override; + + String rel() const { return attribute("rel"); } + String type() const { return attribute("type"); } + String href() const { return attribute("href"); } +}; + +template<> +inline bool is<HTMLLinkElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "link"; +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLStyleElement.cpp b/Libraries/LibWeb/DOM/HTMLStyleElement.cpp new file mode 100644 index 0000000000..4a48fb3fa1 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLStyleElement.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/StringBuilder.h> +#include <LibWeb/DOM/Document.h> +#include <LibWeb/DOM/HTMLStyleElement.h> +#include <LibWeb/DOM/Text.h> +#include <LibWeb/Parser/CSSParser.h> + +namespace Web { + +HTMLStyleElement::HTMLStyleElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLStyleElement::~HTMLStyleElement() +{ +} + +void HTMLStyleElement::inserted_into(Node& new_parent) +{ + StringBuilder builder; + for_each_child([&](auto& child) { + if (is<Text>(child)) + builder.append(to<Text>(child).text_content()); + }); + m_stylesheet = parse_css(builder.to_string()); + if (m_stylesheet) + document().add_sheet(*m_stylesheet); + HTMLElement::inserted_into(new_parent); +} + +void HTMLStyleElement::removed_from(Node& old_parent) +{ + if (m_stylesheet) { + // FIXME: Remove the sheet from the document + } + return HTMLElement::removed_from(old_parent); +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLStyleElement.h b/Libraries/LibWeb/DOM/HTMLStyleElement.h new file mode 100644 index 0000000000..f4534c9dab --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLStyleElement.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class StyleSheet; + +class HTMLStyleElement : public HTMLElement { +public: + HTMLStyleElement(Document&, const String& tag_name); + virtual ~HTMLStyleElement() override; + + virtual void inserted_into(Node&) override; + virtual void removed_from(Node&) override; + +private: + RefPtr<StyleSheet> m_stylesheet; +}; + +} diff --git a/Libraries/LibWeb/DOM/HTMLTitleElement.cpp b/Libraries/LibWeb/DOM/HTMLTitleElement.cpp new file mode 100644 index 0000000000..c523c8812e --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLTitleElement.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/HTMLTitleElement.h> + +namespace Web { + +HTMLTitleElement::HTMLTitleElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) +{ +} + +HTMLTitleElement::~HTMLTitleElement() +{ +} + +} diff --git a/Libraries/LibWeb/DOM/HTMLTitleElement.h b/Libraries/LibWeb/DOM/HTMLTitleElement.h new file mode 100644 index 0000000000..6485a3d428 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLTitleElement.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/HTMLElement.h> + +namespace Web { + +class HTMLTitleElement : public HTMLElement { +public: + HTMLTitleElement(Document&, const String& tag_name); + virtual ~HTMLTitleElement() override; +}; + +template<> +inline bool is<HTMLTitleElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "title"; +} + +} diff --git a/Libraries/LibWeb/DOM/Node.cpp b/Libraries/LibWeb/DOM/Node.cpp new file mode 100644 index 0000000000..7c2341b0cb --- /dev/null +++ b/Libraries/LibWeb/DOM/Node.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/StringBuilder.h> +#include <LibWeb/CSS/StyleResolver.h> +#include <LibWeb/DOM/Element.h> +#include <LibWeb/DOM/HTMLAnchorElement.h> +#include <LibWeb/DOM/Node.h> +#include <LibWeb/Layout/LayoutBlock.h> +#include <LibWeb/Layout/LayoutDocument.h> +#include <LibWeb/Layout/LayoutInline.h> +#include <LibWeb/Layout/LayoutNode.h> +#include <LibWeb/Layout/LayoutText.h> + +namespace Web { + +Node::Node(Document& document, NodeType type) + : m_document(document) + , m_type(type) +{ +} + +Node::~Node() +{ +} + +const HTMLAnchorElement* Node::enclosing_link_element() const +{ + for (auto* node = this; node; node = node->parent()) { + if (is<HTMLAnchorElement>(*node) && to<HTMLAnchorElement>(*node).has_attribute("href")) + return to<HTMLAnchorElement>(node); + } + return nullptr; +} + +const HTMLElement* Node::enclosing_html_element() const +{ + return first_ancestor_of_type<HTMLElement>(); +} + +String Node::text_content() const +{ + Vector<String> strings; + StringBuilder builder; + for (auto* child = first_child(); child; child = child->next_sibling()) { + auto text = child->text_content(); + if (!text.is_empty()) { + builder.append(child->text_content()); + builder.append(' '); + } + } + if (builder.length() > 1) + builder.trim(1); + return builder.to_string(); +} + +const Element* Node::next_element_sibling() const +{ + for (auto* node = next_sibling(); node; node = node->next_sibling()) { + if (node->is_element()) + return static_cast<const Element*>(node); + } + return nullptr; +} + +const Element* Node::previous_element_sibling() const +{ + for (auto* node = previous_sibling(); node; node = node->previous_sibling()) { + if (node->is_element()) + return static_cast<const Element*>(node); + } + return nullptr; +} + +RefPtr<LayoutNode> Node::create_layout_node(const StyleProperties*) const +{ + return nullptr; +} + +void Node::invalidate_style() +{ + for_each_in_subtree_of_type<Element>([&](auto& element) { + element.set_needs_style_update(true); + return IterationDecision::Continue; + }); + document().schedule_style_update(); +} + +bool Node::is_link() const +{ + auto* enclosing_link = enclosing_link_element(); + if (!enclosing_link) + return false; + return enclosing_link->has_attribute("href"); +} + +} diff --git a/Libraries/LibWeb/DOM/Node.h b/Libraries/LibWeb/DOM/Node.h new file mode 100644 index 0000000000..51a48bdffd --- /dev/null +++ b/Libraries/LibWeb/DOM/Node.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <AK/Badge.h> +#include <AK/RefPtr.h> +#include <AK/String.h> +#include <AK/Vector.h> +#include <LibWeb/TreeNode.h> + +namespace Web { + +enum class NodeType : unsigned { + INVALID = 0, + ELEMENT_NODE = 1, + TEXT_NODE = 3, + COMMENT_NODE = 8, + DOCUMENT_NODE = 9, + DOCUMENT_TYPE_NODE = 10, + DOCUMENT_FRAGMENT_NODE = 11, +}; + +class Document; +class Element; +class HTMLElement; +class HTMLAnchorElement; +class ParentNode; +class LayoutNode; +class StyleResolver; +class StyleProperties; + +class Node : public TreeNode<Node> { +public: + virtual ~Node(); + + 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_document_type() const { return type() == NodeType::DOCUMENT_TYPE_NODE; } + bool is_comment() const { return type() == NodeType::COMMENT_NODE; } + bool is_character_data() const { return type() == NodeType::TEXT_NODE || type() == NodeType::COMMENT_NODE; } + bool is_document_fragment() const { return type() == NodeType::DOCUMENT_FRAGMENT_NODE; } + bool is_parent_node() const { return is_element() || is_document(); } + + virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const; + + virtual String tag_name() const = 0; + + virtual String text_content() const; + + Document& document() { return m_document; } + 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; } + + template<typename T> + const T* first_child_of_type() const; + + template<typename T> + const T* first_ancestor_of_type() const; + + virtual void inserted_into(Node&) {} + virtual void removed_from(Node&) {} + + const LayoutNode* layout_node() const { return m_layout_node; } + LayoutNode* layout_node() { return m_layout_node; } + + void set_layout_node(Badge<LayoutNode>, LayoutNode* layout_node) const { m_layout_node = layout_node; } + + const Element* previous_element_sibling() const; + const Element* next_element_sibling() const; + + virtual bool is_child_allowed(const Node&) const { return true; } + + bool needs_style_update() const { return m_needs_style_update; } + void set_needs_style_update(bool value) { m_needs_style_update = value; } + + void invalidate_style(); + + bool is_link() const; + +protected: + Node(Document&, NodeType); + + Document& m_document; + mutable LayoutNode* m_layout_node { nullptr }; + NodeType m_type { NodeType::INVALID }; + bool m_needs_style_update { false }; +}; + +template<typename T> +inline bool is(const Node&) +{ + return false; +} + +template<typename T> +inline bool is(const Node* node) +{ + return !node || is<T>(*node); +} + +template<> +inline bool is<Node>(const Node&) +{ + return true; +} + +template<> +inline bool is<ParentNode>(const Node& node) +{ + return node.is_parent_node(); +} + +template<typename T> +inline const T& to(const Node& node) +{ + ASSERT(is<T>(node)); + return static_cast<const T&>(node); +} + +template<typename T> +inline T* to(Node* node) +{ + ASSERT(is<T>(node)); + return static_cast<T*>(node); +} + +template<typename T> +inline const T* to(const Node* node) +{ + ASSERT(is<T>(node)); + return static_cast<const T*>(node); +} + +template<typename T> +inline T& to(Node& node) +{ + ASSERT(is<T>(node)); + return static_cast<T&>(node); +} + +template<typename T> +inline const T* Node::first_child_of_type() const +{ + for (auto* child = first_child(); child; child = child->next_sibling()) { + if (is<T>(*child)) + return to<T>(child); + } + return nullptr; +} + +template<typename T> +inline const T* Node::first_ancestor_of_type() const +{ + for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { + if (is<T>(*ancestor)) + return to<T>(ancestor); + } + return nullptr; +} + +} diff --git a/Libraries/LibWeb/DOM/ParentNode.cpp b/Libraries/LibWeb/DOM/ParentNode.cpp new file mode 100644 index 0000000000..3bc86e480d --- /dev/null +++ b/Libraries/LibWeb/DOM/ParentNode.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/ParentNode.h> + diff --git a/Libraries/LibWeb/DOM/ParentNode.h b/Libraries/LibWeb/DOM/ParentNode.h new file mode 100644 index 0000000000..e8e826c959 --- /dev/null +++ b/Libraries/LibWeb/DOM/ParentNode.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibWeb/DOM/Node.h> + +namespace Web { + +class ParentNode : public Node { +public: + template<typename F> void for_each_child(F) const; + template<typename F> void for_each_child(F); + +protected: + explicit ParentNode(Document& document, NodeType type) + : Node(document, type) + { + } +}; + +template<typename Callback> +inline void ParentNode::for_each_child(Callback callback) const +{ + for (auto* node = first_child(); node; node = node->next_sibling()) + callback(*node); +} + +template<typename Callback> +inline void ParentNode::for_each_child(Callback callback) +{ + for (auto* node = first_child(); node; node = node->next_sibling()) + callback(*node); +} + +} diff --git a/Libraries/LibWeb/DOM/Text.cpp b/Libraries/LibWeb/DOM/Text.cpp new file mode 100644 index 0000000000..65c2e36550 --- /dev/null +++ b/Libraries/LibWeb/DOM/Text.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/DOM/Text.h> +#include <LibWeb/Layout/LayoutText.h> + +namespace Web { + +Text::Text(Document& document, const String& data) + : CharacterData(document, NodeType::TEXT_NODE, data) +{ +} + +Text::~Text() +{ +} + +RefPtr<LayoutNode> Text::create_layout_node(const StyleProperties*) const +{ + return adopt(*new LayoutText(*this)); +} + +} diff --git a/Libraries/LibWeb/DOM/Text.h b/Libraries/LibWeb/DOM/Text.h new file mode 100644 index 0000000000..5a482ed6a0 --- /dev/null +++ b/Libraries/LibWeb/DOM/Text.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <AK/String.h> +#include <LibWeb/DOM/CharacterData.h> + +namespace Web { + +class Text final : public CharacterData { +public: + explicit Text(Document&, const String&); + virtual ~Text() override; + + virtual String tag_name() const override { return "#text"; } + +private: + virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; +}; + +template<> +inline bool is<Text>(const Node& node) +{ + return node.is_text(); +} + +} |