From fa1f7868336236fe19fe9609322af149160d28b1 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Wed, 6 Dec 2023 12:30:38 +0800 Subject: [PATCH] :bug: fix https://github.com/siyuan-note/siyuan/issues/9822 --- app/src/mobile/util/keyboardToolbar.ts | 8 +-- app/src/protyle/wysiwyg/enter.ts | 70 +++++++++++++++++++++++- app/src/protyle/wysiwyg/input.ts | 4 +- app/src/protyle/wysiwyg/keydown.ts | 73 ++------------------------ 4 files changed, 79 insertions(+), 76 deletions(-) diff --git a/app/src/mobile/util/keyboardToolbar.ts b/app/src/mobile/util/keyboardToolbar.ts index e9298706f..74fdcbab4 100644 --- a/app/src/mobile/util/keyboardToolbar.ts +++ b/app/src/mobile/util/keyboardToolbar.ts @@ -11,7 +11,7 @@ import {focusByRange, getSelectionPosition} from "../../protyle/util/selection"; import {getCurrentEditor} from "../editor"; import {fontEvent, getFontNodeElements} from "../../protyle/toolbar/Font"; import {hideElements} from "../../protyle/ui/hideElements"; -import {input} from "../../protyle/wysiwyg/input"; +import {softEnter} from "../../protyle/wysiwyg/enter"; let renderKeyboardToolbarTimeout: number; let showUtil = false; @@ -634,9 +634,9 @@ export const initKeyboardToolbar = () => { focusByRange(range); return; } else if (type === "softLine") { - range.insertNode(document.createTextNode("\n")); - range.collapse(false); - input(protyle, nodeElement, range); + range.extractContents(); + softEnter(range, nodeElement, protyle); + focusByRange(range); return; } else if (type === "add") { if (buttonElement.classList.contains("protyle-toolbar__item--current")) { diff --git a/app/src/protyle/wysiwyg/enter.ts b/app/src/protyle/wysiwyg/enter.ts index 74c2103fe..6ffd8f578 100644 --- a/app/src/protyle/wysiwyg/enter.ts +++ b/app/src/protyle/wysiwyg/enter.ts @@ -1,5 +1,5 @@ import {genEmptyElement, insertEmptyBlock} from "../../block/util"; -import {getSelectionOffset, focusByWbr, setLastNodeRange, focusBlock} from "../util/selection"; +import {getSelectionOffset, focusByWbr, setLastNodeRange, focusBlock, focusByRange} from "../util/selection"; import { getContenteditableElement, getTopEmptyElement, @@ -13,8 +13,9 @@ import {highlightRender} from "../render/highlightRender"; import {Constants} from "../../constants"; import {scrollCenter} from "../../util/highlightById"; import {hideElements} from "../ui/hideElements"; -import {setStorageVal} from "../util/compatibility"; +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; @@ -418,3 +419,68 @@ const removeEmptyNode = (newElement: Element) => { } } }; + +export const softEnter = (range: Range, nodeElement: HTMLElement, protyle: IProtyle) => { + let startElement = range.startContainer as HTMLElement; + const nextSibling = hasNextSibling(startElement) as Element; + // 图片之前软换行 + if (nextSibling && nextSibling.nodeType !== 3 && nextSibling.classList.contains("img")) { + nextSibling.insertAdjacentHTML("beforebegin", ""); + const oldHTML = nodeElement.outerHTML; + nextSibling.previousElementSibling.remove(); + const newlineNode = document.createTextNode("\n"); + startElement.after(document.createTextNode(Constants.ZWSP)); + startElement.after(newlineNode); + range.selectNode(newlineNode); + range.collapse(false); + updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, oldHTML); + return true; + } + // 行内元素末尾软换行 https://github.com/siyuan-note/insider/issues/886 + if (startElement.nodeType === 3) { + startElement = startElement.parentElement; + } + if (startElement && protyle.toolbar.getCurrentType(range).length > 0 && + getSelectionOffset(startElement, startElement, range).end === startElement.textContent.length) { + addNewLineToEnd(range, nodeElement, protyle, startElement); + return true; + } + if (isIPad() || isMobile()) { + // iPad shift+enter 无效 + startElement = range.startContainer as HTMLElement; + const nextSibling = hasNextSibling(startElement); + if (nextSibling && nextSibling.textContent.trim() !== "") { + document.execCommand("insertHTML", false, "\n"); + return true; + } + addNewLineToEnd(range, nodeElement, protyle, startElement); + return true; + } + return false +} + +const addNewLineToEnd = (range: Range, nodeElement: HTMLElement, protyle: IProtyle, startElement: Element) => { + const wbrElement = document.createElement("wbr"); + if (startElement.nodeType === 3) { + range.insertNode(wbrElement); + } else { + startElement.insertAdjacentElement("afterend", wbrElement); + } + const oldHTML = nodeElement.outerHTML; + wbrElement.remove(); + let endNewlineNode + if (!hasNextSibling(startElement)) { + endNewlineNode = document.createTextNode("\n"); + startElement.after(endNewlineNode); + } + const newlineNode = document.createTextNode("\n"); + startElement.after(newlineNode); + if (endNewlineNode) { + range.setStart(endNewlineNode, 0); + } else { + range.setStart(newlineNode, 1); + } + range.collapse(true); + focusByRange(range); + updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, oldHTML); +} diff --git a/app/src/protyle/wysiwyg/input.ts b/app/src/protyle/wysiwyg/input.ts index 9f11857ea..913fa22eb 100644 --- a/app/src/protyle/wysiwyg/input.ts +++ b/app/src/protyle/wysiwyg/input.ts @@ -45,12 +45,13 @@ export const input = async (protyle: IProtyle, blockElement: HTMLElement, range: focusByWbr(blockElement, range); return; } + blockElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); const wbrElement = document.createElement("wbr"); range.insertNode(wbrElement); const id = blockElement.getAttribute("data-node-id"); if (type !== "NodeCodeBlock" && (editElement.innerHTML.endsWith("\n") || editElement.innerHTML.endsWith("\n\n"))) { // 软换行 - updateTransaction(protyle, id, blockElement.outerHTML, blockElement.outerHTML.replace("\n", "")); + updateTransaction(protyle, id, blockElement.outerHTML, protyle.wysiwyg.lastHTMLs[id] || blockElement.outerHTML.replace("\n", "")); wbrElement.remove(); return; } @@ -69,7 +70,6 @@ export const input = async (protyle: IProtyle, blockElement: HTMLElement, range: brElement.remove(); } - blockElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); if (editElement.innerHTML === "》" || editElement.innerHTML.indexOf("\n》") > -1) { editElement.innerHTML = editElement.innerHTML.replace("》", ">"); } diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index 5cded9039..bc173b36a 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -22,12 +22,11 @@ import { getNextBlock, getPreviousBlock, getTopAloneElement, - hasNextSibling, hasPreviousSibling, isNotEditBlock, } from "./getBlock"; import {matchHotKey} from "../util/hotKey"; -import {enter} from "./enter"; +import {enter, softEnter} from "./enter"; import {fixTable} from "../util/table"; import { turnsIntoOneTransaction, turnsIntoTransaction, @@ -866,72 +865,10 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { } // 软换行 - if (matchHotKey("⇧↩", event) && selectText === "") { - let startElement = range.startContainer as HTMLElement; - const nextSibling = hasNextSibling(startElement) as Element; - // 图片之前软换行 - if (nextSibling && nextSibling.nodeType !== 3 && nextSibling.classList.contains("img")) { - nextSibling.insertAdjacentHTML("beforebegin", ""); - const oldHTML = nodeElement.outerHTML; - nextSibling.previousElementSibling.remove(); - const newlineNode = document.createTextNode("\n"); - startElement.after(document.createTextNode(Constants.ZWSP)); - startElement.after(newlineNode); - range.selectNode(newlineNode); - range.collapse(false); - updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, oldHTML); - event.stopPropagation(); - event.preventDefault(); - return; - } - // 行内元素软换行 https://github.com/siyuan-note/insider/issues/886 - if (startElement.nodeType === 3) { - startElement = startElement.parentElement; - } - if (startElement && protyle.toolbar.getCurrentType(range).length > 0 && - getSelectionOffset(startElement, startElement, range).end === startElement.textContent.length) { - startElement.insertAdjacentHTML("afterend", ""); - const oldHTML = nodeElement.outerHTML; - startElement.nextElementSibling.remove(); - if (!hasNextSibling(startElement)) { - startElement.after(document.createTextNode("\n")); - } - const newlineNode = document.createTextNode("\n"); - startElement.after(newlineNode); - range.selectNode(newlineNode); - range.collapse(false); - updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, oldHTML); - event.stopPropagation(); - event.preventDefault(); - return; - } - if (window.siyuan.config.system.container === "ios") { - // iPad shift+enter 无效 - startElement = range.startContainer as HTMLElement; - const nextSibling = hasNextSibling(startElement); - if (nextSibling && nextSibling.textContent.trim() !== "") { - document.execCommand("insertHTML", false, "\n"); - event.stopPropagation(); - event.preventDefault(); - return; - } - if (!nextSibling) { - startElement.after(document.createTextNode("\n")); - } - const newlineNode = document.createTextNode("\n"); - startElement.after(newlineNode); - const newlineNextSibling = hasNextSibling(newlineNode); - if (newlineNextSibling && newlineNextSibling.textContent === "\n") { - range.setStart(newlineNextSibling, 0); - } else { - range.setStart(newlineNode, 0); - } - range.collapse(false); - focusByRange(range); - event.stopPropagation(); - event.preventDefault(); - return; - } + if (matchHotKey("⇧↩", event) && selectText === "" && softEnter(range, nodeElement, protyle)) { + event.stopPropagation(); + event.preventDefault(); + return; } // 回车