mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 20:32:44 +00:00 
			
		
		
		
	Browser: Add error page
Add a simple HTML error page that gets loaded into the HtmlView when loading the page fails. Closes #1210 and #1516
This commit is contained in:
		
							parent
							
								
									b1365d94f4
								
							
						
					
					
						commit
						021d78f8f7
					
				
					 5 changed files with 79 additions and 28 deletions
				
			
		
							
								
								
									
										21
									
								
								Base/res/html/error.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Base/res/html/error.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| <!DOCTYPE html> | ||||
| <html> | ||||
|     <head> | ||||
|         <title>Error!</title> | ||||
|         <style> | ||||
|             h1 { | ||||
|                 display: inline; | ||||
|             } | ||||
|             header { | ||||
|                 margin-bottom: 10px; | ||||
|             } | ||||
|         </style> | ||||
|     </head> | ||||
|     <body> | ||||
|         <header> | ||||
|             <img src="file:///res/icons/32x32/msgbox-warning.png" alt="Warning" width="24" height="24"> | ||||
|             <h1>Failed to load %s</h1> | ||||
|         </header> | ||||
|         <p>Error: %s</p> | ||||
|     </body> | ||||
| </html> | ||||
|  | @ -346,23 +346,51 @@ void HtmlView::load(const URL& url) | |||
|     if (on_load_start) | ||||
|         on_load_start(url); | ||||
| 
 | ||||
|     ResourceLoader::the().load(url, [this, url](auto data) { | ||||
|         if (data.is_null()) { | ||||
|             dbg() << "Load failed!"; | ||||
|             ASSERT_NOT_REACHED(); | ||||
|         } | ||||
|     ResourceLoader::the().load( | ||||
|         url, | ||||
|         [this, url](auto data) { | ||||
|             if (data.is_null()) { | ||||
|                 load_error_page(url, "No data"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|         RefPtr<Document> document; | ||||
|         if (url.path().ends_with(".png")) { | ||||
|             document = create_image_document(data, url); | ||||
|         } else { | ||||
|             document = parse_html_document(data, url); | ||||
|         } | ||||
|         ASSERT(document); | ||||
|         set_document(document); | ||||
|         if (on_title_change) | ||||
|             on_title_change(document->title()); | ||||
|     }); | ||||
|             RefPtr<Document> document; | ||||
|             if (url.path().ends_with(".png")) { | ||||
|                 document = create_image_document(data, url); | ||||
|             } else { | ||||
|                 document = parse_html_document(data, url); | ||||
|             } | ||||
|             ASSERT(document); | ||||
|             set_document(document); | ||||
|             if (on_title_change) | ||||
|                 on_title_change(document->title()); | ||||
|         }, | ||||
|         [this, url](auto error) { | ||||
|             load_error_page(url, error); | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| void HtmlView::load_error_page(const URL& failed_url, const String& error) | ||||
| { | ||||
|     auto error_page_url = "file:///res/html/error.html"; | ||||
|     ResourceLoader::the().load( | ||||
|         error_page_url, | ||||
|         [this, failed_url, error](auto data) { | ||||
|             ASSERT(!data.is_null()); | ||||
|             auto html = String::format( | ||||
|                 String::copy(data).characters(), | ||||
|                 escape_html_entities(failed_url.to_string()).characters(), | ||||
|                 escape_html_entities(error).characters()); | ||||
|             auto document = parse_html_document(html, failed_url); | ||||
|             ASSERT(document); | ||||
|             set_document(document); | ||||
|             if (on_title_change) | ||||
|                 on_title_change(document->title()); | ||||
|         }, | ||||
|         [](auto error) { | ||||
|             dbg() << "Failed to load error page: " << error; | ||||
|             ASSERT_NOT_REACHED(); | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| const LayoutDocument* HtmlView::layout_root() const | ||||
|  |  | |||
|  | @ -50,6 +50,7 @@ public: | |||
| 
 | ||||
|     void reload(); | ||||
|     void load(const URL&); | ||||
|     void load_error_page(const URL&, const String& error); | ||||
|     void scroll_to_anchor(const StringView&); | ||||
| 
 | ||||
|     URL url() const; | ||||
|  |  | |||
|  | @ -26,9 +26,9 @@ | |||
| 
 | ||||
| #include <AK/SharedBuffer.h> | ||||
| #include <LibCore/File.h> | ||||
| #include <LibWeb/ResourceLoader.h> | ||||
| #include <LibProtocol/Client.h> | ||||
| #include <LibProtocol/Download.h> | ||||
| #include <LibWeb/ResourceLoader.h> | ||||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
|  | @ -45,36 +45,37 @@ ResourceLoader::ResourceLoader() | |||
| { | ||||
| } | ||||
| 
 | ||||
| void ResourceLoader::load(const URL& url, Function<void(const ByteBuffer&)> callback) | ||||
| void ResourceLoader::load(const URL& url, Function<void(const ByteBuffer&)> success_callback, Function<void(const String&)> error_callback) | ||||
| { | ||||
|     if (url.protocol() == "file") { | ||||
|         auto f = Core::File::construct(); | ||||
|         f->set_filename(url.path()); | ||||
|         if (!f->open(Core::IODevice::OpenMode::ReadOnly)) { | ||||
|             dbg() << "ResourceLoader::load: Error: " << f->error_string(); | ||||
|             callback({}); | ||||
|             if (error_callback) | ||||
|                 error_callback(f->error_string()); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         auto data = f->read_all(); | ||||
|         deferred_invoke([data = move(data), callback = move(callback)](auto&) { | ||||
|             callback(data); | ||||
|         deferred_invoke([data = move(data), success_callback = move(success_callback)](auto&) { | ||||
|             success_callback(data); | ||||
|         }); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (url.protocol() == "http") { | ||||
|         auto download = protocol_client().start_download(url.to_string()); | ||||
|         download->on_finish = [this, callback = move(callback)](bool success, const ByteBuffer& payload, auto) { | ||||
|         download->on_finish = [this, success_callback = move(success_callback), error_callback = move(error_callback)](bool success, const ByteBuffer& payload, auto) { | ||||
|             --m_pending_loads; | ||||
|             if (on_load_counter_change) | ||||
|                 on_load_counter_change(); | ||||
|             if (!success) { | ||||
|                 dbg() << "HTTP load failed!"; | ||||
|                 callback({}); | ||||
|                 if (error_callback) | ||||
|                     error_callback("HTTP load failed"); | ||||
|                 return; | ||||
|             } | ||||
|             callback(ByteBuffer::copy(payload.data(), payload.size())); | ||||
|             success_callback(ByteBuffer::copy(payload.data(), payload.size())); | ||||
|         }; | ||||
|         ++m_pending_loads; | ||||
|         if (on_load_counter_change) | ||||
|  | @ -82,8 +83,8 @@ void ResourceLoader::load(const URL& url, Function<void(const ByteBuffer&)> call | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     dbg() << "Unimplemented protocol: " << url.protocol(); | ||||
|     ASSERT_NOT_REACHED(); | ||||
|     if (error_callback) | ||||
|         error_callback(String::format("Protocol not implemented: %s", url.protocol().characters())); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ class ResourceLoader : public Core::Object { | |||
| public: | ||||
|     static ResourceLoader& the(); | ||||
| 
 | ||||
|     void load(const URL&, Function<void(const ByteBuffer&)>); | ||||
|     void load(const URL&, Function<void(const ByteBuffer&)> success_callback, Function<void(const String&)> error_callback = nullptr); | ||||
| 
 | ||||
|     Function<void()> on_load_counter_change; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Linus Groh
						Linus Groh