fix(acceptance-r2): 二轮验收 4 项回修(docs/15)
C5 粘贴:handleDOMEvents.paste 前置拦截无 HTML/无文件的多行纯文本按段落 插入(真机菜单粘贴走 execCommand 兜底、与 Ctrl+V 同中 clipboard 插件的 Markdown 解析);插入改开放 Slice,消除段中空段。 E3 相对导出:先选保存位置,再按导出目录重写图片相对路径。 E4 复制为 HTML:剪贴板变体公式只留 MathML、Mermaid 栅格化 PNG。 E6 HTML 导入:DOM 预处理剥 head/脚本/SVG、自家 KaTeX 还原 $ 源码、 GFM 插件加载失败降级。vitest 79 通过 + 2 跳过。
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { createMarkdownEditor, cursorFromSelection } from '../src/editor/editor'
|
||||
import { editorViewCtx } from '@milkdown/kit/core'
|
||||
import { AllSelection, NodeSelection } from '@milkdown/kit/prose/state'
|
||||
import { AllSelection, NodeSelection, TextSelection } from '@milkdown/kit/prose/state'
|
||||
import { buildTextIndex, findInIndex } from '../src/editor/search'
|
||||
import { insertPlainText } from '../src/editor/paste'
|
||||
import { findBlockIndex } from '../src/editor/cursorSync'
|
||||
@@ -123,3 +123,38 @@ describe('验收回修回归', () => {
|
||||
expect(md).toContain('| 1 | 2 |')
|
||||
})
|
||||
})
|
||||
|
||||
describe('二轮验收回归', () => {
|
||||
it('Ctrl+V 粘贴记事本三行纯文本分成三段(C5)', async () => {
|
||||
const { host, editor } = await makeEditor('已有文字')
|
||||
editor.action((ctx) => {
|
||||
const view = ctx.get(editorViewCtx)
|
||||
view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, 5)))
|
||||
})
|
||||
const view = editor.action((ctx) => ctx.get(editorViewCtx))
|
||||
const event = new Event('paste', { bubbles: true, cancelable: true })
|
||||
Object.defineProperty(event, 'clipboardData', {
|
||||
value: { files: [], getData: (type: string) => (type === 'text/plain' ? '第一行\r\n第二行\r\n第三行' : '') },
|
||||
})
|
||||
view.dom.dispatchEvent(event)
|
||||
const md = getMarkdown(editor)
|
||||
expect(md).toContain('第一行\n\n第二行\n\n第三行')
|
||||
await editor.destroy()
|
||||
host.remove()
|
||||
})
|
||||
|
||||
it('段落中间粘贴多行不产生空段落(C5)', async () => {
|
||||
const { host, editor } = await makeEditor('前后文')
|
||||
editor.action((ctx) => {
|
||||
const view = ctx.get(editorViewCtx)
|
||||
view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, 2)))
|
||||
})
|
||||
const { insertPlainText } = await import('../src/editor/paste')
|
||||
insertPlainText(editor, '第一行\n第二行')
|
||||
const md = getMarkdown(editor)
|
||||
expect(md).toContain('前第一行\n\n第二行后文')
|
||||
expect(md).not.toContain('<br />')
|
||||
await editor.destroy()
|
||||
host.remove()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -52,3 +52,38 @@ describe('导入转换', () => {
|
||||
expect(md).toContain('**加粗**')
|
||||
})
|
||||
})
|
||||
|
||||
describe('二轮验收:导出与导入', () => {
|
||||
it('相对路径按导出文件位置重写(E3)', async () => {
|
||||
const html = await markdownToExportHtml('# 图\n\n\n', {
|
||||
title: 't', themeId: 'default', imageMode: 'relative',
|
||||
docDir: 'C:/ws/docs', exportDir: 'C:/out', highlight: false, renderMermaid: false,
|
||||
})
|
||||
expect(html).toContain('src="../ws/docs/doc.assets/pic%20one.png"')
|
||||
const sameDir = await markdownToExportHtml('', {
|
||||
title: 't', themeId: 'default', imageMode: 'relative',
|
||||
docDir: 'C:/ws', exportDir: 'C:/ws', highlight: false, renderMermaid: false,
|
||||
})
|
||||
expect(sameDir).toContain('src="img.png"')
|
||||
})
|
||||
|
||||
it('剪贴板版公式只剩 MathML(E4)', async () => {
|
||||
const html = await markdownToExportHtml('公式 $x=1$ 在此\n', {
|
||||
title: 't', themeId: 'default', imageMode: 'embed', forClipboard: true,
|
||||
highlight: false, renderMermaid: false,
|
||||
})
|
||||
expect(html).toContain('<math')
|
||||
expect(html).not.toContain('katex-html')
|
||||
})
|
||||
|
||||
it('导入整页 HTML 先剥 head/脚本/SVG(E6)', async () => {
|
||||
const md = await htmlToMarkdown('<html><head><title>标题</title><style>.a{color:red}</style></head>'
|
||||
+ '<body><h1>正文題</h1><script>alert(1)</script><p>第一段</p>'
|
||||
+ '<svg><rect width="10"/></svg><p>第二段</p></body></html>')
|
||||
expect(md).toContain('# 正文題')
|
||||
expect(md).toContain('第一段')
|
||||
expect(md).toContain('第二段')
|
||||
expect(md).not.toContain('alert')
|
||||
expect(md).not.toContain('color:red')
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user