mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-04 23:19:27 +00:00
LibHTML: Implement the <br> element for line breaking
The <br> element will produce a special LayoutBreak node in the layout tree, which forces a break in the line layout whenever encountered. This patch also makes LayoutBlock use the current line-height as the minimum effective height for each line box. This ensures that having multiple <br> elements in a row doesn't create 0-height line boxes.
This commit is contained in:
parent
bf79b198f6
commit
6242459c0f
14
Base/home/anon/www/br.html
Normal file
14
Base/home/anon/www/br.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
<html>
|
||||
<head><title>BR element test</title></head>
|
||||
<body>
|
||||
Hello world<br>
|
||||
This is<br><br>
|
||||
a test page<br>
|
||||
for<br>
|
||||
the<br>
|
||||
<br>
|
||||
BR element!
|
||||
<br><br><br><br>
|
||||
Does it work?
|
||||
</body>
|
||||
</html>
|
|
@ -24,6 +24,7 @@ h1 {
|
|||
<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="br.html">br element</a></li>
|
||||
<li><a href="http://www.serenityos.org/">www.serenityos.org</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <LibHTML/DOM/ElementFactory.h>
|
||||
#include <LibHTML/DOM/HTMLAnchorElement.h>
|
||||
#include <LibHTML/DOM/HTMLBRElement.h>
|
||||
#include <LibHTML/DOM/HTMLBlinkElement.h>
|
||||
#include <LibHTML/DOM/HTMLBodyElement.h>
|
||||
#include <LibHTML/DOM/HTMLFontElement.h>
|
||||
|
@ -37,6 +38,8 @@ NonnullRefPtr<Element> create_element(Document& document, const String& tag_name
|
|||
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 == "br")
|
||||
return adopt(*new HTMLBRElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "h1"
|
||||
|| lowercase_tag_name == "h2"
|
||||
|| lowercase_tag_name == "h3"
|
||||
|
|
16
Libraries/LibHTML/DOM/HTMLBRElement.cpp
Normal file
16
Libraries/LibHTML/DOM/HTMLBRElement.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include <LibHTML/DOM/HTMLBRElement.h>
|
||||
#include <LibHTML/Layout/LayoutBreak.h>
|
||||
|
||||
HTMLBRElement::HTMLBRElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLBRElement::~HTMLBRElement()
|
||||
{
|
||||
}
|
||||
|
||||
RefPtr<LayoutNode> HTMLBRElement::create_layout_node(const StyleResolver&, const StyleProperties*) const
|
||||
{
|
||||
return adopt(*new LayoutBreak(*this));
|
||||
}
|
17
Libraries/LibHTML/DOM/HTMLBRElement.h
Normal file
17
Libraries/LibHTML/DOM/HTMLBRElement.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibHTML/DOM/HTMLElement.h>
|
||||
|
||||
class HTMLBRElement final : public HTMLElement {
|
||||
public:
|
||||
HTMLBRElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLBRElement() override;
|
||||
|
||||
virtual RefPtr<LayoutNode> create_layout_node(const StyleResolver&, 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";
|
||||
}
|
|
@ -54,10 +54,12 @@ void LayoutBlock::layout_inline_children()
|
|||
child.split_into_lines(*this);
|
||||
});
|
||||
|
||||
int min_line_height = style().line_height();
|
||||
|
||||
int content_height = 0;
|
||||
|
||||
for (auto& line_box : m_line_boxes) {
|
||||
int max_height = 0;
|
||||
int max_height = min_line_height;
|
||||
for (auto& fragment : line_box.fragments()) {
|
||||
max_height = max(max_height, fragment.rect().height());
|
||||
}
|
||||
|
|
17
Libraries/LibHTML/Layout/LayoutBreak.cpp
Normal file
17
Libraries/LibHTML/Layout/LayoutBreak.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include <LibHTML/Layout/LayoutBlock.h>
|
||||
#include <LibHTML/Layout/LayoutBreak.h>
|
||||
|
||||
LayoutBreak::LayoutBreak(const HTMLBRElement& element)
|
||||
: LayoutNode(&element)
|
||||
{
|
||||
set_inline(true);
|
||||
}
|
||||
|
||||
LayoutBreak::~LayoutBreak()
|
||||
{
|
||||
}
|
||||
|
||||
void LayoutBreak::split_into_lines(LayoutBlock& block)
|
||||
{
|
||||
block.line_boxes().append(LineBox());
|
||||
}
|
16
Libraries/LibHTML/Layout/LayoutBreak.h
Normal file
16
Libraries/LibHTML/Layout/LayoutBreak.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibHTML/DOM/HTMLBRElement.h>
|
||||
#include <LibHTML/Layout/LayoutNode.h>
|
||||
|
||||
class LayoutBreak final : public LayoutNode {
|
||||
public:
|
||||
explicit LayoutBreak(const HTMLBRElement&);
|
||||
virtual ~LayoutBreak() override;
|
||||
|
||||
const HTMLBRElement& node() const { return to<HTMLBRElement>(*LayoutNode::node()); }
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "LayoutBreak"; }
|
||||
virtual void split_into_lines(LayoutBlock&) override;
|
||||
};
|
|
@ -15,6 +15,7 @@ LIBHTML_OBJS = \
|
|||
DOM/HTMLImageElement.o \
|
||||
DOM/HTMLLinkElement.o \
|
||||
DOM/HTMLBlinkElement.o \
|
||||
DOM/HTMLBRElement.o \
|
||||
DOM/Document.o \
|
||||
DOM/Text.o \
|
||||
DOM/DocumentType.o \
|
||||
|
@ -39,6 +40,7 @@ LIBHTML_OBJS = \
|
|||
Layout/LayoutImage.o \
|
||||
Layout/LayoutListItem.o \
|
||||
Layout/LayoutListItemMarker.o \
|
||||
Layout/LayoutBreak.o \
|
||||
Layout/BoxModelMetrics.o \
|
||||
Layout/LineBox.o \
|
||||
Layout/LineBoxFragment.o \
|
||||
|
|
Loading…
Reference in a new issue