All files / roosterjs-content-model-core/lib/command/paste paste.ts

96.15% Statements 25/26
77.78% Branches 14/18
100% Functions 3/3
96.15% Lines 25/26

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 851x 1x 1x 1x 1x 1x                           1x     51x   33x 33x   33x 27x   27x 27x   27x         33x 33x     33x   33x         33x     33x                     33x                 33x     33x             49x    
import { cleanHtmlComments } from './cleanHtmlComments';
import { cloneModelForPaste, mergePasteContent } from './mergePasteContent';
import { convertInlineCss } from '../createModelFromHtml/convertInlineCss';
import { createPasteFragment } from './createPasteFragment';
import { generatePasteOptionFromPlugins } from './generatePasteOptionFromPlugins';
import { retrieveHtmlInfo } from './retrieveHtmlInfo';
import type {
    PasteTypeOrGetter,
    ClipboardData,
    IEditor,
    DOMCreator,
} from 'roosterjs-content-model-types';
 
/**
 * Paste into editor using a clipboardData object
 * @param editor The Editor object.
 * @param clipboardData Clipboard data retrieved from clipboard
 * @param pasteTypeOrGetter Type of content to paste or function that returns the Paste Type to use based on the document and the clipboard Data. @default normal
 */
export function paste(
    editor: IEditor,
    clipboardData: ClipboardData,
    pasteTypeOrGetter: PasteTypeOrGetter = 'normal'
) {
    editor.focus();
    let isFirstPaste = false;
 
    if (!clipboardData.modelBeforePaste) {
        isFirstPaste = true;
 
        editor.formatContentModel(model => {
            clipboardData.modelBeforePaste = cloneModelForPaste(model);
 
            return false;
        });
    }
 
    // 1. Prepare variables
    const domCreator = editor.getDOMCreator();
    Iif (!domCreator.isBypassed && clipboardData.rawHtml) {
        clipboardData.rawHtml = cleanHtmlComments(clipboardData.rawHtml);
    }
    const doc = createDOMFromHtml(clipboardData.rawHtml, domCreator);
    const pasteType =
        typeof pasteTypeOrGetter == 'function'
            ? pasteTypeOrGetter(doc, clipboardData)
            : pasteTypeOrGetter;
 
    // 2. Handle HTML from clipboard
    const htmlFromClipboard = retrieveHtmlInfo(doc, clipboardData);
 
    // 3. Create target fragment
    const sourceFragment = createPasteFragment(
        editor.getDocument(),
        clipboardData,
        pasteType,
        (clipboardData.rawHtml == clipboardData.html
            ? doc
            : createDOMFromHtml(clipboardData.html, domCreator)
        )?.body
    );
 
    // 4. Trigger BeforePaste event to allow plugins modify the fragment
    const eventResult = generatePasteOptionFromPlugins(
        editor,
        clipboardData,
        sourceFragment,
        htmlFromClipboard,
        pasteType
    );
 
    // 5. Convert global CSS to inline CSS
    convertInlineCss(eventResult.fragment, htmlFromClipboard.globalCssRules);
 
    // 6. Merge pasted content into main Content Model
    mergePasteContent(editor, eventResult, isFirstPaste);
}
 
function createDOMFromHtml(
    html: string | null | undefined,
    domCreator: DOMCreator
): Document | null {
    return html ? domCreator.htmlToDOM(html) : null;
}