Skip to content

Commit ed75115

Browse files
committed
🎨 Improve right-click menu paste
1 parent 38a7bf0 commit ed75115

2 files changed

Lines changed: 27 additions & 10 deletions

File tree

app/src/protyle/util/compatibility.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,37 @@ import {fetchPost} from "../../util/fetch";
33
import {Constants} from "../../constants";
44

55
export const encodeBase64 = (text: string): string => {
6-
const encoder = new TextEncoder();
7-
const bytes = encoder.encode(text);
8-
return btoa(String.fromCharCode(...bytes));
6+
if (typeof Buffer !== "undefined") {
7+
return Buffer.from(text, "utf8").toString("base64");
8+
} else {
9+
const encoder = new TextEncoder();
10+
const bytes = encoder.encode(text);
11+
let binary = "";
12+
const chunkSize = 0x8000; // 避免栈溢出
13+
14+
for (let i = 0; i < bytes.length; i += chunkSize) {
15+
const chunk = bytes.subarray(i, Math.min(i + chunkSize, bytes.length));
16+
binary += String.fromCharCode.apply(null, chunk);
17+
}
18+
19+
return btoa(binary);
20+
}
921
};
1022

1123
const getSiyuanHTML = (text: IClipboardData) => {
12-
const siyuanMatch = text.textHTML.match(/<!--siyuan-data:([^>]+)-->/);
24+
const siyuanMatch = text.textHTML.match(/<!--data-siyuan='([^']+)'-->/);
1325
if (siyuanMatch) {
1426
try {
15-
const decoder = new TextDecoder();
16-
const bytes = Uint8Array.from(atob(siyuanMatch[1]), char => char.charCodeAt(0));
17-
text.siyuanHTML = decoder.decode(bytes);
27+
if (typeof Buffer !== "undefined") {
28+
const decodedBytes = Buffer.from(siyuanMatch[1], "base64");
29+
text.siyuanHTML = decodedBytes.toString("utf8");
30+
} else {
31+
const decoder = new TextDecoder();
32+
const bytes = Uint8Array.from(atob(siyuanMatch[1]), char => char.charCodeAt(0));
33+
text.siyuanHTML = decoder.decode(bytes);
34+
}
1835
// 移除注释节点,保持原有的 text/html 内容
19-
text.textHTML = text.textHTML.replace(/<!--siyuan-data:[^>]+-->/, "");
36+
text.textHTML = text.textHTML.replace(/<!--data-siyuan='[^']+'-->/, "");
2037
} catch (e) {
2138
console.log("Failed to decode siyuan data from HTML comment:", e);
2239
}

app/src/protyle/wysiwyg/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ export class WYSIWYG {
450450
restoreLuteMarkdownSyntax(protyle);
451451

452452
// 在 text/html 中插入注释节点,用于右键菜单粘贴时获取 text/siyuan 数据
453-
event.clipboardData.setData("text/html", `<!--siyuan-data:${encodeBase64(siyuanHTML)}-->` + (selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html)));
453+
event.clipboardData.setData("text/html", `<!--data-siyuan='${encodeBase64(siyuanHTML)}'-->` + (selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html)));
454454
});
455455

456456
this.element.addEventListener("mousedown", (event: MouseEvent) => {
@@ -1953,7 +1953,7 @@ export class WYSIWYG {
19531953
restoreLuteMarkdownSyntax(protyle);
19541954

19551955
// 在 text/html 中插入注释节点,用于右键菜单粘贴时获取 text/siyuan 数据
1956-
event.clipboardData.setData("text/html", `<!--siyuan-data:${encodeBase64(siyuanHTML)}-->` + (selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html)));
1956+
event.clipboardData.setData("text/html", `<!--data-siyuan='${encodeBase64(siyuanHTML)}'-->` + (selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html)));
19571957
});
19581958

19591959
let beforeContextmenuRange: Range;

0 commit comments

Comments
 (0)