Skip to content

Commit 38f2616

Browse files
authored
Merge pull request #93 from susanwere/fix-pasting-markdown-with-html
fix pasting of markdown containing links
2 parents 239dfc2 + 8d487f9 commit 38f2616

File tree

2 files changed

+52
-14
lines changed

2 files changed

+52
-14
lines changed

Diff for: src/paste-markdown-html.ts

+13-14
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function onPaste(event: ClipboardEvent) {
3737
// Generate DOM tree from HTML string
3838
const parser = new DOMParser()
3939
const doc = parser.parseFromString(textHTMLClean, 'text/html')
40-
const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ELEMENT, node =>
40+
const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ALL, node =>
4141
node.parentNode && isLink(node.parentNode) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT,
4242
)
4343

@@ -64,15 +64,17 @@ function convertToMarkdown(plaintext: string, walker: TreeWalker): string {
6464
index++
6565
const text = isLink(currentNode)
6666
? (currentNode.textContent || '').replace(/[\t\n\r ]+/g, ' ')
67-
: (currentNode.firstChild as Text)?.wholeText || ''
67+
: (currentNode as Text)?.wholeText || ''
68+
69+
// No need to transform whitespace
70+
if (isEmptyString(text)) {
71+
currentNode = walker.nextNode()
72+
continue
73+
}
6874

6975
// update value of markdownIgnoreBeforeIndex with current index if the current node is not a link
7076
if (!isLink(currentNode)) {
7177
markdownIgnoreBeforeIndex += text.replace(/[\t\n\r ]+/g, ' ').trimStart().length
72-
}
73-
74-
// No need to transform whitespace
75-
if (isEmptyString(text)) {
7678
currentNode = walker.nextNode()
7779
continue
7880
}
@@ -81,14 +83,11 @@ function convertToMarkdown(plaintext: string, walker: TreeWalker): string {
8183
const markdownFoundIndex = markdown.indexOf(text, markdownIgnoreBeforeIndex)
8284

8385
if (markdownFoundIndex >= 0) {
84-
if (isLink(currentNode)) {
85-
const markdownLink = linkify(currentNode, text)
86-
// Transform 'example link plus more text' into 'example [link](example link) plus more text'
87-
// Method: 'example [link](example link) plus more text' = 'example ' + '[link](example link)' + ' plus more text'
88-
markdown =
89-
markdown.slice(0, markdownFoundIndex) + markdownLink + markdown.slice(markdownFoundIndex + text.length)
90-
markdownIgnoreBeforeIndex = markdownFoundIndex + markdownLink.length
91-
}
86+
const markdownLink = linkify(currentNode, text)
87+
// Transform 'example link plus more text' into 'example [link](example link) plus more text'
88+
// Method: 'example [link](example link) plus more text' = 'example ' + '[link](example link)' + ' plus more text'
89+
markdown = markdown.slice(0, markdownFoundIndex) + markdownLink + markdown.slice(markdownFoundIndex + text.length)
90+
markdownIgnoreBeforeIndex = markdownFoundIndex + markdownLink.length
9291
}
9392

9493
currentNode = walker.nextNode()

Diff for: test/test.js

+39
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,45 @@ describe('paste-markdown', function () {
443443
paste(textarea, {'text/html': sentence, 'text/plain': plaintextSentence})
444444
assert.equal(textarea.value, markdownSentence)
445445
})
446+
447+
it('finds the right link when identical labels are present chrome and edge', function () {
448+
// eslint-disable-next-line github/unescaped-html-literal
449+
const sentence = `<meta charset='utf-8'>
450+
<p>foo bar<br>bar<span> </span><a href="https://www.abcxyz.org/">bar</a></p><p>bar<span> </span><a href="https://www.abcxyz.com/">bar</a><span> </span>foo</p>`
451+
452+
const markdownSentence = `foo bar
453+
bar [bar](https://www.abcxyz.org/)
454+
455+
bar [bar](https://www.abcxyz.com/) foo`
456+
457+
const plaintextSentence = `foo bar
458+
bar bar
459+
460+
bar bar foo`
461+
462+
paste(textarea, {'text/html': sentence, 'text/plain': plaintextSentence})
463+
assert.equal(textarea.value, markdownSentence)
464+
})
465+
466+
it('finds the right link when identical labels are present firefox', function () {
467+
// eslint-disable-next-line github/unescaped-html-literal
468+
const sentence = `<meta charset='utf-8'>
469+
<div><div><p>foo bar<br>
470+
bar <a href="https://www.abcxyz.org/">bar</a></p>
471+
<p>bar <a href="https://www.abcxyz.com/">bar</a> foo</p></div></div>`
472+
const markdownSentence = `foo bar
473+
bar [bar](https://www.abcxyz.org/)
474+
475+
bar [bar](https://www.abcxyz.com/) foo`
476+
477+
const plaintextSentence = `foo bar
478+
bar bar
479+
480+
bar bar foo`
481+
482+
paste(textarea, {'text/html': sentence, 'text/plain': plaintextSentence})
483+
assert.equal(textarea.value, markdownSentence)
484+
})
446485
})
447486
})
448487

0 commit comments

Comments
 (0)