fix: 优化粘贴 input 复制内容,多次粘贴会产生多余的html问题

This commit is contained in:
luochao 2021-01-16 10:59:53 +08:00
parent 1ebc95b342
commit f12d6ee600
2 changed files with 61 additions and 4 deletions

View File

@ -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 来兼容一下

View File

@ -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)
})
})