diff --git a/app/src/menus/protyle.ts b/app/src/menus/protyle.ts
index 7eefbb43f..a5e0cf163 100644
--- a/app/src/menus/protyle.ts
+++ b/app/src/menus/protyle.ts
@@ -302,26 +302,6 @@ export const contentMenu = (protyle: IProtyle, nodeElement: Element) => {
copyPlainText(cloneContents.textContent);
}
}).element);
- window.siyuan.menus.menu.append(new MenuItem({
- label: window.siyuan.languages.copy + " HTML",
- click() {
- focusByRange(getEditorRange(nodeElement));
- let html = "";
- getSelection().getRangeAt(0).cloneContents().childNodes.forEach(item => {
- if (item.nodeType === 3) {
- html += item.textContent;
- } else {
- html += (item as Element).outerHTML;
- }
- });
- if (protyle.disabled) {
- html = getEnableHTML(html);
- }
- const tempElement = document.createElement("template");
- tempElement.innerHTML = protyle.lute.BlockDOM2HTML(html);
- writeText(tempElement.content.firstElementChild.innerHTML);
- }
- }).element);
if (protyle.disabled) {
return;
}
diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts
index 5324cd36b..666e5dea6 100644
--- a/app/src/protyle/gutter/index.ts
+++ b/app/src/protyle/gutter/index.ts
@@ -601,18 +601,6 @@ export class Gutter {
});
copyPlainText(html.trimEnd());
}
- }, {
- label: window.siyuan.languages.copy + " HTML",
- click() {
- let html = "";
- selectsElement.forEach(item => {
- html += item.outerHTML;
- });
- if (protyle.disabled) {
- html = getEnableHTML(html);
- }
- writeText(protyle.lute.BlockDOM2HTML(html));
- }
}, {
label: window.siyuan.languages.duplicate,
accelerator: window.siyuan.config.keymap.editor.general.duplicate.custom,
@@ -989,15 +977,6 @@ export class Gutter {
});
copyPlainText(text.trimEnd());
}
- }, {
- label: window.siyuan.languages.copy + " HTML",
- click() {
- let html = nodeElement.outerHTML;
- if (protyle.disabled) {
- html = getEnableHTML(html);
- }
- writeText(protyle.lute.BlockDOM2HTML(html));
- }
}, {
label: window.siyuan.languages.duplicate,
accelerator: window.siyuan.config.keymap.editor.general.duplicate.custom,
diff --git a/app/src/protyle/util/paste.ts b/app/src/protyle/util/paste.ts
index bc8e691d4..567f23067 100644
--- a/app/src/protyle/util/paste.ts
+++ b/app/src/protyle/util/paste.ts
@@ -86,25 +86,24 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
event.preventDefault();
let textHTML;
let textPlain;
+ let siyuanHTML;
let files;
if ("clipboardData" in event) {
textHTML = event.clipboardData.getData("text/html");
textPlain = event.clipboardData.getData("text/plain");
+ siyuanHTML = event.clipboardData.getData("text/siyuan");
files = event.clipboardData.files;
} else {
textHTML = event.dataTransfer.getData("text/html");
textPlain = event.dataTransfer.getData("text/plain");
+ siyuanHTML = event.dataTransfer.getData("text/siyuan");
if (event.dataTransfer.types[0] === "Files") {
files = event.dataTransfer.items;
}
}
- // 复制标题及其下方块使用 writeText,需将 textPLain 转换为 textHTML
- if (textPlain.endsWith(Constants.ZWSP) && !textHTML) {
- textHTML = textPlain;
- }
/// #if !BROWSER
// 不再支持 PC 浏览器 https://github.com/siyuan-note/siyuan/issues/7206
- if (!textHTML && !textPlain && ("clipboardData" in event)) {
+ if (!siyuanHTML && !textHTML && !textPlain && ("clipboardData" in event)) {
if ("darwin" === window.siyuan.config.system.os) {
const xmlString = clipboard.read("NSFilenamesPboardType");
const domParser = new DOMParser();
@@ -136,9 +135,12 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
`${textPlain}`) {
textHTML = "";
}
-
+ // 复制标题及其下方块使用 writeText,需将 textPlain 转换为 textHTML
+ if (textPlain.endsWith(Constants.ZWSP) && !textHTML && !siyuanHTML) {
+ siyuanHTML = textPlain.substr(0, textPlain.length - 1);
+ }
// 剪切复制中首位包含空格或仅有空格 https://github.com/siyuan-note/siyuan/issues/5667
- if (!textHTML.endsWith(Constants.ZWSP) && !textHTML.startsWith(Constants.ZWSP)) {
+ if (!siyuanHTML) {
// process word
const doc = new DOMParser().parseFromString(textHTML, "text/html");
if (doc.body && doc.body.innerHTML) {
@@ -148,10 +150,9 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
if (textHTML.startsWith("\n") && textHTML.endsWith("\n\n")) {
textHTML = doc.body.innerHTML.trim().replace("", "").replace("", "");
}
+ textHTML = Lute.Sanitize(textHTML);
}
- textHTML = Lute.Sanitize(textHTML);
-
const nodeElement = hasClosestBlock(event.target);
if (!nodeElement) {
if (files && files.length > 0) {
@@ -165,8 +166,29 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
});
const code = processPasteCode(textHTML, textPlain);
const range = getEditorRange(protyle.wysiwyg.element);
- // process code
- if (nodeElement.getAttribute("data-type") === "NodeCodeBlock") {
+ if (siyuanHTML) {
+ // 编辑器内部粘贴
+ const tempElement = document.createElement("div")
+ tempElement.innerHTML = siyuanHTML
+ let isBlock = false;
+ tempElement.querySelectorAll("[data-node-id]").forEach((e) => {
+ const newId = Lute.NewNodeID();
+ e.setAttribute("data-node-id", newId);
+ e.classList.remove("protyle-wysiwyg--select", "protyle-wysiwyg--hl");
+ e.setAttribute("updated", newId.split("-")[0]);
+ isBlock = true;
+ });
+ if (nodeElement.classList.contains("table")) {
+ isBlock = false;
+ }
+ // 从历史中复制后粘贴
+ tempElement.querySelectorAll('[contenteditable="false"][spellcheck]').forEach((e) => {
+ e.setAttribute("contenteditable", "true");
+ });
+ const tempInnerHTML = tempElement.innerHTML;
+ insertHTML(tempInnerHTML, protyle, isBlock);
+ filterClipboardHint(protyle, tempInnerHTML);
+ } else if (nodeElement.getAttribute("data-type") === "NodeCodeBlock") {
// 粘贴在代码位置
insertHTML(textPlain, protyle);
return;
@@ -213,77 +235,34 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
}
if (isHTML) {
const tempElement = document.createElement("div");
- if (textHTML.startsWith(Constants.ZWSP)) {
- // 剪切块内容后粘贴
- // mac 复制后会带有 https://github.com/siyuan-note/siyuan/issues/5751
- tempElement.innerHTML = textHTML.substr(1).replace('', "");
- let isBlock = false;
- tempElement.querySelectorAll("[data-node-id]").forEach((e) => {
- const newId = Lute.NewNodeID();
- e.setAttribute("data-node-id", newId);
- e.classList.remove("protyle-wysiwyg--select", "protyle-wysiwyg--hl");
- e.setAttribute("updated", newId.split("-")[0]);
- isBlock = true;
- });
- if (nodeElement.classList.contains("table")) {
- isBlock = false;
+ tempElement.innerHTML = textHTML;
+ tempElement.querySelectorAll("[style]").forEach((e) => {
+ e.removeAttribute("style");
+ });
+ // 移除空的 A 标签
+ tempElement.querySelectorAll("a").forEach((e) => {
+ if (e.innerHTML.trim() === "") {
+ e.remove();
}
- insertHTML(tempElement.innerHTML, protyle, isBlock);
- // 转换为 md,避免再次粘贴 ID 重复
- const tempMd = protyle.lute.BlockDOM2StdMd(tempElement.innerHTML);
- writeText(tempMd);
- filterClipboardHint(protyle, tempMd);
- } else if (textHTML.endsWith(Constants.ZWSP)) {
- // 编辑器内部粘贴
- tempElement.innerHTML = textHTML.substr(0, textHTML.length - 1).replace('', "");
- let isBlock = false;
- tempElement.querySelectorAll("[data-node-id]").forEach((e) => {
- const newId = Lute.NewNodeID();
- e.setAttribute("data-node-id", newId);
- e.classList.remove("protyle-wysiwyg--select", "protyle-wysiwyg--hl");
- e.setAttribute("updated", newId.split("-")[0]);
- isBlock = true;
- });
- if (nodeElement.classList.contains("table")) {
- isBlock = false;
- }
- // 从历史中复制后粘贴
- tempElement.querySelectorAll('[contenteditable="false"][spellcheck]').forEach((e) => {
- e.setAttribute("contenteditable", "true");
- });
- const tempInnerHTML = tempElement.innerHTML;
- insertHTML(tempInnerHTML, protyle, isBlock);
- filterClipboardHint(protyle, tempInnerHTML);
- } else {
- tempElement.innerHTML = textHTML;
- tempElement.querySelectorAll("[style]").forEach((e) => {
- e.removeAttribute("style");
- });
- // 移除空的 A 标签
- tempElement.querySelectorAll("a").forEach((e) => {
- if (e.innerHTML.trim() === "") {
- e.remove();
+ });
+ fetchPost("/api/lute/html2BlockDOM", {
+ dom: tempElement.innerHTML
+ }, (response) => {
+ insertHTML(response.data, protyle);
+ protyle.wysiwyg.element.querySelectorAll('[data-type~="block-ref"]').forEach(item => {
+ if (item.textContent === "") {
+ fetchPost("/api/block/getRefText", {id: item.getAttribute("data-id")}, (response) => {
+ item.innerHTML = response.data;
+ });
}
});
- fetchPost("/api/lute/html2BlockDOM", {
- dom: tempElement.innerHTML
- }, (response) => {
- insertHTML(response.data, protyle);
- protyle.wysiwyg.element.querySelectorAll('[data-type~="block-ref"]').forEach(item => {
- if (item.textContent === "") {
- fetchPost("/api/block/getRefText", {id: item.getAttribute("data-id")}, (response) => {
- item.innerHTML = response.data;
- });
- }
- });
- blockRender(protyle, protyle.wysiwyg.element);
- processRender(protyle.wysiwyg.element);
- highlightRender(protyle.wysiwyg.element);
- filterClipboardHint(protyle, response.data);
- scrollCenter(protyle);
- });
- return;
- }
+ blockRender(protyle, protyle.wysiwyg.element);
+ processRender(protyle.wysiwyg.element);
+ highlightRender(protyle.wysiwyg.element);
+ filterClipboardHint(protyle, response.data);
+ scrollCenter(protyle);
+ });
+ return;
} else if (files && files.length > 0) {
uploadFiles(protyle, files);
} else if (textPlain.trim() !== "" && files && files.length === 0) {
diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts
index 8644abded..93f5da5de 100644
--- a/app/src/protyle/wysiwyg/index.ts
+++ b/app/src/protyle/wysiwyg/index.ts
@@ -281,7 +281,8 @@ export class WYSIWYG {
html = getEnableHTML(html);
}
event.clipboardData.setData("text/plain", textPlain || protyle.lute.BlockDOM2StdMd(html).trimEnd());
- event.clipboardData.setData("text/html", html + Constants.ZWSP);
+ event.clipboardData.setData("text/html", protyle.lute.BlockDOM2HTML(html));
+ event.clipboardData.setData("text/siyuan", html);
});
this.element.addEventListener("mousedown", (event: MouseEvent) => {
if (event.button === 2 || window.siyuan.ctrlIsPressed) {
@@ -1115,7 +1116,8 @@ export class WYSIWYG {
}
protyle.hint.render(protyle);
event.clipboardData.setData("text/plain", protyle.lute.BlockDOM2StdMd(html).trimEnd()); // 需要 trimEnd,否则 \n 会导致 https://github.com/siyuan-note/siyuan/issues/6218
- event.clipboardData.setData("text/html", Constants.ZWSP + html);
+ event.clipboardData.setData("text/html", protyle.lute.BlockDOM2HTML(html));
+ event.clipboardData.setData("text/siyuan", html);
});
let beforeContextmenuRange: Range;