Prechádzať zdrojové kódy

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).
Mathis Wiehl 2 rokov pred
rodič
commit
9927dab993

+ 8 - 0
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

+ 15 - 0
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>

+ 2 - 1
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 };
 };
 
 }

+ 4 - 1
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;
     }