Skip to content

fix(markdown): keep only inline content when parsing inline HTML - #8169

Merged
bdbch merged 3 commits into
ueberdosis:mainfrom
lazerg:fix/issue-8168-unclosed-inline-html
Aug 8, 2026
Merged

fix(markdown): keep only inline content when parsing inline HTML#8169
bdbch merged 3 commits into
ueberdosis:mainfrom
lazerg:fix/issue-8168-unclosed-inline-html

Conversation

@lazerg

@lazerg lazerg commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Fixes

Fixes #8168

Changes and Review

Markdown like <b>123 has no closing tag, so the inline HTML parsed to an empty paragraph that got returned into the inline stream, producing a paragraph inside a paragraph. Inline HTML now keeps only the inline content it parses to, so manager.parse('<b>123') returns a plain paragraph with the text 123. The same held for other tags that gave a block node inline, for example <span></span> or <h1>. Verify with the added tests in packages/markdown/__tests__/mixed-html.spec.ts.

Checklist

  • I have added a changeset if necessary.
  • I have added tests if possible.
  • I have made sure to test my changes myself.

Responsibility

  • I have reviewed and understand these changes, and I take responsibility for this PR, even if an AI agent created it.

@lazerg
lazerg requested a review from a team as a code owner August 7, 2026 09:37
@changeset-bot

changeset-bot Bot commented Aug 7, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cd59360

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 74 packages
Name Type
@tiptap/markdown Patch
@tiptap/core Patch
@tiptap/extension-audio Patch
@tiptap/extension-blockquote Patch
@tiptap/extension-bold Patch
@tiptap/extension-bubble-menu Patch
@tiptap/extension-bullet-list Patch
@tiptap/extension-code-block-lowlight Patch
@tiptap/extension-code-block Patch
@tiptap/extension-code Patch
@tiptap/extension-collaboration-caret Patch
@tiptap/extension-collaboration Patch
@tiptap/extension-color Patch
@tiptap/extension-details Patch
@tiptap/extension-document Patch
@tiptap/extension-drag-handle-react Patch
@tiptap/extension-drag-handle-vue-2 Patch
@tiptap/extension-drag-handle-vue-3 Patch
@tiptap/extension-drag-handle Patch
@tiptap/extension-emoji Patch
@tiptap/extension-file-handler Patch
@tiptap/extension-find-and-replace Patch
@tiptap/extension-floating-menu Patch
@tiptap/extension-font-family Patch
@tiptap/extension-hard-break Patch
@tiptap/extension-heading Patch
@tiptap/extension-highlight Patch
@tiptap/extension-horizontal-rule Patch
@tiptap/extension-image Patch
@tiptap/extension-invisible-characters Patch
@tiptap/extension-italic Patch
@tiptap/extension-link Patch
@tiptap/extension-list Patch
@tiptap/extension-mathematics Patch
@tiptap/extension-mention Patch
@tiptap/extension-node-range Patch
@tiptap/extension-ordered-list Patch
@tiptap/extension-paragraph Patch
@tiptap/extension-ruby-text Patch
@tiptap/extension-strike Patch
@tiptap/extension-subscript Patch
@tiptap/extension-superscript Patch
@tiptap/extension-table-of-contents Patch
@tiptap/extension-table Patch
@tiptap/extension-text-align Patch
@tiptap/extension-text-style Patch
@tiptap/extension-text Patch
@tiptap/extension-twitch Patch
@tiptap/extension-typography Patch
@tiptap/extension-underline Patch
@tiptap/extension-unique-id Patch
@tiptap/extension-youtube Patch
@tiptap/extensions Patch
@tiptap/html Patch
@tiptap/pm Patch
@tiptap/react Patch
@tiptap/starter-kit Patch
@tiptap/static-renderer Patch
@tiptap/suggestion Patch
@tiptap/vue-2 Patch
@tiptap/vue-3 Patch
@tiptap/extension-character-count Patch
@tiptap/extension-dropcursor Patch
@tiptap/extension-focus Patch
@tiptap/extension-gapcursor Patch
@tiptap/extension-history Patch
@tiptap/extension-list-item Patch
@tiptap/extension-list-keymap Patch
@tiptap/extension-placeholder Patch
@tiptap/extension-table-cell Patch
@tiptap/extension-table-header Patch
@tiptap/extension-table-row Patch
@tiptap/extension-task-item Patch
@tiptap/extension-task-list Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify

netlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploy Preview for tiptap-embed ready!

Name Link
🔨 Latest commit cd59360
🔍 Latest deploy log https://app.netlify.com/projects/tiptap-embed/deploys/6a75aa6c8a29730008d84752
😎 Deploy Preview https://deploy-preview-8169--tiptap-embed.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: ca04108e-30ee-4db0-bdad-72db1c04917d

📥 Commits

Reviewing files that changed from the base of the PR and between 7333eba and cd59360.

📒 Files selected for processing (1)
  • packages/markdown/__tests__/mixed-html.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/markdown/tests/mixed-html.spec.ts

📝 Walkthrough

Summary

  • Fixed unclosed inline HTML parsing, such as <b>123.
  • Preserved text and prevented nested paragraphs.
  • Added handling for empty inline tags, block tags, and <br>.
  • Added tests for mixed Markdown and HTML.
  • Added a patch changeset for @tiptap/markdown.

Walkthrough

The parser now filters block wrappers from inline HTML content and preserves valid inline text. Tests cover unclosed tags, empty elements, block elements, and hard breaks. A patch changeset documents the fix.

Changes

Markdown inline HTML parsing

Layer / File(s) Summary
Filter inline HTML content
packages/markdown/src/MarkdownManager.ts
Inline HTML parsing now recursively removes block wrappers, preserves schema-recognized inline nodes, caches inline-node types, and returns null when no inline content remains.
Validate inline HTML parsing
packages/markdown/__tests__/mixed-html.spec.ts, .changeset/2026-08-07-markdown-unclosed-inline-html.md
Tests cover unclosed tags, empty elements, block elements used inline, and <br> hard breaks. The changeset documents the patch.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • ueberdosis/tiptap#8116 — Both changes update MarkdownManager inline HTML parsing to prevent invalid block nodes in inline content.

Possibly related PRs

Suggested labels: area: markdown, impact: low, complexity: medium

Suggested reviewers: bdbch

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: retaining only inline content when parsing inline HTML.
Description check ✅ Passed The description includes the required fix, change summary, verification guidance, changeset checklist, tests checklist, and responsibility confirmation.
Linked Issues check ✅ Passed The changes address issue #8168 by removing block nodes from inline HTML results and preserving valid inline text, with focused tests.
Out of Scope Changes check ✅ Passed The changeset, parser update, and focused mixed HTML tests are directly related to the linked issue and stated objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added area: markdown Markdown parsing and serialization complexity: easy Small effort, well-defined scope impact: low No direct user impact labels Aug 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/markdown/__tests__/mixed-html.spec.ts (1)

80-85: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add tests for empty inline HTML cases.

These tests cover unclosed <b> tags, but not empty <span></span> or unsupported <img>. Add deterministic assertions for these inputs. Verify the exact doc.content shape and the absence of nested paragraph nodes.

As per coding guidelines, deterministic user-visible behavior in TypeScript requires unit-test coverage.

Also applies to: 87-94

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/markdown/__tests__/mixed-html.spec.ts` around lines 80 - 85, Extend
the mixed HTML parsing tests near the existing unclosed <b> case with
deterministic cases for empty <span></span> and unsupported <img> input. Assert
each exact doc.content structure and explicitly verify that no nested paragraph
nodes are produced, matching the parser’s intended user-visible behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.changeset/2026-08-07-markdown-unclosed-inline-html.md:
- Line 5: Shorten the changeset sentence to one brief, user-facing statement
describing the corrected handling of unclosed inline HTML in Markdown, removing
internal parsing details, nested-paragraph terminology, and schema references.

---

Nitpick comments:
In `@packages/markdown/__tests__/mixed-html.spec.ts`:
- Around line 80-85: Extend the mixed HTML parsing tests near the existing
unclosed <b> case with deterministic cases for empty <span></span> and
unsupported <img> input. Assert each exact doc.content structure and explicitly
verify that no nested paragraph nodes are produced, matching the parser’s
intended user-visible behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: a2fced40-9b48-457a-897c-6d38e4af6186

📥 Commits

Reviewing files that changed from the base of the PR and between 390d4db and e09207d.

📒 Files selected for processing (3)
  • .changeset/2026-08-07-markdown-unclosed-inline-html.md
  • packages/markdown/__tests__/mixed-html.spec.ts
  • packages/markdown/src/MarkdownManager.ts

Comment thread .changeset/2026-08-07-markdown-unclosed-inline-html.md Outdated
@lazerg lazerg changed the title fix(markdown): drop empty inline HTML instead of nesting a paragraph fix(markdown): keep only inline content when parsing inline HTML Aug 7, 2026
@coderabbitai coderabbitai Bot added complexity: medium Moderate change, possibly multiple files and removed complexity: easy Small effort, well-defined scope labels Aug 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/markdown/__tests__/mixed-html.spec.ts (1)

102-109: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for a schema-recognized inline node.

These tests cover text nodes, marks, empty HTML, and block wrappers. They do not verify that a custom inline node survives the schema-based filtering. Add one deterministic inline-node test and assert that it remains in the surrounding paragraph.

As per coding guidelines, add or update unit tests for user-visible behavior when deterministic; use Vitest tests under packages/**/__tests__/.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/markdown/__tests__/mixed-html.spec.ts` around lines 102 - 109, Add a
deterministic Vitest case near the existing mixed HTML parsing tests that parses
a schema-recognized custom inline node surrounded by text, then assert the node
remains inside the resulting paragraph in document order. Reuse the existing
manager and established inline-node schema symbol or fixture rather than
introducing unrelated test setup.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/markdown/src/MarkdownManager.ts`:
- Around line 62-63: Update registerExtension() to register extensions before
schema-dependent parsing, keep baseExtensions synchronized with the current
extensions, and invalidate both inlineNodeTypesCache and schemaParseDomTagsCache
whenever registration changes the schema. Ensure schemaParseDomTagsCache is
built from the current extensions rather than only baseExtensions.

---

Nitpick comments:
In `@packages/markdown/__tests__/mixed-html.spec.ts`:
- Around line 102-109: Add a deterministic Vitest case near the existing mixed
HTML parsing tests that parses a schema-recognized custom inline node surrounded
by text, then assert the node remains inside the resulting paragraph in document
order. Reuse the existing manager and established inline-node schema symbol or
fixture rather than introducing unrelated test setup.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: c132764f-5aab-4d76-94dc-ca3c538f5d61

📥 Commits

Reviewing files that changed from the base of the PR and between e09207d and 7333eba.

📒 Files selected for processing (3)
  • .changeset/2026-08-07-markdown-unclosed-inline-html.md
  • packages/markdown/__tests__/mixed-html.spec.ts
  • packages/markdown/src/MarkdownManager.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/2026-08-07-markdown-unclosed-inline-html.md

Comment thread packages/markdown/src/MarkdownManager.ts
@bdbch
bdbch merged commit 03ba40e into ueberdosis:main Aug 8, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: markdown Markdown parsing and serialization complexity: medium Moderate change, possibly multiple files impact: low No direct user impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@tiptap/markdown produces invalid nested paragraph JSON for unclosed HTML like <b>123

2 participants