123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import Command from './command'
- import history from '../history'
- import { Data, Shape } from 'types'
- import { deepClone } from 'utils'
- import tld from 'utils/tld'
- import { getShapeUtils } from 'state/shape-utils'
-
- export default function deleteSelected(data: Data): void {
- const selectedShapes = tld.getSelectedShapes(data)
-
- const selectedIdsArr = selectedShapes
- .filter((shape) => !shape.isLocked)
- .map((shape) => shape.id)
-
- const shapeIdsToDelete = selectedIdsArr.flatMap((id) =>
- tld.getDocumentBranch(data, id)
- )
-
- const remainingIds = selectedShapes
- .filter((shape) => shape.isLocked)
- .map((shape) => shape.id)
-
- let deletedShapes: Shape[] = []
-
- history.execute(
- data,
- new Command({
- name: 'delete_selection',
- category: 'canvas',
- manualSelection: true,
- do(data) {
- // Update selected ids
- tld.setSelectedIds(data, remainingIds)
-
- // Recursively delete shapes (and maybe their parents too)
- deletedShapes = deleteShapes(data, shapeIdsToDelete)
- },
- undo(data) {
- const page = tld.getPage(data)
-
- // Update selected ids
- tld.setSelectedIds(data, selectedIdsArr)
-
- // Restore deleted shapes
- deletedShapes.forEach((shape) => (page.shapes[shape.id] = shape))
-
- // Update parents
- deletedShapes.forEach((shape) => {
- if (shape.parentId === data.currentPageId) return
-
- const parent = page.shapes[shape.parentId]
-
- getShapeUtils(parent)
- .setProperty(parent, 'children', [...parent.children, shape.id])
- .onChildrenChange(
- parent,
- parent.children.map((id) => page.shapes[id])
- )
- })
- },
- })
- )
- }
-
- /** Recursively delete shapes and their parents */
-
- function deleteShapes(
- data: Data,
- shapeIds: string[],
- shapesDeleted: Shape[] = []
- ): Shape[] {
- const parentsToDelete: string[] = []
-
- const page = tld.getPage(data)
-
- const parentIds = new Set(shapeIds.map((id) => page.shapes[id].parentId))
-
- // Delete shapes
- shapeIds.forEach((id) => {
- shapesDeleted.push(deepClone(page.shapes[id]))
- delete page.shapes[id]
- })
-
- // Update parents
- parentIds.forEach((id) => {
- const parent = page.shapes[id]
-
- if (!parent || id === page.id) return
-
- getShapeUtils(parent)
- .setProperty(
- parent,
- 'children',
- parent.children.filter((childId) => !shapeIds.includes(childId))
- )
- .onChildrenChange(
- parent,
- parent.children.map((id) => page.shapes[id])
- )
-
- if (getShapeUtils(parent).shouldDelete(parent)) {
- parentsToDelete.push(parent.id)
- }
- })
-
- if (parentsToDelete.length > 0) {
- return deleteShapes(data, parentsToDelete, shapesDeleted)
- }
-
- return shapesDeleted
- }
|