From 807aabfe7ae727cc0bc1ae1b6393ce9d1fa76b27 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sat, 4 Feb 2023 15:40:54 +0800 Subject: [PATCH] :art: fix https://github.com/siyuan-note/siyuan/issues/6115 --- app/src/protyle/gutter/index.ts | 171 ++++++++++++++++++------------- app/src/protyle/wysiwyg/index.ts | 27 ++++- 2 files changed, 122 insertions(+), 76 deletions(-) diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index cbfa7a966..3accf4cde 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -566,49 +566,54 @@ export class Gutter { }).element); } } + const copyMenu: IMenu[] = [{ + label: window.siyuan.languages.copy, + accelerator: "⌘C", + click() { + if (isNotEditBlock(selectsElement[0])) { + let html = ""; + selectsElement.forEach(item => { + html += removeEmbed(item); + }); + writeText(protyle.lute.BlockDOM2StdMd(html).trimEnd()); + } else { + focusByRange(getEditorRange(selectsElement[0])); + document.execCommand("copy"); + } + } + }, { + label: window.siyuan.languages.copyPlainText, + accelerator: window.siyuan.config.keymap.editor.general.copyPlainText.custom, + click() { + let html = ""; + selectsElement.forEach(item => { + item.querySelectorAll("[spellcheck]").forEach(editItem => { + const cloneNode = editItem.cloneNode(true) as HTMLElement; + cloneNode.querySelectorAll('[data-type="backslash"]').forEach(slashItem => { + slashItem.firstElementChild.remove(); + }); + html += cloneNode.textContent + "\n"; + }); + }); + copyPlainText(html.trimEnd()); + } + }, { + label: window.siyuan.languages.duplicate, + accelerator: window.siyuan.config.keymap.editor.general.duplicate.custom, + disabled: protyle.disabled, + click() { + duplicateBlock(selectsElement, protyle); + } + }] + const copyTextRefMenu = this.genCopyTextRef(selectsElement) + if (copyTextRefMenu) { + copyMenu.splice(2, 0, copyTextRefMenu); + } 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])) { - let html = ""; - selectsElement.forEach(item => { - html += removeEmbed(item); - }); - writeText(protyle.lute.BlockDOM2StdMd(html).trimEnd()); - } else { - focusByRange(getEditorRange(selectsElement[0])); - document.execCommand("copy"); - } - } - }, { - label: window.siyuan.languages.copyPlainText, - accelerator: window.siyuan.config.keymap.editor.general.copyPlainText.custom, - click() { - let html = ""; - selectsElement.forEach(item => { - item.querySelectorAll("[spellcheck]").forEach(editItem => { - const cloneNode = editItem.cloneNode(true) as HTMLElement; - cloneNode.querySelectorAll('[data-type="backslash"]').forEach(slashItem => { - slashItem.firstElementChild.remove(); - }); - html += cloneNode.textContent + "\n"; - }); - }); - copyPlainText(html.trimEnd()); - } - }, { - label: window.siyuan.languages.duplicate, - accelerator: window.siyuan.config.keymap.editor.general.duplicate.custom, - disabled: protyle.disabled, - click() { - duplicateBlock(selectsElement, protyle); - } - }] + submenu: copyMenu, }).element); if (protyle.disabled) { return; @@ -948,43 +953,48 @@ export class Gutter { submenu: turnIntoSubmenu }).element); } + const copyMenu = (copySubMenu(id, true, nodeElement) as IMenu[]).concat([{ + label: window.siyuan.languages.copy, + accelerator: "⌘C", + click() { + if (isNotEditBlock(nodeElement)) { + writeText(protyle.lute.BlockDOM2StdMd(removeEmbed(nodeElement)).trimEnd()); + } else { + focusByRange(getEditorRange(nodeElement)); + document.execCommand("copy"); + } + } + }, { + label: window.siyuan.languages.copyPlainText, + accelerator: window.siyuan.config.keymap.editor.general.copyPlainText.custom, + click() { + let text = ""; + nodeElement.querySelectorAll("[spellcheck]").forEach(item => { + const cloneNode = item.cloneNode(true) as HTMLElement; + cloneNode.querySelectorAll('[data-type="backslash"]').forEach(slashItem => { + slashItem.firstElementChild.remove(); + }); + text += cloneNode.textContent + "\n"; + }); + copyPlainText(text.trimEnd()); + } + }, { + label: window.siyuan.languages.duplicate, + accelerator: window.siyuan.config.keymap.editor.general.duplicate.custom, + disabled: protyle.disabled, + click() { + duplicateBlock([nodeElement], protyle); + } + }]) + const copyTextRefMenu = this.genCopyTextRef([nodeElement]) + if (copyTextRefMenu) { + copyMenu.splice(copyMenu.length - 1, 0, copyTextRefMenu); + } window.siyuan.menus.menu.append(new MenuItem({ label: window.siyuan.languages.copy, icon: "iconCopy", type: "submenu", - submenu: (copySubMenu(id, true, nodeElement) as IMenu[]).concat([{ - label: window.siyuan.languages.copy, - accelerator: "⌘C", - click() { - if (isNotEditBlock(nodeElement)) { - writeText(protyle.lute.BlockDOM2StdMd(removeEmbed(nodeElement)).trimEnd()); - } else { - focusByRange(getEditorRange(nodeElement)); - document.execCommand("copy"); - } - } - }, { - label: window.siyuan.languages.copyPlainText, - accelerator: window.siyuan.config.keymap.editor.general.copyPlainText.custom, - click() { - let text = ""; - nodeElement.querySelectorAll("[spellcheck]").forEach(item => { - const cloneNode = item.cloneNode(true) as HTMLElement; - cloneNode.querySelectorAll('[data-type="backslash"]').forEach(slashItem => { - slashItem.firstElementChild.remove(); - }); - text += cloneNode.textContent + "\n"; - }); - copyPlainText(text.trimEnd()); - } - }, { - label: window.siyuan.languages.duplicate, - accelerator: window.siyuan.config.keymap.editor.general.duplicate.custom, - disabled: protyle.disabled, - click() { - duplicateBlock([nodeElement], protyle); - } - }]) + submenu: copyMenu }).element); if (!protyle.disabled) { window.siyuan.menus.menu.append(new MenuItem({ @@ -1431,7 +1441,7 @@ export class Gutter { updateHTML = `${window.siyuan.languages.modifiedAt} ${dayjs(updateHTML).format("YYYY-MM-DD HH:mm:ss")}
`; } window.siyuan.menus.menu.append(new MenuItem({ - iconHTML:Constants.ZWSP, + iconHTML: Constants.ZWSP, type: "readonly", label: `${updateHTML}${window.siyuan.languages.createdAt} ${dayjs(id.substr(0, 14)).format("YYYY-MM-DD HH:mm:ss")}`, }).element); @@ -1718,6 +1728,21 @@ export class Gutter { }]); } + private genCopyTextRef(selectsElement: Element[]): false | IMenu { + if (isNotEditBlock(selectsElement[0])) { + return false + } + return { + label: `${window.siyuan.languages.copy} ${window.siyuan.languages.text} *`, + click() { + // 用于标识复制文本 * + selectsElement[0].setAttribute("data-reftext", "true") + focusByRange(getEditorRange(selectsElement[0])); + document.execCommand("copy"); + } + } + } + public render(protyle: IProtyle, element: Element, wysiwyg: HTMLElement) { // https://github.com/siyuan-note/siyuan/issues/4659 const titleElement = wysiwyg.parentElement.querySelector(".protyle-title__input"); diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index ba1d8accf..2f4fdc06c 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -214,14 +214,35 @@ export class WYSIWYG { let html = ""; let textPlain = ""; if (selectElements.length > 0) { + const isRefText = selectElements[0].getAttribute("data-reftext") === "true" if (selectElements[0].getAttribute("data-type") === "NodeListItem" && selectElements[0].parentElement.classList.contains("list") && // 反链复制列表项 https://github.com/siyuan-note/siyuan/issues/6555 selectElements[0].parentElement.childElementCount - 1 === selectElements.length) { - html = selectElements[0].parentElement.outerHTML; + if (isRefText) { + const cloneElement = selectElements[0].parentElement.cloneNode(true) as HTMLElement + const cloneEditElement = getContenteditableElement(cloneElement) + if (cloneEditElement) { + cloneEditElement.insertAdjacentHTML("beforeend", ` *`) + } + html = cloneElement.outerHTML; + selectElements[0].removeAttribute("data-reftext") + } else { + html = selectElements[0].parentElement.outerHTML; + } } else { - selectElements.forEach(item => { + selectElements.forEach((item, index) => { const topElement = getTopAloneElement(item); - html += removeEmbed(topElement); + if (isRefText && index === 0) { + const cloneElement = topElement.cloneNode(true) as HTMLElement + const cloneEditElement = getContenteditableElement(cloneElement) + if (cloneEditElement) { + cloneEditElement.insertAdjacentHTML("beforeend", ` *`) + } + html += removeEmbed(cloneElement); + selectElements[0].removeAttribute("data-reftext") + } else { + html += removeEmbed(topElement); + } }); } } else {