chore: bump Prettier to the latest (#4185)
This commit is contained in:
parent
277ffaacb9
commit
1c7056bdaa
@ -69,7 +69,7 @@
|
|||||||
"jest-canvas-mock": "2.3.1",
|
"jest-canvas-mock": "2.3.1",
|
||||||
"lint-staged": "11.2.6",
|
"lint-staged": "11.2.6",
|
||||||
"pepjs": "0.5.3",
|
"pepjs": "0.5.3",
|
||||||
"prettier": "2.2.1",
|
"prettier": "2.4.1",
|
||||||
"rewire": "5.0.0"
|
"rewire": "5.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -110,10 +110,8 @@ export const actionDeleteSelected = register({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let { elements: nextElements, appState: nextAppState } =
|
||||||
elements: nextElements,
|
deleteSelectedElements(elements, appState);
|
||||||
appState: nextAppState,
|
|
||||||
} = deleteSelectedElements(elements, appState);
|
|
||||||
fixBindingsAfterDeletion(
|
fixBindingsAfterDeletion(
|
||||||
nextElements,
|
nextElements,
|
||||||
elements.filter(({ id }) => appState.selectedElementIds[id]),
|
elements.filter(({ id }) => appState.selectedElementIds[id]),
|
||||||
|
@ -19,11 +19,8 @@ export const actionFinalize = register({
|
|||||||
name: "finalize",
|
name: "finalize",
|
||||||
perform: (elements, appState, _, { canvas, focusContainer }) => {
|
perform: (elements, appState, _, { canvas, focusContainer }) => {
|
||||||
if (appState.editingLinearElement) {
|
if (appState.editingLinearElement) {
|
||||||
const {
|
const { elementId, startBindingElement, endBindingElement } =
|
||||||
elementId,
|
appState.editingLinearElement;
|
||||||
startBindingElement,
|
|
||||||
endBindingElement,
|
|
||||||
} = appState.editingLinearElement;
|
|
||||||
const element = LinearElementEditor.getElement(elementId);
|
const element = LinearElementEditor.getElement(elementId);
|
||||||
|
|
||||||
if (element) {
|
if (element) {
|
||||||
|
@ -99,9 +99,8 @@ export const actionGroup = register({
|
|||||||
// to the z order of the highest element in the layer stack
|
// to the z order of the highest element in the layer stack
|
||||||
const elementsInGroup = getElementsInGroup(updatedElements, newGroupId);
|
const elementsInGroup = getElementsInGroup(updatedElements, newGroupId);
|
||||||
const lastElementInGroup = elementsInGroup[elementsInGroup.length - 1];
|
const lastElementInGroup = elementsInGroup[elementsInGroup.length - 1];
|
||||||
const lastGroupElementIndex = updatedElements.lastIndexOf(
|
const lastGroupElementIndex =
|
||||||
lastElementInGroup,
|
updatedElements.lastIndexOf(lastElementInGroup);
|
||||||
);
|
|
||||||
const elementsAfterGroup = updatedElements.slice(lastGroupElementIndex + 1);
|
const elementsAfterGroup = updatedElements.slice(lastGroupElementIndex + 1);
|
||||||
const elementsBeforeGroup = updatedElements
|
const elementsBeforeGroup = updatedElements
|
||||||
.slice(0, lastGroupElementIndex)
|
.slice(0, lastGroupElementIndex)
|
||||||
|
@ -96,10 +96,9 @@ const APP_STATE_STORAGE_CONF = (<
|
|||||||
/** server (shareLink/collab/...) */
|
/** server (shareLink/collab/...) */
|
||||||
server: boolean;
|
server: boolean;
|
||||||
},
|
},
|
||||||
T extends Record<keyof AppState, Values>
|
T extends Record<keyof AppState, Values>,
|
||||||
>(
|
>(config: { [K in keyof T]: K extends keyof AppState ? T[K] : never }) =>
|
||||||
config: { [K in keyof T]: K extends keyof AppState ? T[K] : never },
|
config)({
|
||||||
) => config)({
|
|
||||||
theme: { browser: true, export: false, server: false },
|
theme: { browser: true, export: false, server: false },
|
||||||
collaborators: { browser: false, export: false, server: false },
|
collaborators: { browser: false, export: false, server: false },
|
||||||
currentChartType: { browser: true, export: false, server: false },
|
currentChartType: { browser: true, export: false, server: false },
|
||||||
@ -172,7 +171,7 @@ const APP_STATE_STORAGE_CONF = (<
|
|||||||
});
|
});
|
||||||
|
|
||||||
const _clearAppStateForStorage = <
|
const _clearAppStateForStorage = <
|
||||||
ExportType extends "export" | "browser" | "server"
|
ExportType extends "export" | "browser" | "server",
|
||||||
>(
|
>(
|
||||||
appState: Partial<AppState>,
|
appState: Partial<AppState>,
|
||||||
exportType: ExportType,
|
exportType: ExportType,
|
||||||
|
@ -794,7 +794,8 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public async componentDidMount() {
|
public async componentDidMount() {
|
||||||
this.excalidrawContainerValue.container = this.excalidrawContainerRef.current;
|
this.excalidrawContainerValue.container =
|
||||||
|
this.excalidrawContainerRef.current;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
process.env.NODE_ENV === ENV.TEST ||
|
process.env.NODE_ENV === ENV.TEST ||
|
||||||
@ -836,10 +837,8 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
this.resizeObserver = new ResizeObserver(() => {
|
this.resizeObserver = new ResizeObserver(() => {
|
||||||
// compute isMobile state
|
// compute isMobile state
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
const {
|
const { width, height } =
|
||||||
width,
|
this.excalidrawContainerRef.current!.getBoundingClientRect();
|
||||||
height,
|
|
||||||
} = this.excalidrawContainerRef.current!.getBoundingClientRect();
|
|
||||||
this.isMobile =
|
this.isMobile =
|
||||||
width < MQ_MAX_WIDTH_PORTRAIT ||
|
width < MQ_MAX_WIDTH_PORTRAIT ||
|
||||||
(height < MQ_MAX_HEIGHT_LANDSCAPE && width < MQ_MAX_WIDTH_LANDSCAPE);
|
(height < MQ_MAX_HEIGHT_LANDSCAPE && width < MQ_MAX_WIDTH_LANDSCAPE);
|
||||||
@ -1243,9 +1242,8 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
async (event: ClipboardEvent | null) => {
|
async (event: ClipboardEvent | null) => {
|
||||||
// #686
|
// #686
|
||||||
const target = document.activeElement;
|
const target = document.activeElement;
|
||||||
const isExcalidrawActive = this.excalidrawContainerRef.current?.contains(
|
const isExcalidrawActive =
|
||||||
target,
|
this.excalidrawContainerRef.current?.contains(target);
|
||||||
);
|
|
||||||
if (!isExcalidrawActive) {
|
if (!isExcalidrawActive) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2207,7 +2205,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
}));
|
}));
|
||||||
this.resetShouldCacheIgnoreZoomDebounced();
|
this.resetShouldCacheIgnoreZoomDebounced();
|
||||||
} else {
|
} else {
|
||||||
gesture.lastCenter = gesture.initialDistance = gesture.initialScale = null;
|
gesture.lastCenter =
|
||||||
|
gesture.initialDistance =
|
||||||
|
gesture.initialScale =
|
||||||
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHoldingSpace || isPanning || isDraggingScrollBar) {
|
if (isHoldingSpace || isPanning || isDraggingScrollBar) {
|
||||||
@ -2516,13 +2517,11 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const onPointerMove = this.onPointerMoveFromPointerDownHandler(
|
const onPointerMove =
|
||||||
pointerDownState,
|
this.onPointerMoveFromPointerDownHandler(pointerDownState);
|
||||||
);
|
|
||||||
|
|
||||||
const onPointerUp = this.onPointerUpFromPointerDownHandler(
|
const onPointerUp =
|
||||||
pointerDownState,
|
this.onPointerUpFromPointerDownHandler(pointerDownState);
|
||||||
);
|
|
||||||
|
|
||||||
const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);
|
const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);
|
||||||
const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);
|
const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);
|
||||||
@ -2727,10 +2726,11 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
allHitElements: [],
|
allHitElements: [],
|
||||||
wasAddedToSelection: false,
|
wasAddedToSelection: false,
|
||||||
hasBeenDuplicated: false,
|
hasBeenDuplicated: false,
|
||||||
hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(
|
hasHitCommonBoundingBoxOfSelectedElements:
|
||||||
origin,
|
this.isHittingCommonBoundingBoxOfSelectedElements(
|
||||||
selectedElements,
|
origin,
|
||||||
),
|
selectedElements,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
drag: {
|
drag: {
|
||||||
hasOccurred: false,
|
hasOccurred: false,
|
||||||
@ -2807,14 +2807,15 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
const elements = this.scene.getElements();
|
const elements = this.scene.getElements();
|
||||||
const selectedElements = getSelectedElements(elements, this.state);
|
const selectedElements = getSelectedElements(elements, this.state);
|
||||||
if (selectedElements.length === 1 && !this.state.editingLinearElement) {
|
if (selectedElements.length === 1 && !this.state.editingLinearElement) {
|
||||||
const elementWithTransformHandleType = getElementWithTransformHandleType(
|
const elementWithTransformHandleType =
|
||||||
elements,
|
getElementWithTransformHandleType(
|
||||||
this.state,
|
elements,
|
||||||
pointerDownState.origin.x,
|
this.state,
|
||||||
pointerDownState.origin.y,
|
pointerDownState.origin.x,
|
||||||
this.state.zoom,
|
pointerDownState.origin.y,
|
||||||
event.pointerType,
|
this.state.zoom,
|
||||||
);
|
event.pointerType,
|
||||||
|
);
|
||||||
if (elementWithTransformHandleType != null) {
|
if (elementWithTransformHandleType != null) {
|
||||||
this.setState({
|
this.setState({
|
||||||
resizingElement: elementWithTransformHandleType.element,
|
resizingElement: elementWithTransformHandleType.element,
|
||||||
@ -2890,9 +2891,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const hitElement = pointerDownState.hit.element;
|
const hitElement = pointerDownState.hit.element;
|
||||||
const someHitElementIsSelected = pointerDownState.hit.allHitElements.some(
|
const someHitElementIsSelected =
|
||||||
(element) => this.isASelectedElement(element),
|
pointerDownState.hit.allHitElements.some((element) =>
|
||||||
);
|
this.isASelectedElement(element),
|
||||||
|
);
|
||||||
if (
|
if (
|
||||||
(hitElement === null || !someHitElementIsSelected) &&
|
(hitElement === null || !someHitElementIsSelected) &&
|
||||||
!event.shiftKey &&
|
!event.shiftKey &&
|
||||||
@ -3554,8 +3556,8 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
? {
|
? {
|
||||||
// if using ctrl/cmd, select the hitElement only if we
|
// if using ctrl/cmd, select the hitElement only if we
|
||||||
// haven't box-selected anything else
|
// haven't box-selected anything else
|
||||||
[pointerDownState.hit.element
|
[pointerDownState.hit.element.id]:
|
||||||
.id]: !elementsWithinSelection.length,
|
!elementsWithinSelection.length,
|
||||||
}
|
}
|
||||||
: null),
|
: null),
|
||||||
},
|
},
|
||||||
@ -4429,7 +4431,9 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
// This will only work as of Chrome 86,
|
// This will only work as of Chrome 86,
|
||||||
// but can be safely ignored on older releases.
|
// but can be safely ignored on older releases.
|
||||||
const item = event.dataTransfer.items[0];
|
const item = event.dataTransfer.items[0];
|
||||||
(file as any).handle = await (item as any).getAsFileSystemHandle();
|
(file as any).handle = await (
|
||||||
|
item as any
|
||||||
|
).getAsFileSystemHandle();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.warn(error.name, error.message);
|
console.warn(error.name, error.message);
|
||||||
}
|
}
|
||||||
@ -4551,10 +4555,8 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
const type = element ? "element" : "canvas";
|
const type = element ? "element" : "canvas";
|
||||||
|
|
||||||
const container = this.excalidrawContainerRef.current!;
|
const container = this.excalidrawContainerRef.current!;
|
||||||
const {
|
const { top: offsetTop, left: offsetLeft } =
|
||||||
top: offsetTop,
|
container.getBoundingClientRect();
|
||||||
left: offsetLeft,
|
|
||||||
} = container.getBoundingClientRect();
|
|
||||||
const left = event.clientX - offsetLeft;
|
const left = event.clientX - offsetLeft;
|
||||||
const top = event.clientY - offsetTop;
|
const top = event.clientY - offsetTop;
|
||||||
|
|
||||||
|
@ -13,9 +13,11 @@ export const CheckboxItem: React.FC<{
|
|||||||
className={clsx("Checkbox", { "is-checked": checked })}
|
className={clsx("Checkbox", { "is-checked": checked })}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
onChange(!checked);
|
onChange(!checked);
|
||||||
((event.currentTarget as HTMLDivElement).querySelector(
|
(
|
||||||
".Checkbox-box",
|
(event.currentTarget as HTMLDivElement).querySelector(
|
||||||
) as HTMLButtonElement).focus();
|
".Checkbox-box",
|
||||||
|
) as HTMLButtonElement
|
||||||
|
).focus();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button className="Checkbox-box" role="checkbox" aria-checked={checked}>
|
<button className="Checkbox-box" role="checkbox" aria-checked={checked}>
|
||||||
|
@ -426,34 +426,34 @@ const LayerUI = ({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const createExporter = (type: ExportType): ExportCB => async (
|
const createExporter =
|
||||||
exportedElements,
|
(type: ExportType): ExportCB =>
|
||||||
) => {
|
async (exportedElements) => {
|
||||||
const fileHandle = await exportCanvas(
|
const fileHandle = await exportCanvas(
|
||||||
type,
|
type,
|
||||||
exportedElements,
|
exportedElements,
|
||||||
appState,
|
appState,
|
||||||
files,
|
files,
|
||||||
{
|
{
|
||||||
exportBackground: appState.exportBackground,
|
exportBackground: appState.exportBackground,
|
||||||
name: appState.name,
|
name: appState.name,
|
||||||
viewBackgroundColor: appState.viewBackgroundColor,
|
viewBackgroundColor: appState.viewBackgroundColor,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.catch(muteFSAbortError)
|
.catch(muteFSAbortError)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
setAppState({ errorMessage: error.message });
|
setAppState({ errorMessage: error.message });
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
if (
|
||||||
appState.exportEmbedScene &&
|
appState.exportEmbedScene &&
|
||||||
fileHandle &&
|
fileHandle &&
|
||||||
isImageFileHandle(fileHandle)
|
isImageFileHandle(fileHandle)
|
||||||
) {
|
) {
|
||||||
setAppState({ fileHandle });
|
setAppState({ fileHandle });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ImageExportDialog
|
<ImageExportDialog
|
||||||
@ -709,7 +709,8 @@ const LayerUI = ({
|
|||||||
{!viewModeEnabled && (
|
{!viewModeEnabled && (
|
||||||
<div
|
<div
|
||||||
className={clsx("undo-redo-buttons zen-mode-transition", {
|
className={clsx("undo-redo-buttons zen-mode-transition", {
|
||||||
"layer-ui__wrapper__footer-left--transition-bottom": zenModeEnabled,
|
"layer-ui__wrapper__footer-left--transition-bottom":
|
||||||
|
zenModeEnabled,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{actionManager.renderAction("undo", { size: "small" })}
|
{actionManager.renderAction("undo", { size: "small" })}
|
||||||
@ -723,7 +724,8 @@ const LayerUI = ({
|
|||||||
className={clsx(
|
className={clsx(
|
||||||
"layer-ui__wrapper__footer-center zen-mode-transition",
|
"layer-ui__wrapper__footer-center zen-mode-transition",
|
||||||
{
|
{
|
||||||
"layer-ui__wrapper__footer-left--transition-bottom": zenModeEnabled,
|
"layer-ui__wrapper__footer-left--transition-bottom":
|
||||||
|
zenModeEnabled,
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
@ -34,10 +34,8 @@ const updateTooltip = (
|
|||||||
width: itemWidth,
|
width: itemWidth,
|
||||||
} = item.getBoundingClientRect();
|
} = item.getBoundingClientRect();
|
||||||
|
|
||||||
const {
|
const { width: labelWidth, height: labelHeight } =
|
||||||
width: labelWidth,
|
tooltip.getBoundingClientRect();
|
||||||
height: labelHeight,
|
|
||||||
} = tooltip.getBoundingClientRect();
|
|
||||||
|
|
||||||
const viewportWidth = window.innerWidth;
|
const viewportWidth = window.innerWidth;
|
||||||
const viewportHeight = window.innerHeight;
|
const viewportHeight = window.innerHeight;
|
||||||
|
@ -30,8 +30,12 @@ export const createIcon = (
|
|||||||
d: string | React.ReactNode,
|
d: string | React.ReactNode,
|
||||||
opts: number | Opts = 512,
|
opts: number | Opts = 512,
|
||||||
) => {
|
) => {
|
||||||
const { width = 512, height = width, mirror, style } =
|
const {
|
||||||
typeof opts === "number" ? ({ width: opts } as Opts) : opts;
|
width = 512,
|
||||||
|
height = width,
|
||||||
|
mirror,
|
||||||
|
style,
|
||||||
|
} = typeof opts === "number" ? ({ width: opts } as Opts) : opts;
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
@ -59,7 +59,7 @@ const getFontFamilyByName = (fontFamilyName: string): FontFamilyValues => {
|
|||||||
|
|
||||||
const restoreElementWithProperties = <
|
const restoreElementWithProperties = <
|
||||||
T extends ExcalidrawElement,
|
T extends ExcalidrawElement,
|
||||||
K extends Pick<T, keyof Omit<Required<T>, keyof ExcalidrawElement>>
|
K extends Pick<T, keyof Omit<Required<T>, keyof ExcalidrawElement>>,
|
||||||
>(
|
>(
|
||||||
element: Required<T>,
|
element: Required<T>,
|
||||||
extra: Pick<
|
extra: Pick<
|
||||||
@ -98,11 +98,11 @@ const restoreElementWithProperties = <
|
|||||||
boundElementIds: element.boundElementIds ?? [],
|
boundElementIds: element.boundElementIds ?? [],
|
||||||
};
|
};
|
||||||
|
|
||||||
return ({
|
return {
|
||||||
...base,
|
...base,
|
||||||
...getNormalizedDimensions(base),
|
...getNormalizedDimensions(base),
|
||||||
...extra,
|
...extra,
|
||||||
} as unknown) as T;
|
} as unknown as T;
|
||||||
};
|
};
|
||||||
|
|
||||||
const restoreElement = (
|
const restoreElement = (
|
||||||
@ -113,10 +113,9 @@ const restoreElement = (
|
|||||||
let fontSize = element.fontSize;
|
let fontSize = element.fontSize;
|
||||||
let fontFamily = element.fontFamily;
|
let fontFamily = element.fontFamily;
|
||||||
if ("font" in element) {
|
if ("font" in element) {
|
||||||
const [fontPx, _fontFamily]: [
|
const [fontPx, _fontFamily]: [string, string] = (
|
||||||
string,
|
element as any
|
||||||
string,
|
).font.split(" ");
|
||||||
] = (element as any).font.split(" ");
|
|
||||||
fontSize = parseInt(fontPx, 10);
|
fontSize = parseInt(fontPx, 10);
|
||||||
fontFamily = getFontFamilyByName(_fontFamily);
|
fontFamily = getFontFamilyByName(_fontFamily);
|
||||||
}
|
}
|
||||||
|
@ -137,14 +137,13 @@ export const bindOrUnbindSelectedElements = (
|
|||||||
const maybeBindBindableElement = (
|
const maybeBindBindableElement = (
|
||||||
bindableElement: NonDeleted<ExcalidrawBindableElement>,
|
bindableElement: NonDeleted<ExcalidrawBindableElement>,
|
||||||
): void => {
|
): void => {
|
||||||
getElligibleElementsForBindableElementAndWhere(
|
getElligibleElementsForBindableElementAndWhere(bindableElement).forEach(
|
||||||
bindableElement,
|
([linearElement, where]) =>
|
||||||
).forEach(([linearElement, where]) =>
|
bindOrUnbindLinearElement(
|
||||||
bindOrUnbindLinearElement(
|
linearElement,
|
||||||
linearElement,
|
where === "end" ? "keep" : bindableElement,
|
||||||
where === "end" ? "keep" : bindableElement,
|
where === "start" ? "keep" : bindableElement,
|
||||||
where === "start" ? "keep" : bindableElement,
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -293,9 +292,11 @@ export const updateBoundElements = (
|
|||||||
const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(
|
const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(
|
||||||
simultaneouslyUpdated,
|
simultaneouslyUpdated,
|
||||||
);
|
);
|
||||||
(Scene.getScene(changedElement)!.getNonDeletedElements(
|
(
|
||||||
boundElementIds,
|
Scene.getScene(changedElement)!.getNonDeletedElements(
|
||||||
) as NonDeleted<ExcalidrawLinearElement>[]).forEach((linearElement) => {
|
boundElementIds,
|
||||||
|
) as NonDeleted<ExcalidrawLinearElement>[]
|
||||||
|
).forEach((linearElement) => {
|
||||||
const bindableElement = changedElement as ExcalidrawBindableElement;
|
const bindableElement = changedElement as ExcalidrawBindableElement;
|
||||||
// In case the boundElementIds are stale
|
// In case the boundElementIds are stale
|
||||||
if (!doesNeedUpdate(linearElement, bindableElement)) {
|
if (!doesNeedUpdate(linearElement, bindableElement)) {
|
||||||
@ -580,9 +581,11 @@ export const fixBindingsAfterDuplication = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Update the linear elements
|
// Update the linear elements
|
||||||
(sceneElements.filter(({ id }) =>
|
(
|
||||||
allBoundElementIds.has(id),
|
sceneElements.filter(({ id }) =>
|
||||||
) as ExcalidrawLinearElement[]).forEach((element) => {
|
allBoundElementIds.has(id),
|
||||||
|
) as ExcalidrawLinearElement[]
|
||||||
|
).forEach((element) => {
|
||||||
const { startBinding, endBinding } = element;
|
const { startBinding, endBinding } = element;
|
||||||
mutateElement(element, {
|
mutateElement(element, {
|
||||||
startBinding: newBindingAfterDuplication(
|
startBinding: newBindingAfterDuplication(
|
||||||
@ -642,17 +645,17 @@ export const fixBindingsAfterDeletion = (
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
(sceneElements.filter(({ id }) =>
|
(
|
||||||
boundElementIds.has(id),
|
sceneElements.filter(({ id }) =>
|
||||||
) as ExcalidrawLinearElement[]).forEach(
|
boundElementIds.has(id),
|
||||||
(element: ExcalidrawLinearElement) => {
|
) as ExcalidrawLinearElement[]
|
||||||
const { startBinding, endBinding } = element;
|
).forEach((element: ExcalidrawLinearElement) => {
|
||||||
mutateElement(element, {
|
const { startBinding, endBinding } = element;
|
||||||
startBinding: newBindingAfterDeletion(startBinding, deletedElementIds),
|
mutateElement(element, {
|
||||||
endBinding: newBindingAfterDeletion(endBinding, deletedElementIds),
|
startBinding: newBindingAfterDeletion(startBinding, deletedElementIds),
|
||||||
});
|
endBinding: newBindingAfterDeletion(endBinding, deletedElementIds),
|
||||||
},
|
});
|
||||||
);
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const newBindingAfterDeletion = (
|
const newBindingAfterDeletion = (
|
||||||
|
@ -78,7 +78,7 @@ const getMinMaxXYFromCurvePathOps = (
|
|||||||
// move, bcurveTo, lineTo, and curveTo
|
// move, bcurveTo, lineTo, and curveTo
|
||||||
if (op === "move") {
|
if (op === "move") {
|
||||||
// change starting point
|
// change starting point
|
||||||
currentP = (data as unknown) as Point;
|
currentP = data as unknown as Point;
|
||||||
// move operation does not draw anything; so, it always
|
// move operation does not draw anything; so, it always
|
||||||
// returns false
|
// returns false
|
||||||
} else if (op === "bcurveTo") {
|
} else if (op === "bcurveTo") {
|
||||||
@ -227,7 +227,7 @@ export const getArrowheadPoints = (
|
|||||||
const prevOp = ops[index - 1];
|
const prevOp = ops[index - 1];
|
||||||
let p0: Point = [0, 0];
|
let p0: Point = [0, 0];
|
||||||
if (prevOp.op === "move") {
|
if (prevOp.op === "move") {
|
||||||
p0 = (prevOp.data as unknown) as Point;
|
p0 = prevOp.data as unknown as Point;
|
||||||
} else if (prevOp.op === "bcurveTo") {
|
} else if (prevOp.op === "bcurveTo") {
|
||||||
p0 = [prevOp.data[4], prevOp.data[5]];
|
p0 = [prevOp.data[4], prevOp.data[5]];
|
||||||
}
|
}
|
||||||
|
@ -866,7 +866,7 @@ const hitTestRoughShape = (
|
|||||||
// move, bcurveTo, lineTo, and curveTo
|
// move, bcurveTo, lineTo, and curveTo
|
||||||
if (op === "move") {
|
if (op === "move") {
|
||||||
// change starting point
|
// change starting point
|
||||||
currentP = (data as unknown) as Point;
|
currentP = data as unknown as Point;
|
||||||
// move operation does not draw anything; so, it always
|
// move operation does not draw anything; so, it always
|
||||||
// returns false
|
// returns false
|
||||||
} else if (op === "bcurveTo") {
|
} else if (op === "bcurveTo") {
|
||||||
|
@ -150,9 +150,8 @@ export class LinearElementEditor {
|
|||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
binding = {
|
binding = {
|
||||||
[activePointIndex === 0
|
[activePointIndex === 0 ? "startBindingElement" : "endBindingElement"]:
|
||||||
? "startBindingElement"
|
bindingElement,
|
||||||
: "endBindingElement"]: bindingElement,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@ -236,10 +235,8 @@ export class LinearElementEditor {
|
|||||||
// from the end points of the `linearElement` - this is to allow disabling
|
// from the end points of the `linearElement` - this is to allow disabling
|
||||||
// binding (which needs to happen at the point the user finishes moving
|
// binding (which needs to happen at the point the user finishes moving
|
||||||
// the point).
|
// the point).
|
||||||
const {
|
const { startBindingElement, endBindingElement } =
|
||||||
startBindingElement,
|
appState.editingLinearElement;
|
||||||
endBindingElement,
|
|
||||||
} = appState.editingLinearElement;
|
|
||||||
if (isBindingEnabled(appState) && isBindingElement(element)) {
|
if (isBindingEnabled(appState) && isBindingElement(element)) {
|
||||||
bindOrUnbindLinearElement(
|
bindOrUnbindLinearElement(
|
||||||
element,
|
element,
|
||||||
|
@ -464,16 +464,12 @@ export const resizeSingleElement = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const [
|
const [newBoundsX1, newBoundsY1, newBoundsX2, newBoundsY2] =
|
||||||
newBoundsX1,
|
getResizedElementAbsoluteCoords(
|
||||||
newBoundsY1,
|
stateAtResizeStart,
|
||||||
newBoundsX2,
|
eleNewWidth,
|
||||||
newBoundsY2,
|
eleNewHeight,
|
||||||
] = getResizedElementAbsoluteCoords(
|
);
|
||||||
stateAtResizeStart,
|
|
||||||
eleNewWidth,
|
|
||||||
eleNewHeight,
|
|
||||||
);
|
|
||||||
const newBoundsWidth = newBoundsX2 - newBoundsX1;
|
const newBoundsWidth = newBoundsX2 - newBoundsX1;
|
||||||
const newBoundsHeight = newBoundsY2 - newBoundsY1;
|
const newBoundsHeight = newBoundsY2 - newBoundsY1;
|
||||||
|
|
||||||
|
@ -36,10 +36,8 @@ export const resizeTest = (
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { rotation: rotationTransformHandle, ...transformHandles } =
|
||||||
rotation: rotationTransformHandle,
|
getTransformHandles(element, zoom, pointerType);
|
||||||
...transformHandles
|
|
||||||
} = getTransformHandles(element, zoom, pointerType);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
rotationTransformHandle &&
|
rotationTransformHandle &&
|
||||||
@ -49,9 +47,8 @@ export const resizeTest = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const filter = Object.keys(transformHandles).filter((key) => {
|
const filter = Object.keys(transformHandles).filter((key) => {
|
||||||
const transformHandle = transformHandles[
|
const transformHandle =
|
||||||
key as Exclude<TransformHandleType, "rotation">
|
transformHandles[key as Exclude<TransformHandleType, "rotation">]!;
|
||||||
]!;
|
|
||||||
if (!transformHandle) {
|
if (!transformHandle) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -105,9 +102,8 @@ export const getTransformHandleTypeFromCoords = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
const found = Object.keys(transformHandles).find((key) => {
|
const found = Object.keys(transformHandles).find((key) => {
|
||||||
const transformHandle = transformHandles[
|
const transformHandle =
|
||||||
key as Exclude<TransformHandleType, "rotation">
|
transformHandles[key as Exclude<TransformHandleType, "rotation">]!;
|
||||||
]!;
|
|
||||||
return (
|
return (
|
||||||
transformHandle &&
|
transformHandle &&
|
||||||
isInsideTransformHandle(transformHandle, scenePointerX, scenePointerY)
|
isInsideTransformHandle(transformHandle, scenePointerX, scenePointerY)
|
||||||
|
@ -17,9 +17,9 @@ export type TransformHandleDirection =
|
|||||||
export type TransformHandleType = TransformHandleDirection | "rotation";
|
export type TransformHandleType = TransformHandleDirection | "rotation";
|
||||||
|
|
||||||
export type TransformHandle = [number, number, number, number];
|
export type TransformHandle = [number, number, number, number];
|
||||||
export type TransformHandles = Partial<
|
export type TransformHandles = Partial<{
|
||||||
{ [T in TransformHandleType]: TransformHandle }
|
[T in TransformHandleType]: TransformHandle;
|
||||||
>;
|
}>;
|
||||||
export type MaybeTransformHandleType = TransformHandleType | false;
|
export type MaybeTransformHandleType = TransformHandleType | false;
|
||||||
|
|
||||||
const transformHandleSizes: { [k in PointerType]: number } = {
|
const transformHandleSizes: { [k in PointerType]: number } = {
|
||||||
|
@ -419,12 +419,8 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "MOUSE_LOCATION": {
|
case "MOUSE_LOCATION": {
|
||||||
const {
|
const { pointer, button, username, selectedElementIds } =
|
||||||
pointer,
|
decryptedData.payload;
|
||||||
button,
|
|
||||||
username,
|
|
||||||
selectedElementIds,
|
|
||||||
} = decryptedData.payload;
|
|
||||||
const socketId: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["socketId"] =
|
const socketId: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["socketId"] =
|
||||||
decryptedData.payload.socketId ||
|
decryptedData.payload.socketId ||
|
||||||
// @ts-ignore legacy, see #2094 (#2097)
|
// @ts-ignore legacy, see #2094 (#2097)
|
||||||
@ -503,12 +499,10 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private loadImageFiles = throttle(async () => {
|
private loadImageFiles = throttle(async () => {
|
||||||
const {
|
const { loadedFiles, erroredFiles } =
|
||||||
loadedFiles,
|
await this.fetchImageFilesFromFirebase({
|
||||||
erroredFiles,
|
elements: this.excalidrawAPI.getSceneElementsIncludingDeleted(),
|
||||||
} = await this.fetchImageFilesFromFirebase({
|
});
|
||||||
elements: this.excalidrawAPI.getSceneElementsIncludingDeleted(),
|
|
||||||
});
|
|
||||||
|
|
||||||
this.excalidrawAPI.addFiles(loadedFiles);
|
this.excalidrawAPI.addFiles(loadedFiles);
|
||||||
|
|
||||||
@ -591,9 +585,8 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
|
|||||||
|
|
||||||
setCollaborators(sockets: string[]) {
|
setCollaborators(sockets: string[]) {
|
||||||
this.setState((state) => {
|
this.setState((state) => {
|
||||||
const collaborators: InstanceType<
|
const collaborators: InstanceType<typeof CollabWrapper>["collaborators"] =
|
||||||
typeof CollabWrapper
|
new Map();
|
||||||
>["collaborators"] = new Map();
|
|
||||||
for (const socketId of sockets) {
|
for (const socketId of sockets) {
|
||||||
if (this.collaborators.has(socketId)) {
|
if (this.collaborators.has(socketId)) {
|
||||||
collaborators.set(socketId, this.collaborators.get(socketId)!);
|
collaborators.set(socketId, this.collaborators.get(socketId)!);
|
||||||
@ -695,7 +688,8 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
|
|||||||
this.contextValue.initializeSocketClient = this.initializeSocketClient;
|
this.contextValue.initializeSocketClient = this.initializeSocketClient;
|
||||||
this.contextValue.onCollabButtonClick = this.onCollabButtonClick;
|
this.contextValue.onCollabButtonClick = this.onCollabButtonClick;
|
||||||
this.contextValue.broadcastElements = this.broadcastElements;
|
this.contextValue.broadcastElements = this.broadcastElements;
|
||||||
this.contextValue.fetchImageFilesFromFirebase = this.fetchImageFilesFromFirebase;
|
this.contextValue.fetchImageFilesFromFirebase =
|
||||||
|
this.fetchImageFilesFromFirebase;
|
||||||
return this.contextValue;
|
return this.contextValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -210,8 +210,8 @@ class Portal {
|
|||||||
socketId: this.socket.id,
|
socketId: this.socket.id,
|
||||||
pointer: payload.pointer,
|
pointer: payload.pointer,
|
||||||
button: payload.button || "up",
|
button: payload.button || "up",
|
||||||
selectedElementIds: this.collab.excalidrawAPI.getAppState()
|
selectedElementIds:
|
||||||
.selectedElementIds,
|
this.collab.excalidrawAPI.getAppState().selectedElementIds,
|
||||||
username: this.collab.state.username,
|
username: this.collab.state.username,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -54,9 +54,8 @@ export const reconcileElements = (
|
|||||||
remoteElements: readonly BroadcastedExcalidrawElement[],
|
remoteElements: readonly BroadcastedExcalidrawElement[],
|
||||||
localAppState: AppState,
|
localAppState: AppState,
|
||||||
): ReconciledElements => {
|
): ReconciledElements => {
|
||||||
const localElementsData = getElementsMapWithIndex<ExcalidrawElement>(
|
const localElementsData =
|
||||||
localElements,
|
getElementsMapWithIndex<ExcalidrawElement>(localElements);
|
||||||
);
|
|
||||||
|
|
||||||
const reconciledElements: ExcalidrawElement[] = localElements.slice();
|
const reconciledElements: ExcalidrawElement[] = localElements.slice();
|
||||||
|
|
||||||
|
@ -14,9 +14,8 @@ export const GitHubCorner = React.memo(
|
|||||||
className="rtl-mirror"
|
className="rtl-mirror"
|
||||||
style={{
|
style={{
|
||||||
marginTop: "calc(var(--space-factor) * -1)",
|
marginTop: "calc(var(--space-factor) * -1)",
|
||||||
[dir === "rtl"
|
[dir === "rtl" ? "marginLeft" : "marginRight"]:
|
||||||
? "marginLeft"
|
"calc(var(--space-factor) * -1)",
|
||||||
: "marginRight"]: "calc(var(--space-factor) * -1)",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
|
@ -31,15 +31,11 @@ export class FileManager {
|
|||||||
getFiles,
|
getFiles,
|
||||||
saveFiles,
|
saveFiles,
|
||||||
}: {
|
}: {
|
||||||
getFiles: (
|
getFiles: (fileIds: FileId[]) => Promise<{
|
||||||
fileIds: FileId[],
|
|
||||||
) => Promise<{
|
|
||||||
loadedFiles: BinaryFileData[];
|
loadedFiles: BinaryFileData[];
|
||||||
erroredFiles: Map<FileId, true>;
|
erroredFiles: Map<FileId, true>;
|
||||||
}>;
|
}>;
|
||||||
saveFiles: (data: {
|
saveFiles: (data: { addedFiles: Map<FileId, BinaryFileData> }) => Promise<{
|
||||||
addedFiles: Map<FileId, BinaryFileData>;
|
|
||||||
}) => Promise<{
|
|
||||||
savedFiles: Map<FileId, true>;
|
savedFiles: Map<FileId, true>;
|
||||||
erroredFiles: Map<FileId, true>;
|
erroredFiles: Map<FileId, true>;
|
||||||
}>;
|
}>;
|
||||||
|
@ -13,9 +13,8 @@ import { MIME_TYPES } from "../../constants";
|
|||||||
|
|
||||||
const FIREBASE_CONFIG = JSON.parse(process.env.REACT_APP_FIREBASE_CONFIG);
|
const FIREBASE_CONFIG = JSON.parse(process.env.REACT_APP_FIREBASE_CONFIG);
|
||||||
|
|
||||||
let firebasePromise: Promise<
|
let firebasePromise: Promise<typeof import("firebase/app").default> | null =
|
||||||
typeof import("firebase/app").default
|
null;
|
||||||
> | null = null;
|
|
||||||
let firestorePromise: Promise<any> | null | true = null;
|
let firestorePromise: Promise<any> | null | true = null;
|
||||||
let firebaseStoragePromise: Promise<any> | null | true = null;
|
let firebaseStoragePromise: Promise<any> | null | true = null;
|
||||||
|
|
||||||
|
@ -78,9 +78,10 @@ export type SocketUpdateDataIncoming =
|
|||||||
type: "INVALID_RESPONSE";
|
type: "INVALID_RESPONSE";
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SocketUpdateData = SocketUpdateDataSource[keyof SocketUpdateDataSource] & {
|
export type SocketUpdateData =
|
||||||
_brand: "socketUpdateData";
|
SocketUpdateDataSource[keyof SocketUpdateDataSource] & {
|
||||||
};
|
_brand: "socketUpdateData";
|
||||||
|
};
|
||||||
|
|
||||||
export const encryptAESGEM = async (
|
export const encryptAESGEM = async (
|
||||||
data: Uint8Array,
|
data: Uint8Array,
|
||||||
|
@ -286,7 +286,8 @@ const ExcalidrawWrapper = () => {
|
|||||||
promise: ResolvablePromise<ImportedDataState | null>;
|
promise: ResolvablePromise<ImportedDataState | null>;
|
||||||
}>({ promise: null! });
|
}>({ promise: null! });
|
||||||
if (!initialStatePromiseRef.current.promise) {
|
if (!initialStatePromiseRef.current.promise) {
|
||||||
initialStatePromiseRef.current.promise = resolvablePromise<ImportedDataState | null>();
|
initialStatePromiseRef.current.promise =
|
||||||
|
resolvablePromise<ImportedDataState | null>();
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -296,10 +297,8 @@ const ExcalidrawWrapper = () => {
|
|||||||
}, VERSION_TIMEOUT);
|
}, VERSION_TIMEOUT);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [
|
const [excalidrawAPI, excalidrawRefCallback] =
|
||||||
excalidrawAPI,
|
useCallbackRefState<ExcalidrawImperativeAPI>();
|
||||||
excalidrawRefCallback,
|
|
||||||
] = useCallbackRefState<ExcalidrawImperativeAPI>();
|
|
||||||
|
|
||||||
const collabAPI = useContext(CollabContext)?.api;
|
const collabAPI = useContext(CollabContext)?.api;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ export const nvector = (value: number = 0, index: number = 0): NVector => {
|
|||||||
if (value !== 0) {
|
if (value !== 0) {
|
||||||
result[index] = value;
|
result[index] = value;
|
||||||
}
|
}
|
||||||
return (result as unknown) as NVector;
|
return result as unknown as NVector;
|
||||||
};
|
};
|
||||||
|
|
||||||
const STRING_EPSILON = 0.000001;
|
const STRING_EPSILON = 0.000001;
|
||||||
|
@ -36,7 +36,7 @@ export const orthogonalThrough = (against: Point, intersection: Point): Line =>
|
|||||||
export const parallel = (line: Line, distance: number): Line => {
|
export const parallel = (line: Line, distance: number): Line => {
|
||||||
const result = line.slice();
|
const result = line.slice();
|
||||||
result[1] -= distance;
|
result[1] -= distance;
|
||||||
return (result as unknown) as Line;
|
return result as unknown as Line;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parallelThrough = (line: Line, point: Point): Line =>
|
export const parallelThrough = (line: Line, point: Point): Line =>
|
||||||
|
7
src/global.d.ts
vendored
7
src/global.d.ts
vendored
@ -49,8 +49,7 @@ type MarkRequired<T, RK extends keyof T> = Exclude<T, RK> &
|
|||||||
|
|
||||||
type MarkNonNullable<T, K extends keyof T> = {
|
type MarkNonNullable<T, K extends keyof T> = {
|
||||||
[P in K]-?: P extends K ? NonNullable<T[P]> : T[P];
|
[P in K]-?: P extends K ? NonNullable<T[P]> : T[P];
|
||||||
} &
|
} & { [P in keyof T]: T[P] };
|
||||||
{ [P in keyof T]: T[P] };
|
|
||||||
|
|
||||||
// PNG encoding/decoding
|
// PNG encoding/decoding
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -102,10 +101,10 @@ declare module "*.scss";
|
|||||||
// (due to TS structural typing)
|
// (due to TS structural typing)
|
||||||
// https://github.com/microsoft/TypeScript/issues/31311#issuecomment-490690695
|
// https://github.com/microsoft/TypeScript/issues/31311#issuecomment-490690695
|
||||||
interface ArrayBuffer {
|
interface ArrayBuffer {
|
||||||
private _brand?: "ArrayBuffer";
|
_brand?: "ArrayBuffer";
|
||||||
}
|
}
|
||||||
interface Uint8Array {
|
interface Uint8Array {
|
||||||
private _brand?: "Uint8Array";
|
_brand?: "Uint8Array";
|
||||||
}
|
}
|
||||||
// --------------------------------------------------------------------------—
|
// --------------------------------------------------------------------------—
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const TerserPlugin = require("terser-webpack-plugin");
|
const TerserPlugin = require("terser-webpack-plugin");
|
||||||
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
|
const BundleAnalyzerPlugin =
|
||||||
.BundleAnalyzerPlugin;
|
require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
|
||||||
const autoprefixer = require("autoprefixer");
|
const autoprefixer = require("autoprefixer");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const webpack = require("webpack");
|
const webpack = require("webpack");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
|
const BundleAnalyzerPlugin =
|
||||||
.BundleAnalyzerPlugin;
|
require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "production",
|
mode: "production",
|
||||||
|
@ -398,16 +398,8 @@ const generateElementShape = (
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "diamond": {
|
case "diamond": {
|
||||||
const [
|
const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] =
|
||||||
topX,
|
getDiamondPoints(element);
|
||||||
topY,
|
|
||||||
rightX,
|
|
||||||
rightY,
|
|
||||||
bottomX,
|
|
||||||
bottomY,
|
|
||||||
leftX,
|
|
||||||
leftY,
|
|
||||||
] = getDiamondPoints(element);
|
|
||||||
shape = generator.polygon(
|
shape = generator.polygon(
|
||||||
[
|
[
|
||||||
[topX, topY],
|
[topX, topY],
|
||||||
|
@ -336,12 +336,8 @@ export const renderScene = (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (selectionColors.length) {
|
if (selectionColors.length) {
|
||||||
const [
|
const [elementX1, elementY1, elementX2, elementY2] =
|
||||||
elementX1,
|
getElementAbsoluteCoords(element);
|
||||||
elementY1,
|
|
||||||
elementX2,
|
|
||||||
elementY2,
|
|
||||||
] = getElementAbsoluteCoords(element);
|
|
||||||
acc.push({
|
acc.push({
|
||||||
angle: element.angle,
|
angle: element.angle,
|
||||||
elementX1,
|
elementX1,
|
||||||
@ -356,9 +352,8 @@ export const renderScene = (
|
|||||||
|
|
||||||
const addSelectionForGroupId = (groupId: GroupId) => {
|
const addSelectionForGroupId = (groupId: GroupId) => {
|
||||||
const groupElements = getElementsInGroup(elements, groupId);
|
const groupElements = getElementsInGroup(elements, groupId);
|
||||||
const [elementX1, elementY1, elementX2, elementY2] = getCommonBounds(
|
const [elementX1, elementY1, elementX2, elementY2] =
|
||||||
groupElements,
|
getCommonBounds(groupElements);
|
||||||
);
|
|
||||||
selections.push({
|
selections.push({
|
||||||
angle: 0,
|
angle: 0,
|
||||||
elementX1,
|
elementX1,
|
||||||
@ -630,14 +625,8 @@ const renderSelectionBorder = (
|
|||||||
selectionColors: string[];
|
selectionColors: string[];
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
const {
|
const { angle, elementX1, elementY1, elementX2, elementY2, selectionColors } =
|
||||||
angle,
|
elementProperties;
|
||||||
elementX1,
|
|
||||||
elementY1,
|
|
||||||
elementX2,
|
|
||||||
elementY2,
|
|
||||||
selectionColors,
|
|
||||||
} = elementProperties;
|
|
||||||
const elementWidth = elementX2 - elementX1;
|
const elementWidth = elementX2 - elementX1;
|
||||||
const elementHeight = elementY2 - elementY1;
|
const elementHeight = elementY2 - elementY1;
|
||||||
|
|
||||||
|
@ -180,10 +180,9 @@ export const getExportSize = (
|
|||||||
exportPadding: number,
|
exportPadding: number,
|
||||||
scale: number,
|
scale: number,
|
||||||
): [number, number] => {
|
): [number, number] => {
|
||||||
const [, , width, height] = getCanvasSize(
|
const [, , width, height] = getCanvasSize(elements, exportPadding).map(
|
||||||
elements,
|
(dimension) => Math.trunc(dimension * scale),
|
||||||
exportPadding,
|
);
|
||||||
).map((dimension) => Math.trunc(dimension * scale));
|
|
||||||
|
|
||||||
return [width, height];
|
return [width, height];
|
||||||
};
|
};
|
||||||
|
@ -30,12 +30,8 @@ export const getScrollBars = (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
// This is the bounding box of all the elements
|
// This is the bounding box of all the elements
|
||||||
const [
|
const [elementsMinX, elementsMinY, elementsMaxX, elementsMaxY] =
|
||||||
elementsMinX,
|
getCommonBounds(elements);
|
||||||
elementsMinY,
|
|
||||||
elementsMaxX,
|
|
||||||
elementsMaxY,
|
|
||||||
] = getCommonBounds(elements);
|
|
||||||
|
|
||||||
// Apply zoom
|
// Apply zoom
|
||||||
const viewportWidthWithZoom = viewportWidth / zoom.value;
|
const viewportWidthWithZoom = viewportWidth / zoom.value;
|
||||||
|
@ -9,16 +9,11 @@ export const getElementsWithinSelection = (
|
|||||||
elements: readonly NonDeletedExcalidrawElement[],
|
elements: readonly NonDeletedExcalidrawElement[],
|
||||||
selection: NonDeletedExcalidrawElement,
|
selection: NonDeletedExcalidrawElement,
|
||||||
) => {
|
) => {
|
||||||
const [
|
const [selectionX1, selectionY1, selectionX2, selectionY2] =
|
||||||
selectionX1,
|
getElementAbsoluteCoords(selection);
|
||||||
selectionY1,
|
|
||||||
selectionX2,
|
|
||||||
selectionY2,
|
|
||||||
] = getElementAbsoluteCoords(selection);
|
|
||||||
return elements.filter((element) => {
|
return elements.filter((element) => {
|
||||||
const [elementX1, elementY1, elementX2, elementY2] = getElementBounds(
|
const [elementX1, elementY1, elementX2, elementY2] =
|
||||||
element,
|
getElementBounds(element);
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
element.type !== "selection" &&
|
element.type !== "selection" &&
|
||||||
|
@ -91,9 +91,8 @@ describe("contextMenu element", () => {
|
|||||||
clientY: 1,
|
clientY: 1,
|
||||||
});
|
});
|
||||||
const contextMenu = queryContextMenu();
|
const contextMenu = queryContextMenu();
|
||||||
const contextMenuOptions = contextMenu?.querySelectorAll(
|
const contextMenuOptions =
|
||||||
".context-menu li",
|
contextMenu?.querySelectorAll(".context-menu li");
|
||||||
);
|
|
||||||
const expectedShortcutNames: ShortcutName[] = [
|
const expectedShortcutNames: ShortcutName[] = [
|
||||||
"selectAll",
|
"selectAll",
|
||||||
"gridMode",
|
"gridMode",
|
||||||
@ -122,9 +121,8 @@ describe("contextMenu element", () => {
|
|||||||
clientY: 1,
|
clientY: 1,
|
||||||
});
|
});
|
||||||
const contextMenu = queryContextMenu();
|
const contextMenu = queryContextMenu();
|
||||||
const contextMenuOptions = contextMenu?.querySelectorAll(
|
const contextMenuOptions =
|
||||||
".context-menu li",
|
contextMenu?.querySelectorAll(".context-menu li");
|
||||||
);
|
|
||||||
const expectedShortcutNames: ShortcutName[] = [
|
const expectedShortcutNames: ShortcutName[] = [
|
||||||
"copyStyles",
|
"copyStyles",
|
||||||
"pasteStyles",
|
"pasteStyles",
|
||||||
@ -210,9 +208,8 @@ describe("contextMenu element", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const contextMenu = queryContextMenu();
|
const contextMenu = queryContextMenu();
|
||||||
const contextMenuOptions = contextMenu?.querySelectorAll(
|
const contextMenuOptions =
|
||||||
".context-menu li",
|
contextMenu?.querySelectorAll(".context-menu li");
|
||||||
);
|
|
||||||
const expectedShortcutNames: ShortcutName[] = [
|
const expectedShortcutNames: ShortcutName[] = [
|
||||||
"copyStyles",
|
"copyStyles",
|
||||||
"pasteStyles",
|
"pasteStyles",
|
||||||
@ -261,9 +258,8 @@ describe("contextMenu element", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const contextMenu = queryContextMenu();
|
const contextMenu = queryContextMenu();
|
||||||
const contextMenuOptions = contextMenu?.querySelectorAll(
|
const contextMenuOptions =
|
||||||
".context-menu li",
|
contextMenu?.querySelectorAll(".context-menu li");
|
||||||
);
|
|
||||||
const expectedShortcutNames: ShortcutName[] = [
|
const expectedShortcutNames: ShortcutName[] = [
|
||||||
"copyStyles",
|
"copyStyles",
|
||||||
"pasteStyles",
|
"pasteStyles",
|
||||||
|
@ -57,7 +57,7 @@ export class API {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static createElement = <
|
static createElement = <
|
||||||
T extends Exclude<ExcalidrawElement["type"], "selection">
|
T extends Exclude<ExcalidrawElement["type"], "selection">,
|
||||||
>({
|
>({
|
||||||
type,
|
type,
|
||||||
id,
|
id,
|
||||||
|
@ -75,10 +75,10 @@ const test = <U extends `${string}:${"L" | "R"}`>(
|
|||||||
const cache: Cache = {};
|
const cache: Cache = {};
|
||||||
const _local = idsToElements(local, cache);
|
const _local = idsToElements(local, cache);
|
||||||
const _remote = idsToElements(remote, cache);
|
const _remote = idsToElements(remote, cache);
|
||||||
const _target = (target.map((uid) => {
|
const _target = target.map((uid) => {
|
||||||
const [, id, source] = uid.match(/^(\w+):([LR])$/)!;
|
const [, id, source] = uid.match(/^(\w+):([LR])$/)!;
|
||||||
return (source === "L" ? _local : _remote).find((e) => e.id === id)!;
|
return (source === "L" ? _local : _remote).find((e) => e.id === id)!;
|
||||||
}) as any) as ReconciledElements;
|
}) as any as ReconciledElements;
|
||||||
const remoteReconciled = reconcileElements(_local, _remote, {} as AppState);
|
const remoteReconciled = reconcileElements(_local, _remote, {} as AppState);
|
||||||
expect(cleanElements(remoteReconciled)).deep.equal(
|
expect(cleanElements(remoteReconciled)).deep.equal(
|
||||||
cleanElements(_target),
|
cleanElements(_target),
|
||||||
|
@ -874,14 +874,10 @@ describe("regression tests", () => {
|
|||||||
|
|
||||||
expect(API.getSelectedElements().length).toBe(2);
|
expect(API.getSelectedElements().length).toBe(2);
|
||||||
|
|
||||||
const {
|
const { x: firstElementPrevX, y: firstElementPrevY } =
|
||||||
x: firstElementPrevX,
|
API.getSelectedElements()[0];
|
||||||
y: firstElementPrevY,
|
const { x: secondElementPrevX, y: secondElementPrevY } =
|
||||||
} = API.getSelectedElements()[0];
|
API.getSelectedElements()[1];
|
||||||
const {
|
|
||||||
x: secondElementPrevX,
|
|
||||||
y: secondElementPrevY,
|
|
||||||
} = API.getSelectedElements()[1];
|
|
||||||
|
|
||||||
// drag elements from point on common bounding box that doesn't hit any of the elements
|
// drag elements from point on common bounding box that doesn't hit any of the elements
|
||||||
mouse.reset();
|
mouse.reset();
|
||||||
|
@ -126,7 +126,8 @@ export const mockBoundingClientRect = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const restoreOriginalGetBoundingClientRect = () => {
|
export const restoreOriginalGetBoundingClientRect = () => {
|
||||||
global.window.HTMLDivElement.prototype.getBoundingClientRect = originalGetBoundingClientRect;
|
global.window.HTMLDivElement.prototype.getBoundingClientRect =
|
||||||
|
originalGetBoundingClientRect;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const assertSelectedElements = (
|
export const assertSelectedElements = (
|
||||||
|
@ -360,7 +360,7 @@ export const resolvablePromise = <T>() => {
|
|||||||
* @param func handler taking at most single parameter (event).
|
* @param func handler taking at most single parameter (event).
|
||||||
*/
|
*/
|
||||||
export const withBatchedUpdates = <
|
export const withBatchedUpdates = <
|
||||||
TFunction extends ((event: any) => void) | (() => void)
|
TFunction extends ((event: any) => void) | (() => void),
|
||||||
>(
|
>(
|
||||||
func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never,
|
func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never,
|
||||||
) =>
|
) =>
|
||||||
|
@ -11783,10 +11783,10 @@ prettier-linter-helpers@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
fast-diff "^1.1.2"
|
fast-diff "^1.1.2"
|
||||||
|
|
||||||
prettier@2.2.1:
|
prettier@2.4.1:
|
||||||
version "2.2.1"
|
version "2.4.1"
|
||||||
resolved "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
|
||||||
integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==
|
integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
|
||||||
|
|
||||||
pretty-bytes@^5.3.0:
|
pretty-bytes@^5.3.0:
|
||||||
version "5.6.0"
|
version "5.6.0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user