mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:47:44 +00:00
LibHTML: Implement the <blink> element
Just in time for Serenity's 1st birthday, here is the <blink> element! This patch adds a bunch of different mechanisms to enable partial repaints of the layout tree (LayoutNode::set_needs_display())) It also adds LayoutNode::is_visible(), which can be toggled to prevent a LayoutNode from rendering anything (it still takes up space though.)
This commit is contained in:
parent
33043941f9
commit
fdbad6284c
16 changed files with 140 additions and 0 deletions
|
@ -194,6 +194,9 @@ void LayoutBlock::compute_height()
|
|||
|
||||
void LayoutBlock::render(RenderingContext& context)
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
|
||||
LayoutNode::render(context);
|
||||
|
||||
// FIXME: position this properly
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue