Skip to content

Commit a1f3676

Browse files
authored
feat: 🎸 prevent duplicated ids for headings (#1580)
* feat: 🎸 prevent duplicated ids for headings ✅ Closes: #1567 * test: add e2e
1 parent 96f56aa commit a1f3676

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

Diff for: e2e/tests/input/heading.spec.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, test } from '@playwright/test'
2-
import { focusEditor, getMarkdown } from '../misc'
2+
import { focusEditor, getMarkdown, waitNextFrame } from '../misc'
33

44
test.beforeEach(async ({ page }) => {
55
await page.goto('/preset-commonmark/')
@@ -21,3 +21,19 @@ test('heading', async ({ page }) => {
2121
const markdown2 = await getMarkdown(page)
2222
expect(markdown2).toBe('# Heading1\n\n## Heading 2\n')
2323
})
24+
25+
test('should generate different id for same heading', async ({ page }) => {
26+
const editor = page.locator('.editor')
27+
await focusEditor(page)
28+
await page.keyboard.type('# Heading1')
29+
await page.keyboard.press('Enter')
30+
await page.keyboard.type('# Heading1')
31+
await page.keyboard.press('Enter')
32+
await page.keyboard.type('## Heading1')
33+
await page.keyboard.press('Enter')
34+
35+
await waitNextFrame(page)
36+
await expect(editor.locator('h1').first()).toHaveAttribute('id', 'heading1')
37+
await expect(editor.locator('h1').last()).toHaveAttribute('id', 'heading1-#2')
38+
await expect(editor.locator('h2')).toHaveAttribute('id', 'heading1-#3')
39+
})

Diff for: packages/plugins/preset-commonmark/src/plugin/sync-heading-id-plugin.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,20 @@ export const syncHeadingIdPlugin = $prose((ctx) => {
1616
const tr = view.state.tr.setMeta('addToHistory', false)
1717

1818
let found = false
19+
const idMap: Record<string, number> = {}
1920

2021
view.state.doc.descendants((node, pos) => {
2122
if (node.type === headingSchema.type(ctx)) {
2223
if (node.textContent.trim().length === 0) return
2324

2425
const attrs = node.attrs
25-
const id = getId(node)
26+
let id = getId(node)
27+
if (idMap[id]) {
28+
idMap[id]! += 1
29+
id += `-#${idMap[id]}`
30+
} else {
31+
idMap[id] = 1
32+
}
2633

2734
if (attrs.id !== id) {
2835
found = true

0 commit comments

Comments
 (0)