mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:52:43 +00:00 
			
		
		
		
	LibWeb: Implement document ready state
This commit is contained in:
		
							parent
							
								
									8aabec1c94
								
							
						
					
					
						commit
						124c52b3b5
					
				
					 5 changed files with 49 additions and 0 deletions
				
			
		|  | @ -41,6 +41,7 @@ | ||||||
| #include <LibWeb/DOM/DocumentType.h> | #include <LibWeb/DOM/DocumentType.h> | ||||||
| #include <LibWeb/DOM/Element.h> | #include <LibWeb/DOM/Element.h> | ||||||
| #include <LibWeb/DOM/ElementFactory.h> | #include <LibWeb/DOM/ElementFactory.h> | ||||||
|  | #include <LibWeb/DOM/Event.h> | ||||||
| #include <LibWeb/DOM/Text.h> | #include <LibWeb/DOM/Text.h> | ||||||
| #include <LibWeb/DOM/Window.h> | #include <LibWeb/DOM/Window.h> | ||||||
| #include <LibWeb/HTML/AttributeNames.h> | #include <LibWeb/HTML/AttributeNames.h> | ||||||
|  | @ -522,4 +523,10 @@ void Document::set_focused_element(Element* element) | ||||||
|         m_layout_root->set_needs_display(); |         m_layout_root->set_needs_display(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Document::set_ready_state(const String& ready_state) | ||||||
|  | { | ||||||
|  |     m_ready_state = ready_state; | ||||||
|  |     dispatch_event(Event::create("readystatechange")); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -174,6 +174,9 @@ public: | ||||||
|     const Document* associated_inert_template_document() const { return m_associated_inert_template_document; } |     const Document* associated_inert_template_document() const { return m_associated_inert_template_document; } | ||||||
|     void set_associated_inert_template_document(Document& document) { m_associated_inert_template_document = document; } |     void set_associated_inert_template_document(Document& document) { m_associated_inert_template_document = document; } | ||||||
| 
 | 
 | ||||||
|  |     const String& ready_state() const { return m_ready_state; } | ||||||
|  |     void set_ready_state(const String&); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     virtual RefPtr<LayoutNode> create_layout_node(const CSS::StyleProperties* parent_style) override; |     virtual RefPtr<LayoutNode> create_layout_node(const CSS::StyleProperties* parent_style) override; | ||||||
| 
 | 
 | ||||||
|  | @ -209,6 +212,8 @@ private: | ||||||
| 
 | 
 | ||||||
|     bool m_created_for_appropriate_template_contents { false }; |     bool m_created_for_appropriate_template_contents { false }; | ||||||
|     RefPtr<Document> m_associated_inert_template_document; |     RefPtr<Document> m_associated_inert_template_document; | ||||||
|  | 
 | ||||||
|  |     String m_ready_state { "loading" }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,4 +17,6 @@ interface Document : Node { | ||||||
|     attribute HTMLElement? body; |     attribute HTMLElement? body; | ||||||
|     readonly attribute HTMLHeadElement? head; |     readonly attribute HTMLHeadElement? head; | ||||||
| 
 | 
 | ||||||
|  |     readonly attribute DOMString readyState; | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -156,6 +156,8 @@ void HTMLDocumentParser::run(const URL& url) | ||||||
| 
 | 
 | ||||||
|     // "The end"
 |     // "The end"
 | ||||||
| 
 | 
 | ||||||
|  |     m_document->set_ready_state("interactive"); | ||||||
|  | 
 | ||||||
|     auto scripts_to_execute_when_parsing_has_finished = m_document->take_scripts_to_execute_when_parsing_has_finished({}); |     auto scripts_to_execute_when_parsing_has_finished = m_document->take_scripts_to_execute_when_parsing_has_finished({}); | ||||||
|     for (auto& script : scripts_to_execute_when_parsing_has_finished) { |     for (auto& script : scripts_to_execute_when_parsing_has_finished) { | ||||||
|         script.execute_script(); |         script.execute_script(); | ||||||
|  | @ -167,6 +169,8 @@ void HTMLDocumentParser::run(const URL& url) | ||||||
|     for (auto& script : scripts_to_execute_as_soon_as_possible) { |     for (auto& script : scripts_to_execute_as_soon_as_possible) { | ||||||
|         script.execute_script(); |         script.execute_script(); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     m_document->set_ready_state("complete"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void HTMLDocumentParser::process_using_the_rules_for(InsertionMode mode, HTMLToken& token) | void HTMLDocumentParser::process_using_the_rules_for(InsertionMode mode, HTMLToken& token) | ||||||
|  |  | ||||||
							
								
								
									
										31
									
								
								Libraries/LibWeb/Tests/HTML/document.readyState.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								Libraries/LibWeb/Tests/HTML/document.readyState.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | ||||||
|  | loadPage("file:///res/html/misc/blank.html"); | ||||||
|  | 
 | ||||||
|  | beforeInitialPageLoad(() => { | ||||||
|  |     window.events = []; | ||||||
|  | 
 | ||||||
|  |     document.addEventListener("readystatechange", () => { | ||||||
|  |         window.events.push(document.readyState); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     document.addEventListener("DOMContentLoaded", () => { | ||||||
|  |         test("Ready state should be 'interactive' when 'DOMContentLoaded' fires", () => { | ||||||
|  |             expect(document.readyState).toBe("interactive"); | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test("Ready state should be 'loading' initially", () => { | ||||||
|  |         expect(document.readyState).toBe("loading"); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | afterInitialPageLoad(() => { | ||||||
|  |     test("'interactive' should come before 'complete' and both should have happened", () => { | ||||||
|  |         expect(window.events).toHaveLength(2); | ||||||
|  |         expect(window.events[0]).toBe("interactive"); | ||||||
|  |         expect(window.events[1]).toBe("complete"); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test("Ready state should be 'complete' after loading", () => { | ||||||
|  |         expect(document.readyState).toBe("complete"); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Luke
						Luke