Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3483,6 +3483,18 @@ class BrowserTabFragment :
return message.data.getString(URL_BUNDLE_KEY)
}

/**
* Use requestFocusNodeHref to get the a tag title for the touched link.
*/
private fun getTargetTitleForLinkSource(): String? {
val handler = Handler()
val message = handler.obtainMessage()

webView?.requestFocusNodeHref(message)

return message.data.getString(TITLE_BUNDLE_KEY)?.trim()
}

private fun getLongPressTarget(hitTestResult: HitTestResult): LongPressTarget? {
return when {
hitTestResult.extra == null -> null
Expand All @@ -3502,6 +3514,7 @@ class BrowserTabFragment :
else -> LongPressTarget(
url = hitTestResult.extra,
type = hitTestResult.type,
text = getTargetTitleForLinkSource(),
)
}
}
Expand Down Expand Up @@ -4100,6 +4113,7 @@ class BrowserTabFragment :
private const val PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 200

private const val URL_BUNDLE_KEY = "url"
private const val TITLE_BUNDLE_KEY = "title"

private const val DOWNLOAD_CONFIRMATION_TAG = "DOWNLOAD_CONFIRMATION_TAG"
private const val DAX_DIALOG_DIALOG_TAG = "DAX_DIALOG_TAG"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2579,7 +2579,7 @@ class BrowserTabViewModel @Inject constructor(
menu: ContextMenu,
) {
logcat(INFO) { "Long pressed on ${target.type}, (url=${target.url}), (image url = ${target.imageUrl})" }
longPressHandler.handleLongPress(target.type, target.url, menu)
longPressHandler.handleLongPress(target.type, target.url, target.text, menu)
}

fun userSelectedItemFromLongPressMenu(
Expand Down Expand Up @@ -2625,6 +2625,11 @@ class BrowserTabViewModel @Inject constructor(
true
}

is RequiredAction.CopyLinkText -> {
command.value = CopyLink(requiredAction.text)
true
}

RequiredAction.None -> {
false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ interface LongPressHandler {
fun handleLongPress(
longPressTargetType: Int,
longPressTargetUrl: String?,
longPressTargetTitle: String?,
menu: ContextMenu,
)

Expand All @@ -50,6 +51,7 @@ interface LongPressHandler {
class DownloadFile(val url: String) : RequiredAction()
class ShareLink(val url: String) : RequiredAction()
class CopyLink(val url: String) : RequiredAction()
class CopyLinkText(val text: String) : RequiredAction()
}
}

Expand All @@ -62,6 +64,7 @@ class WebViewLongPressHandler @Inject constructor(
override fun handleLongPress(
longPressTargetType: Int,
longPressTargetUrl: String?,
longPressTargetTitle: String?,
menu: ContextMenu,
) {
menu.setHeaderTitle(longPressTargetUrl?.take(MAX_TITLE_LENGTH) ?: context.getString(R.string.options))
Expand Down Expand Up @@ -93,6 +96,10 @@ class WebViewLongPressHandler @Inject constructor(
if (!customTabDetector.isCustomTab()) {
addLinkMenuOpenInTabOptions(menu)
}
if (!longPressTargetTitle.isNullOrEmpty()) {
addLinkMenuCopyLinkTextOptions(menu)
}

addLinkMenuOtherOptions(menu)
}
}
Expand Down Expand Up @@ -125,6 +132,10 @@ class WebViewLongPressHandler @Inject constructor(
menu.add(0, CONTEXT_MENU_ID_SHARE_LINK, CONTEXT_MENU_ID_SHARE_LINK, R.string.shareLink)
}

private fun addLinkMenuCopyLinkTextOptions(menu: ContextMenu) {
menu.add(0, CONTEXT_MENU_ID_COPY_TEXT, CONTEXT_MENU_ID_COPY_TEXT, R.string.copyText)
}

private fun isLinkSupported(longPressTargetUrl: String?) = URLUtil.isNetworkUrl(longPressTargetUrl) || URLUtil.isDataUrl(longPressTargetUrl)

override fun userSelectedMenuItem(
Expand Down Expand Up @@ -162,6 +173,11 @@ class WebViewLongPressHandler @Inject constructor(
val url = longPressTarget.url ?: return None
return CopyLink(url)
}
CONTEXT_MENU_ID_COPY_TEXT -> {
// pixel.fire(LONG_PRESS_COPY_TEXT)
val text = longPressTarget.text ?: return None
return CopyLinkText(text)
}
else -> None
}
}
Expand All @@ -173,6 +189,7 @@ class WebViewLongPressHandler @Inject constructor(
const val CONTEXT_MENU_ID_SHARE_LINK = 4
const val CONTEXT_MENU_ID_DOWNLOAD_IMAGE = 5
const val CONTEXT_MENU_ID_OPEN_IMAGE_IN_NEW_BACKGROUND_TAB = 6
const val CONTEXT_MENU_ID_COPY_TEXT = 7

private const val MAX_TITLE_LENGTH = 100
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ data class LongPressTarget(
val url: String?,
val type: Int,
val imageUrl: String? = null,
val text: String? = null,
)
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
<string name="shareLink">Share Link</string>
<string name="shareMenuTitle">Share</string>
<string name="copyUrl">Copy Link Address</string>
<string name="copyText">Copy Link Text</string>

<!-- Find in page -->
<string name="findInPageMenuTitle">Find in Page</string>
Expand Down
Loading