1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 04:54:58 +00:00

Browser: Add a context menu item to search for the selected text

This commit is contained in:
Timothy Flynn 2023-10-23 13:36:33 -04:00 committed by Andreas Kling
parent 6af279a22d
commit ae6e2e682e
4 changed files with 35 additions and 1 deletions

View file

@ -48,6 +48,7 @@ ErrorOr<IconBag> IconBag::try_create()
icon_bag.pause = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/pause.png"sv)); icon_bag.pause = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/pause.png"sv));
icon_bag.mute = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/audio-volume-muted.png"sv)); icon_bag.mute = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/audio-volume-muted.png"sv));
icon_bag.unmute = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/audio-volume-high.png"sv)); icon_bag.unmute = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/audio-volume-high.png"sv));
icon_bag.search = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/find.png"sv));
return icon_bag; return icon_bag;
} }

View file

@ -50,5 +50,6 @@ struct IconBag final {
RefPtr<Gfx::Bitmap> pause { nullptr }; RefPtr<Gfx::Bitmap> pause { nullptr };
RefPtr<Gfx::Bitmap> mute { nullptr }; RefPtr<Gfx::Bitmap> mute { nullptr };
RefPtr<Gfx::Bitmap> unmute { nullptr }; RefPtr<Gfx::Bitmap> unmute { nullptr };
RefPtr<Gfx::Bitmap> search { nullptr };
}; };
} }

View file

@ -45,6 +45,7 @@
#include <LibWeb/Layout/Viewport.h> #include <LibWeb/Layout/Viewport.h>
#include <LibWeb/Loader/ResourceLoader.h> #include <LibWeb/Loader/ResourceLoader.h>
#include <LibWebView/OutOfProcessWebView.h> #include <LibWebView/OutOfProcessWebView.h>
#include <LibWebView/SearchEngine.h>
#include <LibWebView/URL.h> #include <LibWebView/URL.h>
namespace Browser { namespace Browser {
@ -633,6 +634,13 @@ Tab::Tab(BrowserWindow& window)
on_tab_close_other_request(*this); on_tab_close_other_request(*this);
})); }));
auto search_selected_text_action = GUI::Action::create(
"&Search for <query>"sv, g_icon_bag.search, [this](auto&) {
auto url = MUST(String::formatted(g_search_engine, URL::percent_encode(*m_page_context_menu_search_text)));
this->window().create_new_tab(url, Web::HTML::ActivateTab::Yes);
},
this);
auto take_visible_screenshot_action = GUI::Action::create( auto take_visible_screenshot_action = GUI::Action::create(
"Take &Visible Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) { "Take &Visible Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) {
if (auto result = view().take_screenshot(WebView::ViewImplementation::ScreenshotType::Visible); result.is_error()) { if (auto result = view().take_screenshot(WebView::ViewImplementation::ScreenshotType::Visible); result.is_error()) {
@ -660,6 +668,9 @@ Tab::Tab(BrowserWindow& window)
m_page_context_menu->add_separator(); m_page_context_menu->add_separator();
m_page_context_menu->add_action(window.copy_selection_action()); 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_action(window.select_all_action());
// FIXME: It would be nice to have a separator here, but the below action is sometimes hidden, and WindowServer
// does not hide successive separators like other toolkits.
m_page_context_menu->add_action(search_selected_text_action);
m_page_context_menu->add_separator(); m_page_context_menu->add_separator();
m_page_context_menu->add_action(move(take_visible_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_action(move(take_full_screenshot_action));
@ -668,7 +679,24 @@ Tab::Tab(BrowserWindow& window)
m_page_context_menu->add_action(window.inspect_dom_tree_action()); m_page_context_menu->add_action(window.inspect_dom_tree_action());
m_page_context_menu->add_action(window.inspect_dom_node_action()); m_page_context_menu->add_action(window.inspect_dom_node_action());
view().on_context_menu_request = [&](auto widget_position) { m_page_context_menu->on_visibility_change = [this](auto visible) {
if (!visible)
m_page_context_menu_search_text = {};
};
view().on_context_menu_request = [&, search_selected_text_action = move(search_selected_text_action)](auto widget_position) {
m_page_context_menu_search_text = g_search_engine.is_empty()
? OptionalNone {}
: view().selected_text_with_whitespace_collapsed();
if (m_page_context_menu_search_text.has_value()) {
auto action_text = WebView::format_search_query_for_display(g_search_engine, *m_page_context_menu_search_text);
search_selected_text_action->set_text(action_text.to_deprecated_string());
search_selected_text_action->set_visible(true);
} else {
search_selected_text_action->set_visible(false);
}
auto screen_position = view().screen_relative_rect().location().translated(widget_position); auto screen_position = view().screen_relative_rect().location().translated(widget_position);
m_page_context_menu->popup(screen_position); m_page_context_menu->popup(screen_position);
}; };

View file

@ -150,9 +150,13 @@ private:
URL m_media_context_menu_url; URL m_media_context_menu_url;
RefPtr<GUI::Menu> m_tab_context_menu; RefPtr<GUI::Menu> m_tab_context_menu;
RefPtr<GUI::Menu> m_page_context_menu; RefPtr<GUI::Menu> m_page_context_menu;
Optional<String> m_page_context_menu_search_text;
RefPtr<GUI::Menu> m_go_back_context_menu; RefPtr<GUI::Menu> m_go_back_context_menu;
RefPtr<GUI::Menu> m_go_forward_context_menu; RefPtr<GUI::Menu> m_go_forward_context_menu;
DeprecatedString m_title; DeprecatedString m_title;
RefPtr<const Gfx::Bitmap> m_icon; RefPtr<const Gfx::Bitmap> m_icon;