Skip to content

Commit

Permalink
Fix brave/brave-ios#6179: Add clean copy feature (brave/brave-ios#7696)
Browse files Browse the repository at this point in the history
  • Loading branch information
cuba authored Sep 15, 2023
1 parent 642693d commit e417faa
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -915,76 +915,96 @@ extension BrowserViewController: ToolbarDelegate {

extension BrowserViewController: UIContextMenuInteractionDelegate {
public func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {

let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { [unowned self] _ in
var actionMenus: [UIMenu?] = []
var pasteMenuChildren: [UIAction] = []

let tab = tabManager.selectedTab
var reloadMenu: UIMenu?
let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { [unowned self] _ in
let actionMenus: [UIMenu?] = [
makePasteMenu(), makeCopyMenu(), makeReloadMenu()
]

if let url = tab?.url, url.isWebPage() {
let reloadTitle = tab?.isDesktopSite == true ? Strings.appMenuViewMobileSiteTitleString : Strings.appMenuViewDesktopSiteTitleString
let reloadIcon = tab?.isDesktopSite == true ? "leo.smartphone" : "leo.monitor"
let reloadAction = UIAction(
title: reloadTitle,
image: UIImage(braveSystemNamed: reloadIcon),
handler: UIAction.deferredActionHandler { [weak tab] _ in
tab?.switchUserAgent()
})

reloadMenu = UIMenu(options: .displayInline, children: [reloadAction])
}

let pasteGoAction = UIAction(
return UIMenu(children: actionMenus.compactMap({ $0 }))
}

if #available(iOS 16.0, *) {
configuration.preferredMenuElementOrder = .priority
}

return configuration
}

/// Create the "Request Destop Site" / "Request Mobile Site" menu if the tab has a webpage loaded
private func makeReloadMenu() -> UIMenu? {
guard let tab = tabManager.selectedTab, let url = tab.url, url.isWebPage() else { return nil }
let reloadTitle = tab.isDesktopSite == true ? Strings.appMenuViewMobileSiteTitleString : Strings.appMenuViewDesktopSiteTitleString
let reloadIcon = tab.isDesktopSite == true ? "leo.smartphone" : "leo.monitor"
let reloadAction = UIAction(
title: reloadTitle,
image: UIImage(braveSystemNamed: reloadIcon),
handler: UIAction.deferredActionHandler { [weak tab] _ in
tab?.switchUserAgent()
})

return UIMenu(options: .displayInline, children: [reloadAction])
}

/// Create the "Paste" and "Paste and Go" menu if there is anything on the `UIPasteboard`
private func makePasteMenu() -> UIMenu? {
guard UIPasteboard.general.hasStrings || UIPasteboard.general.hasURLs else { return nil }

var children: [UIAction] = [
UIAction(
identifier: .pasteAndGo,
handler: UIAction.deferredActionHandler { _ in
if let pasteboardContents = UIPasteboard.general.string {
self.topToolbar(self.topToolbar, didSubmitText: pasteboardContents)
}
})

let pasteAction = UIAction(
}
),
UIAction(
identifier: .paste,
handler: UIAction.deferredActionHandler { _ in
if let pasteboardContents = UIPasteboard.general.string {
self.topToolbar.enterOverlayMode(pasteboardContents, pasted: true, search: true)
}
})

pasteMenuChildren = [pasteGoAction, pasteAction]

if #unavailable(iOS 16.0), isUsingBottomBar {
pasteMenuChildren.reverse()
}

let copyAction = UIAction(
title: Strings.copyAddressTitle,
}
)
]

if #unavailable(iOS 16.0), isUsingBottomBar {
children.reverse()
}

return UIMenu(options: .displayInline, children: children)
}

/// Create the "Copy Link" and "Copy Clean Link" menu if there is any URL loaded on the tab.
///
/// - Note: "Copy Clean Link" will be included even if no cleaning is done to the url.
private func makeCopyMenu() -> UIMenu? {
let tab = tabManager.selectedTab
guard let url = self.topToolbar.currentURL else { return nil }

var children: [UIAction] = [
UIAction(
title: Strings.copyLinkActionTitle,
image: UIImage(systemName: "doc.on.doc"),
handler: UIAction.deferredActionHandler { _ in
if let url = self.topToolbar.currentURL {
UIPasteboard.general.url = url as URL
}
})

let copyMenu = UIMenu(options: .displayInline, children: [copyAction])

if UIPasteboard.general.hasStrings || UIPasteboard.general.hasURLs {
let pasteMenu = UIMenu(options: .displayInline, children: pasteMenuChildren)
actionMenus.append(contentsOf: [pasteMenu, copyMenu])
} else {
actionMenus.append(copyMenu)
}

actionMenus.append(reloadMenu)

return UIMenu(children: actionMenus.compactMap { $0 })
}
UIPasteboard.general.url = url as URL
}
),
UIAction(
title: Strings.copyCleanLink,
image: UIImage(braveSystemNamed: "leo.broom"),
handler: UIAction.deferredActionHandler { _ in
let service = URLSanitizerServiceFactory.get(privateMode: tab?.isPrivate ?? true)
let cleanedURL = service?.sanitizeURL(url) ?? url
UIPasteboard.general.url = cleanedURL
}
)
]

if #available(iOS 16.0, *) {
configuration.preferredMenuElementOrder = .priority
if #unavailable(iOS 16.0), isUsingBottomBar {
children.reverse()
}

return configuration
return UIMenu(options: .displayInline, children: children)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,7 @@ extension BrowserViewController: WKUIDelegate {
}
}
openNewPrivateTabAction.accessibilityLabel = "linkContextMenu.openInNewPrivateTab"

actions.append(openNewPrivateTabAction)

if UIApplication.shared.supportsMultipleScenes {
Expand Down Expand Up @@ -1019,13 +1020,25 @@ extension BrowserViewController: WKUIDelegate {

let copyAction = UIAction(
title: Strings.copyLinkActionTitle,
image: UIImage(systemName: "doc.on.doc")
) { _ in
UIPasteboard.general.url = url
}
image: UIImage(systemName: "doc.on.doc"),
handler: UIAction.deferredActionHandler { _ in
UIPasteboard.general.url = url as URL
}
)
copyAction.accessibilityLabel = "linkContextMenu.copyLink"

actions.append(copyAction)

let copyCleanLinkAction = UIAction(
title: Strings.copyCleanLink,
image: UIImage(braveSystemNamed: "leo.broom"),
handler: UIAction.deferredActionHandler { _ in
let service = URLSanitizerServiceFactory.get(privateMode: currentTab.isPrivate)
let cleanedURL = service?.sanitizeURL(url) ?? url
UIPasteboard.general.url = cleanedURL
}
)
copyCleanLinkAction.accessibilityLabel = "linkContextMenu.copyCleanLink"
actions.append(copyCleanLinkAction)

if let braveWebView = webView as? BraveWebView {
let shareAction = UIAction(
Expand Down
9 changes: 8 additions & 1 deletion Sources/BraveStrings/BraveStrings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ extension Strings {
public static let download = NSLocalizedString("CommonDownload", tableName: "BraveShared", bundle: .module, value: "Download", comment: "Text to choose for downloading a file (example: saving an image to phone)")
public static let showLinkPreviewsActionTitle = NSLocalizedString("ShowLinkPreviewsActionTitle", tableName: "BraveShared", bundle: .module, value: "Show Link Previews", comment: "Context menu item for showing link previews")
public static let hideLinkPreviewsActionTitle = NSLocalizedString("HideLinkPreviewsActionTitle", tableName: "BraveShared", bundle: .module, value: "Hide Link Previews", comment: "Context menu item for hiding link previews")
public static let copyAddressTitle = NSLocalizedString("CopyAddressTitle", bundle: .module, value: "Copy Address", comment: "The title for the button that lets you copy the url from the location bar.")
public static let learnMore = NSLocalizedString(
"learnMore", tableName: "BraveShared",
bundle: .module, value: "Learn More", comment: "")
Expand Down Expand Up @@ -974,6 +973,14 @@ extension Strings {
public static let codeWordInputHelp = NSLocalizedString("CodeWordInputHelp", tableName: "BraveShared", bundle: .module, value: "Type your supplied sync chain code words into the form below.", comment: "Code words input help")
public static let copyToClipboard = NSLocalizedString("CopyToClipboard", tableName: "BraveShared", bundle: .module, value: "Copy to Clipboard", comment: "Copy codewords title")
public static let copiedToClipboard = NSLocalizedString("CopiedToClipboard", tableName: "BraveShared", bundle: .module, value: "Copied to Clipboard!", comment: "Copied codewords title")

/// A menu option available when long pressing on a link which allows you to copy a clean version of the url which strips out some query parameters.
public static let copyCleanLink = NSLocalizedString(
"CopyCleanLink", tableName: "BraveShared", bundle: .module,
value: "Copy Clean Link",
comment: "A menu option available when long pressing on a link which allows you to copy a clean version of the url which strips out some query parameters."
)

public static let syncUnsuccessful = NSLocalizedString("SyncUnsuccessful", tableName: "BraveShared", bundle: .module, value: "Unsuccessful", comment: "")
public static let syncUnableCreateGroup = NSLocalizedString("SyncUnableCreateGroup", tableName: "BraveShared", bundle: .module, value: "Can't sync this device", comment: "Description on popup when setting up a sync group fails")
public static let copied = NSLocalizedString("Copied", tableName: "BraveShared", bundle: .module, value: "Copied!", comment: "Copied action complete title")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"symbols" : [
{
"idiom" : "universal"
}
]
}
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@mozilla/readability": "^0.4.2",
"brave-core-ios": "https://github.com/brave/brave-browser/releases/download/v1.58.124/brave-core-ios-1.58.124.tgz",
"leo": "github:brave/leo#7f2dfddb70aff1501ef5a2f3c640a8c74a7343ee",
"leo-sf-symbols": "github:brave/leo-sf-symbols#72bf8ce76567d29ebe2a0932d17fb015956c48bc",
"leo-sf-symbols": "github:brave/leo-sf-symbols#d6056328b8d6ef06e68996ff02a22e06f52590c3",
"page-metadata-parser": "^1.1.3",
"webpack-cli": "^4.8.0"
},
Expand Down

0 comments on commit e417faa

Please sign in to comment.