All files / roosterjs-content-model-plugins/lib/imageEdit/utils applyChange.ts

80% Statements 24/30
58.62% Branches 17/29
100% Functions 1/1
80% Lines 24/30

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 881x 1x 1x 1x                                 1x                 4x 4x 4x 4x   4x                       4x 4x     4x   4x     4x           4x     4x             4x       4x 4x       4x   4x 4x 4x      
import { checkEditInfoState } from './checkEditInfoState';
import { generateDataURL } from './generateDataURL';
import { getGeneratedImageSize } from './generateImageSize';
import { updateImageEditInfo } from './updateImageEditInfo';
import type {
    ContentModelImage,
    IEditor,
    ImageMetadataFormat,
} from 'roosterjs-content-model-types';
 
/**
 * @internal
 * Apply changes from the edit info of an image, write result to the image
 * @param editor The editor object that contains the image
 * @param image The image to apply the change
 * @param editInfo Edit info that contains the changed information of the image
 * @param previousSrc Last src value of the image before the change was made
 * @param wasResizedOrCropped if the image was resized or cropped apply the new image dimensions
 * @param editingImage (optional) Image in editing state
 */
export function applyChange(
    editor: IEditor,
    image: HTMLImageElement,
    contentModelImage: ContentModelImage,
    editInfo: ImageMetadataFormat,
    previousSrc: string,
    wasResizedOrCropped: boolean,
    editingImage?: HTMLImageElement
) {
    let newSrc = '';
    const imageEditing = editingImage ?? image;
    const initEditInfo = updateImageEditInfo(contentModelImage, imageEditing) ?? undefined;
    const state = checkEditInfoState(editInfo, initEditInfo);
 
    switch (state) {
        case 'ResizeOnly':
            // For resize only case, no need to generate a new image, just reuse the original one
            newSrc = editInfo.src || '';
            break;
        case 'SameWithLast':
            // For SameWithLast case, image may be resized but the content is still the same with last one,
            // so no need to create a new image, but just reuse last one
            newSrc = previousSrc;
            break;
        case 'FullyChanged':
            // For other cases (cropped, rotated, ...) we need to create a new image to reflect the change
            newSrc = generateDataURL(editingImage ?? image, editInfo);
            break;
    }
 
    const srcChanged = newSrc != previousSrc;
 
    Eif (srcChanged) {
        // If the src is changed, fire an EditImage event so that plugins knows that a new image is used, and can
        // replace the new src with some other string and it will be used and set to the image
        const event = editor.triggerEvent('editImage', {
            image: image,
            originalSrc: editInfo.src || image.src,
            previousSrc,
            newSrc,
        });
        newSrc = event.newSrc;
    }
 
    Iif (newSrc == editInfo.src) {
        // If newSrc is the same with original one, it means there is only size change, but no rotation, no cropping,
        // so we don't need to keep edit info, we can delete it
        updateImageEditInfo(contentModelImage, imageEditing, null);
    } else {
        // Otherwise, save the new edit info to the image so that next time when we edit the same image, we know
        // the edit info
        updateImageEditInfo(contentModelImage, imageEditing, editInfo);
    }
 
    // Write back the change to image, and set its new size
    const generatedImageSize = getGeneratedImageSize(editInfo);
    Iif (!generatedImageSize) {
        return;
    }
 
    contentModelImage.src = newSrc;
 
    Eif (wasResizedOrCropped || state == 'FullyChanged') {
        contentModelImage.format.width = generatedImageSize.targetWidth + 'px';
        contentModelImage.format.height = generatedImageSize.targetHeight + 'px';
    }
}