Browse Source

LibWeb: Bring html element height calculation closer to the spec

Previously we always set the height of the HTML element equal to the
viewport height but now this will only happen in quirks mode as it is
intended. Otherwise the html element height will be computed as auto.
Aliaksandr Kalenik 1 year ago
parent
commit
a482166087

+ 9 - 0
Tests/LibWeb/Layout/expected/block-and-inline/html-element-height-quirks-mode-off.txt

@@ -0,0 +1,9 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x136 [BFC] children: not-inline
+    BlockContainer <body> at (18,18) content-size 764x100 children: not-inline
+      BlockContainer <div.box> at (18,18) content-size 100x100 children: not-inline
+
+ViewportPaintable (Viewport<#document>) [0,0 800x600]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x136]
+    PaintableWithLines (BlockContainer<BODY>) [8,8 784x120]
+      PaintableWithLines (BlockContainer<DIV>.box) [18,18 100x100]

+ 9 - 0
Tests/LibWeb/Layout/expected/block-and-inline/html-element-height-quirks-mode-on.txt

@@ -0,0 +1,9 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
+    BlockContainer <body> at (18,18) content-size 764x300 children: not-inline
+      BlockContainer <div.box> at (18,18) content-size 100x100 children: not-inline
+
+ViewportPaintable (Viewport<#document>) [0,0 800x600]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
+    PaintableWithLines (BlockContainer<BODY>) [8,8 784x320]
+      PaintableWithLines (BlockContainer<DIV>.box) [18,18 100x100]

+ 5 - 5
Tests/LibWeb/Layout/expected/viewport-overflow-propagation-2.txt

@@ -1,10 +1,10 @@
 Viewport <#document> at (0,0) content-size 800x600 [BFC] children: not-inline
-  BlockContainer <html> at (0,0) content-size 800x616 [BFC] children: not-inline
-    BlockContainer <body> at (8,8) content-size 784x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x2016 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x2000 children: not-inline
       BlockContainer <div.long> at (8,8) content-size 784x2000 children: inline
         TextNode <#text>
 
-ViewportPaintable (Viewport<#document>) [0,0 800x600] overflow: [0,0 800x2008]
-  PaintableWithLines (BlockContainer<HTML>) [0,0 800x616] overflow: [0,0 800x2008]
-    PaintableWithLines (BlockContainer<BODY>) [8,8 784x600] overflow: [8,8 784x2000]
+ViewportPaintable (Viewport<#document>) [0,0 800x600] overflow: [0,0 800x2016]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x2016]
+    PaintableWithLines (BlockContainer<BODY>) [8,8 784x2000]
       PaintableWithLines (BlockContainer<DIV>.long) [8,8 784x2000]

+ 15 - 0
Tests/LibWeb/Layout/input/block-and-inline/html-element-height-quirks-mode-off.html

@@ -0,0 +1,15 @@
+<!doctype html><style>
+    * {
+        outline: 1px solid black !important;
+    }
+    body {
+        border: 10px solid purple;
+        display: block;
+        height: 50%;
+    }
+    .box {
+        background-color: palevioletred;
+        height: 100px;
+        width: 100px;
+    }
+</style><body><div class="box"></div>

+ 15 - 0
Tests/LibWeb/Layout/input/block-and-inline/html-element-height-quirks-mode-on.html

@@ -0,0 +1,15 @@
+<style>
+    * {
+        outline: 1px solid black !important;
+    }
+    body {
+        border: 10px solid purple;
+        display: block;
+        height: 50%;
+    }
+    .box {
+        background-color: palevioletred;
+        height: 100px;
+        width: 100px;
+    }
+</style><body><div class="box"></div>

+ 0 - 1
Userland/Libraries/LibWeb/DOM/Document.cpp

@@ -996,7 +996,6 @@ void Document::update_layout()
             VERIFY(document_element->layout_node());
             auto& icb_state = layout_state.get_mutable(verify_cast<Layout::NodeWithStyleAndBoxModelMetrics>(*document_element->layout_node()));
             icb_state.set_content_width(viewport_rect.width());
-            icb_state.set_content_height(viewport_rect.height());
         }
 
         root_formatting_context.run(

+ 10 - 2
Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp

@@ -478,7 +478,7 @@ void BlockFormattingContext::compute_height(Box const& box, AvailableSpace const
         auto margins = box_state.margin_top + box_state.margin_bottom;
 
         // 2. Let size be the size of the initial containing block in the block flow direction minus margins.
-        auto size = box_state.content_height() - margins;
+        auto size = m_state.get(*box.containing_block()).content_height() - margins;
 
         // 3. Return the bigger value of size and the normal border box size the element would have
         //    according to the CSS specification.
@@ -630,7 +630,13 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain
 
     auto const y = m_y_offset_of_current_block_container.value();
 
-    if (box_state.has_definite_height()) {
+    auto box_is_html_element_in_quirks_mode = box.document().in_quirks_mode()
+        && box.dom_node()
+        && box.dom_node()->is_html_html_element()
+        && box.computed_values().height().is_auto();
+
+    // NOTE: In quirks mode, the html element's height matches the viewport so it can be treated as definite
+    if (box_state.has_definite_height() || box_is_html_element_in_quirks_mode) {
         compute_height(box, available_space);
     }
 
@@ -881,6 +887,8 @@ void BlockFormattingContext::layout_viewport(LayoutMode layout_mode, AvailableSp
     //       and we call directly into the SVG layout code from here.
     if (root().first_child() && root().first_child()->is_svg_svg_box()) {
         auto const& svg_root = verify_cast<SVGSVGBox>(*root().first_child());
+        auto content_height = m_state.get(*svg_root.containing_block()).content_height();
+        m_state.get_mutable(svg_root).set_content_height(content_height);
         auto svg_formatting_context = create_independent_formatting_context_if_needed(m_state, svg_root);
         svg_formatting_context->run(svg_root, layout_mode, available_space);
     } else {