Skip to content

Preserve content when pasting multiple HTML tables - #128

Open
cyberianin wants to merge 1 commit into
github:mainfrom
cyberianin:fix/multiple-table-paste-data-loss
Open

cyberianin wants to merge 1 commit into
github:mainfrom
cyberianin:fix/multiple-table-paste-data-loss

Conversation

@cyberianin

Copy link
Copy Markdown

Problem

When clipboard HTML contains two tables, generateText() takes the source before the first <table, converts only the first parsed table, and resumes after the last </table>. This silently removes the content between the tables and the second table. The same function serves paste and drop.

Fix

For HTML containing multiple, nested, or ambiguously bounded tables, use text/plain only when a deliberately narrow check confirms that simple paragraphs and independent tables match its Markdown blocks in order. Otherwise, preserve the original HTML source in the editor instead of attempting a potentially lossy partial conversion. Keep the existing single-table conversion path, with a guard for tag casing that its source slicing cannot handle. Let later handlers observe defaultPrevented so one handled event produces one insertion. The final skip-formatting cleanup listener still runs on the same element.

Minimal reproduction

Clipboard text/html:

<p>Before</p><table><tr><th>First</th></tr><tr><td>One</td></tr></table><p>Between</p><table><tr><th>Second</th></tr><tr><td>Two</td></tr></table><p>After</p>

Clipboard text/plain:

Before

| First |
| --- |
| One |

Between

| Second |
| --- |
| Two |

After

Before this change, the result loses Between and the second table. After this change, the complete Markdown is inserted once. If the plain representation is absent, incomplete, or ambiguous, the original HTML string is inserted once instead.

Verification

  • The same focused regression test fails on upstream 86be75f8 (middle content absent) and passes with this patch.
  • npm test: 60 passed, 0 failed.
  • npm run lint: passed.
  • npm run build: passed.
  • Paste and drop on a local 16,881-character report with 15 headings and two tables inserted the reconstructed HTML string exactly once, with both tables and intervening content present.

Scope and limitations

The fallback preserves the source HTML string in the editor; it does not prove equivalent rendering in GitHub Flavored Markdown. The report's HTML was reconstructed from its Markdown, not captured from the original clipboard. Complex headings, lists, rich cells, skipped or nested tables are deliberately left as HTML rather than partially converted. The plain-text check is conservative and is not a general HTML-to-Markdown converter.

This differs from #20, which replaced every parsed table in a DOM container and returned the container's serialized innerHTML, including turning skipped tables into text. That change was reverted by #22 after regressions on GitHub.com. This patch does not serialize the whole clipboard DOM or convert every table; it preserves the original HTML when a complete plain-text Markdown representation cannot be established.

@cyberianin
cyberianin marked this pull request as ready for review October 27, 2026 21:03
@cyberianin
cyberianin requested a review from a team as a code owner October 27, 2026 21:03

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant