diff options
author | Timothy Flynn <trflynn89@pm.me> | 2023-05-17 09:53:13 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-05-17 19:47:05 +0200 |
commit | d8b14da380f0d35f5197b741c81f84c64cfb6204 (patch) | |
tree | 1a67b0b15771b5feac5cae6eb5a182035e4accea | |
parent | 5312a140fedc08f8fd2469b65f5d7b05a172bd62 (diff) | |
download | serenity-d8b14da380f0d35f5197b741c81f84c64cfb6204.zip |
Browser+Ladybird+LibWebView: Move some common functions to LibWebView
The implementations of handle_web_content_process_crash and
take_screenshot are exactly the same across Browser and Ladybird. Let's
reduce some code duplication and move them to LibWebView.
-rw-r--r-- | Ladybird/Tab.cpp | 35 | ||||
-rw-r--r-- | Ladybird/Tab.h | 6 | ||||
-rw-r--r-- | Ladybird/WebContentView.cpp | 37 | ||||
-rw-r--r-- | Ladybird/WebContentView.h | 5 | ||||
-rw-r--r-- | Userland/Applications/Browser/BrowserWindow.cpp | 53 | ||||
-rw-r--r-- | Userland/Applications/Browser/BrowserWindow.h | 10 | ||||
-rw-r--r-- | Userland/Applications/Browser/Tab.cpp | 24 | ||||
-rw-r--r-- | Userland/Applications/Browser/Tab.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/OutOfProcessWebView.cpp | 36 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/OutOfProcessWebView.h | 5 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/ViewImplementation.cpp | 58 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/ViewImplementation.h | 8 |
12 files changed, 90 insertions, 188 deletions
diff --git a/Ladybird/Tab.cpp b/Ladybird/Tab.cpp index 853addbf6b..1c0ff29980 100644 --- a/Ladybird/Tab.cpp +++ b/Ladybird/Tab.cpp @@ -9,12 +9,8 @@ #include "BrowserWindow.h" #include "Settings.h" #include "Utilities.h" -#include <AK/LexicalPath.h> #include <Browser/History.h> -#include <LibCore/DateTime.h> -#include <LibCore/StandardPaths.h> #include <LibGfx/ImageFormats/BMPWriter.h> -#include <LibGfx/ImageFormats/PNGWriter.h> #include <QClipboard> #include <QCoreApplication> #include <QFont> @@ -191,7 +187,7 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView:: auto* take_visible_screenshot_action = new QAction("Take &Visible Screenshot", this); take_visible_screenshot_action->setIcon(QIcon(QString("%1/res/icons/16x16/filetype-image.png").arg(s_serenity_resource_root.characters()))); QObject::connect(take_visible_screenshot_action, &QAction::triggered, this, [this]() { - if (auto result = take_screenshot(ScreenshotType::Visible); result.is_error()) { + if (auto result = view().take_screenshot(WebView::ViewImplementation::ScreenshotType::Visible); result.is_error()) { auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors(); QMessageBox::warning(this, "Ladybird", qstring_from_ak_string(error)); } @@ -200,7 +196,7 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView:: auto* take_full_screenshot_action = new QAction("Take &Full Screenshot", this); take_full_screenshot_action->setIcon(QIcon(QString("%1/res/icons/16x16/filetype-image.png").arg(s_serenity_resource_root.characters()))); QObject::connect(take_full_screenshot_action, &QAction::triggered, this, [this]() { - if (auto result = take_screenshot(ScreenshotType::Full); result.is_error()) { + if (auto result = view().take_screenshot(WebView::ViewImplementation::ScreenshotType::Full); result.is_error()) { auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors(); QMessageBox::warning(this, "Ladybird", qstring_from_ak_string(error)); } @@ -450,33 +446,6 @@ void Tab::copy_link_url(URL const& url) clipboard->setText(qstring_from_ak_deprecated_string(url.to_deprecated_string())); } -ErrorOr<void> Tab::take_screenshot(ScreenshotType type) -{ - Gfx::ShareableBitmap bitmap; - - switch (type) { - case ScreenshotType::Visible: - bitmap = view().take_screenshot(); - break; - case ScreenshotType::Full: - bitmap = view().take_document_screenshot(); - break; - } - - if (!bitmap.is_valid()) - return Error::from_string_view("Failed to take a screenshot of the current tab"sv); - - LexicalPath path { Core::StandardPaths::downloads_directory() }; - path = path.append(TRY(Core::DateTime::now().to_string("screenshot-%Y-%m-%d-%H-%M-%S.png"sv))); - - auto encoded = TRY(Gfx::PNGWriter::encode(*bitmap.bitmap())); - - auto screenshot_file = TRY(Core::File::open(path.string(), Core::File::OpenMode::Write)); - TRY(screenshot_file->write_until_depleted(encoded)); - - return {}; -} - void Tab::location_edit_return_pressed() { navigate(m_location_edit->text()); diff --git a/Ladybird/Tab.h b/Ladybird/Tab.h index 0f313681d0..77598303dc 100644 --- a/Ladybird/Tab.h +++ b/Ladybird/Tab.h @@ -60,12 +60,6 @@ private: void open_link_in_new_tab(URL const&); void copy_link_url(URL const&); - enum class ScreenshotType { - Visible, - Full, - }; - ErrorOr<void> take_screenshot(ScreenshotType); - QBoxLayout* m_layout; QToolBar* m_toolbar { nullptr }; QToolButton* m_reset_zoom_button { nullptr }; diff --git a/Ladybird/WebContentView.cpp b/Ladybird/WebContentView.cpp index a09ac93458..c51b7fde98 100644 --- a/Ladybird/WebContentView.cpp +++ b/Ladybird/WebContentView.cpp @@ -637,43 +637,6 @@ void WebContentView::create_client(WebView::EnableCallgrindProfiling enable_call client().async_connect_to_webdriver(m_webdriver_content_ipc_path); } -Gfx::ShareableBitmap WebContentView::take_screenshot() const -{ - if (auto* bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr()) - return bitmap->to_shareable_bitmap(); - return {}; -} - -Gfx::ShareableBitmap WebContentView::take_document_screenshot() -{ - return client().take_document_screenshot(); -} - -void WebContentView::handle_web_content_process_crash() -{ - dbgln("WebContent process crashed!"); - create_client(); - VERIFY(m_client_state.client); - - // Don't keep a stale backup bitmap around. - m_backup_bitmap = nullptr; - - handle_resize(); - StringBuilder builder; - builder.append("<html><head><title>Crashed: "sv); - builder.append(escape_html_entities(m_url.to_deprecated_string())); - builder.append("</title></head><body>"sv); - builder.append("<h1>Web page crashed"sv); - if (!m_url.host().is_empty()) { - builder.appendff(" on {}", escape_html_entities(m_url.host())); - } - builder.append("</h1>"sv); - auto escaped_url = escape_html_entities(m_url.to_deprecated_string()); - builder.appendff("The web page <a href=\"{}\">{}</a> has crashed.<br><br>You can reload the page to try again.", escaped_url, escaped_url); - builder.append("</body></html>"sv); - load_html(builder.to_deprecated_string(), m_url); -} - void WebContentView::notify_server_did_paint(Badge<WebContentClient>, i32 bitmap_id, Gfx::IntSize size) { if (m_client_state.back_bitmap.id == bitmap_id) { diff --git a/Ladybird/WebContentView.h b/Ladybird/WebContentView.h index 9ac0bc9837..095c87ede1 100644 --- a/Ladybird/WebContentView.h +++ b/Ladybird/WebContentView.h @@ -113,9 +113,6 @@ public: Gfx::IntPoint to_content(Gfx::IntPoint) const; Gfx::IntPoint to_widget(Gfx::IntPoint) const; - Gfx::ShareableBitmap take_screenshot() const; - Gfx::ShareableBitmap take_document_screenshot(); - enum class PaletteMode { Default, Dark, @@ -223,7 +220,5 @@ private: Gfx::IntRect m_viewport_rect; - void handle_web_content_process_crash(); - StringView m_webdriver_content_ipc_path; }; diff --git a/Userland/Applications/Browser/BrowserWindow.cpp b/Userland/Applications/Browser/BrowserWindow.cpp index 8aaaa84f40..c6bd6e5499 100644 --- a/Userland/Applications/Browser/BrowserWindow.cpp +++ b/Userland/Applications/Browser/BrowserWindow.cpp @@ -14,10 +14,8 @@ #include "CookieJar.h" #include "InspectorWidget.h" #include "Tab.h" -#include <AK/LexicalPath.h> #include <Applications/Browser/BrowserWindowGML.h> #include <LibConfig/Client.h> -#include <LibCore/DateTime.h> #include <LibCore/StandardPaths.h> #include <LibGUI/Application.h> #include <LibGUI/Clipboard.h> @@ -32,7 +30,6 @@ #include <LibGUI/TabWidget.h> #include <LibGUI/ToolbarContainer.h> #include <LibGUI/Widget.h> -#include <LibGfx/ImageFormats/PNGWriter.h> #include <LibJS/Interpreter.h> #include <LibWeb/CSS/PreferredColorScheme.h> #include <LibWeb/Dump.h> @@ -259,22 +256,6 @@ void BrowserWindow::build_menus() this); m_inspect_dom_node_action->set_status_tip("Open inspector for this element"); - m_take_visible_screenshot_action = GUI::Action::create( - "Take &Visible Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) { - if (auto result = take_screenshot(ScreenshotType::Visible); result.is_error()) - GUI::MessageBox::show_error(this, DeprecatedString::formatted("{}", result.error())); - }, - this); - m_take_visible_screenshot_action->set_status_tip("Save a screenshot of the visible portion of the current tab to the Downloads directory"sv); - - m_take_full_screenshot_action = GUI::Action::create( - "Take &Full Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) { - if (auto result = take_screenshot(ScreenshotType::Full); result.is_error()) - GUI::MessageBox::show_error(this, DeprecatedString::formatted("{}", result.error())); - }, - this); - m_take_full_screenshot_action->set_status_tip("Save a screenshot of the entirety of the current tab to the Downloads directory"sv); - auto& inspect_menu = add_menu("&Inspect"_string.release_value_but_fixme_should_propagate_errors()); inspect_menu.add_action(*m_view_source_action); inspect_menu.add_action(*m_inspect_dom_tree_action); @@ -655,10 +636,6 @@ Tab& BrowserWindow::create_new_tab(URL url, Web::HTML::ActivateTab activate) return active_tab().view().get_session_storage_entries(); }; - new_tab.on_take_screenshot = [this]() { - return active_tab().view().take_screenshot(); - }; - new_tab.load(url); dbgln_if(SPAM_DEBUG, "Added new tab {:p}, loading {}", &new_tab, url); @@ -776,36 +753,6 @@ void BrowserWindow::event(Core::Event& event) Window::event(event); } -ErrorOr<void> BrowserWindow::take_screenshot(ScreenshotType type) -{ - if (!active_tab().on_take_screenshot) - return {}; - - Gfx::ShareableBitmap bitmap; - - switch (type) { - case ScreenshotType::Visible: - bitmap = active_tab().on_take_screenshot(); - break; - case ScreenshotType::Full: - bitmap = active_tab().view().take_document_screenshot(); - break; - } - - if (!bitmap.is_valid()) - return Error::from_string_view("Failed to take a screenshot of the current tab"sv); - - LexicalPath path { Core::StandardPaths::downloads_directory() }; - path = path.append(Core::DateTime::now().to_deprecated_string("screenshot-%Y-%m-%d-%H-%M-%S.png"sv)); - - auto encoded = TRY(Gfx::PNGWriter::encode(*bitmap.bitmap())); - - auto screenshot_file = TRY(Core::File::open(path.string(), Core::File::OpenMode::Write)); - TRY(screenshot_file->write_until_depleted(encoded)); - - return {}; -} - void BrowserWindow::update_displayed_zoom_level() { VERIFY(m_zoom_menu); diff --git a/Userland/Applications/Browser/BrowserWindow.h b/Userland/Applications/Browser/BrowserWindow.h index 0d19d196a6..ba94bdeb23 100644 --- a/Userland/Applications/Browser/BrowserWindow.h +++ b/Userland/Applications/Browser/BrowserWindow.h @@ -41,8 +41,6 @@ public: GUI::Action& view_source_action() { return *m_view_source_action; } GUI::Action& inspect_dom_tree_action() { return *m_inspect_dom_tree_action; } GUI::Action& inspect_dom_node_action() { return *m_inspect_dom_node_action; } - GUI::Action& take_visible_screenshot_action() { return *m_take_visible_screenshot_action; } - GUI::Action& take_full_screenshot_action() { return *m_take_full_screenshot_action; } void content_filters_changed(); void autoplay_allowlist_changed(); @@ -65,12 +63,6 @@ private: void update_displayed_zoom_level(); - enum class ScreenshotType { - Visible, - Full, - }; - ErrorOr<void> take_screenshot(ScreenshotType); - RefPtr<GUI::Action> m_go_back_action; RefPtr<GUI::Action> m_go_forward_action; RefPtr<GUI::Action> m_go_home_action; @@ -80,8 +72,6 @@ private: RefPtr<GUI::Action> m_view_source_action; RefPtr<GUI::Action> m_inspect_dom_tree_action; RefPtr<GUI::Action> m_inspect_dom_node_action; - RefPtr<GUI::Action> m_take_visible_screenshot_action; - RefPtr<GUI::Action> m_take_full_screenshot_action; RefPtr<GUI::Menu> m_zoom_menu; diff --git a/Userland/Applications/Browser/Tab.cpp b/Userland/Applications/Browser/Tab.cpp index f83e24ecb6..af7e7a5c7c 100644 --- a/Userland/Applications/Browser/Tab.cpp +++ b/Userland/Applications/Browser/Tab.cpp @@ -554,6 +554,26 @@ Tab::Tab(BrowserWindow& window) on_tab_close_other_request(*this); })); + auto take_visible_screenshot_action = GUI::Action::create( + "Take &Visible Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) { + if (auto result = view().take_screenshot(WebView::ViewImplementation::ScreenshotType::Visible); result.is_error()) { + auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors(); + GUI::MessageBox::show_error(&this->window(), error); + } + }, + this); + take_visible_screenshot_action->set_status_tip("Save a screenshot of the visible portion of the current tab to the Downloads directory"sv); + + auto take_full_screenshot_action = GUI::Action::create( + "Take &Full Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) { + if (auto result = view().take_screenshot(WebView::ViewImplementation::ScreenshotType::Full); result.is_error()) { + auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors(); + GUI::MessageBox::show_error(&this->window(), error); + } + }, + this); + take_full_screenshot_action->set_status_tip("Save a screenshot of the entirety of the current tab to the Downloads directory"sv); + m_page_context_menu = GUI::Menu::construct(); m_page_context_menu->add_action(window.go_back_action()); m_page_context_menu->add_action(window.go_forward_action()); @@ -562,8 +582,8 @@ Tab::Tab(BrowserWindow& window) m_page_context_menu->add_action(window.copy_selection_action()); m_page_context_menu->add_action(window.select_all_action()); m_page_context_menu->add_separator(); - m_page_context_menu->add_action(window.take_visible_screenshot_action()); - m_page_context_menu->add_action(window.take_full_screenshot_action()); + m_page_context_menu->add_action(move(take_visible_screenshot_action)); + m_page_context_menu->add_action(move(take_full_screenshot_action)); m_page_context_menu->add_separator(); m_page_context_menu->add_action(window.view_source_action()); m_page_context_menu->add_action(window.inspect_dom_tree_action()); diff --git a/Userland/Applications/Browser/Tab.h b/Userland/Applications/Browser/Tab.h index ecc4f300d0..6fe3589bdb 100644 --- a/Userland/Applications/Browser/Tab.h +++ b/Userland/Applications/Browser/Tab.h @@ -77,7 +77,6 @@ public: Function<Vector<Web::Cookie::Cookie>()> on_get_cookies_entries; Function<OrderedHashMap<DeprecatedString, DeprecatedString>()> on_get_local_storage_entries; Function<OrderedHashMap<DeprecatedString, DeprecatedString>()> on_get_session_storage_entries; - Function<Gfx::ShareableBitmap()> on_take_screenshot; void enable_webdriver_mode(); diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp index 8c47ff9f31..a65256f91b 100644 --- a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp +++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp @@ -35,30 +35,6 @@ OutOfProcessWebView::OutOfProcessWebView() OutOfProcessWebView::~OutOfProcessWebView() = default; -void OutOfProcessWebView::handle_web_content_process_crash() -{ - create_client(); - VERIFY(m_client_state.client); - - // Don't keep a stale backup bitmap around. - m_backup_bitmap = nullptr; - - handle_resize(); - StringBuilder builder; - builder.append("<html><head><title>Crashed: "sv); - builder.append(escape_html_entities(m_url.to_deprecated_string())); - builder.append("</title></head><body>"sv); - builder.append("<h1>Web page crashed"sv); - if (!m_url.host().is_empty()) { - builder.appendff(" on {}", escape_html_entities(m_url.host())); - } - builder.append("</h1>"sv); - auto escaped_url = escape_html_entities(m_url.to_deprecated_string()); - builder.appendff("The web page <a href=\"{}\">{}</a> has crashed.<br><br>You can reload the page to try again.", escaped_url, escaped_url); - builder.append("</body></html>"sv); - load_html(builder.to_deprecated_string(), m_url); -} - void OutOfProcessWebView::create_client(EnableCallgrindProfiling) { m_client_state = {}; @@ -591,18 +567,6 @@ void OutOfProcessWebView::set_window_size(Gfx::IntSize size) client().async_set_window_size(size); } -Gfx::ShareableBitmap OutOfProcessWebView::take_screenshot() const -{ - if (auto* bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr()) - return bitmap->to_shareable_bitmap(); - return {}; -} - -Gfx::ShareableBitmap OutOfProcessWebView::take_document_screenshot() -{ - return client().take_document_screenshot(); -} - void OutOfProcessWebView::focusin_event(GUI::FocusEvent&) { client().async_set_has_focus(true); diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.h b/Userland/Libraries/LibWebView/OutOfProcessWebView.h index 8d8f3f9c31..1be13f44a7 100644 --- a/Userland/Libraries/LibWebView/OutOfProcessWebView.h +++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.h @@ -53,9 +53,6 @@ public: void set_system_visibility_state(bool visible); - Gfx::ShareableBitmap take_screenshot() const; - Gfx::ShareableBitmap take_document_screenshot(); - // This is a hint that tells OOPWV that the content will scale to the viewport size. // In practice, this means that OOPWV may render scaled stale versions of the content while resizing. void set_content_scales_to_viewport(bool); @@ -183,8 +180,6 @@ private: virtual Gfx::IntRect viewport_rect() const override; - void handle_web_content_process_crash(); - using InputEvent = Variant<GUI::KeyEvent, GUI::MouseEvent>; void enqueue_input_event(InputEvent const&); void process_next_input_event(); diff --git a/Userland/Libraries/LibWebView/ViewImplementation.cpp b/Userland/Libraries/LibWebView/ViewImplementation.cpp index 85cd532f86..1b112257fb 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.cpp +++ b/Userland/Libraries/LibWebView/ViewImplementation.cpp @@ -5,7 +5,11 @@ */ #include <AK/Error.h> +#include <AK/LexicalPath.h> #include <AK/String.h> +#include <LibCore/DateTime.h> +#include <LibCore/StandardPaths.h> +#include <LibGfx/ImageFormats/PNGWriter.h> #include <LibWebView/ViewImplementation.h> namespace WebView { @@ -286,4 +290,58 @@ void ViewImplementation::request_repaint() client().async_paint(viewport_rect(), m_client_state.back_bitmap.id); } +void ViewImplementation::handle_web_content_process_crash() +{ + dbgln("WebContent process crashed!"); + + create_client(); + VERIFY(m_client_state.client); + + // Don't keep a stale backup bitmap around. + m_backup_bitmap = nullptr; + + handle_resize(); + StringBuilder builder; + builder.append("<html><head><title>Crashed: "sv); + builder.append(escape_html_entities(m_url.to_deprecated_string())); + builder.append("</title></head><body>"sv); + builder.append("<h1>Web page crashed"sv); + if (!m_url.host().is_empty()) { + builder.appendff(" on {}", escape_html_entities(m_url.host())); + } + builder.append("</h1>"sv); + auto escaped_url = escape_html_entities(m_url.to_deprecated_string()); + builder.appendff("The web page <a href=\"{}\">{}</a> has crashed.<br><br>You can reload the page to try again.", escaped_url, escaped_url); + builder.append("</body></html>"sv); + load_html(builder.to_deprecated_string(), m_url); +} + +ErrorOr<void> ViewImplementation::take_screenshot(ScreenshotType type) +{ + Gfx::ShareableBitmap bitmap; + + switch (type) { + case ScreenshotType::Visible: + if (auto* visible_bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr()) + bitmap = visible_bitmap->to_shareable_bitmap(); + break; + case ScreenshotType::Full: + bitmap = client().take_document_screenshot(); + break; + } + + if (!bitmap.is_valid()) + return Error::from_string_view("Failed to take a screenshot of the current tab"sv); + + LexicalPath path { Core::StandardPaths::downloads_directory() }; + path = path.append(TRY(Core::DateTime::now().to_string("screenshot-%Y-%m-%d-%H-%M-%S.png"sv))); + + auto encoded = TRY(Gfx::PNGWriter::encode(*bitmap.bitmap())); + + auto screenshot_file = TRY(Core::File::open(path.string(), Core::File::OpenMode::Write)); + TRY(screenshot_file->write_until_depleted(encoded)); + + return {}; +} + } diff --git a/Userland/Libraries/LibWebView/ViewImplementation.h b/Userland/Libraries/LibWebView/ViewImplementation.h index 23e8a5d2d4..75ca656d5b 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.h +++ b/Userland/Libraries/LibWebView/ViewImplementation.h @@ -74,6 +74,12 @@ public: void toggle_video_loop_state(); void toggle_video_controls_state(); + enum class ScreenshotType { + Visible, + Full, + }; + ErrorOr<void> take_screenshot(ScreenshotType); + virtual void notify_server_did_layout(Badge<WebContentClient>, Gfx::IntSize content_size) = 0; virtual void notify_server_did_paint(Badge<WebContentClient>, i32 bitmap_id, Gfx::IntSize) = 0; virtual void notify_server_did_invalidate_content_rect(Badge<WebContentClient>, Gfx::IntRect const&) = 0; @@ -157,6 +163,8 @@ protected: ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, EnableCallgrindProfiling = EnableCallgrindProfiling::No, IsLayoutTestMode = IsLayoutTestMode::No); #endif + void handle_web_content_process_crash(); + struct SharedBitmap { i32 id { -1 }; i32 pending_paints { 0 }; |