-
Notifications
You must be signed in to change notification settings - Fork 870
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add copy clean link to the macOS application menu bar
- Loading branch information
1 parent
425992a
commit 96baed4
Showing
15 changed files
with
343 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* Copyright (c) 2022 The Brave Authors. All rights reserved. | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
* You can obtain one at https://mozilla.org/MPL/2.0/. */ | ||
|
||
#ifndef BRAVE_BROWSER_BRAVE_APP_CONTROLLER_MAC_H_ | ||
#define BRAVE_BROWSER_BRAVE_APP_CONTROLLER_MAC_H_ | ||
|
||
#import "chrome/browser/app_controller_mac.h" | ||
|
||
// Manages logic to switch hotkey between copy and copy clean link item. | ||
@interface BraveAppController : AppController { | ||
NSMenuItem* _copyMenuItem; | ||
NSMenuItem* _copyCleanLinkMenuItem; | ||
absl::optional<bool> _hasSelectedURLForTesting; | ||
} | ||
|
||
// Testing API. | ||
- (void)setCopyMenuItemForTesting:(NSMenuItem*)menuItem; // NOLINT | ||
- (void)setCopyCleanLinkMenuItemForTesting:(NSMenuItem*)menuItem; // NOLINT | ||
- (void)setSelectedURLForTesting:(bool)selected; // NOLINT | ||
|
||
@end | ||
|
||
#endif // BRAVE_BROWSER_BRAVE_APP_CONTROLLER_MAC_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* Copyright (c) 2022 The Brave Authors. All rights reserved. | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
* You can obtain one at https://mozilla.org/MPL/2.0/. */ | ||
|
||
#import "brave/browser/brave_app_controller_mac.h" | ||
|
||
#include "brave/app/brave_command_ids.h" | ||
#include "brave/browser/ui/browser_commands.h" | ||
#include "chrome/app/chrome_command_ids.h" | ||
#include "chrome/browser/ui/browser.h" | ||
#include "chrome/browser/ui/browser_commands.h" | ||
#include "chrome/browser/ui/browser_finder.h" | ||
#include "chrome/grit/generated_resources.h" | ||
|
||
@implementation BraveAppController | ||
|
||
- (void)mainMenuCreated { | ||
[super mainMenuCreated]; | ||
|
||
NSMenu* editMenu = [[[NSApp mainMenu] itemWithTag:IDC_EDIT_MENU] submenu]; | ||
_copyMenuItem = [editMenu itemWithTag:IDC_CONTENT_CONTEXT_COPY]; | ||
DCHECK(_copyMenuItem); | ||
[[_copyMenuItem menu] setDelegate:self]; | ||
_copyCleanLinkMenuItem = [editMenu itemWithTag:IDC_COPY_CLEAN_LINK]; | ||
DCHECK(_copyCleanLinkMenuItem); | ||
[[_copyCleanLinkMenuItem menu] setDelegate:self]; | ||
} | ||
|
||
- (void)dealloc { | ||
[[_copyMenuItem menu] setDelegate:nil]; | ||
[[_copyCleanLinkMenuItem menu] setDelegate:nil]; | ||
[super dealloc]; | ||
} | ||
|
||
- (Browser*)getBrowser { | ||
return chrome::FindBrowserWithProfile([self lastProfileIfLoaded]); | ||
} | ||
|
||
- (BOOL)shouldShowCleanLinkItem { | ||
if (_hasSelectedURLForTesting.has_value()) { | ||
return _hasSelectedURLForTesting.value(); | ||
} | ||
return brave::HasSelectedURL([self getBrowser]); | ||
} | ||
|
||
- (void)setKeyEquivalentToItem:(NSMenuItem*)item { | ||
auto* hootkeyItem = | ||
item == _copyMenuItem ? _copyMenuItem : _copyCleanLinkMenuItem; | ||
auto* noHootkeyItem = | ||
item == _copyMenuItem ? _copyCleanLinkMenuItem : _copyMenuItem; | ||
|
||
[hootkeyItem setKeyEquivalent:@"c"]; | ||
[hootkeyItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand]; | ||
|
||
[noHootkeyItem setKeyEquivalent:@""]; | ||
[noHootkeyItem setKeyEquivalentModifierMask:0]; | ||
} | ||
|
||
- (void)menuNeedsUpdate:(NSMenu*)menu { | ||
if (menu != [_copyMenuItem menu] && menu != [_copyCleanLinkMenuItem menu]) { | ||
[super menuNeedsUpdate:menu]; | ||
return; | ||
} | ||
if ([self shouldShowCleanLinkItem]) { | ||
[_copyCleanLinkMenuItem setHidden:NO]; | ||
[self setKeyEquivalentToItem:_copyCleanLinkMenuItem]; | ||
} else { | ||
[_copyCleanLinkMenuItem setHidden:YES]; | ||
[self setKeyEquivalentToItem:_copyMenuItem]; | ||
} | ||
} | ||
|
||
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { | ||
NSInteger tag = [item tag]; | ||
if (tag == IDC_COPY_CLEAN_LINK) { | ||
return [self shouldShowCleanLinkItem]; | ||
} | ||
return [super validateUserInterfaceItem:item]; | ||
} | ||
|
||
- (void)commandDispatch:(id)sender { | ||
NSInteger tag = [sender tag]; | ||
if (tag == IDC_COPY_CLEAN_LINK) { | ||
chrome::ExecuteCommand([self getBrowser], IDC_COPY_CLEAN_LINK); | ||
return; | ||
} | ||
|
||
[super commandDispatch:sender]; | ||
} | ||
|
||
- (void)setCopyMenuItemForTesting:(NSMenuItem*)menuItem { | ||
_copyMenuItem = menuItem; | ||
} | ||
|
||
- (void)setCopyCleanLinkMenuItemForTesting:(NSMenuItem*)menuItem { | ||
_copyCleanLinkMenuItem = menuItem; | ||
} | ||
- (void)setSelectedURLForTesting:(bool)value { | ||
_hasSelectedURLForTesting = value; | ||
} | ||
|
||
@end // @implementation BraveAppController |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* Copyright (c) 2022 The Brave Authors. All rights reserved. | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
* You can obtain one at https://mozilla.org/MPL/2.0/. */ | ||
|
||
#import <Cocoa/Cocoa.h> | ||
|
||
#import "brave/browser/brave_app_controller_mac.h" | ||
#include "content/public/test/browser_task_environment.h" | ||
#include "testing/platform_test.h" | ||
|
||
class BraveAppControllerTest : public PlatformTest { | ||
protected: | ||
BraveAppControllerTest() {} | ||
|
||
void SetUp() override { | ||
PlatformTest::SetUp(); | ||
braveAppController_.reset([[BraveAppController alloc] init]); | ||
copyMenuItem_.reset([[NSMenuItem alloc] initWithTitle:@"" | ||
action:0 | ||
keyEquivalent:@""]); | ||
[braveAppController_ setCopyMenuItemForTesting:copyMenuItem_]; | ||
|
||
copyCleanLinkMenuItem_.reset([[NSMenuItem alloc] initWithTitle:@"" | ||
action:0 | ||
keyEquivalent:@""]); | ||
[braveAppController_ | ||
setCopyCleanLinkMenuItemForTesting:copyCleanLinkMenuItem_]; | ||
} | ||
|
||
void TearDown() override { | ||
[braveAppController_ setCopyMenuItemForTesting:nil]; | ||
[braveAppController_ setCopyCleanLinkMenuItemForTesting:nil]; | ||
PlatformTest::TearDown(); | ||
} | ||
|
||
void CheckHotkeysOnCopyItem() { | ||
[braveAppController_ setSelectedURLForTesting:false]; | ||
|
||
[braveAppController_ menuNeedsUpdate:[copyMenuItem_ menu]]; | ||
|
||
EXPECT_TRUE([[copyMenuItem_ keyEquivalent] isEqualToString:@"c"]); | ||
EXPECT_EQ([copyMenuItem_ keyEquivalentModifierMask], | ||
NSEventModifierFlagCommand); | ||
|
||
EXPECT_TRUE([[copyCleanLinkMenuItem_ keyEquivalent] isEqualToString:@""]); | ||
EXPECT_EQ([copyCleanLinkMenuItem_ keyEquivalentModifierMask], 0UL); | ||
EXPECT_TRUE([copyCleanLinkMenuItem_ isHidden]); | ||
} | ||
|
||
void CheckHotkeysOnCleanLinkItem() { | ||
[braveAppController_ setSelectedURLForTesting:true]; | ||
|
||
[braveAppController_ menuNeedsUpdate:[copyMenuItem_ menu]]; | ||
|
||
EXPECT_TRUE([[copyMenuItem_ keyEquivalent] isEqualToString:@""]); | ||
EXPECT_EQ([copyMenuItem_ keyEquivalentModifierMask], 0UL); | ||
|
||
EXPECT_TRUE([[copyCleanLinkMenuItem_ keyEquivalent] isEqualToString:@"c"]); | ||
EXPECT_EQ([copyCleanLinkMenuItem_ keyEquivalentModifierMask], | ||
NSEventModifierFlagCommand); | ||
EXPECT_FALSE([copyCleanLinkMenuItem_ isHidden]); | ||
} | ||
|
||
base::scoped_nsobject<BraveAppController> braveAppController_; | ||
base::scoped_nsobject<NSMenuItem> copyMenuItem_; | ||
base::scoped_nsobject<NSMenuItem> copyCleanLinkMenuItem_; | ||
content::BrowserTaskEnvironment task_environment_; | ||
}; | ||
|
||
TEST_F(BraveAppControllerTest, OnlyCopyItem) { | ||
CheckHotkeysOnCopyItem(); | ||
} | ||
|
||
TEST_F(BraveAppControllerTest, CleanLinkItemAdded) { | ||
CheckHotkeysOnCleanLinkItem(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* Copyright (c) 2022 The Brave Authors. All rights reserved. | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
* You can obtain one at https://mozilla.org/MPL/2.0/. */ | ||
|
||
#include "brave/browser/ui/views/omnibox/brave_omnibox_view_views.h" | ||
|
||
#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" | ||
|
||
BraveOmniboxViewViews::BraveOmniboxViewViews( | ||
OmniboxEditController* controller, | ||
std::unique_ptr<OmniboxClient> client, | ||
bool popup_window_mode, | ||
LocationBarView* location_bar, | ||
const gfx::FontList& font_list) | ||
: OmniboxViewViews(controller, | ||
std::move(client), | ||
popup_window_mode, | ||
location_bar, | ||
font_list) {} | ||
|
||
BraveOmniboxViewViews::~BraveOmniboxViewViews() = default; | ||
|
||
bool BraveOmniboxViewViews::SelectedTextIsURL() { | ||
GURL url; | ||
bool write_url = false; | ||
std::u16string selected_text = GetSelectedText(); | ||
model()->AdjustTextForCopy(GetSelectedRange().GetMin(), &selected_text, &url, | ||
&write_url); | ||
return write_url; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* Copyright (c) 2022 The Brave Authors. All rights reserved. | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
* You can obtain one at https://mozilla.org/MPL/2.0/. */ | ||
|
||
#ifndef BRAVE_BROWSER_UI_VIEWS_OMNIBOX_BRAVE_OMNIBOX_VIEW_VIEWS_H_ | ||
#define BRAVE_BROWSER_UI_VIEWS_OMNIBOX_BRAVE_OMNIBOX_VIEW_VIEWS_H_ | ||
|
||
#include <memory> | ||
|
||
#include "chrome/browser/ui/views/omnibox/omnibox_view_views.h" | ||
|
||
class OmniboxEditController; | ||
class OmniboxClient; | ||
class LocationBarView; | ||
namespace gfx { | ||
class FontList; | ||
} // namespace gfx | ||
|
||
class BraveOmniboxViewViews : public OmniboxViewViews { | ||
public: | ||
BraveOmniboxViewViews(OmniboxEditController* controller, | ||
std::unique_ptr<OmniboxClient> client, | ||
bool popup_window_mode, | ||
LocationBarView* location_bar, | ||
const gfx::FontList& font_list); | ||
|
||
BraveOmniboxViewViews(const BraveOmniboxViewViews&) = delete; | ||
BraveOmniboxViewViews& operator=(const BraveOmniboxViewViews&) = delete; | ||
~BraveOmniboxViewViews() override; | ||
|
||
bool SelectedTextIsURL(); | ||
}; | ||
|
||
#endif // BRAVE_BROWSER_UI_VIEWS_OMNIBOX_BRAVE_OMNIBOX_VIEW_VIEWS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/* Copyright (c) 2022 The Brave Authors. All rights reserved. | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
* You can obtain one at https://mozilla.org/MPL/2.0/. */ | ||
|
||
#include "chrome/browser/chrome_browser_main_mac.h" | ||
#import "brave/browser/brave_app_controller_mac.h" | ||
|
||
#define AppController BraveAppController | ||
#include "src/chrome/browser/chrome_browser_main_mac.mm" |
Oops, something went wrong.