Skip to content

Commit

Permalink
Merge pull request #2672 from nextcloud/fix/stable24/link_handling
Browse files Browse the repository at this point in the history
Backport link fixes to stable24
  • Loading branch information
max-nextcloud committed Jul 6, 2022
2 parents e1f374f + 0a5c403 commit 0ca9864
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 68 deletions.
4 changes: 2 additions & 2 deletions js/editor.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/editor.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/text-files.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/text-files.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/text-public.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/text-public.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/text-text.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/text-text.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/text-viewer.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/text-viewer.js.map

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions src/helpers/links.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

import { generateUrl } from '@nextcloud/router'
import markdownit from './../markdownit/index.js'

const absolutePath = function(base, rel) {
if (!rel) {
Expand Down Expand Up @@ -77,7 +78,38 @@ const parseHref = function(dom) {
return ref
}

const openLink = function(event, _attrs) {
const linkElement = event.target.closest('a')
const htmlHref = linkElement.href
const query = OC.parseQueryString(htmlHref)
const fragment = OC.parseQueryString(htmlHref.split('#').pop())
if (query.dir && fragment.relPath) {
const filename = fragment.relPath.split('/').pop()
const path = `${query.dir}/${filename}`
document.title = `${filename} - ${OC.theme.title}`
if (window.location.pathname.match(/apps\/files\/$/)) {
// The files app still lacks a popState handler
// to allow for using the back button
// OC.Util.History.pushState('', htmlHref)
}
OCA.Viewer.open({ path })
return
}
if (query.fileId) {
// open the direct file link
window.open(generateUrl(`/f/${query.fileId}`))
return
}
if (!markdownit.validateLink(htmlHref)) {
console.error('Invalid link', htmlHref)
return false
}
window.open(htmlHref)
return true
}

export {
domHref,
parseHref,
openLink,
}
38 changes: 27 additions & 11 deletions src/marks/Link.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,29 @@
*/

import TipTapLink from '@tiptap/extension-link'
import { domHref, parseHref } from './../helpers/links.js'
import { domHref, parseHref, openLink } from './../helpers/links.js'
import { clickHandler } from '../plugins/link.js'

const Link = TipTapLink.extend({

attrs: {
href: {
default: null,
},
addOptions() {
return {
...this.parent?.(),
onClick: openLink,
}
},

addAttributes() {
return {
href: {
default: null,
},
}
},

inclusive: false,

parseDOM: [
parseHTML: [
{
tag: 'a[href]',
getAttrs: dom => ({
Expand All @@ -43,10 +52,10 @@ const Link = TipTapLink.extend({
},
],

toDOM: node => ['a', {
...node.attrs,
href: domHref(node),
title: node.attrs.href,
renderHTML: ({ mark, HTMLAttributes }) => ['a', {
...mark.attrs,
href: domHref(mark),
title: mark.attrs.href,
rel: 'noopener noreferrer nofollow',
}, 0],

Expand All @@ -62,7 +71,14 @@ const Link = TipTapLink.extend({
}

// add custom click handler
return [...plugins, clickHandler({ editor: this.editor, type: this.type })]
return [
...plugins,
clickHandler({
editor: this.editor,
type: this.type,
onClick: this.options.onClick,
}),
]
},
})

Expand Down
58 changes: 16 additions & 42 deletions src/plugins/link.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,25 @@
import { generateUrl } from '@nextcloud/router'
import { Plugin } from 'prosemirror-state'
import markdownit from './../markdownit/index.js'
import { Plugin, PluginKey } from 'prosemirror-state'

const clickHandler = ({ editor }) => {
const clickHandler = ({ editor, type, onClick }) => {
return new Plugin({
props: {
key: new PluginKey('textLink'),
handleClick: (view, pos, event) => {
const linkElement = event.target.parentElement instanceof HTMLAnchorElement
? event.target.parentElement
: event.target

const isLink = linkElement && linkElement instanceof HTMLAnchorElement

const htmlHref = linkElement?.href
const $clicked = view.state.doc.resolve(pos)
const link = $clicked.marks().find(m => m.type.name === type.name)
if (!link) {
return false
}
if (!link.attrs.href) {
console.warn('Could not determine href of link.')
console.debug(link)
return false
}

// is handleable link
if (htmlHref && isLink) {
// We use custom onClick handler only for left clicks
if (event.button === 0 && !event.ctrlKey) {
event.stopPropagation()

if (event.button === 0 && !event.ctrlKey && htmlHref.startsWith(window.location.origin)) {
const query = OC.parseQueryString(htmlHref)
const fragment = OC.parseQueryString(htmlHref.split('#').pop())
if (query.dir && fragment.relPath) {
const filename = fragment.relPath.split('/').pop()
const path = `${query.dir}/${filename}`
document.title = `${filename} - ${OC.theme.title}`
if (window.location.pathname.match(/apps\/files\/$/)) {
// The files app still lacks a popState handler
// to allow for using the back button
// OC.Util.History.pushState('', htmlHref)
}
OCA.Viewer.open({ path })
return
}
if (query.fileId) {
// open the direct file link
window.open(generateUrl(`/f/${query.fileId}`))
return
}
}

if (!markdownit.validateLink(htmlHref)) {
console.error('Invalid link', htmlHref)
return
}

window.open(htmlHref)
return onClick?.(event, link.attrs)
}
},
},
Expand Down

0 comments on commit 0ca9864

Please sign in to comment.