summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathis Wiehl <mail@mathiswiehl.de>2023-03-15 21:11:38 +0100
committerSam Atkins <atkinssj@gmail.com>2023-03-16 08:40:29 +0000
commit9927dab9939f8c5b0fec668a1881baf612d97773 (patch)
tree6b448b91548179f659fe1bb8b1f40c107eca1200
parent2fe4be40afbeee0c99c4a04054cb01f309e6b735 (diff)
downloadserenity-9927dab9939f8c5b0fec668a1881baf612d97773.zip
LibWeb: Don't drop single <br/> lines
Previously, when having inline contexts consisting of just a `<br/>` tag, we would not create a line box. Ensure that there is always a line box when a line is explicitly being broken and also ensure it won't be trimmed due to being empty. This will a fix a number of sites that use `<br>` tags for layouts between block elements (even though the spec says they shouldn't).
-rw-r--r--Tests/LibWeb/Layout/expected/single-br-inline-layout.txt8
-rw-r--r--Tests/LibWeb/Layout/input/single-br-inline-layout.html15
-rw-r--r--Userland/Libraries/LibWeb/Layout/LineBox.h3
-rw-r--r--Userland/Libraries/LibWeb/Layout/LineBuilder.cpp5
4 files changed, 29 insertions, 2 deletions
diff --git a/Tests/LibWeb/Layout/expected/single-br-inline-layout.txt b/Tests/LibWeb/Layout/expected/single-br-inline-layout.txt
new file mode 100644
index 0000000000..9e37d696c6
--- /dev/null
+++ b/Tests/LibWeb/Layout/expected/single-br-inline-layout.txt
@@ -0,0 +1,8 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+ BlockContainer <html> at (0,0) content-size 800x37.46875 children: not-inline
+ BlockContainer <body> at (8,8) content-size 784x21.46875 children: not-inline
+ BlockContainer <div#begin> at (8,8) content-size 784x2 children: not-inline
+ BlockContainer <(anonymous)> at (8,10) content-size 784x17.46875 children: inline
+ line 0 width: 0, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+ BreakNode <br>
+ BlockContainer <div#end> at (8,27.46875) content-size 784x2 children: not-inline
diff --git a/Tests/LibWeb/Layout/input/single-br-inline-layout.html b/Tests/LibWeb/Layout/input/single-br-inline-layout.html
new file mode 100644
index 0000000000..709113949c
--- /dev/null
+++ b/Tests/LibWeb/Layout/input/single-br-inline-layout.html
@@ -0,0 +1,15 @@
+<style>
+ body {
+ font-family: 'SerenitySans';
+ }
+
+ #begin {
+ height: 2px;
+ background-color: blue;
+ }
+
+ #end {
+ height: 2px;
+ background-color: red;
+ }
+</style><div id="begin"></div><br><div id="end"></div> \ No newline at end of file
diff --git a/Userland/Libraries/LibWeb/Layout/LineBox.h b/Userland/Libraries/LibWeb/Layout/LineBox.h
index a333943b63..8bfd6a3f91 100644
--- a/Userland/Libraries/LibWeb/Layout/LineBox.h
+++ b/Userland/Libraries/LibWeb/Layout/LineBox.h
@@ -28,7 +28,7 @@ public:
void trim_trailing_whitespace();
bool is_empty_or_ends_in_whitespace() const;
- bool is_empty() const { return m_fragments.is_empty(); }
+ bool is_empty() const { return m_fragments.is_empty() && !m_has_break; }
private:
friend class BlockContainer;
@@ -40,6 +40,7 @@ private:
CSSPixels m_height { 0 };
CSSPixels m_bottom { 0 };
CSSPixels m_baseline { 0 };
+ bool m_has_break { false };
};
}
diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp
index b09adc0fe7..f02278b1a9 100644
--- a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp
+++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp
@@ -26,6 +26,9 @@ LineBuilder::~LineBuilder()
void LineBuilder::break_line(Optional<CSSPixels> next_item_width)
{
+ auto last_line_box = ensure_last_line_box();
+ last_line_box.m_has_break = true;
+
update_last_line();
size_t break_count = 0;
bool floats_intrude_at_current_y = false;
@@ -305,7 +308,7 @@ void LineBuilder::remove_last_line_if_empty()
{
// If there's an empty line box at the bottom, just remove it instead of giving it height.
auto& line_boxes = m_containing_block_state.line_boxes;
- if (!line_boxes.is_empty() && line_boxes.last().fragments().is_empty()) {
+ if (!line_boxes.is_empty() && line_boxes.last().is_empty()) {
line_boxes.take_last();
m_last_line_needs_update = false;
}