mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 21:52:45 +00:00 
			
		
		
		
	LibWeb: Invalidate layout-transformed text on DOM text node change
This fixes an issue where programmatically changing the value of an input element wasn't reflected visually.
This commit is contained in:
		
							parent
							
								
									e2740bd19d
								
							
						
					
					
						commit
						1c47695bae
					
				
					 5 changed files with 44 additions and 0 deletions
				
			
		|  | @ -0,0 +1,22 @@ | ||||||
|  | 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 784x21.46875 children: inline | ||||||
|  |       line 0 width: 120, height: 21.46875, bottom: 21.46875, baseline: 21.46875 | ||||||
|  |         frag 0 from BlockContainer start: 0, length: 0, rect: [9,9 118x19.46875] | ||||||
|  |       BlockContainer <input#foo> at (9,9) content-size 118x19.46875 inline-block [BFC] children: not-inline | ||||||
|  |         Box <div> at (11,10) content-size 114x17.46875 flex-container(row) [FFC] children: not-inline | ||||||
|  |           BlockContainer <div> at (11,10) content-size 49.734375x17.46875 flex-item [BFC] children: inline | ||||||
|  |             line 0 width: 49.734375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 | ||||||
|  |               frag 0 from TextNode start: 0, length: 4, rect: [11,10 49.734375x17.46875] | ||||||
|  |                 "PASS" | ||||||
|  |             TextNode <#text> | ||||||
|  |       TextNode <#text> | ||||||
|  |       TextNode <#text> | ||||||
|  | 
 | ||||||
|  | PaintableWithLines (Viewport<#document>) [0,0 800x600] | ||||||
|  |   PaintableWithLines (BlockContainer<HTML>) [0,0 800x600] | ||||||
|  |     PaintableWithLines (BlockContainer<BODY>) [8,8 784x21.46875] | ||||||
|  |       PaintableWithLines (BlockContainer<INPUT>#foo) [8,8 120x21.46875] | ||||||
|  |         PaintableBox (Box<DIV>) [9,9 118x19.46875] | ||||||
|  |           PaintableWithLines (BlockContainer<DIV>) [11,10 49.734375x17.46875] | ||||||
|  |             TextPaintable (TextNode<#text>) | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | <input id="foo"> | ||||||
|  | <script> | ||||||
|  |     let foo = document.getElementById("foo"); | ||||||
|  |     foo.value = "FAIL"; | ||||||
|  |     document.body.offsetWidth; // Force a layout | ||||||
|  |     document.addEventListener("DOMContentLoaded", function() { | ||||||
|  |         foo.value = "PASS"; | ||||||
|  |     }); | ||||||
|  | </script> | ||||||
|  | @ -10,6 +10,7 @@ | ||||||
| #include <LibWeb/DOM/MutationType.h> | #include <LibWeb/DOM/MutationType.h> | ||||||
| #include <LibWeb/DOM/Range.h> | #include <LibWeb/DOM/Range.h> | ||||||
| #include <LibWeb/DOM/StaticNodeList.h> | #include <LibWeb/DOM/StaticNodeList.h> | ||||||
|  | #include <LibWeb/Layout/TextNode.h> | ||||||
| 
 | 
 | ||||||
| namespace Web::DOM { | namespace Web::DOM { | ||||||
| 
 | 
 | ||||||
|  | @ -108,6 +109,12 @@ WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t coun | ||||||
|     if (parent()) |     if (parent()) | ||||||
|         parent()->children_changed(); |         parent()->children_changed(); | ||||||
| 
 | 
 | ||||||
|  |     // NOTE: Since the text node's data has changed, we need to invalidate the text for rendering.
 | ||||||
|  |     //       This ensures that the new text is reflected in layout, even if we don't end up
 | ||||||
|  |     //       doing a full layout tree rebuild.
 | ||||||
|  |     if (auto* layout_node = this->layout_node(); layout_node && layout_node->is_text_node()) | ||||||
|  |         static_cast<Layout::TextNode&>(*layout_node).invalidate_text_for_rendering(); | ||||||
|  | 
 | ||||||
|     set_needs_style_update(true); |     set_needs_style_update(true); | ||||||
|     document().set_needs_layout(); |     document().set_needs_layout(); | ||||||
|     return {}; |     return {}; | ||||||
|  |  | ||||||
|  | @ -41,6 +41,11 @@ static ErrorOr<DeprecatedString> apply_text_transform(DeprecatedString const& st | ||||||
|     return string; |     return string; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void TextNode::invalidate_text_for_rendering() | ||||||
|  | { | ||||||
|  |     m_text_for_rendering = {}; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| DeprecatedString const& TextNode::text_for_rendering() const | DeprecatedString const& TextNode::text_for_rendering() const | ||||||
| { | { | ||||||
|     if (m_text_for_rendering.is_null()) |     if (m_text_for_rendering.is_null()) | ||||||
|  |  | ||||||
|  | @ -47,6 +47,7 @@ public: | ||||||
|         Utf8View::Iterator m_iterator; |         Utf8View::Iterator m_iterator; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     void invalidate_text_for_rendering(); | ||||||
|     void compute_text_for_rendering(); |     void compute_text_for_rendering(); | ||||||
| 
 | 
 | ||||||
|     virtual JS::GCPtr<Painting::Paintable> create_paintable() const override; |     virtual JS::GCPtr<Painting::Paintable> create_paintable() const override; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling