summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Base/home/anon/www/blink.html5
-rw-r--r--Base/home/anon/www/welcome.html1
-rw-r--r--Libraries/LibHTML/CSS/Default.css4
-rw-r--r--Libraries/LibHTML/DOM/HTMLBlinkElement.cpp27
-rw-r--r--Libraries/LibHTML/DOM/HTMLBlinkElement.h16
-rw-r--r--Libraries/LibHTML/Frame.cpp7
-rw-r--r--Libraries/LibHTML/Frame.h5
-rw-r--r--Libraries/LibHTML/HtmlView.cpp6
-rw-r--r--Libraries/LibHTML/Layout/LayoutBlock.cpp3
-rw-r--r--Libraries/LibHTML/Layout/LayoutBlock.h12
-rw-r--r--Libraries/LibHTML/Layout/LayoutImage.cpp3
-rw-r--r--Libraries/LibHTML/Layout/LayoutNode.cpp22
-rw-r--r--Libraries/LibHTML/Layout/LayoutNode.h20
-rw-r--r--Libraries/LibHTML/Layout/LineBoxFragment.cpp5
-rw-r--r--Libraries/LibHTML/Makefile.shared1
-rw-r--r--Libraries/LibHTML/Parser/HTMLParser.cpp3
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"