fix: 优化粘贴 input 复制内容,多次粘贴会产生多余的html问题
This commit is contained in:
parent
1ebc95b342
commit
f12d6ee600
|
@ -7,6 +7,7 @@ import Editor from '../../editor/index'
|
|||
import { getPasteText, getPasteHtml } from '../paste/paste-event'
|
||||
import { isFunction } from '../../utils/util'
|
||||
import { urlRegex } from '../../utils/const'
|
||||
import $, { DomElement } from '../../utils/dom-core'
|
||||
|
||||
/**
|
||||
* 格式化html
|
||||
|
@ -34,6 +35,33 @@ function formatCode(val: string) {
|
|||
return pasteText
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断html是否使用P标签包裹
|
||||
* @param html 粘贴的html
|
||||
* @author luochao
|
||||
*/
|
||||
function isParagraphHtml(html: string): boolean {
|
||||
if (html === '') return false
|
||||
|
||||
const container = document.createElement('div')
|
||||
container.innerHTML = html
|
||||
|
||||
return container.firstChild?.nodeName === 'P'
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前选区是否是空段落
|
||||
* @param topElem 选区顶层元素
|
||||
* @author luochao
|
||||
*/
|
||||
function isEmptyParagraph(topElem: DomElement | undefined): boolean {
|
||||
if (!topElem?.length) return false
|
||||
|
||||
const dom = topElem.elems[0]
|
||||
|
||||
return dom.nodeName === 'P' && dom.innerHTML === '<br>'
|
||||
}
|
||||
|
||||
/**
|
||||
* 粘贴文本和 html
|
||||
* @param editor 编辑器对象
|
||||
|
@ -98,7 +126,22 @@ function pasteTextHtml(editor: Editor, pasteEvents: Function[]) {
|
|||
if (isCssStyle) {
|
||||
editor.cmd.do('insertHTML', `${formatHtml(pasteText)}`) // text
|
||||
} else {
|
||||
editor.cmd.do('insertHTML', `${formatHtml(pasteHtml)}`) // html
|
||||
const html = formatHtml(pasteHtml)
|
||||
// 如果是段落,为了兼容 firefox 和 chrome差异,自定义插入
|
||||
if (isParagraphHtml(html)) {
|
||||
const $textEl = editor.$textElem
|
||||
$textEl.append($(html))
|
||||
// 如果选区是空段落,移除空段落
|
||||
if (isEmptyParagraph($topElem)) {
|
||||
$topElem.remove()
|
||||
}
|
||||
// 移动光标到编辑器最后的位置
|
||||
const lastEl = $textEl.last()
|
||||
if (!lastEl?.length) return
|
||||
editor.selection.moveCursor(lastEl.elems[0])
|
||||
} else {
|
||||
editor.cmd.do('insertHTML', `${formatHtml(pasteHtml)}`) // html
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
// 此时使用 pasteText 来兼容一下
|
||||
|
|
|
@ -164,7 +164,6 @@ describe('text utils getPasteImgs test', () => {
|
|||
})
|
||||
|
||||
expect(mockPasteTextHandle).toBeCalledWith('<div>1234</div>')
|
||||
expect(document.execCommand).toBeCalledWith('insertHTML', false, '<p>123</p><p><br></p>')
|
||||
})
|
||||
|
||||
test('如果复制内容有 html, 第一次插入 html 报错会使用 pasteText 再执行一次', () => {
|
||||
|
@ -198,7 +197,22 @@ describe('text utils getPasteImgs test', () => {
|
|||
})
|
||||
|
||||
expect(mockPasteTextHandle).toBeCalledWith('<div>1234</div>')
|
||||
expect(mockPasteTextHandle).toBeCalledWith('<div>12345</div>')
|
||||
expect(document.execCommand).toBeCalledWith('insertHTML', false, '<p>123</p><p><br></p>')
|
||||
})
|
||||
|
||||
test('如果复制的内容是段落,则不通过 cmd 插入,自定义插入内容到编辑器', () => {
|
||||
mockCommand(document)
|
||||
|
||||
jest.spyOn(pasteEvents, 'getPasteHtml').mockImplementation(() => '<p>1234</p>')
|
||||
|
||||
const editor = createEditor(document, 'div4')
|
||||
const pasteEventList: Function[] = []
|
||||
pasteTextHtml(editor, pasteEventList)
|
||||
|
||||
pasteEventList.forEach(fn => {
|
||||
fn(new Event(''))
|
||||
})
|
||||
|
||||
expect(document.execCommand).not.toHaveBeenCalled()
|
||||
expect(editor.$textElem.elems[0].innerHTML.indexOf('<p>1234</p>')).toBeGreaterThanOrEqual(0)
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue