Skip to content

Commit

Permalink
Reassign Ctrl/Cmd + C default hotkey to copy clean urls
Browse files Browse the repository at this point in the history
  • Loading branch information
spylogsster committed Jan 20, 2023
1 parent 0945438 commit 8135599
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 75 deletions.
72 changes: 68 additions & 4 deletions browser/ui/views/omnibox/brave_omnibox_view_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,23 @@
#include <utility>

#include "brave/app/brave_command_ids.h"
#include "brave/browser/url_sanitizer/url_sanitizer_service_factory.h"
#include "brave/components/url_sanitizer/browser/url_sanitizer_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/grit/generated_resources.h"
#include "components/omnibox/browser/omnibox_edit_controller.h"
#include "components/omnibox/browser/omnibox_edit_model.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"

namespace {
void BraveUpdateContextMenu(ui::SimpleMenuModel* menu_contents, GURL url) {
if (!url.SchemeIsHTTPOrHTTPS())
return;
absl::optional<size_t> copy_position =
menu_contents->GetIndexOfCommandId(views::Textfield::kCopy);
if (!copy_position)
return;
menu_contents->InsertItemWithStringIdAt(
copy_position.value() + 1, IDC_COPY_CLEAN_LINK, IDS_COPY_CLEAN_LINK);
}
} // namespace

BraveOmniboxViewViews::~BraveOmniboxViewViews() = default;

Expand All @@ -27,3 +36,58 @@ bool BraveOmniboxViewViews::SelectedTextIsURL() {
&write_url);
return write_url;
}

#if BUILDFLAG(IS_WIN)
bool BraveOmniboxViewViews::AcceleratorPressed(
const ui::Accelerator& accelerator) {
ui::KeyEvent event(
accelerator.key_state() == ui::Accelerator::KeyState::PRESSED
? ui::ET_KEY_PRESSED
: ui::ET_KEY_RELEASED,
accelerator.key_code(), accelerator.modifiers());
auto command = GetCommandForKeyEvent(event);

if ((GetTextInputType() != ui::TEXT_INPUT_TYPE_PASSWORD) &&
(command != ui::TextEditCommand::COPY || !SelectedTextIsURL())) {
return OmniboxViewViews::AcceleratorPressed(accelerator);
}
ExecuteCommand(IDC_COPY_CLEAN_LINK, 0);
return true;
}

bool BraveOmniboxViewViews::GetAcceleratorForCommandId(
int command_id,
ui::Accelerator* accelerator) const {
bool is_url = const_cast<BraveOmniboxViewViews*>(this)->SelectedTextIsURL();
if (is_url) {
if (command_id == kCopy) {
return false;
}
if (command_id == IDC_COPY_CLEAN_LINK) {
*accelerator = ui::Accelerator(ui::VKEY_C, ui::EF_PLATFORM_ACCELERATOR);
return true;
}
}
return OmniboxViewViews::GetAcceleratorForCommandId(command_id, accelerator);
}
#endif // BUILDFLAG(IS_WIN)

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
void BraveOmniboxViewViews::ExecuteTextEditCommand(
ui::TextEditCommand command) {
if (command == ui::TextEditCommand::COPY && SelectedTextIsURL()) {
ExecuteCommand(IDC_COPY_CLEAN_LINK, 0);
return;
}
OmniboxViewViews::ExecuteTextEditCommand(command);
}
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)

void BraveOmniboxViewViews::UpdateContextMenu(
ui::SimpleMenuModel* menu_contents) {
OmniboxViewViews::UpdateContextMenu(menu_contents);
if (SelectedTextIsURL()) {
BraveUpdateContextMenu(menu_contents,
controller()->GetLocationBarModel()->GetURL());
}
}
14 changes: 14 additions & 0 deletions browser/ui/views/omnibox/brave_omnibox_view_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ class BraveOmniboxViewViews : public OmniboxViewViews {
~BraveOmniboxViewViews() override;

bool SelectedTextIsURL();

protected:
#if BUILDFLAG(IS_WIN)
// View overrides:
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
bool GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) const override;
#endif // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
// ui::views::Textfield
void ExecuteTextEditCommand(ui::TextEditCommand command) override;
#endif
// ui::views::TextfieldController:
void UpdateContextMenu(ui::SimpleMenuModel* menu_contents) override;
};

#endif // BRAVE_BROWSER_UI_VIEWS_OMNIBOX_BRAVE_OMNIBOX_VIEW_VIEWS_H_
80 changes: 78 additions & 2 deletions browser/ui/views/omnibox/brave_omnibox_view_views_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class BraveOmniboxViewViewsTest : public InProcessBrowserTest {
};

// Load brave url and check copied url also has brave scheme.
IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, CopyURLToClipboardTest) {
IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest,
CopyInternalURLToClipboardTest) {
const std::string test_url("brave://version/");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(test_url)));

Expand Down Expand Up @@ -73,6 +74,30 @@ IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, CopyCleanURLToClipboardTest) {
"e=&f=g&=end");
}

IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, CopyURLToClipboardTest) {
brave::URLSanitizerServiceFactory::GetForBrowserContext(browser()->profile())
->Initialize(R"([
{ "include": [ "*://*/*"], "params": ["utm_content"] }
])");
const std::string test_url(
"https://dev-pages.bravesoftware.com/clean-urls/"
"exempted/"
"?brave_testing1=foo&brave_testing2=bar&brave_testing3=keep&"
"d&utm_content=removethis&e=&f=g&=end");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(test_url)));

omnibox_view()->SelectAll(true);
omnibox_view()->ExecuteCommand(views::Textfield::kCopy, 0);
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
std::string text_from_clipboard;
clipboard->ReadAsciiText(ui::ClipboardBuffer::kCopyPaste,
/* data_dst = */ nullptr, &text_from_clipboard);
EXPECT_EQ(text_from_clipboard,
"https://dev-pages.bravesoftware.com/clean-urls/exempted/"
"?brave_testing1=foo&brave_testing2=bar&brave_testing3=keep&d&"
"utm_content=removethis&e=&f=g&=end");
}

IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, DoNotSanitizeInternalURLS) {
const std::string test_url("brave://settings/?utm_ad=1");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(test_url)));
Expand All @@ -83,10 +108,61 @@ IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, DoNotSanitizeInternalURLS) {
base::RunLoop().RunUntilIdle();

omnibox_view()->SelectAll(true);
omnibox_view()->ExecuteCommand(IDC_COPY_CLEAN_LINK, 0);
omnibox_view()->ExecuteCommand(views::Textfield::kCopy, 0);
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
std::string text_from_clipboard;
clipboard->ReadAsciiText(ui::ClipboardBuffer::kCopyPaste,
/* data_dst = */ nullptr, &text_from_clipboard);
EXPECT_EQ(text_from_clipboard, "brave://settings/?utm_ad=1");
}

IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest,
CopyCleanedURLToClipboardByHotkey) {
brave::URLSanitizerServiceFactory::GetForBrowserContext(browser()->profile())
->Initialize(R"([
{ "include": [ "*://*/*"], "params": ["utm_content"] }
])");
const std::string test_url(
"https://dev-pages.bravesoftware.com/clean-urls/"
"exempted/"
"?brave_testing1=foo&brave_testing2=bar&brave_testing3=keep&&;b&"
"d&utm_content=removethis&e=&f=g&=end");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(test_url)));

omnibox_view()->SelectAll(true);

auto* textfield = static_cast<views::Textfield*>(omnibox_view());
textfield->AcceleratorPressed(
ui::Accelerator(ui::VKEY_C, ui::EF_PLATFORM_ACCELERATOR));
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
std::string text_from_clipboard;
clipboard->ReadAsciiText(ui::ClipboardBuffer::kCopyPaste,
/* data_dst = */ nullptr, &text_from_clipboard);
EXPECT_EQ(text_from_clipboard,
"https://dev-pages.bravesoftware.com/clean-urls/exempted/"
"?brave_testing1=foo&brave_testing2=bar&brave_testing3=keep&&;b&d&"
"e=&f=g&=end");
}

IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, CopyTextToClipboardByHotkey) {
brave::URLSanitizerServiceFactory::GetForBrowserContext(browser()->profile())
->Initialize(R"([
{ "include": [ "*://*/*"], "params": ["utm_content"] }
])");
const std::string test_text(
"exempted/"
"?brave_testing1=foo&brave_testing2=bar&brave_testing3=keep&&;b&"
"d&utm_content=removethis&e=&f=g&=end");
auto* textfield = static_cast<views::Textfield*>(omnibox_view());
textfield->SetText(base::UTF8ToUTF16(test_text));

omnibox_view()->SelectAll(true);

textfield->AcceleratorPressed(
ui::Accelerator(ui::VKEY_C, ui::EF_PLATFORM_ACCELERATOR));
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
std::string text_from_clipboard;
clipboard->ReadAsciiText(ui::ClipboardBuffer::kCopyPaste,
/* data_dst = */ nullptr, &text_from_clipboard);
EXPECT_EQ(text_from_clipboard, test_text);
}
69 changes: 0 additions & 69 deletions chromium_src/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,77 +4,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
#include "base/strings/utf_string_conversions.h"
#include "brave/app/brave_command_ids.h"
#include "brave/browser/ui/views/omnibox/brave_omnibox_popup_contents_view.h"
#include "brave/browser/url_sanitizer/url_sanitizer_service_factory.h"
#include "brave/components/url_sanitizer/browser/url_sanitizer_service.h"
#include "brave/grit/brave_generated_resources.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/translate/chrome_translate_client.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_controller.h"
#include "chrome/grit/generated_resources.h"
#include "components/omnibox/browser/omnibox_edit_model.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/views/controls/textfield/textfield.h"

namespace {

void BraveUpdateContextMenu(ui::SimpleMenuModel* menu_contents, GURL url) {
if (!url.SchemeIsHTTPOrHTTPS())
return;
absl::optional<size_t> copy_position =
menu_contents->GetIndexOfCommandId(views::Textfield::kCopy);
if (!copy_position)
return;
menu_contents->InsertItemWithStringIdAt(
copy_position.value() + 1, IDC_COPY_CLEAN_LINK, IDS_COPY_CLEAN_LINK);
}

void BraveCopyCleanURL(Profile* profile,
OmniboxEditModel* model,
int sel_min,
std::u16string selected_text) {
GURL url;
bool write_url = false;
model->AdjustTextForCopy(sel_min, &selected_text, &url, &write_url);
if (!write_url || !url.is_valid())
return;
GURL sanitized_url =
brave::URLSanitizerServiceFactory::GetForBrowserContext(profile)
->SanitizeURL(url);
ui::ScopedClipboardWriter scoped_clipboard_writer(
ui::ClipboardBuffer::kCopyPaste);
scoped_clipboard_writer.WriteText(base::UTF8ToUTF16(sanitized_url.spec()));
}

int GetSearchEnginesID() {
return IDS_MANAGE_SEARCH_ENGINES_AND_SITE_SEARCH;
}

} // namespace

#define ShowBubble \
ShowBubble(); \
return; \
case IDC_COPY_CLEAN_LINK: \
BraveCopyCleanURL(location_bar_view_->profile(), model(), \
GetSelectedRange().GetMin(), GetSelectedText()); \
GetSelectedText

#undef IDS_MANAGE_SEARCH_ENGINES_AND_SITE_SEARCH
#define IDS_MANAGE_SEARCH_ENGINES_AND_SITE_SEARCH GetSearchEnginesID()); \
if (model()->CurrentTextIsURL() && !GetSelectedText().empty()) \
BraveUpdateContextMenu(menu_contents, \
controller()->GetLocationBarModel()->GetURL()
#define OmniboxPopupContentsView BraveOmniboxPopupContentsView
#include "src/chrome/browser/ui/views/omnibox/omnibox_view_views.cc"
#undef OmniboxPopupContentsView
#undef IDS_MANAGE_SEARCH_ENGINES_AND_SITE_SEARCH
#define IDS_MANAGE_SEARCH_ENGINES_AND_SITE_SEARCH GetSearchEnginesID()

#undef ShowBubble

0 comments on commit 8135599

Please sign in to comment.