diff --git a/src/element/resizeTest.ts b/src/element/resizeTest.ts index 51ecf7ef8..b82e5cadb 100644 --- a/src/element/resizeTest.ts +++ b/src/element/resizeTest.ts @@ -34,7 +34,7 @@ export function resizeTest( } export function getElementWithResizeHandler( - elements: ExcalidrawElement[], + elements: readonly ExcalidrawElement[], { x, y }: { x: number; y: number }, { scrollX, scrollY }: SceneScroll ) { diff --git a/src/history.ts b/src/history.ts index 6b93e92ac..514421848 100644 --- a/src/history.ts +++ b/src/history.ts @@ -5,7 +5,7 @@ class SceneHistory { private stateHistory: string[] = []; private redoStack: string[] = []; - generateCurrentEntry(elements: ExcalidrawElement[]) { + generateCurrentEntry(elements: readonly ExcalidrawElement[]) { return JSON.stringify( elements.map(element => ({ ...element, isSelected: false })) ); @@ -37,7 +37,7 @@ class SceneHistory { this.redoStack.splice(0, this.redoStack.length); } - redoOnce(elements: ExcalidrawElement[]) { + redoOnce(elements: readonly ExcalidrawElement[]) { const currentEntry = this.generateCurrentEntry(elements); const entryToRestore = this.redoStack.pop(); if (entryToRestore !== undefined) { @@ -48,7 +48,7 @@ class SceneHistory { return null; } - undoOnce(elements: ExcalidrawElement[]) { + undoOnce(elements: readonly ExcalidrawElement[]) { const currentEntry = this.generateCurrentEntry(elements); let entryToRestore = this.stateHistory.pop(); diff --git a/src/index.tsx b/src/index.tsx index 81fde87eb..65f3a87e2 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -157,7 +157,7 @@ export class App extends React.Component<{}, AppState> { if (isInputLike(event.target)) return; if (event.key === KEYS.ESCAPE) { - elements = clearSelection([...elements]); + elements = clearSelection(elements); this.forceUpdate(); event.preventDefault(); } else if (event.key === KEYS.BACKSPACE || event.key === KEYS.DELETE) { @@ -416,7 +416,7 @@ export class App extends React.Component<{}, AppState> { activeTool={this.state.elementType} onToolChange={value => { this.setState({ elementType: value }); - elements = clearSelection([...elements]); + elements = clearSelection(elements); document.documentElement.style.cursor = value === "text" ? "text" : "crosshair"; this.forceUpdate(); @@ -670,7 +670,7 @@ export class App extends React.Component<{}, AppState> { } if (!element.isSelected) { - elements = clearSelection([...elements]); + elements = clearSelection(elements); element.isSelected = true; this.forceUpdate(); } @@ -772,7 +772,7 @@ export class App extends React.Component<{}, AppState> { } else { // We unselect every other elements unless shift is pressed if (!e.shiftKey) { - elements = clearSelection([...elements]); + elements = clearSelection(elements); } } // No matter what, we select it @@ -783,7 +783,9 @@ export class App extends React.Component<{}, AppState> { ...elements, ...elements.reduce((duplicates, element) => { if (element.isSelected) { - duplicates.push(duplicateElement(element)); + duplicates = duplicates.concat( + duplicateElement(element) + ); element.isSelected = false; } return duplicates; @@ -792,7 +794,7 @@ export class App extends React.Component<{}, AppState> { } } else { // If we don't click on anything, let's remove all the selected elements - elements = clearSelection([...elements]); + elements = clearSelection(elements); } isDraggingElements = someElementIsSelected(elements); @@ -991,7 +993,7 @@ export class App extends React.Component<{}, AppState> { : height; if (this.state.elementType === "selection") { - elements = setSelection([...elements], draggingElement); + elements = setSelection(elements, draggingElement); } // We don't want to save history when moving an element history.skipRecording(); @@ -1009,7 +1011,7 @@ export class App extends React.Component<{}, AppState> { // if no element is clicked, clear the selection and redraw if (draggingElement === null) { - elements = clearSelection([...elements]); + elements = clearSelection(elements); this.forceUpdate(); return; } @@ -1061,7 +1063,9 @@ export class App extends React.Component<{}, AppState> { let textY = e.clientY; if (elementAtPosition && isTextElement(elementAtPosition)) { - elements.splice(elements.indexOf(elementAtPosition), 1); + elements = elements.filter( + element => element !== elementAtPosition + ); this.forceUpdate(); Object.assign(element, elementAtPosition); @@ -1165,7 +1169,7 @@ export class App extends React.Component<{}, AppState> { parsedElements.length > 0 && parsedElements[0].type // need to implement a better check here... ) { - elements = clearSelection([...elements]); + elements = clearSelection(elements); if (x == null) x = 10 - this.state.scrollX; if (y == null) y = 10 - this.state.scrollY; diff --git a/src/renderer/renderScene.ts b/src/renderer/renderScene.ts index 0901d47d2..e5753f369 100644 --- a/src/renderer/renderScene.ts +++ b/src/renderer/renderScene.ts @@ -14,7 +14,7 @@ import { import { renderElement } from "./renderElement"; export function renderScene( - elements: ExcalidrawElement[], + elements: readonly ExcalidrawElement[], rc: RoughCanvas, canvas: HTMLCanvasElement, sceneState: SceneState, diff --git a/src/scene/comparisons.ts b/src/scene/comparisons.ts index 30418a93b..62b4b5df0 100644 --- a/src/scene/comparisons.ts +++ b/src/scene/comparisons.ts @@ -2,7 +2,7 @@ import { ExcalidrawElement } from "../element/types"; import { hitTest } from "../element/collision"; import { getElementAbsoluteCoords } from "../element"; -export const hasBackground = (elements: ExcalidrawElement[]) => +export const hasBackground = (elements: readonly ExcalidrawElement[]) => elements.some( element => element.isSelected && @@ -11,7 +11,7 @@ export const hasBackground = (elements: ExcalidrawElement[]) => element.type === "diamond") ); -export const hasStroke = (elements: ExcalidrawElement[]) => +export const hasStroke = (elements: readonly ExcalidrawElement[]) => elements.some( element => element.isSelected && @@ -21,11 +21,11 @@ export const hasStroke = (elements: ExcalidrawElement[]) => element.type === "arrow") ); -export const hasText = (elements: ExcalidrawElement[]) => +export const hasText = (elements: readonly ExcalidrawElement[]) => elements.some(element => element.isSelected && element.type === "text"); export function getElementAtPosition( - elements: ExcalidrawElement[], + elements: readonly ExcalidrawElement[], x: number, y: number ) { @@ -42,7 +42,7 @@ export function getElementAtPosition( } export function getElementContainingPosition( - elements: ExcalidrawElement[], + elements: readonly ExcalidrawElement[], x: number, y: number ) { diff --git a/src/scene/createScene.ts b/src/scene/createScene.ts index fb697ec0a..004760296 100644 --- a/src/scene/createScene.ts +++ b/src/scene/createScene.ts @@ -1,6 +1,6 @@ import { ExcalidrawElement } from "../element/types"; export const createScene = () => { - const elements = Array.of(); + const elements: readonly ExcalidrawElement[] = []; return { elements }; }; diff --git a/src/scene/data.ts b/src/scene/data.ts index 89993358d..16309e8f3 100644 --- a/src/scene/data.ts +++ b/src/scene/data.ts @@ -23,11 +23,14 @@ function saveFile(name: string, data: string) { } interface DataState { - elements: ExcalidrawElement[]; + elements: readonly ExcalidrawElement[]; appState: any; } -export function saveAsJSON(elements: ExcalidrawElement[], name: string) { +export function saveAsJSON( + elements: readonly ExcalidrawElement[], + name: string +) { const serialized = JSON.stringify({ version: 1, source: window.location.origin, @@ -74,7 +77,7 @@ export function loadFromJSON() { } export function exportAsPNG( - elements: ExcalidrawElement[], + elements: readonly ExcalidrawElement[], canvas: HTMLCanvasElement, { exportBackground, @@ -140,7 +143,7 @@ export function exportAsPNG( } function restore( - savedElements: ExcalidrawElement[], + savedElements: readonly ExcalidrawElement[], savedState: any ): DataState { return { @@ -185,7 +188,7 @@ export function restoreFromLocalStorage() { } export function saveToLocalStorage( - elements: ExcalidrawElement[], + elements: readonly ExcalidrawElement[], state: AppState ) { localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(elements)); diff --git a/src/scene/scrollbars.ts b/src/scene/scrollbars.ts index fbd77fb00..0c0043ce2 100644 --- a/src/scene/scrollbars.ts +++ b/src/scene/scrollbars.ts @@ -7,7 +7,7 @@ export const SCROLLBAR_WIDTH = 6; export const SCROLLBAR_COLOR = "rgba(0,0,0,0.3)"; export function getScrollBars( - elements: ExcalidrawElement[], + elements: readonly ExcalidrawElement[], canvasWidth: number, canvasHeight: number, scrollX: number, @@ -76,7 +76,7 @@ export function getScrollBars( } export function isOverScrollBars( - elements: ExcalidrawElement[], + elements: readonly ExcalidrawElement[], x: number, y: number, canvasWidth: number, diff --git a/src/scene/selection.ts b/src/scene/selection.ts index 640d63542..ad11eb356 100644 --- a/src/scene/selection.ts +++ b/src/scene/selection.ts @@ -2,7 +2,7 @@ import { ExcalidrawElement } from "../element/types"; import { getElementAbsoluteCoords } from "../element"; export function setSelection( - elements: ExcalidrawElement[], + elements: readonly ExcalidrawElement[], selection: ExcalidrawElement ) { const [ @@ -29,7 +29,7 @@ export function setSelection( return elements; } -export function clearSelection(elements: ExcalidrawElement[]) { +export function clearSelection(elements: readonly ExcalidrawElement[]) { elements.forEach(element => { element.isSelected = false; }); @@ -37,11 +37,11 @@ export function clearSelection(elements: ExcalidrawElement[]) { return elements; } -export function deleteSelectedElements(elements: ExcalidrawElement[]) { +export function deleteSelectedElements(elements: readonly ExcalidrawElement[]) { return elements.filter(el => !el.isSelected); } -export function getSelectedIndices(elements: ExcalidrawElement[]) { +export function getSelectedIndices(elements: readonly ExcalidrawElement[]) { const selectedIndices: number[] = []; elements.forEach((element, index) => { if (element.isSelected) { @@ -51,11 +51,11 @@ export function getSelectedIndices(elements: ExcalidrawElement[]) { return selectedIndices; } -export const someElementIsSelected = (elements: ExcalidrawElement[]) => +export const someElementIsSelected = (elements: readonly ExcalidrawElement[]) => elements.some(element => element.isSelected); export function getSelectedAttribute( - elements: ExcalidrawElement[], + elements: readonly ExcalidrawElement[], getAttribute: (element: ExcalidrawElement) => T ): T | null { const attributes = Array.from(