diff options
-rw-r--r-- | Base/home/anon/www/blink.html | 5 | ||||
-rw-r--r-- | Base/home/anon/www/welcome.html | 1 | ||||
-rw-r--r-- | Libraries/LibHTML/CSS/Default.css | 4 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/HTMLBlinkElement.cpp | 27 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/HTMLBlinkElement.h | 16 | ||||
-rw-r--r-- | Libraries/LibHTML/Frame.cpp | 7 | ||||
-rw-r--r-- | Libraries/LibHTML/Frame.h | 5 | ||||
-rw-r--r-- | Libraries/LibHTML/HtmlView.cpp | 6 | ||||
-rw-r--r-- | Libraries/LibHTML/Layout/LayoutBlock.cpp | 3 | ||||
-rw-r--r-- | Libraries/LibHTML/Layout/LayoutBlock.h | 12 | ||||
-rw-r--r-- | Libraries/LibHTML/Layout/LayoutImage.cpp | 3 | ||||
-rw-r--r-- | Libraries/LibHTML/Layout/LayoutNode.cpp | 22 | ||||
-rw-r--r-- | Libraries/LibHTML/Layout/LayoutNode.h | 20 | ||||
-rw-r--r-- | Libraries/LibHTML/Layout/LineBoxFragment.cpp | 5 | ||||
-rw-r--r-- | Libraries/LibHTML/Makefile.shared | 1 | ||||
-rw-r--r-- | Libraries/LibHTML/Parser/HTMLParser.cpp | 3 |
16 files changed, 140 insertions, 0 deletions
diff --git a/Base/home/anon/www/blink.html b/Base/home/anon/www/blink.html new file mode 100644 index 0000000000..529923b485 --- /dev/null +++ b/Base/home/anon/www/blink.html @@ -0,0 +1,5 @@ +<html> + <body> + <blink>Hello friends!</blink> + </body> +</html> diff --git a/Base/home/anon/www/welcome.html b/Base/home/anon/www/welcome.html index ce4ccd86a6..8a1524bc29 100644 --- a/Base/home/anon/www/welcome.html +++ b/Base/home/anon/www/welcome.html @@ -23,6 +23,7 @@ h1 { <li><a href="images.html">images</a></li> <li><a href="selectors.html">selectors</a></li> <li><a href="link.html">link element</a></li> + <li><a href="blink.html">blink element</a></li> <li><a href="http://www.serenityos.org/">www.serenityos.org</a></li> </ul> </body> diff --git a/Libraries/LibHTML/CSS/Default.css b/Libraries/LibHTML/CSS/Default.css index af2082129a..103544b5b9 100644 --- a/Libraries/LibHTML/CSS/Default.css +++ b/Libraries/LibHTML/CSS/Default.css @@ -97,3 +97,7 @@ hr { border-color: #888888; border-style: inset; } + +blink { + display: inline; +} diff --git a/Libraries/LibHTML/DOM/HTMLBlinkElement.cpp b/Libraries/LibHTML/DOM/HTMLBlinkElement.cpp new file mode 100644 index 0000000000..258946e4a7 --- /dev/null +++ b/Libraries/LibHTML/DOM/HTMLBlinkElement.cpp @@ -0,0 +1,27 @@ +#include <LibCore/CTimer.h> +#include <LibHTML/CSS/StyleProperties.h> +#include <LibHTML/CSS/StyleValue.h> +#include <LibHTML/DOM/HTMLBlinkElement.h> +#include <LibHTML/Layout/LayoutNode.h> + +HTMLBlinkElement::HTMLBlinkElement(Document& document, const String& tag_name) + : HTMLElement(document, tag_name) + , m_timer(CTimer::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/LibHTML/DOM/HTMLBlinkElement.h b/Libraries/LibHTML/DOM/HTMLBlinkElement.h new file mode 100644 index 0000000000..ca7c74160b --- /dev/null +++ b/Libraries/LibHTML/DOM/HTMLBlinkElement.h @@ -0,0 +1,16 @@ +#pragma once + +#include <LibHTML/DOM/HTMLElement.h> + +class CTimer; + +class HTMLBlinkElement : public HTMLElement { +public: + HTMLBlinkElement(Document&, const String& tag_name); + virtual ~HTMLBlinkElement() override; + +private: + void blink(); + + NonnullRefPtr<CTimer> m_timer; +}; diff --git a/Libraries/LibHTML/Frame.cpp b/Libraries/LibHTML/Frame.cpp index ee2ae46a79..f635528b70 100644 --- a/Libraries/LibHTML/Frame.cpp +++ b/Libraries/LibHTML/Frame.cpp @@ -29,3 +29,10 @@ void Frame::set_size(const Size& size) return; m_size = size; } + +void Frame::set_needs_display(const Rect& rect) +{ + if (!on_set_needs_display) + return; + on_set_needs_display(rect); +} diff --git a/Libraries/LibHTML/Frame.h b/Libraries/LibHTML/Frame.h index 4915ebe0f7..b1b4ab7dea 100644 --- a/Libraries/LibHTML/Frame.h +++ b/Libraries/LibHTML/Frame.h @@ -1,8 +1,10 @@ #pragma once +#include <AK/Function.h> #include <AK/Noncopyable.h> #include <AK/RefPtr.h> #include <AK/Weakable.h> +#include <LibDraw/Rect.h> #include <LibDraw/Size.h> #include <LibHTML/TreeNode.h> @@ -23,6 +25,9 @@ public: const Size& size() const { return m_size; } void set_size(const Size&); + void set_needs_display(const Rect&); + Function<void(const Rect&)> on_set_needs_display; + private: Frame(); diff --git a/Libraries/LibHTML/HtmlView.cpp b/Libraries/LibHTML/HtmlView.cpp index b909fbb2bd..a1c0c8162c 100644 --- a/Libraries/LibHTML/HtmlView.cpp +++ b/Libraries/LibHTML/HtmlView.cpp @@ -17,6 +17,12 @@ HtmlView::HtmlView(GWidget* parent) : GScrollableWidget(parent) , m_main_frame(Frame::create()) { + main_frame().on_set_needs_display = [this](auto& content_rect) { + Rect adjusted_rect = content_rect; + adjusted_rect.set_location(to_widget_position(content_rect.location())); + update(adjusted_rect); + }; + set_frame_shape(FrameShape::Container); set_frame_shadow(FrameShadow::Sunken); set_frame_thickness(2); diff --git a/Libraries/LibHTML/Layout/LayoutBlock.cpp b/Libraries/LibHTML/Layout/LayoutBlock.cpp index 3f3e95c625..dca51eebca 100644 --- a/Libraries/LibHTML/Layout/LayoutBlock.cpp +++ b/Libraries/LibHTML/Layout/LayoutBlock.cpp @@ -194,6 +194,9 @@ void LayoutBlock::compute_height() void LayoutBlock::render(RenderingContext& context) { + if (!is_visible()) + return; + LayoutNode::render(context); // FIXME: position this properly diff --git a/Libraries/LibHTML/Layout/LayoutBlock.h b/Libraries/LibHTML/Layout/LayoutBlock.h index 01198bdb7c..a9d242effd 100644 --- a/Libraries/LibHTML/Layout/LayoutBlock.h +++ b/Libraries/LibHTML/Layout/LayoutBlock.h @@ -38,3 +38,15 @@ private: Vector<LineBox> m_line_boxes; }; + +template<typename Callback> +void LayoutNode::for_each_fragment_of_this(Callback callback) +{ + auto& block = *containing_block(); + for (auto& line_box : block.line_boxes()) { + for (auto& fragment : line_box.fragments()) { + if (callback(fragment) == IterationDecision::Break) + return; + } + } +} diff --git a/Libraries/LibHTML/Layout/LayoutImage.cpp b/Libraries/LibHTML/Layout/LayoutImage.cpp index 82a111c04a..72a03f03cb 100644 --- a/Libraries/LibHTML/Layout/LayoutImage.cpp +++ b/Libraries/LibHTML/Layout/LayoutImage.cpp @@ -34,6 +34,9 @@ void LayoutImage::layout() void LayoutImage::render(RenderingContext& context) { + if (!is_visible()) + return; + if (renders_as_alt_text()) { context.painter().set_font(Font::default_font()); StylePainter::paint_frame(context.painter(), rect(), FrameShape::Container, FrameShadow::Sunken, 2); diff --git a/Libraries/LibHTML/Layout/LayoutNode.cpp b/Libraries/LibHTML/Layout/LayoutNode.cpp index 3527c3dbd1..031d8a454c 100644 --- a/Libraries/LibHTML/Layout/LayoutNode.cpp +++ b/Libraries/LibHTML/Layout/LayoutNode.cpp @@ -1,6 +1,7 @@ #include <LibGUI/GPainter.h> #include <LibHTML/DOM/Document.h> #include <LibHTML/DOM/Element.h> +#include <LibHTML/Frame.h> #include <LibHTML/Layout/LayoutBlock.h> #include <LibHTML/Layout/LayoutNode.h> @@ -38,6 +39,9 @@ const LayoutBlock* LayoutNode::containing_block() const void LayoutNode::render(RenderingContext& context) { + if (!is_visible()) + return; + #ifdef DRAW_BOXES_AROUND_LAYOUT_NODES context.painter().draw_rect(m_rect, Color::Blue); #endif @@ -127,3 +131,21 @@ void LayoutNode::split_into_lines(LayoutBlock& container) } }); } + +void LayoutNode::set_needs_display() +{ + auto* frame = document().frame(); + ASSERT(frame); + + if (!is_inline()) { + const_cast<Frame*>(frame)->set_needs_display(rect()); + return; + } + + for_each_fragment_of_this([&](auto& fragment) { + if (&fragment.layout_node() == this || is_ancestor_of(fragment.layout_node())) { + const_cast<Frame*>(frame)->set_needs_display(fragment.rect()); + } + return IterationDecision::Continue; + }); +} diff --git a/Libraries/LibHTML/Layout/LayoutNode.h b/Libraries/LibHTML/Layout/LayoutNode.h index c75798b800..78b77dd850 100644 --- a/Libraries/LibHTML/Layout/LayoutNode.h +++ b/Libraries/LibHTML/Layout/LayoutNode.h @@ -76,6 +76,16 @@ public: virtual void split_into_lines(LayoutBlock& container); + bool is_visible() const { return m_visible; } + void set_visible(bool visible) { m_visible = visible; } + + void set_needs_display(); + + bool is_ancestor_of(const LayoutNode&) const; + + template<typename Callback> + void for_each_fragment_of_this(Callback); + protected: explicit LayoutNode(const Node*); @@ -88,6 +98,7 @@ private: Rect m_rect; bool m_inline { false }; bool m_has_style { false }; + bool m_visible { true }; }; class LayoutNodeWithStyle : public LayoutNode { @@ -119,3 +130,12 @@ inline const LayoutNodeWithStyle* LayoutNode::parent() const { return static_cast<const LayoutNodeWithStyle*>(TreeNode<LayoutNode>::parent()); } + +inline bool LayoutNode::is_ancestor_of(const LayoutNode& other) const +{ + for (auto* ancestor = other.parent(); ancestor; ancestor = ancestor->parent()) { + if (ancestor == this) + return true; + } + return false; +} diff --git a/Libraries/LibHTML/Layout/LineBoxFragment.cpp b/Libraries/LibHTML/Layout/LineBoxFragment.cpp index 1ff6755d6d..4f64c93481 100644 --- a/Libraries/LibHTML/Layout/LineBoxFragment.cpp +++ b/Libraries/LibHTML/Layout/LineBoxFragment.cpp @@ -5,6 +5,11 @@ void LineBoxFragment::render(RenderingContext& context) { + for (auto* ancestor = layout_node().parent(); ancestor; ancestor = ancestor->parent()) { + if (!ancestor->is_visible()) + return; + } + if (layout_node().is_text()) { auto& layout_text = static_cast<const LayoutText&>(layout_node()); layout_text.render_fragment(context, *this); diff --git a/Libraries/LibHTML/Makefile.shared b/Libraries/LibHTML/Makefile.shared index e4b772c1cf..ee4ee44011 100644 --- a/Libraries/LibHTML/Makefile.shared +++ b/Libraries/LibHTML/Makefile.shared @@ -14,6 +14,7 @@ LIBHTML_OBJS = \ DOM/HTMLFontElement.o \ DOM/HTMLImageElement.o \ DOM/HTMLLinkElement.o \ + DOM/HTMLBlinkElement.o \ DOM/Document.o \ DOM/Text.o \ DOM/DocumentType.o \ diff --git a/Libraries/LibHTML/Parser/HTMLParser.cpp b/Libraries/LibHTML/Parser/HTMLParser.cpp index 22618796c3..06ae02e88d 100644 --- a/Libraries/LibHTML/Parser/HTMLParser.cpp +++ b/Libraries/LibHTML/Parser/HTMLParser.cpp @@ -4,6 +4,7 @@ #include <LibHTML/DOM/DocumentType.h> #include <LibHTML/DOM/Element.h> #include <LibHTML/DOM/HTMLAnchorElement.h> +#include <LibHTML/DOM/HTMLBlinkElement.h> #include <LibHTML/DOM/HTMLBodyElement.h> #include <LibHTML/DOM/HTMLFontElement.h> #include <LibHTML/DOM/HTMLHRElement.h> @@ -42,6 +43,8 @@ static NonnullRefPtr<Element> create_element(Document& document, const String& t return adopt(*new HTMLLinkElement(document, tag_name)); if (lowercase_tag_name == "img") return adopt(*new HTMLImageElement(document, tag_name)); + if (lowercase_tag_name == "blink") + return adopt(*new HTMLBlinkElement(document, tag_name)); if (lowercase_tag_name == "h1" || lowercase_tag_name == "h2" || lowercase_tag_name == "h3" |