Skip to content

Commit

Permalink
feat(doc): support paste img by right context
Browse files Browse the repository at this point in the history
  • Loading branch information
Gggpound committed Nov 21, 2024
1 parent a6c2e52 commit 38b229a
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ import {
Inject,
RxDisposable,
} from '@univerjs/core';
import { FILES_CLIPBOARD_MIME_TYPE, HTML_CLIPBOARD_MIME_TYPE, PLAIN_TEXT_CLIPBOARD_MIME_TYPE } from '@univerjs/ui';
import {
FILE__BMP_CLIPBOARD_MIME_TYPE,
FILE__JPEG_CLIPBOARD_MIME_TYPE,
FILE__WEBP_CLIPBOARD_MIME_TYPE,
FILE_PNG_CLIPBOARD_MIME_TYPE,
HTML_CLIPBOARD_MIME_TYPE,
PLAIN_TEXT_CLIPBOARD_MIME_TYPE,
} from '@univerjs/ui';
import { takeUntil } from 'rxjs';
import { whenDocOrEditor } from '../../commands/commands/clipboard.command';
import { IDocClipboardService } from '../../services/clipboard/clipboard.service';
Expand Down Expand Up @@ -59,8 +66,16 @@ export class DocClipboardController extends RxDisposable implements IRenderModul
const clipboardEvent = config!.event as ClipboardEvent;
let htmlContent = clipboardEvent.clipboardData?.getData(HTML_CLIPBOARD_MIME_TYPE);
const textContent = clipboardEvent.clipboardData?.getData(PLAIN_TEXT_CLIPBOARD_MIME_TYPE);

const imageTypes = [
FILE__BMP_CLIPBOARD_MIME_TYPE,
FILE__JPEG_CLIPBOARD_MIME_TYPE,
FILE__WEBP_CLIPBOARD_MIME_TYPE,
FILE_PNG_CLIPBOARD_MIME_TYPE,
];

const files = [...(clipboardEvent.clipboardData?.items || [])]
.filter((item) => item.kind === FILES_CLIPBOARD_MIME_TYPE && item.type === 'image/png')
.filter((item) => imageTypes.includes(item.type))
.map((item) => item.getAsFile()!)
.filter((e) => !!e);

Expand Down
27 changes: 24 additions & 3 deletions packages/docs-ui/src/services/clipboard/clipboard.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ import type { IRectRangeWithStyle, ITextRangeWithStyle } from '@univerjs/engine-
import { BuildTextUtils, createIdentifier, DataStreamTreeTokenType, Disposable, DOC_RANGE_TYPE, DOCS_NORMAL_EDITOR_UNIT_ID_KEY, getBodySlice, ICommandService, ILogService, Inject, IUniverInstanceService, normalizeBody, ObjectRelativeFromH, ObjectRelativeFromV, PositionedObjectLayoutType, SliceBodyType, toDisposable, Tools, UniverInstanceType } from '@univerjs/core';
import { DocSelectionManagerService } from '@univerjs/docs';
import { DrawingTypeEnum, ImageSourceType } from '@univerjs/drawing';
import { HTML_CLIPBOARD_MIME_TYPE, IClipboardInterfaceService, PLAIN_TEXT_CLIPBOARD_MIME_TYPE } from '@univerjs/ui';
import {
FILE__BMP_CLIPBOARD_MIME_TYPE,
FILE__JPEG_CLIPBOARD_MIME_TYPE,
FILE__WEBP_CLIPBOARD_MIME_TYPE,
FILE_PNG_CLIPBOARD_MIME_TYPE,
HTML_CLIPBOARD_MIME_TYPE,
IClipboardInterfaceService,
PLAIN_TEXT_CLIPBOARD_MIME_TYPE,
} from '@univerjs/ui';
import { CutContentCommand, InnerPasteCommand } from '../../commands/commands/clipboard.inner.command';
import { getCursorWhenDelete } from '../../commands/commands/doc-delete.command';
import { copyContentCache, extractId, genId } from './copy-content-cache';
Expand Down Expand Up @@ -411,10 +419,9 @@ export class DocClipboardService extends Disposable implements IDocClipboardServ

private async _genDocDataFromClipboardItems(items: ClipboardItem[]): Promise<Partial<IDocumentData>> {
try {
// TODO: support paste image.

let html = '';
let text = '';
const files: File[] = [];
for (const clipboardItem of items) {
for (const type of clipboardItem.types) {
switch (type) {
Expand All @@ -426,9 +433,23 @@ export class DocClipboardService extends Disposable implements IDocClipboardServ
html = await clipboardItem.getType(type).then((blob) => blob && blob.text());
break;
}
case FILE__BMP_CLIPBOARD_MIME_TYPE:
case FILE__JPEG_CLIPBOARD_MIME_TYPE:
case FILE__WEBP_CLIPBOARD_MIME_TYPE:
case FILE_PNG_CLIPBOARD_MIME_TYPE: {
const blob = await clipboardItem.getType(type);
const file = new File([blob], `pasted_image.${type.split('/')[1]}`, { type });
files.push(file);
break;
}
}
}
}
if (!html && !text && files.length) {
// 粘贴图片
const imageHtml = await this._createImagePasteHtml(files);
html = imageHtml;
}

return this._genDocDataFromHtmlAndText(html, text);
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,6 @@ export class HtmlToUDMService {
const docTransformHeight = Number(element.dataset.docTransformHeight || height);
// 外部会进行替换.
const id = Tools.generateRandomId(6);
body.textRuns!.push({
st: body.dataStream.length,
ed: body.dataStream.length,
});
doc.body?.customBlocks?.push({ startIndex: body.dataStream.length, blockId: id });
body.dataStream += '\b';
if (!doc.drawings) {
Expand Down
6 changes: 5 additions & 1 deletion packages/ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ export { DesktopBeforeCloseService, IBeforeCloseService } from './services/befor
export { CopyCommand, CutCommand, PasteCommand } from './services/clipboard/clipboard.command';
export {
BrowserClipboardService,
FILES_CLIPBOARD_MIME_TYPE,
FILE__BMP_CLIPBOARD_MIME_TYPE,
FILE__JPEG_CLIPBOARD_MIME_TYPE,
FILE__WEBP_CLIPBOARD_MIME_TYPE,
FILE_PNG_CLIPBOARD_MIME_TYPE,
FILE_SVG_XML_CLIPBOARD_MIME_TYPE,
HTML_CLIPBOARD_MIME_TYPE,
IClipboardInterfaceService,
PLAIN_TEXT_CLIPBOARD_MIME_TYPE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ import { supportClipboardAPI } from './clipboard-utils';

export const PLAIN_TEXT_CLIPBOARD_MIME_TYPE = 'text/plain';
export const HTML_CLIPBOARD_MIME_TYPE = 'text/html';
export const FILES_CLIPBOARD_MIME_TYPE = 'file';
export const FILE_PNG_CLIPBOARD_MIME_TYPE = 'image/png';
export const FILE__JPEG_CLIPBOARD_MIME_TYPE = 'image/jpeg';
export const FILE__BMP_CLIPBOARD_MIME_TYPE = 'image/bmp';
export const FILE__WEBP_CLIPBOARD_MIME_TYPE = 'image/webp';
export const FILE_SVG_XML_CLIPBOARD_MIME_TYPE = 'image/svg+xml';

/**
* This interface provides an interface to access system's clipboard.
Expand Down

0 comments on commit 38b229a

Please sign in to comment.