diff --git a/src/paste-markdown-html.ts b/src/paste-markdown-html.ts index 6ad7baa..d7c3fa0 100644 --- a/src/paste-markdown-html.ts +++ b/src/paste-markdown-html.ts @@ -37,7 +37,7 @@ function onPaste(event: ClipboardEvent) { // Generate DOM tree from HTML string const parser = new DOMParser() const doc = parser.parseFromString(textHTMLClean, 'text/html') - const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ELEMENT, node => + const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ALL, node => node.parentNode && isLink(node.parentNode) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT, ) @@ -64,15 +64,17 @@ function convertToMarkdown(plaintext: string, walker: TreeWalker): string { index++ const text = isLink(currentNode) ? (currentNode.textContent || '').replace(/[\t\n\r ]+/g, ' ') - : (currentNode.firstChild as Text)?.wholeText || '' + : (currentNode as Text)?.wholeText || '' + + // No need to transform whitespace + if (isEmptyString(text)) { + currentNode = walker.nextNode() + continue + } // update value of markdownIgnoreBeforeIndex with current index if the current node is not a link if (!isLink(currentNode)) { markdownIgnoreBeforeIndex += text.replace(/[\t\n\r ]+/g, ' ').trimStart().length - } - - // No need to transform whitespace - if (isEmptyString(text)) { currentNode = walker.nextNode() continue } @@ -81,14 +83,11 @@ function convertToMarkdown(plaintext: string, walker: TreeWalker): string { const markdownFoundIndex = markdown.indexOf(text, markdownIgnoreBeforeIndex) if (markdownFoundIndex >= 0) { - if (isLink(currentNode)) { - const markdownLink = linkify(currentNode, text) - // Transform 'example link plus more text' into 'example [link](example link) plus more text' - // Method: 'example [link](example link) plus more text' = 'example ' + '[link](example link)' + ' plus more text' - markdown = - markdown.slice(0, markdownFoundIndex) + markdownLink + markdown.slice(markdownFoundIndex + text.length) - markdownIgnoreBeforeIndex = markdownFoundIndex + markdownLink.length - } + const markdownLink = linkify(currentNode, text) + // Transform 'example link plus more text' into 'example [link](example link) plus more text' + // Method: 'example [link](example link) plus more text' = 'example ' + '[link](example link)' + ' plus more text' + markdown = markdown.slice(0, markdownFoundIndex) + markdownLink + markdown.slice(markdownFoundIndex + text.length) + markdownIgnoreBeforeIndex = markdownFoundIndex + markdownLink.length } currentNode = walker.nextNode() diff --git a/test/test.js b/test/test.js index 775e16a..dcf266a 100644 --- a/test/test.js +++ b/test/test.js @@ -443,6 +443,45 @@ describe('paste-markdown', function () { paste(textarea, {'text/html': sentence, 'text/plain': plaintextSentence}) assert.equal(textarea.value, markdownSentence) }) + + it('finds the right link when identical labels are present chrome and edge', function () { + // eslint-disable-next-line github/unescaped-html-literal + const sentence = ` +
foo bar
bar bar
bar bar foo
` + + const markdownSentence = `foo bar +bar [bar](https://www.abcxyz.org/) + +bar [bar](https://www.abcxyz.com/) foo` + + const plaintextSentence = `foo bar +bar bar + +bar bar foo` + + paste(textarea, {'text/html': sentence, 'text/plain': plaintextSentence}) + assert.equal(textarea.value, markdownSentence) + }) + + it('finds the right link when identical labels are present firefox', function () { + // eslint-disable-next-line github/unescaped-html-literal + const sentence = ` + ` + const markdownSentence = `foo bar +bar [bar](https://www.abcxyz.org/) + +bar [bar](https://www.abcxyz.com/) foo` + + const plaintextSentence = `foo bar +bar bar + +bar bar foo` + + paste(textarea, {'text/html': sentence, 'text/plain': plaintextSentence}) + assert.equal(textarea.value, markdownSentence) + }) }) })