Skip to content

Commit 26e6288

Browse files
authored
Merge pull request #19 from github/dont-throw-away-text-around-table
Retain other text around HTML tables
2 parents cccc5ea + 4813e90 commit 26e6288

File tree

2 files changed

+43
-19
lines changed

2 files changed

+43
-19
lines changed

src/paste-markdown-table.ts

+17-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* @flow strict */
2-
31
import {insertText} from './text'
42

53
export function install(el: HTMLElement): void {
@@ -17,18 +15,17 @@ export function uninstall(el: HTMLElement): void {
1715
function onDrop(event: DragEvent) {
1816
const transfer = event.dataTransfer
1917
if (!transfer) return
20-
2118
if (hasFile(transfer)) return
2219

23-
const table = hasTable(transfer)
24-
if (!table) return
20+
const textToPaste = generateText(transfer)
21+
if (!textToPaste) return
2522

2623
event.stopPropagation()
2724
event.preventDefault()
2825

2926
const field = event.currentTarget
3027
if (field instanceof HTMLTextAreaElement) {
31-
insertText(field, tableMarkdown(table))
28+
insertText(field, textToPaste)
3229
}
3330
}
3431

@@ -40,15 +37,15 @@ function onDragover(event: DragEvent) {
4037
function onPaste(event: ClipboardEvent) {
4138
if (!event.clipboardData) return
4239

43-
const table = hasTable(event.clipboardData)
44-
if (!table) return
40+
const textToPaste = generateText(event.clipboardData)
41+
if (!textToPaste) return
4542

4643
event.stopPropagation()
4744
event.preventDefault()
4845

4946
const field = event.currentTarget
5047
if (field instanceof HTMLTextAreaElement) {
51-
insertText(field, tableMarkdown(table))
48+
insertText(field, textToPaste)
5249
}
5350
}
5451

@@ -84,18 +81,19 @@ function tableMarkdown(node: Element): string {
8481
return `\n${header}${body}\n\n`
8582
}
8683

87-
function parseTable(html: string): HTMLElement | null {
84+
function generateText(transfer: DataTransfer): string | undefined {
85+
if (Array.from(transfer.types).indexOf('text/html') === -1) return
86+
87+
const html = transfer.getData('text/html')
88+
if (!/<table/i.test(html)) return
89+
8890
const el = document.createElement('div')
8991
el.innerHTML = html
90-
return el.querySelector('table')
91-
}
92-
93-
function hasTable(transfer: DataTransfer): HTMLElement | null {
94-
if (Array.from(transfer.types).indexOf('text/html') === -1) return null
92+
let table = el.querySelector('table')
93+
table = !table || table.closest('[data-paste-markdown-skip]') ? null : table
94+
if (!table) return
9595

96-
const html = transfer.getData('text/html')
97-
if (!/<table/i.test(html)) return null
96+
const formattedTable = tableMarkdown(table)
9897

99-
const table = parseTable(html)
100-
return !table || table.closest('[data-paste-markdown-skip]') ? null : table
98+
return html.replace(/<meta.*?>/, '').replace(/<table[.\S\s]*<\/table>/, `\n${formattedTable}`)
10199
}

test/test.js

+26
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,29 @@ describe('paste-markdown', function () {
3838
assert.include(textarea.value, 'name | origin\n-- | --\nhubot | github\nbender | futurama')
3939
})
4040

41+
it('retains text around tables', async function () {
42+
const data = {
43+
'text/html': `
44+
<p>Here is a cool table</p>
45+
<table>
46+
<thead><tr><th>name</th><th>origin</th></tr></thead>
47+
<tbody>
48+
<tr><td>hubot</td><td>github</td></tr>
49+
<tr><td>bender</td><td>futurama</td></tr>
50+
</tbody>
51+
</table>
52+
<p>Very cool</p>
53+
`
54+
}
55+
56+
paste(textarea, data)
57+
assert.equal(
58+
textarea.value.trim(),
59+
// eslint-disable-next-line github/unescaped-html-literal
60+
'<p>Here is a cool table</p>\n \n\nname | origin\n-- | --\nhubot | github\nbender | futurama\n\n\n <p>Very cool</p>'
61+
)
62+
})
63+
4164
it('rejects layout tables', function () {
4265
const data = {
4366
'text/html': `
@@ -51,6 +74,9 @@ describe('paste-markdown', function () {
5174
`
5275
}
5376
paste(textarea, data)
77+
78+
// Synthetic paste events don't manipulate the DOM. A empty textarea
79+
// means that the event handler didn't fire and normal paste happened.
5480
assert.equal(textarea.value, '')
5581
})
5682

0 commit comments

Comments
 (0)