"use strict";
import {MyRecovery} from "../model/MyRecovery.js";
import {MyDocItem} from "../model/MyDocItem.js";
import {MyMapItem} from "../model/MyMapItem.js";
export class MyBiz {
constructor() {
}
/**
* 根据类型名称解析 样式的 class 名称
* @param styleName
* @returns {string}
*/
parseStyleName2ClassName(styleName) {
switch (styleName) {
case "b":
return "childStyleStrong";
case "i":
return "childStyleI";
case "u":
return "childStyleU";
case "c_red":
return "childStyleColor";
case "del":
return "childStyleDel"
}
}
/**
* 输入事件
* @param e
*/
inputHandle(e) {
let curP = window.myEdit.utils.GetEventTarget(e);
this.updateText(curP)
}
/**
* 中文输入开始事件
* @param e
*/
compositionstartHandle(e) {
// console.log("compositionstart")
window.myEdit.ctx.inCompositionEvent = true
}
/**
* 中文输入结束事件
* @param e
*/
compositionendHandle(e) {
// console.log("compositionend")
let curP = window.myEdit.utils.GetEventTarget(e);
this.updateText(curP)
//中文输入结束
window.myEdit.ctx.inCompositionEvent = false
}
/**
* 撤销事件
* @param event
*/
cancelHandle(event) {
console.log('触发ctrl + Z 事件', event.target)
if (window.myEdit.ctx.latestOpDoc !== undefined && window.myEdit.ctx.latestOpDoc !== null) {
//恢复
window.myEdit.ctx.latestOpDoc.recovery();
//测试展示
window.myEdit.ctx.showTestText()
//阻止事件
window.myEdit.utils.ProhibitDefaultEvent(event);
}
window.myEdit.ctx.latestOpDoc = null
}
/**
* 删除事件
* @param event
*/
deleteHandle(event) {
let curP = window.myEdit.utils.GetEventTarget(event);
let cNo = parseInt(curP.getAttribute("data-order"))
//维护最近一次编辑的内容
if (window.myEdit.ctx.latestOpDoc === undefined
|| window.myEdit.ctx.latestOpDoc === null
|| window.myEdit.ctx.latestOpDoc.getData().getAttribute("data-id") !== curP.getAttribute("data-id")) {
window.myEdit.ctx.latestOpDoc = new MyRecovery(curP.cloneNode(true), function () {
let cNo = parseInt(this.data.getAttribute("data-order"))
console.log("恢复", this.data, cNo, " this: ", this)
if (cNo > 1) {
window.myEdit.utils.InsertAfter(this.data, document.querySelector("#noteshare p[data-order='" + (cNo - 1) + "']"))
} else {
//添加元素到首位 todo_xxx
// window.myEdit.ctx.MyRoot.insertBefore(this.data, window.myEdit.ctx.MyRoot.children[0])
window.myEdit.ctx.MyRoot.insertBefore(this.data, window.myEdit.ctx.MyRoot.children[0]);
}
// 恢复该元素展示
window.myEdit.ctx.MyDocMap.get(cNo).setHidden(false);
})
}
//如果是第一行
let previousSibling = curP.previousSibling
console.log(curP, previousSibling === undefined, previousSibling.id === undefined)
if (previousSibling === undefined || previousSibling.id === undefined) {
//显示用户的输入内容
window.myEdit.ctx.showTestText()
return
}
console.log('触发删除', curP.innerHTML, cNo)
let curS = window.myEdit.utils.GetSelection();
// console.log("当前内容: ", curP.innerHTML, " 当前选区 :", curS)
//处理前面没有内容,后面还有内容需要拼接到上层的场景
if ((curS.isCollapsed && curS.anchorOffset === 0) || curP.innerHTML === '
') {
let curNodeRetainHtml = curP.innerHTML
//阻止事件传递
window.myEdit.utils.ProhibitDefaultEvent(event);
//设置该元素隐藏
window.myEdit.ctx.MyDocMap.get(cNo).setHidden(true)
//删除当前元素
// curP.remove()
curP.innerHTML = "
"
let emptyRowNoList = window.myEdit.ctx.MyDocMap.get("emptyRowNoList");
if (emptyRowNoList === undefined || emptyRowNoList === null) {
emptyRowNoList = [];
window.myEdit.ctx.MyDocMap.set("emptyRowNoList", emptyRowNoList);
}
emptyRowNoList.push(cNo);
//拼接
if (curNodeRetainHtml !== '
') {
previousSibling.innerHTML = previousSibling.innerHTML + curNodeRetainHtml
}
//收起选区到一个点,光标落在一个可编辑元素上
window.getSelection().setPosition(previousSibling, 1);
}
//显示用户的输入内容
window.myEdit.ctx.showTestText();
}
/**
* 回车事件
* @param event
* @param onkeydownHandle
*/
enterHandler(event) {
//阻止事件
window.myEdit.utils.ProhibitDefaultEvent(event);
//uuid
let uuid = window.myEdit.utils.Uuid();
//rowNo
let rowNo = 0;
let emptyRowNoList = window.myEdit.ctx.MyDocMap.get("emptyRowNoList");
console.log(emptyRowNoList);
let empListIsEmpty = (emptyRowNoList === undefined || emptyRowNoList === null || emptyRowNoList.length <= 0);
if (!empListIsEmpty) {
let tmpArr = [];
for (let i = 0; i < emptyRowNoList.length; i++) {
let tmpNo = emptyRowNoList[i];
if (window.myEdit.ctx.getMapItem(tmpNo).getHidden()) {
tmpArr.push(emptyRowNoList[i]);
}
}
window.myEdit.ctx.MyDocMap.set("emptyRowNoList", tmpArr);
empListIsEmpty = tmpArr.length <= 0;
emptyRowNoList = tmpArr
}
if (empListIsEmpty) {
rowNo = window.myEdit.ctx.incrementNumThenReturn();
//添加新元素
let newParagraph = document.createElement("p")
newParagraph.setAttribute("contenteditable", "true")
newParagraph.setAttribute("data-id", uuid)
newParagraph.setAttribute("id", uuid)
newParagraph.setAttribute("data-order", rowNo)
newParagraph.onkeydown = window.myEdit.eventListener.KeydownListener
// newParagraph.innerHTML = "
"
window.myEdit.ctx.MyRoot.appendChild(newParagraph)
window.myEdit.ctx.MyDocMap.set(rowNo, new MyMapItem(uuid))
//收起选区到一个点,光标落在一个可编辑元素上
window.getSelection().setPosition(newParagraph, 0);
return
}
let sortArr = emptyRowNoList.sort((a, b) => a - b)
console.log(sortArr);
// 最小值
rowNo = sortArr[0];
let newParagraph = document.querySelector("#noteshare p[data-order='" + rowNo + "']");
newParagraph.innerHTML = "
";
window.myEdit.ctx.MyDocMap.get(rowNo).setHidden(false);
//收起选区到一个点,光标落在一个可编辑元素上
window.getSelection().setPosition(newParagraph, 0)
}
/**
* 更新文档
* @param {*} e
*/
updateText(curP) {
if (window.myEdit.ctx.inCompositionEvent) {
return;
}
let myP = new MyDocItem(curP);
let cNo = myP.parseOrder();
let mapItem = window.myEdit.ctx.getMapItem(cNo)
//内容不变则不处理
let h5CurLen = curP.innerText.length
let myDocNodeLen = (mapItem && mapItem.getSource()) ? mapItem.getSource().length : 0
if (h5CurLen === myDocNodeLen) {
return
}
mapItem.setSource(curP.innerText);
mapItem.setHidden(false);
// console.log("curPTx: ", curP.innerText, "MyDocMap : ", utils.MyDocMap)
//显示用户的输入内容
window.myEdit.ctx.showTestText()
}
/**
* 空格键处理
* @param {*} event
*/
emptyKeyWorkHandler(event) {
let curP = window.myEdit.utils.GetEventTarget(event);
let myDocItem = new MyDocItem(curP);
let inputLength = curP.innerText.length
console.log("emptyKeyWorkHandler :", curP, " _'", curP.innerHTML, "'_'", curP.innerText, "'_",
"\neq00", curP.innerHTML.startsWith(" # "),
"\neq01", curP.innerHTML.startsWith(" # "),
"\neq1", curP.innerText.startsWith("# "),
"\neq2", curP.innerText.startsWith("#"),
"\neq3", curP.innerHTML.startsWith("# "),
"\neq4", curP.innerHTML.startsWith("# "))
/**
* h1 ~ h6
*/
if (curP.innerText.startsWith("#")) {
let curNo = myDocItem.parseOrder();
let mapNode = window.myEdit.ctx.MyDocMap.get(curNo);
if (curP.innerHTML.startsWith("######")) {
mapNode.getStyle().setNodeType("h6")
curP.innerHTML = curP.innerHTML.replace("######", "")
this.becomeAnotherElement(curP, "h6")
} else if (curP.innerHTML.startsWith("#####")) {
mapNode.getStyle().setNodeType("h5")
curP.innerHTML = curP.innerHTML.replace("#####", "")
this.becomeAnotherElement(curP, "h5")
} else if (curP.innerHTML.startsWith("####")) {
mapNode.getStyle().setNodeType("h4")
curP.innerHTML = curP.innerHTML.replace("####", "")
this.becomeAnotherElement(curP, "h4")
} else if (curP.innerHTML.startsWith("###")) {
mapNode.getStyle().setNodeType("h3")
curP.innerHTML = curP.innerHTML.replace("###", "")
this.becomeAnotherElement(curP, "h3")
} else if (curP.innerHTML.startsWith("##")) {
mapNode.getStyle().setNodeType("h2")
curP.innerHTML = curP.innerHTML.replace("##", "")
this.becomeAnotherElement(curP, "h2")
} else {
mapNode.getStyle().setNodeType("h1")
curP.innerHTML = curP.innerHTML.replace("#", "")
this.becomeAnotherElement(curP, "h1")
}
}
/**
* 无序列表效果
*/
if (curP.innerText.startsWith("-")) {
let curNo = myDocItem.parseOrder();
let mapNode = window.myEdit.ctx.MyDocMap.get(curNo);
mapNode.getStyle().setPreStyle("ul", true)
//clean
let historyContent = curP.innerHTML.replace("-", "");
mapNode.setSource(curP.innerText)
//根据上一层级元素动态选择 todo
curP.setAttribute("style", "padding-left: 1rem;")
//新增元素
let newParagraph = document.createElement("span");
newParagraph.setAttribute("contenteditable", "false")
//∙ vs ∘
newParagraph.innerHTML = "∙ "
curP.innerHTML = ""
curP.append(newParagraph);
curP.innerHTML = curP.innerHTML + historyContent
//收起选区到一个点,光标落在一个可编辑元素上
window.myEdit.utils.GetSelection().collapse(curP, true)
}
/**
* 有序列表效果
*/
let preContent = curP.innerText.split("\.")[0]
if (window.myEdit.utils.IsNum(preContent)) {
let curNo = myDocItem.parseOrder();
let mapNode = window.myEdit.ctx.MyDocMap.get(curNo);
mapNode.getStyle().setPreStyle("ol", preContent)
//clean
let historyContent = curP.innerHTML.replace(preContent + ".", "");
mapNode.setSource(curP.innerText)
//todo
curP.setAttribute("style", "padding-left: 1rem;")
//新增元素
let newParagraph = document.createElement("span");
newParagraph.setAttribute("contenteditable", "false");
newParagraph.innerHTML = preContent + ". "
curP.innerHTML = ""
curP.append(newParagraph);
curP.innerHTML = curP.innerHTML + historyContent
//收起选区到一个点,光标落在一个可编辑元素上
window.myEdit.utils.GetSelection().collapse(curP, true)
}
}
/**
* 变成另一个元素
* @param {*} elementName
*/
becomeAnotherElement(curP, elementName) {
let newParagraph = document.createElement(elementName)
newParagraph.setAttribute("contenteditable", "true")
newParagraph.setAttribute("data-id", curP.getAttribute("data-id"))
newParagraph.setAttribute("id", curP.getAttribute("data-id"))
newParagraph.setAttribute("data-order", curP.getAttribute("data-order"))
newParagraph.onkeydown = window.myEdit.eventListener.KeydownListener
//todo 支持 有数据的行 在行首输入 #
// if()
// switch (elementName){
// case "h1":
// }
newParagraph.innerHTML = curP.innerHTML
window.myEdit.utils.InsertAfter(curP, newParagraph)
curP.remove();
curP = newParagraph;
//matData
let myP = new MyDocItem(curP);
let curNo = myP.parseOrder();
let mapNode = window.myEdit.ctx.getMapItem(curNo)
mapNode.setSource(curP.innerText)
//收起选区到一个点,光标落在一个可编辑元素上
window.myEdit.utils.GetSelection().setPosition(newParagraph, 0)
}
/**
* 包围样式事件处理
* @param event
*/
surroundContentsByStyleHandler(event) {
let curS = window.myEdit.utils.GetSelection();
let curP = window.myEdit.utils.GetEventTarget(event);
let styleName = curP.getAttribute("data-value");
if (styleName === undefined || styleName === null) {
styleName = curP.closest("span").getAttribute("data-value");
console.log("closest: ", curP, curP.closest("span"))
}
let className = this.parseStyleName2ClassName(styleName)
//todo 只对 nodeType = p 执行
console.log("当前光标信息: ", curS, styleName, " className: ", className, curP)
for (let i = 0; i < curS.rangeCount; i++) {
let curSec = curS.getRangeAt(i);
let curPe = curSec.commonAncestorContainer;
//一个元素节点,例如
和
if (!curPeIsP && curPeParentIsP) { //没选择,则退出 if (start === end) { return } else { // div } let curStartP = curSec.startContainer.parentElement; console.log("debug1: ", curStartP, curStartP.nodeType, curStartP.nodeName) //维护最近一次编辑的内容(暂时只支持恢复最近一次编辑) window.myEdit.ctx.latestOpDoc = new 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 window.myEdit.utils.SyncMapItemChildrenStyle(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; //光标保持 // curS.collapseToEnd(); // window.myEdit.utils.GetSelection().setPosition(newParagraph, 0); } else { let tmpPNode = curSec.commonAncestorContainer; if (!curPeIsP && curPeParentIsSpan) { tmpPNode = curSec.commonAncestorContainer.parentNode.parentNode; } console.log("debug2: ", curSec.commonAncestorContainer, tmpPNode, tmpPNode.children, tmpPNode.childNodes) //维护最近一次编辑的内容(暂时只支持恢复最近一次编辑) window.myEdit.ctx.latestOpDoc = new MyRecovery(tmpPNode.cloneNode(true), function () { console.log("恢复上一步样式1", this.data) let curEl = document.getElementById(this.data.getAttribute("id")); curEl.innerHTML = this.data.innerHTML; //文本映射 直接覆盖 map 中的 childrenStyle window.myEdit.utils.SyncMapItemChildrenStyle(this.data); }) let myChildren = tmpPNode.childNodes // let curEleSize = tmpPNode.childNodes.length for (let j = 0; j < myChildren.length; j++) { let curEle = myChildren[j] if (curS.containsNode(curEle, true)) { curEle.classList.remove(className); curEle.classList.add(className); } } curPEle = curSec.commonAncestorContainer; } //文本映射 直接覆盖 map 中的 childrenStyle window.myEdit.utils.SyncMapItemChildrenStyle(curPEle); } } }