Skip to content

Commit 78a8ee6

Browse files
author
mokimo
committed
feat(clipboard): Copy&Paste keeps links relative
1 parent ef1e8a6 commit 78a8ee6

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

spec/clipboard.spec.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { parseContent } from '../src/clipboard'
1+
import { parseContent, updateConfig } from '../src/clipboard'
2+
import * as config from '../src/config'
23

34
describe('Clipboard', () => {
45
describe('parseContent()', () => {
@@ -142,5 +143,12 @@ describe('Clipboard', () => {
142143

143144
expect(parseContent(div)[0]).toEqual('bar')
144145
})
146+
147+
it('keeps internal links of a anchorTag with an href attribute', () => {
148+
expect(extractSingleBlock('<a href="http://localhost:9876/test123">a</a>')).toEqual('<a href="http://localhost:9876/test123">a</a>')
149+
config.pastedHtmlRules.keepInternalRelativeLinks = true
150+
updateConfig(config)
151+
expect(extractSingleBlock('<a href="http://localhost:9876/test123">a</a>')).toEqual('<a href="/test123">a</a>')
152+
})
145153
})
146154
})

src/clipboard.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ let allowedElements, requiredAttributes, transformElements, blockLevelElements
88
let splitIntoBlocks, blacklistedElements
99
let whitespaceOnly = /^\s*$/
1010
let blockPlaceholder = '<!-- BLOCK -->'
11+
let keepInternalRelativeLinks
1112

1213
updateConfig(config)
1314
export function updateConfig (config) {
@@ -16,6 +17,7 @@ export function updateConfig (config) {
1617
requiredAttributes = rules.requiredAttributes || {}
1718
transformElements = rules.transformElements || {}
1819
blacklistedElements = rules.blacklistedElements || []
20+
keepInternalRelativeLinks = rules.keepInternalRelativeLinks || false
1921

2022
blockLevelElements = {}
2123
rules.blockLevelElements.forEach((name) => { blockLevelElements[name] = true })
@@ -41,7 +43,6 @@ export function paste (element, cursor, callback) {
4143
const blocks = parseContent(pasteHolder)
4244
$(pasteHolder).remove()
4345
element.removeAttribute(config.pastingAttribute)
44-
4546
cursor.restore()
4647
callback(blocks, cursor)
4748
}, 0)
@@ -68,6 +69,8 @@ export function injectPasteholder (document) {
6869
* - Parse pasted content
6970
* - Split it up into blocks
7071
* - clean and normalize every block
72+
* - optionally strip the host location an anchorTag-href
73+
* www.livindocs.io/internalLink -> /internalLink
7174
*
7275
* @param {DOM node} A container where the pasted content is located.
7376
* @returns {Array of Strings} An array of cleaned innerHTML like strings.
@@ -87,14 +90,19 @@ export function filterHtmlElements (elem) {
8790
return ''
8891
}
8992

93+
// Keep internal relative links relative (on paste).
94+
if (keepInternalRelativeLinks && child.nodeName === 'A' && child.href) {
95+
const stripInternalHost = child.href.replace(window.location.origin, '')
96+
child.setAttribute('href', stripInternalHost)
97+
}
98+
9099
if (child.nodeType === nodeType.elementNode) {
91100
const childContent = filterHtmlElements(child)
92101
return content + conditionalNodeWrap(child, childContent)
93102
}
94103

95104
// Escape HTML characters <, > and &
96105
if (child.nodeType === nodeType.textNode) return content + string.escapeHtml(child.nodeValue)
97-
98106
return content
99107
}, '')
100108
}

src/config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,7 @@ export const pastedHtmlRules = {
7070

7171
// A list of elements that will get completly removed when pasted. Their tags
7272
// and content (text content and child elements) will get removed.
73-
blacklistedElements: ['style', 'script']
73+
blacklistedElements: ['style', 'script'],
74+
75+
keepInternalRelativeLinks: false
7476
}

0 commit comments

Comments
 (0)