All files / roosterjs-content-model-dom/lib/domUtils/event extractClipboardItems.ts

90% Statements 36/40
96.77% Branches 30/31
92.86% Functions 13/14
90% Lines 36/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 911x     1x     5x 5x 1x   1x                 1x       14x                   14x   25x   25x 3x 3x 3x 3x 3x 3x 3x           22x 8x 8x 8x 7x 7x   8x     14x   14x 14x 14x   12x 12x 12x           14x                     14x   14x 14x    
import { readFile } from '../readFile';
import type { ClipboardData, EdgeLinkPreview } from 'roosterjs-content-model-types';
 
const ContentHandlers: {
    [contentType: string]: (data: ClipboardData, value: string, type?: string) => void;
} = {
    ['text/html']: (data, value) => (data.rawHtml = value),
    ['text/plain']: (data, value) => (data.text = value),
    ['text/*']: (data, value, type?) => !!type && (data.customValues[type] = value),
    ['text/link-preview']: tryParseLinkPreview,
    ['text/uri-list']: (data, value) => (data.text = value),
};
 
/**
 * Extract clipboard items to be a ClipboardData object for IE
 * @param items The clipboard items retrieve from a DataTransfer object
 * @param allowedCustomPasteType Allowed custom content type when paste besides text/plain, text/html and images
    Only text types are supported, and do not add "text/" prefix to the type values
 */
export function extractClipboardItems(
    items: DataTransferItem[],
    allowedCustomPasteType?: string[]
): Promise<ClipboardData> {
    const data: ClipboardData = {
        types: [],
        text: '',
        image: null,
        files: [],
        rawHtml: null,
        customValues: {},
        pasteNativeEvent: true,
    };
 
    return Promise.all(
        (items || []).map(item => {
            const type = item.type;
 
            if (type.indexOf('image/') == 0 && !data.image && item.kind == 'file') {
                data.types.push(type);
                data.image = item.getAsFile();
                return new Promise<void>(resolve => {
                    Eif (data.image) {
                        readFile(data.image, dataUrl => {
                            data.imageDataUri = dataUrl;
                            resolve();
                        });
                    } else {
                        resolve();
                    }
                });
            } else if (item.kind == 'file') {
                return new Promise<void>(resolve => {
                    const file = item.getAsFile();
                    if (!!file) {
                        data.types.push(type);
                        data.files!.push(file);
                    }
                    resolve();
                });
            } else {
                const customType = getAllowedCustomType(type, allowedCustomPasteType);
                const handler =
                    ContentHandlers[type] || (customType ? ContentHandlers['text/*'] : null);
                return new Promise<void>(resolve =>
                    handler
                        ? item.getAsString(value => {
                              data.types.push(type);
                              handler(data, value, customType);
                              resolve();
                          })
                        : resolve()
                );
            }
        })
    ).then(() => data);
}
 
function tryParseLinkPreview(data: ClipboardData, value: string) {
    try {
        data.customValues['link-preview'] = value;
        data.linkPreview = JSON.parse(value) as EdgeLinkPreview;
    } catch {}
}
 
function getAllowedCustomType(type: string, allowedCustomPasteType?: string[]) {
    const textType = type.indexOf('text/') == 0 ? type.substring('text/'.length) : null;
    const index =
        allowedCustomPasteType && textType ? allowedCustomPasteType.indexOf(textType) : -1;
    return textType && index >= 0 ? textType : undefined;
}