shaoyongjun c31252f2c8 to:sync
2024-10-28 01:33:33 +08:00

419 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** *
* 工具类
*/
(function () {
/**
* 最新修改的元素
*/
const latestOpDoc = null
class MyRecovery {
constructor(data, func) {
this.data = data;
this.func = func;
}
getData() {
return this.data;
}
getFun() {
return this.func;
}
recovery() {
this.func();
}
}
/**
* 行数增加记录
*/
const num = 0
/**
* 是否开始输入中文
*/
const inCompositionEvent = false;
/**
* 我的文档数据
*/
const MyDocMap = new Map()
// push推一个在后面就是 append 的意思
// pop从后面拉走配合 push 就是栈
// unshift从前面加一个数据就是 insert(it, 0) 的意思
// shift前面拉个数据走配合 shift 就是一个反向栈,配合 push 就是队列
class MyQueue {
constructor(size) {
this.insertIndex = 0
this.delIndex = 0
this.capacity = 0;
this.size = size;
this.arr = new Array(size);
}
push(handle) {
if (this.capacity === this.arr.length) {
console.log("满了");
this.capacity--;
this.arr[this.capacity] = null;
//todo 替代
// this.end++;
}
this.arr[this.capacity] = handle;
this.capacity++;
}
pull() {
if (this.capacity <= 0) {
return null
}
this.capacity--;
//到底回退
if (this.shift > this.size) {
this.shift = 0;
}
return this.arr[this.shift];
}
}
class MyNode {
constructor(id) {
this.id = id
this.hidden = false
this.style = new InnerStyle()
}
getHidden() {
return this.hidden
}
setHidden(val) {
this.hidden = val
}
setSource(source) {
this.source = source
}
getSource() {
return this.source
}
getStyle() {
return this.style
}
}
class InnerStyle {
constructor() {
this.nodeType = "p"
//map-> index:classList
this.childrenStyle = null;
this.preStyle = null;
this.getNodeType = function getNodeType() {
return this.nodeType
}
this.setNodeType = function setNodeType(nodeType) {
this.nodeType = nodeType
}
//前置类型 如 ul ol 代码块 等
this.setPreStyle = function setPreStyle(k, v) {
if (this.preStyle == null) {
this.preStyle = new MyKV(k, v);
}
}
this.getPreStyle = function getPreStyle() {
return this.preStyle
}
}
setChildrenStyle(index, classList) {
if (this.childrenStyle === null) {
this.childrenStyle = new Map();
}
this.childrenStyle.set(index, classList)
}
getChildrenStyle(index) {
return this.childrenStyle.get(index);
}
getChildrenStyleMap() {
return this.childrenStyle;
}
setChildrenStyleMapNull() {
this.childrenStyle = null;
}
}
class MyKV {
constructor(k, v) {
this.k = k
this.v = v
this.getK = function getK() {
return this.k
}
this.getV = function getV() {
return this.v
}
}
}
/**
* 主节点元素
*/
const MyRoot = document.getElementById("noteshare")
function isNum(value) {
return !isNaN(parseFloat(value)) && isFinite(value)
}
function getSelection() {
return window.getSelection() || document.selection
}
/**
*
* @returns 生产uuid
*/
function uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
.replace(/[xy]/g, function (c) {
const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8)
return v.toString(16)
}).split("-")[0]
}
/**
* 在目标元素后面插叙 新元素
* @param {*} newElement
* @param {*} targetElement
*/
function insertAfter(newElement, targetElement) {
// console.log("开始: ",newElement, targetElement)
var parent = targetElement.parentNode
if (parent.lastChild == targetElement) {
// 如果最后的节点是目标元素,则直接添加。因为默认是最后
parent.appendChild(newElement)
} else {
parent.insertBefore(newElement, targetElement.nextSibling)
//如果不是,则插入在目标元素的下一个兄弟节点 的前面。也就是目标元素的后面
}
}
function parseOrder(curP) {
return parseInt(curP.getAttribute("data-order"))
}
/**
*
* @param {*} curP
* @param onkeydownHandle
*/
function firstCmd(curP, onkeydownHandle) {
let newParagraph;
let inputLength = curP.innerText.length
/**
* h1 ~ h6
*/
if (curP.innerText.startsWith("#") && curP.innerHTML.endsWith("&nbsp;")) {
let curNo = parseOrder(curP)
let mapNode = utils.MyDocMap.get(curNo)
// console.log(curP, " - ", curP.innerHTML, curP.innerHTML.startsWith("# "))
if (curP.innerHTML.startsWith("#&nbsp;") || curP.innerHTML.startsWith("# ")) {
mapNode.getStyle().setNodeType("h1")
becomeAnotherElement(curP, "h1", onkeydownHandle)
} else if (curP.innerHTML.startsWith("##&nbsp;")) {
mapNode.getStyle().setNodeType("h2")
becomeAnotherElement(curP, "h2", onkeydownHandle)
} else if (curP.innerHTML.startsWith("###&nbsp;")) {
mapNode.getStyle().setNodeType("h3")
becomeAnotherElement(curP, "h3", onkeydownHandle)
} else if (curP.innerHTML.startsWith("####&nbsp;")) {
mapNode.getStyle().setNodeType("h4")
becomeAnotherElement(curP, "h4", onkeydownHandle)
} else if (curP.innerHTML.startsWith("#####&nbsp;")) {
mapNode.getStyle().setNodeType("h5")
becomeAnotherElement(curP, "h5", onkeydownHandle)
} else {
mapNode.getStyle().setNodeType("h6")
becomeAnotherElement(curP, "h6", onkeydownHandle)
}
}
/**
* 无序列表效果
*/
if (inputLength === 2 && curP.innerText.startsWith("-") && curP.innerHTML.endsWith("&nbsp;")) {
let curNo = parseOrder(curP)
let mapNode = utils.MyDocMap.get(curNo)
mapNode.getStyle().setPreStyle("ul", true)
//clean
curP.innerHTML = ""
mapNode.setSource("")
//根据上一层级元素动态选择 todo
curP.setAttribute("style", "padding-left: 1rem;")
//新增元素
newParagraph = document.createElement("span");
newParagraph.setAttribute("contenteditable", "false")
//∙ vs ∘
newParagraph.innerHTML = "∙ &nbsp;"
curP.append(newParagraph)
//添加一个选区
var selObj = window.getSelection()
var rangeObj = document.createRange()
rangeObj.selectNode(curP)
selObj.addRange(rangeObj)
//收起选区到一个点,光标落在一个可编辑元素上
window.getSelection().collapse(curP, true)
}
/**
* 有序列表效果
*/
if (inputLength > 2 && inputLength <= 5 && isNum(curP.innerText.substring(0, inputLength - 2)) && curP.innerHTML.endsWith(".&nbsp;")) {
let num = curP.innerText.substring(0, inputLength - 2)
console.log(curP.innerText, num)
let curNo = parseOrder(curP)
let mapNode = utils.MyDocMap.get(curNo)
mapNode.getStyle().setPreStyle("ol", num)
//clean
curP.innerHTML = ""
mapNode.setSource("")
//todo
curP.setAttribute("style", "padding-left: 1rem;")
//新增元素
newParagraph = document.createElement("span");
newParagraph.setAttribute("contenteditable", "false")
newParagraph.innerHTML = num + ".&nbsp;"
curP.append(newParagraph)
//添加一个选区
var selObj = window.getSelection()
var rangeObj = document.createRange()
rangeObj.selectNode(curP)
selObj.addRange(rangeObj)
//收起选区到一个点,光标落在一个可编辑元素上
window.getSelection().collapse(curP, true)
}
}
/**
* 变成另一个元素
* @param {*} curP
* @param {*} elementName
*/
function becomeAnotherElement(curP, elementName, onkeydownHandle) {
var 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 = onkeydownHandle
//todo 支持 有数据的行 在行首输入 #
// if()
// switch (elementName){
// case "h1":
// }
newParagraph.innerHTML = "<br>"
insertAfter(newParagraph, curP)
curP.remove()
//matData
let curNo = parseOrder(curP)
let mapNode = utils.MyDocMap.get(curNo)
mapNode.setSource("")
//收起选区到一个点,光标落在一个可编辑元素上
window.getSelection().setPosition(newParagraph, 0)
}
function 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"
}
}
function syncOnePInfo(p) {
//子元素为空不处理
if (p.children.length <= 0) {
return
}
// let id = p.getAttribute("id");
let order = parseInt(p.getAttribute("data-order"));
let curMapData = this.MyDocMap.get(order);
//清空重置
curMapData.getStyle().setChildrenStyleMapNull();
for (let i = 0; i < p.children.length; i++) {
let curItem = p.children[i];
let tmpClassList = curItem.classList;
if (tmpClassList != null && tmpClassList.length > 0) {
curMapData.getStyle().setChildrenStyle(i, tmpClassList);
}
}
console.log("curPEle : ", p, " children: ", p.children, " childrenMap: ", curMapData.getStyle().getChildrenStyleMap())
}
window.utils = {
isNum,
uuid,
parseOrder,
getSelection,
insertAfter,
firstCmd,
becomeAnotherElement,
parseStyleName2ClassName,
syncOnePInfo,
latestOpDoc,
num,
inCompositionEvent,
MyDocMap,
MyRoot,
MyNode,
InnerStyle,
MyKV,
MyQueue,
MyRecovery,
}
})()