diff --git a/packages/editor/src/lib/editor/Editor.ts b/packages/editor/src/lib/editor/Editor.ts index 0f28bcbaa..24813f927 100644 --- a/packages/editor/src/lib/editor/Editor.ts +++ b/packages/editor/src/lib/editor/Editor.ts @@ -36,7 +36,6 @@ import { createShapeId, getShapePropKeysByStyle, isPageId, - isShape, isShapeId, } from '@tldraw/tlschema' import { @@ -4575,31 +4574,31 @@ export class Editor extends EventEmitter { * @public */ @computed getCurrentPageShapesSorted(): TLShape[] { - // todo: consider making into a function call that includes options for selected-only, rendering, etc. - // todo: consider making a derivation or something, or merging with rendering shapes - const shapes = new Set(this.getCurrentPageShapes().sort(sortByIndex)) + const shapes = this.getCurrentPageShapes().sort(sortByIndex) + const parentChildMap = new Map() + const result: TLShape[] = [] + const topLevelShapes: TLShape[] = [] + let shape: TLShape, parent: TLShape | undefined - const results: TLShape[] = [] - - function pushShapeWithDescendants(shape: TLShape): void { - results.push(shape) - shapes.delete(shape) - - shapes.forEach((otherShape) => { - if (otherShape.parentId === shape.id) { - pushShapeWithDescendants(otherShape) + for (let i = 0, n = shapes.length; i < n; i++) { + shape = shapes[i] + parent = this.getShape(shape.parentId) + if (parent) { + if (!parentChildMap.has(parent.id)) { + parentChildMap.set(parent.id, []) } - }) + parentChildMap.get(parent.id)!.push(shape) + } else { + // undefined if parent is a shape + topLevelShapes.push(shape) + } } - shapes.forEach((shape) => { - const parent = this.getShape(shape.parentId) - if (!isShape(parent)) { - pushShapeWithDescendants(shape) - } - }) + for (let i = 0, n = topLevelShapes.length; i < n; i++) { + pushShapeWithDescendants(topLevelShapes[i], parentChildMap, result) + } - return results + return result } /** @@ -8884,3 +8883,17 @@ function applyPartialToShape(prev: T, partial?: TLShapePartia if (!next) return prev return next } + +function pushShapeWithDescendants( + shape: TLShape, + parentChildMap: Map, + result: TLShape[] +): void { + result.push(shape) + const children = parentChildMap.get(shape.id) + if (children) { + for (let i = 0, n = children.length; i < n; i++) { + pushShapeWithDescendants(children[i], parentChildMap, result) + } + } +}