Merge pull request #2926 from wangeditor-team/fix-init-empty-p-dom
fix: 默认设置空行由<p><br></p>改成<p data-we-empty-p=""><br></p>
This commit is contained in:
commit
f25ef62b05
|
@ -6,6 +6,7 @@
|
|||
import Editor from '../index'
|
||||
import $, { DomElement } from '../../utils/dom-core'
|
||||
import { getRandom } from '../../utils/util'
|
||||
import { EMPTY_P } from '../../utils/const'
|
||||
|
||||
const styleSettings = {
|
||||
border: '1px solid #c9d8db',
|
||||
|
@ -65,7 +66,7 @@ export default function (editor: Editor): void {
|
|||
// 编辑器有默认值的时候隐藏placeholder
|
||||
$placeholder.hide()
|
||||
} else {
|
||||
$textElem.append($('<p><br></p>')) // 新增一行,方便继续编辑
|
||||
$textElem.append($(EMPTY_P)) // 新增一行,方便继续编辑
|
||||
}
|
||||
|
||||
// 编辑区域加入DOM
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import Editor from '../index'
|
||||
import $ from '../../utils/dom-core'
|
||||
import { EMPTY_P } from '../../utils/const'
|
||||
|
||||
/**
|
||||
* 初始化编辑器选区,将光标定位到文档末尾
|
||||
|
@ -16,7 +17,7 @@ function initSelection(editor: Editor, newLine?: boolean) {
|
|||
const $children = $textElem.children()
|
||||
if (!$children || !$children.length) {
|
||||
// 如果编辑器区域无内容,添加一个空行,重新设置选区
|
||||
$textElem.append($('<p><br></p>'))
|
||||
$textElem.append($(EMPTY_P))
|
||||
initSelection(editor)
|
||||
return
|
||||
}
|
||||
|
@ -28,8 +29,8 @@ function initSelection(editor: Editor, newLine?: boolean) {
|
|||
const html = $last.html().toLowerCase()
|
||||
const nodeName = $last.getNodeName()
|
||||
if ((html !== '<br>' && html !== '<br/>') || nodeName !== 'P') {
|
||||
// 最后一个元素不是 <p><br></p>,添加一个空行,重新设置选区
|
||||
$textElem.append($('<p><br></p>'))
|
||||
// 最后一个元素不是 空标签,添加一个空行,重新设置选区
|
||||
$textElem.append($(EMPTY_P))
|
||||
initSelection(editor)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import $, { DomElement } from '../utils/dom-core'
|
||||
import { UA } from '../utils/util'
|
||||
import Editor from './index'
|
||||
import { EMPTY_P } from '../utils/const'
|
||||
|
||||
class SelectionAndRange {
|
||||
public editor: Editor
|
||||
|
@ -58,7 +59,7 @@ class SelectionAndRange {
|
|||
const $textElem = editor.$textElem
|
||||
if ($textElem.isContain($containerElem)) {
|
||||
if ($textElem.elems[0] === $containerElem.elems[0]) {
|
||||
if ($textElem.html().trim() === '<p><br></p>') {
|
||||
if ($textElem.html().trim() === EMPTY_P) {
|
||||
const $children = $textElem.children()
|
||||
const $last = $children?.last()
|
||||
editor.selection.createRangeByElem($last as DomElement, true, true)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* @description 代码块为最后一块内容时往下跳出代码块
|
||||
* @author zhengwenjian
|
||||
*/
|
||||
import { EMPTY_P } from '../../../utils/const'
|
||||
import Editor from '../../../editor/index'
|
||||
import $ from '../../../utils/dom-core'
|
||||
|
||||
|
@ -20,7 +21,7 @@ export default function bindEventJumpCodeBlock(editor: Editor) {
|
|||
const $lastNode = $textElem.children()?.last()
|
||||
if (node?.elems[0].tagName === 'XMP' && $lastNode?.elems[0].tagName === 'PRE') {
|
||||
// 就是最后一块是代码块的情况插入空p标签并光标移至p
|
||||
const $emptyP = $('<p><br></p>')
|
||||
const $emptyP = $(EMPTY_P)
|
||||
$textElem.append($emptyP)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -8,6 +8,7 @@ import { PanelConf } from '../menu-constructors/Panel'
|
|||
import { getRandom } from '../../utils/util'
|
||||
import $, { DomElement } from '../../utils/dom-core'
|
||||
import isActive from './is-active'
|
||||
import { EMPTY_P } from '../../utils/const'
|
||||
|
||||
export default function (editor: Editor, text: string, languageType: string): PanelConf {
|
||||
// panel 中需要用到的id
|
||||
|
@ -35,7 +36,7 @@ export default function (editor: Editor, text: string, languageType: string): Pa
|
|||
|
||||
// 通过dom操作添加换行标签
|
||||
// @ts-ignore
|
||||
$('<p><br></p>').insertAfter($codeElem)
|
||||
$(EMPTY_P).insertAfter($codeElem)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,6 +9,7 @@ import Editor from '../../editor/index'
|
|||
import { MenuActive } from '../menu-constructors/Menu'
|
||||
import { getRandomCode } from '../../utils/util'
|
||||
import { TCatalog } from '../../config/events'
|
||||
import { EMPTY_P } from '../../utils/const'
|
||||
|
||||
class Head extends DropListMenu implements MenuActive {
|
||||
oldCatalogs: TCatalog[] | undefined
|
||||
|
@ -154,7 +155,7 @@ class Head extends DropListMenu implements MenuActive {
|
|||
let endElem = $($selection.getSelectionEndElem())
|
||||
// 判断用户选中元素是否为最后一个空元素,如果是将endElem指向上一个元素
|
||||
if (
|
||||
endElem.elems[0].outerHTML === $('<p><br></p>').elems[0].outerHTML &&
|
||||
endElem.elems[0].outerHTML === $(EMPTY_P).elems[0].outerHTML &&
|
||||
!endElem.elems[0].nextSibling
|
||||
) {
|
||||
endElem = endElem.prev()!
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { EMPTY_P } from '../../../utils/const'
|
||||
import Editor from '../../../editor/index'
|
||||
import $, { DomElement } from '../../../utils/dom-core'
|
||||
function bindEvent(editor: Editor) {
|
||||
|
@ -5,7 +6,7 @@ function bindEvent(editor: Editor) {
|
|||
const $selectElem = editor.selection.getSelectionContainerElem() as DomElement
|
||||
const $topSelectElem = editor.selection.getSelectionRangeTopNodes()[0]
|
||||
// 对quote的enter进行特殊处理
|
||||
//最后一行为<p><br></p>时再按会出跳出blockquote
|
||||
//最后一行为空标签时再按会出跳出blockquote
|
||||
if ($topSelectElem?.getNodeName() === 'BLOCKQUOTE') {
|
||||
// firefox下点击引用按钮会选中外容器<blockquote></blockquote>
|
||||
if ($selectElem.getNodeName() === 'BLOCKQUOTE') {
|
||||
|
@ -15,7 +16,7 @@ function bindEvent(editor: Editor) {
|
|||
if ($selectElem.text() === '') {
|
||||
e.preventDefault()
|
||||
$selectElem.remove()
|
||||
const $newLine = $('<p><br></p>')
|
||||
const $newLine = $(EMPTY_P)
|
||||
$newLine.insertAfter($topSelectElem)
|
||||
// 将光标移动br前面
|
||||
editor.selection.moveCursor($newLine.getNode(), 0)
|
||||
|
|
|
@ -9,6 +9,7 @@ import BtnMenu from '../menu-constructors/BtnMenu'
|
|||
import { MenuActive } from '../menu-constructors/Menu'
|
||||
import bindEvent from './bind-event'
|
||||
import createQuote from './create-quote-node'
|
||||
import { EMPTY_P } from '../../utils/const'
|
||||
|
||||
class Quote extends BtnMenu implements MenuActive {
|
||||
constructor(editor: Editor) {
|
||||
|
@ -62,7 +63,7 @@ class Quote extends BtnMenu implements MenuActive {
|
|||
// 即时更新btn状态
|
||||
this.tryChangeActive()
|
||||
// 防止最后一行无法跳出
|
||||
$(`<p><br></p>`).insertAfter($quote)
|
||||
$(EMPTY_P).insertAfter($quote)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import Editor from '../../editor/index'
|
|||
import { MenuActive } from '../menu-constructors/Menu'
|
||||
import bindEvent from './bind-event/index'
|
||||
import { UA } from '../../utils/util'
|
||||
import { EMPTY_P } from '../../utils/const'
|
||||
class splitLine extends BtnMenu implements MenuActive {
|
||||
constructor(editor: Editor) {
|
||||
const $elem = $(
|
||||
|
@ -53,7 +54,7 @@ class splitLine extends BtnMenu implements MenuActive {
|
|||
*/
|
||||
private createSplitLine(): void {
|
||||
// 防止插入分割线时没有占位元素的尴尬
|
||||
let splitLineDOM: string = '<hr/><p><br/></p>'
|
||||
let splitLineDOM: string = `<hr/>${EMPTY_P}`
|
||||
// 火狐浏览器不需要br标签占位
|
||||
if (UA.isFirefox) {
|
||||
splitLineDOM = '<hr/><p></p>'
|
||||
|
|
|
@ -11,6 +11,7 @@ import Editor from '../../../editor/index'
|
|||
import operatingEvent from './event/operating-event'
|
||||
|
||||
import getNode from './event/getNode'
|
||||
import { EMPTY_P } from '../../../utils/const'
|
||||
|
||||
/**
|
||||
* 生成 Tooltip 的显示隐藏函数
|
||||
|
@ -38,7 +39,7 @@ function createShowHideFn(editor: Editor) {
|
|||
// 选中img元素
|
||||
editor.selection.createRangeByElem($node)
|
||||
editor.selection.restoreSelection()
|
||||
editor.cmd.do('insertHTML', '<p><br></p>')
|
||||
editor.cmd.do('insertHTML', EMPTY_P)
|
||||
// 返回 true,表示执行完之后,隐藏 tooltip。否则不隐藏。
|
||||
return true
|
||||
},
|
||||
|
@ -104,7 +105,7 @@ function createShowHideFn(editor: Editor) {
|
|||
editor.selection.restoreSelection()
|
||||
|
||||
if (trLength === 0) {
|
||||
newdom = '<p><br></p>'
|
||||
newdom = EMPTY_P
|
||||
} else {
|
||||
newdom = getnode.getTableHtml(
|
||||
operatingEvent.DeleteRow($(htmlStr), index).elems[0]
|
||||
|
@ -166,7 +167,7 @@ function createShowHideFn(editor: Editor) {
|
|||
editor.selection.restoreSelection()
|
||||
|
||||
if (tdLength === 1) {
|
||||
newdom = '<p><br></p>'
|
||||
newdom = EMPTY_P
|
||||
} else {
|
||||
newdom = getnode.getTableHtml(
|
||||
operatingEvent.DeleteCol($(htmlStr), index).elems[0]
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* @author lichunlin
|
||||
*/
|
||||
|
||||
import { EMPTY_P } from '../../utils/const'
|
||||
import Editor from '../../editor/index'
|
||||
import $ from '../../utils/dom-core'
|
||||
|
||||
|
@ -55,7 +56,7 @@ class CreateTable {
|
|||
const tableDom =
|
||||
`<table border="0" width="100%" cellpadding="0" cellspacing="0"><tbody>` +
|
||||
rowStr +
|
||||
'</tbody></table><p><br></p>'
|
||||
`</tbody></table>${EMPTY_P}`
|
||||
return tableDom
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import $ from '../../../utils/dom-core'
|
|||
import { getCursorNextNode, isAllTodo } from '../util'
|
||||
import createTodo from '../todo'
|
||||
import { dealTextNode, isTodo } from '../util'
|
||||
import { EMPTY_P } from '../../../utils/const'
|
||||
|
||||
/**
|
||||
* todolist 内部逻辑
|
||||
|
@ -56,7 +57,7 @@ function bindEvent(editor: Editor) {
|
|||
|
||||
// 回车时内容为空时,删去此行
|
||||
if ($topSelectElem.text() === '') {
|
||||
const $p = $(`<p><br></p>`)
|
||||
const $p = $(EMPTY_P)
|
||||
$p.insertAfter($topSelectElem)
|
||||
selection.moveCursor($p.getNode())
|
||||
$topSelectElem.remove()
|
||||
|
@ -106,7 +107,7 @@ function bindEvent(editor: Editor) {
|
|||
// 处理内容为空的情况
|
||||
if ($topSelectElem.text() === '') {
|
||||
e.preventDefault()
|
||||
const $newP = $(`<p><br></p>`)
|
||||
const $newP = $(EMPTY_P)
|
||||
$newP.insertAfter($topSelectElem)
|
||||
$topSelectElem.remove()
|
||||
selection.moveCursor($newP.getNode(), 0)
|
||||
|
@ -139,7 +140,7 @@ function bindEvent(editor: Editor) {
|
|||
const $topSelectElem = selection.getSelectionRangeTopNodes()[0]
|
||||
if ($topSelectElem && isTodo($topSelectElem)) {
|
||||
if ($topSelectElem.text() === '') {
|
||||
$(`<p><br></p>`).insertAfter($topSelectElem)
|
||||
$(EMPTY_P).insertAfter($topSelectElem)
|
||||
$topSelectElem.remove()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import { PanelConf, PanelTabConf } from '../menu-constructors/Panel'
|
|||
import { getRandom } from '../../utils/util'
|
||||
import $ from '../../utils/dom-core'
|
||||
import UploadVideo from './upload-video'
|
||||
import { EMPTY_P } from '../../utils/const'
|
||||
|
||||
export default function (editor: Editor, video: string): PanelConf {
|
||||
const config = editor.config
|
||||
|
@ -24,7 +25,7 @@ export default function (editor: Editor, video: string): PanelConf {
|
|||
* @param iframe html标签
|
||||
*/
|
||||
function insertVideo(video: string): void {
|
||||
editor.cmd.do('insertHTML', video + '<p><br></p>')
|
||||
editor.cmd.do('insertHTML', video + EMPTY_P)
|
||||
|
||||
// video添加后的回调
|
||||
editor.config.onlineVideoCallback(video)
|
||||
|
|
|
@ -7,6 +7,7 @@ import Editor from '../../editor/index'
|
|||
import { arrForEach, forEach } from '../../utils/util'
|
||||
import post from '../../editor/upload/upload-core'
|
||||
import Progress from '../../editor/upload/progress'
|
||||
import { EMPTY_P } from '../../utils/const'
|
||||
|
||||
type ResData = {
|
||||
url: string
|
||||
|
@ -251,7 +252,7 @@ class UploadVideo {
|
|||
if (!config.customInsertVideo) {
|
||||
editor.cmd.do(
|
||||
'insertHTML',
|
||||
`<video src="${url}" controls="controls" style="max-width:100%"></video><p><br></p>`
|
||||
`<video src="${url}" controls="controls" style="max-width:100%"></video>${EMPTY_P}`
|
||||
)
|
||||
} else {
|
||||
config.customInsertVideo(url)
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
/**
|
||||
* @description 删除时保留 <p><br></p>
|
||||
* @description 删除时保留 EMPTY_P
|
||||
* @author wangfupeng
|
||||
*/
|
||||
|
||||
import { EMPTY_P } from '../../utils/const'
|
||||
import Editor from '../../editor/index'
|
||||
import $ from '../../utils/dom-core'
|
||||
|
||||
/**
|
||||
* 删除时保留 <p><br></p>
|
||||
* 删除时保留 EMPTY_P
|
||||
* @param editor 编辑器实例
|
||||
* @param deleteUpEvents delete 键 up 时的 hooks
|
||||
* @param deleteDownEvents delete 建 down 时的 hooks
|
||||
|
@ -20,7 +21,7 @@ function deleteToKeepP(editor: Editor, deleteUpEvents: Function[], deleteDownEve
|
|||
// firefox 时用 txtHtml === '<br>' 判断,其他用 !txtHtml 判断
|
||||
if (!txtHtml || txtHtml === '<br>') {
|
||||
// 内容空了
|
||||
const $p = $('<p><br/></p>')
|
||||
const $p = $(EMPTY_P)
|
||||
$textElem.html(' ') // 一定要先清空,否则在 firefox 下有问题
|
||||
$textElem.append($p)
|
||||
editor.selection.createRangeByElem($p, false, true)
|
||||
|
@ -35,7 +36,7 @@ function deleteToKeepP(editor: Editor, deleteUpEvents: Function[], deleteDownEve
|
|||
function downFn(e: Event) {
|
||||
const $textElem = editor.$textElem
|
||||
const txtHtml = $textElem.html().toLowerCase().trim()
|
||||
if (txtHtml === '<p><br></p>') {
|
||||
if (txtHtml === EMPTY_P) {
|
||||
// 最后剩下一个空行,就不再删除了
|
||||
e.preventDefault()
|
||||
return
|
||||
|
|
|
@ -40,8 +40,8 @@ function enterToCreateP(editor: Editor, enterUpEvents: Function[], enterDownEven
|
|||
}
|
||||
|
||||
const nodeName = $selectionElem.getNodeName()
|
||||
if (nodeName === 'P') {
|
||||
// 当前的标签是 P ,不用做处理
|
||||
if (nodeName === 'P' && $selectionElem.attr('data-we-empty-p') === null) {
|
||||
// 当前的标签是 P 且不为 editor 生成的空白占位 p 标签,不用做处理
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ function initTextHooks(text: Text): void {
|
|||
// 回车时,保证生成的是 <p> 标签
|
||||
enterToCreateP(editor, eventHooks.enterUpEvents, eventHooks.enterDownEvents)
|
||||
|
||||
// 删除时,保留 <p><br></p>
|
||||
// 删除时,保留 EMPTY_P
|
||||
deleteToKeepP(editor, eventHooks.deleteUpEvents, eventHooks.deleteDownEvents)
|
||||
|
||||
// tab 转换为空格
|
||||
|
|
|
@ -9,6 +9,7 @@ import initEventHooks from './event-hooks/index'
|
|||
import { UA, throttle } from '../utils/util'
|
||||
import getChildrenJSON, { NodeListType } from './getChildrenJSON'
|
||||
import getHtmlByNodeList from './getHtmlByNodeList'
|
||||
import { EMPTY_P, EMPTY_P_LAST_REGEX, EMPTY_P_REGEX } from '../utils/const'
|
||||
|
||||
/** 按键函数 */
|
||||
type KeyBoardHandler = (event: KeyboardEvent) => unknown
|
||||
|
@ -123,7 +124,7 @@ class Text {
|
|||
* 清空内容
|
||||
*/
|
||||
public clear(): void {
|
||||
this.html('<p><br></p>')
|
||||
this.html(EMPTY_P)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,12 +140,16 @@ class Text {
|
|||
let html = $textElem.html()
|
||||
// 未选中任何内容的时候点击“加粗”或者“斜体”等按钮,就得需要一个空的占位符 ​ ,这里替换掉
|
||||
html = html.replace(/\u200b/gm, '')
|
||||
html = html.replace(/<p><\/p>/gim, '') // 去掉空行
|
||||
html = html.replace(/<p><br\/?><\/p>$/gim, '') // 去掉最后的 <p><br><p>
|
||||
// 去掉空行
|
||||
html = html.replace(/<p><\/p>/gim, '')
|
||||
// 去掉最后的 空标签
|
||||
html = html.replace(EMPTY_P_LAST_REGEX, '')
|
||||
// 为了避免用户在最后生成的EMPTY_P标签中编辑数据, 最后产生多余标签, 去除所有p标签上的data-we-empty-p属性
|
||||
html = html.replace(EMPTY_P_REGEX, '<p>')
|
||||
|
||||
/**
|
||||
* 这里的代码为了处理火狐多余的空行标签,但是强制删除空行标签会带来其他问题
|
||||
* html()方法返回的的值,"<p><br></p>"中pr会被删除,只留下<p>,点不进去,从而产生垃圾数据
|
||||
* html()方法返回的的值,EMPTY_P中pr会被删除,只留下<p>,点不进去,从而产生垃圾数据
|
||||
* 目前在末位有多个空行的情况下执行撤销重做操作,会产生一种不记录末尾空行的错觉
|
||||
* 暂时注释, 等待进一步的兼容处理
|
||||
*/
|
||||
|
@ -174,7 +179,7 @@ class Text {
|
|||
// 有 val ,则是设置 html
|
||||
val = val.trim()
|
||||
if (val === '') {
|
||||
val = `<p><br></p>`
|
||||
val = EMPTY_P
|
||||
}
|
||||
if (val.indexOf('<') !== 0) {
|
||||
// 内容用 p 标签包裹
|
||||
|
@ -244,20 +249,11 @@ class Text {
|
|||
*/
|
||||
public append(html: string): void {
|
||||
const editor = this.editor
|
||||
const $textElem = editor.$textElem
|
||||
const blankLineReg = /(<p><br><\/p>)+$/g
|
||||
if (html.indexOf('<') !== 0) {
|
||||
// 普通字符串,用 <p> 包裹
|
||||
html = `<p>${html}</p>`
|
||||
}
|
||||
if (blankLineReg.test($textElem.html().trim())) {
|
||||
// 如果有多个空行替换最后一个 <p><br></p>
|
||||
const insertHtml = $textElem.html().replace(/(.*)<p><br><\/p>/, '$1' + html)
|
||||
this.html(insertHtml)
|
||||
} else {
|
||||
$textElem.append($(html))
|
||||
}
|
||||
|
||||
this.html(this.html() + html)
|
||||
// 初始化选区,将光标定位到内容尾部
|
||||
editor.initSelection()
|
||||
}
|
||||
|
|
|
@ -7,3 +7,12 @@ export function EMPTY_FN() {}
|
|||
|
||||
//用于校验是否为url格式字符串
|
||||
export const urlRegex = /^(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?/
|
||||
|
||||
// 编辑器为了方便继续输入/换行等原因 主动生成的空标签
|
||||
export const EMPTY_P = '<p data-we-empty-p=""><br></p>'
|
||||
|
||||
// 用于校验dom中最后 由编辑器主动生成的空标签结构
|
||||
export const EMPTY_P_LAST_REGEX = /<p data-we-empty-p=""><br\/?><\/p>$/gim
|
||||
|
||||
// 用于校验dom中所有 由编辑器主动生成的空标签结构
|
||||
export const EMPTY_P_REGEX = /<p data-we-empty-p="">/gim
|
||||
|
|
|
@ -7,6 +7,7 @@ import createEditor from '../../../helpers/create-editor'
|
|||
import Editor from '../../../../src/editor'
|
||||
import compile from '../../../../src/editor/history/data/node/compile'
|
||||
import { restore, revoke } from '../../../../src/editor/history/data/node/decompilation'
|
||||
import { EMPTY_P } from '../../../../src/utils/const'
|
||||
|
||||
let editor: Editor
|
||||
|
||||
|
@ -28,7 +29,7 @@ describe('Editor history decompile', () => {
|
|||
|
||||
revoke(compileData)
|
||||
|
||||
expect(editor.$textElem.html()).toEqual('<p><br></p>')
|
||||
expect(editor.$textElem.html()).toEqual(EMPTY_P)
|
||||
done()
|
||||
})
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ test('重做 兼容模式', done => {
|
|||
const redo = getMenuInstance(editor, Redo) as Redo
|
||||
redo.clickHandler()
|
||||
// 兼容模式
|
||||
expect(editor.$textElem.html()).toEqual('<p><br><span>123</span></p>')
|
||||
expect(editor.txt.html()).toEqual('<p><br/><span>123</span></p>')
|
||||
}
|
||||
done()
|
||||
},
|
||||
|
|
|
@ -6,6 +6,7 @@ import CreateTable from '../../../../src/menus/table/create-table'
|
|||
import createEditor from '../../../helpers/create-editor'
|
||||
import mockCommand from '../../../helpers/command-mock'
|
||||
import $ from '../../../../src/utils/dom-core'
|
||||
import { EMPTY_P } from '../../../../src/utils/const'
|
||||
|
||||
let editor: ReturnType<typeof createEditor>
|
||||
let createTableInstance: CreateTable
|
||||
|
@ -26,7 +27,7 @@ describe('Create Table Util', () => {
|
|||
expect(document.execCommand).toBeCalledWith(
|
||||
'insertHTML',
|
||||
false,
|
||||
`<table border="0" width="100%" cellpadding="0" cellspacing="0"><tbody><tr><th></th></tr><tr><td></td></tr></tbody></table><p><br></p>`
|
||||
`<table border="0" width="100%" cellpadding="0" cellspacing="0"><tbody><tr><th></th></tr><tr><td></td></tr></tbody></table>${EMPTY_P}`
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import createEditor from '../../helpers/create-editor'
|
|||
import Undo from '../../../src/menus/undo/index'
|
||||
import mockCmdFn from '../../helpers/command-mock'
|
||||
import { getMenuInstance } from '../../helpers/menus'
|
||||
import { EMPTY_P } from '../../../src/utils/const'
|
||||
|
||||
test('撤销', done => {
|
||||
let count = 0
|
||||
|
@ -18,7 +19,7 @@ test('撤销', done => {
|
|||
undo.clickHandler()
|
||||
if (editor.isCompatibleMode) {
|
||||
// 兼容模式
|
||||
expect(editor.$textElem.html()).toEqual('<p><br></p>')
|
||||
expect(editor.$textElem.html()).toEqual(EMPTY_P)
|
||||
} else {
|
||||
// 标准模式
|
||||
expect(editor.history.size).toEqual([0, 1])
|
||||
|
|
|
@ -8,6 +8,7 @@ import mockFile from '../../../helpers/mock-file'
|
|||
import mockXHR from '../../../helpers/mock-xhr'
|
||||
import Editor from '../../../../src/editor'
|
||||
import UploadVideo from '../../../../src/menus/video/upload-video'
|
||||
import { EMPTY_P } from '../../../../src/utils/const'
|
||||
|
||||
let editor: Editor
|
||||
let id = 1
|
||||
|
@ -71,7 +72,7 @@ describe('upload video', () => {
|
|||
expect(document.execCommand).toBeCalledWith(
|
||||
'insertHTML',
|
||||
false,
|
||||
`<video src="${videoUrl}" controls="controls" style="max-width:100%"></video><p><br></p>`
|
||||
`<video src="${videoUrl}" controls="controls" style="max-width:100%"></video>${EMPTY_P}`
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -89,7 +90,7 @@ describe('upload video', () => {
|
|||
expect(document.execCommand).toBeCalledWith(
|
||||
'insertHTML',
|
||||
false,
|
||||
`<video src="${videoUrl}" controls="controls" style="max-width:100%"></video><p><br></p>`
|
||||
`<video src="${videoUrl}" controls="controls" style="max-width:100%"></video>${EMPTY_P}`
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* @author luochao
|
||||
*/
|
||||
import delToKeepP from '../../../src/text/event-hooks/del-to-keep-p'
|
||||
import { EMPTY_P } from '../../../src/utils/const'
|
||||
import createEditor from '../../helpers/create-editor'
|
||||
|
||||
describe('editor.text event-hooks tab-to-space test', () => {
|
||||
|
@ -17,7 +18,7 @@ describe('editor.text event-hooks tab-to-space test', () => {
|
|||
expect(downFns.length).toBe(1)
|
||||
})
|
||||
|
||||
test('当编辑器内容为空时,执行 up 函数,则会插入 <p><br></p> 内容', () => {
|
||||
test('当编辑器内容为空时,执行 up 函数,则会插入 EMPTY_P 内容', () => {
|
||||
const upFns: Function[] = []
|
||||
const downFns: Function[] = []
|
||||
const editor = createEditor(document, 'div2')
|
||||
|
@ -30,10 +31,10 @@ describe('editor.text event-hooks tab-to-space test', () => {
|
|||
fn()
|
||||
})
|
||||
|
||||
expect(editor.$textElem.elems[0].innerHTML).toEqual('<p><br></p>')
|
||||
expect(editor.$textElem.html()).toEqual(EMPTY_P)
|
||||
})
|
||||
|
||||
test('当编辑器内容只有 <br> 时,执行 up 函数,则会插入 <p><br></p> 内容', () => {
|
||||
test('当编辑器内容只有 <br> 时,执行 up 函数,则会插入 EMPTY_P 内容', () => {
|
||||
const upFns: Function[] = []
|
||||
const downFns: Function[] = []
|
||||
const editor = createEditor(document, 'div3')
|
||||
|
@ -46,17 +47,17 @@ describe('editor.text event-hooks tab-to-space test', () => {
|
|||
fn()
|
||||
})
|
||||
|
||||
expect(editor.$textElem.elems[0].innerHTML).toEqual(' <p><br></p>')
|
||||
expect(editor.$textElem.html()).toEqual(` ${EMPTY_P}`)
|
||||
})
|
||||
|
||||
test('当编辑器内容清空到只剩下 <p><br></p> 内容时,则不允许再删除', () => {
|
||||
test('当编辑器内容清空到只剩下 EMPTY_P 内容时,则不允许再删除', () => {
|
||||
const upFns: Function[] = []
|
||||
const downFns: Function[] = []
|
||||
const editor = createEditor(document, 'div4')
|
||||
|
||||
delToKeepP(editor, upFns, downFns)
|
||||
|
||||
editor.txt.html('<p><br></p>')
|
||||
editor.txt.html(EMPTY_P)
|
||||
|
||||
const e = new KeyboardEvent('mousedown')
|
||||
const mockPreventDefault = jest.fn()
|
||||
|
@ -66,7 +67,7 @@ describe('editor.text event-hooks tab-to-space test', () => {
|
|||
fn(e)
|
||||
})
|
||||
|
||||
expect(editor.$textElem.elems[0].innerHTML).toEqual('<p><br></p>')
|
||||
expect(editor.$textElem.html()).toEqual(EMPTY_P)
|
||||
expect(mockPreventDefault).toBeCalled()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -6,6 +6,7 @@ import enterToCreateP from '../../../src/text/event-hooks/enter-to-create-p'
|
|||
import $ from '../../../src/utils/dom-core'
|
||||
import createEditor from '../../helpers/create-editor'
|
||||
import commandMock from '../../helpers/command-mock'
|
||||
import { EMPTY_P } from '../../../src/utils/const'
|
||||
|
||||
type Editor = ReturnType<typeof createEditor>
|
||||
|
||||
|
@ -38,7 +39,7 @@ describe('editor.text event-hooks tab-to-space test', () => {
|
|||
expect(downFns.length).toBe(1)
|
||||
})
|
||||
|
||||
test('当编辑器选区内容父元素为 <code><br></code> ,则移除内容, 插入 <p><br></p>', () => {
|
||||
test('当编辑器选区内容父元素为 <code><br></code> ,则移除内容, 插入 EMPTY_P', () => {
|
||||
const upFns: Function[] = []
|
||||
const downFns: Function[] = []
|
||||
|
||||
|
@ -52,7 +53,7 @@ describe('editor.text event-hooks tab-to-space test', () => {
|
|||
fn()
|
||||
})
|
||||
|
||||
expect(editor.$textElem.elems[0].innerHTML).toEqual('<p><br></p>')
|
||||
expect(editor.$textElem.elems[0].innerHTML).toEqual(EMPTY_P)
|
||||
})
|
||||
|
||||
test('当编辑器选区内容的父元素不是 $textElm,则不处理', () => {
|
||||
|
|
|
@ -6,6 +6,7 @@ import createEditor from '../../helpers/create-editor'
|
|||
import $ from '../../../src/utils/dom-core'
|
||||
import dispatchEvent from '../../helpers/mock-dispatch-event'
|
||||
import { UA } from '../../../src/utils/util'
|
||||
import { EMPTY_P } from '../../../src/utils/const'
|
||||
|
||||
let editor: ReturnType<typeof createEditor>
|
||||
let id = 1
|
||||
|
@ -73,13 +74,13 @@ describe('Editor Text test', () => {
|
|||
expect(editor.$textContainerElem.find('.placeholder').elems[0]).toHaveStyle('display:none')
|
||||
})
|
||||
|
||||
test('编辑器初始化后,调用 txt clear 方法,清空编辑内容,只留下 p><br></p>', () => {
|
||||
test('编辑器初始化后,调用 txt clear 方法,清空编辑内容,只留下 EMPTY_P', () => {
|
||||
editor.txt.html('<p>123</p>')
|
||||
|
||||
editor.txt.clear()
|
||||
|
||||
expect(editor.txt.html()).toBe('')
|
||||
expect(editor.$textElem.elems[0].innerHTML).toBe('<p><br></p>')
|
||||
expect(editor.$textElem.elems[0].innerHTML).toBe(EMPTY_P)
|
||||
})
|
||||
|
||||
test('编辑器初始化后,调用 txt setJSON 方法将 JSON 内容设置成 html', () => {
|
||||
|
|
Loading…
Reference in New Issue