/* 编辑区域 */ import $ from '../util/dom-core.js' import { getPasteText, getPasteHtml, getPasteImgs } from '../util/paste-handle.js' import { UA, isFunction, replaceHtmlSymbol } from '../util/util.js' // 获取一个 elem.childNodes 的 JSON 数据 function getChildrenJSON($elem) { const result = [] const $children = $elem.childNodes() || [] // 注意 childNodes() 可以获取文本节点 $children.forEach(curElem => { let elemResult const nodeType = curElem.nodeType // 文本节点 if (nodeType === 3) { elemResult = curElem.textContent elemResult = replaceHtmlSymbol(elemResult) } // 普通 DOM 节点 if (nodeType === 1) { elemResult = {} // tag elemResult.tag = curElem.nodeName.toLowerCase() // attr const attrData = [] const attrList = curElem.attributes || {} const attrListLength = attrList.length || 0 for (let i = 0; i < attrListLength; i++) { const attr = attrList[i] attrData.push({ name: attr.name, value: attr.value }) } elemResult.attrs = attrData // children(递归) elemResult.children = getChildrenJSON($(curElem)) } result.push(elemResult) }) return result } // 构造函数 function Text(editor) { this.editor = editor } // 修改原型 Text.prototype = { constructor: Text, // 初始化 init: function () { // 绑定事件 this._bindEvent() }, // 清空内容 clear: function () { this.html('
${val}
`) // 初始化选取,将光标定位到内容尾部 editor.initSelection() } }, // 追加内容 append: function (html) { const editor = this.editor const $textElem = editor.$textElem $textElem.append($(html)) // 初始化选取,将光标定位到内容尾部 editor.initSelection() }, // 绑定事件 _bindEvent: function () { // 实时保存选取 this._saveRangeRealTime() // 按回车建时的特殊处理 this._enterKeyHandle() // 清空时保留的顶级标签,改为
function pHandle(e) {
const $selectionElem = editor.selection.getSelectionContainerElem()
const $parentElem = $selectionElem.parent()
if ($parentElem.html() === '
') {
// 回车之前光标所在一个
.....
,并将选取定位到
,删除当前标签 insertEmptyP($selectionElem) } $textElem.on('keyup', e => { if (e.keyCode !== 13) { // 不是回车键 return } // 将回车之后生成的非
的顶级标签,改为
pHandle(e) }) //
回车时 特殊处理
function codeHandle(e) {
const $selectionElem = editor.selection.getSelectionContainerElem()
if (!$selectionElem) {
return
}
const $parentElem = $selectionElem.parent()
const selectionNodeName = $selectionElem.getNodeName()
const parentNodeName = $parentElem.getNodeName()
if (selectionNodeName !== 'CODE' || parentNodeName !== 'PRE') {
// 不符合要求 忽略
return
}
if (!editor.cmd.queryCommandSupported('insertHTML')) {
// 必须原生支持 insertHTML 命令
return
}
// 处理:光标定位到代码末尾,联系点击两次回车,即跳出代码块
if (editor._willBreakCode === true) {
// 此时可以跳出代码块
// 插入 ,并将选取定位到
const $p = $('
回车时 特殊处理
codeHandle(e)
})
},
// 清空时保留 ${pasteText}
`) return } // 先放开注释,有问题再追查 ———— // // 表格中忽略,可能会出现异常问题 // if (nodeName === 'TD' || nodeName === 'TH') { // return // } if (!pasteHtml) { // 没有内容,可继续执行下面的图片粘贴 resetTime() return } try { // firefox 中,获取的 pasteHtml 可能是没有${pasteText}
`) } }) // 粘贴图片 $textElem.on('paste', e => { if (UA.isIE()) { return } else { e.preventDefault() } // 粘贴图片和文本,只能同时使用一个 if (!canDo()) { return } // 获取粘贴的图片 const pasteFiles = getPasteImgs(e) if (!pasteFiles || !pasteFiles.length) { return } // 获取当前的元素 const $selectionElem = editor.selection.getSelectionContainerElem() if (!$selectionElem) { return } const nodeName = $selectionElem.getNodeName() // code 中粘贴忽略 if (nodeName === 'CODE' || nodeName === 'PRE') { return } // 上传图片 const uploadImg = editor.uploadImg uploadImg.uploadImg(pasteFiles) }) }, // tab 特殊处理 _tabHandle: function () { const editor = this.editor const $textElem = editor.$textElem $textElem.on('keydown', e => { if (e.keyCode !== 9) { return } if (!editor.cmd.queryCommandSupported('insertHTML')) { // 必须原生支持 insertHTML 命令 return } const $selectionElem = editor.selection.getSelectionContainerElem() if (!$selectionElem) { return } const $parentElem = $selectionElem.parent() const selectionNodeName = $selectionElem.getNodeName() const parentNodeName = $parentElem.getNodeName() if (selectionNodeName === 'CODE' && parentNodeName === 'PRE') { // 里面
editor.cmd.do('insertHTML', ' ')
} else {
// 普通文字
editor.cmd.do('insertHTML', ' ')
}
e.preventDefault()
})
},
// img 点击
_imgHandle: function () {
const editor = this.editor
const $textElem = editor.$textElem
// 为图片增加 selected 样式
$textElem.on('click', 'img', function (e) {
const img = this
const $img = $(img)
if ($img.attr('data-w-e') === '1') {
// 是表情图片,忽略
return
}
// 记录当前点击过的图片
editor._selectedImg = $img
// 修改选区并 restore ,防止用户此时点击退格键,会删除其他内容
editor.selection.createRangeByElem($img)
editor.selection.restoreSelection()
})
// 去掉图片的 selected 样式
$textElem.on('click keyup', e => {
if (e.target.matches('img')) {
// 点击的是图片,忽略
return
}
// 删除记录
editor._selectedImg = null
})
},
// 拖拽事件
_dragHandle: function () {
const editor = this.editor
// 禁用 document 拖拽事件
const $document = $(document)
$document.on('dragleave drop dragenter dragover', function (e) {
e.preventDefault()
})
// 添加编辑区域拖拽事件
const $textElem = editor.$textElem
$textElem.on('drop', function (e) {
e.preventDefault()
const files = e.dataTransfer && e.dataTransfer.files
if (!files || !files.length) {
return
}
// 上传图片
const uploadImg = editor.uploadImg
uploadImg.uploadImg(files)
})
}
}
export default Text