mylomen-server/static/js/event/impl/MutationObserverImpl.js
shaoyongjun 97611ea548 to:sync
2024-11-09 18:59:45 +08:00

289 lines
13 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.

"use strict";
/**
* 使用样式事件
*/
define(function (require, exports, module) {
function handle(mutationList) {
for (let mutation of mutationList) {
switch (mutation.type) {
case "childList":
addNewP(mutation);
break;
case "characterData":
updateText(mutation);
break;
case "attributes":
//暂时忽略属性变化
break
default: {
other(mutation);
}
}
}
}
function other(mutation) {
console.dir(mutation)
// console.log("other -> mutation : ", mutation,
// // 观察的变动类型attributes、characterData或者childList
// "\ntype", mutation.type,
// //发生变动的DOM节点。
// "\ntarget", mutation.target, mutation.target.nodeName, mutation.previousSibling,
// "\ntargetParent", mutation.target.parentElement, mutation.target.parentNode,
// //新增的DOM节点。
// "\naddedNodes", mutation.addedNodes,
// //删除的DOM节点。
// "\nremovedNodes", mutation.removedNodes,
// //前一个同级节点如果没有则返回null。
// "\npreviousSibling", mutation.previousSibling,
// //下一个同级节点如果没有则返回null。
// "\nnextSibling", mutation.nextSibling,
// //发生变动的属性。如果设置了attributeFilter则只返回预先指定的属性。
// "\nattributeName", mutation.attributeName,
// //变动前的值。这个属性只对attribute和characterData变动有效如果发生childList变动则返回null。
// "\noldValue", mutation.oldValue);
}
function addNewP(mutation) {
//div 下新增p元素
let target = mutation.target;
// target.clone()
if (target.nodeName === "DIV" && mutation.previousSibling !== null) {
let utils = require("../../common/utils");
let ctx = require("../../common/ctx");
let newParagraph = mutation.previousSibling.nextSibling;
console.log(
"addNewP target: ", target,
"\nnodeType: ", target.nodeType,
"\nnodeName: ", target.nodeName,
"\ndata: ", target.value,
"\n next: ", newParagraph,
"\ncurRowNo: ", ctx.getCurRowNo()
)
if (newParagraph !== undefined && newParagraph !== null) {
newParagraph.id = utils.Uuid(ctx.usn, ctx.docType);
newParagraph.setAttribute("data-order", ctx.incrementNumThenReturn());
// let newParagraph = document.getElementById(targetP.id);
//前置 span
let preSpan = newParagraph.querySelector("span[data-flag='span_pre']");
if (preSpan === undefined || preSpan === null) {
preSpan = document.createElement("span");
preSpan.setAttribute("contenteditable", "false")
preSpan.setAttribute("data-flag", "span_pre")
//额外处理无序和有序列表
let preP = newParagraph.previousElementSibling;
if (preP !== undefined && preP !== null) {
let preSpanTxtOfPreP = preP.querySelector("span[data-flag='span_pre']").textContent;
if (preSpanTxtOfPreP === " • " || preSpanTxtOfPreP === " ◦ " || preSpanTxtOfPreP === " ▪ ") {
preSpan.setAttribute("contenteditable", "true");
preSpan.innerHTML = "<span contenteditable='false'>" + preSpanTxtOfPreP + "</span>";
}
}
//添加到元素首位
newParagraph.insertBefore(preSpan, newParagraph.firstChild);
} else {
console.log("newParagraph preSpan exist ", newParagraph, " ", preSpan)
}
//内置span
let spanContent = newParagraph.querySelector("span[data-flag='span_content']");
if (spanContent === undefined || spanContent === null) {
spanContent = document.createElement("span");
spanContent.append(document.createElement("br"));
spanContent.setAttribute("data-flag", "span_content")
spanContent.setAttribute("placeholder", "请输入")
newParagraph.appendChild(spanContent);
} else {
console.log("newParagraph spanContent exist", spanContent);
spanContent.innerHTML = "<br/>";
}
utils.GetSelection().removeAllRanges();
utils.GetSelection().setPosition(spanContent, 0);
spanContent.focus();
}
return
}
//解决flex 布局 for 无序列表 前面可以输入问题)回车不换行问题
if (target.nodeName === "P" && target.getAttribute("data-order") != null
&& mutation.previousSibling !== null && mutation.previousSibling.getAttribute("data-flag") === "span_content") { //
let utils = require("../../common/utils");
let flagP = target;
for (let i = 0; i < mutation.addedNodes.length; i++) {
let tmpSpan = mutation.addedNodes[i];
let tmpP = document.createElement("p");
tmpP.appendChild(tmpSpan)
utils.InsertAfter(flagP, tmpP);
flagP = tmpP;
}
// console.log(
// "addNewSpan target: ", target,
// "\nmutation:", mutation,
// "\naddedNodes:", mutation.addedNodes,
// "\nnodeType: ", target.nodeType,
// "\nnodeName: ", target.nodeName,
// "\ndata: ", target.value,
// "\n previousContentSpan: ", previousContentSpan,
// "\ncurRowNo: ", ctx.getCurRowNo()
// )
return;
}
//删除 for 无序列表 删除样式恢复正常行
if (mutation.removedNodes.length === 0
&& mutation.addedNodes.length === 1
&& target.nodeName === "P" && target.getAttribute("data-order") != null
// && target.childNodes
&& mutation.addedNodes[0].nodeName === "BR"
) {
console.log(
"删除 br target: ", target,
"\nmutation:", mutation,
"\ntarget.childNodes:", target.childNodes,
"\naddedNodes:", mutation.addedNodes,
"\nremovedNodes:", mutation.removedNodes,
"\nnodeType: ", mutation.addedNodes[0].nodeType,
"\nnodeName: ", mutation.addedNodes[0].nodeName,
"\ndata: ", mutation.addedNodes[0].value
)
console.log("捕捉 ‘删除样式恢复正常行’ 成功")
let spanContent = document.createElement("span");
spanContent.setAttribute("data-flag", "span_content")
spanContent.innerHTML = "<br>";
target.innerHTML = null;
target.append(spanContent);
return;
}
other(mutation);
}
function updateText(mutation) {
let target = mutation.target;
if (target.nodeType === 3 && target.nodeName === "#text") {
let utils = require("../../common/utils");
let ctx = require("../../common/ctx");
//测试内容填写
let testDiv = document.getElementById("testDevice");
testDiv.innerText = mutation.oldValue
let grandfatherElement = target.parentNode?.parentElement;
//处理添加了样式的 行
if (grandfatherElement != null && grandfatherElement.getAttribute("data-flag") === "span_content") {
//正在输入中文直接忽略
if (ctx.Compositionstart) {
return;
}
let select = utils.GetSelection();
let selectRange = select.getRangeAt(0);
if (select.isCollapsed) { //输入场景
let tmpSpan = selectRange.startContainer.parentElement;
console.log(utils.GetText(tmpSpan))
let curTxt = utils.GetText(tmpSpan);
if (curTxt.trim().length <= 1) {
return
}
// console.dir(select)
// console.dir(mutation)
// console.dir(grandfatherElement)
// console.dir(tmpSpan)
// console.log(tmpSpan)
// console.log(curTxt.split(''))
let curTxtArr = curTxt.split('');
//保留一个
tmpSpan.innerText = curTxtArr[0];
let lastSpan = tmpSpan;
for (let i = 1; i < curTxtArr.length; i++) {
let tmpSpan = document.createElement("span");
tmpSpan.innerText = curTxtArr[i];
utils.InsertAfter(lastSpan, tmpSpan);
lastSpan = tmpSpan;
}
//选区调整
console.log("lastSpan : ", lastSpan)
utils.GetSelection().setPosition(lastSpan, 1);
} else {
console.log("TODO 暂时不支持")
}
} else { // 处理没有添加样式的行
console.log("TODO 暂时不支持")
}
//处理无序列表和有序列表 探究
if (target.parentNode === undefined || target.parentNode?.parentElement === undefined) {
return;
}
// console.log(
// "updateText mutation: ", mutation,
// "\ntarget: ", target,
// "\nnodeType: ", target.nodeType,
// "\nnodeName: ", target.nodeName,
// "\ndata: ", target.value,
// "\noldValue: ", target.oldValue, target.oldValue?.startsWith("- "),
// "\nparentNode: ", target.parentNode, target.parentElement,
// "\nparentNode_parentNode: ", target.parentNode?.parentElement,
// )
let curP = target.parentElement?.closest("p");
let curSpanContent = curP.querySelector("span[data-flag='span_content']")
// console.log("curSpanContent: ", curSpanContent)
//无序列表
if (curSpanContent.innerHTML.startsWith("- ") || curSpanContent.innerHTML.startsWith("-&nbsp;")) {
let curPreSpan = curP.querySelector("span[data-flag='span_pre']");
let curPreSpanTxt = utils.GetText(curPreSpan);
if (curPreSpanTxt === " • " || curPreSpanTxt === " ◦ " || curPreSpanTxt === " ▪ ") {
return;
} else {
let previousSiblingP = curP.previousElementSibling;
let preSpanTxtOfPreP = null
if (previousSiblingP != null) {
let tmpPre = previousSiblingP.querySelector("span[data-flag='span_pre']");
preSpanTxtOfPreP = utils.GetText(tmpPre);
}
//上一级是否也是无序列表。 如果是则 后移
if (preSpanTxtOfPreP != null && (preSpanTxtOfPreP === " • " || preSpanTxtOfPreP === " ◦ " || preSpanTxtOfPreP === " ▪ ")) {
if (preSpanTxtOfPreP === " • ") {
curPreSpan.setAttribute("contenteditable", "true");
curPreSpan.innerHTML = "<span contenteditable='false'>" + " ◦ " + "</span>"
} else if (preSpanTxtOfPreP === " ◦ ") {
curPreSpan.setAttribute("contenteditable", "true");
curPreSpan.innerHTML = "<span contenteditable='false'>" + " ▪ " + "</span>"
} else {
console.log("不支持继续下转")
}
} else {
curPreSpan.innerHTML = "<span>" + " • " + "</span>"
}
curSpanContent.textContent = curSpanContent.textContent.substring(2, curSpanContent.textContent.length);
//光标定位
utils.GetSelection().removeAllRanges();
utils.GetSelection().setPosition(curSpanContent, 0);
curSpanContent.focus();
}
}
} else {
other(mutation);
}
}
//导出
exports.handle = handle;
});