feat: add clipboardEvent2Blocks for white board to paste

This commit is contained in:
QiShaoXuan
2022-08-24 16:39:29 +08:00
parent ce0c021c5e
commit c20288ce76
3 changed files with 30 additions and 39 deletions
@@ -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) {