Merge pull request #894 from nipunrajk/fix/markdown-task-list-links

fix(markdown): prevent task lists with links from corrupting DOM
This commit is contained in:
Alam
2026-10-21 12:00:48 +05:30
committed by GitHub
2 changed files with 66 additions and 1 deletions
+1 -1
View File
@@ -674,7 +674,7 @@ export class MarkdownEditor {
.use(emoji) // Emoji: :smile: -> 😄
.use(ins) // Inserted text: ++text++ -> <ins>text</ins>
.use(mark) // Marked text: ==text== -> <mark>text</mark>
.use(taskLists, { enabled: true, label: true, labelAfter: true }) // Task lists: - [x] done
.use(taskLists, { enabled: true, label: false }) // Task lists: - [x] done
.use(anchor, { permalink: false }) // Header anchors
.use(tocDoneRight); // Table of contents: ${toc}
}
+65
View File
@@ -0,0 +1,65 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { MarkdownEditor } from '@/js/utils/markdown-editor';
describe('Markdown to PDF - Task Lists with Links (Fixes #715)', () => {
let container: HTMLDivElement;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
it('renders task list items containing links without unclosed anchor tags or swallows', () => {
const markdown = `- [ ] [Links](https://bentopdf.com)
Paragraph below link`;
new MarkdownEditor(container, {
initialContent: markdown,
});
const preview = container.querySelector('#mdPreview');
expect(preview).not.toBeNull();
const html = preview?.innerHTML || '';
// Check that the checkbox is rendered
expect(html).toContain('type="checkbox"');
// Check that the link is properly closed and contains the correct URL
const anchor = preview?.querySelector('a');
expect(anchor).not.toBeNull();
expect(anchor?.getAttribute('href')).toBe('https://bentopdf.com');
expect(anchor?.textContent?.trim()).toBe('Links');
// Check that the paragraph below is rendered as a separate sibling paragraph and NOT inside the anchor
const paragraph = preview?.querySelector('p');
expect(paragraph).not.toBeNull();
expect(paragraph?.textContent?.trim()).toBe('Paragraph below link');
expect(anchor?.contains(paragraph)).toBe(false);
});
it('correctly handles checked task lists with links and formatting', () => {
const markdown = `- [x] [Completed Link](https://bentopdf.com) with **bold text**
- [ ] Regular task without link`;
new MarkdownEditor(container, {
initialContent: markdown,
});
const preview = container.querySelector('#mdPreview');
const checkboxes = preview?.querySelectorAll('input[type="checkbox"]');
expect(checkboxes?.length).toBe(2);
const checkedBox = checkboxes?.[0] as HTMLInputElement;
expect(checkedBox?.checked).toBe(true);
const anchor = preview?.querySelector('a');
expect(anchor?.getAttribute('href')).toBe('https://bentopdf.com');
expect(anchor?.textContent?.trim()).toBe('Completed Link');
const strong = preview?.querySelector('strong');
expect(strong?.textContent).toBe('bold text');
expect(anchor?.contains(strong)).toBe(false);
});
});