mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-11 15:16:28 +08:00
feat: add clipboardEvent2Blocks for white board to paste
This commit is contained in:
@@ -10,7 +10,6 @@ export class Clipboard {
|
||||
private _clipboardEventDispatcher: ClipboardEventDispatcher;
|
||||
private _copy: Copy;
|
||||
private _paste: Paste;
|
||||
private readonly _supportMarkdownPaste = true;
|
||||
public clipboardUtils: ClipboardUtils;
|
||||
private _clipboardTarget: HTMLElement;
|
||||
|
||||
@@ -19,7 +18,7 @@ export class Clipboard {
|
||||
this._clipboardTarget = clipboardTarget;
|
||||
this._copy = new Copy(editor);
|
||||
|
||||
this._paste = new Paste(editor, this._supportMarkdownPaste);
|
||||
this._paste = new Paste(editor);
|
||||
|
||||
this._clipboardEventDispatcher = new ClipboardEventDispatcher(
|
||||
editor,
|
||||
@@ -49,7 +48,9 @@ export class Clipboard {
|
||||
return this._clipboardTarget;
|
||||
}
|
||||
|
||||
setEditorContainer(container: HTMLElement) {}
|
||||
public clipboardEvent2Blocks(e: ClipboardEvent) {
|
||||
return this._paste.clipboardEvent2Blocks(e);
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
this._clipboardEventDispatcher.dispose(this.clipboardTarget);
|
||||
|
||||
@@ -147,14 +147,14 @@ export class ClipboardUtils {
|
||||
).join('');
|
||||
}
|
||||
|
||||
async convertHTMLString2Blocks(html: string) {
|
||||
async convertHTMLString2Blocks(html: string): Promise<ClipBlockInfo[]> {
|
||||
const htmlEl = document.createElement('html');
|
||||
htmlEl.innerHTML = html;
|
||||
htmlEl.querySelector('head')?.remove();
|
||||
|
||||
return this.convertHtml2Block(htmlEl);
|
||||
return this.convertHtml2Blocks(htmlEl);
|
||||
}
|
||||
async convertHtml2Block(element: Element): Promise<ClipBlockInfo[]> {
|
||||
async convertHtml2Blocks(element: Element): Promise<ClipBlockInfo[]> {
|
||||
const editableViews = this._editor.getEditableViews();
|
||||
// 如果block能够捕捉htmlElement则返回block的html2block
|
||||
const [clipBlockInfos] = (
|
||||
@@ -174,7 +174,7 @@ export class ClipboardUtils {
|
||||
return (
|
||||
await Promise.all(
|
||||
Array.from(element.children).map(async childElement => {
|
||||
const clipBlockInfos = await this.convertHtml2Block(
|
||||
const clipBlockInfos = await this.convertHtml2Blocks(
|
||||
childElement
|
||||
);
|
||||
|
||||
|
||||
@@ -19,13 +19,10 @@ type TextValueItem = {
|
||||
export class Paste {
|
||||
private _editor: Editor;
|
||||
private _markdownParse: MarkdownParser;
|
||||
private readonly _supportMarkdownPaste: boolean = true;
|
||||
private _utils: ClipboardUtils;
|
||||
constructor(editor: Editor, supportMarkdownPaste?: boolean) {
|
||||
constructor(editor: Editor) {
|
||||
this._markdownParse = new MarkdownParser();
|
||||
this._editor = editor;
|
||||
this._supportMarkdownPaste =
|
||||
supportMarkdownPaste ?? this._supportMarkdownPaste;
|
||||
|
||||
this._utils = new ClipboardUtils(editor);
|
||||
this.handlePaste = this.handlePaste.bind(this);
|
||||
@@ -37,17 +34,21 @@ export class Paste {
|
||||
OFFICE_CLIPBOARD_MIMETYPE.TEXT,
|
||||
];
|
||||
|
||||
public handlePaste(e: ClipboardEvent) {
|
||||
public async handlePaste(e: ClipboardEvent) {
|
||||
e.stopPropagation();
|
||||
|
||||
const clipboardData = e.clipboardData;
|
||||
const blocks = await this.clipboardEvent2Blocks(e);
|
||||
await this._insertBlocks(blocks);
|
||||
}
|
||||
|
||||
public async clipboardEvent2Blocks(e: ClipboardEvent) {
|
||||
const clipboardData = e.clipboardData;
|
||||
const isPureFile = Paste._isPureFileInClipboard(clipboardData);
|
||||
|
||||
if (isPureFile) {
|
||||
this._pasteFile(clipboardData);
|
||||
} else {
|
||||
this._pasteContent(clipboardData);
|
||||
return this._file2Blocks(clipboardData);
|
||||
}
|
||||
return this._clipboardData2Blocks(clipboardData);
|
||||
}
|
||||
// Get the most needed clipboard data based on `_optimalMimeTypes` order
|
||||
public getOptimalClip(clipboardData: ClipboardEvent['clipboardData']) {
|
||||
@@ -66,43 +67,41 @@ export class Paste {
|
||||
return null;
|
||||
}
|
||||
|
||||
private _pasteContent(clipboardData: ClipboardEvent['clipboardData']) {
|
||||
private async _clipboardData2Blocks(
|
||||
clipboardData: ClipboardEvent['clipboardData']
|
||||
): Promise<ClipBlockInfo[]> {
|
||||
const optimalClip = this.getOptimalClip(clipboardData);
|
||||
if (
|
||||
optimalClip?.type ===
|
||||
OFFICE_CLIPBOARD_MIMETYPE.DOCS_DOCUMENT_SLICE_CLIP_WRAPPED
|
||||
) {
|
||||
return this._firePasteEditAction(optimalClip.data);
|
||||
const clipInfo: InnerClipInfo = JSON.parse(optimalClip.data);
|
||||
return clipInfo.data;
|
||||
}
|
||||
|
||||
const textClipData = escape(
|
||||
clipboardData.getData(OFFICE_CLIPBOARD_MIMETYPE.TEXT)
|
||||
);
|
||||
|
||||
const shouldConvertMarkdown =
|
||||
this._supportMarkdownPaste &&
|
||||
this._markdownParse.checkIfTextContainsMd(textClipData);
|
||||
|
||||
if (
|
||||
optimalClip?.type === OFFICE_CLIPBOARD_MIMETYPE.HTML &&
|
||||
!shouldConvertMarkdown
|
||||
) {
|
||||
return this._pasteHtml(optimalClip.data);
|
||||
return this._utils.convertHTMLString2Blocks(optimalClip.data);
|
||||
}
|
||||
|
||||
if (shouldConvertMarkdown) {
|
||||
const md2html = marked.parse(textClipData);
|
||||
return this._pasteHtml(md2html);
|
||||
return this._utils.convertHTMLString2Blocks(md2html);
|
||||
}
|
||||
|
||||
return this._pasteText(textClipData);
|
||||
return this._utils.textToBlock(textClipData);
|
||||
}
|
||||
|
||||
private async _firePasteEditAction(clipboardData: string) {
|
||||
const clipInfo: InnerClipInfo = JSON.parse(clipboardData);
|
||||
clipInfo && this._insertBlocks(clipInfo.data);
|
||||
}
|
||||
|
||||
private async _pasteFile(clipboardData: any) {
|
||||
private async _file2Blocks(clipboardData: any): Promise<ClipBlockInfo[]> {
|
||||
const file = Paste._getImageFile(clipboardData);
|
||||
if (file) {
|
||||
const result = await services.api.file.create({
|
||||
@@ -121,8 +120,9 @@ export class Paste {
|
||||
},
|
||||
children: [] as ClipBlockInfo[],
|
||||
};
|
||||
await this._insertBlocks([blockInfo]);
|
||||
return [blockInfo];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
private static _isPureFileInClipboard(clipboardData: DataTransfer) {
|
||||
const types = clipboardData.types;
|
||||
@@ -423,16 +423,6 @@ export class Paste {
|
||||
);
|
||||
}
|
||||
|
||||
private async _pasteHtml(clipData: string) {
|
||||
const block2 = await this._utils.convertHTMLString2Blocks(clipData);
|
||||
await this._insertBlocks(block2);
|
||||
}
|
||||
|
||||
private async _pasteText(clipData: string) {
|
||||
const blocks = this._utils.textToBlock(clipData);
|
||||
await this._insertBlocks(blocks);
|
||||
}
|
||||
|
||||
private static _getImageFile(clipboardData: any) {
|
||||
const files = clipboardData.files;
|
||||
if (files && files[0] && files[0].type.indexOf('image') > -1) {
|
||||
|
||||
Reference in New Issue
Block a user