/** * 样式 */
(function (utils) {
function inputHandle(e) {
if (!utils.inCompositionEvent) {
updateText(e)
}
}
function compositionstartHandle(e) {
// console.log("compositionstart")
utils.inCompositionEvent = true
}
function compositionendHandle(e) {
// console.log("compositionend")
updateText(e)
utils.inCompositionEvent = false
}
/**
* 鼠标按下事件
*/
function windowsCtrZHandle(e) {
const event = e || window.event //标准化事件处理
const keyCode = event.keyCode || event.which || event.charCode
const metaKey = event.metaKey
// console.log("windows键盘事件 ", event, keyCombination, metaKey, keyCode)
//撤销
if (metaKey && keyCode === 90) {
console.log('触发ctrl + Z 事件', e.target)
if (utils.latestOpDoc !== undefined && utils.latestOpDoc !== null) {
// //
// let cNo = parseInt(utils.latestOpDoc.getAttribute("data-order"))
// console.log("恢复", utils.latestOpDoc, cNo)
// if (cNo > 1) {
// let qq = "#noteshare p[data-order='" + (cNo - 1) + "']"
// // console.log("qq: ", qq)
// utils.insertAfter(utils.latestOpDoc, document.querySelector(qq))
// } else {
// //添加元素到首位
// yanxuelu.insertBefore(utils.latestOpDoc, utils.MyRoot.children[0])
// }
// utils.MyDocMap.get(cNo).setHidden(false)
//恢复
utils.latestOpDoc.recovery();
// utils.MyDocMap.get(cNo).setSource(latestOpDoc.innerText)
//
showTestText()
event.preventDefault()
event.returnValue = false
}
utils.latestOpDoc = null
}
}
/**
* 鼠标按下事件 & 键盘组合事件
* @param {*} e
*/
function onkeydownHandle(e) {
const event = e || window.event //标准化事件处理
// window.event 等价于 event参数
// 有些浏览器除了通过keyCode获取输入键code,还可以通过which,charCode获取,这么写是出于浏览器兼容性考虑
const keyCode = event.keyCode || event.which || event.charCode
const keyCombination = event.ctrlKey
const metaKey = event.metaKey
// console.log("键盘事件 ", event, keyCombination, metaKey, keyCode)
// ctrl + c 复制
if (keyCombination && keyCode === 67) {
// 阻止默认事件
event.preventDefault()
event.returnValue = false
console.log('触发ctrl + c 事件', e.target)
}
//撤销
if (metaKey && keyCode === 90) {
// console.log('触发ctrl + Z 事件', e.target)
if (utils.latestOpDoc !== undefined && utils.latestOpDoc !== null) {
// console.log(utils.latestOpDoc)
//恢复
utils.latestOpDoc.recovery();
//
// console.log(MyDocMap.get(cNo))
let cNo = parseInt(utils.latestOpDoc.getData().getAttribute("data-order"))
utils.MyDocMap.get(cNo).setHidden(false)
// utils.MyDocMap.get(cNo).setSource(latestOpDoc.innerText)
//
showTestText()
//阻止事件
event.preventDefault()
event.returnValue = false
}
utils.latestOpDoc = null
}
//删除
if (keyCode === 46 || keyCode === 8) {
let curP = event.target
let cNo = parseInt(curP.getAttribute("data-order"))
//维护最近一次编辑的内容
if (utils.latestOpDoc === undefined || utils.latestOpDoc === null || utils.latestOpDoc.getData().getAttribute("data-id") !== curP.getAttribute("data-id")) {
utils.latestOpDoc = new utils.MyRecovery(curP.cloneNode(true), function () {
let cNo = parseInt(this.data.getAttribute("data-order"))
console.log("恢复", this.data, cNo)
if (cNo > 1) {
utils.insertAfter(this.data, document.querySelector("#noteshare p[data-order='" + (cNo - 1) + "']"))
} else {
//添加元素到首位
utils.MyRoot.insertBefore(this.data, utils.MyRoot.children[0])
}
// 恢复该元素展示
utils.MyDocMap.get(cNo).setHidden(false)
})
}
//如果是第一行
let previousSibling = curP.previousSibling
// console.log(curP, previousSibling == undefined ,previousSibling.id == undefined)
if (previousSibling === undefined || previousSibling.id === undefined) {
//显示用户的输入内容
showTestText()
return
}
// console.log('触发删除', curP.innerHTML, cNo, utils.num, utils.MyDocMap.get(cNo + 1))
let curS = window.getSelection()
// console.log("当前内容: ", curP.innerHTML, " 当前选区 :", curS)
//处理前面没有内容,后面还有内容需要拼接到上层的场景
if ((curS.isCollapsed && curS.anchorOffset === 0) || curP.innerHTML === '
') {
let curNodeRetainHtml = curP.innerHTML
//异步修正顺序(第一行删除不掉)
// if (curP.innerHTML === '
' ) {
// console.log("删除当前行。选取信息: ", curS)
//阻止事件传递
event.preventDefault()
event.returnValue = false
//设置该元素隐藏
utils.MyDocMap.get(cNo).setHidden(true)
//删除当前元素
curP.remove()
//拼接
if (curNodeRetainHtml !== '
') {
previousSibling.innerHTML = previousSibling.innerHTML + curNodeRetainHtml
}
//收起选区到一个点,光标落在一个可编辑元素上
window.getSelection().setPosition(previousSibling, 1);
}
//显示用户的输入内容
showTestText();
}
//回车事件
if (keyCode === 13 /* && currentNode === key.lastElementChild */) {
event.preventDefault()
let uuid = utils.uuid()
let curOrder = ++(utils.num)
var newParagraph = document.createElement("p")
newParagraph.setAttribute("contenteditable", "true")
newParagraph.setAttribute("data-id", uuid)
newParagraph.setAttribute("id", uuid)
newParagraph.setAttribute("data-order", curOrder)
newParagraph.onkeydown = onkeydownHandle
newParagraph.focus()
newParagraph.innerHTML = "
"
utils.MyRoot.appendChild(newParagraph)
utils.MyDocMap.set(curOrder, new utils.MyNode(uuid))
//收起选区到一个点,光标落在一个可编辑元素上
window.getSelection().setPosition(newParagraph, 0)
}
}
/**
*
*/
function showTestText() {
//显示用户的输入内容
const obj = {};
for ([k, v] of utils.MyDocMap.entries()) {
if (v.getHidden() && v.getHidden() === true) {
continue
}
obj[k] = v
}
// console.log("当前文档结构数: ",obj);
// var userInput = document.getElementById("testInput")
// userInput.value = JSON.stringify(obj)
}
/**
* 更新文档
* @param {*} e
*/
function updateText(e) {
let curP = e.target
//是否需要变更元素类型
utils.firstCmd(curP, onkeydownHandle)
let cNo = parseInt(curP.getAttribute("data-order"))
let cp = utils.MyDocMap.get(cNo)
//内容不变则不处理
let h5CurLen = curP.innerText.length
let myDocNodeLen = (cp && cp.getSource()) ? cp.getSource().length : 0
if (h5CurLen === myDocNodeLen) {
return
}
cp.setSource(curP.innerText)
// console.log("curPTx: ", curP.innerText, "MyDocMap : ", utils.MyDocMap)
//显示用户的输入内容
showTestText()
}
function surroundContentsByStyle() {
let curS = utils.getSelection()
let curSec = curS.getRangeAt(0)
let styleName = this.getAttribute("data-value");
let className = utils.parseStyleName2ClassName(styleName)
//todo 只对 nodeType = p 执行
// console.log("当前光标信息: ", curS, " 当前选区信息 : ", curSec)
for (let i = 0; i < curS.rangeCount; i++) {
let curSec = curS.getRangeAt(i)
let curEleSize = curSec.commonAncestorContainer.childNodes.length
let curStartP = curSec.startContainer.parentElement
//todo 先支持 一行。
let start = curSec.startOffset;
let end = curSec.endOffset;
// console.log(curStartP.cloneNode(true), styleName, start, end, " curEleSize: ", curEleSize)
let curPEle = null;
//第一次选择的时候将整行转换成
if (curEleSize === 0) { //没选择,则退出 if (start === end) { return } // console.log("debug1: ", curSec.commonAncestorContainer) //维护最近一次编辑的内容(暂时只支持恢复最近一次编辑) utils.latestOpDoc = new utils.MyRecovery(curStartP.cloneNode(true), function () { console.log("恢复上一步样式1", this.innerHTML) let curEl = document.getElementById(this.data.getAttribute("id")); curEl.innerHTML = this.data.innerHTML; //文本映射 直接覆盖 map 中的 childrenStyle utils.syncOnePInfo(this.data); }) let curHtml = "" for (let j = 0; j < curStartP.innerText.length; j++) { // console.log(curStartP.innerText.charAt(j)) if (j >= start && j < end) { curHtml += '' + curStartP.innerText.charAt(j) + ''; } else { curHtml += '' + curStartP.innerText.charAt(j) + ''; } } curStartP.innerHTML = curHtml; curPEle = curStartP; } else { // console.log("debug2: ", curSec.commonAncestorContainer) //维护最近一次编辑的内容(暂时只支持恢复最近一次编辑) utils.latestOpDoc = new utils.MyRecovery(curSec.commonAncestorContainer.cloneNode(true), function () { console.log("恢复上一步样式1", this.data) let curEl = document.getElementById(this.data.getAttribute("id")); curEl.innerHTML = this.data.innerHTML; //文本映射 直接覆盖 map 中的 childrenStyle utils.syncOnePInfo(this.data); }) let myChildren = curSec.commonAncestorContainer.children for (let j = 0; j < curEleSize; j++) { let curEle = myChildren[j] if (curS.containsNode(curEle, true)) { curEle.classList.remove(className); curEle.classList.add(className); } } curPEle = curSec.commonAncestorContainer; } //文本映射 直接覆盖 map 中的 childrenStyle utils.syncOnePInfo(curPEle) } } window.styleCmd = { inputHandle, compositionstartHandle, compositionendHandle, onkeydownHandle, windowsCtrZHandle, surroundContentsByStyle, showTestText, updateText, } })(utils)