This commit is contained in:
Vanessa 2022-11-09 14:25:02 +08:00
parent 3f00813034
commit 4bd2760b2b
4 changed files with 97 additions and 57 deletions

View file

@ -200,6 +200,7 @@ export const initFileMenu = (notebookId: string, pathString: string, liElement:
icon: "iconCopy",
submenu: (copySubMenu(id, false) as IMenu[]).concat([{
label: window.siyuan.languages.duplicate,
accelerator: window.siyuan.config.keymap.editor.general.duplicate.custom,
click() {
fetchPost("/api/filetree/duplicateDoc", {
id

View file

@ -21,7 +21,6 @@ import {getContenteditableElement, getTopAloneElement, isNotEditBlock} from "../
import * as dayjs from "dayjs";
import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {cancelSB, insertEmptyBlock, jumpToParentNext} from "../../block/util";
import {scrollCenter} from "../../util/highlightById";
import {countBlockWord} from "../../layout/status";
/// #if !MOBILE
import {openFileById} from "../../editor/util";
@ -29,6 +28,7 @@ import {openFileById} from "../../editor/util";
import {Constants} from "../../constants";
import {openMobileFileById} from "../../mobile/editor";
import {mathRender} from "../markdown/mathRender";
import {duplicateBlock} from "../wysiwyg/commonHotkey";
export class Gutter {
public element: HTMLElement;
@ -543,6 +543,9 @@ export class Gutter {
window.siyuan.menus.menu.append(new MenuItem({
label: window.siyuan.languages.copy,
icon: "iconCopy",
type: "submenu",
submenu: [{
label: window.siyuan.languages.copy,
accelerator: "⌘C",
click() {
if (isNotEditBlock(selectsElement[0])) {
@ -556,8 +559,7 @@ export class Gutter {
document.execCommand("copy");
}
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
}, {
label: window.siyuan.languages.copyPlainText,
accelerator: window.siyuan.config.keymap.editor.general.copyPlainText.custom,
click() {
@ -573,8 +575,7 @@ export class Gutter {
});
writeText(html.trimEnd());
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
}, {
label: window.siyuan.languages.copy + " HTML",
click() {
let html = "";
@ -583,6 +584,14 @@ export class Gutter {
});
writeText(protyle.lute.BlockDOM2HTML(html));
}
}, {
label: window.siyuan.languages.duplicate,
accelerator: window.siyuan.config.keymap.editor.general.duplicate.custom,
disabled: protyle.disabled,
click() {
duplicateBlock(selectsElement, protyle);
}
}]
}).element);
if (protyle.disabled) {
return;
@ -948,26 +957,10 @@ export class Gutter {
}
}, {
label: window.siyuan.languages.duplicate,
accelerator: window.siyuan.config.keymap.editor.general.duplicate.custom,
disabled: protyle.disabled,
click() {
const tempElement = nodeElement.cloneNode(true) as HTMLElement;
const newId = Lute.NewNodeID();
tempElement.setAttribute("data-node-id", newId);
tempElement.querySelectorAll("[data-node-id]").forEach(item => {
item.setAttribute("data-node-id", Lute.NewNodeID());
});
nodeElement.after(tempElement);
scrollCenter(protyle);
transaction(protyle, [{
action: "insert",
data: nodeElement.nextElementSibling.outerHTML,
id: newId,
previousID: id,
}], [{
action: "delete",
id: newId,
}]);
focusBlock(tempElement);
duplicateBlock([nodeElement], protyle);
}
}])
}).element);

View file

@ -2,6 +2,7 @@ import {matchHotKey} from "../util/hotKey";
import {fetchPost} from "../../util/fetch";
import {writeText} from "../util/compatibility";
import {
focusBlock,
focusByOffset,
getSelectionOffset,
setFirstNodeRange,
@ -16,6 +17,8 @@ import {getContenteditableElement} from "./getBlock";
import {hasClosestByMatchTag} from "../util/hasClosest";
import {hideElements} from "../ui/hideElements";
import {countBlockWord} from "../../layout/status";
import {scrollCenter} from "../../util/highlightById";
import {transaction} from "./transaction";
export const commonHotkey = (protyle: IProtyle, event: KeyboardEvent) => {
const target = event.target as HTMLElement;
@ -180,3 +183,35 @@ export const getStartEndElement = (selectElements: NodeListOf<Element> | Element
endElement
};
};
export const duplicateBlock = (nodeElements: Element[], protyle: IProtyle) => {
let focusElement
const doOperations: IOperation[] = []
const undoOperations: IOperation[] = []
nodeElements.forEach((item, index) => {
const tempElement = item.cloneNode(true) as HTMLElement;
if (index === nodeElements.length - 1) {
focusElement = tempElement
}
const newId = Lute.NewNodeID();
tempElement.setAttribute("data-node-id", newId);
tempElement.querySelectorAll("[data-node-id]").forEach(childItem => {
childItem.setAttribute("data-node-id", Lute.NewNodeID());
});
item.classList.remove("protyle-wysiwyg--select");
item.after(tempElement);
doOperations.push({
action: "insert",
data: tempElement.outerHTML,
id: newId,
previousID: item.getAttribute("data-node-id"),
})
undoOperations.push({
action: "delete",
id: newId,
})
})
transaction(protyle, doOperations, undoOperations);
focusBlock(focusElement);
scrollCenter(protyle);
}

View file

@ -42,7 +42,7 @@ import {isLocalPath} from "../../util/pathName";
/// #if !MOBILE
import {openBy, openFileById} from "../../editor/util";
/// #endif
import {commonHotkey, downSelect, getStartEndElement, upSelect} from "./commonHotkey";
import {commonHotkey, downSelect, duplicateBlock, getStartEndElement, upSelect} from "./commonHotkey";
import {linkMenu, refMenu, setFold, zoomOut} from "../../menus/protyle";
import {removeEmbed} from "./removeEmbed";
import {openAttr} from "../../menus/commonMenuItem";
@ -1446,6 +1446,17 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
return;
}
if (matchHotKey(window.siyuan.config.keymap.editor.general.duplicate.custom, event)) {
event.preventDefault();
event.stopPropagation();
let selectsElement: HTMLElement[] = Array.from(protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select"));
if (selectsElement.length === 0) {
selectsElement = [nodeElement];
}
duplicateBlock(selectsElement, protyle);
return;
}
// tab 需等待 list 和 table 处理完成
if (event.key === "Tab" && !event.ctrlKey && !isCtrl(event) && !event.altKey) {
event.preventDefault();