From 4e1dab477a66f8f171a725ab535514cb825c30a5 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 13 Nov 2024 16:35:17 -0500 Subject: [PATCH] LibWebView+UI: Handle common WebView client initialization in LibWebView No need to have every UI manually implement these common steps. --- Libraries/LibWebView/ViewImplementation.cpp | 42 +++++++++++++++++++ Libraries/LibWebView/ViewImplementation.h | 3 +- UI/AppKit/Interface/LadybirdWebViewBridge.cpp | 35 +--------------- UI/Headless/HeadlessWebView.cpp | 31 +------------- UI/Headless/HeadlessWebView.h | 3 -- UI/Qt/WebContentView.cpp | 30 +------------ 6 files changed, 47 insertions(+), 97 deletions(-) diff --git a/Libraries/LibWebView/ViewImplementation.cpp b/Libraries/LibWebView/ViewImplementation.cpp index e956ceb0bdb..553e15c754f 100644 --- a/Libraries/LibWebView/ViewImplementation.cpp +++ b/Libraries/LibWebView/ViewImplementation.cpp @@ -10,8 +10,11 @@ #include #include #include +#include #include #include +#include +#include #include #ifdef AK_OS_MACOS @@ -500,6 +503,45 @@ void ViewImplementation::handle_resize() client().async_set_viewport_size(page_id(), this->viewport_size()); } +void ViewImplementation::initialize_client(CreateNewClient create_new_client) +{ + if (create_new_client == CreateNewClient::Yes) { + m_client_state = {}; + + // FIXME: Fail to open the tab, rather than crashing the whole application if these fail. + auto request_server_socket = connect_new_request_server_client().release_value_but_fixme_should_propagate_errors(); + auto image_decoder_socket = connect_new_image_decoder_client().release_value_but_fixme_should_propagate_errors(); + + m_client_state.client = launch_web_content_process(*this, AK::move(image_decoder_socket), AK::move(request_server_socket)).release_value_but_fixme_should_propagate_errors(); + } else { + m_client_state.client->register_view(m_client_state.page_index, *this); + } + + m_client_state.client->on_web_content_process_crash = [this] { + Core::deferred_invoke([this] { + handle_web_content_process_crash(); + + if (on_web_content_crashed) + on_web_content_crashed(); + }); + }; + + m_client_state.client_handle = MUST(Web::Crypto::generate_random_uuid()); + client().async_set_window_handle(m_client_state.page_index, m_client_state.client_handle); + + client().async_set_device_pixels_per_css_pixel(m_client_state.page_index, m_device_pixel_ratio); + client().async_set_system_visibility_state(m_client_state.page_index, m_system_visibility_state); + + if (auto webdriver_content_ipc_path = Application::chrome_options().webdriver_content_ipc_path; webdriver_content_ipc_path.has_value()) + client().async_connect_to_webdriver(m_client_state.page_index, *webdriver_content_ipc_path); + + if (Application::chrome_options().allow_popups == AllowPopups::Yes) + client().async_debug_request(m_client_state.page_index, "block-pop-ups"sv, "off"sv); + + if (auto const& user_agent_preset = Application::web_content_options().user_agent_preset; user_agent_preset.has_value()) + client().async_debug_request(m_client_state.page_index, "spoof-user-agent"sv, *user_agents.get(*user_agent_preset)); +} + void ViewImplementation::handle_web_content_process_crash(LoadErrorPage load_error_page) { dbgln("\033[31;1mWebContent process crashed!\033[0m Last page loaded: {}", m_url); diff --git a/Libraries/LibWebView/ViewImplementation.h b/Libraries/LibWebView/ViewImplementation.h index 56c051dc7d4..fd3979cfc4a 100644 --- a/Libraries/LibWebView/ViewImplementation.h +++ b/Libraries/LibWebView/ViewImplementation.h @@ -230,6 +230,7 @@ public: Function on_inspector_requested_cookie_context_menu; Function on_inspector_executed_console_script; Function on_inspector_exported_inspector_html; + Function on_web_content_crashed; virtual Web::DevicePixelSize viewport_size() const = 0; virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const = 0; @@ -253,7 +254,7 @@ protected: No, Yes, }; - virtual void initialize_client(CreateNewClient = CreateNewClient::Yes) { } + virtual void initialize_client(CreateNewClient = CreateNewClient::Yes); enum class LoadErrorPage { No, diff --git a/UI/AppKit/Interface/LadybirdWebViewBridge.cpp b/UI/AppKit/Interface/LadybirdWebViewBridge.cpp index b05b74896dc..c25c31553e5 100644 --- a/UI/AppKit/Interface/LadybirdWebViewBridge.cpp +++ b/UI/AppKit/Interface/LadybirdWebViewBridge.cpp @@ -8,10 +8,7 @@ #include #include #include -#include #include -#include -#include #import @@ -144,45 +141,15 @@ Gfx::IntPoint WebViewBridge::to_widget_position(Gfx::IntPoint content_position) void WebViewBridge::initialize_client(CreateNewClient create_new_client) { - if (create_new_client == CreateNewClient::Yes) { - m_client_state = {}; + ViewImplementation::initialize_client(create_new_client); - auto request_server_socket = WebView::connect_new_request_server_client().release_value_but_fixme_should_propagate_errors(); - auto image_decoder_socket = WebView::connect_new_image_decoder_client().release_value_but_fixme_should_propagate_errors(); - - m_client_state.client = launch_web_content_process(*this, AK::move(image_decoder_socket), AK::move(request_server_socket)).release_value_but_fixme_should_propagate_errors(); - } else { - m_client_state.client->register_view(m_client_state.page_index, *this); - } - - m_client_state.client->on_web_content_process_crash = [this] { - Core::deferred_invoke([this] { - handle_web_content_process_crash(); - }); - }; - - m_client_state.client_handle = MUST(Web::Crypto::generate_random_uuid()); - client().async_set_window_handle(m_client_state.page_index, m_client_state.client_handle); - - client().async_set_device_pixels_per_css_pixel(m_client_state.page_index, m_device_pixel_ratio); client().async_set_preferred_color_scheme(m_client_state.page_index, m_preferred_color_scheme); - - set_system_visibility_state(m_system_visibility_state); update_palette(); if (!m_screen_rects.is_empty()) { // FIXME: Update the screens again if they ever change. client().async_update_screen_rects(m_client_state.page_index, m_screen_rects, 0); } - - if (auto const& webdriver_content_ipc_path = WebView::Application::chrome_options().webdriver_content_ipc_path; webdriver_content_ipc_path.has_value()) { - client().async_connect_to_webdriver(m_client_state.page_index, *webdriver_content_ipc_path); - } - - if (auto const& user_agent_preset = WebView::Application::web_content_options().user_agent_preset; user_agent_preset.has_value()) { - auto user_agent = *WebView::user_agents.get(*user_agent_preset); - client().async_debug_request(m_client_state.page_index, "spoof-user-agent"sv, user_agent); - } } void WebViewBridge::initialize_client_as_child(WebViewBridge const& parent, u64 page_index) diff --git a/UI/Headless/HeadlessWebView.cpp b/UI/Headless/HeadlessWebView.cpp index a6f51d5a329..c1ad8bf073a 100644 --- a/UI/Headless/HeadlessWebView.cpp +++ b/UI/Headless/HeadlessWebView.cpp @@ -6,8 +6,6 @@ #include #include -#include -#include #include #include @@ -153,39 +151,12 @@ NonnullOwnPtr HeadlessWebView::create_child(HeadlessWebView con void HeadlessWebView::initialize_client(CreateNewClient create_new_client) { - if (create_new_client == CreateNewClient::Yes) { - auto request_server_socket = WebView::connect_new_request_server_client().release_value_but_fixme_should_propagate_errors(); - auto image_decoder_socket = WebView::connect_new_image_decoder_client().release_value_but_fixme_should_propagate_errors(); - - m_client_state.client = WebView::launch_web_content_process(*this, move(image_decoder_socket), move(request_server_socket)).release_value_but_fixme_should_propagate_errors(); - } else { - m_client_state.client->register_view(m_client_state.page_index, *this); - } - - m_client_state.client_handle = MUST(Web::Crypto::generate_random_uuid()); - client().async_set_window_handle(m_client_state.page_index, m_client_state.client_handle); + ViewImplementation::initialize_client(create_new_client); client().async_update_system_theme(m_client_state.page_index, m_theme); client().async_set_viewport_size(m_client_state.page_index, viewport_size()); client().async_set_window_size(m_client_state.page_index, viewport_size()); client().async_update_screen_rects(m_client_state.page_index, { screen_rect }, 0); - - set_system_visibility_state(m_system_visibility_state); - - if (Application::chrome_options().allow_popups == WebView::AllowPopups::Yes) - client().async_debug_request(m_client_state.page_index, "block-pop-ups"sv, "off"sv); - - if (auto const& web_driver_ipc_path = Application::chrome_options().webdriver_content_ipc_path; web_driver_ipc_path.has_value()) - client().async_connect_to_webdriver(m_client_state.page_index, *web_driver_ipc_path); - - m_client_state.client->on_web_content_process_crash = [this] { - Core::deferred_invoke([this] { - handle_web_content_process_crash(LoadErrorPage::No); - - if (on_web_content_crashed) - on_web_content_crashed(); - }); - }; } void HeadlessWebView::clear_content_filters() diff --git a/UI/Headless/HeadlessWebView.h b/UI/Headless/HeadlessWebView.h index d0f627e7ef6..c15a614b1af 100644 --- a/UI/Headless/HeadlessWebView.h +++ b/UI/Headless/HeadlessWebView.h @@ -7,7 +7,6 @@ #pragma once #include -#include #include #include #include @@ -31,8 +30,6 @@ public: TestPromise& test_promise() { return *m_test_promise; } void on_test_complete(TestCompletion); - Function on_web_content_crashed; - private: HeadlessWebView(Core::AnonymousBuffer theme, Web::DevicePixelSize viewport_size); diff --git a/UI/Qt/WebContentView.cpp b/UI/Qt/WebContentView.cpp index 4f0f65b4080..9a566a65ceb 100644 --- a/UI/Qt/WebContentView.cpp +++ b/UI/Qt/WebContentView.cpp @@ -20,11 +20,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -619,36 +617,10 @@ void WebContentView::update_screen_rects() void WebContentView::initialize_client(WebView::ViewImplementation::CreateNewClient create_new_client) { - if (create_new_client == CreateNewClient::Yes) { - m_client_state = {}; - - // FIXME: Fail to open the tab, rather than crashing the whole application if these fail. - auto request_server_socket = WebView::connect_new_request_server_client().release_value_but_fixme_should_propagate_errors(); - auto image_decoder_socket = WebView::connect_new_image_decoder_client().release_value_but_fixme_should_propagate_errors(); - - m_client_state.client = launch_web_content_process(*this, AK::move(image_decoder_socket), AK::move(request_server_socket)).release_value_but_fixme_should_propagate_errors(); - } else { - m_client_state.client->register_view(m_client_state.page_index, *this); - } - - m_client_state.client->on_web_content_process_crash = [this] { - Core::deferred_invoke([this] { - handle_web_content_process_crash(); - }); - }; - - m_client_state.client_handle = Web::Crypto::generate_random_uuid().release_value_but_fixme_should_propagate_errors(); - client().async_set_window_handle(m_client_state.page_index, m_client_state.client_handle); - - client().async_set_device_pixels_per_css_pixel(m_client_state.page_index, m_device_pixel_ratio); - - set_system_visibility_state(m_system_visibility_state); + ViewImplementation::initialize_client(create_new_client); update_palette(); update_screen_rects(); - - if (auto webdriver_content_ipc_path = WebView::Application::chrome_options().webdriver_content_ipc_path; webdriver_content_ipc_path.has_value()) - client().async_connect_to_webdriver(m_client_state.page_index, *webdriver_content_ipc_path); } void WebContentView::update_cursor(Gfx::StandardCursor cursor)