mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-26 19:38:48 +01:00
This commit is contained in:
parent
280f97ee81
commit
0d3dec71f3
4 changed files with 38 additions and 49 deletions
|
|
@ -5,17 +5,22 @@ import {Constants} from "../../constants";
|
|||
export const encodeBase64 = (text: string): string => {
|
||||
const encoder = new TextEncoder();
|
||||
const bytes = encoder.encode(text);
|
||||
const binaryString = String.fromCharCode(...bytes);
|
||||
const base64 = btoa(binaryString);
|
||||
return base64;
|
||||
return btoa(String.fromCharCode(...bytes));
|
||||
};
|
||||
|
||||
export const decodeBase64 = (base64: string): string => {
|
||||
const decoder = new TextDecoder();
|
||||
const binaryString = atob(base64);
|
||||
const bytes = Uint8Array.from(binaryString, char => char.charCodeAt(0));
|
||||
const text = decoder.decode(bytes);
|
||||
return text;
|
||||
const getSiyuanHTML = (text: IClipboardData) => {
|
||||
const siyuanMatch = text.textHTML.match(/<!--siyuan-data:([^>]+)-->/);
|
||||
if (siyuanMatch) {
|
||||
try {
|
||||
const decoder = new TextDecoder();
|
||||
const bytes = Uint8Array.from(atob(siyuanMatch[1]), char => char.charCodeAt(0));
|
||||
text.siyuanHTML = decoder.decode(bytes);
|
||||
// 移除注释节点,保持原有的 text/html 内容
|
||||
text.textHTML = text.textHTML.replace(/<!--siyuan-data:[^>]+-->/, "");
|
||||
} catch (e) {
|
||||
console.log("Failed to decode siyuan data from HTML comment:", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const openByMobile = (uri: string) => {
|
||||
|
|
@ -71,30 +76,14 @@ export const readText = () => {
|
|||
};
|
||||
|
||||
export const readClipboard = async () => {
|
||||
const text: {
|
||||
textHTML?: string,
|
||||
textPlain?: string,
|
||||
siyuanHTML?: string,
|
||||
files?: File[],
|
||||
} = {textPlain: "", textHTML: "", siyuanHTML: ""};
|
||||
const text: IClipboardData = {textPlain: "", textHTML: "", siyuanHTML: ""};
|
||||
try {
|
||||
const clipboardContents = await navigator.clipboard.read();
|
||||
for (const item of clipboardContents) {
|
||||
if (item.types.includes("text/html")) {
|
||||
const blob = await item.getType("text/html");
|
||||
text.textHTML = await blob.text();
|
||||
|
||||
// 从 text/html 中的注释节点提取 text/siyuan 数据
|
||||
const siyuanMatch = text.textHTML.match(/<!--siyuan-data:([^>]+)-->/);
|
||||
if (siyuanMatch) {
|
||||
try {
|
||||
text.siyuanHTML = decodeBase64(siyuanMatch[1]);
|
||||
// 移除注释节点,保持原有的 text/html 内容
|
||||
text.textHTML = text.textHTML.replace(/<!--siyuan-data:[^>]+-->/, "");
|
||||
} catch (e) {
|
||||
console.log("Failed to decode siyuan data from HTML comment:", e);
|
||||
}
|
||||
}
|
||||
getSiyuanHTML(text);
|
||||
}
|
||||
if (item.types.includes("text/plain")) {
|
||||
const blob = await item.getType("text/plain");
|
||||
|
|
@ -110,9 +99,11 @@ export const readClipboard = async () => {
|
|||
if (isInAndroid()) {
|
||||
text.textPlain = window.JSAndroid.readClipboard();
|
||||
text.textHTML = window.JSAndroid.readHTMLClipboard();
|
||||
getSiyuanHTML(text);
|
||||
} else if (isInHarmony()) {
|
||||
text.textPlain = window.JSHarmony.readClipboard();
|
||||
text.textHTML = window.JSHarmony.readHTMLClipboard();
|
||||
getSiyuanHTML(text);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,12 +245,7 @@ const readLocalFile = async (protyle: IProtyle, localFiles: string[]) => {
|
|||
uploadLocalFiles(localFiles, protyle, true);
|
||||
};
|
||||
|
||||
export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEvent | {
|
||||
textHTML?: string,
|
||||
textPlain?: string,
|
||||
siyuanHTML?: string,
|
||||
files?: File[],
|
||||
}) & {
|
||||
export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEvent | IClipboardData) & {
|
||||
target: HTMLElement
|
||||
}) => {
|
||||
if ("clipboardData" in event || "dataTransfer" in event) {
|
||||
|
|
|
|||
|
|
@ -442,17 +442,15 @@ export class WYSIWYG {
|
|||
// Remove ZWSP when copying inline elements https://github.com/siyuan-note/siyuan/issues/13882
|
||||
.replace(new RegExp(Constants.ZWSP, "g"), "");
|
||||
event.clipboardData.setData("text/plain", textPlain);
|
||||
|
||||
// 获取 text/siyuan 数据
|
||||
|
||||
// 设置 text/siyuan 数据
|
||||
enableLuteMarkdownSyntax(protyle);
|
||||
const siyuanData = selectTableElement ? protyle.lute.HTML2BlockDOM(html) : html;
|
||||
event.clipboardData.setData("text/siyuan", siyuanData);
|
||||
const siyuanHTML = selectTableElement ? protyle.lute.HTML2BlockDOM(html) : html;
|
||||
event.clipboardData.setData("text/siyuan", siyuanHTML);
|
||||
restoreLuteMarkdownSyntax(protyle);
|
||||
|
||||
|
||||
// 在 text/html 中插入注释节点,用于右键菜单粘贴时获取 text/siyuan 数据
|
||||
const textHTML = selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html);
|
||||
const siyuanComment = `<!--siyuan-data:${encodeBase64(siyuanData)}-->`;
|
||||
event.clipboardData.setData("text/html", siyuanComment + textHTML);
|
||||
event.clipboardData.setData("text/html", `<!--siyuan-data:${encodeBase64(siyuanHTML)}-->` + (selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html)));
|
||||
});
|
||||
|
||||
this.element.addEventListener("mousedown", (event: MouseEvent) => {
|
||||
|
|
@ -1947,17 +1945,15 @@ export class WYSIWYG {
|
|||
}
|
||||
textPlain = textPlain.replace(/\u00A0/g, " "); // Replace non-breaking spaces with normal spaces when copying https://github.com/siyuan-note/siyuan/issues/9382
|
||||
event.clipboardData.setData("text/plain", textPlain);
|
||||
|
||||
// 获取 text/siyuan 数据
|
||||
|
||||
// 设置 text/siyuan 数据
|
||||
enableLuteMarkdownSyntax(protyle);
|
||||
const siyuanData = selectTableElement ? protyle.lute.HTML2BlockDOM(html) : html;
|
||||
event.clipboardData.setData("text/siyuan", siyuanData);
|
||||
const siyuanHTML = selectTableElement ? protyle.lute.HTML2BlockDOM(html) : html;
|
||||
event.clipboardData.setData("text/siyuan", siyuanHTML);
|
||||
restoreLuteMarkdownSyntax(protyle);
|
||||
|
||||
|
||||
// 在 text/html 中插入注释节点,用于右键菜单粘贴时获取 text/siyuan 数据
|
||||
const textHTML = selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html);
|
||||
const siyuanComment = `<!--siyuan-data:${encodeBase64(siyuanData)}-->`;
|
||||
event.clipboardData.setData("text/html", siyuanComment + textHTML);
|
||||
event.clipboardData.setData("text/html", `<!--siyuan-data:${encodeBase64(siyuanHTML)}-->` + (selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html)));
|
||||
});
|
||||
|
||||
let beforeContextmenuRange: Range;
|
||||
|
|
|
|||
7
app/src/types/index.d.ts
vendored
7
app/src/types/index.d.ts
vendored
|
|
@ -260,6 +260,13 @@ interface Window {
|
|||
destroyTheme(): Promise<void>;
|
||||
}
|
||||
|
||||
interface IClipboardData {
|
||||
textHTML?: string,
|
||||
textPlain?: string,
|
||||
siyuanHTML?: string,
|
||||
files?: File[],
|
||||
}
|
||||
|
||||
interface IRefDefs {
|
||||
refID: string,
|
||||
defIDs?: string[]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue