mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:22:45 +00:00 
			
		
		
		
	LibWeb: Account for CSS transform in Element::getClientRects()
This commit is contained in:
		
							parent
							
								
									96d5f555e1
								
							
						
					
					
						commit
						fb2166f19c
					
				
					 3 changed files with 45 additions and 3 deletions
				
			
		|  | @ -0,0 +1 @@ | ||||||
|  |        {"x":68,"y":118,"width":100,"height":100,"top":118,"right":168,"bottom":218,"left":68} | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | <!DOCTYPE html> | ||||||
|  | <style type="text/css"> | ||||||
|  |     .transform-1 { | ||||||
|  |         transform: translate(100px, 100px); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .transform-2 { | ||||||
|  |         transform: translate(-50px, 0px); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #box { | ||||||
|  |         background-color: magenta; | ||||||
|  |         width: 100px; | ||||||
|  |         height: 100px; | ||||||
|  |         opacity: 0.1; | ||||||
|  |         transform: translate(10px, 10px); | ||||||
|  |     } | ||||||
|  | </style> | ||||||
|  | <div class="transform-1"> | ||||||
|  |     <div class="transform-2"> | ||||||
|  |         <div id="box"></div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | <script src="include.js"></script> | ||||||
|  | <script> | ||||||
|  |     test(() => { | ||||||
|  |         const transformed_box_rect = document.getElementById("box").getBoundingClientRect(); | ||||||
|  |         println(JSON.stringify(transformed_box_rect)); | ||||||
|  |     }); | ||||||
|  | </script> | ||||||
|  | @ -900,7 +900,7 @@ JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const | ||||||
| 
 | 
 | ||||||
|     // 3. Return a DOMRectList object containing DOMRect objects in content order, one for each box fragment,
 |     // 3. Return a DOMRectList object containing DOMRect objects in content order, one for each box fragment,
 | ||||||
|     // describing its border area (including those with a height or width of zero) with the following constraints:
 |     // describing its border area (including those with a height or width of zero) with the following constraints:
 | ||||||
|     // FIXME: - Apply the transforms that apply to the element and its ancestors.
 |     // - Apply the transforms that apply to the element and its ancestors.
 | ||||||
|     // FIXME: - If the element on which the method was invoked has a computed value for the display property of table
 |     // FIXME: - If the element on which the method was invoked has a computed value for the display property of table
 | ||||||
|     //          or inline-table include both the table box and the caption box, if any, but not the anonymous container box.
 |     //          or inline-table include both the table box and the caption box, if any, but not the anonymous container box.
 | ||||||
|     // FIXME: - Replace each anonymous block box with its child box(es) and repeat this until no anonymous block boxes
 |     // FIXME: - Replace each anonymous block box with its child box(es) and repeat this until no anonymous block boxes
 | ||||||
|  | @ -908,16 +908,27 @@ JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const | ||||||
|     const_cast<Document&>(document()).update_layout(); |     const_cast<Document&>(document()).update_layout(); | ||||||
|     VERIFY(document().navigable()); |     VERIFY(document().navigable()); | ||||||
|     auto viewport_offset = document().navigable()->viewport_scroll_offset(); |     auto viewport_offset = document().navigable()->viewport_scroll_offset(); | ||||||
|  | 
 | ||||||
|  |     Gfx::AffineTransform transform; | ||||||
|  |     for (auto const* containing_block = this->layout_node(); containing_block; containing_block = containing_block->containing_block()) { | ||||||
|  |         Gfx::AffineTransform containing_block_transform; | ||||||
|  |         if (containing_block->paintable() && containing_block->paintable()->is_paintable_box()) { | ||||||
|  |             auto const& containing_block_paintable_box = static_cast<Painting::PaintableBox const&>(*containing_block->paintable()); | ||||||
|  |             containing_block_transform = Gfx::extract_2d_affine_transform(containing_block_paintable_box.transform()); | ||||||
|  |         } | ||||||
|  |         transform = transform.multiply(containing_block_transform); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     auto const* paintable = this->paintable(); |     auto const* paintable = this->paintable(); | ||||||
|     if (auto const* paintable_box = this->paintable_box()) { |     if (auto const* paintable_box = this->paintable_box()) { | ||||||
|         auto absolute_rect = paintable_box->absolute_border_box_rect(); |         auto absolute_rect = paintable_box->absolute_border_box_rect(); | ||||||
|         absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y()); |         absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y()); | ||||||
|         rects.append(Geometry::DOMRect::create(realm(), absolute_rect.to_type<float>())); |         rects.append(Geometry::DOMRect::create(realm(), transform.map(absolute_rect.to_type<float>()))); | ||||||
|     } else if (paintable && is<Painting::InlinePaintable>(*paintable)) { |     } else if (paintable && is<Painting::InlinePaintable>(*paintable)) { | ||||||
|         auto const& inline_paintable = static_cast<Painting::InlinePaintable const&>(*paintable); |         auto const& inline_paintable = static_cast<Painting::InlinePaintable const&>(*paintable); | ||||||
|         auto absolute_rect = inline_paintable.bounding_rect(); |         auto absolute_rect = inline_paintable.bounding_rect(); | ||||||
|         absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y()); |         absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y()); | ||||||
|         rects.append(Geometry::DOMRect::create(realm(), absolute_rect.to_type<float>())); |         rects.append(Geometry::DOMRect::create(realm(), transform.map(absolute_rect.to_type<float>()))); | ||||||
|     } else if (paintable) { |     } else if (paintable) { | ||||||
|         dbgln("FIXME: Failed to get client rects for element ({})", debug_description()); |         dbgln("FIXME: Failed to get client rects for element ({})", debug_description()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Aliaksandr Kalenik
						Aliaksandr Kalenik