| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2024-10-04 13:19:50 +02:00
										 |  |  |  * Copyright (c) 2020-2023, Andreas Kling <andreas@ladybird.org> | 
					
						
							| 
									
										
										
										
											2025-07-23 11:29:03 +01:00
										 |  |  |  * Copyright (c) 2021-2025, Sam Atkins <sam@ladybird.org> | 
					
						
							| 
									
										
										
										
											2023-01-12 14:35:35 +00:00
										 |  |  |  * Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org> | 
					
						
							| 
									
										
										
										
											2022-10-18 12:40:14 +02:00
										 |  |  |  * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org> | 
					
						
							| 
									
										
										
										
											2022-11-03 13:30:11 -04:00
										 |  |  |  * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org> | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |  * Copyright (c) 2023-2024, Andrew Kaster <akaster@serenityos.org> | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 16:35:10 +01:00
										 |  |  | #include <AK/JsonObject.h>
 | 
					
						
							| 
									
										
										
										
											2022-04-08 01:46:47 +04:30
										 |  |  | #include <AK/QuickSort.h>
 | 
					
						
							| 
									
										
										
										
											2024-11-10 15:14:12 +01:00
										 |  |  | #include <LibCore/EventLoop.h>
 | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  | #include <LibGC/Heap.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | #include <LibGfx/Bitmap.h>
 | 
					
						
							| 
									
										
										
										
											2022-04-09 09:28:38 +02:00
										 |  |  | #include <LibGfx/Font/FontDatabase.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | #include <LibGfx/SystemTheme.h>
 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:20:06 +01:00
										 |  |  | #include <LibJS/Runtime/ConsoleObject.h>
 | 
					
						
							| 
									
										
										
										
											2024-09-03 10:18:43 -04:00
										 |  |  | #include <LibJS/Runtime/Date.h>
 | 
					
						
							| 
									
										
										
										
											2024-08-24 12:15:20 -04:00
										 |  |  | #include <LibUnicode/TimeZone.h>
 | 
					
						
							| 
									
										
										
										
											2023-05-21 08:52:03 -05:00
										 |  |  | #include <LibWeb/ARIA/RoleType.h>
 | 
					
						
							| 
									
										
										
										
											2021-02-03 10:41:07 +01:00
										 |  |  | #include <LibWeb/Bindings/MainThreadVM.h>
 | 
					
						
							| 
									
										
										
										
											2025-02-18 09:19:56 +01:00
										 |  |  | #include <LibWeb/CSS/ComputedProperties.h>
 | 
					
						
							| 
									
										
										
										
											2025-07-23 11:29:03 +01:00
										 |  |  | #include <LibWeb/CSS/Parser/ErrorReporter.h>
 | 
					
						
							| 
									
										
										
										
											2023-05-08 06:37:18 +02:00
										 |  |  | #include <LibWeb/CSS/StyleComputer.h>
 | 
					
						
							| 
									
										
										
										
											2025-08-07 18:20:13 +03:00
										 |  |  | #include <LibWeb/CookieStore/CookieStore.h>
 | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | #include <LibWeb/DOM/Attr.h>
 | 
					
						
							|  |  |  | #include <LibWeb/DOM/CharacterData.h>
 | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  | #include <LibWeb/DOM/Document.h>
 | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | #include <LibWeb/DOM/Element.h>
 | 
					
						
							|  |  |  | #include <LibWeb/DOM/ElementFactory.h>
 | 
					
						
							| 
									
										
										
										
											2024-11-13 16:07:16 +00:00
										 |  |  | #include <LibWeb/DOM/ShadowRoot.h>
 | 
					
						
							| 
									
										
										
										
											2023-12-07 11:00:57 -05:00
										 |  |  | #include <LibWeb/DOM/Text.h>
 | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  | #include <LibWeb/Dump.h>
 | 
					
						
							| 
									
										
										
										
											2021-11-18 15:01:28 +01:00
										 |  |  | #include <LibWeb/HTML/BrowsingContext.h>
 | 
					
						
							| 
									
										
										
										
											2024-02-25 13:02:47 -05:00
										 |  |  | #include <LibWeb/HTML/HTMLInputElement.h>
 | 
					
						
							|  |  |  | #include <LibWeb/HTML/SelectedFile.h>
 | 
					
						
							| 
									
										
										
										
											2022-02-08 19:50:14 +01:00
										 |  |  | #include <LibWeb/HTML/Storage.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-14 20:19:41 +02:00
										 |  |  | #include <LibWeb/HTML/TraversableNavigable.h>
 | 
					
						
							| 
									
										
										
										
											2022-03-07 23:08:26 +01:00
										 |  |  | #include <LibWeb/HTML/Window.h>
 | 
					
						
							| 
									
										
										
										
											2023-12-05 16:54:53 -05:00
										 |  |  | #include <LibWeb/Infra/Strings.h>
 | 
					
						
							| 
									
										
										
										
											2023-02-25 11:04:29 +01:00
										 |  |  | #include <LibWeb/Layout/Viewport.h>
 | 
					
						
							| 
									
										
										
										
											2021-09-27 11:39:17 +02:00
										 |  |  | #include <LibWeb/Loader/ContentFilter.h>
 | 
					
						
							| 
									
										
										
										
											2022-04-08 01:46:47 +04:30
										 |  |  | #include <LibWeb/Loader/ProxyMappings.h>
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:31:09 -04:00
										 |  |  | #include <LibWeb/Loader/ResourceLoader.h>
 | 
					
						
							| 
									
										
										
										
											2024-07-02 19:28:39 +01:00
										 |  |  | #include <LibWeb/Loader/UserAgent.h>
 | 
					
						
							| 
									
										
										
										
											2023-12-06 10:36:27 -05:00
										 |  |  | #include <LibWeb/Namespace.h>
 | 
					
						
							| 
									
										
										
										
											2022-03-11 00:03:28 +01:00
										 |  |  | #include <LibWeb/Painting/StackingContext.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-19 09:29:04 +02:00
										 |  |  | #include <LibWeb/Painting/ViewportPaintable.h>
 | 
					
						
							| 
									
										
										
										
											2023-04-17 13:21:19 -04:00
										 |  |  | #include <LibWeb/PermissionsPolicy/AutoplayAllowlist.h>
 | 
					
						
							| 
									
										
										
										
											2022-10-08 10:54:52 +02:00
										 |  |  | #include <LibWeb/Platform/EventLoopPlugin.h>
 | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | #include <LibWebView/Attribute.h>
 | 
					
						
							| 
									
										
										
										
											2022-02-25 12:18:30 +02:00
										 |  |  | #include <WebContent/ConnectionFromClient.h>
 | 
					
						
							| 
									
										
										
										
											2023-11-29 09:34:38 -07:00
										 |  |  | #include <WebContent/PageClient.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | #include <WebContent/PageHost.h>
 | 
					
						
							|  |  |  | #include <WebContent/WebContentClientEndpoint.h>
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | namespace WebContent { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-08 22:01:46 +02:00
										 |  |  | ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<IPC::Transport> transport) | 
					
						
							| 
									
										
										
										
											2024-10-22 15:47:33 -06:00
										 |  |  |     : IPC::ConnectionFromClient<WebContentClientEndpoint, WebContentServerEndpoint>(*this, move(transport), 1) | 
					
						
							| 
									
										
										
										
											2020-06-17 18:00:18 +02:00
										 |  |  |     , m_page_host(PageHost::create(*this)) | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 10:38:35 +02:00
										 |  |  | ConnectionFromClient::~ConnectionFromClient() = default; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 12:18:30 +02:00
										 |  |  | void ConnectionFromClient::die() | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-10-08 10:54:52 +02:00
										 |  |  |     Web::Platform::EventLoopPlugin::the().quit(); | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-03 21:19:46 +05:00
										 |  |  | Messages::WebContentServer::InitTransportResponse ConnectionFromClient::init_transport([[maybe_unused]] int peer_pid) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef AK_OS_WINDOWS
 | 
					
						
							| 
									
										
										
										
											2025-06-28 03:32:38 -07:00
										 |  |  |     m_transport->set_peer_pid(peer_pid); | 
					
						
							| 
									
										
										
										
											2025-01-03 21:19:46 +05:00
										 |  |  |     return Core::System::getpid(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     VERIFY_NOT_REACHED(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  | Optional<PageClient&> ConnectionFromClient::page(u64 index, SourceLocation location) | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = m_page_host->page(index); page.has_value()) | 
					
						
							|  |  |  |         return *page; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dbgln("ConnectionFromClient::{}: Did not find a page with ID {}", location.function_name(), index); | 
					
						
							|  |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  | Optional<PageClient const&> ConnectionFromClient::page(u64 index, SourceLocation location) const | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = m_page_host->page(index); page.has_value()) | 
					
						
							|  |  |  |         return *page; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dbgln("ConnectionFromClient::{}: Did not find a page with ID {}", location.function_name(), index); | 
					
						
							|  |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-30 19:12:22 -06:00
										 |  |  | void ConnectionFromClient::close_server() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     shutdown(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | Messages::WebContentServer::GetWindowHandleResponse ConnectionFromClient::get_window_handle(u64 page_id) | 
					
						
							| 
									
										
										
										
											2023-03-14 07:05:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         return page->page().top_level_traversable()->window_handle(); | 
					
						
							|  |  |  |     return String {}; | 
					
						
							| 
									
										
										
										
											2023-03-14 07:05:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_window_handle(u64 page_id, String handle) | 
					
						
							| 
									
										
										
										
											2023-03-16 17:36:36 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |         page->page().top_level_traversable()->set_window_handle(move(handle)); | 
					
						
							| 
									
										
										
										
											2023-03-16 17:36:36 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::connect_to_webdriver(u64 page_id, ByteString webdriver_ipc_path) | 
					
						
							| 
									
										
										
										
											2022-11-08 10:03:07 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) { | 
					
						
							|  |  |  |         // FIXME: Propagate this error back to the browser.
 | 
					
						
							|  |  |  |         if (auto result = page->connect_to_webdriver(webdriver_ipc_path); result.is_error()) | 
					
						
							|  |  |  |             dbgln("Unable to connect to the WebDriver process: {}", result.error()); | 
					
						
							| 
									
										
										
										
											2024-02-12 17:39:20 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-08 10:03:07 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-24 09:27:36 -04:00
										 |  |  | void ConnectionFromClient::connect_to_web_ui(u64 page_id, IPC::File web_ui_socket) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (auto page = this->page(page_id); page.has_value()) { | 
					
						
							|  |  |  |         // FIXME: Propagate this error back to the browser.
 | 
					
						
							|  |  |  |         if (auto result = page->connect_to_web_ui(move(web_ui_socket)); result.is_error()) | 
					
						
							|  |  |  |             dbgln("Unable to connect to the WebUI host: {}", result.error()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::connect_to_image_decoder(IPC::File image_decoder_socket) | 
					
						
							| 
									
										
										
										
											2024-06-26 13:44:42 -06:00
										 |  |  | { | 
					
						
							|  |  |  |     if (on_image_decoder_connection) | 
					
						
							|  |  |  |         on_image_decoder_connection(image_decoder_socket); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-09 13:07:57 -04:00
										 |  |  | void ConnectionFromClient::connect_to_request_server(IPC::File request_server_socket) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (on_request_server_connection) | 
					
						
							|  |  |  |         on_request_server_connection(request_server_socket); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::update_system_theme(u64 page_id, Core::AnonymousBuffer theme_buffer) | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-02-12 17:39:20 -07:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     Gfx::set_system_theme(theme_buffer); | 
					
						
							|  |  |  |     auto impl = Gfx::PaletteImpl::create_with_anonymous_buffer(theme_buffer); | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     page->set_palette_impl(*impl); | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::update_screen_rects(u64 page_id, Vector<Web::DevicePixelRect> rects, u32 main_screen) | 
					
						
							| 
									
										
										
										
											2021-04-04 00:12:37 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->set_screen_rects(rects, main_screen); | 
					
						
							| 
									
										
										
										
											2021-04-04 00:12:37 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::load_url(u64 page_id, URL::URL url) | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-02-12 17:39:20 -07:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-01-30 23:43:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     page->page().load(url); | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::load_html(u64 page_id, ByteString html) | 
					
						
							| 
									
										
										
										
											2020-10-08 21:11:01 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().load_html(html); | 
					
						
							| 
									
										
										
										
											2020-10-08 21:11:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-13 18:51:27 +02:00
										 |  |  | void ConnectionFromClient::reload(u64 page_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().reload(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-13 22:33:48 +02:00
										 |  |  | void ConnectionFromClient::traverse_the_history_by_delta(u64 page_id, i32 delta) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().traverse_the_history_by_delta(delta); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_viewport_size(u64 page_id, Web::DevicePixelSize size) | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-06-03 17:53:55 +03:00
										 |  |  |         page->set_viewport_size(size); | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::ready_to_paint(u64 page_id) | 
					
						
							| 
									
										
										
										
											2024-01-07 10:35:45 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->ready_to_paint(); | 
					
						
							| 
									
										
										
										
											2024-01-07 10:35:45 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::key_event(u64 page_id, Web::KeyEvent event) | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |     enqueue_input_event({ page_id, move(event), 0 }); | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::mouse_event(u64 page_id, Web::MouseEvent event) | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-05 17:06:32 -05:00
										 |  |  |     // OPTIMIZATION: Coalesce consecutive unprocessed mouse move and wheel events.
 | 
					
						
							| 
									
										
										
										
											2024-03-06 10:36:28 -05:00
										 |  |  |     auto event_to_coalesce = [&]() -> Web::MouseEvent const* { | 
					
						
							| 
									
										
										
										
											2024-03-05 17:06:32 -05:00
										 |  |  |         if (m_input_event_queue.is_empty()) | 
					
						
							| 
									
										
										
										
											2024-03-06 10:36:28 -05:00
										 |  |  |             return nullptr; | 
					
						
							|  |  |  |         if (m_input_event_queue.tail().page_id != page_id) | 
					
						
							|  |  |  |             return nullptr; | 
					
						
							| 
									
										
										
										
											2023-03-14 13:47:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-05 17:06:32 -05:00
										 |  |  |         if (event.type != Web::MouseEvent::Type::MouseMove && event.type != Web::MouseEvent::Type::MouseWheel) | 
					
						
							| 
									
										
										
										
											2024-03-06 10:36:28 -05:00
										 |  |  |             return nullptr; | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 10:36:28 -05:00
										 |  |  |         if (auto const* mouse_event = m_input_event_queue.tail().event.get_pointer<Web::MouseEvent>()) { | 
					
						
							|  |  |  |             if (mouse_event->type == event.type) | 
					
						
							|  |  |  |                 return mouse_event; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 10:36:28 -05:00
										 |  |  |         return nullptr; | 
					
						
							| 
									
										
										
										
											2023-08-04 20:52:43 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 10:36:28 -05:00
										 |  |  |     if (auto const* last_mouse_event = event_to_coalesce()) { | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |         event.wheel_delta_x += last_mouse_event->wheel_delta_x; | 
					
						
							|  |  |  |         event.wheel_delta_y += last_mouse_event->wheel_delta_y; | 
					
						
							| 
									
										
										
										
											2024-03-06 10:36:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |         m_input_event_queue.tail().event = move(event); | 
					
						
							| 
									
										
										
										
											2024-03-05 17:06:32 -05:00
										 |  |  |         ++m_input_event_queue.tail().coalesced_event_count; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-04 20:52:43 +02:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |     enqueue_input_event({ page_id, move(event), 0 }); | 
					
						
							| 
									
										
										
										
											2023-03-14 13:26:06 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::drag_event(u64 page_id, Web::DragEvent event) | 
					
						
							| 
									
										
										
										
											2024-08-17 13:36:28 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |     enqueue_input_event({ page_id, move(event), 0 }); | 
					
						
							| 
									
										
										
										
											2024-08-17 13:36:28 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-08 23:59:50 +02:00
										 |  |  | void ConnectionFromClient::pinch_event(u64 page_id, Web::PinchEvent event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enqueue_input_event({ page_id, move(event), 0 }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-14 23:25:12 +01:00
										 |  |  | void ConnectionFromClient::enqueue_input_event(Web::QueuedInputEvent event) | 
					
						
							| 
									
										
										
										
											2023-03-14 13:26:06 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     m_input_event_queue.enqueue(move(event)); | 
					
						
							| 
									
										
										
										
											2021-09-28 15:39:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::debug_request(u64 page_id, ByteString request, ByteString argument) | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-02-12 17:39:20 -07:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-14 20:19:41 +02:00
										 |  |  |     if (request == "dump-session-history") { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |         auto const& traversable = page->page().top_level_traversable(); | 
					
						
							| 
									
										
										
										
											2023-08-14 20:19:41 +02:00
										 |  |  |         Web::dump_tree(*traversable); | 
					
						
							| 
									
										
										
										
											2025-07-17 23:45:04 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-08-14 20:19:41 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-12 00:38:19 +02:00
										 |  |  |     if (request == "dump-display-list") { | 
					
						
							|  |  |  |         if (auto* doc = page->page().top_level_browsing_context().active_document()) { | 
					
						
							|  |  |  |             auto display_list_dump = doc->dump_display_list(); | 
					
						
							|  |  |  |             dbgln("{}", display_list_dump); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if (request == "dump-dom-tree") { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |         if (auto* doc = page->page().top_level_browsing_context().active_document()) | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  |             Web::dump_tree(*doc); | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if (request == "dump-layout-tree") { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |         if (auto* doc = page->page().top_level_browsing_context().active_document()) { | 
					
						
							| 
									
										
										
										
											2023-02-25 11:04:29 +01:00
										 |  |  |             if (auto* viewport = doc->layout_node()) | 
					
						
							|  |  |  |                 Web::dump_tree(*viewport); | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-18 20:22:58 +01:00
										 |  |  |     if (request == "dump-paint-tree") { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |         if (auto* doc = page->page().top_level_browsing_context().active_document()) { | 
					
						
							| 
									
										
										
										
											2023-03-18 20:22:58 +01:00
										 |  |  |             if (auto* paintable = doc->paintable()) | 
					
						
							|  |  |  |                 Web::dump_tree(*paintable); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-03-18 20:22:58 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-05 19:01:12 +01:00
										 |  |  |     if (request == "dump-stacking-context-tree") { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |         if (auto* doc = page->page().top_level_browsing_context().active_document()) { | 
					
						
							| 
									
										
										
										
											2023-02-25 11:04:29 +01:00
										 |  |  |             if (auto* viewport = doc->layout_node()) { | 
					
						
							| 
									
										
										
										
											2025-07-06 14:45:04 +02:00
										 |  |  |                 auto& viewport_paintable = static_cast<Web::Painting::ViewportPaintable&>(*viewport->paintable_box()); | 
					
						
							|  |  |  |                 viewport_paintable.build_stacking_context_tree_if_needed(); | 
					
						
							|  |  |  |                 if (auto* stacking_context = viewport_paintable.stacking_context()) { | 
					
						
							|  |  |  |                     StringBuilder builder; | 
					
						
							|  |  |  |                     stacking_context->dump(builder); | 
					
						
							|  |  |  |                     dbgln("{}", builder.string_view()); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-02-05 19:01:12 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2022-02-05 19:01:12 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if (request == "dump-style-sheets") { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |         if (auto* doc = page->page().top_level_browsing_context().active_document()) { | 
					
						
							| 
									
										
										
										
											2024-11-13 16:07:16 +00:00
										 |  |  |             dbgln("=== In document: ==="); | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  |             for (auto& sheet : doc->style_sheets().sheets()) { | 
					
						
							| 
									
										
										
										
											2024-10-15 11:35:01 +01:00
										 |  |  |                 Web::dump_sheet(sheet); | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-11-13 16:07:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             doc->for_each_shadow_root([&](auto& shadow_root) { | 
					
						
							|  |  |  |                 dbgln("=== In shadow root {}: ===", shadow_root.host()->debug_description()); | 
					
						
							|  |  |  |                 shadow_root.for_each_css_style_sheet([&](auto& sheet) { | 
					
						
							|  |  |  |                     Web::dump_sheet(sheet); | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 15:33:08 +03:30
										 |  |  |     if (request == "dump-all-resolved-styles") { | 
					
						
							| 
									
										
										
										
											2025-09-18 11:44:56 +01:00
										 |  |  |         auto dump_style = [](String const& title, Web::CSS::ComputedProperties const& style, OrderedHashMap<FlyString, Web::CSS::StyleProperty> const& custom_properties) { | 
					
						
							| 
									
										
										
										
											2025-07-07 14:52:05 +01:00
										 |  |  |             dbgln("+ {}", title); | 
					
						
							| 
									
										
										
										
											2025-08-24 15:38:14 +12:00
										 |  |  |             for (size_t i = to_underlying(Web::CSS::first_longhand_property_id); i < to_underlying(Web::CSS::last_longhand_property_id); ++i) { | 
					
						
							| 
									
										
										
										
											2025-08-25 16:55:07 +12:00
										 |  |  |                 dbgln("|  {} = {}", Web::CSS::string_from_property_id(static_cast<Web::CSS::PropertyID>(i)), style.property(static_cast<Web::CSS::PropertyID>(i)).to_string(Web::CSS::SerializationMode::Normal)); | 
					
						
							| 
									
										
										
										
											2025-07-07 14:52:05 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             for (auto const& [name, property] : custom_properties) { | 
					
						
							|  |  |  |                 dbgln("|  {} = {}", name, property.value->to_string(Web::CSS::SerializationMode::Normal)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             dbgln("---"); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |         if (auto* doc = page->page().top_level_browsing_context().active_document()) { | 
					
						
							| 
									
										
										
										
											2025-07-07 14:52:05 +01:00
										 |  |  |             Queue<Web::DOM::Node*> nodes_to_visit; | 
					
						
							|  |  |  |             nodes_to_visit.enqueue(doc->document_element()); | 
					
						
							|  |  |  |             while (!nodes_to_visit.is_empty()) { | 
					
						
							|  |  |  |                 auto node = nodes_to_visit.dequeue(); | 
					
						
							|  |  |  |                 for (auto& child : node->children_as_vector()) | 
					
						
							|  |  |  |                     nodes_to_visit.enqueue(child.ptr()); | 
					
						
							|  |  |  |                 if (auto* element = as_if<Web::DOM::Element>(node)) { | 
					
						
							| 
									
										
										
										
											2025-09-05 14:56:12 +01:00
										 |  |  |                     auto styles = doc->style_computer().compute_style({ *element }); | 
					
						
							| 
									
										
										
										
											2025-07-07 14:52:05 +01:00
										 |  |  |                     dump_style(MUST(String::formatted("Element {}", node->debug_description())), styles, element->custom_properties({})); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     for (auto pseudo_element_index = 0; pseudo_element_index < to_underlying(Web::CSS::PseudoElement::KnownPseudoElementCount); ++pseudo_element_index) { | 
					
						
							|  |  |  |                         auto pseudo_element_type = static_cast<Web::CSS::PseudoElement>(pseudo_element_index); | 
					
						
							|  |  |  |                         if (auto pseudo_element = element->get_pseudo_element(pseudo_element_type); pseudo_element.has_value() && pseudo_element->computed_properties()) { | 
					
						
							|  |  |  |                             dump_style(MUST(String::formatted("PseudoElement {}::{}", node->debug_description(), Web::CSS::pseudo_element_name(pseudo_element_type))), *pseudo_element->computed_properties(), pseudo_element->custom_properties()); | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2024-08-02 13:59:19 +02:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2023-05-27 15:33:08 +03:30
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-05-27 15:33:08 +03:30
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-23 11:29:03 +01:00
										 |  |  |     if (request == "dump-all-css-errors") { | 
					
						
							|  |  |  |         Web::CSS::Parser::ErrorReporter::the().dump(); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if (request == "collect-garbage") { | 
					
						
							| 
									
										
										
										
											2024-11-10 15:14:12 +01:00
										 |  |  |         // NOTE: We use deferred_invoke here to ensure that GC runs with as little on the stack as possible.
 | 
					
						
							|  |  |  |         Core::deferred_invoke([] { | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  |             Web::Bindings::main_thread_vm().heap().collect_garbage(GC::Heap::CollectionType::CollectGarbage, true); | 
					
						
							| 
									
										
										
										
											2024-11-10 15:14:12 +01:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if (request == "set-line-box-borders") { | 
					
						
							|  |  |  |         bool state = argument == "on"; | 
					
						
							| 
									
										
										
										
											2025-06-26 22:33:58 +02:00
										 |  |  |         auto traversable = page->page().top_level_traversable(); | 
					
						
							|  |  |  |         traversable->set_should_show_line_box_borders(state); | 
					
						
							|  |  |  |         traversable->set_needs_repaint(); | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-03-29 15:31:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if (request == "clear-cache") { | 
					
						
							| 
									
										
										
										
											2021-03-29 15:31:09 -04:00
										 |  |  |         Web::ResourceLoader::the().clear_cache(); | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-03-29 15:31:09 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-04-14 15:13:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if (request == "spoof-user-agent") { | 
					
						
							| 
									
										
										
										
											2023-12-16 17:49:34 +03:30
										 |  |  |         Web::ResourceLoader::the().set_user_agent(MUST(String::from_byte_string(argument))); | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-04-14 15:13:51 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-12 02:10:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-30 23:29:15 +01:00
										 |  |  |     if (request == "scripting") { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |         page->page().set_is_scripting_enabled(argument == "on"); | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2022-03-30 23:29:15 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-15 02:01:13 +02:00
										 |  |  |     if (request == "block-pop-ups") { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |         page->page().set_should_block_pop_ups(argument == "on"); | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2022-11-15 02:01:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 19:50:14 +01:00
										 |  |  |     if (request == "dump-local-storage") { | 
					
						
							| 
									
										
										
										
											2025-07-17 23:45:04 +02:00
										 |  |  |         if (auto* document = page->page().top_level_browsing_context().active_document()) { | 
					
						
							|  |  |  |             auto storage_or_error = document->window()->local_storage(); | 
					
						
							|  |  |  |             if (storage_or_error.is_error()) | 
					
						
							|  |  |  |                 dbgln("Failed to retrieve local storage: {}", storage_or_error.release_error()); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 storage_or_error.release_value()->dump(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-12 15:12:17 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2022-02-08 19:50:14 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-12 16:36:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-02 19:28:39 +01:00
										 |  |  |     if (request == "navigator-compatibility-mode") { | 
					
						
							|  |  |  |         Web::NavigatorCompatibilityMode compatibility_mode; | 
					
						
							|  |  |  |         if (argument == "chrome") { | 
					
						
							|  |  |  |             compatibility_mode = Web::NavigatorCompatibilityMode::Chrome; | 
					
						
							|  |  |  |         } else if (argument == "gecko") { | 
					
						
							|  |  |  |             compatibility_mode = Web::NavigatorCompatibilityMode::Gecko; | 
					
						
							|  |  |  |         } else if (argument == "webkit") { | 
					
						
							|  |  |  |             compatibility_mode = Web::NavigatorCompatibilityMode::WebKit; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             dbgln("Unknown navigator compatibility mode '{}', defaulting to Chrome", argument); | 
					
						
							|  |  |  |             compatibility_mode = Web::NavigatorCompatibilityMode::Chrome; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Web::ResourceLoader::the().set_navigator_compatibility_mode(compatibility_mode); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-03-06 17:54:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (request == "content-filtering") { | 
					
						
							|  |  |  |         Web::ContentFilter::the().set_filtering_enabled(argument == "on"); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-31 09:06:25 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::get_source(u64 page_id) | 
					
						
							| 
									
										
										
										
											2021-02-23 06:14:12 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) { | 
					
						
							|  |  |  |         if (auto* doc = page->page().top_level_browsing_context().active_document()) | 
					
						
							| 
									
										
										
										
											2024-10-18 17:20:15 -04:00
										 |  |  |             async_did_get_source(page_id, doc->url(), doc->base_url(), doc->source()); | 
					
						
							| 
									
										
										
										
											2021-02-23 06:14:12 -06:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::inspect_dom_tree(u64 page_id) | 
					
						
							| 
									
										
										
										
											2021-06-07 16:35:10 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) { | 
					
						
							|  |  |  |         if (auto* doc = page->page().top_level_browsing_context().active_document()) | 
					
						
							| 
									
										
										
										
											2025-02-21 11:51:05 -05:00
										 |  |  |             async_did_inspect_dom_tree(page_id, doc->dump_dom_tree_as_json()); | 
					
						
							| 
									
										
										
										
											2021-06-07 16:35:10 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-20 16:56:46 +00:00
										 |  |  | void ConnectionFromClient::inspect_dom_node(u64 page_id, WebView::DOMNodeProperties::Type property_type, Web::UniqueNodeID node_id, Optional<Web::CSS::PseudoElement> pseudo_element) | 
					
						
							| 
									
										
										
										
											2021-08-27 12:31:55 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-02-12 17:39:20 -07:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |     clear_inspected_dom_node(page_id); | 
					
						
							| 
									
										
										
										
											2021-08-27 12:31:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-20 10:37:44 +02:00
										 |  |  |     auto* node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |     // Nodes without layout (aka non-visible nodes) don't have style computed.
 | 
					
						
							|  |  |  |     if (!node || !node->layout_node() || !node->is_element()) { | 
					
						
							|  |  |  |         async_did_inspect_dom_node(page_id, { property_type, {} }); | 
					
						
							| 
									
										
										
										
											2023-12-30 09:30:27 -05:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-11-24 20:05:39 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-27 12:31:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |     auto& element = as<Web::DOM::Element>(*node); | 
					
						
							| 
									
										
										
										
											2025-02-21 09:34:02 -05:00
										 |  |  |     node->document().set_inspected_node(node); | 
					
						
							| 
									
										
										
										
											2021-08-27 12:31:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-18 19:34:58 +02:00
										 |  |  |     auto properties = element.computed_properties(pseudo_element); | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!properties) { | 
					
						
							|  |  |  |         async_did_inspect_dom_node(page_id, { property_type, {} }); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto serialize_computed_style = [&]() { | 
					
						
							|  |  |  |         JsonObject serialized; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         properties->for_each_property([&](auto property_id, auto& value) { | 
					
						
							|  |  |  |             serialized.set( | 
					
						
							|  |  |  |                 Web::CSS::string_from_property_id(property_id), | 
					
						
							| 
									
										
										
										
											2025-05-16 19:20:24 +01:00
										 |  |  |                 value.to_string(Web::CSS::SerializationMode::Normal)); | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-26 14:31:57 +01:00
										 |  |  |         // FIXME: Custom properties are not yet included in ComputedProperties, so add them manually.
 | 
					
						
							|  |  |  |         auto custom_properties = element.custom_properties(pseudo_element); | 
					
						
							|  |  |  |         for (auto const& [name, value] : custom_properties) { | 
					
						
							|  |  |  |             serialized.set(name, value.value->to_string(Web::CSS::SerializationMode::Normal)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         return serialized; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto serialize_layout = [&](Web::Layout::Node const* layout_node) { | 
					
						
							|  |  |  |         if (!layout_node || !layout_node->is_box() || !layout_node->first_paintable() || !layout_node->first_paintable()->is_paintable_box()) { | 
					
						
							|  |  |  |             return JsonObject {}; | 
					
						
							| 
									
										
										
										
											2023-12-30 09:30:27 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-08-27 12:31:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         auto const& paintable_box = as<Web::Painting::PaintableBox>(*layout_node->first_paintable()); | 
					
						
							|  |  |  |         auto const& box_model = paintable_box.box_model(); | 
					
						
							| 
									
										
										
										
											2021-08-27 12:31:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         JsonObject serialized; | 
					
						
							| 
									
										
										
										
											2021-12-08 11:51:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         serialized.set("width"sv, paintable_box.content_width().to_double()); | 
					
						
							|  |  |  |         serialized.set("height"sv, paintable_box.content_height().to_double()); | 
					
						
							| 
									
										
										
										
											2021-12-08 11:51:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         serialized.set("padding-top"sv, box_model.padding.top.to_double()); | 
					
						
							|  |  |  |         serialized.set("padding-right"sv, box_model.padding.right.to_double()); | 
					
						
							|  |  |  |         serialized.set("padding-bottom"sv, box_model.padding.bottom.to_double()); | 
					
						
							|  |  |  |         serialized.set("padding-left"sv, box_model.padding.left.to_double()); | 
					
						
							| 
									
										
										
										
											2025-03-08 10:41:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         serialized.set("margin-top"sv, box_model.margin.top.to_double()); | 
					
						
							|  |  |  |         serialized.set("margin-right"sv, box_model.margin.right.to_double()); | 
					
						
							|  |  |  |         serialized.set("margin-bottom"sv, box_model.margin.bottom.to_double()); | 
					
						
							|  |  |  |         serialized.set("margin-left"sv, box_model.margin.left.to_double()); | 
					
						
							| 
									
										
										
										
											2021-12-08 11:51:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         serialized.set("border-top-width"sv, box_model.border.top.to_double()); | 
					
						
							|  |  |  |         serialized.set("border-right-width"sv, box_model.border.right.to_double()); | 
					
						
							|  |  |  |         serialized.set("border-bottom-width"sv, box_model.border.bottom.to_double()); | 
					
						
							|  |  |  |         serialized.set("border-left-width"sv, box_model.border.left.to_double()); | 
					
						
							| 
									
										
										
										
											2022-03-04 16:29:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-16 19:20:24 +01:00
										 |  |  |         serialized.set("box-sizing"sv, properties->property(Web::CSS::PropertyID::BoxSizing).to_string(Web::CSS::SerializationMode::Normal)); | 
					
						
							|  |  |  |         serialized.set("display"sv, properties->property(Web::CSS::PropertyID::Display).to_string(Web::CSS::SerializationMode::Normal)); | 
					
						
							|  |  |  |         serialized.set("float"sv, properties->property(Web::CSS::PropertyID::Float).to_string(Web::CSS::SerializationMode::Normal)); | 
					
						
							|  |  |  |         serialized.set("line-height"sv, properties->property(Web::CSS::PropertyID::LineHeight).to_string(Web::CSS::SerializationMode::Normal)); | 
					
						
							|  |  |  |         serialized.set("position"sv, properties->property(Web::CSS::PropertyID::Position).to_string(Web::CSS::SerializationMode::Normal)); | 
					
						
							|  |  |  |         serialized.set("z-index"sv, properties->property(Web::CSS::PropertyID::ZIndex).to_string(Web::CSS::SerializationMode::Normal)); | 
					
						
							| 
									
										
										
										
											2022-03-04 16:29:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         return serialized; | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2025-02-10 15:18:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |     auto serialize_used_fonts = [&]() { | 
					
						
							|  |  |  |         JsonArray serialized; | 
					
						
							| 
									
										
										
										
											2025-02-10 15:18:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         properties->computed_font_list().for_each_font_entry([&](Gfx::FontCascadeList::Entry const& entry) { | 
					
						
							|  |  |  |             auto const& font = *entry.font; | 
					
						
							| 
									
										
										
										
											2022-03-04 16:29:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |             JsonObject font_object; | 
					
						
							|  |  |  |             font_object.set("name"sv, font.family().to_string()); | 
					
						
							|  |  |  |             font_object.set("size"sv, font.point_size()); | 
					
						
							|  |  |  |             font_object.set("weight"sv, font.weight()); | 
					
						
							|  |  |  |             serialized.must_append(move(font_object)); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2023-12-30 09:30:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |         return serialized; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     JsonValue serialized; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (property_type) { | 
					
						
							|  |  |  |     case WebView::DOMNodeProperties::Type::ComputedStyle: | 
					
						
							|  |  |  |         serialized = serialize_computed_style(); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case WebView::DOMNodeProperties::Type::Layout: | 
					
						
							|  |  |  |         serialized = serialize_layout(element.layout_node()); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case WebView::DOMNodeProperties::Type::UsedFonts: | 
					
						
							|  |  |  |         serialized = serialize_used_fonts(); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-08-27 12:31:55 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 15:50:56 -04:00
										 |  |  |     async_did_inspect_dom_node(page_id, { property_type, move(serialized) }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ConnectionFromClient::clear_inspected_dom_node(u64 page_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (auto& navigable : Web::HTML::all_navigables()) { | 
					
						
							|  |  |  |         if (navigable->active_document() != nullptr) { | 
					
						
							|  |  |  |             navigable->active_document()->set_inspected_node(nullptr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-27 12:31:55 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-20 16:56:46 +00:00
										 |  |  | void ConnectionFromClient::highlight_dom_node(u64 page_id, Web::UniqueNodeID node_id, Optional<Web::CSS::PseudoElement> pseudo_element) | 
					
						
							| 
									
										
										
										
											2025-02-21 09:34:02 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (auto& navigable : Web::HTML::all_navigables()) { | 
					
						
							|  |  |  |         if (navigable->active_document() != nullptr) { | 
					
						
							|  |  |  |             navigable->active_document()->set_highlighted_node(nullptr, {}); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							|  |  |  |     if (!node || !node->layout_node()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     node->document().set_highlighted_node(node, pseudo_element); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::inspect_accessibility_tree(u64 page_id) | 
					
						
							| 
									
										
										
										
											2023-12-30 09:06:22 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) { | 
					
						
							|  |  |  |         if (auto* doc = page->page().top_level_browsing_context().active_document()) | 
					
						
							| 
									
										
										
										
											2025-02-21 11:51:05 -05:00
										 |  |  |             async_did_inspect_accessibility_tree(page_id, doc->dump_accessibility_tree_as_json()); | 
					
						
							| 
									
										
										
										
											2023-12-30 09:06:22 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::get_hovered_node_id(u64 page_id) | 
					
						
							| 
									
										
										
										
											2021-08-27 17:33:10 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-02-12 17:39:20 -07:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-20 10:37:44 +02:00
										 |  |  |     Web::UniqueNodeID node_id = 0; | 
					
						
							| 
									
										
										
										
											2023-12-30 09:42:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto* document = page->page().top_level_browsing_context().active_document()) { | 
					
						
							| 
									
										
										
										
											2023-12-30 09:42:24 -05:00
										 |  |  |         if (auto* hovered_node = document->hovered_node()) | 
					
						
							|  |  |  |             node_id = hovered_node->unique_id(); | 
					
						
							| 
									
										
										
										
											2021-08-27 17:33:10 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-30 09:42:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |     async_did_get_hovered_node_id(page_id, node_id); | 
					
						
							| 
									
										
										
										
											2021-08-27 17:33:10 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 11:18:35 +01:00
										 |  |  | void ConnectionFromClient::list_style_sheets(u64 page_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-14 16:22:16 -04:00
										 |  |  |     async_did_list_style_sheets(page_id, page->list_style_sheets()); | 
					
						
							| 
									
										
										
										
											2024-08-23 11:18:35 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::request_style_sheet_source(u64 page_id, Web::CSS::StyleSheetIdentifier identifier) | 
					
						
							| 
									
										
										
										
											2024-08-23 11:18:35 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (auto* document = page->page().top_level_browsing_context().active_document()) { | 
					
						
							| 
									
										
										
										
											2024-10-18 17:20:15 -04:00
										 |  |  |         if (auto stylesheet = document->get_style_sheet_source(identifier); stylesheet.has_value()) | 
					
						
							|  |  |  |             async_did_get_style_sheet_source(page_id, identifier, document->base_url(), stylesheet.value()); | 
					
						
							| 
									
										
										
										
											2024-08-23 11:18:35 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-06 17:32:43 -05:00
										 |  |  | void ConnectionFromClient::set_listen_for_dom_mutations(u64 page_id, bool listen_for_dom_mutations) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     page->page().set_listen_for_dom_mutations(listen_for_dom_mutations); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-10 18:15:31 -04:00
										 |  |  | void ConnectionFromClient::get_dom_node_inner_html(u64 page_id, Web::UniqueNodeID node_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							|  |  |  |     if (!dom_node) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     String html; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (dom_node->is_element()) { | 
					
						
							|  |  |  |         auto const& element = static_cast<Web::DOM::Element const&>(*dom_node); | 
					
						
							|  |  |  |         html = element.inner_html().release_value_but_fixme_should_propagate_errors(); | 
					
						
							|  |  |  |     } else if (dom_node->is_text() || dom_node->is_comment()) { | 
					
						
							|  |  |  |         auto const& character_data = static_cast<Web::DOM::CharacterData const&>(*dom_node); | 
					
						
							| 
									
										
										
										
											2025-07-24 12:05:52 -04:00
										 |  |  |         html = character_data.data().to_utf8_but_should_be_ported_to_utf16(); | 
					
						
							| 
									
										
										
										
											2025-03-10 18:15:31 -04:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async_did_get_dom_node_html(page_id, html); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-10 17:36:41 -04:00
										 |  |  | void ConnectionFromClient::get_dom_node_outer_html(u64 page_id, Web::UniqueNodeID node_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							|  |  |  |     if (!dom_node) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     String html; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (dom_node->is_element()) { | 
					
						
							|  |  |  |         auto const& element = static_cast<Web::DOM::Element const&>(*dom_node); | 
					
						
							|  |  |  |         html = element.outer_html().release_value_but_fixme_should_propagate_errors(); | 
					
						
							|  |  |  |     } else if (dom_node->is_text() || dom_node->is_comment()) { | 
					
						
							|  |  |  |         auto const& character_data = static_cast<Web::DOM::CharacterData const&>(*dom_node); | 
					
						
							| 
									
										
										
										
											2025-07-24 12:05:52 -04:00
										 |  |  |         html = character_data.data().to_utf8_but_should_be_ported_to_utf16(); | 
					
						
							| 
									
										
										
										
											2025-03-10 17:36:41 -04:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async_did_get_dom_node_html(page_id, html); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ConnectionFromClient::set_dom_node_outer_html(u64 page_id, Web::UniqueNodeID node_id, String html) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							|  |  |  |     if (!dom_node) { | 
					
						
							|  |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (dom_node->is_element()) { | 
					
						
							|  |  |  |         auto& element = static_cast<Web::DOM::Element&>(*dom_node); | 
					
						
							|  |  |  |         element.set_outer_html(html).release_value_but_fixme_should_propagate_errors(); | 
					
						
							|  |  |  |     } else if (dom_node->is_text() || dom_node->is_comment()) { | 
					
						
							|  |  |  |         auto& character_data = static_cast<Web::DOM::CharacterData&>(*dom_node); | 
					
						
							| 
									
										
										
										
											2025-07-24 12:05:52 -04:00
										 |  |  |         character_data.set_data(Utf16String::from_utf8(html)); | 
					
						
							| 
									
										
										
										
											2025-03-10 17:36:41 -04:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async_did_finish_editing_dom_node(page_id, node_id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_dom_node_text(u64 page_id, Web::UniqueNodeID node_id, String text) | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     if (!dom_node || (!dom_node->is_text() && !dom_node->is_comment())) { | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto& character_data = static_cast<Web::DOM::CharacterData&>(*dom_node); | 
					
						
							| 
									
										
										
										
											2025-07-24 12:05:52 -04:00
										 |  |  |     character_data.set_data(Utf16String::from_utf8(text)); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |     async_did_finish_editing_dom_node(page_id, character_data.unique_id()); | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_dom_node_tag(u64 page_id, Web::UniqueNodeID node_id, String name) | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     if (!dom_node || !dom_node->is_element() || !dom_node->parent()) { | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto& element = static_cast<Web::DOM::Element&>(*dom_node); | 
					
						
							|  |  |  |     auto new_element = Web::DOM::create_element(element.document(), name, element.namespace_uri(), element.prefix(), element.is_value()).release_value_but_fixme_should_propagate_errors(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     element.for_each_attribute([&](auto const& attribute) { | 
					
						
							| 
									
										
										
										
											2024-01-03 12:47:38 +13:00
										 |  |  |         new_element->set_attribute_value(attribute.local_name(), attribute.value(), attribute.prefix(), attribute.namespace_uri()); | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (auto* child_node = element.first_child()) { | 
					
						
							|  |  |  |         MUST(element.remove_child(*child_node)); | 
					
						
							|  |  |  |         MUST(new_element->append_child(*child_node)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     element.parent()->replace_child(*new_element, element).release_value_but_fixme_should_propagate_errors(); | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |     async_did_finish_editing_dom_node(page_id, new_element->unique_id()); | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::add_dom_node_attributes(u64 page_id, Web::UniqueNodeID node_id, Vector<WebView::Attribute> attributes) | 
					
						
							| 
									
										
										
										
											2023-12-05 16:49:47 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     if (!dom_node || !dom_node->is_element()) { | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							| 
									
										
										
										
											2023-12-05 16:49:47 -05:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-05 16:49:47 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto& element = static_cast<Web::DOM::Element&>(*dom_node); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 17:27:43 -04:00
										 |  |  |     for (auto const& attribute : attributes) { | 
					
						
							|  |  |  |         // NOTE: We ignore invalid attributes for now, but we may want to send feedback to the user that this failed.
 | 
					
						
							|  |  |  |         (void)element.set_attribute(attribute.name, attribute.value); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |     async_did_finish_editing_dom_node(page_id, element.unique_id()); | 
					
						
							| 
									
										
										
										
											2023-12-05 16:49:47 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::replace_dom_node_attribute(u64 page_id, Web::UniqueNodeID node_id, String name, Vector<WebView::Attribute> replacement_attributes) | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     if (!dom_node || !dom_node->is_element()) { | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto& element = static_cast<Web::DOM::Element&>(*dom_node); | 
					
						
							| 
									
										
										
										
											2023-12-05 16:54:53 -05:00
										 |  |  |     bool should_remove_attribute = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (auto const& attribute : replacement_attributes) { | 
					
						
							| 
									
										
										
										
											2025-05-18 15:04:56 +12:00
										 |  |  |         if (should_remove_attribute && name.equals_ignoring_ascii_case(attribute.name)) | 
					
						
							| 
									
										
										
										
											2023-12-05 16:54:53 -05:00
										 |  |  |             should_remove_attribute = false; | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 17:27:43 -04:00
										 |  |  |         // NOTE: We ignore invalid attributes for now, but we may want to send feedback to the user that this failed.
 | 
					
						
							|  |  |  |         (void)element.set_attribute(attribute.name, attribute.value); | 
					
						
							| 
									
										
										
										
											2023-12-05 16:54:53 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (should_remove_attribute) | 
					
						
							|  |  |  |         element.remove_attribute(name); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |     async_did_finish_editing_dom_node(page_id, element.unique_id()); | 
					
						
							| 
									
										
										
										
											2023-11-19 10:42:11 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::create_child_element(u64 page_id, Web::UniqueNodeID node_id) | 
					
						
							| 
									
										
										
										
											2023-12-07 11:00:57 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     if (!dom_node) { | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-07 11:00:57 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto element = Web::DOM::create_element(dom_node->document(), Web::HTML::TagNames::div, Web::Namespace::HTML).release_value_but_fixme_should_propagate_errors(); | 
					
						
							|  |  |  |     dom_node->append_child(element).release_value_but_fixme_should_propagate_errors(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |     async_did_finish_editing_dom_node(page_id, element->unique_id()); | 
					
						
							| 
									
										
										
										
											2023-12-07 11:00:57 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::create_child_text_node(u64 page_id, Web::UniqueNodeID node_id) | 
					
						
							| 
									
										
										
										
											2023-12-07 11:00:57 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     if (!dom_node) { | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-07 11:00:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 12:05:52 -04:00
										 |  |  |     auto text_node = dom_node->realm().create<Web::DOM::Text>(dom_node->document(), "text"_utf16); | 
					
						
							| 
									
										
										
										
											2023-12-07 11:00:57 -05:00
										 |  |  |     dom_node->append_child(text_node).release_value_but_fixme_should_propagate_errors(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |     async_did_finish_editing_dom_node(page_id, text_node->unique_id()); | 
					
						
							| 
									
										
										
										
											2023-12-07 11:00:57 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-10 18:01:29 -04:00
										 |  |  | void ConnectionFromClient::insert_dom_node_before(u64 page_id, Web::UniqueNodeID node_id, Web::UniqueNodeID parent_node_id, Optional<Web::UniqueNodeID> sibling_node_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							|  |  |  |     auto* parent_dom_node = Web::DOM::Node::from_unique_id(parent_node_id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!dom_node || !parent_dom_node) { | 
					
						
							|  |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GC::Ptr<Web::DOM::Node> sibling_dom_node; | 
					
						
							|  |  |  |     if (sibling_node_id.has_value()) { | 
					
						
							|  |  |  |         sibling_dom_node = Web::DOM::Node::from_unique_id(*sibling_node_id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!sibling_dom_node) { | 
					
						
							|  |  |  |             async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     parent_dom_node->insert_before(*dom_node, sibling_dom_node); | 
					
						
							|  |  |  |     async_did_finish_editing_dom_node(page_id, dom_node->unique_id()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::clone_dom_node(u64 page_id, Web::UniqueNodeID node_id) | 
					
						
							| 
									
										
										
										
											2023-12-07 11:12:43 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     if (!dom_node || !dom_node->parent_node()) { | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-07 11:12:43 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-25 11:06:41 +02:00
										 |  |  |     auto dom_node_clone = MUST(dom_node->clone_node(nullptr, true)); | 
					
						
							| 
									
										
										
										
											2023-12-07 11:12:43 -05:00
										 |  |  |     dom_node->parent_node()->insert_before(dom_node_clone, dom_node->next_sibling()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |     async_did_finish_editing_dom_node(page_id, dom_node_clone->unique_id()); | 
					
						
							| 
									
										
										
										
											2023-12-07 11:12:43 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::remove_dom_node(u64 page_id, Web::UniqueNodeID node_id) | 
					
						
							| 
									
										
										
										
											2023-12-05 14:59:54 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-02-12 17:39:20 -07:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     auto* active_document = page->page().top_level_browsing_context().active_document(); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     if (!active_document) { | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							| 
									
										
										
										
											2023-12-05 14:59:54 -05:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-05 14:59:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto* dom_node = Web::DOM::Node::from_unique_id(node_id); | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     if (!dom_node) { | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |         async_did_finish_editing_dom_node(page_id, {}); | 
					
						
							| 
									
										
										
										
											2023-12-05 14:59:54 -05:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-12-30 10:08:33 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* previous_dom_node = dom_node->previous_sibling(); | 
					
						
							|  |  |  |     if (!previous_dom_node) | 
					
						
							|  |  |  |         previous_dom_node = dom_node->parent(); | 
					
						
							| 
									
										
										
										
											2023-12-05 14:59:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     dom_node->remove(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |     async_did_finish_editing_dom_node(page_id, previous_dom_node->unique_id()); | 
					
						
							| 
									
										
										
										
											2023-12-05 14:59:54 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::take_document_screenshot(u64 page_id) | 
					
						
							| 
									
										
										
										
											2023-09-17 16:11:16 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-02-12 17:39:20 -07:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-21 19:15:32 +03:00
										 |  |  |     page->queue_screenshot_task({}); | 
					
						
							| 
									
										
										
										
											2022-11-05 00:09:41 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::take_dom_node_screenshot(u64 page_id, Web::UniqueNodeID node_id) | 
					
						
							| 
									
										
										
										
											2023-12-06 11:51:44 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-02-12 17:39:20 -07:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-21 19:15:32 +03:00
										 |  |  |     page->queue_screenshot_task(node_id); | 
					
						
							| 
									
										
										
										
											2023-12-06 11:51:44 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-19 10:40:00 -04:00
										 |  |  | static void append_page_text(Web::Page& page, StringBuilder& builder) | 
					
						
							| 
									
										
										
										
											2023-12-12 13:25:06 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-19 10:40:00 -04:00
										 |  |  |     auto* document = page.top_level_browsing_context().active_document(); | 
					
						
							|  |  |  |     if (!document) { | 
					
						
							|  |  |  |         builder.append("(no DOM tree)"sv); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* body = document->body(); | 
					
						
							|  |  |  |     if (!body) { | 
					
						
							|  |  |  |         builder.append("(no body)"sv); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     builder.append(body->inner_text()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void append_layout_tree(Web::Page& page, StringBuilder& builder) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto* document = page.top_level_browsing_context().active_document(); | 
					
						
							|  |  |  |     if (!document) { | 
					
						
							|  |  |  |         builder.append("(no DOM tree)"sv); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-05 20:50:05 +01:00
										 |  |  |     document->update_layout(Web::DOM::UpdateLayoutReason::Debugging); | 
					
						
							| 
									
										
										
										
											2024-09-19 10:40:00 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto* layout_root = document->layout_node(); | 
					
						
							|  |  |  |     if (!layout_root) { | 
					
						
							|  |  |  |         builder.append("(no layout tree)"sv); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Web::dump_tree(builder, *layout_root); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void append_paint_tree(Web::Page& page, StringBuilder& builder) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto* document = page.top_level_browsing_context().active_document(); | 
					
						
							|  |  |  |     if (!document) { | 
					
						
							|  |  |  |         builder.append("(no DOM tree)"sv); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-05 20:50:05 +01:00
										 |  |  |     document->update_layout(Web::DOM::UpdateLayoutReason::Debugging); | 
					
						
							| 
									
										
										
										
											2024-09-19 10:40:00 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto* layout_root = document->layout_node(); | 
					
						
							|  |  |  |     if (!layout_root) { | 
					
						
							|  |  |  |         builder.append("(no layout tree)"sv); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-16 15:19:32 +02:00
										 |  |  |     if (!layout_root->first_paintable()) { | 
					
						
							| 
									
										
										
										
											2024-09-19 10:40:00 -04:00
										 |  |  |         builder.append("(no paint tree)"sv); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-16 15:19:32 +02:00
										 |  |  |     Web::dump_tree(builder, *layout_root->first_paintable()); | 
					
						
							| 
									
										
										
										
											2024-09-19 10:40:00 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-06 14:45:04 +02:00
										 |  |  | static void append_stacking_context_tree(Web::Page& page, StringBuilder& builder) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto* document = page.top_level_browsing_context().active_document(); | 
					
						
							|  |  |  |     if (!document) { | 
					
						
							|  |  |  |         builder.append("(no DOM tree)"sv); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     document->update_layout(Web::DOM::UpdateLayoutReason::Debugging); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* layout_root = document->layout_node(); | 
					
						
							|  |  |  |     if (!layout_root) { | 
					
						
							|  |  |  |         builder.append("(no layout tree)"sv); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!layout_root->first_paintable()) { | 
					
						
							|  |  |  |         builder.append("(no paint tree)"sv); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto& viewport_paintable = static_cast<Web::Painting::ViewportPaintable&>(*layout_root->paintable_box()); | 
					
						
							|  |  |  |     viewport_paintable.build_stacking_context_tree_if_needed(); | 
					
						
							|  |  |  |     if (auto* stacking_context = viewport_paintable.stacking_context()) { | 
					
						
							|  |  |  |         stacking_context->dump(builder); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-19 10:40:00 -04:00
										 |  |  | static void append_gc_graph(StringBuilder& builder) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto gc_graph = Web::Bindings::main_thread_vm().heap().dump_graph(); | 
					
						
							|  |  |  |     gc_graph.serialize(builder); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ConnectionFromClient::request_internal_page_info(u64 page_id, WebView::PageInfoType type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) { | 
					
						
							|  |  |  |         async_did_get_internal_page_info(page_id, type, "(no page)"_string); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     StringBuilder builder; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (has_flag(type, WebView::PageInfoType::Text)) { | 
					
						
							|  |  |  |         append_page_text(page->page(), builder); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (has_flag(type, WebView::PageInfoType::LayoutTree)) { | 
					
						
							|  |  |  |         if (!builder.is_empty()) | 
					
						
							|  |  |  |             builder.append("\n"sv); | 
					
						
							|  |  |  |         append_layout_tree(page->page(), builder); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (has_flag(type, WebView::PageInfoType::PaintTree)) { | 
					
						
							|  |  |  |         if (!builder.is_empty()) | 
					
						
							|  |  |  |             builder.append("\n"sv); | 
					
						
							|  |  |  |         append_paint_tree(page->page(), builder); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-06 14:45:04 +02:00
										 |  |  |     if (has_flag(type, WebView::PageInfoType::StackingContextTree)) { | 
					
						
							|  |  |  |         if (!builder.is_empty()) | 
					
						
							|  |  |  |             builder.append("\n"sv); | 
					
						
							|  |  |  |         append_stacking_context_tree(page->page(), builder); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-19 10:40:00 -04:00
										 |  |  |     if (has_flag(type, WebView::PageInfoType::GCGraph)) { | 
					
						
							|  |  |  |         if (!builder.is_empty()) | 
					
						
							|  |  |  |             builder.append("\n"sv); | 
					
						
							|  |  |  |         append_gc_graph(builder); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async_did_get_internal_page_info(page_id, type, MUST(builder.to_string())); | 
					
						
							| 
									
										
										
										
											2023-12-12 13:25:06 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | Messages::WebContentServer::GetSelectedTextResponse ConnectionFromClient::get_selected_text(u64 page_id) | 
					
						
							| 
									
										
										
										
											2021-07-14 08:32:55 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-04-26 16:59:04 +02:00
										 |  |  |         return page->page().focused_navigable().selected_text().to_byte_string(); | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     return ByteString {}; | 
					
						
							| 
									
										
										
										
											2021-07-14 08:32:55 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::select_all(u64 page_id) | 
					
						
							| 
									
										
										
										
											2021-07-14 08:53:55 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-04-26 16:59:04 +02:00
										 |  |  |         page->page().focused_navigable().select_all(); | 
					
						
							| 
									
										
										
										
											2021-07-14 08:53:55 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::find_in_page(u64 page_id, String query, CaseSensitivity case_sensitivity) | 
					
						
							| 
									
										
										
										
											2024-05-29 20:09:33 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-14 16:56:38 +01:00
										 |  |  |     auto result = page->page().find_in_page({ .string = query, .case_sensitivity = case_sensitivity }); | 
					
						
							| 
									
										
										
										
											2024-06-09 18:35:32 +01:00
										 |  |  |     async_did_find_in_page(page_id, result.current_match_index, result.total_match_count); | 
					
						
							| 
									
										
										
										
											2024-05-29 20:09:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ConnectionFromClient::find_in_page_next_match(u64 page_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-09 18:35:32 +01:00
										 |  |  |     auto result = page->page().find_in_page_next_match(); | 
					
						
							|  |  |  |     async_did_find_in_page(page_id, result.current_match_index, result.total_match_count); | 
					
						
							| 
									
										
										
										
											2024-05-29 20:09:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ConnectionFromClient::find_in_page_previous_match(u64 page_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-09 18:35:32 +01:00
										 |  |  |     auto result = page->page().find_in_page_previous_match(); | 
					
						
							|  |  |  |     async_did_find_in_page(page_id, result.current_match_index, result.total_match_count); | 
					
						
							| 
									
										
										
										
											2024-05-29 20:09:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-18 09:18:54 -04:00
										 |  |  | void ConnectionFromClient::paste(u64 page_id, Utf16String text) | 
					
						
							| 
									
										
										
										
											2024-03-22 11:56:49 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-04-26 16:59:04 +02:00
										 |  |  |         page->page().focused_navigable().paste(text); | 
					
						
							| 
									
										
										
										
											2024-03-22 11:56:49 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_content_filters(u64, Vector<String> filters) | 
					
						
							| 
									
										
										
										
											2021-09-27 11:39:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-04-21 07:36:40 -04:00
										 |  |  |     Web::ContentFilter::the().set_patterns(filters).release_value_but_fixme_should_propagate_errors(); | 
					
						
							| 
									
										
										
										
											2021-09-27 11:39:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::set_autoplay_allowed_on_all_websites(u64) | 
					
						
							| 
									
										
										
										
											2023-04-17 13:21:19 -04:00
										 |  |  | { | 
					
						
							|  |  |  |     auto& autoplay_allowlist = Web::PermissionsPolicy::AutoplayAllowlist::the(); | 
					
						
							|  |  |  |     autoplay_allowlist.enable_globally(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_autoplay_allowlist(u64, Vector<String> allowlist) | 
					
						
							| 
									
										
										
										
											2023-04-17 13:21:19 -04:00
										 |  |  | { | 
					
						
							|  |  |  |     auto& autoplay_allowlist = Web::PermissionsPolicy::AutoplayAllowlist::the(); | 
					
						
							| 
									
										
										
										
											2025-03-29 08:54:51 -04:00
										 |  |  |     autoplay_allowlist.enable_for_origins(allowlist); | 
					
						
							| 
									
										
										
										
											2023-04-17 13:21:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_proxy_mappings(u64, Vector<ByteString> proxies, HashMap<ByteString, size_t> mappings) | 
					
						
							| 
									
										
										
										
											2022-04-08 01:46:47 +04:30
										 |  |  | { | 
					
						
							|  |  |  |     auto keys = mappings.keys(); | 
					
						
							|  |  |  |     quick_sort(keys, [&](auto& a, auto& b) { return a.length() < b.length(); }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 17:49:34 +03:30
										 |  |  |     OrderedHashMap<ByteString, size_t> sorted_mappings; | 
					
						
							| 
									
										
										
										
											2022-04-08 01:46:47 +04:30
										 |  |  |     for (auto& key : keys) { | 
					
						
							|  |  |  |         auto value = *mappings.get(key); | 
					
						
							|  |  |  |         if (value >= proxies.size()) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         sorted_mappings.set(key, value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |     Web::ProxyMappings::the().set_mappings(move(proxies), move(sorted_mappings)); | 
					
						
							| 
									
										
										
										
											2022-04-08 01:46:47 +04:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_preferred_color_scheme(u64 page_id, Web::CSS::PreferredColorScheme color_scheme) | 
					
						
							| 
									
										
										
										
											2021-10-26 17:00:10 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->set_preferred_color_scheme(color_scheme); | 
					
						
							| 
									
										
										
										
											2021-10-26 17:00:10 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_preferred_contrast(u64 page_id, Web::CSS::PreferredContrast contrast) | 
					
						
							| 
									
										
										
										
											2024-06-13 01:03:56 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->set_preferred_contrast(contrast); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_preferred_motion(u64 page_id, Web::CSS::PreferredMotion motion) | 
					
						
							| 
									
										
										
										
											2024-06-13 16:15:59 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->set_preferred_motion(motion); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_preferred_languages(u64, Vector<String> preferred_languages) | 
					
						
							| 
									
										
										
										
											2024-07-23 21:10:24 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     // FIXME: Whenever the user agent needs to make the navigator.languages attribute of a Window or WorkerGlobalScope
 | 
					
						
							|  |  |  |     // object global return a new set of language tags, the user agent must queue a global task on the DOM manipulation
 | 
					
						
							|  |  |  |     // task source given global to fire an event named languagechange at global, and wait until that task begins to be
 | 
					
						
							|  |  |  |     // executed before actually returning a new value.
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |     Web::ResourceLoader::the().set_preferred_languages(move(preferred_languages)); | 
					
						
							| 
									
										
										
										
											2024-07-23 21:10:24 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 09:30:34 -04:00
										 |  |  | void ConnectionFromClient::set_enable_global_privacy_control(u64, bool enable) | 
					
						
							| 
									
										
										
										
											2024-07-02 20:29:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-04-02 09:30:34 -04:00
										 |  |  |     Web::ResourceLoader::the().set_enable_global_privacy_control(enable); | 
					
						
							| 
									
										
										
										
											2024-07-02 20:29:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::set_has_focus(u64 page_id, bool has_focus) | 
					
						
							| 
									
										
										
										
											2022-02-06 19:03:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->set_has_focus(has_focus); | 
					
						
							| 
									
										
										
										
											2022-02-06 19:03:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::set_is_scripting_enabled(u64 page_id, bool is_scripting_enabled) | 
					
						
							| 
									
										
										
										
											2022-03-30 23:23:14 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->set_is_scripting_enabled(is_scripting_enabled); | 
					
						
							| 
									
										
										
										
											2022-03-30 23:23:14 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::set_device_pixels_per_css_pixel(u64 page_id, float device_pixels_per_css_pixel) | 
					
						
							| 
									
										
										
										
											2023-01-12 14:35:35 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->set_device_pixels_per_css_pixel(device_pixels_per_css_pixel); | 
					
						
							| 
									
										
										
										
											2023-01-12 14:35:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-25 13:10:00 +01:00
										 |  |  | void ConnectionFromClient::set_maximum_frames_per_second(u64 page_id, double maximum_frames_per_second) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->set_maximum_frames_per_second(maximum_frames_per_second); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::set_window_position(u64 page_id, Web::DevicePixelPoint position) | 
					
						
							| 
									
										
										
										
											2022-11-01 14:55:53 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->set_window_position(position); | 
					
						
							| 
									
										
										
										
											2022-11-01 14:55:53 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::set_window_size(u64 page_id, Web::DevicePixelSize size) | 
					
						
							| 
									
										
										
										
											2022-11-01 14:55:53 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->set_window_size(size); | 
					
						
							| 
									
										
										
										
											2022-11-01 14:55:53 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-28 23:37:11 -04:00
										 |  |  | void ConnectionFromClient::did_update_window_rect(u64 page_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().did_update_window_rect(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::handle_file_return(u64, i32 error, Optional<IPC::File> file, i32 request_id) | 
					
						
							| 
									
										
										
										
											2022-02-26 17:50:31 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-02 07:29:19 -05:00
										 |  |  |     auto file_request = m_requested_files.take(request_id); | 
					
						
							| 
									
										
										
										
											2022-02-26 17:50:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-30 16:35:47 -05:00
										 |  |  |     VERIFY(file_request.has_value()); | 
					
						
							|  |  |  |     VERIFY(file_request.value().on_file_request_finish); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     file_request.value().on_file_request_finish(error != 0 ? Error::from_errno(error) : ErrorOr<i32> { file->take_fd() }); | 
					
						
							| 
									
										
										
										
											2022-02-26 17:50:31 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::request_file(u64 page_id, Web::FileRequest file_request) | 
					
						
							| 
									
										
										
										
											2022-02-26 17:50:31 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     i32 const id = last_id++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-30 16:35:47 -05:00
										 |  |  |     auto path = file_request.path(); | 
					
						
							|  |  |  |     m_requested_files.set(id, move(file_request)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  |     async_did_request_file(page_id, path, id); | 
					
						
							| 
									
										
										
										
											2022-02-26 17:50:31 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-09-19 20:50:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-13 11:24:16 -05:00
										 |  |  | void ConnectionFromClient::set_system_visibility_state(u64 page_id, Web::HTML::VisibilityState visibility_state) | 
					
						
							| 
									
										
										
										
											2022-09-19 20:50:33 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-11-13 11:24:16 -05:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().top_level_traversable()->set_system_visibility_state(visibility_state); | 
					
						
							| 
									
										
										
										
											2022-09-19 20:50:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::js_console_input(u64 page_id, String js_source) | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     auto page = this->page(page_id); | 
					
						
							|  |  |  |     if (!page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-02-12 17:39:20 -07:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     page->js_console_input(js_source); | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::run_javascript(u64 page_id, String js_source) | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->run_javascript(js_source); | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ConnectionFromClient::js_console_request_messages(u64 page_id, i32 start_index) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->js_console_request_messages(start_index); | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ConnectionFromClient::alert_closed(u64 page_id) | 
					
						
							| 
									
										
										
										
											2022-11-15 15:49:36 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().alert_closed(); | 
					
						
							| 
									
										
										
										
											2022-11-15 15:49:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::confirm_closed(u64 page_id, bool accepted) | 
					
						
							| 
									
										
										
										
											2022-11-15 15:49:36 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().confirm_closed(accepted); | 
					
						
							| 
									
										
										
										
											2022-11-15 15:49:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::prompt_closed(u64 page_id, Optional<String> response) | 
					
						
							| 
									
										
										
										
											2022-11-15 15:49:36 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |         page->page().prompt_closed(move(response)); | 
					
						
							| 
									
										
										
										
											2022-11-15 15:49:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::color_picker_update(u64 page_id, Optional<Color> picked_color, Web::HTML::ColorPickerUpdateState state) | 
					
						
							| 
									
										
										
										
											2023-09-04 11:32:40 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().color_picker_update(picked_color, state); | 
					
						
							| 
									
										
										
										
											2023-09-04 11:32:40 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::file_picker_closed(u64 page_id, Vector<Web::HTML::SelectedFile> selected_files) | 
					
						
							| 
									
										
										
										
											2024-02-25 13:02:47 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |         page->page().file_picker_closed(selected_files); | 
					
						
							| 
									
										
										
										
											2024-02-25 13:02:47 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::select_dropdown_closed(u64 page_id, Optional<u32> selected_item_id) | 
					
						
							| 
									
										
										
										
											2023-12-07 15:53:49 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							| 
									
										
										
										
											2024-04-03 19:19:08 +02:00
										 |  |  |         page->page().select_dropdown_closed(selected_item_id); | 
					
						
							| 
									
										
										
										
											2023-12-07 15:53:49 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 11:38:31 -04:00
										 |  |  | void ConnectionFromClient::retrieved_clipboard_entries(u64 page_id, u64 request_id, Vector<Web::Clipboard::SystemClipboardItem> items) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().retrieved_clipboard_entries(request_id, move(items)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::toggle_media_play_state(u64 page_id) | 
					
						
							| 
									
										
										
										
											2023-05-15 11:17:58 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().toggle_media_play_state().release_value_but_fixme_should_propagate_errors(); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:17:58 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::toggle_media_mute_state(u64 page_id) | 
					
						
							| 
									
										
										
										
											2023-06-16 11:29:54 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().toggle_media_mute_state(); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:29:54 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::toggle_media_loop_state(u64 page_id) | 
					
						
							| 
									
										
										
										
											2023-05-15 11:17:58 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().toggle_media_loop_state().release_value_but_fixme_should_propagate_errors(); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:17:58 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-02 18:00:48 -07:00
										 |  |  | void ConnectionFromClient::toggle_media_controls_state(u64 page_id) | 
					
						
							| 
									
										
										
										
											2023-05-15 11:17:58 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().toggle_media_controls_state().release_value_but_fixme_should_propagate_errors(); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:17:58 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 09:41:15 -04:00
										 |  |  | void ConnectionFromClient::toggle_page_mute_state(u64 page_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							|  |  |  |         page->page().toggle_page_mute_state(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  | void ConnectionFromClient::set_user_style(u64 page_id, String source) | 
					
						
							| 
									
										
										
										
											2023-08-21 15:50:31 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-29 10:05:05 -04:00
										 |  |  |     if (auto page = this->page(page_id); page.has_value()) | 
					
						
							| 
									
										
										
										
											2025-03-08 12:22:39 -05:00
										 |  |  |         page->page().set_user_style(move(source)); | 
					
						
							| 
									
										
										
										
											2023-08-21 15:50:31 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-24 12:15:20 -04:00
										 |  |  | void ConnectionFromClient::system_time_zone_changed() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-03 10:18:43 -04:00
										 |  |  |     JS::clear_system_time_zone_cache(); | 
					
						
							| 
									
										
										
										
											2024-08-24 12:15:20 -04:00
										 |  |  |     Unicode::clear_system_time_zone_cache(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-07 18:20:13 +03:00
										 |  |  | void ConnectionFromClient::cookies_changed(Vector<Web::Cookie::Cookie> cookies) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (auto& navigable : Web::HTML::all_navigables()) { | 
					
						
							|  |  |  |         auto window = navigable->active_window(); | 
					
						
							|  |  |  |         if (!window) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         window->cookie_store()->process_cookie_changes(cookies); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-17 17:31:42 +02:00
										 |  |  | } |