Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Remove Link" option in the right-click context menu for links #5126

Merged
merged 17 commits into from
Jun 8, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import showPopupMenu from '@common/modules/window-register/application-menu-help
import { type AnyMenuItem } from '@dts/renderer/context'
import { type SyntaxNode } from '@lezer/common'
import openMarkdownLink from '../util/open-markdown-link'
import { removeMarkdownLink } from '../util/remove-markdown-link'
import { shortenUrlVisually } from '@common/util/shorten-url-visually'
import makeValidUri from 'source/common/util/make-valid-uri'
import { pathDirname } from 'source/common/util/renderer-path-polyfill'
Expand Down Expand Up @@ -87,6 +88,12 @@ export function linkImageMenu (view: EditorView, node: SyntaxNode, coords: { x:
enabled: true,
type: 'normal',
label: (url.indexOf('mailto:') === 0) ? trans('Copy Mail Address') : trans('Copy Link')
},
{
id: 'menu.remove_link',
enabled: true,
type: 'normal',
label: trans('Remove Link')
}
]

Expand Down Expand Up @@ -127,6 +134,14 @@ export function linkImageMenu (view: EditorView, node: SyntaxNode, coords: { x:
})
} else if (clickedID === 'open-img-in-browser') {
window.location.href = validAbsoluteURI
} else if (clickedID === 'menu.remove_link') {
if (node.type.name === 'URL' && node.parent?.type.name === 'Link') {
// Handles when user clicks on (url) node in the [text](url) type link
removeMarkdownLink(node.parent, view)
} else {
// Handles when user clicks on [text] part of [text](url) type link or <url> part of <url> type link
removeMarkdownLink(node, view)
}
}
})
}
60 changes: 60 additions & 0 deletions source/common/modules/markdown-editor/util/remove-markdown-link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* @ignore
* BEGIN HEADER
*
* Contains: removeMarkdownLink function
* CVM-Role: Utility function
* Maintainers: Neil Mazumdar NMazzy
* Maxwell Bruce MWBruce
* License: GNU GPL v3
*
* Description: This function removes a markdown link, performing necessary
* transformations where applicable.
*
* END HEADER
*/

import { type EditorView } from '@codemirror/view'
import { type ChangeSpec } from '@codemirror/state'
import { type SyntaxNode } from '@lezer/common'
import { shortenUrlVisually } from 'source/common/util/shorten-url-visually'

/**
* Utility to remove a markdown link. It extracts the text from the markdown
* link and replaces the link with just the text.
*
* @param {EditorView} view - The editor view
* @param {SyntaxNode} node - The node containing the Link
*/
export function removeMarkdownLink (node: SyntaxNode, view: EditorView): void {
const from = node.from
const to = node.to
var linkText: string

if (node.type.name === 'URL') {
linkText = view.state.sliceDoc(from, to)

if ((linkText[0] === '<') && (linkText[linkText.length-1] === '>')) {
// This is where the URL with <> formate is parsed
// We remove the < > brackets from the link text\
const regex = /<([^>]+)>/g;
const match = regex.exec(linkText)

if (match !== null) {
linkText = match[1]
} else {
console.error('Unable to parse <> style URL')
return
}
} else {
// LinkText is already a URL
}
} else {
// This is where the URL with []() format is parsed
// Using same logic seen in AST Parser to get the text between the []
const marks = node.getChildren('LinkMark')
linkText = view.state.sliceDoc(marks[0].to, marks[1].from)
}
const changes: ChangeSpec = { from, to, insert: linkText }
view.dispatch({ changes })
}