mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:42:44 +00:00 
			
		
		
		
	LibWeb: Handle overlapping floating box and left margin
Allow the left margin of a box which creates a block formatting context to overlap with left floating boxes which are siblings in the document tree. Fixes #20233 and the comment layout on https://lobste.rs.
This commit is contained in:
		
							parent
							
								
									34c702e6e8
								
							
						
					
					
						commit
						6a17a30e2e
					
				
					 6 changed files with 100 additions and 2 deletions
				
			
		|  | @ -8,12 +8,16 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline | |||
|       BlockContainer <div.ab> at (108,8) content-size 684x17.46875 children: not-inline | ||||
|         BlockContainer <(anonymous)> at (108,8) content-size 684x0 children: inline | ||||
|           TextNode <#text> | ||||
|         BlockContainer <div> at (108,8) content-size 684x0 children: inline | ||||
|           TextNode <#text> | ||||
|           BlockContainer <div.a> at (108,8) content-size 14.265625x17.46875 floating [BFC] children: inline | ||||
|             line 0 width: 14.265625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 | ||||
|               frag 0 from TextNode start: 0, length: 1, rect: [108,8 14.265625x17.46875] | ||||
|                 "A" | ||||
|             TextNode <#text> | ||||
|           TextNode <#text> | ||||
|         BlockContainer <(anonymous)> at (108,8) content-size 684x0 children: inline | ||||
|           TextNode <#text> | ||||
|         BlockContainer <div.b> at (122.265625,8) content-size 669.734375x17.46875 [BFC] children: inline | ||||
|           line 0 width: 9.34375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 | ||||
|             frag 0 from TextNode start: 0, length: 1, rect: [122.265625,8 9.34375x17.46875] | ||||
|  |  | |||
|  | @ -0,0 +1,47 @@ | |||
| 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 (8,8) content-size 784x34.9375 children: not-inline | ||||
|       BlockContainer <div> at (8,8) content-size 784x34.9375 children: not-inline | ||||
|         BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline | ||||
|           TextNode <#text> | ||||
|         BlockContainer <div> at (8,8) content-size 784x0 children: inline | ||||
|           TextNode <#text> | ||||
|           BlockContainer <div.a> at (8,8) content-size 57.0625x34.9375 floating [BFC] children: not-inline | ||||
|             BlockContainer <(anonymous)> at (8,8) content-size 57.0625x0 children: inline | ||||
|               TextNode <#text> | ||||
|             BlockContainer <div.a4> at (8,8) content-size 57.0625x17.46875 children: inline | ||||
|               line 0 width: 57.0625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 | ||||
|                 frag 0 from TextNode start: 0, length: 4, rect: [8,8 57.0625x17.46875] | ||||
|                   "AAAA" | ||||
|               TextNode <#text> | ||||
|             BlockContainer <(anonymous)> at (8,25.46875) content-size 57.0625x0 children: inline | ||||
|               TextNode <#text> | ||||
|             BlockContainer <div> at (8,25.46875) content-size 57.0625x17.46875 children: inline | ||||
|               line 0 width: 14.265625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 | ||||
|                 frag 0 from TextNode start: 0, length: 1, rect: [8,25.46875 14.265625x17.46875] | ||||
|                   "A" | ||||
|               TextNode <#text> | ||||
|             BlockContainer <(anonymous)> at (8,42.9375) content-size 57.0625x0 children: inline | ||||
|               TextNode <#text> | ||||
|           TextNode <#text> | ||||
|         BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline | ||||
|           TextNode <#text> | ||||
|         BlockContainer <div> at (108,8) content-size 684x34.9375 children: not-inline | ||||
|           BlockContainer <(anonymous)> at (108,8) content-size 684x0 children: inline | ||||
|             TextNode <#text> | ||||
|           BlockContainer <div> at (108,8) content-size 684x17.46875 children: inline | ||||
|             line 0 width: 9.34375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 | ||||
|               frag 0 from TextNode start: 0, length: 1, rect: [108,8 9.34375x17.46875] | ||||
|                 "B" | ||||
|             TextNode <#text> | ||||
|           BlockContainer <(anonymous)> at (108,25.46875) content-size 684x0 children: inline | ||||
|             TextNode <#text> | ||||
|           BlockContainer <div.c> at (108,25.46875) content-size 684x17.46875 [BFC] children: inline | ||||
|             line 0 width: 10.3125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 | ||||
|               frag 0 from TextNode start: 0, length: 1, rect: [108,25.46875 10.3125x17.46875] | ||||
|                 "C" | ||||
|             TextNode <#text> | ||||
|           BlockContainer <(anonymous)> at (108,42.9375) content-size 684x0 children: inline | ||||
|             TextNode <#text> | ||||
|         BlockContainer <(anonymous)> at (8,42.9375) content-size 784x0 children: inline | ||||
|           TextNode <#text> | ||||
|  | @ -20,7 +20,9 @@ | |||
| 
 | ||||
| <body> | ||||
|     <div class="ab"> | ||||
|         <div> | ||||
|             <div class="a">A</div> | ||||
|         </div> | ||||
|         <div class="b">B</div> | ||||
|     </div> | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,26 @@ | |||
| <style> | ||||
|     .a { | ||||
|         float: left; | ||||
|     } | ||||
| 
 | ||||
|     .a4 { | ||||
|         display: block; | ||||
|     } | ||||
| 
 | ||||
|     .c { | ||||
|         overflow: hidden; | ||||
|     } | ||||
| </style> | ||||
| 
 | ||||
| <div> | ||||
|     <div> | ||||
|         <div class="a"> | ||||
|             <div class="a4">AAAA</div> | ||||
|             <div>A</div> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div style="margin-left: 100px"> | ||||
|         <div>B</div> | ||||
|         <div class="c">C</div> | ||||
|     </div> | ||||
| </div> | ||||
|  | @ -802,6 +802,18 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_vertically | |||
|     box_state.set_content_offset(CSSPixelPoint { box_state.offset.x(), y }); | ||||
| } | ||||
| 
 | ||||
| // Returns whether the given box has the given ancestor on the path to root, ignoring the anonymous blocks.
 | ||||
| static bool box_has_ancestor_in_non_anonymous_containing_block_chain(Box const* box, Box const& ancestor, Box const& root) | ||||
| { | ||||
|     Box const* current_ancestor = box ? box->non_anonymous_containing_block() : &root; | ||||
|     while (current_ancestor != &root) { | ||||
|         if (current_ancestor == &ancestor) | ||||
|             return true; | ||||
|         current_ancestor = current_ancestor->non_anonymous_containing_block(); | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| void BlockFormattingContext::place_block_level_element_in_normal_flow_horizontally(Box const& child_box, AvailableSpace const& available_space) | ||||
| { | ||||
|     auto& box_state = m_state.get_mutable(child_box); | ||||
|  | @ -814,7 +826,12 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_horizontal | |||
|         auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(child_box, root()); | ||||
|         auto space_and_containing_margin = space_used_and_containing_margin_for_floats(box_in_root_rect.y()); | ||||
|         available_width_within_containing_block -= space_and_containing_margin.left_used_space + space_and_containing_margin.right_used_space; | ||||
|         x += space_and_containing_margin.left_used_space; | ||||
|         auto const& containing_box_state = m_state.get(*child_box.containing_block()); | ||||
|         if (box_has_ancestor_in_non_anonymous_containing_block_chain(space_and_containing_margin.matching_left_float_box, *child_box.non_anonymous_containing_block(), root())) | ||||
|             x = space_and_containing_margin.left_used_space; | ||||
|         else | ||||
|             // If the floating box doesn't share a containing block with the child box, the child box margin should overlap with the width of the floating box.
 | ||||
|             x = max(space_and_containing_margin.left_used_space - containing_box_state.margin_left, 0); | ||||
|     } | ||||
| 
 | ||||
|     if (child_box.containing_block()->computed_values().text_align() == CSS::TextAlign::LibwebCenter) { | ||||
|  | @ -1056,6 +1073,7 @@ BlockFormattingContext::SpaceUsedAndContainingMarginForFloats BlockFormattingCon | |||
|                 + floating_box_state.content_width() | ||||
|                 + floating_box_state.margin_box_right(); | ||||
|             space_and_containing_margin.left_total_containing_margin = offset_from_containing_block_chain_margins_between_here_and_root; | ||||
|             space_and_containing_margin.matching_left_float_box = floating_box.box.ptr(); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -121,6 +121,7 @@ protected: | |||
|         // Each block in the containing chain adds its own margin and we store the total here.
 | ||||
|         CSSPixels left_total_containing_margin; | ||||
|         CSSPixels right_total_containing_margin; | ||||
|         Box const* matching_left_float_box { nullptr }; | ||||
|     }; | ||||
| 
 | ||||
|     struct ShrinkToFitResult { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andi Gallo
						Andi Gallo