diff --git a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20200924100950-9op5xi1.sy b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20200924100950-9op5xi1.sy index d009dfd18..494487cb3 100644 --- a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20200924100950-9op5xi1.sy +++ b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20200924100950-9op5xi1.sy @@ -7,7 +7,7 @@ "id": "20200924100950-9op5xi1", "title": "Shortcuts", "type": "doc", - "updated": "20221109143648" + "updated": "20221123220150" }, "Children": [ { @@ -7603,7 +7603,7 @@ "Properties": { "colgroup": "|", "id": "20210601185420-1s8e9uy", - "updated": "20221105230819" + "updated": "20221123220150" }, "Children": [ { @@ -7642,41 +7642,6 @@ } ] }, - { - "Type": "NodeTableRow", - "Data": "tr", - "Children": [ - { - "Type": "NodeTableCell", - "Data": "td", - "Children": [ - { - "Type": "NodeText", - "Data": "Move" - } - ] - }, - { - "Type": "NodeTableCell", - "Data": "td", - "Children": [ - { - "Type": "NodeText", - "Data": "​" - }, - { - "Type": "NodeTextMark", - "TextMarkType": "kbd", - "TextMarkTextContent": "Drag" - }, - { - "Type": "NodeText", - "Data": "​" - } - ] - } - ] - }, { "Type": "NodeTableRow", "Data": "tr", @@ -7847,6 +7812,173 @@ ] } ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "Move" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "Drag" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "Copy and move" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "Ctrl+Drag" + }, + { + "Type": "NodeText", + "Data": "​ / " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "⌃+Drag" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "Generate block ref" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "Alt+Drag" + }, + { + "Type": "NodeText", + "Data": "​ / " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "⌥+Drag" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "Generate embed block" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "Shift+Drag" + }, + { + "Type": "NodeText", + "Data": "​ / " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "⇧+Drag" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] } ] }, diff --git a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20200813004551-gm0pbn1.sy b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20200813004551-gm0pbn1.sy index 2dc7778e8..97cabd428 100644 --- a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20200813004551-gm0pbn1.sy +++ b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20200813004551-gm0pbn1.sy @@ -7,7 +7,7 @@ "id": "20200813004551-gm0pbn1", "title": "快捷键", "type": "doc", - "updated": "20221109143355" + "updated": "20221123214805" }, "Children": [ { @@ -7572,7 +7572,7 @@ "Properties": { "colgroup": "|", "id": "20210526200223-xyuqsge", - "updated": "20221105230414" + "updated": "20221123214805" }, "Children": [ { @@ -7607,41 +7607,6 @@ } ] }, - { - "Type": "NodeTableRow", - "Data": "tr", - "Children": [ - { - "Type": "NodeTableCell", - "Data": "td", - "Children": [ - { - "Type": "NodeText", - "Data": "移动" - } - ] - }, - { - "Type": "NodeTableCell", - "Data": "td", - "Children": [ - { - "Type": "NodeText", - "Data": "​" - }, - { - "Type": "NodeTextMark", - "TextMarkType": "kbd", - "TextMarkTextContent": "拖拽" - }, - { - "Type": "NodeText", - "Data": "​" - } - ] - } - ] - }, { "Type": "NodeTableRow", "Data": "tr", @@ -7671,7 +7636,7 @@ }, { "Type": "NodeText", - "Data": "​" + "Data": "​​" } ] } @@ -7706,7 +7671,7 @@ }, { "Type": "NodeText", - "Data": "​ / " + "Data": "​​ / " }, { "Type": "NodeTextMark", @@ -7715,7 +7680,7 @@ }, { "Type": "NodeText", - "Data": "​" + "Data": "​​" } ] } @@ -7750,7 +7715,7 @@ }, { "Type": "NodeText", - "Data": "​ / " + "Data": "​​ / " }, { "Type": "NodeTextMark", @@ -7759,7 +7724,7 @@ }, { "Type": "NodeText", - "Data": "​" + "Data": "​​" } ] } @@ -7794,16 +7759,187 @@ }, { "Type": "NodeText", - "Data": "​ / " + "Data": "​​ / " }, { "Type": "NodeTextMark", "TextMarkType": "kbd", "TextMarkTextContent": "⇧Click" }, + { + "Type": "NodeText", + "Data": "​​" + } + ] + } + ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "移动" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ { "Type": "NodeText", "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "拖拽" + }, + { + "Type": "NodeText", + "Data": "​​" + } + ] + } + ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "复制并移动" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "Ctrl+拖拽" + }, + { + "Type": "NodeText", + "Data": "​​ / " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "⌃+拖拽" + }, + { + "Type": "NodeText", + "Data": "​​" + } + ] + } + ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "生成块" + }, + { + "Type": "NodeText", + "Data": "引用" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "Alt+拖拽" + }, + { + "Type": "NodeText", + "Data": "​​ / " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "⌥+拖拽" + }, + { + "Type": "NodeText", + "Data": "​​" + } + ] + } + ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "生成嵌入块" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "Shift+拖拽" + }, + { + "Type": "NodeText", + "Data": "​​ / " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "⇧+拖拽" + }, + { + "Type": "NodeText", + "Data": "​​" } ] } diff --git a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20211226122549-jktxego.sy b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20211226122549-jktxego.sy index 785d12a32..778c0ebd5 100644 --- a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20211226122549-jktxego.sy +++ b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20211226122549-jktxego.sy @@ -6,7 +6,7 @@ "icon": "2328", "id": "20211226122549-jktxego", "title": "快捷鍵", - "updated": "20221109143714" + "updated": "20221123220121" }, "Children": [ { @@ -7604,7 +7604,7 @@ "Properties": { "colgroup": "|", "id": "20211226122652-ykdt6pc", - "updated": "20221105230731" + "updated": "20221123220121" }, "Children": [ { @@ -7639,41 +7639,6 @@ } ] }, - { - "Type": "NodeTableRow", - "Data": "tr", - "Children": [ - { - "Type": "NodeTableCell", - "Data": "td", - "Children": [ - { - "Type": "NodeText", - "Data": "移動" - } - ] - }, - { - "Type": "NodeTableCell", - "Data": "td", - "Children": [ - { - "Type": "NodeText", - "Data": "​" - }, - { - "Type": "NodeTextMark", - "TextMarkType": "kbd", - "TextMarkTextContent": "拖拽" - }, - { - "Type": "NodeText", - "Data": "​" - } - ] - } - ] - }, { "Type": "NodeTableRow", "Data": "tr", @@ -7844,6 +7809,173 @@ ] } ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "移動" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "拖拽" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "複製並移動" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "Ctrl+拖拽" + }, + { + "Type": "NodeText", + "Data": "​ / " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "⌃+拖拽" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "生成塊引用" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "Alt+拖拽" + }, + { + "Type": "NodeText", + "Data": "​ / " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "⌥+拖拽" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "Type": "NodeTableRow", + "Data": "tr", + "Children": [ + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "生成嵌入塊" + } + ] + }, + { + "Type": "NodeTableCell", + "Data": "td", + "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "Shift+拖拽" + }, + { + "Type": "NodeText", + "Data": "​ / " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "kbd", + "TextMarkTextContent": "⇧+拖拽" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] } ] }, diff --git a/app/src/protyle/util/editorCommonEvent.ts b/app/src/protyle/util/editorCommonEvent.ts index 1bdb88225..8cdd2b285 100644 --- a/app/src/protyle/util/editorCommonEvent.ts +++ b/app/src/protyle/util/editorCommonEvent.ts @@ -20,7 +20,8 @@ import {insertHTML} from "./insertHTML"; import {isBrowser} from "../../util/functions"; import {hideElements} from "../ui/hideElements"; -const moveTo = async (protyle: IProtyle, sourceElements: Element[], targetElement: Element, isSameDoc: boolean, position: InsertPosition) => { +const moveTo = async (protyle: IProtyle, sourceElements: Element[], targetElement: Element, + isSameDoc: boolean, position: InsertPosition, isCopy: boolean) => { let topSourceElement; const doOperations: IOperation[] = []; const undoOperations: IOperation[] = []; @@ -43,28 +44,57 @@ const moveTo = async (protyle: IProtyle, sourceElements: Element[], targetElemen item.removeAttribute("fold"); foldHeadingIds.push({id, parentID}); } - undoOperations.push({ - action: "move", - id, - previousID: item.previousElementSibling?.getAttribute("data-node-id"), - parentID, - }); - if (!isSameDoc) { + let copyId + let copyElement + if (isCopy) { + copyId = Lute.NewNodeID(); + undoOperations.push({ + action: "delete", + id: copyId, + }); + } else { + undoOperations.push({ + action: "move", + id, + previousID: item.previousElementSibling?.getAttribute("data-node-id"), + parentID, + }); + } + if (!isSameDoc && !isCopy) { // 打开两个相同的文档 const sameElement = protyle.wysiwyg.element.querySelector(`[data-node-id="${id}"]`); if (sameElement) { sameElement.remove(); } } - tempTargetElement.insertAdjacentElement(position, item); - doOperations.push({ - action: "move", - id, - previousID: position === "afterend" ? targetId : item.previousElementSibling?.getAttribute("data-node-id"), // 不能使用常量,移动后会被修改 - parentID: item.parentElement?.getAttribute("data-node-id") || protyle.block.parentID || protyle.block.rootID, - }); + + if (isCopy) { + copyElement = item.cloneNode(true) as HTMLElement; + copyElement.setAttribute("data-node-id", copyId); + copyElement.querySelectorAll("[data-node-id]").forEach((e) => { + const newId = Lute.NewNodeID(); + e.setAttribute("data-node-id", newId); + e.setAttribute("updated", newId.split("-")[0]); + }); + tempTargetElement.insertAdjacentElement(position, copyElement); + doOperations.push({ + action: "insert", + id: copyId, + data: copyElement.outerHTML, + previousID: position === "afterend" ? targetId : item.previousElementSibling?.getAttribute("data-node-id"), // 不能使用常量,移动后会被修改 + parentID: item.parentElement?.getAttribute("data-node-id") || protyle.block.parentID || protyle.block.rootID, + }); + } else { + tempTargetElement.insertAdjacentElement(position, item); + doOperations.push({ + action: "move", + id, + previousID: position === "afterend" ? targetId : item.previousElementSibling?.getAttribute("data-node-id"), // 不能使用常量,移动后会被修改 + parentID: item.parentElement?.getAttribute("data-node-id") || protyle.block.parentID || protyle.block.rootID, + }); + } if (position !== "afterend") { - tempTargetElement = item; + tempTargetElement = isCopy ? copyElement : item; } }); undoOperations.reverse(); @@ -353,7 +383,7 @@ const dragSb = async (protyle: IProtyle, sourceElements: Element[], targetElemen focusBlock(sourceElements[0]); }; -const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElement: Element, isBottom: boolean) => { +const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElement: Element, isBottom: boolean, isCopy: boolean) => { const isSameDoc = protyle.element.contains(sourceElements[0]); const doOperations: IOperation[] = []; const undoOperations: IOperation[] = []; @@ -425,7 +455,7 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem id: newSourceElement.getAttribute("data-node-id"), }); } else { - const moveToResult = await moveTo(protyle, sourceElements, targetElement, isSameDoc, "afterend"); + const moveToResult = await moveTo(protyle, sourceElements, targetElement, isSameDoc, "afterend", isCopy); doOperations.push(...moveToResult.doOperations); undoOperations.push(...moveToResult.undoOperations); topSourceElement = moveToResult.topSourceElement; @@ -485,7 +515,7 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem id: newSourceElement.getAttribute("data-node-id"), }); } else { - const moveToResult = await moveTo(protyle, sourceElements, targetElement, isSameDoc, "beforebegin"); + const moveToResult = await moveTo(protyle, sourceElements, targetElement, isSameDoc, "beforebegin", isCopy); doOperations.push(...moveToResult.doOperations); undoOperations.push(...moveToResult.undoOperations); topSourceElement = moveToResult.topSourceElement; @@ -515,7 +545,8 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem }); }); } - if (oldSourceParentElement && oldSourceParentElement.classList.contains("list") && + if (!isCopy && + oldSourceParentElement && oldSourceParentElement.classList.contains("list") && oldSourceParentElement.getAttribute("data-subtype") === "o" && !oldSourceParentElement.isSameNode(sourceElements[0].parentElement) && oldSourceParentElement.childElementCount > 1) { Array.from(oldSourceParentElement.children).forEach((item) => { @@ -550,7 +581,7 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem } // 删除空元素 - if (topSourceElement) { + if (!isCopy && topSourceElement) { doOperations.push({ action: "delete", id: topSourceElement.getAttribute("data-node-id"), @@ -572,12 +603,12 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem } } } - if (oldSourceParentElement && oldSourceParentElement.classList.contains("sb") && oldSourceParentElement.childElementCount === 2) { + if (!isCopy && oldSourceParentElement && oldSourceParentElement.classList.contains("sb") && oldSourceParentElement.childElementCount === 2) { // 拖拽后,sb 只剩下一个元素 const sbData = cancelSB(protyle, oldSourceParentElement); doOperations.push(sbData.doOperations[0], sbData.doOperations[1]); undoOperations.splice(0, 0, sbData.undoOperations[0], sbData.undoOperations[1]); - } else if (oldSourceParentElement && oldSourceParentElement.classList.contains("protyle-wysiwyg") && oldSourceParentElement.childElementCount === 0) { + } else if (!isCopy && oldSourceParentElement && oldSourceParentElement.classList.contains("protyle-wysiwyg") && oldSourceParentElement.childElementCount === 0) { /// #if !MOBILE // 拖拽后,根文档原内容为空,且不为悬浮窗 const protyleElement = hasClosestByClassName(oldSourceParentElement, "protyle", true); @@ -599,7 +630,7 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem } /// #endif } - if (isSameDoc) { + if (isSameDoc || isCopy) { transaction(protyle, doOperations, undoOperations); } else { // 跨文档不支持撤销 @@ -686,7 +717,7 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => { if (targetElement.parentElement.getAttribute("data-type") === "NodeSuperBlock" && targetElement.parentElement.getAttribute("data-sb-layout") === "col") { if (targetClass.includes("dragover__left") || targetClass.includes("dragover__right")) { - dragSame(protyle, sourceElements, targetElement, targetClass.includes("dragover__right")); + dragSame(protyle, sourceElements, targetElement, targetClass.includes("dragover__right"), event.ctrlKey); } else { dragSb(protyle, sourceElements, targetElement, targetClass.includes("dragover__bottom"), "row"); } @@ -694,7 +725,7 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => { if (targetClass.includes("dragover__left") || targetClass.includes("dragover__right")) { dragSb(protyle, sourceElements, targetElement, targetClass.includes("dragover__right"), "col"); } else { - dragSame(protyle, sourceElements, targetElement, targetClass.includes("dragover__bottom")); + dragSame(protyle, sourceElements, targetElement, targetClass.includes("dragover__bottom"), event.ctrlKey); } } } diff --git a/app/src/protyle/util/paste.ts b/app/src/protyle/util/paste.ts index 0a941b27d..09397e3be 100644 --- a/app/src/protyle/util/paste.ts +++ b/app/src/protyle/util/paste.ts @@ -227,9 +227,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven const newId = Lute.NewNodeID(); e.setAttribute("data-node-id", newId); e.classList.remove("protyle-wysiwyg--select", "protyle-wysiwyg--hl"); - if (e.getAttribute("updated")) { - e.setAttribute("updated", newId.split("-")[0]); - } + e.setAttribute("updated", newId.split("-")[0]); isBlock = true; }); if (nodeElement.classList.contains("table")) {