All files / roosterjs-content-model-plugins/lib/imageEdit/Resizer createImageResizer.ts

95.12% Statements 39/41
84.38% Branches 27/32
100% Functions 11/11
95.12% Lines 39/41

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 91 92 93 94 95 96 97 98 99 100 101 102 1031x 1x 1x 1x                   1x 1x         1x       19x 19x 19x   152x 152x 152x     152x 19x               19x   19x 57x 171x 171x     171x 76x       19x               19x 19x 57x 171x 171x     171x 76x       19x     1x 152x       171x 171x 171x 171x 171x 171x                              
import { createElement } from '../../pluginUtils/CreateElement/createElement';
import { ImageEditElementClass } from '../types/ImageEditElementClass';
import { isElementOfType, isNodeOfType } from 'roosterjs-content-model-dom';
import { Xs, Ys } from '../constants/constants';
import type { CreateElementData } from '../../pluginUtils/CreateElement/CreateElementData';
import type { DNDDirectionX, DnDDirectionY } from '../types/DragAndDropContext';
/**
 * @internal
 */
export interface OnShowResizeHandle {
    (elementData: CreateElementData, x: DNDDirectionX, y: DnDDirectionY): void;
}
 
const RESIZE_HANDLE_MARGIN = 6;
const RESIZE_HANDLE_SIZE = 10;
 
/**
 * @internal
 */
export function createImageResizer(
    doc: Document,
    onShowResizeHandle?: OnShowResizeHandle
): HTMLDivElement[] {
    const cornerElements = getCornerResizeHTML(onShowResizeHandle);
    const sideElements = getSideResizeHTML(onShowResizeHandle);
    const handles = [...cornerElements, ...sideElements]
        .map(element => {
            const handle = createElement(element, doc);
            Eif (isNodeOfType(handle, 'ELEMENT_NODE') && isElementOfType(handle, 'div')) {
                return handle;
            }
        })
        .filter(element => !!element) as HTMLDivElement[];
    return handles;
}
 
/**
 * @internal
 * Get HTML for resize handles at the corners
 */
function getCornerResizeHTML(onShowResizeHandle?: OnShowResizeHandle): CreateElementData[] {
    const result: CreateElementData[] = [];
 
    Xs.forEach(x =>
        Ys.forEach(y => {
            const elementData = (x == '') == (y == '') ? getResizeHandleHTML(x, y) : null;
            Iif (onShowResizeHandle && elementData) {
                onShowResizeHandle(elementData, x, y);
            }
            if (elementData) {
                result.push(elementData);
            }
        })
    );
    return result;
}
 
/**
 * @internal
 * Get HTML for resize handles on the sides
 */
function getSideResizeHTML(onShowResizeHandle?: OnShowResizeHandle): CreateElementData[] {
    const result: CreateElementData[] = [];
    Xs.forEach(x =>
        Ys.forEach(y => {
            const elementData = (x == '') != (y == '') ? getResizeHandleHTML(x, y) : null;
            Iif (onShowResizeHandle && elementData) {
                onShowResizeHandle(elementData, x, y);
            }
            if (elementData) {
                result.push(elementData);
            }
        })
    );
    return result;
}
 
const createHandleStyle = (direction: string, topOrBottom: string, leftOrRight: string) => {
    return `position:relative;width:${RESIZE_HANDLE_SIZE}px;height:${RESIZE_HANDLE_SIZE}px;background-color: #FFFFFF;cursor:${direction}-resize;${topOrBottom}:-${RESIZE_HANDLE_MARGIN}px;${leftOrRight}:-${RESIZE_HANDLE_MARGIN}px;border-radius:100%;border: 2px solid #bfbfbf;box-shadow: 0px 0.36316px 1.36185px rgba(100, 100, 100, 0.25);`;
};
 
function getResizeHandleHTML(x: DNDDirectionX, y: DnDDirectionY): CreateElementData | null {
    const leftOrRight = x == 'w' ? 'left' : 'right';
    const topOrBottom = y == 'n' ? 'top' : 'bottom';
    const leftOrRightValue = x == '' ? '50%' : '0px';
    const topOrBottomValue = y == '' ? '50%' : '0px';
    const direction = y + x;
    return x == '' && y == ''
        ? null
        : {
              tag: 'div',
              style: `position:absolute;${leftOrRight}:${leftOrRightValue};${topOrBottom}:${topOrBottomValue}`,
              children: [
                  {
                      tag: 'div',
                      style: createHandleStyle(direction, topOrBottom, leftOrRight),
                      className: ImageEditElementClass.ResizeHandle,
                      dataset: { x, y },
                  },
              ],
          };
}