diff --git a/app/src/protyle/wysiwyg/enter.ts b/app/src/protyle/wysiwyg/enter.ts index ed2e537be..eae5b72cb 100644 --- a/app/src/protyle/wysiwyg/enter.ts +++ b/app/src/protyle/wysiwyg/enter.ts @@ -17,195 +17,6 @@ import {isIPad, setStorageVal} from "../util/compatibility"; import {mathRender} from "../render/mathRender"; import {isMobile} from "../../util/functions"; -const listEnter = (protyle: IProtyle, blockElement: HTMLElement, range: Range) => { - const listItemElement = blockElement.parentElement; - - const editableElement = getContenteditableElement(blockElement); - if (// \n 是因为 https://github.com/siyuan-note/siyuan/issues/3846 - ["", "\n"].includes(editableElement.textContent) && - blockElement.previousElementSibling.classList.contains("protyle-action") && - !blockElement.querySelector("img") // https://ld246.com/article/1651820644238 - ) { - if (listItemElement.nextElementSibling?.classList.contains("protyle-attr")) { - listOutdent(protyle, [blockElement.parentElement], range); - return true; - } else if (!listItemElement.parentElement.classList.contains("protyle-wysiwyg")) { - // 打断列表 - breakList(protyle, blockElement, range); - return true; - } - } - - const position = getSelectionOffset(editableElement, protyle.wysiwyg.element, range); - if (range.toString() === "" && position.start === 0 && - // 段首为图片是 start 也为 0 - !hasPreviousSibling(range.startContainer)) { - // 段首换行 - if (listItemElement.parentElement.classList.contains("protyle-wysiwyg")) { - return true; - } - // https://github.com/siyuan-note/siyuan/issues/8935 - const wbrElement = document.createElement("wbr"); - range.insertNode(wbrElement); - const html = listItemElement.parentElement.outerHTML; - wbrElement.remove(); - let newElement = genListItemElement(listItemElement, -1, true); - if (!blockElement.previousElementSibling.classList.contains("protyle-action")) { - // 列表项中有多个块,最后一个块为空,换行应进行缩进 - if (getContenteditableElement(blockElement).textContent !== "") { - return false; - } - blockElement.remove(); - newElement = genListItemElement(listItemElement, -1, true); - listItemElement.insertAdjacentElement("afterend", newElement); - } else if (getContenteditableElement(blockElement).textContent === "") { - listItemElement.insertAdjacentElement("afterend", newElement); - } else { - listItemElement.insertAdjacentElement("beforebegin", newElement); - } - if (listItemElement.getAttribute("data-subtype") === "o") { - updateListOrder(listItemElement.parentElement); - } - updateTransaction(protyle, listItemElement.parentElement.getAttribute("data-node-id"), listItemElement.parentElement.outerHTML, html); - focusByWbr(newElement, range); - scrollCenter(protyle); - removeEmptyNode(newElement); - return true; - } - - const subListElement = listItemElement.querySelector(".list"); - let newElement; - if (subListElement && listItemElement.getAttribute("fold") !== "1" && - // 子列表下的段落块回车 https://ld246.com/article/1623919354587 - blockElement.nextElementSibling.isSameNode(subListElement)) { - // 含有子列表的换行 - if (position.end >= editableElement.textContent.length - - // 数学公式结尾会有 zwsp https://github.com/siyuan-note/siyuan/issues/6679 - (editableElement.textContent.endsWith(Constants.ZWSP) ? 1 : 0)) { - // 段末换行,在子列表中插入 - range.insertNode(document.createElement("wbr")); - const html = subListElement.outerHTML; - blockElement.querySelector("wbr").remove(); - newElement = genListItemElement(subListElement.firstElementChild, -1, true); - subListElement.firstElementChild.before(newElement); - if (subListElement.getAttribute("data-subtype") === "o") { - updateListOrder(subListElement); - } - updateTransaction(protyle, subListElement.getAttribute("data-node-id"), subListElement.outerHTML, html); - focusByWbr(listItemElement, range); - scrollCenter(protyle); - } else { - // 文字中间换行 - range.insertNode(document.createElement("wbr")); - const listItemHTMl = listItemElement.outerHTML; - const html = listItemElement.parentElement.outerHTML; - if (range.toString() !== "") { - range.extractContents(); - range.insertNode(document.createElement("wbr")); - } - range.setEndAfter(editableElement.lastChild); - newElement = genListItemElement(listItemElement, 0, false); - const newEditElement = getContenteditableElement(newElement); - newEditElement.appendChild(range.extractContents()); - newEditElement.parentElement.after(subListElement); - listItemElement.insertAdjacentElement("afterend", newElement); - if (listItemElement.getAttribute("data-subtype") === "o") { - updateListOrder(listItemElement.parentElement); - } - if (listItemElement.parentElement.classList.contains("protyle-wysiwyg")) { - transaction(protyle, [{ - action: "update", - data: listItemElement.outerHTML, - id: listItemElement.getAttribute("data-node-id") - }, { - action: "insert", - id: newElement.getAttribute("data-node-id"), - data: newElement.outerHTML, - previousID: listItemElement.getAttribute("data-node-id") - }], [{ - action: "delete", - id: newElement.getAttribute("data-node-id"), - }, { - action: "update", - data: listItemHTMl, - id: listItemElement.getAttribute("data-node-id") - }]); - } else { - updateTransaction(protyle, listItemElement.parentElement.getAttribute("data-node-id"), listItemElement.parentElement.outerHTML, html); - } - focusByWbr(newElement, range); - scrollCenter(protyle); - } - removeEmptyNode(newElement); - return true; - } - if ((range.toString() === "" || range.toString() === Constants.ZWSP) && range.startContainer.nodeType === 3 && range.startOffset === 0) { - // 图片后的零宽空格前回车 https://github.com/siyuan-note/siyuan/issues/5690 - // 列表中的图片后双击换行图片光标错误 https://ld246.com/article/1660987186727/comment/1662181221732?r=Vanessa#comments - let nextSibling = range.startContainer; - while (nextSibling) { - if (nextSibling.textContent === Constants.ZWSP) { - range.setStart(nextSibling, 1); - range.collapse(false); - break; - } else { - nextSibling = nextSibling.nextSibling; - } - } - } - range.insertNode(document.createElement("wbr")); - const listItemHTML = listItemElement.outerHTML; - const html = listItemElement.parentElement.outerHTML; - if (range.toString() !== "") { - range.extractContents(); - range.insertNode(document.createElement("wbr")); - } - range.setEndAfter(editableElement.lastChild); - newElement = genListItemElement(listItemElement, 0, false); - const selectNode = range.extractContents(); - if (selectNode.firstChild.nodeType !== 3 && selectNode.firstChild.textContent === "") { - // 回车移除空元素 https://github.com/siyuan-note/insider/issues/480 - selectNode.firstChild.after(document.createElement("wbr")); - selectNode.firstChild.remove(); - } - // https://github.com/siyuan-note/siyuan/issues/3850 - // https://github.com/siyuan-note/siyuan/issues/6018 - if ((editableElement?.lastElementChild?.getAttribute("data-type") || "").indexOf("inline-math") > -1 && - !hasNextSibling(editableElement?.lastElementChild)) { - editableElement.insertAdjacentText("beforeend", "\n"); - } - getContenteditableElement(newElement).appendChild(selectNode); - listItemElement.insertAdjacentElement("afterend", newElement); - if (listItemElement.getAttribute("data-subtype") === "o") { - updateListOrder(listItemElement.parentElement); - } - if (listItemElement.parentElement.classList.contains("protyle-wysiwyg")) { - transaction(protyle, [{ - action: "update", - id: listItemElement.getAttribute("data-node-id"), - data: listItemElement.outerHTML, - }, { - action: "insert", - id: newElement.getAttribute("data-node-id"), - data: newElement.outerHTML, - previousID: listItemElement.getAttribute("data-node-id") - }], [{ - action: "delete", - id: newElement.getAttribute("data-node-id"), - }, { - action: "update", - id: listItemElement.getAttribute("data-node-id"), - data: listItemHTML - }]); - } else { - updateTransaction(protyle, listItemElement.parentElement.getAttribute("data-node-id"), listItemElement.parentElement.outerHTML, html); - } - focusByWbr(newElement, range); - scrollCenter(protyle); - removeEmptyNode(newElement); - return true; -}; - export const enter = (blockElement: HTMLElement, range: Range, protyle: IProtyle) => { const disableElement = isNotEditBlock(blockElement); if (!disableElement && blockElement.classList.contains("protyle-wysiwyg--select")) { @@ -215,7 +26,9 @@ export const enter = (blockElement: HTMLElement, range: Range, protyle: IProtyle return; } // https://github.com/siyuan-note/siyuan/issues/5471 - if (disableElement) { + if (disableElement || + // https://github.com/siyuan-note/siyuan/issues/10633 + blockElement.classList.contains("table")) { if (blockElement.parentElement.classList.contains("li")) { const oldHTML = blockElement.parentElement.parentElement.outerHTML; const newElement = genListItemElement(blockElement.parentElement, 0, true); @@ -446,6 +259,195 @@ export const enter = (blockElement: HTMLElement, range: Range, protyle: IProtyle return true; }; +const listEnter = (protyle: IProtyle, blockElement: HTMLElement, range: Range) => { + const listItemElement = blockElement.parentElement; + + const editableElement = getContenteditableElement(blockElement); + if (// \n 是因为 https://github.com/siyuan-note/siyuan/issues/3846 + ["", "\n"].includes(editableElement.textContent) && + blockElement.previousElementSibling.classList.contains("protyle-action") && + !blockElement.querySelector("img") // https://ld246.com/article/1651820644238 + ) { + if (listItemElement.nextElementSibling?.classList.contains("protyle-attr")) { + listOutdent(protyle, [blockElement.parentElement], range); + return true; + } else if (!listItemElement.parentElement.classList.contains("protyle-wysiwyg")) { + // 打断列表 + breakList(protyle, blockElement, range); + return true; + } + } + + const position = getSelectionOffset(editableElement, protyle.wysiwyg.element, range); + if (range.toString() === "" && position.start === 0 && + // 段首为图片是 start 也为 0 + !hasPreviousSibling(range.startContainer)) { + // 段首换行 + if (listItemElement.parentElement.classList.contains("protyle-wysiwyg")) { + return true; + } + // https://github.com/siyuan-note/siyuan/issues/8935 + const wbrElement = document.createElement("wbr"); + range.insertNode(wbrElement); + const html = listItemElement.parentElement.outerHTML; + wbrElement.remove(); + let newElement = genListItemElement(listItemElement, -1, true); + if (!blockElement.previousElementSibling.classList.contains("protyle-action")) { + // 列表项中有多个块,最后一个块为空,换行应进行缩进 + if (getContenteditableElement(blockElement).textContent !== "") { + return false; + } + blockElement.remove(); + newElement = genListItemElement(listItemElement, -1, true); + listItemElement.insertAdjacentElement("afterend", newElement); + } else if (getContenteditableElement(blockElement).textContent === "") { + listItemElement.insertAdjacentElement("afterend", newElement); + } else { + listItemElement.insertAdjacentElement("beforebegin", newElement); + } + if (listItemElement.getAttribute("data-subtype") === "o") { + updateListOrder(listItemElement.parentElement); + } + updateTransaction(protyle, listItemElement.parentElement.getAttribute("data-node-id"), listItemElement.parentElement.outerHTML, html); + focusByWbr(newElement, range); + scrollCenter(protyle); + removeEmptyNode(newElement); + return true; + } + + const subListElement = listItemElement.querySelector(".list"); + let newElement; + if (subListElement && listItemElement.getAttribute("fold") !== "1" && + // 子列表下的段落块回车 https://ld246.com/article/1623919354587 + blockElement.nextElementSibling.isSameNode(subListElement)) { + // 含有子列表的换行 + if (position.end >= editableElement.textContent.length - + // 数学公式结尾会有 zwsp https://github.com/siyuan-note/siyuan/issues/6679 + (editableElement.textContent.endsWith(Constants.ZWSP) ? 1 : 0)) { + // 段末换行,在子列表中插入 + range.insertNode(document.createElement("wbr")); + const html = subListElement.outerHTML; + blockElement.querySelector("wbr").remove(); + newElement = genListItemElement(subListElement.firstElementChild, -1, true); + subListElement.firstElementChild.before(newElement); + if (subListElement.getAttribute("data-subtype") === "o") { + updateListOrder(subListElement); + } + updateTransaction(protyle, subListElement.getAttribute("data-node-id"), subListElement.outerHTML, html); + focusByWbr(listItemElement, range); + scrollCenter(protyle); + } else { + // 文字中间换行 + range.insertNode(document.createElement("wbr")); + const listItemHTMl = listItemElement.outerHTML; + const html = listItemElement.parentElement.outerHTML; + if (range.toString() !== "") { + range.extractContents(); + range.insertNode(document.createElement("wbr")); + } + range.setEndAfter(editableElement.lastChild); + newElement = genListItemElement(listItemElement, 0, false); + const newEditElement = getContenteditableElement(newElement); + newEditElement.appendChild(range.extractContents()); + newEditElement.parentElement.after(subListElement); + listItemElement.insertAdjacentElement("afterend", newElement); + if (listItemElement.getAttribute("data-subtype") === "o") { + updateListOrder(listItemElement.parentElement); + } + if (listItemElement.parentElement.classList.contains("protyle-wysiwyg")) { + transaction(protyle, [{ + action: "update", + data: listItemElement.outerHTML, + id: listItemElement.getAttribute("data-node-id") + }, { + action: "insert", + id: newElement.getAttribute("data-node-id"), + data: newElement.outerHTML, + previousID: listItemElement.getAttribute("data-node-id") + }], [{ + action: "delete", + id: newElement.getAttribute("data-node-id"), + }, { + action: "update", + data: listItemHTMl, + id: listItemElement.getAttribute("data-node-id") + }]); + } else { + updateTransaction(protyle, listItemElement.parentElement.getAttribute("data-node-id"), listItemElement.parentElement.outerHTML, html); + } + focusByWbr(newElement, range); + scrollCenter(protyle); + } + removeEmptyNode(newElement); + return true; + } + if ((range.toString() === "" || range.toString() === Constants.ZWSP) && range.startContainer.nodeType === 3 && range.startOffset === 0) { + // 图片后的零宽空格前回车 https://github.com/siyuan-note/siyuan/issues/5690 + // 列表中的图片后双击换行图片光标错误 https://ld246.com/article/1660987186727/comment/1662181221732?r=Vanessa#comments + let nextSibling = range.startContainer; + while (nextSibling) { + if (nextSibling.textContent === Constants.ZWSP) { + range.setStart(nextSibling, 1); + range.collapse(false); + break; + } else { + nextSibling = nextSibling.nextSibling; + } + } + } + range.insertNode(document.createElement("wbr")); + const listItemHTML = listItemElement.outerHTML; + const html = listItemElement.parentElement.outerHTML; + if (range.toString() !== "") { + range.extractContents(); + range.insertNode(document.createElement("wbr")); + } + range.setEndAfter(editableElement.lastChild); + newElement = genListItemElement(listItemElement, 0, false); + const selectNode = range.extractContents(); + if (selectNode.firstChild.nodeType !== 3 && selectNode.firstChild.textContent === "") { + // 回车移除空元素 https://github.com/siyuan-note/insider/issues/480 + selectNode.firstChild.after(document.createElement("wbr")); + selectNode.firstChild.remove(); + } + // https://github.com/siyuan-note/siyuan/issues/3850 + // https://github.com/siyuan-note/siyuan/issues/6018 + if ((editableElement?.lastElementChild?.getAttribute("data-type") || "").indexOf("inline-math") > -1 && + !hasNextSibling(editableElement?.lastElementChild)) { + editableElement.insertAdjacentText("beforeend", "\n"); + } + getContenteditableElement(newElement).appendChild(selectNode); + listItemElement.insertAdjacentElement("afterend", newElement); + if (listItemElement.getAttribute("data-subtype") === "o") { + updateListOrder(listItemElement.parentElement); + } + if (listItemElement.parentElement.classList.contains("protyle-wysiwyg")) { + transaction(protyle, [{ + action: "update", + id: listItemElement.getAttribute("data-node-id"), + data: listItemElement.outerHTML, + }, { + action: "insert", + id: newElement.getAttribute("data-node-id"), + data: newElement.outerHTML, + previousID: listItemElement.getAttribute("data-node-id") + }], [{ + action: "delete", + id: newElement.getAttribute("data-node-id"), + }, { + action: "update", + id: listItemElement.getAttribute("data-node-id"), + data: listItemHTML + }]); + } else { + updateTransaction(protyle, listItemElement.parentElement.getAttribute("data-node-id"), listItemElement.parentElement.outerHTML, html); + } + focusByWbr(newElement, range); + scrollCenter(protyle); + removeEmptyNode(newElement); + return true; +}; + const removeEmptyNode = (newElement: Element) => { const children = getContenteditableElement(newElement).childNodes; for (let i = 0; i < children.length; i++) { diff --git a/app/src/protyle/wysiwyg/remove.ts b/app/src/protyle/wysiwyg/remove.ts index a556b57f4..001367a3c 100644 --- a/app/src/protyle/wysiwyg/remove.ts +++ b/app/src/protyle/wysiwyg/remove.ts @@ -23,169 +23,6 @@ import {Constants} from "../../constants"; import {scrollCenter} from "../../util/highlightById"; import {isMobile} from "../../util/functions"; -const removeLi = (protyle: IProtyle, blockElement: Element, range: Range, isDelete = false) => { - if (!blockElement.parentElement.previousElementSibling && blockElement.parentElement.nextElementSibling && blockElement.parentElement.nextElementSibling.classList.contains("protyle-attr")) { - listOutdent(protyle, [blockElement.parentElement], range, isDelete, blockElement); - return; - } - // 第一个子列表合并到上一个块的末尾 - if (!blockElement.parentElement.previousElementSibling && blockElement.parentElement.parentElement.parentElement.classList.contains("list")) { - range.insertNode(document.createElement("wbr")); - const listElement = blockElement.parentElement.parentElement; - const listHTML = listElement.outerHTML; - const previousLastElement = blockElement.parentElement.parentElement.previousElementSibling.lastElementChild; - const previousHTML = previousLastElement.parentElement.outerHTML; - blockElement.parentElement.firstElementChild.remove(); - blockElement.parentElement.lastElementChild.remove(); - previousLastElement.insertAdjacentHTML("beforebegin", blockElement.parentElement.innerHTML); - blockElement.parentElement.remove(); - if (listElement.getAttribute("data-subtype") === "o") { - updateListOrder(listElement); - } - transaction(protyle, [{ - action: "update", - id: listElement.getAttribute("data-node-id"), - data: listElement.outerHTML - }, { - action: "update", - data: previousLastElement.parentElement.outerHTML, - id: previousLastElement.parentElement.getAttribute("data-node-id"), - }], [{ - action: "update", - data: previousHTML, - id: previousLastElement.parentElement.getAttribute("data-node-id"), - }, { - action: "update", - data: listHTML, - id: listElement.getAttribute("data-node-id"), - }]); - focusByWbr(previousLastElement.parentElement, range); - return; - } - // 顶级列表首行删除变为块 - if (!blockElement.parentElement.previousElementSibling) { - if (blockElement.parentElement.parentElement.classList.contains("protyle-wysiwyg")) { - return; - } - moveToPrevious(blockElement, range, isDelete); - range.insertNode(document.createElement("wbr")); - const listElement = blockElement.parentElement.parentElement; - const listHTML = listElement.outerHTML; - blockElement.parentElement.firstElementChild.remove(); - blockElement.parentElement.lastElementChild.remove(); - const tempElement = document.createElement("div"); - tempElement.innerHTML = blockElement.parentElement.innerHTML; - const doOperations: IOperation[] = []; - const undoOperations: IOperation[] = []; - Array.from(tempElement.children).forEach((item, index) => { - doOperations.push({ - action: "insert", - id: item.getAttribute("data-node-id"), - data: item.outerHTML, - previousID: index === 0 ? listElement.previousElementSibling?.getAttribute("data-node-id") : doOperations[index - 1].id, - parentID: listElement.parentElement.getAttribute("data-node-id") || protyle.block.parentID - }); - undoOperations.push({ - action: "delete", - id: item.getAttribute("data-node-id"), - }); - }); - listElement.insertAdjacentHTML("beforebegin", blockElement.parentElement.innerHTML); - blockElement.parentElement.remove(); - if (listElement.getAttribute("data-subtype") === "o") { - updateListOrder(listElement, parseInt(listElement.firstElementChild.getAttribute("data-marker")) - 1); - } - doOperations.splice(0, 0, { - action: "update", - id: listElement.getAttribute("data-node-id"), - data: listElement.outerHTML - }); - undoOperations.push({ - action: "update", - data: listHTML, - id: listElement.getAttribute("data-node-id"), - }); - transaction(protyle, doOperations, undoOperations); - focusByWbr(protyle.wysiwyg.element, range); - return; - } - - // 列表项合并到前一个列表项的最后一个块末尾 - const listItemElement = blockElement.parentElement; - if (listItemElement.previousElementSibling && listItemElement.previousElementSibling.classList.contains("protyle-breadcrumb__bar")) { - return; - } - const listItemId = listItemElement.getAttribute("data-node-id"); - const listElement = listItemElement.parentElement; - moveToPrevious(blockElement, range, isDelete); - range.insertNode(document.createElement("wbr")); - const html = listElement.outerHTML; - const doOperations: IOperation[] = []; - const undoOperations: IOperation[] = [{ - action: "insert", - id: listItemId, - data: "", - previousID: listItemElement.previousElementSibling.getAttribute("data-node-id") - }]; - const previousLastElement = listItemElement.previousElementSibling.lastElementChild; - if (listItemElement.previousElementSibling.getAttribute("fold") === "1") { - if (getContenteditableElement(blockElement).textContent.trim() === "" && - blockElement.nextElementSibling.classList.contains("protyle-attr")) { - doOperations.push({ - action: "delete", - id: listItemId - }); - undoOperations[0].data = listItemElement.outerHTML; - setLastNodeRange(getContenteditableElement(listItemElement.previousElementSibling), range); - range.collapse(true); - listItemElement.remove(); - } else { - setLastNodeRange(getContenteditableElement(listItemElement.previousElementSibling), range); - range.collapse(true); - focusByRange(range); - blockElement.querySelector("wbr")?.remove(); - return; - } - } else { - let previousID = previousLastElement.previousElementSibling.getAttribute("data-node-id"); - Array.from(blockElement.parentElement.children).forEach((item, index) => { - if (item.classList.contains("protyle-action") || item.classList.contains("protyle-attr")) { - return; - } - const id = item.getAttribute("data-node-id"); - doOperations.push({ - action: "move", - id, - previousID, - }); - undoOperations.push({ - action: "move", - id, - previousID: index === 1 ? undefined : previousID, - parentID: listItemId - }); - previousID = id; - previousLastElement.before(item); - }); - doOperations.push({ - action: "delete", - id: listItemId - }); - undoOperations[0].data = listItemElement.outerHTML; - listItemElement.remove(); - } - - if (listElement.classList.contains("protyle-wysiwyg")) { - transaction(protyle, doOperations, undoOperations); - } else { - if (listElement.getAttribute("data-subtype") === "o") { - updateListOrder(listElement); - } - updateTransaction(protyle, listElement.getAttribute("data-node-id"), listElement.outerHTML, html); - } - focusByWbr(previousLastElement.parentElement, range); -}; - export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Range, type: "Delete" | "Backspace" | "remove") => { // 删除后,防止滚动条滚动后调用 get 请求,因为返回的请求已查找不到内容块了 preventScroll(protyle); @@ -580,3 +417,166 @@ export const removeImage = (imgSelectElement: Element, nodeElement: HTMLElement, updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, oldHTML); focusByWbr(nodeElement, range); }; + +const removeLi = (protyle: IProtyle, blockElement: Element, range: Range, isDelete = false) => { + if (!blockElement.parentElement.previousElementSibling && blockElement.parentElement.nextElementSibling && blockElement.parentElement.nextElementSibling.classList.contains("protyle-attr")) { + listOutdent(protyle, [blockElement.parentElement], range, isDelete, blockElement); + return; + } + // 第一个子列表合并到上一个块的末尾 + if (!blockElement.parentElement.previousElementSibling && blockElement.parentElement.parentElement.parentElement.classList.contains("list")) { + range.insertNode(document.createElement("wbr")); + const listElement = blockElement.parentElement.parentElement; + const listHTML = listElement.outerHTML; + const previousLastElement = blockElement.parentElement.parentElement.previousElementSibling.lastElementChild; + const previousHTML = previousLastElement.parentElement.outerHTML; + blockElement.parentElement.firstElementChild.remove(); + blockElement.parentElement.lastElementChild.remove(); + previousLastElement.insertAdjacentHTML("beforebegin", blockElement.parentElement.innerHTML); + blockElement.parentElement.remove(); + if (listElement.getAttribute("data-subtype") === "o") { + updateListOrder(listElement); + } + transaction(protyle, [{ + action: "update", + id: listElement.getAttribute("data-node-id"), + data: listElement.outerHTML + }, { + action: "update", + data: previousLastElement.parentElement.outerHTML, + id: previousLastElement.parentElement.getAttribute("data-node-id"), + }], [{ + action: "update", + data: previousHTML, + id: previousLastElement.parentElement.getAttribute("data-node-id"), + }, { + action: "update", + data: listHTML, + id: listElement.getAttribute("data-node-id"), + }]); + focusByWbr(previousLastElement.parentElement, range); + return; + } + // 顶级列表首行删除变为块 + if (!blockElement.parentElement.previousElementSibling) { + if (blockElement.parentElement.parentElement.classList.contains("protyle-wysiwyg")) { + return; + } + moveToPrevious(blockElement, range, isDelete); + range.insertNode(document.createElement("wbr")); + const listElement = blockElement.parentElement.parentElement; + const listHTML = listElement.outerHTML; + blockElement.parentElement.firstElementChild.remove(); + blockElement.parentElement.lastElementChild.remove(); + const tempElement = document.createElement("div"); + tempElement.innerHTML = blockElement.parentElement.innerHTML; + const doOperations: IOperation[] = []; + const undoOperations: IOperation[] = []; + Array.from(tempElement.children).forEach((item, index) => { + doOperations.push({ + action: "insert", + id: item.getAttribute("data-node-id"), + data: item.outerHTML, + previousID: index === 0 ? listElement.previousElementSibling?.getAttribute("data-node-id") : doOperations[index - 1].id, + parentID: listElement.parentElement.getAttribute("data-node-id") || protyle.block.parentID + }); + undoOperations.push({ + action: "delete", + id: item.getAttribute("data-node-id"), + }); + }); + listElement.insertAdjacentHTML("beforebegin", blockElement.parentElement.innerHTML); + blockElement.parentElement.remove(); + if (listElement.getAttribute("data-subtype") === "o") { + updateListOrder(listElement, parseInt(listElement.firstElementChild.getAttribute("data-marker")) - 1); + } + doOperations.splice(0, 0, { + action: "update", + id: listElement.getAttribute("data-node-id"), + data: listElement.outerHTML + }); + undoOperations.push({ + action: "update", + data: listHTML, + id: listElement.getAttribute("data-node-id"), + }); + transaction(protyle, doOperations, undoOperations); + focusByWbr(protyle.wysiwyg.element, range); + return; + } + + // 列表项合并到前一个列表项的最后一个块末尾 + const listItemElement = blockElement.parentElement; + if (listItemElement.previousElementSibling && listItemElement.previousElementSibling.classList.contains("protyle-breadcrumb__bar")) { + return; + } + const listItemId = listItemElement.getAttribute("data-node-id"); + const listElement = listItemElement.parentElement; + moveToPrevious(blockElement, range, isDelete); + range.insertNode(document.createElement("wbr")); + const html = listElement.outerHTML; + const doOperations: IOperation[] = []; + const undoOperations: IOperation[] = [{ + action: "insert", + id: listItemId, + data: "", + previousID: listItemElement.previousElementSibling.getAttribute("data-node-id") + }]; + const previousLastElement = listItemElement.previousElementSibling.lastElementChild; + if (listItemElement.previousElementSibling.getAttribute("fold") === "1") { + if (getContenteditableElement(blockElement).textContent.trim() === "" && + blockElement.nextElementSibling.classList.contains("protyle-attr")) { + doOperations.push({ + action: "delete", + id: listItemId + }); + undoOperations[0].data = listItemElement.outerHTML; + setLastNodeRange(getContenteditableElement(listItemElement.previousElementSibling), range); + range.collapse(true); + listItemElement.remove(); + } else { + setLastNodeRange(getContenteditableElement(listItemElement.previousElementSibling), range); + range.collapse(true); + focusByRange(range); + blockElement.querySelector("wbr")?.remove(); + return; + } + } else { + let previousID = previousLastElement.previousElementSibling.getAttribute("data-node-id"); + Array.from(blockElement.parentElement.children).forEach((item, index) => { + if (item.classList.contains("protyle-action") || item.classList.contains("protyle-attr")) { + return; + } + const id = item.getAttribute("data-node-id"); + doOperations.push({ + action: "move", + id, + previousID, + }); + undoOperations.push({ + action: "move", + id, + previousID: index === 1 ? undefined : previousID, + parentID: listItemId + }); + previousID = id; + previousLastElement.before(item); + }); + doOperations.push({ + action: "delete", + id: listItemId + }); + undoOperations[0].data = listItemElement.outerHTML; + listItemElement.remove(); + } + + if (listElement.classList.contains("protyle-wysiwyg")) { + transaction(protyle, doOperations, undoOperations); + } else { + if (listElement.getAttribute("data-subtype") === "o") { + updateListOrder(listElement); + } + updateTransaction(protyle, listElement.getAttribute("data-node-id"), listElement.outerHTML, html); + } + focusByWbr(previousLastElement.parentElement, range); +};