Rename shapes apis (#1787)

This PR updates APIs related to shapes in the Editor.

- removes the requirement for an `id` when creating shapes
- `shapesOnCurrentPage` -> `currentPageShapes`
- `findAncestor` -> `findShapeAncestor`
- `findCommonAncestor` -> `findCommonShapeAncestor`
- Adds `getCurrentPageShapeIds`
- `getAncestors` -> `getShapeAncestors`
- `getClipPath` -> `getShapeClipPath`
- `getGeometry` -> `getShapeGeometry`
- `getHandles` -> `getShapeHandles`
- `getTransform` -> `getShapeLocalTransform`
- `getPageTransform` -> `getShapePageTransform`
- `getOutlineSegments` -> `getShapeOutlineSegments`
- `getPageBounds` -> `getShapePageBounds`
- `getPageTransform` -> `getShapePageTransform`
- `getParentTransform` -> `getShapeParentTransform`
- `selectionBounds` -> `selectionRotatedPageBounds`

### Change Type

- [x] `major` — Breaking change

### Test Plan

- [x] Unit Tests
This commit is contained in:
Steve Ruiz 2023-08-02 19:12:25 +01:00 committed by GitHub
parent 39dbbca90e
commit bf27743595
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
104 changed files with 1151 additions and 1115 deletions

View file

@ -10,7 +10,7 @@ export function sleep(ms: number) {
// } // }
// export async function expectToHaveNShapes(page: Page, numberOfShapes: number) { // export async function expectToHaveNShapes(page: Page, numberOfShapes: number) {
// expect(await page.evaluate(() => editor.shapesOnCurrentPage.length)).toBe(numberOfShapes) // expect(await page.evaluate(() => editor.currentPageShapes.length)).toBe(numberOfShapes)
// } // }
// export async function expectToHaveNSelectedShapes(page: Page, numberOfSelectedShapes: number) { // export async function expectToHaveNSelectedShapes(page: Page, numberOfSelectedShapes: number) {

View file

@ -23,7 +23,7 @@ test.describe.skip('clipboard tests', () => {
await page.mouse.down() await page.mouse.down()
await page.mouse.up() await page.mouse.up()
expect(await page.evaluate(() => editor.shapesOnCurrentPage.length)).toBe(1) expect(await page.evaluate(() => editor.currentPageShapes.length)).toBe(1)
expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1) expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1)
await page.keyboard.down('Control') await page.keyboard.down('Control')
@ -32,7 +32,7 @@ test.describe.skip('clipboard tests', () => {
await page.keyboard.press('KeyV') await page.keyboard.press('KeyV')
await page.keyboard.up('Control') await page.keyboard.up('Control')
expect(await page.evaluate(() => editor.shapesOnCurrentPage.length)).toBe(2) expect(await page.evaluate(() => editor.currentPageShapes.length)).toBe(2)
expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1) expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1)
}) })
@ -42,7 +42,7 @@ test.describe.skip('clipboard tests', () => {
await page.mouse.down() await page.mouse.down()
await page.mouse.up() await page.mouse.up()
expect(await page.evaluate(() => editor.shapesOnCurrentPage.length)).toBe(1) expect(await page.evaluate(() => editor.currentPageShapes.length)).toBe(1)
expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1) expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1)
await page.getByTestId('main.menu').click() await page.getByTestId('main.menu').click()
@ -53,7 +53,7 @@ test.describe.skip('clipboard tests', () => {
await page.getByTestId('menu-item.edit').click() await page.getByTestId('menu-item.edit').click()
await page.getByTestId('menu-item.paste').click() await page.getByTestId('menu-item.paste').click()
expect(await page.evaluate(() => editor.shapesOnCurrentPage.length)).toBe(2) expect(await page.evaluate(() => editor.currentPageShapes.length)).toBe(2)
expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1) expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1)
}) })
@ -63,7 +63,7 @@ test.describe.skip('clipboard tests', () => {
await page.mouse.down() await page.mouse.down()
await page.mouse.up() await page.mouse.up()
expect(await page.evaluate(() => editor.shapesOnCurrentPage.length)).toBe(1) expect(await page.evaluate(() => editor.currentPageShapes.length)).toBe(1)
expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1) expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1)
await page.mouse.click(100, 100, { button: 'right' }) await page.mouse.click(100, 100, { button: 'right' })
@ -73,7 +73,7 @@ test.describe.skip('clipboard tests', () => {
await page.mouse.click(100, 100, { button: 'right' }) await page.mouse.click(100, 100, { button: 'right' })
await page.getByTestId('menu-item.paste').click() await page.getByTestId('menu-item.paste').click()
expect(await page.evaluate(() => editor.shapesOnCurrentPage.length)).toBe(2) expect(await page.evaluate(() => editor.currentPageShapes.length)).toBe(2)
expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1) expect(await page.evaluate(() => editor.selectedShapes.length)).toBe(1)
}) })
}) })

View file

@ -46,7 +46,7 @@ export class CardShapeUtil extends ShapeUtil<ICardShape> {
// Render method — the React component that will be rendered for the shape // Render method — the React component that will be rendered for the shape
component(shape: ICardShape) { component(shape: ICardShape) {
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode }) const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode })
// Unfortunately eslint will think this is a class components // Unfortunately eslint will think this is a class components

View file

@ -55,7 +55,7 @@ export class CardShapeUtil extends BaseBoxShapeUtil<CardShape> {
} }
component(shape: CardShape) { component(shape: CardShape) {
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode }) const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode })
return ( return (

View file

@ -539,14 +539,14 @@ export class Editor extends EventEmitter<TLEventMap> {
ease?: (t: number) => number; ease?: (t: number) => number;
}): this; }): this;
animateToShape(shapeId: TLShapeId, opts?: TLAnimationOptions): this; animateToShape(shapeId: TLShapeId, opts?: TLAnimationOptions): this;
animateToUser(userId: string): void; animateToUser(userId: string): this;
// @internal (undocumented) // @internal (undocumented)
annotateError(error: unknown, { origin, willCrashApp, tags, extras, }: { annotateError(error: unknown, { origin, willCrashApp, tags, extras, }: {
origin: string; origin: string;
willCrashApp: boolean; willCrashApp: boolean;
tags?: Record<string, boolean | number | string>; tags?: Record<string, boolean | number | string>;
extras?: Record<string, unknown>; extras?: Record<string, unknown>;
}): void; }): this;
get assets(): (TLBookmarkAsset | TLImageAsset | TLVideoAsset)[]; get assets(): (TLBookmarkAsset | TLImageAsset | TLVideoAsset)[];
bail(): this; bail(): this;
bailToMark(id: string): this; bailToMark(id: string): this;
@ -570,10 +570,9 @@ export class Editor extends EventEmitter<TLEventMap> {
centerOnPoint(point: VecLike, animation?: TLAnimationOptions): this; centerOnPoint(point: VecLike, animation?: TLAnimationOptions): this;
// @internal // @internal
protected _clickManager: ClickManager; protected _clickManager: ClickManager;
get commonBoundsOfAllShapesOnCurrentPage(): Box2d | undefined;
complete(): this; complete(): this;
// @internal (undocumented) // @internal (undocumented)
crash(error: unknown): void; crash(error: unknown): this;
// @internal // @internal
get crashingError(): unknown; get crashingError(): unknown;
createAssets(assets: TLAsset[]): this; createAssets(assets: TLAsset[]): this;
@ -591,11 +590,15 @@ export class Editor extends EventEmitter<TLEventMap> {
}; };
}; };
createPage(title: string, id?: TLPageId, belowPageIndex?: string): this; createPage(title: string, id?: TLPageId, belowPageIndex?: string): this;
createShape<T extends TLUnknownShape>(partial: TLShapePartial<T>, select?: boolean): this; createShape<T extends TLUnknownShape>(partial: OptionalKeys<TLShapePartial<T>, 'id'>): this;
createShapes<T extends TLUnknownShape>(partials: TLShapePartial<T>[], select?: boolean): this; createShapes<T extends TLUnknownShape>(partials: OptionalKeys<TLShapePartial<T>, 'id'>[]): this;
get croppingShapeId(): null | TLShapeId; get croppingShapeId(): null | TLShapeId;
get currentPage(): TLPage; get currentPage(): TLPage;
get currentPageBounds(): Box2d | undefined;
get currentPageId(): TLPageId; get currentPageId(): TLPageId;
get currentPageShapeIds(): Set<TLShapeId>;
get currentPageShapes(): TLShape[];
get currentPageShapesSorted(): TLShape[];
get currentPageState(): TLInstancePageState; get currentPageState(): TLInstancePageState;
get currentTool(): StateNode | undefined; get currentTool(): StateNode | undefined;
get currentToolId(): string; get currentToolId(): string;
@ -648,12 +651,12 @@ export class Editor extends EventEmitter<TLEventMap> {
}) => void) | null; }) => void) | null;
}[K]; }[K];
}; };
findAncestor(shape: TLShape, predicate: (parent: TLShape) => boolean): TLShape | undefined;
// (undocumented)
findAncestor(id: TLShapeId, predicate: (parent: TLShape) => boolean): TLShape | undefined;
findCommonAncestor(shapes: TLShape[], predicate?: (shape: TLShape) => boolean): TLShapeId | undefined; findCommonAncestor(shapes: TLShape[], predicate?: (shape: TLShape) => boolean): TLShapeId | undefined;
// (undocumented) // (undocumented)
findCommonAncestor(ids: TLShapeId[], predicate?: (shape: TLShape) => boolean): TLShapeId | undefined; findCommonAncestor(ids: TLShapeId[], predicate?: (shape: TLShape) => boolean): TLShapeId | undefined;
findShapeAncestor(shape: TLShape, predicate: (parent: TLShape) => boolean): TLShape | undefined;
// (undocumented)
findShapeAncestor(id: TLShapeId, predicate: (parent: TLShape) => boolean): TLShape | undefined;
flipShapes(shapes: TLShape[], operation: 'horizontal' | 'vertical'): this; flipShapes(shapes: TLShape[], operation: 'horizontal' | 'vertical'): this;
// (undocumented) // (undocumented)
flipShapes(ids: TLShapeId[], operation: 'horizontal' | 'vertical'): this; flipShapes(ids: TLShapeId[], operation: 'horizontal' | 'vertical'): this;
@ -663,9 +666,6 @@ export class Editor extends EventEmitter<TLEventMap> {
getAncestorPageId(shape?: TLShape): TLPageId | undefined; getAncestorPageId(shape?: TLShape): TLPageId | undefined;
// (undocumented) // (undocumented)
getAncestorPageId(shapeId?: TLShapeId): TLPageId | undefined; getAncestorPageId(shapeId?: TLShapeId): TLPageId | undefined;
getAncestors(shape: TLShape, acc?: TLShape[]): TLShape[];
// (undocumented)
getAncestors(id: TLShapeId, acc?: TLShape[]): TLShape[];
// (undocumented) // (undocumented)
getArrowInfo(shape: TLArrowShape): ArrowInfo | undefined; getArrowInfo(shape: TLArrowShape): ArrowInfo | undefined;
getArrowsBoundTo(shapeId: TLShapeId): { getArrowsBoundTo(shapeId: TLShapeId): {
@ -676,51 +676,24 @@ export class Editor extends EventEmitter<TLEventMap> {
// (undocumented) // (undocumented)
getAsset(id: TLAssetId): TLAsset | undefined; getAsset(id: TLAssetId): TLAsset | undefined;
getAssetForExternalContent(info: TLExternalAssetContent_2): Promise<TLAsset | undefined>; getAssetForExternalContent(info: TLExternalAssetContent_2): Promise<TLAsset | undefined>;
getClipPath(shape: TLShape): string | undefined;
// (undocumented)
getClipPath(id: TLShapeId): string | undefined;
getContainer: () => HTMLElement; getContainer: () => HTMLElement;
getContent(ids: TLShapeId[]): TLContent | undefined; getContent(ids: TLShapeId[]): TLContent | undefined;
// (undocumented) // (undocumented)
getContent(shapes: TLShape[]): TLContent | undefined; getContent(shapes: TLShape[]): TLContent | undefined;
getCurrentPageShapeIds(pageId: TLPageId): Set<TLShapeId>;
// (undocumented)
getCurrentPageShapeIds(page: TLPage): Set<TLShapeId>;
getDroppingOverShape(point: VecLike, droppingShapes?: TLShape[]): TLShape | undefined; getDroppingOverShape(point: VecLike, droppingShapes?: TLShape[]): TLShape | undefined;
getGeometry<T extends Geometry2d>(id: TLShapeId): T;
// (undocumented)
getGeometry<T extends Geometry2d>(shape: TLShape): T;
getHandles<T extends TLShape>(id: T['id']): TLHandle[] | undefined;
// (undocumented)
getHandles<T extends TLShape>(shape: T): TLHandle[] | undefined;
getHighestIndexForParent(parent: TLPage | TLShape): string; getHighestIndexForParent(parent: TLPage | TLShape): string;
// (undocumented) // (undocumented)
getHighestIndexForParent(parentId: TLParentId): string; getHighestIndexForParent(parentId: TLParentId): string;
getInitialMetaForShape(_shape: TLShape): JsonObject; getInitialMetaForShape(_shape: TLShape): JsonObject;
getMaskedPageBounds(id: TLShapeId): Box2d | undefined;
// (undocumented)
getMaskedPageBounds(shape: TLShape): Box2d | undefined;
getOutermostSelectableShape(shape: TLShape, filter?: (shape: TLShape) => boolean): TLShape; getOutermostSelectableShape(shape: TLShape, filter?: (shape: TLShape) => boolean): TLShape;
// (undocumented) // (undocumented)
getOutermostSelectableShape(id: TLShapeId, filter?: (shape: TLShape) => boolean): TLShape; getOutermostSelectableShape(id: TLShapeId, filter?: (shape: TLShape) => boolean): TLShape;
getOutlineSegments<T extends TLShape>(shape: T): Vec2d[][];
// (undocumented)
getOutlineSegments<T extends TLShape>(id: T['id']): Vec2d[][];
getPage(page: TLPage): TLPage | undefined; getPage(page: TLPage): TLPage | undefined;
// (undocumented) // (undocumented)
getPage(id: TLPageId): TLPage | undefined; getPage(id: TLPageId): TLPage | undefined;
getPageBounds(shape: TLShape): Box2d | undefined;
// (undocumented)
getPageBounds(id: TLShapeId): Box2d | undefined;
getPageMask(id: TLShapeId): undefined | VecLike[];
// (undocumented)
getPageMask(shape: TLShape): undefined | VecLike[];
getPageTransform(id: TLShapeId): Matrix2d;
// (undocumented)
getPageTransform(shape: TLShape): Matrix2d;
getParentShape(shape?: TLShape): TLShape | undefined;
// (undocumented)
getParentShape(shapeId?: TLShapeId): TLShape | undefined;
getParentTransform(shape: TLShape): Matrix2d;
// (undocumented)
getParentTransform(id: TLShapeId): Matrix2d;
getPointInParentSpace(shape: TLShape, point: VecLike): Vec2d; getPointInParentSpace(shape: TLShape, point: VecLike): Vec2d;
// (undocumented) // (undocumented)
getPointInParentSpace(id: TLShapeId, point: VecLike): Vec2d; getPointInParentSpace(id: TLShapeId, point: VecLike): Vec2d;
@ -731,6 +704,9 @@ export class Editor extends EventEmitter<TLEventMap> {
getShape<T extends TLShape = TLShape>(id: TLParentId): T | undefined; getShape<T extends TLShape = TLShape>(id: TLParentId): T | undefined;
// (undocumented) // (undocumented)
getShape<T extends TLShape = TLShape>(shape: TLShape): T | undefined; getShape<T extends TLShape = TLShape>(shape: TLShape): T | undefined;
getShapeAncestors(shape: TLShape, acc?: TLShape[]): TLShape[];
// (undocumented)
getShapeAncestors(id: TLShapeId, acc?: TLShape[]): TLShape[];
getShapeAndDescendantIds(ids: TLShapeId[]): Set<TLShapeId>; getShapeAndDescendantIds(ids: TLShapeId[]): Set<TLShapeId>;
getShapeAtPoint(point: VecLike, opts?: { getShapeAtPoint(point: VecLike, opts?: {
hitInside?: boolean | undefined; hitInside?: boolean | undefined;
@ -739,9 +715,39 @@ export class Editor extends EventEmitter<TLEventMap> {
hitFrameInside?: boolean | undefined; hitFrameInside?: boolean | undefined;
filter?: ((shape: TLShape) => boolean) | undefined; filter?: ((shape: TLShape) => boolean) | undefined;
}): TLShape | undefined; }): TLShape | undefined;
getShapeIdsInPage(page: TLPage): Set<TLShapeId>; getShapeClipPath(shape: TLShape): string | undefined;
// (undocumented) // (undocumented)
getShapeIdsInPage(pageId: TLPageId): Set<TLShapeId>; getShapeClipPath(id: TLShapeId): string | undefined;
getShapeGeometry<T extends Geometry2d>(id: TLShapeId): T;
// (undocumented)
getShapeGeometry<T extends Geometry2d>(shape: TLShape): T;
getShapeHandles<T extends TLShape>(id: T['id']): TLHandle[] | undefined;
// (undocumented)
getShapeHandles<T extends TLShape>(shape: T): TLHandle[] | undefined;
getShapeLocalTransform(shape: TLShape): Matrix2d;
// (undocumented)
getShapeLocalTransform(id: TLShapeId): Matrix2d;
getShapeMask(id: TLShapeId): undefined | VecLike[];
// (undocumented)
getShapeMask(shape: TLShape): undefined | VecLike[];
getShapeMaskedPageBounds(id: TLShapeId): Box2d | undefined;
// (undocumented)
getShapeMaskedPageBounds(shape: TLShape): Box2d | undefined;
getShapeOutlineSegments<T extends TLShape>(shape: T): Vec2d[][];
// (undocumented)
getShapeOutlineSegments<T extends TLShape>(id: T['id']): Vec2d[][];
getShapePageBounds(shape: TLShape): Box2d | undefined;
// (undocumented)
getShapePageBounds(id: TLShapeId): Box2d | undefined;
getShapePageTransform(id: TLShapeId): Matrix2d;
// (undocumented)
getShapePageTransform(shape: TLShape): Matrix2d;
getShapeParent(shape?: TLShape): TLShape | undefined;
// (undocumented)
getShapeParent(shapeId?: TLShapeId): TLShape | undefined;
getShapeParentTransform(shape: TLShape): Matrix2d;
// (undocumented)
getShapeParentTransform(id: TLShapeId): Matrix2d;
getShapesAtPoint(point: VecLike, opts?: { getShapesAtPoint(point: VecLike, opts?: {
margin?: number | undefined; margin?: number | undefined;
hitInside?: boolean | undefined; hitInside?: boolean | undefined;
@ -766,9 +772,6 @@ export class Editor extends EventEmitter<TLEventMap> {
darkMode?: boolean | undefined; darkMode?: boolean | undefined;
preserveAspectRatio: React.SVGAttributes<SVGSVGElement>['preserveAspectRatio']; preserveAspectRatio: React.SVGAttributes<SVGSVGElement>['preserveAspectRatio'];
}>): Promise<SVGSVGElement | undefined>; }>): Promise<SVGSVGElement | undefined>;
getTransform(shape: TLShape): Matrix2d;
// (undocumented)
getTransform(id: TLShapeId): Matrix2d;
groupShapes(ids: TLShapeId[], groupId?: TLShapeId): this; groupShapes(ids: TLShapeId[], groupId?: TLShapeId): this;
// (undocumented) // (undocumented)
groupShapes(shapes: TLShape[], groupId?: TLShapeId): this; groupShapes(shapes: TLShape[], groupId?: TLShapeId): this;
@ -777,7 +780,6 @@ export class Editor extends EventEmitter<TLEventMap> {
hasAncestor(shapeId: TLShapeId | undefined, ancestorId: TLShapeId): boolean; hasAncestor(shapeId: TLShapeId | undefined, ancestorId: TLShapeId): boolean;
get hintingShapeIds(): TLShapeId[]; get hintingShapeIds(): TLShapeId[];
readonly history: HistoryManager<this>; readonly history: HistoryManager<this>;
// (undocumented)
get hoveredShape(): TLUnknownShape | undefined; get hoveredShape(): TLUnknownShape | undefined;
get hoveredShapeId(): null | TLShapeId; get hoveredShapeId(): null | TLShapeId;
inputs: { inputs: {
@ -906,8 +908,8 @@ export class Editor extends EventEmitter<TLEventMap> {
selectAll(): this; selectAll(): this;
get selectedShapeIds(): TLShapeId[]; get selectedShapeIds(): TLShapeId[];
get selectedShapes(): TLShape[]; get selectedShapes(): TLShape[];
get selectionBounds(): Box2d | undefined;
get selectionPageBounds(): Box2d | null; get selectionPageBounds(): Box2d | null;
get selectionRotatedPageBounds(): Box2d | undefined;
get selectionRotation(): number; get selectionRotation(): number;
selectNone(): this; selectNone(): this;
sendBackward(shapes: TLShape[]): this; sendBackward(shapes: TLShape[]): this;
@ -917,27 +919,19 @@ export class Editor extends EventEmitter<TLEventMap> {
// (undocumented) // (undocumented)
sendToBack(ids: TLShapeId[]): this; sendToBack(ids: TLShapeId[]): this;
setCamera(point: VecLike, animation?: TLAnimationOptions): this; setCamera(point: VecLike, animation?: TLAnimationOptions): this;
// (undocumented)
setCroppingId(id: null | TLShapeId): this; setCroppingId(id: null | TLShapeId): this;
setCurrentPage(page: TLPage, opts?: TLViewportOptions): this; setCurrentPage(page: TLPage, opts?: TLViewportOptions): this;
// (undocumented) // (undocumented)
setCurrentPage(pageId: TLPageId, opts?: TLViewportOptions): this; setCurrentPage(pageId: TLPageId, opts?: TLViewportOptions): this;
setCurrentTool(id: string, info?: {}): this; setCurrentTool(id: string, info?: {}): this;
// (undocumented)
setEditingId(id: null | TLShapeId): this; setEditingId(id: null | TLShapeId): this;
// (undocumented)
setErasingIds(ids: TLShapeId[]): this; setErasingIds(ids: TLShapeId[]): this;
// (undocumented) setFocusedGroupId(next: null | TLShapeId): this;
setFocusedGroupId(next: TLPageId | TLShapeId): this;
// (undocumented)
setHintingIds(ids: TLShapeId[]): this; setHintingIds(ids: TLShapeId[]): this;
// (undocumented)
setHoveredId(id: null | TLShapeId): this; setHoveredId(id: null | TLShapeId): this;
setOpacity(opacity: number, ephemeral?: boolean, squashing?: boolean): this; setOpacity(opacity: number, ephemeral?: boolean, squashing?: boolean): this;
setSelectedShapeIds(ids: TLShapeId[], squashing?: boolean): this; setSelectedShapeIds(ids: TLShapeId[], squashing?: boolean): this;
setStyle<T>(style: StyleProp<T>, value: T, ephemeral?: boolean, squashing?: boolean): this; setStyle<T>(style: StyleProp<T>, value: T, ephemeral?: boolean, squashing?: boolean): this;
get shapeIdsOnCurrentPage(): Set<TLShapeId>;
get shapesOnCurrentPage(): TLShape[];
shapeUtils: { shapeUtils: {
readonly [K in string]?: ShapeUtil<TLUnknownShape>; readonly [K in string]?: ShapeUtil<TLUnknownShape>;
}; };
@ -949,13 +943,12 @@ export class Editor extends EventEmitter<TLEventMap> {
direction: VecLike; direction: VecLike;
friction: number; friction: number;
speedThreshold?: number | undefined; speedThreshold?: number | undefined;
}): this | undefined; }): this;
readonly snaps: SnapManager; readonly snaps: SnapManager;
get sortedShapesOnCurrentPage(): TLShape[];
stackShapes(shapes: TLShape[], operation: 'horizontal' | 'vertical', gap: number): this; stackShapes(shapes: TLShape[], operation: 'horizontal' | 'vertical', gap: number): this;
// (undocumented) // (undocumented)
stackShapes(ids: TLShapeId[], operation: 'horizontal' | 'vertical', gap: number): this; stackShapes(ids: TLShapeId[], operation: 'horizontal' | 'vertical', gap: number): this;
startFollowingUser(userId: string): this | undefined; startFollowingUser(userId: string): this;
stopCameraAnimation(): this; stopCameraAnimation(): this;
stopFollowingUser(): this; stopFollowingUser(): this;
readonly store: TLStore; readonly store: TLStore;

View file

@ -192,13 +192,13 @@ function HandlesWrapper() {
const isReadonly = useValue('isChangingStyle', () => editor.instanceState.isReadonly, [editor]) const isReadonly = useValue('isChangingStyle', () => editor.instanceState.isReadonly, [editor])
const handles = useValue( const handles = useValue(
'handles', 'handles',
() => (editor.onlySelectedShape ? editor.getHandles(editor.onlySelectedShape) : undefined), () => (editor.onlySelectedShape ? editor.getShapeHandles(editor.onlySelectedShape) : undefined),
[editor] [editor]
) )
const transform = useValue( const transform = useValue(
'transform', 'transform',
() => () =>
editor.onlySelectedShape ? editor.getPageTransform(editor.onlySelectedShape) : undefined, editor.onlySelectedShape ? editor.getShapePageTransform(editor.onlySelectedShape) : undefined,
[editor] [editor]
) )
@ -396,7 +396,7 @@ const DebugSvgCopy = track(function DupSvg({ id }: { id: TLShapeId }) {
const unsubscribe = react('shape to svg', async () => { const unsubscribe = react('shape to svg', async () => {
const renderId = Math.random() const renderId = Math.random()
latest = renderId latest = renderId
const bb = editor.getPageBounds(id) const bb = editor.getShapePageBounds(id)
const el = await editor.getSvg([id], { padding: 0 }) const el = await editor.getSvg([id], { padding: 0 })
if (el && bb && latest === renderId) { if (el && bb && latest === renderId) {
el.style.setProperty('overflow', 'visible') el.style.setProperty('overflow', 'visible')
@ -443,7 +443,9 @@ const UiLogger = track(() => {
export function SelectionForegroundWrapper() { export function SelectionForegroundWrapper() {
const editor = useEditor() const editor = useEditor()
const selectionRotation = useValue('selection rotation', () => editor.selectionRotation, [editor]) const selectionRotation = useValue('selection rotation', () => editor.selectionRotation, [editor])
const selectionBounds = useValue('selection bounds', () => editor.selectionBounds, [editor]) const selectionBounds = useValue('selection bounds', () => editor.selectionRotatedPageBounds, [
editor,
])
const { SelectionForeground } = useEditorComponents() const { SelectionForeground } = useEditorComponents()
if (!selectionBounds || !SelectionForeground) return null if (!selectionBounds || !SelectionForeground) return null
return <SelectionForeground bounds={selectionBounds} rotation={selectionRotation} /> return <SelectionForeground bounds={selectionBounds} rotation={selectionRotation} />
@ -452,7 +454,9 @@ export function SelectionForegroundWrapper() {
export function SelectionBackgroundWrapper() { export function SelectionBackgroundWrapper() {
const editor = useEditor() const editor = useEditor()
const selectionRotation = useValue('selection rotation', () => editor.selectionRotation, [editor]) const selectionRotation = useValue('selection rotation', () => editor.selectionRotation, [editor])
const selectionBounds = useValue('selection bounds', () => editor.selectionBounds, [editor]) const selectionBounds = useValue('selection bounds', () => editor.selectionRotatedPageBounds, [
editor,
])
const { SelectionBackground } = useEditorComponents() const { SelectionBackground } = useEditorComponents()
if (!selectionBounds || !SelectionBackground) return null if (!selectionBounds || !SelectionBackground) return null
return <SelectionBackground bounds={selectionBounds} rotation={selectionRotation} /> return <SelectionBackground bounds={selectionBounds} rotation={selectionRotation} />

View file

@ -33,8 +33,8 @@ export const GeometryDebuggingView = track(function GeometryDebuggingView({
> >
{renderingShapes.map((result) => { {renderingShapes.map((result) => {
const shape = editor.getShape(result.id)! const shape = editor.getShape(result.id)!
const geometry = editor.getGeometry(shape) const geometry = editor.getShapeGeometry(shape)
const pageTransform = editor.getPageTransform(shape)! const pageTransform = editor.getShapePageTransform(shape)!
const pointInShapeSpace = editor.getPointInShapeSpace(shape, currentPagePoint) const pointInShapeSpace = editor.getPointInShapeSpace(shape, currentPagePoint)
const nearestPointOnShape = geometry.nearestPoint(pointInShapeSpace) const nearestPointOnShape = geometry.nearestPoint(pointInShapeSpace)

View file

@ -53,7 +53,7 @@ export const Shape = track(function Shape({
const shape = editor.getShape(id) const shape = editor.getShape(id)
if (!shape) return // probably the shape was just deleted if (!shape) return // probably the shape was just deleted
const pageTransform = editor.getPageTransform(id) const pageTransform = editor.getShapePageTransform(id)
const transform = Matrix2d.toCssString(pageTransform) const transform = Matrix2d.toCssString(pageTransform)
setProperty('transform', transform) setProperty('transform', transform)
}, },
@ -66,7 +66,7 @@ export const Shape = track(function Shape({
const shape = editor.getShape(id) const shape = editor.getShape(id)
if (!shape) return null if (!shape) return null
const clipPath = editor.getClipPath(id) const clipPath = editor.getShapeClipPath(id)
setProperty('clip-path', clipPath ?? 'none') setProperty('clip-path', clipPath ?? 'none')
}, },
[editor, setProperty] [editor, setProperty]
@ -78,7 +78,7 @@ export const Shape = track(function Shape({
const shape = editor.getShape(id) const shape = editor.getShape(id)
if (!shape) return null if (!shape) return null
const bounds = editor.getGeometry(shape).bounds const bounds = editor.getShapeGeometry(shape).bounds
setProperty('width', Math.max(1, Math.ceil(bounds.width)) + 'px') setProperty('width', Math.max(1, Math.ceil(bounds.width)) + 'px')
setProperty('height', Math.max(1, Math.ceil(bounds.height)) + 'px') setProperty('height', Math.max(1, Math.ceil(bounds.height)) + 'px')
}, },
@ -155,7 +155,7 @@ const InnerShapeBackground = React.memo(
const CulledShape = React.memo( const CulledShape = React.memo(
function CulledShape<T extends TLShape>({ shape }: { shape: T }) { function CulledShape<T extends TLShape>({ shape }: { shape: T }) {
const editor = useEditor() const editor = useEditor()
const bounds = editor.getGeometry(shape).bounds const bounds = editor.getShapeGeometry(shape).bounds
return ( return (
<div <div

View file

@ -60,7 +60,7 @@ const _ShapeIndicator: TLShapeIndicatorComponent = ({ id, className, color, opac
const transform = useValue( const transform = useValue(
'transform', 'transform',
() => { () => {
const pageTransform = editor.getPageTransform(id) const pageTransform = editor.getShapePageTransform(id)
if (!pageTransform) return '' if (!pageTransform) return ''
return pageTransform.toCssString() return pageTransform.toCssString()
}, },

View file

@ -33,7 +33,7 @@ export function createTLStore({ initialData, defaultName = '', ...rest }: TLStor
'schema' in rest 'schema' in rest
? rest.schema ? rest.schema
: createTLSchema({ : createTLSchema({
shapes: shapesOnCurrentPageToShapeMap(checkShapesAndAddCore(rest.shapeUtils)), shapes: currentPageShapesToShapeMap(checkShapesAndAddCore(rest.shapeUtils)),
}) })
return new Store({ return new Store({
schema, schema,
@ -44,7 +44,7 @@ export function createTLStore({ initialData, defaultName = '', ...rest }: TLStor
}) })
} }
function shapesOnCurrentPageToShapeMap(shapeUtils: TLShapeUtilConstructor<TLUnknownShape>[]) { function currentPageShapesToShapeMap(shapeUtils: TLShapeUtilConstructor<TLUnknownShape>[]) {
return Object.fromEntries( return Object.fromEntries(
shapeUtils.map((s): [string, SchemaShapeInfo] => [ shapeUtils.map((s): [string, SchemaShapeInfo] => [
s.type, s.type,

File diff suppressed because it is too large Load diff

View file

@ -235,9 +235,9 @@ export class SnapManager {
@computed get snapPointsCache() { @computed get snapPointsCache() {
const { editor } = this const { editor } = this
return editor.store.createComputedCache<SnapPoint[], TLShape>('snapPoints', (shape) => { return editor.store.createComputedCache<SnapPoint[], TLShape>('snapPoints', (shape) => {
const pageTransfrorm = editor.getPageTransform(shape.id) const pageTransfrorm = editor.getShapePageTransform(shape.id)
if (!pageTransfrorm) return undefined if (!pageTransfrorm) return undefined
const snapPoints = this.editor.getGeometry(shape).snapPoints const snapPoints = this.editor.getShapeGeometry(shape).snapPoints
return snapPoints.map((point, i) => { return snapPoints.map((point, i) => {
const { x, y } = Matrix2d.applyToPoint(pageTransfrorm, point) const { x, y } = Matrix2d.applyToPoint(pageTransfrorm, point)
return { x, y, id: `${shape.id}:${i}` } return { x, y, id: `${shape.id}:${i}` }
@ -267,7 +267,7 @@ export class SnapManager {
// Skip any shapes that don't allow snapping // Skip any shapes that don't allow snapping
if (!util.canSnap(childShape)) continue if (!util.canSnap(childShape)) continue
// Only consider shapes if they're inside of the viewport page bounds // Only consider shapes if they're inside of the viewport page bounds
const pageBounds = editor.getPageBounds(childId) const pageBounds = editor.getShapePageBounds(childId)
if (!(pageBounds && renderingBounds.includes(pageBounds))) continue if (!(pageBounds && renderingBounds.includes(pageBounds))) continue
// Snap to children of groups but not group itself // Snap to children of groups but not group itself
if (editor.isShapeOfType<TLGroupShape>(childShape, 'group')) { if (editor.isShapeOfType<TLGroupShape>(childShape, 'group')) {
@ -277,7 +277,7 @@ export class SnapManager {
snappableShapes.push({ snappableShapes.push({
id: childId, id: childId,
pageBounds, pageBounds,
isClosed: editor.getGeometry(childShape).isClosed, isClosed: editor.getShapeGeometry(childShape).isClosed,
}) })
} }
} }
@ -498,9 +498,9 @@ export class SnapManager {
@computed get outlinesInPageSpace() { @computed get outlinesInPageSpace() {
return this.snappableShapes.map(({ id, isClosed }) => { return this.snappableShapes.map(({ id, isClosed }) => {
const outline = deepCopy(this.editor.getGeometry(id).vertices) const outline = deepCopy(this.editor.getShapeGeometry(id).vertices)
if (isClosed) outline.push(outline[0]) if (isClosed) outline.push(outline[0])
const pageTransform = this.editor.getPageTransform(id) const pageTransform = this.editor.getShapePageTransform(id)
if (!pageTransform) throw Error('No page transform') if (!pageTransform) throw Error('No page transform')
return Matrix2d.applyToPoints(pageTransform, outline) return Matrix2d.applyToPoints(pageTransform, outline)
}) })

View file

@ -208,7 +208,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
* @public * @public
*/ */
getOutlineSegments(shape: Shape): Vec2d[][] { getOutlineSegments(shape: Shape): Vec2d[][] {
return [this.editor.getGeometry(shape).vertices] return [this.editor.getShapeGeometry(shape).vertices]
} }
/** /**

View file

@ -31,8 +31,8 @@ export class GroupShapeUtil extends ShapeUtil<TLGroupShape> {
return new Group2d({ return new Group2d({
children: children.map((childId) => { children: children.map((childId) => {
const shape = this.editor.getShape(childId)! const shape = this.editor.getShape(childId)!
const geometry = this.editor.getGeometry(childId) const geometry = this.editor.getShapeGeometry(childId)
const points = this.editor.getTransform(shape)!.applyToPoints(geometry.vertices) const points = this.editor.getShapeLocalTransform(shape)!.applyToPoints(geometry.vertices)
if (geometry.isClosed) { if (geometry.isClosed) {
return new Polygon2d({ return new Polygon2d({
@ -77,7 +77,7 @@ export class GroupShapeUtil extends ShapeUtil<TLGroupShape> {
return null return null
} }
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
return ( return (
<SVGContainer id={shape.id}> <SVGContainer id={shape.id}>
@ -92,7 +92,7 @@ export class GroupShapeUtil extends ShapeUtil<TLGroupShape> {
camera: { z: zoomLevel }, camera: { z: zoomLevel },
} = this.editor } = this.editor
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
return <DashedOutlineBox className="" bounds={bounds} zoomLevel={zoomLevel} /> return <DashedOutlineBox className="" bounds={bounds} zoomLevel={zoomLevel} />
} }

View file

@ -58,7 +58,7 @@ export function getCurvedArrowInfo(editor: Editor, shape: TLArrowShape, extraBen
return getStraightArrowInfo(editor, shape) return getStraightArrowInfo(editor, shape)
} }
const arrowPageTransform = editor.getPageTransform(shape)! const arrowPageTransform = editor.getShapePageTransform(shape)!
if (startShapeInfo && !startShapeInfo.isExact) { if (startShapeInfo && !startShapeInfo.isExact) {
// Points in page space // Points in page space
@ -80,7 +80,7 @@ export function getCurvedArrowInfo(editor: Editor, shape: TLArrowShape, extraBen
let intersections = fn( let intersections = fn(
centerInStartShapeLocalSpace, centerInStartShapeLocalSpace,
handleArc.radius, handleArc.radius,
editor.getGeometry(startShapeInfo.shape).vertices editor.getShapeGeometry(startShapeInfo.shape).vertices
) )
if (intersections) { if (intersections) {
@ -160,7 +160,7 @@ export function getCurvedArrowInfo(editor: Editor, shape: TLArrowShape, extraBen
let intersections = fn( let intersections = fn(
centerInEndShapeLocalSpace, centerInEndShapeLocalSpace,
handleArc.radius, handleArc.radius,
editor.getGeometry(endShapeInfo.shape).outerVertices editor.getShapeGeometry(endShapeInfo.shape).outerVertices
) )
if (intersections) { if (intersections) {

View file

@ -25,8 +25,8 @@ export function getBoundShapeInfoForTerminal(
} }
const shape = editor.getShape(terminal.boundShapeId)! const shape = editor.getShape(terminal.boundShapeId)!
const transform = editor.getPageTransform(shape)! const transform = editor.getShapePageTransform(shape)!
const geometry = editor.getGeometry(shape) const geometry = editor.getShapeGeometry(shape)
return { return {
shape, shape,
@ -56,9 +56,9 @@ export function getArrowTerminalInArrowSpace(
// Find the actual local point of the normalized terminal on // Find the actual local point of the normalized terminal on
// the bound shape and transform it to page space, then transform // the bound shape and transform it to page space, then transform
// it to arrow space // it to arrow space
const { point, size } = editor.getGeometry(boundShape).bounds const { point, size } = editor.getShapeGeometry(boundShape).bounds
const shapePoint = Vec2d.Add(point, Vec2d.MulV(terminal.normalizedAnchor, size)) const shapePoint = Vec2d.Add(point, Vec2d.MulV(terminal.normalizedAnchor, size))
const pagePoint = Matrix2d.applyToPoint(editor.getPageTransform(boundShape)!, shapePoint) const pagePoint = Matrix2d.applyToPoint(editor.getShapePageTransform(boundShape)!, shapePoint)
const arrowPoint = Matrix2d.applyToPoint(Matrix2d.Inverse(arrowPageTransform), pagePoint) const arrowPoint = Matrix2d.applyToPoint(Matrix2d.Inverse(arrowPageTransform), pagePoint)
return arrowPoint return arrowPoint
} }
@ -66,7 +66,7 @@ export function getArrowTerminalInArrowSpace(
/** @public */ /** @public */
export function getArrowTerminalsInArrowSpace(editor: Editor, shape: TLArrowShape) { export function getArrowTerminalsInArrowSpace(editor: Editor, shape: TLArrowShape) {
const arrowPageTransform = editor.getPageTransform(shape)! const arrowPageTransform = editor.getShapePageTransform(shape)!
const start = getArrowTerminalInArrowSpace(editor, arrowPageTransform, shape.props.start) const start = getArrowTerminalInArrowSpace(editor, arrowPageTransform, shape.props.start)
const end = getArrowTerminalInArrowSpace(editor, arrowPageTransform, shape.props.end) const end = getArrowTerminalInArrowSpace(editor, arrowPageTransform, shape.props.end)

View file

@ -32,7 +32,7 @@ export function getStraightArrowInfo(editor: Editor, shape: TLArrowShape): Arrow
const startShapeInfo = getBoundShapeInfoForTerminal(editor, start) const startShapeInfo = getBoundShapeInfoForTerminal(editor, start)
const endShapeInfo = getBoundShapeInfoForTerminal(editor, end) const endShapeInfo = getBoundShapeInfoForTerminal(editor, end)
const arrowPageTransform = editor.getPageTransform(shape)! const arrowPageTransform = editor.getShapePageTransform(shape)!
// Update the position of the arrowhead's end point // Update the position of the arrowhead's end point
updateArrowheadPointWithBoundShape( updateArrowheadPointWithBoundShape(

View file

@ -29,8 +29,8 @@ export class Pointing extends StateNode {
this.editor.mark(this.markId) this.editor.mark(this.markId)
this.editor.createShapes<TLBaseBoxShape>( this.editor
[ .createShapes<TLBaseBoxShape>([
{ {
id, id,
type: shapeType, type: shapeType,
@ -41,9 +41,8 @@ export class Pointing extends StateNode {
h: 1, h: 1,
}, },
}, },
], ])
true .select(id)
)
this.editor.setCurrentTool('select.resizing', { this.editor.setCurrentTool('select.resizing', {
...info, ...info,
target: 'selection', target: 'selection',
@ -99,7 +98,7 @@ export class Pointing extends StateNode {
const { w, h } = this.editor.getShapeUtil(shape).getDefaultProps() as TLBaseBoxShape['props'] const { w, h } = this.editor.getShapeUtil(shape).getDefaultProps() as TLBaseBoxShape['props']
const delta = new Vec2d(w / 2, h / 2) const delta = new Vec2d(w / 2, h / 2)
const parentTransform = this.editor.getParentTransform(shape) const parentTransform = this.editor.getShapeParentTransform(shape)
if (parentTransform) delta.rot(-parentTransform.rotation()) if (parentTransform) delta.rot(-parentTransform.rotation())
this.editor.updateShapes<TLBaseBoxShape>([ this.editor.updateShapes<TLBaseBoxShape>([

View file

@ -69,7 +69,7 @@ export function useGestureEvents(ref: React.RefObject<HTMLDivElement>) {
if (shape) { if (shape) {
const util = editor.getShapeUtil(shape) const util = editor.getShapeUtil(shape)
if (util.canScroll(shape)) { if (util.canScroll(shape)) {
const bounds = editor.getPageBounds(editor.editingShapeId) const bounds = editor.getShapePageBounds(editor.editingShapeId)
if (bounds?.containsPoint(editor.inputs.currentPagePoint)) { if (bounds?.containsPoint(editor.inputs.currentPagePoint)) {
return return
} }

View file

@ -7,7 +7,7 @@ import { useEditor } from './useEditor'
function getHandle(editor: Editor, id: TLShapeId, handleId: string) { function getHandle(editor: Editor, id: TLShapeId, handleId: string) {
const shape = editor.getShape<TLArrowShape | TLLineShape>(id)! const shape = editor.getShape<TLArrowShape | TLLineShape>(id)!
const handles = editor.getHandles(shape)! const handles = editor.getShapeHandles(shape)!
return { shape, handle: handles.find((h) => h.id === handleId) } return { shape, handle: handles.find((h) => h.id === handleId) }
} }

View file

@ -13,7 +13,7 @@ export function useZoomCss() {
const setScaleDebounced = debounce(setScale, 100) const setScaleDebounced = debounce(setScale, 100)
const scheduler = new EffectScheduler('useZoomCss', () => { const scheduler = new EffectScheduler('useZoomCss', () => {
const numShapes = editor.shapeIdsOnCurrentPage.size const numShapes = editor.currentPageShapeIds.size
if (numShapes < 300) { if (numShapes < 300) {
setScale(editor.zoomLevel) setScale(editor.zoomLevel)
} else { } else {

View file

@ -9,7 +9,7 @@ import { Vec2d } from '../primitives/Vec2d'
export function getRotationSnapshot({ editor }: { editor: Editor }): TLRotationSnapshot | null { export function getRotationSnapshot({ editor }: { editor: Editor }): TLRotationSnapshot | null {
const { const {
selectionRotation, selectionRotation,
selectionBounds, selectionRotatedPageBounds: selectionBounds,
inputs: { originPagePoint }, inputs: { originPagePoint },
selectedShapes, selectedShapes,
} = editor } = editor
@ -33,7 +33,7 @@ export function getRotationSnapshot({ editor }: { editor: Editor }): TLRotationS
initialSelectionRotation: selectionRotation, initialSelectionRotation: selectionRotation,
shapeSnapshots: selectedShapes.map((shape) => ({ shapeSnapshots: selectedShapes.map((shape) => ({
shape: structuredClone(shape), shape: structuredClone(shape),
initialPagePoint: editor.getPageTransform(shape.id)!.point(), initialPagePoint: editor.getShapePageTransform(shape.id)!.point(),
})), })),
} }
} }
@ -78,7 +78,7 @@ export function applyRotationToSnapshotShapes({
// around the pivot point (the average center of all rotating shapes.) // around the pivot point (the average center of all rotating shapes.)
const parentTransform = isShapeId(shape.parentId) const parentTransform = isShapeId(shape.parentId)
? editor.getPageTransform(shape.parentId)! ? editor.getShapePageTransform(shape.parentId)!
: Matrix2d.Identity() : Matrix2d.Identity()
const newPagePoint = Vec2d.RotWith(initialPagePoint, selectionPageCenter, delta) const newPagePoint = Vec2d.RotWith(initialPagePoint, selectionPageCenter, delta)

View file

@ -39,9 +39,9 @@ it('enters the arrow state', () => {
describe('When in the idle state', () => { describe('When in the idle state', () => {
it('enters the pointing state and creates a shape on pointer down', () => { it('enters the pointing state and creates a shape on pointer down', () => {
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor.setCurrentTool('arrow').pointerDown(0, 0) editor.setCurrentTool('arrow').pointerDown(0, 0)
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore + 1) expect(shapesAfter).toBe(shapesBefore + 1)
editor.expectPathToBe('root.arrow.pointing') editor.expectPathToBe('root.arrow.pointing')
}) })
@ -55,18 +55,18 @@ describe('When in the idle state', () => {
describe('When in the pointing state', () => { describe('When in the pointing state', () => {
it('cancels on pointer up', () => { it('cancels on pointer up', () => {
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor.setCurrentTool('arrow').pointerDown(0, 0).pointerUp(0, 0) editor.setCurrentTool('arrow').pointerDown(0, 0).pointerUp(0, 0)
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore) expect(shapesAfter).toBe(shapesBefore)
expect(editor.hintingShapeIds.length).toBe(0) expect(editor.hintingShapeIds.length).toBe(0)
editor.expectPathToBe('root.arrow.idle') editor.expectPathToBe('root.arrow.idle')
}) })
it('bails on cancel', () => { it('bails on cancel', () => {
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor.setCurrentTool('arrow').pointerDown(0, 0).cancel() editor.setCurrentTool('arrow').pointerDown(0, 0).cancel()
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore) expect(shapesAfter).toBe(shapesBefore)
expect(editor.hintingShapeIds.length).toBe(0) expect(editor.hintingShapeIds.length).toBe(0)
editor.expectPathToBe('root.arrow.idle') editor.expectPathToBe('root.arrow.idle')
@ -82,7 +82,7 @@ describe('When in the pointing state', () => {
describe('When dragging the arrow', () => { describe('When dragging the arrow', () => {
it('updates the arrow on pointer move', () => { it('updates the arrow on pointer move', () => {
editor.setCurrentTool('arrow').pointerDown(0, 0).pointerMove(10, 10) editor.setCurrentTool('arrow').pointerDown(0, 0).pointerMove(10, 10)
const arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
editor.expectShapeToMatch(arrow, { editor.expectShapeToMatch(arrow, {
id: arrow.id, id: arrow.id,
type: 'arrow', type: 'arrow',
@ -97,9 +97,9 @@ describe('When dragging the arrow', () => {
}) })
it('returns to select.idle, keeping shape, on pointer up', () => { it('returns to select.idle, keeping shape, on pointer up', () => {
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor.setCurrentTool('arrow').pointerDown(0, 0).pointerMove(10, 10).pointerUp(10, 10) editor.setCurrentTool('arrow').pointerDown(0, 0).pointerMove(10, 10).pointerUp(10, 10)
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore + 1) expect(shapesAfter).toBe(shapesBefore + 1)
expect(editor.hintingShapeIds.length).toBe(0) expect(editor.hintingShapeIds.length).toBe(0)
editor.expectPathToBe('root.select.idle') editor.expectPathToBe('root.select.idle')
@ -107,18 +107,18 @@ describe('When dragging the arrow', () => {
it('returns to arrow.idle, keeping shape, on pointer up when tool lock is active', () => { it('returns to arrow.idle, keeping shape, on pointer up when tool lock is active', () => {
editor.updateInstanceState({ isToolLocked: true }) editor.updateInstanceState({ isToolLocked: true })
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor.setCurrentTool('arrow').pointerDown(0, 0).pointerMove(10, 10).pointerUp(10, 10) editor.setCurrentTool('arrow').pointerDown(0, 0).pointerMove(10, 10).pointerUp(10, 10)
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore + 1) expect(shapesAfter).toBe(shapesBefore + 1)
expect(editor.hintingShapeIds.length).toBe(0) expect(editor.hintingShapeIds.length).toBe(0)
editor.expectPathToBe('root.arrow.idle') editor.expectPathToBe('root.arrow.idle')
}) })
it('bails on cancel', () => { it('bails on cancel', () => {
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor.setCurrentTool('arrow').pointerDown(0, 0).pointerMove(10, 10).cancel() editor.setCurrentTool('arrow').pointerDown(0, 0).pointerMove(10, 10).cancel()
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore) expect(shapesAfter).toBe(shapesBefore)
editor.expectPathToBe('root.arrow.idle') editor.expectPathToBe('root.arrow.idle')
}) })
@ -139,7 +139,7 @@ describe('When pointing a start shape', () => {
// Clear hinting ids when moving away // Clear hinting ids when moving away
expect(editor.hintingShapeIds.length).toBe(0) expect(editor.hintingShapeIds.length).toBe(0)
const arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
editor.expectShapeToMatch(arrow, { editor.expectShapeToMatch(arrow, {
id: arrow.id, id: arrow.id,
type: 'arrow', type: 'arrow',
@ -179,7 +179,7 @@ describe('When pointing an end shape', () => {
// Set hinting id when pointing the shape // Set hinting id when pointing the shape
expect(editor.hintingShapeIds.length).toBe(1) expect(editor.hintingShapeIds.length).toBe(1)
const arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
editor.expectShapeToMatch(arrow, { editor.expectShapeToMatch(arrow, {
id: arrow.id, id: arrow.id,
type: 'arrow', type: 'arrow',
@ -208,7 +208,7 @@ describe('When pointing an end shape', () => {
editor.pointerMove(375, 375) editor.pointerMove(375, 375)
let arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] let arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
expect(editor.hintingShapeIds.length).toBe(1) expect(editor.hintingShapeIds.length).toBe(1)
@ -230,7 +230,7 @@ describe('When pointing an end shape', () => {
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
editor.expectShapeToMatch(arrow, { editor.expectShapeToMatch(arrow, {
id: arrow.id, id: arrow.id,
@ -250,7 +250,7 @@ describe('When pointing an end shape', () => {
editor.pointerMove(375, 0) editor.pointerMove(375, 0)
expect(editor.hintingShapeIds.length).toBe(0) expect(editor.hintingShapeIds.length).toBe(0)
arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
editor.expectShapeToMatch(arrow, { editor.expectShapeToMatch(arrow, {
id: arrow.id, id: arrow.id,
@ -268,7 +268,7 @@ describe('When pointing an end shape', () => {
editor.pointerMove(325, 325) editor.pointerMove(325, 325)
expect(editor.hintingShapeIds.length).toBe(1) expect(editor.hintingShapeIds.length).toBe(1)
arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
editor.expectShapeToMatch(arrow, { editor.expectShapeToMatch(arrow, {
id: arrow.id, id: arrow.id,
@ -289,7 +289,7 @@ describe('When pointing an end shape', () => {
// Give time for the velocity to die down // Give time for the velocity to die down
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
editor.expectShapeToMatch(arrow, { editor.expectShapeToMatch(arrow, {
id: arrow.id, id: arrow.id,
@ -316,7 +316,7 @@ describe('When pointing an end shape', () => {
editor.inputs.pointerVelocity = new Vec2d(1, 1) editor.inputs.pointerVelocity = new Vec2d(1, 1)
editor.pointerMove(370, 370) editor.pointerMove(370, 370)
const arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
expect(editor.hintingShapeIds.length).toBe(1) expect(editor.hintingShapeIds.length).toBe(1)
@ -340,7 +340,7 @@ describe('When pointing an end shape', () => {
it('begins precise when moving slowly', () => { it('begins precise when moving slowly', () => {
editor.setCurrentTool('arrow').pointerDown(0, 0) editor.setCurrentTool('arrow').pointerDown(0, 0)
let arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] let arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
editor.expectShapeToMatch(arrow, { editor.expectShapeToMatch(arrow, {
id: arrow.id, id: arrow.id,
@ -358,7 +358,7 @@ describe('When pointing an end shape', () => {
editor.inputs.pointerVelocity = new Vec2d(0.001, 0.001) editor.inputs.pointerVelocity = new Vec2d(0.001, 0.001)
editor.pointerMove(375, 375) editor.pointerMove(375, 375)
arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
expect(editor.hintingShapeIds.length).toBe(1) expect(editor.hintingShapeIds.length).toBe(1)
@ -390,7 +390,7 @@ describe('reparenting issue', () => {
editor.pointerMove(100, 100) editor.pointerMove(100, 100)
editor.pointerUp() editor.pointerUp()
const arrowId = editor.sortedShapesOnCurrentPage[0].id const arrowId = editor.currentPageShapesSorted[0].id
// Now create three shapes // Now create three shapes
editor.createShapes([ editor.createShapes([

View file

@ -302,7 +302,7 @@ describe('Other cases when arrow are moved', () => {
.groupShapes(editor.selectedShapeIds) .groupShapes(editor.selectedShapeIds)
editor.setCurrentTool('arrow').pointerDown(1000, 1000).pointerMove(50, 350).pointerUp(50, 350) editor.setCurrentTool('arrow').pointerDown(1000, 1000).pointerMove(50, 350).pointerUp(50, 350)
let arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] let arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
assert(editor.isShapeOfType<TLArrowShape>(arrow, 'arrow')) assert(editor.isShapeOfType<TLArrowShape>(arrow, 'arrow'))
assert(arrow.props.end.type === 'binding') assert(arrow.props.end.type === 'binding')
expect(arrow.props.end.boundShapeId).toBe(ids.box3) expect(arrow.props.end.boundShapeId).toBe(ids.box3)
@ -322,7 +322,7 @@ describe('When a shape it rotated', () => {
it('binds correctly', () => { it('binds correctly', () => {
editor.setCurrentTool('arrow').pointerDown(0, 0).pointerMove(375, 375) editor.setCurrentTool('arrow').pointerDown(0, 0).pointerMove(375, 375)
const arrow = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const arrow = editor.currentPageShapes[editor.currentPageShapes.length - 1]
expect(editor.getShape(arrow.id)).toMatchObject({ expect(editor.getShape(arrow.id)).toMatchObject({
props: { props: {
@ -371,8 +371,8 @@ describe('resizing', () => {
.pointerUp() .pointerUp()
.setCurrentTool('select') .setCurrentTool('select')
const arrow1 = editor.shapesOnCurrentPage.at(-2)! const arrow1 = editor.currentPageShapes.at(-2)!
const arrow2 = editor.shapesOnCurrentPage.at(-1)! const arrow2 = editor.currentPageShapes.at(-1)!
editor editor
.select(arrow1.id, arrow2.id) .select(arrow1.id, arrow2.id)
@ -426,8 +426,8 @@ describe('resizing', () => {
.pointerUp() .pointerUp()
.setCurrentTool('select') .setCurrentTool('select')
const arrow1 = editor.shapesOnCurrentPage.at(-2)! const arrow1 = editor.currentPageShapes.at(-2)!
const arrow2 = editor.shapesOnCurrentPage.at(-1)! const arrow2 = editor.currentPageShapes.at(-1)!
editor.updateShapes([{ id: arrow1.id, type: 'arrow', props: { bend: 50 } }]) editor.updateShapes([{ id: arrow1.id, type: 'arrow', props: { bend: 50 } }])

View file

@ -223,7 +223,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
const next = deepCopy(shape) as TLArrowShape const next = deepCopy(shape) as TLArrowShape
const pageTransform = this.editor.getPageTransform(next.id)! const pageTransform = this.editor.getShapePageTransform(next.id)!
const pointInPageSpace = pageTransform.applyToPoint(handle) const pointInPageSpace = pageTransform.applyToPoint(handle)
if (this.editor.inputs.ctrlKey) { if (this.editor.inputs.ctrlKey) {
@ -237,7 +237,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
return next return next
} }
const point = this.editor.getPageTransform(shape.id)!.applyToPoint(handle) const point = this.editor.getShapePageTransform(shape.id)!.applyToPoint(handle)
const target = this.editor.getShapeAtPoint(point, { const target = this.editor.getShapeAtPoint(point, {
filter: (shape) => this.editor.getShapeUtil(shape).canBind(shape), filter: (shape) => this.editor.getShapeUtil(shape).canBind(shape),
@ -258,7 +258,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
// we've got a target! the handle is being dragged over a shape, bind to it // we've got a target! the handle is being dragged over a shape, bind to it
const targetGeometry = this.editor.getGeometry(target) const targetGeometry = this.editor.getShapeGeometry(target)
const targetBounds = targetGeometry.bounds const targetBounds = targetGeometry.bounds
const pointInTargetSpace = this.editor.getPointInShapeSpace(target, pointInPageSpace) const pointInTargetSpace = this.editor.getPointInShapeSpace(target, pointInPageSpace)
@ -491,7 +491,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
) && !this.editor.instanceState.isReadonly ) && !this.editor.instanceState.isReadonly
const info = this.editor.getArrowInfo(shape) const info = this.editor.getArrowInfo(shape)
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
const changeIndex = React.useMemo<number>(() => { const changeIndex = React.useMemo<number>(() => {
@ -564,7 +564,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
) )
const labelGeometry = shape.props.text.trim() const labelGeometry = shape.props.text.trim()
? (this.editor.getGeometry<Group2d>(shape).children[1] as Rectangle2d) ? (this.editor.getShapeGeometry<Group2d>(shape).children[1] as Rectangle2d)
: null : null
const maskStartArrowhead = !( const maskStartArrowhead = !(
@ -667,7 +667,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
const { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape) const { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape)
const info = this.editor.getArrowInfo(shape) const info = this.editor.getArrowInfo(shape)
const geometry = this.editor.getGeometry<Group2d>(shape) const geometry = this.editor.getShapeGeometry<Group2d>(shape)
const bounds = geometry.bounds const bounds = geometry.bounds
const labelGeometry = shape.props.text.trim() ? (geometry.children[1] as Rectangle2d) : null const labelGeometry = shape.props.text.trim() ? (geometry.children[1] as Rectangle2d) : null
@ -799,7 +799,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
// Arrowhead end path // Arrowhead end path
const ae = info.end.arrowhead && getArrowheadPathForType(info, 'end', strokeWidth) const ae = info.end.arrowhead && getArrowheadPathForType(info, 'end', strokeWidth)
const geometry = this.editor.getGeometry<Group2d>(shape) const geometry = this.editor.getShapeGeometry<Group2d>(shape)
const bounds = geometry.bounds const bounds = geometry.bounds
const labelGeometry = shape.props.text.trim() ? (geometry.children[1] as Rectangle2d) : null const labelGeometry = shape.props.text.trim() ? (geometry.children[1] as Rectangle2d) : null

View file

@ -43,7 +43,7 @@ export class Pointing extends StateNode {
this.editor.setCurrentTool('select.dragging_handle', { this.editor.setCurrentTool('select.dragging_handle', {
shape: this.shape, shape: this.shape,
handle: this.editor.getHandles(this.shape)!.find((h) => h.id === 'end')!, handle: this.editor.getShapeHandles(this.shape)!.find((h) => h.id === 'end')!,
isCreating: true, isCreating: true,
onInteractionEnd: 'arrow', onInteractionEnd: 'arrow',
}) })
@ -94,7 +94,7 @@ export class Pointing extends StateNode {
const shape = this.editor.getShape<TLArrowShape>(id) const shape = this.editor.getShape<TLArrowShape>(id)
if (!shape) throw Error(`expected shape`) if (!shape) throw Error(`expected shape`)
const handles = this.editor.getHandles(shape) const handles = this.editor.getShapeHandles(shape)
if (!handles) throw Error(`expected handles for arrow`) if (!handles) throw Error(`expected handles for arrow`)
const util = this.editor.getShapeUtil<TLArrowShape>('arrow') const util = this.editor.getShapeUtil<TLArrowShape>('arrow')
@ -121,7 +121,7 @@ export class Pointing extends StateNode {
const shape = this.shape const shape = this.shape
if (!shape) throw Error(`expected shape`) if (!shape) throw Error(`expected shape`)
const handles = this.editor.getHandles(shape) const handles = this.editor.getShapeHandles(shape)
if (!handles) throw Error(`expected handles for arrow`) if (!handles) throw Error(`expected handles for arrow`)
// end update // end update

View file

@ -44,7 +44,7 @@ export class BookmarkShapeUtil extends BaseBoxShapeUtil<TLBookmarkShape> {
shape.props.assetId ? this.editor.getAsset(shape.props.assetId) : null shape.props.assetId ? this.editor.getAsset(shape.props.assetId) : null
) as TLBookmarkAsset ) as TLBookmarkAsset
const pageRotation = this.editor.getPageTransform(shape)!.rotation() const pageRotation = this.editor.getShapePageTransform(shape)!.rotation()
const address = getHumanReadableAddress(shape) const address = getHumanReadableAddress(shape)

View file

@ -210,7 +210,7 @@ export class Drawing extends StateNode {
// Convert prevPoint to page space // Convert prevPoint to page space
const prevPointPageSpace = Matrix2d.applyToPoint( const prevPointPageSpace = Matrix2d.applyToPoint(
this.editor.getPageTransform(shape.id)!, this.editor.getShapePageTransform(shape.id)!,
prevPoint prevPoint
) )
this.pagePointWhereCurrentSegmentChanged = prevPointPageSpace this.pagePointWhereCurrentSegmentChanged = prevPointPageSpace
@ -336,7 +336,7 @@ export class Drawing extends StateNode {
points: [{ ...prevLastPoint }, newLastPoint], points: [{ ...prevLastPoint }, newLastPoint],
} }
const transform = this.editor.getPageTransform(shape)! const transform = this.editor.getShapePageTransform(shape)!
this.pagePointWhereCurrentSegmentChanged = Matrix2d.applyToPoint( this.pagePointWhereCurrentSegmentChanged = Matrix2d.applyToPoint(
transform, transform,
@ -500,7 +500,7 @@ export class Drawing extends StateNode {
} }
if (didSnap && snapSegment) { if (didSnap && snapSegment) {
const transform = this.editor.getPageTransform(shape)! const transform = this.editor.getShapePageTransform(shape)!
const first = snapSegment.points[0] const first = snapSegment.points[0]
const lastPoint = last(snapSegment.points) const lastPoint = last(snapSegment.points)
if (!lastPoint) throw Error('Expected a last point!') if (!lastPoint) throw Error('Expected a last point!')

View file

@ -97,7 +97,7 @@ export class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {
[] []
) )
const pageRotation = this.editor.getPageTransform(shape)!.rotation() const pageRotation = this.editor.getShapePageTransform(shape)!.rotation()
const isInteractive = isEditing || isHoveringWhileEditingSameShape const isInteractive = isEditing || isHoveringWhileEditingSameShape

View file

@ -12,44 +12,44 @@ afterEach(() => {
describe(FrameShapeTool, () => { describe(FrameShapeTool, () => {
it('Creates frame shapes on click-and-drag, supports undo and redo', () => { it('Creates frame shapes on click-and-drag, supports undo and redo', () => {
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerMove(100, 100) editor.pointerMove(100, 100)
editor.pointerUp(100, 100) editor.pointerUp(100, 100)
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
expect(editor.shapesOnCurrentPage[0]?.type).toBe('frame') expect(editor.currentPageShapes[0]?.type).toBe('frame')
expect(editor.selectedShapeIds[0]).toBe(editor.shapesOnCurrentPage[0]?.id) expect(editor.selectedShapeIds[0]).toBe(editor.currentPageShapes[0]?.id)
editor.undo() editor.undo()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.redo() editor.redo()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
it('Creates frame shapes on click, supports undo and redo', () => { it('Creates frame shapes on click, supports undo and redo', () => {
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerUp(50, 50) editor.pointerUp(50, 50)
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
expect(editor.shapesOnCurrentPage[0]?.type).toBe('frame') expect(editor.currentPageShapes[0]?.type).toBe('frame')
expect(editor.selectedShapeIds[0]).toBe(editor.shapesOnCurrentPage[0]?.id) expect(editor.selectedShapeIds[0]).toBe(editor.currentPageShapes[0]?.id)
editor.undo() editor.undo()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.redo() editor.redo()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
}) })
@ -114,22 +114,22 @@ describe('When in the pointing state', () => {
}) })
it('Creates a frame and returns to select tool on pointer up', () => { it('Creates a frame and returns to select tool on pointer up', () => {
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerUp(50, 50) editor.pointerUp(50, 50)
editor.expectPathToBe('root.select.idle') editor.expectPathToBe('root.select.idle')
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
it('Creates a frame and returns to frame.idle on pointer up if tool lock is enabled', () => { it('Creates a frame and returns to frame.idle on pointer up if tool lock is enabled', () => {
editor.updateInstanceState({ isToolLocked: true }) editor.updateInstanceState({ isToolLocked: true })
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerUp(50, 50) editor.pointerUp(50, 50)
editor.expectPathToBe('root.frame.idle') editor.expectPathToBe('root.frame.idle')
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
}) })

View file

@ -50,7 +50,7 @@ export class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {
} }
override component(shape: TLFrameShape) { override component(shape: TLFrameShape) {
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
const theme = useDefaultColorTheme() const theme = useDefaultColorTheme()
@ -90,7 +90,9 @@ export class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {
g.appendChild(rect) g.appendChild(rect)
// Text label // Text label
const pageRotation = canonicalizeRotation(this.editor.getPageTransform(shape.id)!.rotation()) const pageRotation = canonicalizeRotation(
this.editor.getShapePageTransform(shape.id)!.rotation()
)
// rotate right 45 deg // rotate right 45 deg
const offsetRotation = pageRotation + Math.PI / 4 const offsetRotation = pageRotation + Math.PI / 4
const scaledRotation = (offsetRotation * (2 / Math.PI) + 4) % 4 const scaledRotation = (offsetRotation * (2 / Math.PI) + 4) % 4
@ -163,7 +165,7 @@ export class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {
} }
indicator(shape: TLFrameShape) { indicator(shape: TLFrameShape) {
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
return ( return (
<rect <rect
@ -217,13 +219,13 @@ export class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {
} }
override onResizeEnd: TLOnResizeEndHandler<TLFrameShape> = (shape) => { override onResizeEnd: TLOnResizeEndHandler<TLFrameShape> = (shape) => {
const bounds = this.editor.getPageBounds(shape)! const bounds = this.editor.getShapePageBounds(shape)!
const children = this.editor.getSortedChildIdsForParent(shape.id) const children = this.editor.getSortedChildIdsForParent(shape.id)
const shapesToReparent: TLShapeId[] = [] const shapesToReparent: TLShapeId[] = []
for (const childId of children) { for (const childId of children) {
const childBounds = this.editor.getPageBounds(childId)! const childBounds = this.editor.getShapePageBounds(childId)!
if (!bounds.includes(childBounds)) { if (!bounds.includes(childBounds)) {
shapesToReparent.push(childId) shapesToReparent.push(childId)
} }

View file

@ -23,7 +23,7 @@ export const FrameHeading = function FrameHeading({
}) { }) {
const editor = useEditor() const editor = useEditor()
const pageRotation = canonicalizeRotation(editor.getPageTransform(id)!.rotation()) const pageRotation = canonicalizeRotation(editor.getShapePageTransform(id)!.rotation())
const isEditing = useIsEditing(id) const isEditing = useIsEditing(id)
const rInput = useRef<HTMLInputElement>(null) const rInput = useRef<HTMLInputElement>(null)

View file

@ -12,44 +12,44 @@ afterEach(() => {
describe(GeoShapeTool, () => { describe(GeoShapeTool, () => {
it('Creates geo shapes on click-and-drag, supports undo and redo', () => { it('Creates geo shapes on click-and-drag, supports undo and redo', () => {
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('geo') editor.setCurrentTool('geo')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerMove(100, 100) editor.pointerMove(100, 100)
editor.pointerUp() editor.pointerUp()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
expect(editor.shapesOnCurrentPage[0]?.type).toBe('geo') expect(editor.currentPageShapes[0]?.type).toBe('geo')
expect(editor.selectedShapeIds[0]).toBe(editor.shapesOnCurrentPage[0]?.id) expect(editor.selectedShapeIds[0]).toBe(editor.currentPageShapes[0]?.id)
editor.undo() editor.undo()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.redo() editor.redo()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
it('Creates geo shapes on click, supports undo and redo', () => { it('Creates geo shapes on click, supports undo and redo', () => {
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('geo') editor.setCurrentTool('geo')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerUp(50, 50) editor.pointerUp(50, 50)
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
expect(editor.shapesOnCurrentPage[0]?.type).toBe('geo') expect(editor.currentPageShapes[0]?.type).toBe('geo')
expect(editor.selectedShapeIds[0]).toBe(editor.shapesOnCurrentPage[0]?.id) expect(editor.selectedShapeIds[0]).toBe(editor.currentPageShapes[0]?.id)
editor.undo() editor.undo()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.redo() editor.redo()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
}) })
@ -100,7 +100,7 @@ describe('When in the idle state', () => {
editor.pointerMove(200, 200) editor.pointerMove(200, 200)
editor.pointerUp(200, 200) editor.pointerUp(200, 200)
expect(editor.shapesOnCurrentPage.length).toBe(2) expect(editor.currentPageShapes.length).toBe(2)
editor.selectAll() editor.selectAll()
expect(editor.selectedShapes.length).toBe(2) expect(editor.selectedShapes.length).toBe(2)
@ -143,22 +143,22 @@ describe('When in the pointing state', () => {
}) })
it('Creates a geo and returns to select tool on pointer up', () => { it('Creates a geo and returns to select tool on pointer up', () => {
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('geo') editor.setCurrentTool('geo')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerUp(50, 50) editor.pointerUp(50, 50)
editor.expectPathToBe('root.select.idle') editor.expectPathToBe('root.select.idle')
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
it('Creates a geo and returns to geo.idle on pointer up if tool lock is enabled', () => { it('Creates a geo and returns to geo.idle on pointer up if tool lock is enabled', () => {
editor.updateInstanceState({ isToolLocked: true }) editor.updateInstanceState({ isToolLocked: true })
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('geo') editor.setCurrentTool('geo')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerUp(50, 50) editor.pointerUp(50, 50)
editor.expectPathToBe('root.geo.idle') editor.expectPathToBe('root.geo.idle')
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
}) })

View file

@ -467,7 +467,7 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
break break
} }
default: { default: {
const geometry = this.editor.getGeometry(shape) const geometry = this.editor.getShapeGeometry(shape)
const outline = const outline =
geometry instanceof Group2d ? geometry.children[0].vertices : geometry.vertices geometry instanceof Group2d ? geometry.children[0].vertices : geometry.vertices
const lines = getLines(shape.props, strokeWidth) const lines = getLines(shape.props, strokeWidth)
@ -554,7 +554,7 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
} }
default: { default: {
const geometry = this.editor.getGeometry(shape) const geometry = this.editor.getShapeGeometry(shape)
const outline = const outline =
geometry instanceof Group2d ? geometry.children[0].vertices : geometry.vertices geometry instanceof Group2d ? geometry.children[0].vertices : geometry.vertices
let path: string let path: string
@ -714,7 +714,7 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
break break
} }
default: { default: {
const geometry = this.editor.getGeometry(shape) const geometry = this.editor.getShapeGeometry(shape)
const outline = const outline =
geometry instanceof Group2d ? geometry.children[0].vertices : geometry.vertices geometry instanceof Group2d ? geometry.children[0].vertices : geometry.vertices
const lines = getLines(shape.props, strokeWidth) const lines = getLines(shape.props, strokeWidth)
@ -760,7 +760,7 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
} }
if (props.text) { if (props.text) {
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
ctx.addExportDef(getFontDefForExport(shape.props.font)) ctx.addExportDef(getFontDefForExport(shape.props.font))

View file

@ -99,7 +99,7 @@ export class Pointing extends StateNode {
: new Box2d(0, 0, 200, 200) : new Box2d(0, 0, 200, 200)
const delta = bounds.center const delta = bounds.center
const parentTransform = this.editor.getParentTransform(shape) const parentTransform = this.editor.getShapeParentTransform(shape)
if (parentTransform) delta.rot(-parentTransform.rotation()) if (parentTransform) delta.rot(-parentTransform.rotation())
this.editor.select(id) this.editor.select(id)

View file

@ -15,9 +15,9 @@ it('enters the line state', () => {
describe('When in the idle state', () => { describe('When in the idle state', () => {
it('enters the pointing state and creates a shape on pointer down', () => { it('enters the pointing state and creates a shape on pointer down', () => {
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor.setCurrentTool('line').pointerDown(0, 0, { target: 'canvas' }) editor.setCurrentTool('line').pointerDown(0, 0, { target: 'canvas' })
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore + 1) expect(shapesAfter).toBe(shapesBefore + 1)
editor.expectPathToBe('root.line.pointing') editor.expectPathToBe('root.line.pointing')
}) })
@ -31,18 +31,18 @@ describe('When in the idle state', () => {
describe('When in the pointing state', () => { describe('When in the pointing state', () => {
it('createes on pointer up', () => { it('createes on pointer up', () => {
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor.setCurrentTool('line').pointerDown(0, 0, { target: 'canvas' }).pointerUp(0, 0) editor.setCurrentTool('line').pointerDown(0, 0, { target: 'canvas' }).pointerUp(0, 0)
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore + 1) expect(shapesAfter).toBe(shapesBefore + 1)
expect(editor.hintingShapeIds.length).toBe(0) expect(editor.hintingShapeIds.length).toBe(0)
editor.expectPathToBe('root.line.idle') editor.expectPathToBe('root.line.idle')
}) })
it('bails on cancel', () => { it('bails on cancel', () => {
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor.setCurrentTool('line').pointerDown(0, 0, { target: 'canvas' }).cancel() editor.setCurrentTool('line').pointerDown(0, 0, { target: 'canvas' }).cancel()
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore) expect(shapesAfter).toBe(shapesBefore)
expect(editor.hintingShapeIds.length).toBe(0) expect(editor.hintingShapeIds.length).toBe(0)
editor.expectPathToBe('root.line.idle') editor.expectPathToBe('root.line.idle')
@ -58,7 +58,7 @@ describe('When in the pointing state', () => {
describe('When dragging the line', () => { describe('When dragging the line', () => {
it('updates the line on pointer move', () => { it('updates the line on pointer move', () => {
editor.setCurrentTool('line').pointerDown(0, 0, { target: 'canvas' }).pointerMove(10, 10) editor.setCurrentTool('line').pointerDown(0, 0, { target: 'canvas' }).pointerMove(10, 10)
const line = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const line = editor.currentPageShapes[editor.currentPageShapes.length - 1]
editor.expectShapeToMatch(line, { editor.expectShapeToMatch(line, {
id: line.id, id: line.id,
type: 'line', type: 'line',
@ -75,13 +75,13 @@ describe('When dragging the line', () => {
}) })
it('returns to select.idle, keeping shape, on pointer up', () => { it('returns to select.idle, keeping shape, on pointer up', () => {
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor editor
.setCurrentTool('line') .setCurrentTool('line')
.pointerDown(0, 0, { target: 'canvas' }) .pointerDown(0, 0, { target: 'canvas' })
.pointerMove(10, 10) .pointerMove(10, 10)
.pointerUp(10, 10) .pointerUp(10, 10)
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore + 1) expect(shapesAfter).toBe(shapesBefore + 1)
expect(editor.hintingShapeIds.length).toBe(0) expect(editor.hintingShapeIds.length).toBe(0)
editor.expectPathToBe('root.select.idle') editor.expectPathToBe('root.select.idle')
@ -89,26 +89,26 @@ describe('When dragging the line', () => {
it('returns to line.idle, keeping shape, on pointer up if tool lock is enabled', () => { it('returns to line.idle, keeping shape, on pointer up if tool lock is enabled', () => {
editor.updateInstanceState({ isToolLocked: true }) editor.updateInstanceState({ isToolLocked: true })
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor editor
.setCurrentTool('line') .setCurrentTool('line')
.pointerDown(0, 0, { target: 'canvas' }) .pointerDown(0, 0, { target: 'canvas' })
.pointerMove(10, 10) .pointerMove(10, 10)
.pointerUp(10, 10) .pointerUp(10, 10)
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore + 1) expect(shapesAfter).toBe(shapesBefore + 1)
expect(editor.hintingShapeIds.length).toBe(0) expect(editor.hintingShapeIds.length).toBe(0)
editor.expectPathToBe('root.line.idle') editor.expectPathToBe('root.line.idle')
}) })
it('bails on cancel', () => { it('bails on cancel', () => {
const shapesBefore = editor.shapesOnCurrentPage.length const shapesBefore = editor.currentPageShapes.length
editor editor
.setCurrentTool('line') .setCurrentTool('line')
.pointerDown(0, 0, { target: 'canvas' }) .pointerDown(0, 0, { target: 'canvas' })
.pointerMove(10, 10) .pointerMove(10, 10)
.cancel() .cancel()
const shapesAfter = editor.shapesOnCurrentPage.length const shapesAfter = editor.currentPageShapes.length
expect(shapesAfter).toBe(shapesBefore) expect(shapesAfter).toBe(shapesBefore)
editor.expectPathToBe('root.line.idle') editor.expectPathToBe('root.line.idle')
}) })
@ -126,7 +126,7 @@ describe('When extending the line with the shift-key in tool-lock mode', () => {
.pointerDown(20, 10, { target: 'canvas' }) .pointerDown(20, 10, { target: 'canvas' })
.pointerUp(20, 10) .pointerUp(20, 10)
const line = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const line = editor.currentPageShapes[editor.currentPageShapes.length - 1]
assert(editor.isShapeOfType<TLLineShape>(line, 'line')) assert(editor.isShapeOfType<TLLineShape>(line, 'line'))
const handles = Object.values(line.props.handles) const handles = Object.values(line.props.handles)
expect(handles.length).toBe(3) expect(handles.length).toBe(3)
@ -143,7 +143,7 @@ describe('When extending the line with the shift-key in tool-lock mode', () => {
.pointerMove(30, 10) .pointerMove(30, 10)
.pointerUp(30, 10) .pointerUp(30, 10)
const line = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const line = editor.currentPageShapes[editor.currentPageShapes.length - 1]
assert(editor.isShapeOfType<TLLineShape>(line, 'line')) assert(editor.isShapeOfType<TLLineShape>(line, 'line'))
const handles = Object.values(line.props.handles) const handles = Object.values(line.props.handles)
expect(handles.length).toBe(3) expect(handles.length).toBe(3)
@ -161,7 +161,7 @@ describe('When extending the line with the shift-key in tool-lock mode', () => {
.pointerMove(30, 10) .pointerMove(30, 10)
.pointerUp(30, 10) .pointerUp(30, 10)
const line = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const line = editor.currentPageShapes[editor.currentPageShapes.length - 1]
assert(editor.isShapeOfType<TLLineShape>(line, 'line')) assert(editor.isShapeOfType<TLLineShape>(line, 'line'))
const handles = Object.values(line.props.handles) const handles = Object.values(line.props.handles)
expect(handles.length).toBe(3) expect(handles.length).toBe(3)
@ -181,7 +181,7 @@ describe('When extending the line with the shift-key in tool-lock mode', () => {
.pointerMove(30, 10) .pointerMove(30, 10)
.pointerUp(30, 10) .pointerUp(30, 10)
const line = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const line = editor.currentPageShapes[editor.currentPageShapes.length - 1]
assert(editor.isShapeOfType<TLLineShape>(line, 'line')) assert(editor.isShapeOfType<TLLineShape>(line, 'line'))
const handles = Object.values(line.props.handles) const handles = Object.values(line.props.handles)
expect(handles.length).toBe(3) expect(handles.length).toBe(3)
@ -203,7 +203,7 @@ describe('When extending the line with the shift-key in tool-lock mode', () => {
.pointerMove(40, 10) .pointerMove(40, 10)
.pointerUp(40, 10) .pointerUp(40, 10)
const line = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const line = editor.currentPageShapes[editor.currentPageShapes.length - 1]
assert(editor.isShapeOfType<TLLineShape>(line, 'line')) assert(editor.isShapeOfType<TLLineShape>(line, 'line'))
const handles = Object.values(line.props.handles) const handles = Object.values(line.props.handles)
expect(handles.length).toBe(3) expect(handles.length).toBe(3)

View file

@ -175,15 +175,15 @@ describe('Misc', () => {
editor.select(boxID, id) editor.select(boxID, id)
expect(editor.getPageBounds(box)!.maxX).not.toEqual(editor.getPageBounds(line)!.maxX) expect(editor.getShapePageBounds(box)!.maxX).not.toEqual(editor.getShapePageBounds(line)!.maxX)
editor.alignShapes(editor.selectedShapeIds, 'right') editor.alignShapes(editor.selectedShapeIds, 'right')
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
expect(editor.getPageBounds(box)!.maxX).toEqual(editor.getPageBounds(line)!.maxX) expect(editor.getShapePageBounds(box)!.maxX).toEqual(editor.getShapePageBounds(line)!.maxX)
expect(editor.getPageBounds(box)!.maxY).not.toEqual(editor.getPageBounds(line)!.maxY) expect(editor.getShapePageBounds(box)!.maxY).not.toEqual(editor.getShapePageBounds(line)!.maxY)
editor.alignShapes(editor.selectedShapeIds, 'bottom') editor.alignShapes(editor.selectedShapeIds, 'bottom')
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
expect(editor.getPageBounds(box)!.maxY).toEqual(editor.getPageBounds(line)!.maxY) expect(editor.getShapePageBounds(box)!.maxY).toEqual(editor.getShapePageBounds(line)!.maxY)
}) })
it('duplicates', () => { it('duplicates', () => {
@ -195,7 +195,7 @@ describe('Misc', () => {
editor.pointerMove(50, 50) // Move shape by 25, 25 editor.pointerMove(50, 50) // Move shape by 25, 25
editor.pointerUp().keyUp('Alt') editor.pointerUp().keyUp('Alt')
expect(Array.from(editor.shapeIdsOnCurrentPage.values()).length).toEqual(2) expect(Array.from(editor.currentPageShapeIds.values()).length).toEqual(2)
}) })
it('deletes', () => { it('deletes', () => {
@ -207,7 +207,7 @@ describe('Misc', () => {
editor.pointerMove(50, 50) // Move shape by 25, 25 editor.pointerMove(50, 50) // Move shape by 25, 25
editor.pointerUp().keyUp('Alt') editor.pointerUp().keyUp('Alt')
let ids = Array.from(editor.shapeIdsOnCurrentPage.values()) let ids = Array.from(editor.currentPageShapeIds.values())
expect(ids.length).toEqual(2) expect(ids.length).toEqual(2)
const duplicate = ids.filter((i) => i !== id)[0] const duplicate = ids.filter((i) => i !== id)[0]
@ -215,7 +215,7 @@ describe('Misc', () => {
editor.deleteShapes(editor.selectedShapeIds) editor.deleteShapes(editor.selectedShapeIds)
ids = Array.from(editor.shapeIdsOnCurrentPage.values()) ids = Array.from(editor.currentPageShapeIds.values())
expect(ids.length).toEqual(1) expect(ids.length).toEqual(1)
expect(ids[0]).toEqual(id) expect(ids[0]).toEqual(id)
}) })

View file

@ -103,7 +103,7 @@ export class LineShapeUtil extends ShapeUtil<TLLineShape> {
} }
override getOutlineSegments(shape: TLLineShape) { override getOutlineSegments(shape: TLLineShape) {
const spline = this.editor.getGeometry(shape) as Polyline2d | CubicSpline2d const spline = this.editor.getShapeGeometry(shape) as Polyline2d | CubicSpline2d
return spline.segments.map((s) => s.vertices) return spline.segments.map((s) => s.vertices)
} }

View file

@ -34,14 +34,14 @@ export class Pointing extends StateNode {
this.shape = shape this.shape = shape
if (inputs.shiftKey) { if (inputs.shiftKey) {
const handles = this.editor.getHandles(this.shape) const handles = this.editor.getShapeHandles(this.shape)
if (!handles) return if (!handles) return
const vertexHandles = handles.filter((h) => h.type === 'vertex').sort(sortByIndex) const vertexHandles = handles.filter((h) => h.type === 'vertex').sort(sortByIndex)
const endHandle = vertexHandles[vertexHandles.length - 1] const endHandle = vertexHandles[vertexHandles.length - 1]
const shapePagePoint = Matrix2d.applyToPoint( const shapePagePoint = Matrix2d.applyToPoint(
this.editor.getParentTransform(this.shape)!, this.editor.getShapeParentTransform(this.shape)!,
new Vec2d(this.shape.x, this.shape.y) new Vec2d(this.shape.x, this.shape.y)
) )
@ -105,7 +105,7 @@ export class Pointing extends StateNode {
if (!this.shape) return if (!this.shape) return
if (this.editor.inputs.isDragging) { if (this.editor.inputs.isDragging) {
const handles = this.editor.getHandles(this.shape) const handles = this.editor.getShapeHandles(this.shape)
if (!handles) { if (!handles) {
if (this.markId) this.editor.bailToMark(this.markId) if (this.markId) this.editor.bailToMark(this.markId)
throw Error('No handles found') throw Error('No handles found')

View file

@ -12,47 +12,47 @@ afterEach(() => {
describe(NoteShapeTool, () => { describe(NoteShapeTool, () => {
it('Creates note shapes on click-and-drag, supports undo and redo', () => { it('Creates note shapes on click-and-drag, supports undo and redo', () => {
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('note') editor.setCurrentTool('note')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerMove(100, 100) editor.pointerMove(100, 100)
editor.pointerUp(100, 100) editor.pointerUp(100, 100)
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
expect(editor.shapesOnCurrentPage[0]?.type).toBe('note') expect(editor.currentPageShapes[0]?.type).toBe('note')
expect(editor.selectedShapeIds[0]).toBe(editor.shapesOnCurrentPage[0]?.id) expect(editor.selectedShapeIds[0]).toBe(editor.currentPageShapes[0]?.id)
editor.cancel() // leave edit mode editor.cancel() // leave edit mode
editor.undo() // undoes the selection change editor.undo() // undoes the selection change
editor.undo() editor.undo()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.redo() editor.redo()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
it('Creates note shapes on click, supports undo and redo', () => { it('Creates note shapes on click, supports undo and redo', () => {
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('note') editor.setCurrentTool('note')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerUp(50, 50) editor.pointerUp(50, 50)
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
expect(editor.shapesOnCurrentPage[0]?.type).toBe('note') expect(editor.currentPageShapes[0]?.type).toBe('note')
expect(editor.selectedShapeIds[0]).toBe(editor.shapesOnCurrentPage[0]?.id) expect(editor.selectedShapeIds[0]).toBe(editor.currentPageShapes[0]?.id)
editor.undo() editor.undo()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.redo() editor.redo()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
}) })
@ -126,21 +126,21 @@ describe('When in the pointing state', () => {
}) })
it('Creates a note and begins editing on pointer up', () => { it('Creates a note and begins editing on pointer up', () => {
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('note') editor.setCurrentTool('note')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerUp(50, 50) editor.pointerUp(50, 50)
editor.expectPathToBe('root.select.editing_shape') editor.expectPathToBe('root.select.editing_shape')
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
it('Creates a frame and returns to frame.idle on pointer up if tool lock is enabled', () => { it('Creates a frame and returns to frame.idle on pointer up if tool lock is enabled', () => {
editor.updateInstanceState({ isToolLocked: true }) editor.updateInstanceState({ isToolLocked: true })
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('note') editor.setCurrentTool('note')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
editor.pointerUp(50, 50) editor.pointerUp(50, 50)
editor.expectPathToBe('root.note.idle') editor.expectPathToBe('root.note.idle')
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
}) })

View file

@ -113,7 +113,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
override toSvg(shape: TLNoteShape, ctx: SvgExportContext) { override toSvg(shape: TLNoteShape, ctx: SvgExportContext) {
ctx.addExportDef(getFontDefForExport(shape.props.font)) ctx.addExportDef(getFontDefForExport(shape.props.font))
const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode }) const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode })
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
const g = document.createElementNS('http://www.w3.org/2000/svg', 'g') const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')

View file

@ -89,20 +89,19 @@ export class Pointing extends StateNode {
this.markId = `creating:${id}` this.markId = `creating:${id}`
this.editor.mark(this.markId) this.editor.mark(this.markId)
this.editor.createShapes( this.editor
[ .createShapes([
{ {
id, id,
type: 'note', type: 'note',
x: originPagePoint.x, x: originPagePoint.x,
y: originPagePoint.y, y: originPagePoint.y,
}, },
], ])
true .select(id)
)
const shape = this.editor.getShape<TLNoteShape>(id)! const shape = this.editor.getShape<TLNoteShape>(id)!
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
// Center the text around the created point // Center the text around the created point
this.editor.updateShapes([ this.editor.updateShapes([

View file

@ -13,7 +13,7 @@ afterEach(() => {
describe(TextShapeTool, () => { describe(TextShapeTool, () => {
it('Creates text, edits it, undoes and redoes', () => { it('Creates text, edits it, undoes and redoes', () => {
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.setCurrentTool('text') editor.setCurrentTool('text')
editor.expectToBeIn('text.idle') editor.expectToBeIn('text.idle')
editor.pointerDown(0, 0) editor.pointerDown(0, 0)
@ -22,28 +22,28 @@ describe(TextShapeTool, () => {
editor.expectToBeIn('select.editing_shape') editor.expectToBeIn('select.editing_shape')
// This comes from the component, not the state chart // This comes from the component, not the state chart
editor.updateShapes([ editor.updateShapes([
{ ...editor.shapesOnCurrentPage[0]!, type: 'text', props: { text: 'Hello' } }, { ...editor.currentPageShapes[0]!, type: 'text', props: { text: 'Hello' } },
]) ])
// Deselect the editing shape // Deselect the editing shape
editor.cancel() editor.cancel()
editor.expectToBeIn('select.idle') editor.expectToBeIn('select.idle')
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
editor.expectShapeToMatch({ editor.expectShapeToMatch({
id: editor.shapesOnCurrentPage[0].id, id: editor.currentPageShapes[0].id,
type: 'text', type: 'text',
props: { text: 'Hello' }, props: { text: 'Hello' },
}) })
editor.undo() editor.undo()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.redo() editor.redo()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
editor.expectShapeToMatch({ editor.expectShapeToMatch({
id: editor.shapesOnCurrentPage[0].id, id: editor.currentPageShapes[0].id,
type: 'text', type: 'text',
props: { text: 'Hello' }, props: { text: 'Hello' },
}) })
@ -71,7 +71,7 @@ describe('When in idle state', () => {
editor.pointerDown(0, 0) editor.pointerDown(0, 0)
editor.pointerUp() editor.pointerUp()
editor.expectToBeIn('select.editing_shape') editor.expectToBeIn('select.editing_shape')
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
it('returns to select on cancel', () => { it('returns to select on cancel', () => {
@ -87,7 +87,7 @@ describe('When in the pointing state', () => {
editor.pointerDown(0, 0) editor.pointerDown(0, 0)
editor.cancel() editor.cancel()
editor.expectToBeIn('text.idle') editor.expectToBeIn('text.idle')
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
}) })
it('returns to idle on interrupt', () => { it('returns to idle on interrupt', () => {
@ -96,7 +96,7 @@ describe('When in the pointing state', () => {
editor.expectToBeIn('text.pointing') editor.expectToBeIn('text.pointing')
editor.interrupt() editor.interrupt()
editor.expectToBeIn('text.idle') editor.expectToBeIn('text.idle')
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
}) })
it('transitions to select.resizing when dragging and edits on pointer up', () => { it('transitions to select.resizing when dragging and edits on pointer up', () => {
@ -105,7 +105,7 @@ describe('When in the pointing state', () => {
editor.pointerMove(10, 10) editor.pointerMove(10, 10)
editor.expectToBeIn('select.resizing') editor.expectToBeIn('select.resizing')
editor.pointerUp() editor.pointerUp()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
editor.expectToBeIn('select.editing_shape') editor.expectToBeIn('select.editing_shape')
}) })
@ -115,8 +115,8 @@ describe('When in the pointing state', () => {
const y = 0 const y = 0
editor.pointerDown(x, y) editor.pointerDown(x, y)
editor.pointerUp() editor.pointerUp()
const bounds = editor.getPageBounds(editor.shapesOnCurrentPage[0])! const bounds = editor.getShapePageBounds(editor.currentPageShapes[0])!
expect(editor.shapesOnCurrentPage[0]).toMatchObject({ expect(editor.currentPageShapes[0]).toMatchObject({
x: x - bounds.width / 2, x: x - bounds.width / 2,
y: y - bounds.height / 2, y: y - bounds.height / 2,
}) })
@ -131,7 +131,7 @@ describe('When resizing', () => {
editor.expectToBeIn('select.resizing') editor.expectToBeIn('select.resizing')
editor.cancel() editor.cancel()
editor.expectToBeIn('text.idle') editor.expectToBeIn('text.idle')
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
}) })
it('does not bails on interrupt while resizing', () => { it('does not bails on interrupt while resizing', () => {
@ -140,7 +140,7 @@ describe('When resizing', () => {
editor.pointerMove(100, 100) editor.pointerMove(100, 100)
editor.expectToBeIn('select.resizing') editor.expectToBeIn('select.resizing')
editor.interrupt() editor.interrupt()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
it('preserves the top left when the text has a fixed width', () => { it('preserves the top left when the text has a fixed width', () => {
@ -149,7 +149,7 @@ describe('When resizing', () => {
const y = 0 const y = 0
editor.pointerDown(x, y) editor.pointerDown(x, y)
editor.pointerMove(x + 100, y + 100) editor.pointerMove(x + 100, y + 100)
expect(editor.shapesOnCurrentPage[0]).toMatchObject({ expect(editor.currentPageShapes[0]).toMatchObject({
x, x,
y, y,
}) })

View file

@ -144,7 +144,7 @@ export class TextShapeUtil extends ShapeUtil<TLTextShape> {
} }
indicator(shape: TLTextShape) { indicator(shape: TLTextShape) {
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
return <rect width={toDomPrecision(bounds.width)} height={toDomPrecision(bounds.height)} /> return <rect width={toDomPrecision(bounds.width)} height={toDomPrecision(bounds.height)} />
} }
@ -152,7 +152,7 @@ export class TextShapeUtil extends ShapeUtil<TLTextShape> {
ctx.addExportDef(getFontDefForExport(shape.props.font)) ctx.addExportDef(getFontDefForExport(shape.props.font))
const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode }) const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode })
const bounds = this.editor.getGeometry(shape).bounds const bounds = this.editor.getShapeGeometry(shape).bounds
const text = shape.props.text const text = shape.props.text
const width = bounds.width / (shape.props.scale ?? 1) const width = bounds.width / (shape.props.scale ?? 1)

View file

@ -72,8 +72,8 @@ export class Pointing extends StateNode {
this.editor.mark('creating text shape') this.editor.mark('creating text shape')
const id = createShapeId() const id = createShapeId()
const { x, y } = this.editor.inputs.currentPagePoint const { x, y } = this.editor.inputs.currentPagePoint
this.editor.createShapes( this.editor
[ .createShapes([
{ {
id, id,
type: 'text', type: 'text',
@ -84,9 +84,8 @@ export class Pointing extends StateNode {
autoSize: true, autoSize: true,
}, },
}, },
], ])
true .select(id)
)
this.editor.setEditingId(id) this.editor.setEditingId(id)
this.editor.setCurrentTool('select') this.editor.setCurrentTool('select')

View file

@ -71,7 +71,7 @@ const TLVideoUtilComponent = track(function TLVideoUtilComponent(props: {
}) { }) {
const { shape, videoUtil } = props const { shape, videoUtil } = props
const showControls = const showControls =
videoUtil.editor.getGeometry(shape).bounds.w * videoUtil.editor.zoomLevel >= 110 videoUtil.editor.getShapeGeometry(shape).bounds.w * videoUtil.editor.zoomLevel >= 110
const asset = shape.props.assetId ? videoUtil.editor.getAsset(shape.props.assetId) : null const asset = shape.props.assetId ? videoUtil.editor.getAsset(shape.props.assetId) : null
const { time, playing } = shape.props const { time, playing } = shape.props
const isEditing = useIsEditing(shape.id) const isEditing = useIsEditing(shape.id)

View file

@ -25,7 +25,7 @@ export class Erasing extends StateNode {
const { originPagePoint } = this.editor.inputs const { originPagePoint } = this.editor.inputs
this.excludedShapeIds = new Set( this.excludedShapeIds = new Set(
this.editor.shapesOnCurrentPage this.editor.currentPageShapes
.filter( .filter(
(shape) => (shape) =>
this.editor.isShapeOrAncestorLocked(shape) || this.editor.isShapeOrAncestorLocked(shape) ||
@ -95,7 +95,7 @@ export class Erasing extends StateNode {
update() { update() {
const { const {
zoomLevel, zoomLevel,
shapesOnCurrentPage, currentPageShapes: currentPageShapes,
erasingShapeIdsSet, erasingShapeIdsSet,
inputs: { currentPagePoint, previousPagePoint }, inputs: { currentPagePoint, previousPagePoint },
} = this.editor } = this.editor
@ -106,17 +106,17 @@ export class Erasing extends StateNode {
const erasing = new Set<TLShapeId>(erasingShapeIdsSet) const erasing = new Set<TLShapeId>(erasingShapeIdsSet)
for (const shape of shapesOnCurrentPage) { for (const shape of currentPageShapes) {
if (this.editor.isShapeOfType<TLGroupShape>(shape, 'group')) continue if (this.editor.isShapeOfType<TLGroupShape>(shape, 'group')) continue
// Avoid testing masked shapes, unless the pointer is inside the mask // Avoid testing masked shapes, unless the pointer is inside the mask
const pageMask = this.editor.getPageMask(shape.id) const pageMask = this.editor.getShapeMask(shape.id)
if (pageMask && !pointInPolygon(currentPagePoint, pageMask)) { if (pageMask && !pointInPolygon(currentPagePoint, pageMask)) {
continue continue
} }
// Hit test the shape using a line segment // Hit test the shape using a line segment
const geometry = this.editor.getGeometry(shape) const geometry = this.editor.getShapeGeometry(shape)
const A = this.editor.getPointInShapeSpace(shape, previousPagePoint) const A = this.editor.getPointInShapeSpace(shape, previousPagePoint)
const B = this.editor.getPointInShapeSpace(shape, currentPagePoint) const B = this.editor.getPointInShapeSpace(shape, currentPagePoint)

View file

@ -13,7 +13,7 @@ export class Pointing extends StateNode {
override onEnter = () => { override onEnter = () => {
const { const {
inputs: { currentPagePoint }, inputs: { currentPagePoint },
sortedShapesOnCurrentPage, currentPageShapesSorted: sortedShapesOnCurrentPage,
zoomLevel, zoomLevel,
} = this.editor } = this.editor

View file

@ -39,7 +39,7 @@ export class Brushing extends StateNode {
} }
this.excludedShapeIds = new Set( this.excludedShapeIds = new Set(
this.editor.shapesOnCurrentPage this.editor.currentPageShapes
.filter( .filter(
(shape) => (shape) =>
this.editor.isShapeOfType<TLGroupShape>(shape, 'group') || this.editor.isShapeOfType<TLGroupShape>(shape, 'group') ||
@ -96,7 +96,7 @@ export class Brushing extends StateNode {
const { const {
zoomLevel, zoomLevel,
currentPageId, currentPageId,
shapesOnCurrentPage, currentPageShapes: currentPageShapes,
inputs: { originPagePoint, currentPagePoint, shiftKey, ctrlKey }, inputs: { originPagePoint, currentPagePoint, shiftKey, ctrlKey },
} = this.editor } = this.editor
@ -118,12 +118,12 @@ export class Brushing extends StateNode {
const { excludedShapeIds } = this const { excludedShapeIds } = this
testAllShapes: for (let i = 0, n = shapesOnCurrentPage.length; i < n; i++) { testAllShapes: for (let i = 0, n = currentPageShapes.length; i < n; i++) {
shape = shapesOnCurrentPage[i] shape = currentPageShapes[i]
if (excludedShapeIds.has(shape.id)) continue testAllShapes if (excludedShapeIds.has(shape.id)) continue testAllShapes
if (results.has(shape.id)) continue testAllShapes if (results.has(shape.id)) continue testAllShapes
pageBounds = this.editor.getPageBounds(shape) pageBounds = this.editor.getShapePageBounds(shape)
if (!pageBounds) continue testAllShapes if (!pageBounds) continue testAllShapes
// If the brush fully wraps a shape, it's almost certainly a hit // If the brush fully wraps a shape, it's almost certainly a hit
@ -144,9 +144,9 @@ export class Brushing extends StateNode {
if (this.brush.collides(pageBounds)) { if (this.brush.collides(pageBounds)) {
// Shapes expect to hit test line segments in their own coordinate system, // Shapes expect to hit test line segments in their own coordinate system,
// so we first need to get the brush corners in the shape's local space. // so we first need to get the brush corners in the shape's local space.
const geometry = this.editor.getGeometry(shape) const geometry = this.editor.getShapeGeometry(shape)
pageTransform = this.editor.getPageTransform(shape) pageTransform = this.editor.getShapePageTransform(shape)
if (!pageTransform) { if (!pageTransform) {
continue testAllShapes continue testAllShapes
@ -190,7 +190,7 @@ export class Brushing extends StateNode {
// Find the outermost selectable shape, check to see if it has a // Find the outermost selectable shape, check to see if it has a
// page mask; and if so, check to see if the brush intersects it // page mask; and if so, check to see if the brush intersects it
const selectedShape = this.editor.getOutermostSelectableShape(shape) const selectedShape = this.editor.getOutermostSelectableShape(shape)
const pageMask = this.editor.getPageMask(selectedShape.id) const pageMask = this.editor.getShapeMask(selectedShape.id)
if ( if (
pageMask && pageMask &&

View file

@ -230,7 +230,7 @@ export class Cropping extends StateNode {
const shape = this.editor.onlySelectedShape as TLImageShape const shape = this.editor.onlySelectedShape as TLImageShape
const selectionBounds = this.editor.selectionBounds! const selectionBounds = this.editor.selectionRotatedPageBounds!
const dragHandlePoint = Vec2d.RotWith( const dragHandlePoint = Vec2d.RotWith(
selectionBounds.getHandlePoint(this.info.handle!), selectionBounds.getHandlePoint(this.info.handle!),

View file

@ -54,7 +54,7 @@ export class DraggingHandle extends StateNode {
this.shapeId = shape.id this.shapeId = shape.id
this.markId = isCreating ? `creating:${shape.id}` : this.editor.mark('dragging handle') this.markId = isCreating ? `creating:${shape.id}` : this.editor.mark('dragging handle')
this.initialHandle = deepCopy(handle) this.initialHandle = deepCopy(handle)
this.initialPageTransform = this.editor.getPageTransform(shape)! this.initialPageTransform = this.editor.getShapePageTransform(shape)!
this.initialPageRotation = this.initialPageTransform.rotation() this.initialPageRotation = this.initialPageTransform.rotation()
this.initialPagePoint = this.editor.inputs.originPagePoint.clone() this.initialPagePoint = this.editor.inputs.originPagePoint.clone()
@ -64,7 +64,7 @@ export class DraggingHandle extends StateNode {
) )
// <!-- Only relevant to arrows // <!-- Only relevant to arrows
const handles = this.editor.getHandles(shape)!.sort(sortByIndex) const handles = this.editor.getShapeHandles(shape)!.sort(sortByIndex)
const index = handles.findIndex((h) => h.id === info.handle.id) const index = handles.findIndex((h) => h.id === info.handle.id)
// Find the adjacent handle // Find the adjacent handle
@ -233,7 +233,7 @@ export class DraggingHandle extends StateNode {
if (isSnapMode ? !ctrlKey : ctrlKey) { if (isSnapMode ? !ctrlKey : ctrlKey) {
// We're snapping // We're snapping
const pageTransform = editor.getPageTransform(shape.id) const pageTransform = editor.getShapePageTransform(shape.id)
if (!pageTransform) throw Error('Expected a page transform') if (!pageTransform) throw Error('Expected a page transform')
// Get all the outline segments from the shape // Get all the outline segments from the shape
@ -245,7 +245,7 @@ export class DraggingHandle extends StateNode {
// find the index of the handle that shares the same index property // find the index of the handle that shares the same index property
// as the initial dragging handle; this catches a quirk of create handles // as the initial dragging handle; this catches a quirk of create handles
const handleIndex = editor const handleIndex = editor
.getHandles(shape)! .getShapeHandles(shape)!
.filter(({ type }) => type === 'vertex') .filter(({ type }) => type === 'vertex')
.sort(sortByIndex) .sort(sortByIndex)
.findIndex(({ index }) => initialHandle.index === index) .findIndex(({ index }) => initialHandle.index === index)
@ -258,7 +258,7 @@ export class DraggingHandle extends StateNode {
}) })
if (snapDelta) { if (snapDelta) {
snapDelta.rot(-editor.getParentTransform(shape)!.rotation()) snapDelta.rot(-editor.getShapeParentTransform(shape)!.rotation())
point.add(snapDelta) point.add(snapDelta)
} }
} }

View file

@ -514,7 +514,7 @@ export const MINOR_NUDGE_FACTOR = 1
export const GRID_INCREMENT = 5 export const GRID_INCREMENT = 5
function isPointInRotatedSelectionBounds(editor: Editor, point: VecLike) { function isPointInRotatedSelectionBounds(editor: Editor, point: VecLike) {
const { selectionBounds } = editor const { selectionRotatedPageBounds: selectionBounds } = editor
if (!selectionBounds) return false if (!selectionBounds) return false
const { selectionRotation } = editor const { selectionRotation } = editor

View file

@ -18,7 +18,7 @@ export class PointingShape extends StateNode {
const { const {
selectedShapeIds, selectedShapeIds,
focusedGroupId, focusedGroupId,
selectionBounds, selectionRotatedPageBounds: selectionBounds,
inputs: { currentPagePoint, shiftKey, altKey }, inputs: { currentPagePoint, shiftKey, altKey },
} = this.editor } = this.editor
@ -125,7 +125,7 @@ export class PointingShape extends StateNode {
} else if (shiftKey) { } else if (shiftKey) {
// Different shape, so we are drilling down into a group with shift key held. // Different shape, so we are drilling down into a group with shift key held.
// Deselect any ancestors and add the target shape to the selection // Deselect any ancestors and add the target shape to the selection
const ancestors = this.editor.getAncestors(outermostSelectableShape) const ancestors = this.editor.getShapeAncestors(outermostSelectableShape)
this.editor.mark('shift deselecting on pointer up') this.editor.mark('shift deselecting on pointer up')
this.editor.setSelectedShapeIds([ this.editor.setSelectedShapeIds([

View file

@ -365,7 +365,7 @@ export class Resizing extends StateNode {
inputs: { originPagePoint }, inputs: { originPagePoint },
} = this.editor } = this.editor
const selectionBounds = this.editor.selectionBounds! const selectionBounds = this.editor.selectionRotatedPageBounds!
const dragHandlePoint = Vec2d.RotWith( const dragHandlePoint = Vec2d.RotWith(
selectionBounds.getHandlePoint(this.info.handle!), selectionBounds.getHandlePoint(this.info.handle!),
@ -415,12 +415,12 @@ export class Resizing extends StateNode {
} }
_createShapeSnapshot = (shape: TLShape) => { _createShapeSnapshot = (shape: TLShape) => {
const pageTransform = this.editor.getPageTransform(shape)! const pageTransform = this.editor.getShapePageTransform(shape)!
const util = this.editor.getShapeUtil(shape) const util = this.editor.getShapeUtil(shape)
return { return {
shape, shape,
bounds: this.editor.getGeometry(shape).bounds, bounds: this.editor.getShapeGeometry(shape).bounds,
pageTransform, pageTransform,
pageRotation: Matrix2d.Decompose(pageTransform!).rotation, pageRotation: Matrix2d.Decompose(pageTransform!).rotation,
isAspectRatioLocked: util.isAspectRatioLocked(shape), isAspectRatioLocked: util.isAspectRatioLocked(shape),

View file

@ -139,7 +139,7 @@ export class Rotating extends StateNode {
_getRotationFromPointerPosition({ snapToNearestDegree }: { snapToNearestDegree: boolean }) { _getRotationFromPointerPosition({ snapToNearestDegree }: { snapToNearestDegree: boolean }) {
const { const {
selectionBounds, selectionRotatedPageBounds: selectionBounds,
selectionRotation, selectionRotation,
inputs: { shiftKey, currentPagePoint }, inputs: { shiftKey, currentPagePoint },
} = this.editor } = this.editor

View file

@ -108,7 +108,7 @@ export class ScribbleBrushing extends StateNode {
private updateScribbleSelection(addPoint: boolean) { private updateScribbleSelection(addPoint: boolean) {
const { const {
zoomLevel, zoomLevel,
shapesOnCurrentPage, currentPageShapes: currentPageShapes,
inputs: { shiftKey, originPagePoint, previousPagePoint, currentPagePoint }, inputs: { shiftKey, originPagePoint, previousPagePoint, currentPagePoint },
} = this.editor } = this.editor
@ -118,12 +118,12 @@ export class ScribbleBrushing extends StateNode {
this.pushPointToScribble() this.pushPointToScribble()
} }
const shapes = shapesOnCurrentPage const shapes = currentPageShapes
let shape: TLShape, geometry: Geometry2d, A: Vec2d, B: Vec2d let shape: TLShape, geometry: Geometry2d, A: Vec2d, B: Vec2d
for (let i = 0, n = shapes.length; i < n; i++) { for (let i = 0, n = shapes.length; i < n; i++) {
shape = shapes[i] shape = shapes[i]
geometry = this.editor.getGeometry(shape) geometry = this.editor.getShapeGeometry(shape)
if ( if (
this.editor.isShapeOfType<TLGroupShape>(shape, 'group') || this.editor.isShapeOfType<TLGroupShape>(shape, 'group') ||
@ -144,7 +144,7 @@ export class ScribbleBrushing extends StateNode {
if (geometry.hitTestLineSegment(A, B, HIT_TEST_MARGIN / zoomLevel)) { if (geometry.hitTestLineSegment(A, B, HIT_TEST_MARGIN / zoomLevel)) {
const outermostShape = this.editor.getOutermostSelectableShape(shape) const outermostShape = this.editor.getOutermostSelectableShape(shape)
const pageMask = this.editor.getPageMask(outermostShape.id) const pageMask = this.editor.getShapeMask(outermostShape.id)
if (pageMask) { if (pageMask) {
const intersection = intersectLineSegmentPolyline( const intersection = intersectLineSegmentPolyline(

View file

@ -272,7 +272,7 @@ export class Translating extends StateNode {
const parentTransform = isPageId(shape.parentId) const parentTransform = isPageId(shape.parentId)
? null ? null
: Matrix2d.Inverse(editor.getPageTransform(shape.parentId)!) : Matrix2d.Inverse(editor.getShapePageTransform(shape.parentId)!)
shapeSnapshot.parentTransform = parentTransform shapeSnapshot.parentTransform = parentTransform
}) })
@ -289,13 +289,13 @@ function getTranslatingSnapshot(editor: Editor) {
if (!shape) return null if (!shape) return null
movingShapes.push(shape) movingShapes.push(shape)
const pagePoint = editor.getPageTransform(id)!.point() const pagePoint = editor.getShapePageTransform(id)!.point()
if (!pagePoint) return null if (!pagePoint) return null
pagePoints.push(pagePoint) pagePoints.push(pagePoint)
const parentTransform = PageRecordType.isId(shape.parentId) const parentTransform = PageRecordType.isId(shape.parentId)
? null ? null
: Matrix2d.Inverse(editor.getPageTransform(shape.parentId)!) : Matrix2d.Inverse(editor.getShapePageTransform(shape.parentId)!)
return { return {
shape, shape,

View file

@ -83,7 +83,7 @@ export function selectOnCanvasPointerUp(editor: Editor) {
if (isShapeId(focusedGroupId)) { if (isShapeId(focusedGroupId)) {
const groupShape = editor.getShape(focusedGroupId)! const groupShape = editor.getShape(focusedGroupId)!
if (!editor.isPointInShape(groupShape, currentPagePoint, { margin: 0, hitInside: true })) { if (!editor.isPointInShape(groupShape, currentPagePoint, { margin: 0, hitInside: true })) {
editor.setFocusedGroupId(editor.currentPageId) editor.setFocusedGroupId(null)
} }
} }
} }

View file

@ -22,8 +22,7 @@ export function BackToContent() {
// viewport... so we also need to narrow down the list to only shapes that // viewport... so we also need to narrow down the list to only shapes that
// are ALSO in the viewport. // are ALSO in the viewport.
const visibleShapes = renderingShapes.filter((s) => s.isInViewport) const visibleShapes = renderingShapes.filter((s) => s.isInViewport)
const showBackToContentNow = const showBackToContentNow = visibleShapes.length === 0 && editor.currentPageShapes.length > 0
visibleShapes.length === 0 && editor.shapesOnCurrentPage.length > 0
if (showBackToContentPrev !== showBackToContentNow) { if (showBackToContentPrev !== showBackToContentNow) {
setShowBackToContent(showBackToContentNow) setShowBackToContent(showBackToContentNow)

View file

@ -7,7 +7,7 @@ export const HTMLCanvas = track(function HTMLCanvas() {
const rCanvas = React.useRef<HTMLCanvasElement>(null) const rCanvas = React.useRef<HTMLCanvasElement>(null)
const camera = editor.camera const camera = editor.camera
const shapes = editor.shapesOnCurrentPage const shapes = editor.currentPageShapes
if (rCanvas.current) { if (rCanvas.current) {
const cvs = rCanvas.current const cvs = rCanvas.current
const ctx = cvs.getContext('2d')! const ctx = cvs.getContext('2d')!
@ -19,7 +19,7 @@ export const HTMLCanvas = track(function HTMLCanvas() {
ctx.translate(camera.x, camera.y) ctx.translate(camera.x, camera.y)
for (const shape of shapes) { for (const shape of shapes) {
const bounds = editor.getPageBounds(shape)! const bounds = editor.getShapePageBounds(shape)!
path.rect(bounds.minX, bounds.minY, bounds.width, bounds.height) path.rect(bounds.minX, bounds.minY, bounds.width, bounds.height)
} }

View file

@ -54,7 +54,7 @@ export function Minimap({ shapeFill, selectFill, viewportFill }: MinimapProps) {
const onDoubleClick = React.useCallback( const onDoubleClick = React.useCallback(
(e: React.MouseEvent<HTMLCanvasElement>) => { (e: React.MouseEvent<HTMLCanvasElement>) => {
if (!editor.shapeIdsOnCurrentPage.size) return if (!editor.currentPageShapeIds.size) return
const point = minimap.minimapScreenPointToPagePoint(e.clientX, e.clientY, false, false) const point = minimap.minimapScreenPointToPagePoint(e.clientX, e.clientY, false, false)
@ -71,7 +71,7 @@ export function Minimap({ shapeFill, selectFill, viewportFill }: MinimapProps) {
const onPointerDown = React.useCallback( const onPointerDown = React.useCallback(
(e: React.PointerEvent<HTMLCanvasElement>) => { (e: React.PointerEvent<HTMLCanvasElement>) => {
setPointerCapture(e.currentTarget, e) setPointerCapture(e.currentTarget, e)
if (!editor.shapeIdsOnCurrentPage.size) return if (!editor.currentPageShapeIds.size) return
rPointing.current = true rPointing.current = true
@ -173,8 +173,11 @@ export function Minimap({ shapeFill, selectFill, viewportFill }: MinimapProps) {
useQuickReactor( useQuickReactor(
'minimap render when pagebounds or collaborators changes', 'minimap render when pagebounds or collaborators changes',
() => { () => {
const { shapeIdsOnCurrentPage, viewportPageBounds, commonBoundsOfAllShapesOnCurrentPage } = const {
editor currentPageShapeIds: shapeIdsOnCurrentPage,
viewportPageBounds,
currentPageBounds: commonBoundsOfAllShapesOnCurrentPage,
} = editor
const _dpr = devicePixelRatio.value const _dpr = devicePixelRatio.value
@ -189,10 +192,10 @@ export function Minimap({ shapeFill, selectFill, viewportFill }: MinimapProps) {
const allShapeBounds = [] as (Box2d & { id: TLShapeId })[] const allShapeBounds = [] as (Box2d & { id: TLShapeId })[]
shapeIdsOnCurrentPage.forEach((id) => { shapeIdsOnCurrentPage.forEach((id) => {
let pageBounds = editor.getPageBounds(id) as Box2d & { id: TLShapeId } let pageBounds = editor.getShapePageBounds(id) as Box2d & { id: TLShapeId }
if (!pageBounds) return if (!pageBounds) return
const pageMask = editor.getPageMask(id) const pageMask = editor.getShapeMask(id)
if (pageMask) { if (pageMask) {
const intersection = intersectPolygonPolygon(pageMask, pageBounds.corners) const intersection = intersectPolygonPolygon(pageMask, pageBounds.corners)

View file

@ -123,7 +123,7 @@ export class MinimapManager {
let { x: px, y: py } = this.getPagePoint(x, y) let { x: px, y: py } = this.getPagePoint(x, y)
if (clampToBounds) { if (clampToBounds) {
const shapesPageBounds = this.editor.commonBoundsOfAllShapesOnCurrentPage const shapesPageBounds = this.editor.currentPageBounds
const vpPageBounds = viewportPageBounds const vpPageBounds = viewportPageBounds
const minX = (shapesPageBounds?.minX ?? 0) - vpPageBounds.width / 2 const minX = (shapesPageBounds?.minX ?? 0) - vpPageBounds.width / 2

View file

@ -12,7 +12,7 @@ export const ZoomMenu = track(function ZoomMenu() {
const breakpoint = useBreakpoint() const breakpoint = useBreakpoint()
const zoom = editor.zoomLevel const zoom = editor.zoomLevel
const hasShapes = editor.shapeIdsOnCurrentPage.size > 0 const hasShapes = editor.currentPageShapeIds.size > 0
const hasSelected = editor.selectedShapeIds.length > 0 const hasSelected = editor.selectedShapeIds.length > 0
const isZoomedTo100 = editor.zoomLevel === 1 const isZoomedTo100 = editor.zoomLevel === 1

View file

@ -344,7 +344,7 @@ export async function pasteExcalidrawContent(editor: Editor, clipboard: any, poi
} }
const rootShapes = compact(rootShapeIds.map((id) => editor.getShape(id))) const rootShapes = compact(rootShapeIds.map((id) => editor.getShape(id)))
const bounds = Box2d.Common(rootShapes.map((s) => editor.getPageBounds(s)!)) const bounds = Box2d.Common(rootShapes.map((s) => editor.getShapePageBounds(s)!))
const viewPortCenter = editor.viewportPageBounds.center const viewPortCenter = editor.viewportPageBounds.center
editor.updateShapes( editor.updateShapes(
rootShapes.map((s) => { rootShapes.map((s) => {

View file

@ -366,7 +366,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
if (editor.currentToolId !== 'select') return if (editor.currentToolId !== 'select') return
trackEvent('duplicate-shapes', { source }) trackEvent('duplicate-shapes', { source })
const ids = editor.selectedShapeIds const ids = editor.selectedShapeIds
const commonBounds = Box2d.Common(compact(ids.map((id) => editor.getPageBounds(id)))) const commonBounds = Box2d.Common(compact(ids.map((id) => editor.getShapePageBounds(id))))
const offset = editor.instanceState.canMoveCamera const offset = editor.instanceState.canMoveCamera
? { ? {
x: commonBounds.width + 10, x: commonBounds.width + 10,

View file

@ -93,7 +93,7 @@ export const TLUiContextMenuSchemaProvider = track(function TLUiContextMenuSchem
const threeStackableItems = useThreeStackableItems() const threeStackableItems = useThreeStackableItems()
const atLeastOneShapeOnPage = useValue( const atLeastOneShapeOnPage = useValue(
'atLeastOneShapeOnPage', 'atLeastOneShapeOnPage',
() => editor.shapeIdsOnCurrentPage.size > 0, () => editor.currentPageShapeIds.size > 0,
[] []
) )
const isTransparentBg = useValue( const isTransparentBg = useValue(

View file

@ -20,7 +20,7 @@ export function useCopyAs() {
// little awkward. // little awkward.
function copyAs(ids: TLShapeId[] = editor.selectedShapeIds, format: TLCopyType = 'svg') { function copyAs(ids: TLShapeId[] = editor.selectedShapeIds, format: TLCopyType = 'svg') {
if (ids.length === 0) { if (ids.length === 0) {
ids = [...editor.shapeIdsOnCurrentPage] ids = [...editor.currentPageShapeIds]
} }
if (ids.length === 0) { if (ids.length === 0) {

View file

@ -21,7 +21,7 @@ export function useExportAs() {
format: TLExportType = 'png' format: TLExportType = 'png'
) { ) {
if (ids.length === 0) { if (ids.length === 0) {
ids = [...editor.shapeIdsOnCurrentPage] ids = [...editor.currentPageShapeIds]
} }
if (ids.length === 0) { if (ids.length === 0) {

View file

@ -60,7 +60,7 @@ export function TLUiMenuSchemaProvider({ overrides, children }: TLUiMenuSchemaPr
[editor] [editor]
) )
const emptyPage = useValue('emptyPage', () => editor.shapeIdsOnCurrentPage.size === 0, [editor]) const emptyPage = useValue('emptyPage', () => editor.currentPageShapeIds.size === 0, [editor])
const selectedCount = useValue('selectedCount', () => editor.selectedShapeIds.length, [editor]) const selectedCount = useValue('selectedCount', () => editor.selectedShapeIds.length, [editor])
const noneSelected = selectedCount === 0 const noneSelected = selectedCount === 0

View file

@ -166,8 +166,10 @@ export function useRegisterExternalContentHandlers() {
const { width, height } = embed const { width, height } = embed
const id = createShapeId()
const shapePartial: TLShapePartial<TLEmbedShape> = { const shapePartial: TLShapePartial<TLEmbedShape> = {
id: createShapeId(), id,
type: 'embed', type: 'embed',
x: position.x - (width || 450) / 2, x: position.x - (width || 450) / 2,
y: position.y - (height || 450) / 2, y: position.y - (height || 450) / 2,
@ -178,7 +180,7 @@ export function useRegisterExternalContentHandlers() {
}, },
} }
editor.createShapes([shapePartial], true) editor.createShapes([shapePartial]).select(id)
}) })
// files // files
@ -405,7 +407,7 @@ export async function createShapesForAssets(editor: Editor, assets: TLAsset[], p
} }
// Create the shapes // Create the shapes
editor.createShapes(paritals, true) editor.createShapes(paritals).select(...paritals.map((p) => p.id))
// Re-position shapes so that the center of the group is at the provided point // Re-position shapes so that the center of the group is at the provided point
const { viewportPageBounds } = editor const { viewportPageBounds } = editor

View file

@ -219,7 +219,7 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
}, },
]) ])
const pageBoundsBeforeLabel = editor.getPageBounds(inCommon.id)! const pageBoundsBeforeLabel = editor.getShapePageBounds(inCommon.id)!
editor.updateShapes([ editor.updateShapes([
{ {
@ -274,7 +274,7 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
}, },
]) ])
const pageBoundsBeforeLabel = editor.getPageBounds(inCommon.id)! const pageBoundsBeforeLabel = editor.getShapePageBounds(inCommon.id)!
editor.updateShapes([ editor.updateShapes([
{ {
@ -329,7 +329,7 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
}, },
]) ])
const pageBoundsBeforeLabel = editor.getPageBounds(inCommon.id)! const pageBoundsBeforeLabel = editor.getShapePageBounds(inCommon.id)!
editor.updateShapes([ editor.updateShapes([
{ {
@ -540,7 +540,7 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
if (!targetShape) continue if (!targetShape) continue
if (targetId) { if (targetId) {
const bounds = editor.getPageBounds(targetId)! const bounds = editor.getShapePageBounds(targetId)!
const v2ShapeFresh = editor.getShape<TLArrowShape>(v2ShapeId)! const v2ShapeFresh = editor.getShape<TLArrowShape>(v2ShapeId)!
@ -552,7 +552,7 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
y: bounds.minY + bounds.height * ny, y: bounds.minY + bounds.height * ny,
}) })
const handles = editor.getHandles(v2ShapeFresh)! const handles = editor.getShapeHandles(v2ShapeFresh)!
const change = util.onHandleChange!(v2ShapeFresh, { const change = util.onHandleChange!(v2ShapeFresh, {
handle: { handle: {
@ -591,7 +591,7 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
editor.selectNone() editor.selectNone()
editor.updateViewportScreenBounds() editor.updateViewportScreenBounds()
const bounds = editor.commonBoundsOfAllShapesOnCurrentPage const bounds = editor.currentPageBounds
if (bounds) { if (bounds) {
editor.zoomToBounds(bounds, 1) editor.zoomToBounds(bounds, 1)
} }

View file

@ -291,7 +291,7 @@ export async function parseAndLoadDocument(
editor.updateViewportScreenBounds() editor.updateViewportScreenBounds()
editor.updateRenderingBounds() editor.updateRenderingBounds()
const bounds = editor.commonBoundsOfAllShapesOnCurrentPage const bounds = editor.currentPageBounds
if (bounds) { if (bounds) {
editor.zoomToBounds(bounds, 1) editor.zoomToBounds(bounds, 1)
} }

View file

@ -99,7 +99,7 @@ describe('When clicking', () => {
// Starts in idle // Starts in idle
editor.expectPathToBe('root.eraser.idle') editor.expectPathToBe('root.eraser.idle')
const shapesBeforeCount = editor.shapesOnCurrentPage.length const shapesBeforeCount = editor.currentPageShapes.length
editor.pointerDown(0, 0) // near enough to box1 editor.pointerDown(0, 0) // near enough to box1
@ -112,7 +112,7 @@ describe('When clicking', () => {
editor.pointerUp() editor.pointerUp()
const shapesAfterCount = editor.shapesOnCurrentPage.length const shapesAfterCount = editor.currentPageShapes.length
// Deletes the erasing shapes // Deletes the erasing shapes
expect(editor.getShape(ids.box1)).toBeUndefined() expect(editor.getShape(ids.box1)).toBeUndefined()
@ -128,18 +128,18 @@ describe('When clicking', () => {
editor.undo() editor.undo()
expect(editor.getShape(ids.box1)).toBeDefined() expect(editor.getShape(ids.box1)).toBeDefined()
expect(editor.shapesOnCurrentPage.length).toBe(shapesBeforeCount) expect(editor.currentPageShapes.length).toBe(shapesBeforeCount)
editor.redo() editor.redo()
expect(editor.getShape(ids.box1)).toBeUndefined() expect(editor.getShape(ids.box1)).toBeUndefined()
expect(editor.shapesOnCurrentPage.length).toBe(shapesBeforeCount - 1) expect(editor.currentPageShapes.length).toBe(shapesBeforeCount - 1)
}) })
it('Erases all shapes under the cursor on click', () => { it('Erases all shapes under the cursor on click', () => {
editor.setCurrentTool('eraser') editor.setCurrentTool('eraser')
const shapesBeforeCount = editor.shapesOnCurrentPage.length const shapesBeforeCount = editor.currentPageShapes.length
editor.pointerDown(99, 99) // next to box1 AND in box2 editor.pointerDown(99, 99) // next to box1 AND in box2
@ -151,7 +151,7 @@ describe('When clicking', () => {
expect(editor.getShape(ids.box1)).toBeUndefined() expect(editor.getShape(ids.box1)).toBeUndefined()
expect(editor.getShape(ids.box2)).toBeUndefined() expect(editor.getShape(ids.box2)).toBeUndefined()
const shapesAfterCount = editor.shapesOnCurrentPage.length const shapesAfterCount = editor.currentPageShapes.length
expect(shapesAfterCount).toBe(shapesBeforeCount - 2) expect(shapesAfterCount).toBe(shapesBeforeCount - 2)
}) })
@ -159,7 +159,7 @@ describe('When clicking', () => {
editor.groupShapes([ids.box2, ids.box3], ids.group1) editor.groupShapes([ids.box2, ids.box3], ids.group1)
editor.setCurrentTool('eraser') editor.setCurrentTool('eraser')
const shapesBeforeCount = editor.shapesOnCurrentPage.length const shapesBeforeCount = editor.currentPageShapes.length
editor.pointerDown(350, 350) // in box3 editor.pointerDown(350, 350) // in box3
@ -168,7 +168,7 @@ describe('When clicking', () => {
editor.pointerUp() editor.pointerUp()
const shapesAfterCount = editor.shapesOnCurrentPage.length const shapesAfterCount = editor.currentPageShapes.length
expect(editor.getShape(ids.box2)).toBeUndefined() expect(editor.getShape(ids.box2)).toBeUndefined()
expect(editor.getShape(ids.box3)).toBeUndefined() expect(editor.getShape(ids.box3)).toBeUndefined()
@ -181,28 +181,28 @@ describe('When clicking', () => {
editor.groupShapes([ids.box2, ids.box3], ids.group1) editor.groupShapes([ids.box2, ids.box3], ids.group1)
editor.setCurrentTool('eraser') editor.setCurrentTool('eraser')
const shapesBeforeCount = editor.shapesOnCurrentPage.length const shapesBeforeCount = editor.currentPageShapes.length
editor.pointerDown(275, 275) // in between box2 AND box3, so over of the new group editor.pointerDown(275, 275) // in between box2 AND box3, so over of the new group
expect(editor.erasingShapeIdsSet).toEqual(new Set([])) expect(editor.erasingShapeIdsSet).toEqual(new Set([]))
editor.pointerUp() editor.pointerUp()
const shapesAfterCount = editor.shapesOnCurrentPage.length const shapesAfterCount = editor.currentPageShapes.length
expect(shapesAfterCount).toBe(shapesBeforeCount) expect(shapesAfterCount).toBe(shapesBeforeCount)
}) })
it('Stops erasing when it reaches a frame when the frame was not was the top-most hovered shape', () => { it('Stops erasing when it reaches a frame when the frame was not was the top-most hovered shape', () => {
editor.setCurrentTool('eraser') editor.setCurrentTool('eraser')
const shapesBeforeCount = editor.shapesOnCurrentPage.length const shapesBeforeCount = editor.currentPageShapes.length
editor.pointerDown(375, 75) // inside of the box4 shape inside of box3 editor.pointerDown(375, 75) // inside of the box4 shape inside of box3
expect(editor.erasingShapeIdsSet).toEqual(new Set([ids.box4])) expect(editor.erasingShapeIdsSet).toEqual(new Set([ids.box4]))
editor.pointerUp() editor.pointerUp()
const shapesAfterCount = editor.shapesOnCurrentPage.length const shapesAfterCount = editor.currentPageShapes.length
expect(shapesAfterCount).toBe(shapesBeforeCount - 1) expect(shapesAfterCount).toBe(shapesBeforeCount - 1)
// Erases the child but does not erase the frame // Erases the child but does not erase the frame
@ -213,14 +213,14 @@ describe('When clicking', () => {
it('Erases a frame only when its clicked on the edge', () => { it('Erases a frame only when its clicked on the edge', () => {
editor.setCurrentTool('eraser') editor.setCurrentTool('eraser')
const shapesBeforeCount = editor.shapesOnCurrentPage.length const shapesBeforeCount = editor.currentPageShapes.length
editor.pointerDown(325, 25) // directly on frame1, not its children editor.pointerDown(325, 25) // directly on frame1, not its children
expect(editor.erasingShapeIdsSet).toEqual(new Set([])) expect(editor.erasingShapeIdsSet).toEqual(new Set([]))
editor.pointerUp() // without dragging! editor.pointerUp() // without dragging!
const shapesAfterCount = editor.shapesOnCurrentPage.length const shapesAfterCount = editor.currentPageShapes.length
expect(shapesAfterCount).toBe(shapesBeforeCount) expect(shapesAfterCount).toBe(shapesBeforeCount)
// Erases BOTH the frame and its child // Erases BOTH the frame and its child
@ -231,14 +231,14 @@ describe('When clicking', () => {
it('Only erases masked shapes when pointer is inside the mask', () => { it('Only erases masked shapes when pointer is inside the mask', () => {
editor.setCurrentTool('eraser') editor.setCurrentTool('eraser')
const shapesBeforeCount = editor.shapesOnCurrentPage.length const shapesBeforeCount = editor.currentPageShapes.length
editor.pointerDown(425, 125) // inside of box4's bounds, but outside of its parent's mask editor.pointerDown(425, 125) // inside of box4's bounds, but outside of its parent's mask
expect(editor.erasingShapeIdsSet).toEqual(new Set([])) expect(editor.erasingShapeIdsSet).toEqual(new Set([]))
editor.pointerUp() // without dragging! editor.pointerUp() // without dragging!
const shapesAfterCount = editor.shapesOnCurrentPage.length const shapesAfterCount = editor.currentPageShapes.length
expect(shapesAfterCount).toBe(shapesBeforeCount) expect(shapesAfterCount).toBe(shapesBeforeCount)
// Erases NEITHER the frame nor its child // Erases NEITHER the frame nor its child
@ -250,7 +250,7 @@ describe('When clicking', () => {
editor.setCurrentTool('eraser') editor.setCurrentTool('eraser')
editor.expectPathToBe('root.eraser.idle') editor.expectPathToBe('root.eraser.idle')
const shapesBeforeCount = editor.shapesOnCurrentPage.length const shapesBeforeCount = editor.currentPageShapes.length
editor.pointerDown(0, 0) // in box1 editor.pointerDown(0, 0) // in box1
editor.expectPathToBe('root.eraser.pointing') editor.expectPathToBe('root.eraser.pointing')
@ -262,7 +262,7 @@ describe('When clicking', () => {
editor.pointerUp() editor.pointerUp()
const shapesAfterCount = editor.shapesOnCurrentPage.length const shapesAfterCount = editor.currentPageShapes.length
editor.expectPathToBe('root.eraser.idle') editor.expectPathToBe('root.eraser.idle')
@ -277,7 +277,7 @@ describe('When clicking', () => {
editor.setCurrentTool('eraser') editor.setCurrentTool('eraser')
editor.expectPathToBe('root.eraser.idle') editor.expectPathToBe('root.eraser.idle')
const shapesBeforeCount = editor.shapesOnCurrentPage.length const shapesBeforeCount = editor.currentPageShapes.length
editor.pointerDown(0, 0) // near to box1 editor.pointerDown(0, 0) // near to box1
editor.expectPathToBe('root.eraser.pointing') editor.expectPathToBe('root.eraser.pointing')
@ -289,7 +289,7 @@ describe('When clicking', () => {
editor.pointerUp() editor.pointerUp()
const shapesAfterCount = editor.shapesOnCurrentPage.length const shapesAfterCount = editor.currentPageShapes.length
editor.expectPathToBe('root.eraser.idle') editor.expectPathToBe('root.eraser.idle')
@ -437,7 +437,7 @@ describe('When clicking and dragging', () => {
describe('Does not erase hollow shapes on click', () => { describe('Does not erase hollow shapes on click', () => {
it('Returns to select on cancel', () => { it('Returns to select on cancel', () => {
editor.selectAll().deleteShapes(editor.selectedShapes) editor.selectAll().deleteShapes(editor.selectedShapes)
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.createShape({ editor.createShape({
id: createShapeId(), id: createShapeId(),
type: 'geo', type: 'geo',
@ -447,7 +447,7 @@ describe('Does not erase hollow shapes on click', () => {
editor.pointerDown() editor.pointerDown()
expect(editor.erasingShapeIds).toEqual([]) expect(editor.erasingShapeIds).toEqual([])
editor.pointerUp() editor.pointerUp()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
}) })

View file

@ -45,33 +45,33 @@ describe('TLSelectTool.Translating', () => {
editor.pointerDown(150, 150, { target: 'shape', shape }) editor.pointerDown(150, 150, { target: 'shape', shape })
editor.pointerMove(200, 200) editor.pointerMove(200, 200)
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
editor.expectShapeToMatch({ id: ids.box1, x: 150, y: 150 }) editor.expectShapeToMatch({ id: ids.box1, x: 150, y: 150 })
const t1 = [...editor.shapeIdsOnCurrentPage.values()] const t1 = [...editor.currentPageShapeIds.values()]
editor.keyDown('Alt') editor.keyDown('Alt')
expect(editor.shapesOnCurrentPage.length).toBe(2) expect(editor.currentPageShapes.length).toBe(2)
editor.expectShapeToMatch({ id: ids.box1, x: 100, y: 100 }) editor.expectShapeToMatch({ id: ids.box1, x: 100, y: 100 })
// const t2 = [...editor.shapeIds.values()] // const t2 = [...editor.shapeIds.values()]
editor.keyUp('Alt') editor.keyUp('Alt')
// There's a timer here! We shouldn't end the clone until the timer is done // There's a timer here! We shouldn't end the clone until the timer is done
expect(editor.shapesOnCurrentPage.length).toBe(2) expect(editor.currentPageShapes.length).toBe(2)
jest.advanceTimersByTime(250) // tick tock jest.advanceTimersByTime(250) // tick tock
// Timer is done! We should have ended the clone. // Timer is done! We should have ended the clone.
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
editor.expectToBeIn('select.translating') editor.expectToBeIn('select.translating')
editor.expectShapeToMatch({ id: ids.box1, x: 150, y: 150 }) editor.expectShapeToMatch({ id: ids.box1, x: 150, y: 150 })
expect([...editor.shapeIdsOnCurrentPage.values()]).toMatchObject(t1) expect([...editor.currentPageShapeIds.values()]).toMatchObject(t1)
// todo: Should cloning again duplicate new shapes, or restore the last clone? // todo: Should cloning again duplicate new shapes, or restore the last clone?
// editor.keyDown('Alt') // editor.keyDown('Alt')
// expect(editor.shapesOnCurrentPage.length).toBe(2) // expect(editor.currentPageShapes.length).toBe(2)
// editor.expectShapeToMatch({ id: ids.box1, x: 100, y: 100 }) // editor.expectShapeToMatch({ id: ids.box1, x: 100, y: 100 })
// expect([...editor.shapeIds.values()]).toMatchObject(t2) // expect([...editor.shapeIds.values()]).toMatchObject(t2)
}) })
@ -95,7 +95,7 @@ describe('TLSelectTool.Translating', () => {
editor.pointerMove(150, 250) editor.pointerMove(150, 250)
editor.pointerUp() editor.pointerUp()
const box2Id = editor.onlySelectedShape!.id const box2Id = editor.onlySelectedShape!.id
expect(editor.shapesOnCurrentPage.length).toStrictEqual(2) expect(editor.currentPageShapes.length).toStrictEqual(2)
expect(ids.box1).not.toEqual(box2Id) expect(ids.box1).not.toEqual(box2Id)
// shift-alt-drag the original, we shouldn't duplicate the copy too: // shift-alt-drag the original, we shouldn't duplicate the copy too:
@ -103,7 +103,7 @@ describe('TLSelectTool.Translating', () => {
expect(editor.selectedShapeIds).toStrictEqual([ids.box1]) expect(editor.selectedShapeIds).toStrictEqual([ids.box1])
editor.pointerMove(250, 150) editor.pointerMove(250, 150)
editor.pointerUp() editor.pointerUp()
expect(editor.shapesOnCurrentPage.length).toStrictEqual(3) expect(editor.currentPageShapes.length).toStrictEqual(3)
}) })
}) })
@ -173,7 +173,7 @@ describe('When double clicking a shape', () => {
.deleteShapes(editor.selectedShapeIds) .deleteShapes(editor.selectedShapeIds)
.selectNone() .selectNone()
.createShapes([{ id: createShapeId(), type: 'geo' }]) .createShapes([{ id: createShapeId(), type: 'geo' }])
.doubleClick(50, 50, { target: 'shape', shape: editor.shapesOnCurrentPage[0] }) .doubleClick(50, 50, { target: 'shape', shape: editor.currentPageShapes[0] })
.expectToBeIn('select.editing_shape') .expectToBeIn('select.editing_shape')
}) })
}) })
@ -358,45 +358,45 @@ describe('When editing shapes', () => {
it('Double clicking the canvas creates a new text shape', () => { it('Double clicking the canvas creates a new text shape', () => {
expect(editor.editingShapeId).toBe(null) expect(editor.editingShapeId).toBe(null)
expect(editor.selectedShapeIds.length).toBe(0) expect(editor.selectedShapeIds.length).toBe(0)
expect(editor.shapesOnCurrentPage.length).toBe(5) expect(editor.currentPageShapes.length).toBe(5)
editor.doubleClick(750, 750) editor.doubleClick(750, 750)
expect(editor.shapesOnCurrentPage.length).toBe(6) expect(editor.currentPageShapes.length).toBe(6)
expect(editor.shapesOnCurrentPage[5].type).toBe('text') expect(editor.currentPageShapes[5].type).toBe('text')
}) })
it('It deletes an empty text shape when your click away', () => { it('It deletes an empty text shape when your click away', () => {
expect(editor.editingShapeId).toBe(null) expect(editor.editingShapeId).toBe(null)
expect(editor.selectedShapeIds.length).toBe(0) expect(editor.selectedShapeIds.length).toBe(0)
expect(editor.shapesOnCurrentPage.length).toBe(5) expect(editor.currentPageShapes.length).toBe(5)
// Create a new shape by double clicking // Create a new shape by double clicking
editor.doubleClick(750, 750) editor.doubleClick(750, 750)
expect(editor.selectedShapeIds.length).toBe(1) expect(editor.selectedShapeIds.length).toBe(1)
expect(editor.shapesOnCurrentPage.length).toBe(6) expect(editor.currentPageShapes.length).toBe(6)
const shapeId = editor.selectedShapeIds[0] const shapeId = editor.selectedShapeIds[0]
// Click away // Click away
editor.click(1000, 1000) editor.click(1000, 1000)
expect(editor.selectedShapeIds.length).toBe(0) expect(editor.selectedShapeIds.length).toBe(0)
expect(editor.shapesOnCurrentPage.length).toBe(5) expect(editor.currentPageShapes.length).toBe(5)
expect(editor.getShape(shapeId)).toBe(undefined) expect(editor.getShape(shapeId)).toBe(undefined)
}) })
it('It deletes an empty text shape when your click another text shape', () => { it('It deletes an empty text shape when your click another text shape', () => {
expect(editor.editingShapeId).toBe(null) expect(editor.editingShapeId).toBe(null)
expect(editor.selectedShapeIds.length).toBe(0) expect(editor.selectedShapeIds.length).toBe(0)
expect(editor.shapesOnCurrentPage.length).toBe(5) expect(editor.currentPageShapes.length).toBe(5)
// Create a new shape by double clicking // Create a new shape by double clicking
editor.doubleClick(750, 750) editor.doubleClick(750, 750)
expect(editor.selectedShapeIds.length).toBe(1) expect(editor.selectedShapeIds.length).toBe(1)
expect(editor.shapesOnCurrentPage.length).toBe(6) expect(editor.currentPageShapes.length).toBe(6)
const shapeId = editor.selectedShapeIds[0] const shapeId = editor.selectedShapeIds[0]
// Click another text shape // Click another text shape
editor.click(50, 50, { target: 'shape', shape: editor.getShape(ids.text1) }) editor.click(50, 50, { target: 'shape', shape: editor.getShape(ids.text1) })
expect(editor.selectedShapeIds.length).toBe(1) expect(editor.selectedShapeIds.length).toBe(1)
expect(editor.shapesOnCurrentPage.length).toBe(5) expect(editor.currentPageShapes.length).toBe(5)
expect(editor.getShape(shapeId)).toBe(undefined) expect(editor.getShape(shapeId)).toBe(undefined)
}) })

View file

@ -479,11 +479,11 @@ export class TestEditor extends Editor {
this.setCurrentTool('select') this.setCurrentTool('select')
const handlePoint = this.selectionBounds!.getHandlePoint( const handlePoint = this.selectionRotatedPageBounds!.getHandlePoint(
ROTATE_CORNER_TO_SELECTION_CORNER[handle] ROTATE_CORNER_TO_SELECTION_CORNER[handle]
) )
.clone() .clone()
.rotWith(this.selectionBounds!.point, this.selectionRotation) .rotWith(this.selectionRotatedPageBounds!.point, this.selectionRotation)
const targetHandlePoint = Vec2d.RotWith(handlePoint, this.selectionPageCenter!, angleRadians) const targetHandlePoint = Vec2d.RotWith(handlePoint, this.selectionPageCenter!, angleRadians)
@ -500,7 +500,7 @@ export class TestEditor extends Editor {
* @public * @public
*/ */
get selectionPageCenter() { get selectionPageCenter() {
const { selectionBounds, selectionRotation } = this const { selectionRotatedPageBounds: selectionBounds, selectionRotation } = this
if (!selectionBounds) return null if (!selectionBounds) return null
return Vec2d.RotWith(selectionBounds.center, selectionBounds.point, selectionRotation) return Vec2d.RotWith(selectionBounds.center, selectionBounds.point, selectionRotation)
} }
@ -531,7 +531,7 @@ export class TestEditor extends Editor {
throw new Error('No selection') throw new Error('No selection')
} }
this.setCurrentTool('select') this.setCurrentTool('select')
const bounds = this.selectionBounds! const bounds = this.selectionRotatedPageBounds!
const preRotationHandlePoint = bounds.getHandlePoint(handle) const preRotationHandlePoint = bounds.getHandlePoint(handle)
const preRotationScaleOriginPoint = options?.altKey const preRotationScaleOriginPoint = options?.altKey
@ -575,9 +575,9 @@ export class TestEditor extends Editor {
* @public * @public
*/ */
getPageCenter(shape: TLShape) { getPageCenter(shape: TLShape) {
const pageTransform = this.getPageTransform(shape.id) const pageTransform = this.getShapePageTransform(shape.id)
if (!pageTransform) return null if (!pageTransform) return null
const center = this.getGeometry(shape).bounds.center const center = this.getShapeGeometry(shape).bounds.center
return Matrix2d.applyToPoint(pageTransform, center) return Matrix2d.applyToPoint(pageTransform, center)
} }
@ -592,7 +592,7 @@ export class TestEditor extends Editor {
* @param id - The id of the shape to get the page rotation for. * @param id - The id of the shape to get the page rotation for.
*/ */
getPageRotationById(id: TLShapeId): number { getPageRotationById(id: TLShapeId): number {
const pageTransform = this.getPageTransform(id) const pageTransform = this.getShapePageTransform(id)
if (pageTransform) { if (pageTransform) {
return Matrix2d.Decompose(pageTransform).rotation return Matrix2d.Decompose(pageTransform).rotation
} }

View file

@ -36,7 +36,7 @@ describe('Making an arrow on the page', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerMove(0, 0) editor.pointerMove(0, 0)
editor.pointerDown() editor.pointerDown()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
it('cleans up the arrow if the user did not start dragging', () => { it('cleans up the arrow if the user did not start dragging', () => {
@ -44,24 +44,24 @@ describe('Making an arrow on the page', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerMove(0, 0) editor.pointerMove(0, 0)
editor.click() editor.click()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
// with double click // with double click
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerMove(0, 0) editor.pointerMove(0, 0)
editor.doubleClick() editor.doubleClick()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
// with pointer up // with pointer up
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown() editor.pointerDown()
editor.pointerUp() editor.pointerUp()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
// did not add it to the history stack // did not add it to the history stack
editor.undo() editor.undo()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
editor.redo() editor.redo()
editor.redo() editor.redo()
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
}) })
it('keeps the arrow if the user dragged', () => { it('keeps the arrow if the user dragged', () => {
@ -75,7 +75,7 @@ describe('Making an arrow on the page', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown(0, 0) editor.pointerDown(0, 0)
editor.pointerMove(100, 0) editor.pointerMove(100, 0)
const arrow1 = editor.shapesOnCurrentPage[0] const arrow1 = editor.currentPageShapes[0]
expect(arrow()).toMatchObject({ expect(arrow()).toMatchObject({
type: 'arrow', type: 'arrow',
@ -262,25 +262,25 @@ describe('When starting an arrow inside of multiple shapes', () => {
it('does not create the arrow immediately', () => { it('does not create the arrow immediately', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
expect(arrow()).toBe(null) expect(arrow()).toBe(null)
}) })
it('does not create a shape if pointer up before drag', () => { it('does not create a shape if pointer up before drag', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
editor.pointerUp(50, 50) editor.pointerUp(50, 50)
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
}) })
it('creates the arrow after a drag, bound to the shape', () => { it('creates the arrow after a drag, bound to the shape', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown(50, 50) editor.pointerDown(50, 50)
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
expect(arrow()).toBe(null) expect(arrow()).toBe(null)
editor.pointerMove(55, 50) editor.pointerMove(55, 50)
expect(editor.shapesOnCurrentPage.length).toBe(2) expect(editor.currentPageShapes.length).toBe(2)
expect(arrow()).toMatchObject({ expect(arrow()).toMatchObject({
x: 50, x: 50,
y: 50, y: 50,
@ -308,10 +308,10 @@ describe('When starting an arrow inside of multiple shapes', () => {
it('always creates the arrow with an imprecise start point', () => { it('always creates the arrow with an imprecise start point', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown(20, 20) // upper left editor.pointerDown(20, 20) // upper left
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
expect(arrow()).toBe(null) expect(arrow()).toBe(null)
editor.pointerMove(25, 20) editor.pointerMove(25, 20)
expect(editor.shapesOnCurrentPage.length).toBe(2) expect(editor.currentPageShapes.length).toBe(2)
expect(arrow()).toMatchObject({ expect(arrow()).toMatchObject({
x: 20, x: 20,
y: 20, y: 20,
@ -340,11 +340,11 @@ describe('When starting an arrow inside of multiple shapes', () => {
it('after a pause before drag, creates an arrow with a precise start point', () => { it('after a pause before drag, creates an arrow with a precise start point', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown(20, 20) // upper left editor.pointerDown(20, 20) // upper left
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
expect(arrow()).toBe(null) expect(arrow()).toBe(null)
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
editor.pointerMove(25, 20) editor.pointerMove(25, 20)
expect(editor.shapesOnCurrentPage.length).toBe(2) expect(editor.currentPageShapes.length).toBe(2)
expect(arrow()).toMatchObject({ expect(arrow()).toMatchObject({
x: 20, x: 20,
y: 20, y: 20,
@ -383,10 +383,10 @@ describe('When starting an arrow inside of multiple shapes', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown(25, 25) editor.pointerDown(25, 25)
expect(editor.shapesOnCurrentPage.length).toBe(2) expect(editor.currentPageShapes.length).toBe(2)
expect(arrow()).toBe(null) expect(arrow()).toBe(null)
editor.pointerMove(30, 30) editor.pointerMove(30, 30)
expect(editor.shapesOnCurrentPage.length).toBe(3) expect(editor.currentPageShapes.length).toBe(3)
expect(arrow()).toMatchObject({ expect(arrow()).toMatchObject({
x: 25, x: 25,
y: 25, y: 25,
@ -417,10 +417,10 @@ describe('When starting an arrow inside of multiple shapes', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown(25, 25) editor.pointerDown(25, 25)
expect(editor.shapesOnCurrentPage.length).toBe(2) expect(editor.currentPageShapes.length).toBe(2)
expect(arrow()).toBe(null) expect(arrow()).toBe(null)
editor.pointerMove(30, 30) editor.pointerMove(30, 30)
expect(editor.shapesOnCurrentPage.length).toBe(3) expect(editor.currentPageShapes.length).toBe(3)
expect(arrow()).toMatchObject({ expect(arrow()).toMatchObject({
x: 25, x: 25,
y: 25, y: 25,
@ -462,10 +462,10 @@ describe('When starting an arrow inside of multiple shapes', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown(25, 25) editor.pointerDown(25, 25)
expect(editor.shapesOnCurrentPage.length).toBe(2) expect(editor.currentPageShapes.length).toBe(2)
expect(arrow()).toBe(null) expect(arrow()).toBe(null)
editor.pointerMove(30, 30) editor.pointerMove(30, 30)
expect(editor.shapesOnCurrentPage.length).toBe(3) expect(editor.currentPageShapes.length).toBe(3)
expect(arrow()).toMatchObject({ expect(arrow()).toMatchObject({
x: 25, x: 25,
y: 25, y: 25,
@ -498,10 +498,10 @@ describe('When starting an arrow inside of multiple shapes', () => {
editor.setCurrentTool('arrow') editor.setCurrentTool('arrow')
editor.pointerDown(25, 25) editor.pointerDown(25, 25)
expect(editor.shapesOnCurrentPage.length).toBe(2) expect(editor.currentPageShapes.length).toBe(2)
expect(arrow()).toBe(null) expect(arrow()).toBe(null)
editor.pointerMove(30, 30) editor.pointerMove(30, 30)
expect(editor.shapesOnCurrentPage.length).toBe(3) expect(editor.currentPageShapes.length).toBe(3)
expect(arrow()).toMatchObject({ expect(arrow()).toMatchObject({
x: 25, x: 25,
y: 25, y: 25,

View file

@ -134,18 +134,18 @@ describe('when multiple shapes are selected', () => {
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
const commonBounds = Box2d.Common([ const commonBounds = Box2d.Common([
editor.getPageBounds(ids.boxA)!, editor.getShapePageBounds(ids.boxA)!,
editor.getPageBounds(ids.boxB)!, editor.getShapePageBounds(ids.boxB)!,
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
]) ])
expect(commonBounds.midX).toBeCloseTo(editor.getPageBounds(ids.boxA)!.midX, 5) expect(commonBounds.midX).toBeCloseTo(editor.getShapePageBounds(ids.boxA)!.midX, 5)
expect(commonBounds.midX).toBeCloseTo(editor.getPageBounds(ids.boxB)!.midX, 5) expect(commonBounds.midX).toBeCloseTo(editor.getShapePageBounds(ids.boxB)!.midX, 5)
expect(commonBounds.midX).toBeCloseTo(editor.getPageBounds(ids.boxC)!.midX, 5) expect(commonBounds.midX).toBeCloseTo(editor.getShapePageBounds(ids.boxC)!.midX, 5)
expect(commonBounds.midY).toBeCloseTo(editor.getPageBounds(ids.boxA)!.midY, 5) expect(commonBounds.midY).toBeCloseTo(editor.getShapePageBounds(ids.boxA)!.midY, 5)
expect(commonBounds.midY).toBeCloseTo(editor.getPageBounds(ids.boxB)!.midY, 5) expect(commonBounds.midY).toBeCloseTo(editor.getShapePageBounds(ids.boxB)!.midY, 5)
expect(commonBounds.midY).toBeCloseTo(editor.getPageBounds(ids.boxC)!.midY, 5) expect(commonBounds.midY).toBeCloseTo(editor.getShapePageBounds(ids.boxC)!.midY, 5)
}) })
it('aligns top-left, when shapes are rotated', () => { it('aligns top-left, when shapes are rotated', () => {
@ -173,18 +173,18 @@ describe('when multiple shapes are selected', () => {
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
const commonBounds = Box2d.Common([ const commonBounds = Box2d.Common([
editor.getPageBounds(ids.boxA)!, editor.getShapePageBounds(ids.boxA)!,
editor.getPageBounds(ids.boxB)!, editor.getShapePageBounds(ids.boxB)!,
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
]) ])
expect(commonBounds.minX).toBeCloseTo(editor.getPageBounds(ids.boxA)!.minX, 5) expect(commonBounds.minX).toBeCloseTo(editor.getShapePageBounds(ids.boxA)!.minX, 5)
expect(commonBounds.minX).toBeCloseTo(editor.getPageBounds(ids.boxB)!.minX, 5) expect(commonBounds.minX).toBeCloseTo(editor.getShapePageBounds(ids.boxB)!.minX, 5)
expect(commonBounds.minX).toBeCloseTo(editor.getPageBounds(ids.boxC)!.minX, 5) expect(commonBounds.minX).toBeCloseTo(editor.getShapePageBounds(ids.boxC)!.minX, 5)
expect(commonBounds.minY).toBeCloseTo(editor.getPageBounds(ids.boxA)!.minY, 5) expect(commonBounds.minY).toBeCloseTo(editor.getShapePageBounds(ids.boxA)!.minY, 5)
expect(commonBounds.minY).toBeCloseTo(editor.getPageBounds(ids.boxB)!.minY, 5) expect(commonBounds.minY).toBeCloseTo(editor.getShapePageBounds(ids.boxB)!.minY, 5)
expect(commonBounds.minY).toBeCloseTo(editor.getPageBounds(ids.boxC)!.minY, 5) expect(commonBounds.minY).toBeCloseTo(editor.getShapePageBounds(ids.boxC)!.minY, 5)
}) })
it('aligns bottom-right, when shapes are rotated', () => { it('aligns bottom-right, when shapes are rotated', () => {
@ -213,17 +213,17 @@ describe('when multiple shapes are selected', () => {
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
const commonBounds = Box2d.Common([ const commonBounds = Box2d.Common([
editor.getPageBounds(ids.boxA)!, editor.getShapePageBounds(ids.boxA)!,
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
]) ])
expect(commonBounds.maxX).toBeCloseTo(editor.getPageBounds(ids.boxA)!.maxX, 5) expect(commonBounds.maxX).toBeCloseTo(editor.getShapePageBounds(ids.boxA)!.maxX, 5)
expect(commonBounds.maxX).toBeCloseTo(editor.getPageBounds(ids.boxB)!.maxX, 5) expect(commonBounds.maxX).toBeCloseTo(editor.getShapePageBounds(ids.boxB)!.maxX, 5)
expect(commonBounds.maxX).toBeCloseTo(editor.getPageBounds(ids.boxC)!.maxX, 5) expect(commonBounds.maxX).toBeCloseTo(editor.getShapePageBounds(ids.boxC)!.maxX, 5)
expect(commonBounds.maxX).toBeCloseTo(editor.getPageBounds(ids.boxA)!.maxX, 5) expect(commonBounds.maxX).toBeCloseTo(editor.getShapePageBounds(ids.boxA)!.maxX, 5)
expect(commonBounds.maxY).toBeCloseTo(editor.getPageBounds(ids.boxB)!.maxY, 5) expect(commonBounds.maxY).toBeCloseTo(editor.getShapePageBounds(ids.boxB)!.maxY, 5)
expect(commonBounds.maxY).toBeCloseTo(editor.getPageBounds(ids.boxC)!.maxY, 5) expect(commonBounds.maxY).toBeCloseTo(editor.getShapePageBounds(ids.boxC)!.maxY, 5)
}) })
}) })
@ -246,8 +246,8 @@ describe('When shapes are parented to other shapes...', () => {
editor.setSelectedShapeIds([ids.boxC, ids.boxB]) editor.setSelectedShapeIds([ids.boxC, ids.boxB])
const commonBoundsBefore = Box2d.Common([ const commonBoundsBefore = Box2d.Common([
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
editor.getPageBounds(ids.boxB)!, editor.getShapePageBounds(ids.boxB)!,
]) ])
editor.alignShapes(editor.selectedShapeIds, 'top') editor.alignShapes(editor.selectedShapeIds, 'top')
@ -256,8 +256,8 @@ describe('When shapes are parented to other shapes...', () => {
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
const commonBoundsAfter = Box2d.Common([ const commonBoundsAfter = Box2d.Common([
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
editor.getPageBounds(ids.boxB)!, editor.getShapePageBounds(ids.boxB)!,
]) ])
expect(commonBoundsBefore.minX).toBeCloseTo(commonBoundsAfter.minX) expect(commonBoundsBefore.minX).toBeCloseTo(commonBoundsAfter.minX)
@ -268,8 +268,8 @@ describe('When shapes are parented to other shapes...', () => {
editor.setSelectedShapeIds([ids.boxC, ids.boxB]) editor.setSelectedShapeIds([ids.boxC, ids.boxB])
const commonBoundsBefore = Box2d.Common([ const commonBoundsBefore = Box2d.Common([
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
editor.getPageBounds(ids.boxB)!, editor.getShapePageBounds(ids.boxB)!,
]) ])
editor.alignShapes(editor.selectedShapeIds, 'bottom') editor.alignShapes(editor.selectedShapeIds, 'bottom')
@ -278,8 +278,8 @@ describe('When shapes are parented to other shapes...', () => {
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
const commonBoundsAfter = Box2d.Common([ const commonBoundsAfter = Box2d.Common([
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
editor.getPageBounds(ids.boxB)!, editor.getShapePageBounds(ids.boxB)!,
]) ])
expect(commonBoundsBefore.maxX).toBeCloseTo(commonBoundsAfter.maxX) expect(commonBoundsBefore.maxX).toBeCloseTo(commonBoundsAfter.maxX)
@ -334,8 +334,8 @@ describe('When shapes are parented to a rotated shape...', () => {
editor.setSelectedShapeIds([ids.boxC, ids.boxB]) editor.setSelectedShapeIds([ids.boxC, ids.boxB])
const commonBoundsBefore = Box2d.Common([ const commonBoundsBefore = Box2d.Common([
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
editor.getPageBounds(ids.boxB)!, editor.getShapePageBounds(ids.boxB)!,
]) ])
editor.alignShapes(editor.selectedShapeIds, 'top') editor.alignShapes(editor.selectedShapeIds, 'top')
@ -344,26 +344,26 @@ describe('When shapes are parented to a rotated shape...', () => {
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
const commonBoundsAfter = Box2d.Common([ const commonBoundsAfter = Box2d.Common([
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
editor.getPageBounds(ids.boxB)!, editor.getShapePageBounds(ids.boxB)!,
]) ])
expect(commonBoundsBefore.minX).toBeCloseTo(commonBoundsAfter.minX) expect(commonBoundsBefore.minX).toBeCloseTo(commonBoundsAfter.minX)
expect(commonBoundsBefore.minY).toBeCloseTo(commonBoundsAfter.minY) expect(commonBoundsBefore.minY).toBeCloseTo(commonBoundsAfter.minY)
expect(commonBoundsAfter.minX).toBeCloseTo(editor.getPageBounds(ids.boxB)!.minX, 5) expect(commonBoundsAfter.minX).toBeCloseTo(editor.getShapePageBounds(ids.boxB)!.minX, 5)
expect(commonBoundsAfter.minX).toBeCloseTo(editor.getPageBounds(ids.boxC)!.minX, 5) expect(commonBoundsAfter.minX).toBeCloseTo(editor.getShapePageBounds(ids.boxC)!.minX, 5)
expect(commonBoundsAfter.minY).toBeCloseTo(editor.getPageBounds(ids.boxB)!.minY, 5) expect(commonBoundsAfter.minY).toBeCloseTo(editor.getShapePageBounds(ids.boxB)!.minY, 5)
expect(commonBoundsAfter.minY).toBeCloseTo(editor.getPageBounds(ids.boxC)!.minY, 5) expect(commonBoundsAfter.minY).toBeCloseTo(editor.getShapePageBounds(ids.boxC)!.minY, 5)
}) })
it('Aligns to the bottom right.', () => { it('Aligns to the bottom right.', () => {
editor.setSelectedShapeIds([ids.boxC, ids.boxB]) editor.setSelectedShapeIds([ids.boxC, ids.boxB])
const commonBoundsBefore = Box2d.Common([ const commonBoundsBefore = Box2d.Common([
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
editor.getPageBounds(ids.boxB)!, editor.getShapePageBounds(ids.boxB)!,
]) ])
editor.alignShapes(editor.selectedShapeIds, 'bottom') editor.alignShapes(editor.selectedShapeIds, 'bottom')
@ -372,17 +372,17 @@ describe('When shapes are parented to a rotated shape...', () => {
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
const commonBoundsAfter = Box2d.Common([ const commonBoundsAfter = Box2d.Common([
editor.getPageBounds(ids.boxC)!, editor.getShapePageBounds(ids.boxC)!,
editor.getPageBounds(ids.boxB)!, editor.getShapePageBounds(ids.boxB)!,
]) ])
expect(commonBoundsBefore.maxX).toBeCloseTo(commonBoundsAfter.maxX) expect(commonBoundsBefore.maxX).toBeCloseTo(commonBoundsAfter.maxX)
expect(commonBoundsBefore.maxY).toBeCloseTo(commonBoundsAfter.maxY) expect(commonBoundsBefore.maxY).toBeCloseTo(commonBoundsAfter.maxY)
expect(commonBoundsAfter.maxX).toBeCloseTo(editor.getPageBounds(ids.boxB)!.maxX, 5) expect(commonBoundsAfter.maxX).toBeCloseTo(editor.getShapePageBounds(ids.boxB)!.maxX, 5)
expect(commonBoundsAfter.maxX).toBeCloseTo(editor.getPageBounds(ids.boxC)!.maxX, 5) expect(commonBoundsAfter.maxX).toBeCloseTo(editor.getShapePageBounds(ids.boxC)!.maxX, 5)
expect(commonBoundsAfter.maxY).toBeCloseTo(editor.getPageBounds(ids.boxB)!.maxY, 5) expect(commonBoundsAfter.maxY).toBeCloseTo(editor.getShapePageBounds(ids.boxB)!.maxY, 5)
expect(commonBoundsAfter.maxY).toBeCloseTo(editor.getPageBounds(ids.boxC)!.maxY, 5) expect(commonBoundsAfter.maxY).toBeCloseTo(editor.getShapePageBounds(ids.boxC)!.maxY, 5)
}) })
}) })

View file

@ -39,7 +39,7 @@ it('gets common bounds', () => {
}, },
]) ])
expect(editor.commonBoundsOfAllShapesOnCurrentPage).toCloselyMatchObject({ expect(editor.currentPageBounds).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
h: 600, h: 600,
@ -62,7 +62,7 @@ it('gets common bounds', () => {
}, },
]) ])
expect(editor.commonBoundsOfAllShapesOnCurrentPage).toCloselyMatchObject({ expect(editor.currentPageBounds).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
h: 700, h: 700,
@ -82,7 +82,7 @@ it('gets common bounds', () => {
}, },
]) ])
expect(editor.commonBoundsOfAllShapesOnCurrentPage).toCloselyMatchObject({ expect(editor.currentPageBounds).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
h: 700, h: 700,

View file

@ -68,7 +68,7 @@ describe('When copying and pasting', () => {
{ id: ids.box2, type: 'geo', x: 300, y: 300, props: { w: 100, h: 100 } }, { id: ids.box2, type: 'geo', x: 300, y: 300, props: { w: 100, h: 100 } },
]) ])
const shapesBefore = editor.shapesOnCurrentPage const shapesBefore = editor.currentPageShapes
editor.selectAll().copy() editor.selectAll().copy()
await assertClipboardOfCorrectShape(mockClipboard.current) await assertClipboardOfCorrectShape(mockClipboard.current)
@ -82,7 +82,7 @@ describe('When copying and pasting', () => {
}) })
editor.paste() editor.paste()
const shapesAfter = editor.shapesOnCurrentPage const shapesAfter = editor.currentPageShapes
// We should not have changed the original shapes // We should not have changed the original shapes
expect(shapesBefore[0]).toMatchObject(shapesAfter[0]) expect(shapesBefore[0]).toMatchObject(shapesAfter[0])
@ -113,7 +113,7 @@ describe('When copying and pasting', () => {
{ id: ids.box2, type: 'geo', x: 1900, y: 0, props: { w: 100, h: 100 } }, { id: ids.box2, type: 'geo', x: 1900, y: 0, props: { w: 100, h: 100 } },
]) ])
const shapesBefore = editor.shapesOnCurrentPage const shapesBefore = editor.currentPageShapes
editor.selectAll().copy() editor.selectAll().copy()
await assertClipboardOfCorrectShape(mockClipboard.current) await assertClipboardOfCorrectShape(mockClipboard.current)
@ -127,7 +127,7 @@ describe('When copying and pasting', () => {
}) })
editor.paste() editor.paste()
const shapesAfter = editor.shapesOnCurrentPage const shapesAfter = editor.currentPageShapes
// We should not have changed the original shapes // We should not have changed the original shapes
expect(shapesBefore[0]).toMatchObject(shapesAfter[0]) expect(shapesBefore[0]).toMatchObject(shapesAfter[0])
@ -153,7 +153,7 @@ describe('When copying and pasting', () => {
{ id: ids.box2, type: 'geo', x: 0, y: 0, props: { w: 100, h: 100 } }, { id: ids.box2, type: 'geo', x: 0, y: 0, props: { w: 100, h: 100 } },
]) ])
const shapesBefore = editor.shapesOnCurrentPage const shapesBefore = editor.currentPageShapes
editor.selectAll().copy() editor.selectAll().copy()
await assertClipboardOfCorrectShape(mockClipboard.current) await assertClipboardOfCorrectShape(mockClipboard.current)
@ -169,7 +169,7 @@ describe('When copying and pasting', () => {
}) })
editor.paste() editor.paste()
const shapesAfter = editor.shapesOnCurrentPage const shapesAfter = editor.currentPageShapes
// We should not have changed the original shapes // We should not have changed the original shapes
expect(shapesBefore[0]).toMatchObject(shapesAfter[0]) expect(shapesBefore[0]).toMatchObject(shapesAfter[0])
@ -226,14 +226,14 @@ describe('When copying and pasting', () => {
}, },
]) ])
const shapesBefore = editor.shapesOnCurrentPage const shapesBefore = editor.currentPageShapes
editor.selectAll().copy() editor.selectAll().copy()
// Test the shape of the clipboard data. // Test the shape of the clipboard data.
await assertClipboardOfCorrectShape(mockClipboard.current) await assertClipboardOfCorrectShape(mockClipboard.current)
editor.paste() editor.paste()
const shapesAfter = editor.shapesOnCurrentPage const shapesAfter = editor.currentPageShapes
// We should not have changed the original shapes // We should not have changed the original shapes
expect(shapesBefore[0]).toMatchObject(shapesAfter[0]) expect(shapesBefore[0]).toMatchObject(shapesAfter[0])
@ -285,7 +285,7 @@ describe('When copying and pasting', () => {
{ id: ids.box2, type: 'geo', x: 300, y: 300, props: { w: 100, h: 100 } }, { id: ids.box2, type: 'geo', x: 300, y: 300, props: { w: 100, h: 100 } },
]) ])
const shapesBefore = editor.shapesOnCurrentPage const shapesBefore = editor.currentPageShapes
editor.selectAll().cut() editor.selectAll().cut()
await assertClipboardOfCorrectShape(mockClipboard.current) await assertClipboardOfCorrectShape(mockClipboard.current)
@ -299,7 +299,7 @@ describe('When copying and pasting', () => {
}) })
editor.paste() editor.paste()
const shapesAfter = editor.shapesOnCurrentPage const shapesAfter = editor.currentPageShapes
// The new shapes should match the old shapes, except for their id // The new shapes should match the old shapes, except for their id
expect(shapesAfter.length).toBe(shapesBefore.length) expect(shapesAfter.length).toBe(shapesBefore.length)
@ -315,7 +315,7 @@ describe('When copying and pasting', () => {
{ id: ids.box2, type: 'geo', x: 1900, y: 0, props: { w: 100, h: 100 } }, { id: ids.box2, type: 'geo', x: 1900, y: 0, props: { w: 100, h: 100 } },
]) ])
const shapesBefore = editor.shapesOnCurrentPage const shapesBefore = editor.currentPageShapes
editor.selectAll().cut() editor.selectAll().cut()
await assertClipboardOfCorrectShape(mockClipboard.current) await assertClipboardOfCorrectShape(mockClipboard.current)
@ -329,7 +329,7 @@ describe('When copying and pasting', () => {
}) })
editor.paste() editor.paste()
const shapesAfter = editor.shapesOnCurrentPage const shapesAfter = editor.currentPageShapes
// The new shapes should match the old shapes, except for their id // The new shapes should match the old shapes, except for their id
expect(shapesAfter.length).toBe(shapesBefore.length) expect(shapesAfter.length).toBe(shapesBefore.length)
@ -346,7 +346,7 @@ describe('When copying and pasting', () => {
{ id: ids.box2, type: 'geo', x: 0, y: 0, props: { w: 100, h: 100 } }, { id: ids.box2, type: 'geo', x: 0, y: 0, props: { w: 100, h: 100 } },
]) ])
const shapesBefore = editor.shapesOnCurrentPage const shapesBefore = editor.currentPageShapes
editor.selectAll().cut() editor.selectAll().cut()
await assertClipboardOfCorrectShape(mockClipboard.current) await assertClipboardOfCorrectShape(mockClipboard.current)
@ -362,7 +362,7 @@ describe('When copying and pasting', () => {
}) })
editor.paste() editor.paste()
const shapesAfter = editor.shapesOnCurrentPage const shapesAfter = editor.currentPageShapes
// The new shapes should match the old shapes, except for the should be positioned on the new viewport center. // The new shapes should match the old shapes, except for the should be positioned on the new viewport center.
expect(shapesAfter.length).toBe(shapesBefore.length) expect(shapesAfter.length).toBe(shapesBefore.length)
@ -408,7 +408,7 @@ describe('When copying and pasting', () => {
}, },
]) ])
const shapesBefore = editor.shapesOnCurrentPage const shapesBefore = editor.currentPageShapes
editor.selectAll().cut() editor.selectAll().cut()
@ -416,7 +416,7 @@ describe('When copying and pasting', () => {
await assertClipboardOfCorrectShape(mockClipboard.current) await assertClipboardOfCorrectShape(mockClipboard.current)
editor.paste() editor.paste()
const shapesAfter = editor.shapesOnCurrentPage const shapesAfter = editor.currentPageShapes
// The new shapes should match the old shapes, except for their id and the arrow's bindings! // The new shapes should match the old shapes, except for their id and the arrow's bindings!
expect(shapesAfter.length).toBe(shapesBefore.length) expect(shapesAfter.length).toBe(shapesBefore.length)
@ -450,7 +450,7 @@ describe('When copying and pasting', () => {
// Move the group // Move the group
.updateShapes([ .updateShapes([
{ {
id: editor.shapesOnCurrentPage[2].id, id: editor.currentPageShapes[2].id,
type: 'group', type: 'group',
x: 400, x: 400,
y: 400, y: 400,
@ -464,12 +464,12 @@ describe('When copying and pasting', () => {
await assertClipboardOfCorrectShape(mockClipboard.current) await assertClipboardOfCorrectShape(mockClipboard.current)
// Paste the shape // Paste the shape
expect(editor.shapesOnCurrentPage.length).toEqual(3) expect(editor.currentPageShapes.length).toEqual(3)
editor.paste() editor.paste()
expect(editor.shapesOnCurrentPage.length).toEqual(4) expect(editor.currentPageShapes.length).toEqual(4)
// Check if the position is correct // Check if the position is correct
const pastedShape = editor.shapesOnCurrentPage[editor.shapesOnCurrentPage.length - 1] const pastedShape = editor.currentPageShapes[editor.currentPageShapes.length - 1]
const pastedPoint = { x: pastedShape.x, y: pastedShape.y } const pastedPoint = { x: pastedShape.x, y: pastedShape.y }
expect(pastedPoint).toMatchObject({ x: 150, y: 150 }) // center of group expect(pastedPoint).toMatchObject({ x: 150, y: 150 }) // center of group

View file

@ -117,13 +117,13 @@ it('Creates shapes at the correct index', () => {
}) })
it('Throws out all shapes if any shape is invalid', () => { it('Throws out all shapes if any shape is invalid', () => {
const n = editor.shapeIdsOnCurrentPage.size const n = editor.currentPageShapeIds.size
expect(() => { expect(() => {
editor.createShapes([{ id: ids.box1, type: 'geo' }]) editor.createShapes([{ id: ids.box1, type: 'geo' }])
}).not.toThrow() }).not.toThrow()
expect(editor.shapeIdsOnCurrentPage.size).toBe(n + 1) expect(editor.currentPageShapeIds.size).toBe(n + 1)
console.error = jest.fn() console.error = jest.fn()
@ -136,5 +136,5 @@ it('Throws out all shapes if any shape is invalid', () => {
]) ])
}).toThrow() }).toThrow()
expect(editor.shapeIdsOnCurrentPage.size).toBe(n + 1) expect(editor.currentPageShapeIds.size).toBe(n + 1)
}) })

View file

@ -17,7 +17,7 @@ it('Duplicates a page', () => {
const oldPageId = editor.currentPageId const oldPageId = editor.currentPageId
const camera = { ...editor.camera } const camera = { ...editor.camera }
const n = editor.pages.length const n = editor.pages.length
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
const existingIds = new Set(editor.pages.map((s) => s.id)) const existingIds = new Set(editor.pages.map((s) => s.id))
@ -31,7 +31,7 @@ it('Duplicates a page', () => {
expect(editor.currentPageId).toBe(newPageId) expect(editor.currentPageId).toBe(newPageId)
// Duplicates the shapes // Duplicates the shapes
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
// Also duplicates the camera // Also duplicates the camera
expect(editor.camera.x).toBe(camera.x) expect(editor.camera.x).toBe(camera.x)

View file

@ -8,12 +8,14 @@ beforeEach(() => {
}) })
it('Sets shape meta by default to an empty object', () => { it('Sets shape meta by default to an empty object', () => {
editor.createShapes([{ id: createShapeId(), type: 'geo' }], true) const id = createShapeId()
editor.createShapes([{ id, type: 'geo' }]).select(id)
expect(editor.onlySelectedShape!.meta).toStrictEqual({}) expect(editor.onlySelectedShape!.meta).toStrictEqual({})
}) })
it('Sets shape meta', () => { it('Sets shape meta', () => {
editor.getInitialMetaForShape = (shape) => ({ firstThreeCharactersOfId: shape.id.slice(0, 3) }) editor.getInitialMetaForShape = (shape) => ({ firstThreeCharactersOfId: shape.id.slice(0, 3) })
editor.createShapes([{ id: createShapeId(), type: 'geo' }], true) const id = createShapeId()
editor.createShapes([{ id, type: 'geo' }]).select(id)
expect(editor.onlySelectedShape!.meta).toStrictEqual({ firstThreeCharactersOfId: 'sha' }) expect(editor.onlySelectedShape!.meta).toStrictEqual({ firstThreeCharactersOfId: 'sha' })
}) })

View file

@ -63,7 +63,7 @@ it('Does not get an SVG when no ids are provided', async () => {
it('Gets the bounding box at the correct size', async () => { it('Gets the bounding box at the correct size', async () => {
const svg = await editor.getSvg(editor.selectedShapeIds) const svg = await editor.getSvg(editor.selectedShapeIds)
const bbox = editor.selectionBounds! const bbox = editor.selectionRotatedPageBounds!
const expanded = bbox.expandBy(SVG_PADDING) // adds 32px padding const expanded = bbox.expandBy(SVG_PADDING) // adds 32px padding
expect(svg!.getAttribute('width')).toMatch(expanded.width + '') expect(svg!.getAttribute('width')).toMatch(expanded.width + '')
@ -72,7 +72,7 @@ it('Gets the bounding box at the correct size', async () => {
it('Gets the bounding box at the correct size', async () => { it('Gets the bounding box at the correct size', async () => {
const svg = (await editor.getSvg(editor.selectedShapeIds))! const svg = (await editor.getSvg(editor.selectedShapeIds))!
const bbox = editor.selectionBounds! const bbox = editor.selectionRotatedPageBounds!
const expanded = bbox.expandBy(SVG_PADDING) // adds 32px padding const expanded = bbox.expandBy(SVG_PADDING) // adds 32px padding
expect(svg!.getAttribute('width')).toMatch(expanded.width + '') expect(svg!.getAttribute('width')).toMatch(expanded.width + '')

View file

@ -92,9 +92,9 @@ describe('Locking', () => {
describe('Locked shapes', () => { describe('Locked shapes', () => {
it('Cannot be deleted', () => { it('Cannot be deleted', () => {
const numberOfShapesBefore = editor.shapesOnCurrentPage.length const numberOfShapesBefore = editor.currentPageShapes.length
editor.deleteShapes([ids.lockedShapeA]) editor.deleteShapes([ids.lockedShapeA])
expect(editor.shapesOnCurrentPage.length).toBe(numberOfShapesBefore) expect(editor.currentPageShapes.length).toBe(numberOfShapesBefore)
}) })
it('Cannot be changed', () => { it('Cannot be changed', () => {
@ -133,20 +133,20 @@ describe('Locked shapes', () => {
it('Cannot be edited', () => { it('Cannot be edited', () => {
const shape = editor.getShape(ids.lockedShapeA)! const shape = editor.getShape(ids.lockedShapeA)!
const shapeCount = editor.shapesOnCurrentPage.length const shapeCount = editor.currentPageShapes.length
// We create a new shape and we edit that one // We create a new shape and we edit that one
editor.doubleClick(10, 10, { target: 'shape', shape }).expectToBeIn('select.editing_shape') editor.doubleClick(10, 10, { target: 'shape', shape }).expectToBeIn('select.editing_shape')
expect(editor.shapesOnCurrentPage.length).toBe(shapeCount + 1) expect(editor.currentPageShapes.length).toBe(shapeCount + 1)
expect(editor.selectedShapeIds).not.toContain(shape.id) expect(editor.selectedShapeIds).not.toContain(shape.id)
}) })
it('Cannot be grouped', () => { it('Cannot be grouped', () => {
const shapeCount = editor.shapesOnCurrentPage.length const shapeCount = editor.currentPageShapes.length
const parentBefore = editor.getShape(ids.lockedShapeA)!.parentId const parentBefore = editor.getShape(ids.lockedShapeA)!.parentId
editor.groupShapes([ids.lockedShapeA, ids.unlockedShapeA, ids.unlockedShapeB]) editor.groupShapes([ids.lockedShapeA, ids.unlockedShapeA, ids.unlockedShapeB])
expect(editor.shapesOnCurrentPage.length).toBe(shapeCount + 1) expect(editor.currentPageShapes.length).toBe(shapeCount + 1)
const parentAfter = editor.getShape(ids.lockedShapeA)!.parentId const parentAfter = editor.getShape(ids.lockedShapeA)!.parentId
expect(parentAfter).toBe(parentBefore) expect(parentAfter).toBe(parentBefore)

View file

@ -38,13 +38,13 @@ describe('Editor.moveShapesToPage', () => {
// box1 didn't get moved, still on page 1 // box1 didn't get moved, still on page 1
expect(editor.getShape(ids.box1)!.parentId).toBe(ids.page1) expect(editor.getShape(ids.box1)!.parentId).toBe(ids.page1)
expect([...editor.shapeIdsOnCurrentPage].sort()).toMatchObject([ids.box2, ids.ellipse1]) expect([...editor.currentPageShapeIds].sort()).toMatchObject([ids.box2, ids.ellipse1])
expect(editor.currentPageId).toBe(ids.page2) expect(editor.currentPageId).toBe(ids.page2)
editor.setCurrentPage(ids.page1) editor.setCurrentPage(ids.page1)
expect([...editor.shapeIdsOnCurrentPage]).toEqual([ids.box1]) expect([...editor.currentPageShapeIds]).toEqual([ids.box1])
}) })
it('Moves children to page', () => { it('Moves children to page', () => {
@ -80,31 +80,23 @@ describe('Editor.moveShapesToPage', () => {
it('Restores on undo / redo', () => { it('Restores on undo / redo', () => {
expect(editor.currentPageId).toBe(ids.page1) expect(editor.currentPageId).toBe(ids.page1)
expect([...editor.shapeIdsOnCurrentPage].sort()).toMatchObject([ expect([...editor.currentPageShapeIds].sort()).toMatchObject([ids.box1, ids.box2, ids.ellipse1])
ids.box1,
ids.box2,
ids.ellipse1,
])
editor.mark('move shapes to page') editor.mark('move shapes to page')
editor.moveShapesToPage([ids.box2], ids.page2) editor.moveShapesToPage([ids.box2], ids.page2)
expect(editor.currentPageId).toBe(ids.page2) expect(editor.currentPageId).toBe(ids.page2)
expect([...editor.shapeIdsOnCurrentPage].sort()).toMatchObject([ids.box2]) expect([...editor.currentPageShapeIds].sort()).toMatchObject([ids.box2])
editor.undo() editor.undo()
expect(editor.currentPageId).toBe(ids.page1) expect(editor.currentPageId).toBe(ids.page1)
expect([...editor.shapeIdsOnCurrentPage].sort()).toMatchObject([ expect([...editor.currentPageShapeIds].sort()).toMatchObject([ids.box1, ids.box2, ids.ellipse1])
ids.box1,
ids.box2,
ids.ellipse1,
])
editor.redo() editor.redo()
expect(editor.currentPageId).toBe(ids.page2) expect(editor.currentPageId).toBe(ids.page2)
expect([...editor.shapeIdsOnCurrentPage].sort()).toMatchObject([ids.box2]) expect([...editor.currentPageShapeIds].sort()).toMatchObject([ids.box2])
}) })
it('Sets the correct indices', () => { it('Sets the correct indices', () => {
@ -192,7 +184,7 @@ describe('arrows', () => {
editor.pointerUp(450, 450) editor.pointerUp(450, 450)
const arrow = editor.onlySelectedShape! const arrow = editor.onlySelectedShape!
expect(editor.getPageBounds(editor.onlySelectedShape!)).toCloselyMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toCloselyMatchObject({
// exiting at the bottom right corner of the first box // exiting at the bottom right corner of the first box
x: 300, x: 300,
y: 300, y: 300,
@ -210,7 +202,7 @@ describe('arrows', () => {
expect(editor.getArrowsBoundTo(firstBox.id).length).toBe(1) expect(editor.getArrowsBoundTo(firstBox.id).length).toBe(1)
expect(editor.getArrowsBoundTo(secondBox.id).length).toBe(0) expect(editor.getArrowsBoundTo(secondBox.id).length).toBe(0)
expect(editor.getPageBounds(arrow)).toCloselyMatchObject({ expect(editor.getShapePageBounds(arrow)).toCloselyMatchObject({
x: 300, x: 300,
y: 250, y: 250,
w: 150, w: 150,

View file

@ -41,13 +41,13 @@ beforeEach(() => {
describe('editor.packShapes', () => { describe('editor.packShapes', () => {
it('packs shapes', () => { it('packs shapes', () => {
editor.selectAll() editor.selectAll()
const centerBefore = editor.selectionBounds!.center.clone() const centerBefore = editor.selectionRotatedPageBounds!.center.clone()
editor.packShapes(editor.selectedShapeIds, 16) editor.packShapes(editor.selectedShapeIds, 16)
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
expect(editor.shapesOnCurrentPage.map((s) => ({ ...s, parentId: 'wahtever' }))).toMatchSnapshot( expect(editor.currentPageShapes.map((s) => ({ ...s, parentId: 'wahtever' }))).toMatchSnapshot(
'packed shapes' 'packed shapes'
) )
const centerAfter = editor.selectionBounds!.center.clone() const centerAfter = editor.selectionRotatedPageBounds!.center.clone()
expect(centerBefore).toMatchObject(centerAfter) expect(centerBefore).toMatchObject(centerAfter)
}) })
@ -55,7 +55,7 @@ describe('editor.packShapes', () => {
editor.updateShapes([{ id: ids.boxA, type: 'geo', rotation: Math.PI }]) editor.updateShapes([{ id: ids.boxA, type: 'geo', rotation: Math.PI }])
editor.selectAll().packShapes(editor.selectedShapeIds, 16) editor.selectAll().packShapes(editor.selectedShapeIds, 16)
jest.advanceTimersByTime(1000) jest.advanceTimersByTime(1000)
expect(editor.shapesOnCurrentPage.map((s) => ({ ...s, parentId: 'wahtever' }))).toMatchSnapshot( expect(editor.currentPageShapes.map((s) => ({ ...s, parentId: 'wahtever' }))).toMatchSnapshot(
'packed shapes' 'packed shapes'
) )
}) })

View file

@ -23,5 +23,5 @@ it('ignores touch events while in pen mode', async () => {
target: 'canvas', target: 'canvas',
}) })
expect(editor.shapesOnCurrentPage.length).toBe(0) expect(editor.currentPageShapes.length).toBe(0)
}) })

View file

@ -4,7 +4,7 @@ import { TestEditor } from '../TestEditor'
let editor: TestEditor let editor: TestEditor
function expectShapesInOrder(editor: TestEditor, ...ids: TLShapeId[]) { function expectShapesInOrder(editor: TestEditor, ...ids: TLShapeId[]) {
expect(editor.sortedShapesOnCurrentPage.map((shape) => shape.id)).toMatchObject(ids) expect(editor.currentPageShapesSorted.map((shape) => shape.id)).toMatchObject(ids)
} }
function getSiblingBelow(editor: TestEditor, id: TLShapeId) { function getSiblingBelow(editor: TestEditor, id: TLShapeId) {
@ -68,7 +68,7 @@ beforeEach(() => {
describe('When running zindex tests', () => { describe('When running zindex tests', () => {
it('Correctly initializes indices', () => { it('Correctly initializes indices', () => {
expect(editor.sortedShapesOnCurrentPage.map((shape) => shape.index)).toMatchObject([ expect(editor.currentPageShapesSorted.map((shape) => shape.index)).toMatchObject([
'a1', 'a1',
'a2', 'a2',
'a3', 'a3',

View file

@ -39,13 +39,13 @@ it('reparents a shape', () => {
it('preserves shape page transfors', () => { it('preserves shape page transfors', () => {
const before = editor.getShape(ids.box1)! const before = editor.getShape(ids.box1)!
const A = editor.getPageTransform(ids.box1) const A = editor.getShapePageTransform(ids.box1)
const A1 = editor.getTransform(before) const A1 = editor.getShapeLocalTransform(before)
editor.reparentShapes([ids.box2], ids.box1) editor.reparentShapes([ids.box2], ids.box1)
const after = editor.getShape(ids.box1)! const after = editor.getShape(ids.box1)!
const B = editor.getPageTransform(ids.box1)! const B = editor.getShapePageTransform(ids.box1)!
const B1 = editor.getTransform(after) const B1 = editor.getShapeLocalTransform(after)
expect(A1).toMatchObject(B1) expect(A1).toMatchObject(B1)
expect(A).toMatchObject(B) expect(A).toMatchObject(B)
}) })

View file

@ -32,13 +32,13 @@ describe('resizing a shape', () => {
editor.resizeShape(ids.boxA, { x: 2, y: 2 }) editor.resizeShape(ids.boxA, { x: 2, y: 2 })
expect(editor.history.numUndos).toBe(startHistoryLength + 1) expect(editor.history.numUndos).toBe(startHistoryLength + 1)
expect(editor.getPageBounds(ids.boxA)).toCloselyMatchObject({ expect(editor.getShapePageBounds(ids.boxA)).toCloselyMatchObject({
w: 800, w: 800,
h: 800, h: 800,
}) })
editor.undo() editor.undo()
expect(editor.getPageBounds(ids.boxA)).toCloselyMatchObject({ expect(editor.getShapePageBounds(ids.boxA)).toCloselyMatchObject({
w: 100, w: 100,
h: 100, h: 100,
}) })
@ -48,7 +48,7 @@ describe('resizing a shape', () => {
editor.createShapes([{ id: ids.boxA, type: 'geo', props: { w: 100, h: 100 } }]) editor.createShapes([{ id: ids.boxA, type: 'geo', props: { w: 100, h: 100 } }])
editor.resizeShape(ids.boxA, { x: 2, y: 2 }) editor.resizeShape(ids.boxA, { x: 2, y: 2 })
expect(editor.getPageBounds(ids.boxA)).toCloselyMatchObject({ expect(editor.getShapePageBounds(ids.boxA)).toCloselyMatchObject({
x: -50, x: -50,
y: -50, y: -50,
w: 200, w: 200,

View file

@ -27,9 +27,9 @@ for (const toolType of ['draw', 'highlight'] as const) {
.pointerUp() .pointerUp()
.expectToBeIn(`${toolType}.idle`) .expectToBeIn(`${toolType}.idle`)
expect(editor.shapesOnCurrentPage).toHaveLength(1) expect(editor.currentPageShapes).toHaveLength(1)
const shape = editor.shapesOnCurrentPage[0] as DrawableShape const shape = editor.currentPageShapes[0] as DrawableShape
expect(shape.type).toBe(toolType) expect(shape.type).toBe(toolType)
expect(shape.props.segments.length).toBe(1) expect(shape.props.segments.length).toBe(1)
@ -46,9 +46,9 @@ for (const toolType of ['draw', 'highlight'] as const) {
.pointerUp() .pointerUp()
.expectToBeIn(`${toolType}.idle`) .expectToBeIn(`${toolType}.idle`)
expect(editor.shapesOnCurrentPage).toHaveLength(1) expect(editor.currentPageShapes).toHaveLength(1)
const shape = editor.shapesOnCurrentPage[0] as DrawableShape const shape = editor.currentPageShapes[0] as DrawableShape
expect(shape.type).toBe(toolType) expect(shape.type).toBe(toolType)
expect(shape.props.segments.length).toBe(1) expect(shape.props.segments.length).toBe(1)
@ -59,7 +59,7 @@ for (const toolType of ['draw', 'highlight'] as const) {
it('Creates a free draw line when shift is not held', () => { it('Creates a free draw line when shift is not held', () => {
editor.setCurrentTool(toolType).pointerDown(10, 10).pointerMove(20, 20) editor.setCurrentTool(toolType).pointerDown(10, 10).pointerMove(20, 20)
const shape = editor.shapesOnCurrentPage[0] as DrawableShape const shape = editor.currentPageShapes[0] as DrawableShape
expect(shape.props.segments.length).toBe(1) expect(shape.props.segments.length).toBe(1)
const segment = shape.props.segments[0] const segment = shape.props.segments[0]
@ -69,7 +69,7 @@ for (const toolType of ['draw', 'highlight'] as const) {
it('Creates a straight line when shift is held', () => { it('Creates a straight line when shift is held', () => {
editor.setCurrentTool(toolType).keyDown('Shift').pointerDown(10, 10).pointerMove(20, 20) editor.setCurrentTool(toolType).keyDown('Shift').pointerDown(10, 10).pointerMove(20, 20)
const shape = editor.shapesOnCurrentPage[0] as DrawableShape const shape = editor.currentPageShapes[0] as DrawableShape
expect(shape.props.segments.length).toBe(1) expect(shape.props.segments.length).toBe(1)
const segment = shape.props.segments[0] const segment = shape.props.segments[0]
@ -90,7 +90,7 @@ for (const toolType of ['draw', 'highlight'] as const) {
.pointerMove(40, 40) .pointerMove(40, 40)
.pointerUp() .pointerUp()
const shape = editor.shapesOnCurrentPage[0] as DrawableShape const shape = editor.currentPageShapes[0] as DrawableShape
expect(shape.props.segments.length).toBe(3) expect(shape.props.segments.length).toBe(3)
expect(shape.props.segments[0].type).toBe('free') expect(shape.props.segments[0].type).toBe('free')
@ -110,7 +110,7 @@ for (const toolType of ['draw', 'highlight'] as const) {
.pointerMove(40, 40) .pointerMove(40, 40)
.pointerUp() .pointerUp()
const shape = editor.shapesOnCurrentPage[0] as DrawableShape const shape = editor.currentPageShapes[0] as DrawableShape
expect(shape.props.segments.length).toBe(3) expect(shape.props.segments.length).toBe(3)
expect(shape.props.segments[0].type).toBe('straight') expect(shape.props.segments[0].type).toBe('straight')
@ -126,14 +126,14 @@ for (const toolType of ['draw', 'highlight'] as const) {
.pointerUp() .pointerUp()
.pointerDown(20, 20) .pointerDown(20, 20)
const shape1 = editor.shapesOnCurrentPage[0] as DrawableShape const shape1 = editor.currentPageShapes[0] as DrawableShape
expect(shape1.props.segments.length).toBe(2) expect(shape1.props.segments.length).toBe(2)
expect(shape1.props.segments[0].type).toBe('straight') expect(shape1.props.segments[0].type).toBe('straight')
expect(shape1.props.segments[1].type).toBe('straight') expect(shape1.props.segments[1].type).toBe('straight')
editor.pointerUp().pointerDown(30, 30).pointerUp() editor.pointerUp().pointerDown(30, 30).pointerUp()
const shape2 = editor.shapesOnCurrentPage[0] as DrawableShape const shape2 = editor.currentPageShapes[0] as DrawableShape
expect(shape2.props.segments.length).toBe(3) expect(shape2.props.segments.length).toBe(3)
expect(shape2.props.segments[2].type).toBe('straight') expect(shape2.props.segments[2].type).toBe('straight')
}) })
@ -149,13 +149,13 @@ for (const toolType of ['draw', 'highlight'] as const) {
.pointerDown(20, 20) .pointerDown(20, 20)
.pointerMove(30, 30) .pointerMove(30, 30)
expect(editor.shapesOnCurrentPage).toHaveLength(2) expect(editor.currentPageShapes).toHaveLength(2)
const shape1 = editor.shapesOnCurrentPage[0] as DrawableShape const shape1 = editor.currentPageShapes[0] as DrawableShape
expect(shape1.props.segments.length).toBe(1) expect(shape1.props.segments.length).toBe(1)
expect(shape1.props.segments[0].type).toBe('free') expect(shape1.props.segments[0].type).toBe('free')
const shape2 = editor.shapesOnCurrentPage[1] as DrawableShape const shape2 = editor.currentPageShapes[1] as DrawableShape
expect(shape2.props.segments.length).toBe(1) expect(shape2.props.segments.length).toBe(1)
expect(shape2.props.segments[0].type).toBe('straight') expect(shape2.props.segments[0].type).toBe('straight')
}) })
@ -172,7 +172,7 @@ for (const toolType of ['draw', 'highlight'] as const) {
editor.setCurrentTool(toolType).keyDown('Shift').pointerDown(0, 0).pointerMove(x, y) editor.setCurrentTool(toolType).keyDown('Shift').pointerDown(0, 0).pointerMove(x, y)
const shape = editor.shapesOnCurrentPage[0] as DrawableShape const shape = editor.currentPageShapes[0] as DrawableShape
const segment = shape.props.segments[0] const segment = shape.props.segments[0]
expect(segment.points[1].x).toBeCloseTo(snappedX) expect(segment.points[1].x).toBeCloseTo(snappedX)
expect(segment.points[1].y).toBeCloseTo(snappedY) expect(segment.points[1].y).toBeCloseTo(snappedY)
@ -186,7 +186,7 @@ for (const toolType of ['draw', 'highlight'] as const) {
editor.setCurrentTool(toolType).keyDown('Meta').pointerDown(0, 0).pointerMove(x, y) editor.setCurrentTool(toolType).keyDown('Meta').pointerDown(0, 0).pointerMove(x, y)
const shape = editor.shapesOnCurrentPage[0] as DrawableShape const shape = editor.currentPageShapes[0] as DrawableShape
const segment = shape.props.segments[0] const segment = shape.props.segments[0]
expect(segment.points[1].x).toBeCloseTo(x) expect(segment.points[1].x).toBeCloseTo(x)
expect(segment.points[1].y).toBeCloseTo(y) expect(segment.points[1].y).toBeCloseTo(y)
@ -205,13 +205,13 @@ for (const toolType of ['draw', 'highlight'] as const) {
.pointerDown(10, 0) .pointerDown(10, 0)
.pointerMove(1, 0) .pointerMove(1, 0)
const shape1 = editor.shapesOnCurrentPage[0] as DrawableShape const shape1 = editor.currentPageShapes[0] as DrawableShape
const segment1 = last(shape1.props.segments)! const segment1 = last(shape1.props.segments)!
const point1 = last(segment1.points)! const point1 = last(segment1.points)!
expect(point1.x).toBe(1) expect(point1.x).toBe(1)
editor.keyDown('Meta') editor.keyDown('Meta')
const shape2 = editor.shapesOnCurrentPage[0] as DrawableShape const shape2 = editor.currentPageShapes[0] as DrawableShape
const segment2 = last(shape2.props.segments)! const segment2 = last(shape2.props.segments)!
const point2 = last(segment2.points)! const point2 = last(segment2.points)!
expect(point2.x).toBe(0) expect(point2.x).toBe(0)
@ -230,13 +230,13 @@ for (const toolType of ['draw', 'highlight'] as const) {
.pointerDown(10, 5) .pointerDown(10, 5)
.pointerMove(1, 5) .pointerMove(1, 5)
const shape1 = editor.shapesOnCurrentPage[0] as DrawableShape const shape1 = editor.currentPageShapes[0] as DrawableShape
const segment1 = last(shape1.props.segments)! const segment1 = last(shape1.props.segments)!
const point1 = last(segment1.points)! const point1 = last(segment1.points)!
expect(point1.x).toBe(1) expect(point1.x).toBe(1)
editor.keyDown('Meta') editor.keyDown('Meta')
const shape2 = editor.shapesOnCurrentPage[0] as DrawableShape const shape2 = editor.currentPageShapes[0] as DrawableShape
const segment2 = last(shape2.props.segments)! const segment2 = last(shape2.props.segments)!
const point2 = last(segment2.points)! const point2 = last(segment2.points)!
expect(point2.x).toBe(0) expect(point2.x).toBe(0)
@ -244,18 +244,18 @@ for (const toolType of ['draw', 'highlight'] as const) {
it('Deletes very short lines on interrupt', () => { it('Deletes very short lines on interrupt', () => {
editor.setCurrentTool(toolType).pointerDown(0, 0).pointerMove(0.1, 0.1).interrupt() editor.setCurrentTool(toolType).pointerDown(0, 0).pointerMove(0.1, 0.1).interrupt()
expect(editor.shapesOnCurrentPage).toHaveLength(0) expect(editor.currentPageShapes).toHaveLength(0)
}) })
it('Does not delete longer lines on interrupt', () => { it('Does not delete longer lines on interrupt', () => {
editor.setCurrentTool(toolType).pointerDown(0, 0).pointerMove(5, 5).interrupt() editor.setCurrentTool(toolType).pointerDown(0, 0).pointerMove(5, 5).interrupt()
expect(editor.shapesOnCurrentPage).toHaveLength(1) expect(editor.currentPageShapes).toHaveLength(1)
}) })
it('Completes on cancel', () => { it('Completes on cancel', () => {
editor.setCurrentTool(toolType).pointerDown(0, 0).pointerMove(5, 5).cancel() editor.setCurrentTool(toolType).pointerDown(0, 0).pointerMove(5, 5).cancel()
expect(editor.shapesOnCurrentPage).toHaveLength(1) expect(editor.currentPageShapes).toHaveLength(1)
const shape = editor.shapesOnCurrentPage[0] as DrawableShape const shape = editor.currentPageShapes[0] as DrawableShape
expect(shape.props.segments.length).toBe(1) expect(shape.props.segments.length).toBe(1)
}) })
}) })

View file

@ -45,11 +45,11 @@ it('creates new bindings for arrows when pasting', async () => {
}, },
]) ])
const shapesBefore = editor.shapesOnCurrentPage const shapesBefore = editor.currentPageShapes
editor.selectAll().duplicateShapes(editor.selectedShapeIds) editor.selectAll().duplicateShapes(editor.selectedShapeIds)
const shapesAfter = editor.shapesOnCurrentPage const shapesAfter = editor.currentPageShapes
// We should not have changed the original shapes // We should not have changed the original shapes
expect(shapesBefore[0]).toMatchObject(shapesAfter[0]) expect(shapesBefore[0]).toMatchObject(shapesAfter[0])
@ -176,9 +176,9 @@ describe('When duplicating shapes that include arrows', () => {
it('Preserves the same selection bounds', () => { it('Preserves the same selection bounds', () => {
editor.selectAll().deleteShapes(editor.selectedShapeIds).createShapes(shapes).selectAll() editor.selectAll().deleteShapes(editor.selectedShapeIds).createShapes(shapes).selectAll()
const boundsBefore = editor.selectionBounds! const boundsBefore = editor.selectionRotatedPageBounds!
editor.duplicateShapes(editor.selectedShapeIds) editor.duplicateShapes(editor.selectedShapeIds)
expect(editor.selectionBounds).toCloselyMatchObject(boundsBefore) expect(editor.selectionRotatedPageBounds).toCloselyMatchObject(boundsBefore)
}) })
it('Preserves the same selection bounds when only duplicating the arrows', () => { it('Preserves the same selection bounds when only duplicating the arrows', () => {
@ -187,14 +187,14 @@ describe('When duplicating shapes that include arrows', () => {
.deleteShapes(editor.selectedShapeIds) .deleteShapes(editor.selectedShapeIds)
.createShapes(shapes) .createShapes(shapes)
.select( .select(
...editor.shapesOnCurrentPage ...editor.currentPageShapes
.filter((s) => editor.isShapeOfType<TLArrowShape>(s, 'arrow')) .filter((s) => editor.isShapeOfType<TLArrowShape>(s, 'arrow'))
.map((s) => s.id) .map((s) => s.id)
) )
const boundsBefore = editor.selectionBounds! const boundsBefore = editor.selectionRotatedPageBounds!
editor.duplicateShapes(editor.selectedShapeIds) editor.duplicateShapes(editor.selectedShapeIds)
const boundsAfter = editor.selectionBounds! const boundsAfter = editor.selectionRotatedPageBounds!
// It's not exactly exact, but close enough is plenty close // It's not exactly exact, but close enough is plenty close
expect(Math.abs(boundsAfter.x - boundsBefore.x)).toBeLessThan(1) expect(Math.abs(boundsAfter.x - boundsBefore.x)).toBeLessThan(1)
@ -203,6 +203,6 @@ describe('When duplicating shapes that include arrows', () => {
expect(Math.abs(boundsAfter.h - boundsBefore.h)).toBeLessThan(1) expect(Math.abs(boundsAfter.h - boundsBefore.h)).toBeLessThan(1)
// If you're feeling up to it: // If you're feeling up to it:
// expect(editor.selectionBounds).toCloselyMatchObject(boundsBefore) // expect(editor.selectionRotatedBounds).toCloselyMatchObject(boundsBefore)
}) })
}) })

View file

@ -405,7 +405,7 @@ describe('flipping rotated shapes', () => {
}) })
const getStartAndEndPoints = (id: TLShapeId) => { const getStartAndEndPoints = (id: TLShapeId) => {
const transform = editor.getPageTransform(id) const transform = editor.getShapePageTransform(id)
if (!transform) throw new Error('no transform') if (!transform) throw new Error('no transform')
const arrow = editor.getShape<TLArrowShape>(id)! const arrow = editor.getShape<TLArrowShape>(id)!
if (arrow.props.start.type !== 'point' || arrow.props.end.type !== 'point') if (arrow.props.start.type !== 'point' || arrow.props.end.type !== 'point')
@ -560,16 +560,16 @@ describe('When flipping shapes that include arrows', () => {
it('Flips horizontally', () => { it('Flips horizontally', () => {
editor.selectAll().deleteShapes(editor.selectedShapeIds).createShapes(shapes) editor.selectAll().deleteShapes(editor.selectedShapeIds).createShapes(shapes)
const boundsBefore = editor.selectionBounds! const boundsBefore = editor.selectionRotatedPageBounds!
editor.flipShapes(editor.selectedShapeIds, 'horizontal') editor.flipShapes(editor.selectedShapeIds, 'horizontal')
expect(editor.selectionBounds).toCloselyMatchObject(boundsBefore) expect(editor.selectionRotatedPageBounds).toCloselyMatchObject(boundsBefore)
}) })
it('Flips vertically', () => { it('Flips vertically', () => {
editor.selectAll().deleteShapes(editor.selectedShapeIds).createShapes(shapes) editor.selectAll().deleteShapes(editor.selectedShapeIds).createShapes(shapes)
const boundsBefore = editor.selectionBounds! const boundsBefore = editor.selectionRotatedPageBounds!
editor.flipShapes(editor.selectedShapeIds, 'vertical') editor.flipShapes(editor.selectedShapeIds, 'vertical')
expect(editor.selectionBounds).toCloselyMatchObject(boundsBefore) expect(editor.selectionRotatedPageBounds).toCloselyMatchObject(boundsBefore)
}) })
}) })

View file

@ -21,7 +21,7 @@ describe('creating frames', () => {
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(100, 100).pointerMove(200, 200).pointerUp(200, 200) editor.pointerDown(100, 100).pointerMove(200, 200).pointerUp(200, 200)
expect(editor.onlySelectedShape?.type).toBe('frame') expect(editor.onlySelectedShape?.type).toBe('frame')
expect(editor.getPageBounds(editor.onlySelectedShape!)).toMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toMatchObject({
x: 100, x: 100,
y: 100, y: 100,
w: 100, w: 100,
@ -33,7 +33,7 @@ describe('creating frames', () => {
editor.pointerDown(100, 100).pointerUp(100, 100) editor.pointerDown(100, 100).pointerUp(100, 100)
expect(editor.onlySelectedShape?.type).toBe('frame') expect(editor.onlySelectedShape?.type).toBe('frame')
const { w, h } = editor.getShapeUtil<TLFrameShape>('frame').getDefaultProps() const { w, h } = editor.getShapeUtil<TLFrameShape>('frame').getDefaultProps()
expect(editor.getPageBounds(editor.onlySelectedShape!)).toMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toMatchObject({
x: 100 - w / 2, x: 100 - w / 2,
y: 100 - h / 2, y: 100 - h / 2,
w, w,
@ -44,7 +44,7 @@ describe('creating frames', () => {
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(100, 100).cancel().pointerUp(100, 100) editor.pointerDown(100, 100).cancel().pointerUp(100, 100)
expect(editor.onlySelectedShape?.type).toBe(undefined) expect(editor.onlySelectedShape?.type).toBe(undefined)
expect(editor.shapesOnCurrentPage).toHaveLength(0) expect(editor.currentPageShapes).toHaveLength(0)
}) })
it('can be canceled while dragging', () => { it('can be canceled while dragging', () => {
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
@ -53,19 +53,19 @@ describe('creating frames', () => {
editor.cancel() editor.cancel()
editor.pointerUp() editor.pointerUp()
expect(editor.onlySelectedShape?.type).toBe(undefined) expect(editor.onlySelectedShape?.type).toBe(undefined)
expect(editor.shapesOnCurrentPage).toHaveLength(0) expect(editor.currentPageShapes).toHaveLength(0)
}) })
it('can be undone', () => { it('can be undone', () => {
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(100, 100).pointerMove(200, 200).pointerUp(200, 200) editor.pointerDown(100, 100).pointerMove(200, 200).pointerUp(200, 200)
expect(editor.onlySelectedShape?.type).toBe('frame') expect(editor.onlySelectedShape?.type).toBe('frame')
expect(editor.shapesOnCurrentPage).toHaveLength(1) expect(editor.currentPageShapes).toHaveLength(1)
editor.undo() editor.undo()
expect(editor.onlySelectedShape?.type).toBe(undefined) expect(editor.onlySelectedShape?.type).toBe(undefined)
expect(editor.shapesOnCurrentPage).toHaveLength(0) expect(editor.currentPageShapes).toHaveLength(0)
}) })
it('can be done inside other frames', () => { it('can be done inside other frames', () => {
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
@ -76,11 +76,11 @@ describe('creating frames', () => {
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(125, 125).pointerMove(175, 175).pointerUp(175, 175) editor.pointerDown(125, 125).pointerMove(175, 175).pointerUp(175, 175)
expect(editor.shapesOnCurrentPage).toHaveLength(2) expect(editor.currentPageShapes).toHaveLength(2)
expect(editor.onlySelectedShape?.parentId).toEqual(frameAId) expect(editor.onlySelectedShape?.parentId).toEqual(frameAId)
expect(editor.getPageBounds(editor.onlySelectedShape!)).toMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toMatchObject({
x: 125, x: 125,
y: 125, y: 125,
w: 50, w: 50,
@ -98,11 +98,11 @@ describe('creating frames', () => {
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(125, 125).pointerMove(175, 175).pointerUp(175, 175) editor.pointerDown(125, 125).pointerMove(175, 175).pointerUp(175, 175)
expect(editor.shapesOnCurrentPage).toHaveLength(2) expect(editor.currentPageShapes).toHaveLength(2)
expect(editor.onlySelectedShape?.parentId).toEqual(frameAId) expect(editor.onlySelectedShape?.parentId).toEqual(frameAId)
expect(editor.getPageBounds(editor.onlySelectedShape!)).toCloselyMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toCloselyMatchObject({
x: 125, x: 125,
y: 125, y: 125,
w: 50, w: 50,
@ -118,7 +118,7 @@ describe('creating frames', () => {
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(100, 100).pointerMove(49, 149) editor.pointerDown(100, 100).pointerMove(49, 149)
expect(editor.getPageBounds(editor.onlySelectedShape!)).toMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toMatchObject({
x: 49, x: 49,
y: 100, y: 100,
w: 51, w: 51,
@ -128,7 +128,7 @@ describe('creating frames', () => {
// x should snap // x should snap
editor.keyDown('Control') editor.keyDown('Control')
expect(editor.snaps.lines).toHaveLength(1) expect(editor.snaps.lines).toHaveLength(1)
expect(editor.getPageBounds(editor.onlySelectedShape!)).toMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toMatchObject({
x: 50, x: 50,
y: 100, y: 100,
w: 50, w: 50,
@ -146,16 +146,14 @@ describe('creating frames', () => {
describe('frame shapes', () => { describe('frame shapes', () => {
it('can receive new children when shapes are drawn on top and the frame is rotated', () => { it('can receive new children when shapes are drawn on top and the frame is rotated', () => {
// We should be starting from an empty canvas // We should be starting from an empty canvas
expect(editor.shapesOnCurrentPage).toHaveLength(0) expect(editor.currentPageShapes).toHaveLength(0)
const frameId = createShapeId('frame') const frameId = createShapeId('frame')
editor editor
// Create a frame // Create a frame
.createShapes( .createShapes([{ id: frameId, type: 'frame', x: 100, y: 100, props: { w: 100, h: 100 } }])
[{ id: frameId, type: 'frame', x: 100, y: 100, props: { w: 100, h: 100 } }], .select(frameId)
true
)
// Rotate it by PI/2 // Rotate it by PI/2
.rotateSelection(Math.PI / 2) .rotateSelection(Math.PI / 2)
// Draw a shape into the frame // Draw a shape into the frame
@ -169,7 +167,7 @@ describe('frame shapes', () => {
.pointerUp() .pointerUp()
// The two shapes should have been created // The two shapes should have been created
expect(editor.shapesOnCurrentPage).toHaveLength(3) expect(editor.currentPageShapes).toHaveLength(3)
// The shapes should be the child of the frame // The shapes should be the child of the frame
const childIds = editor.getSortedChildIdsForParent(frameId) const childIds = editor.getSortedChildIdsForParent(frameId)
@ -186,7 +184,7 @@ describe('frame shapes', () => {
editor.pointerDown(100, 100).pointerMove(200, 200).pointerUp(200, 200) editor.pointerDown(100, 100).pointerMove(200, 200).pointerUp(200, 200)
editor.resizeSelection({ scaleX: 0.5, scaleY: 0.5 }, 'bottom_right') editor.resizeSelection({ scaleX: 0.5, scaleY: 0.5 }, 'bottom_right')
expect(editor.getPageBounds(editor.onlySelectedShape!)).toCloselyMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toCloselyMatchObject({
x: 100, x: 100,
y: 100, y: 100,
w: 50, w: 50,
@ -200,7 +198,7 @@ describe('frame shapes', () => {
editor.setCurrentTool('frame') editor.setCurrentTool('frame')
editor.pointerDown(100, 100).pointerMove(200, 200).pointerUp(200, 200) editor.pointerDown(100, 100).pointerMove(200, 200).pointerUp(200, 200)
editor.resizeSelection({ scaleX: 0.5, scaleY: 0.5 }, 'bottom_right', { altKey: true }) editor.resizeSelection({ scaleX: 0.5, scaleY: 0.5 }, 'bottom_right', { altKey: true })
expect(editor.getPageBounds(editor.onlySelectedShape!)).toCloselyMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toCloselyMatchObject({
x: 125, x: 125,
y: 125, y: 125,
w: 50, w: 50,
@ -223,13 +221,13 @@ describe('frame shapes', () => {
editor.resizeSelection({ scaleX: 0.5, scaleY: 0.5 }, 'bottom_right') editor.resizeSelection({ scaleX: 0.5, scaleY: 0.5 }, 'bottom_right')
expect(editor.getPageBounds(frameId)).toCloselyMatchObject({ expect(editor.getShapePageBounds(frameId)).toCloselyMatchObject({
x: 100, x: 100,
y: 100, y: 100,
w: 50, w: 50,
h: 50, h: 50,
}) })
expect(editor.getPageBounds(boxId)).toCloselyMatchObject({ expect(editor.getShapePageBounds(boxId)).toCloselyMatchObject({
x: 125, x: 125,
y: 125, y: 125,
w: 50, w: 50,
@ -345,9 +343,9 @@ describe('frame shapes', () => {
editor.setCurrentTool('select') editor.setCurrentTool('select')
editor.select(ids.boxA) editor.select(ids.boxA)
editor.pointerDown(275, 275, ids.boxA).pointerMove(275, 74) editor.pointerDown(275, 275, ids.boxA).pointerMove(275, 74)
expect(editor.getPageBounds(ids.boxA)).toMatchObject({ y: 49 }) expect(editor.getShapePageBounds(ids.boxA)).toMatchObject({ y: 49 })
editor.keyDown('Control') editor.keyDown('Control')
expect(editor.getPageBounds(ids.boxA)).toMatchObject({ y: 50 }) expect(editor.getShapePageBounds(ids.boxA)).toMatchObject({ y: 50 })
expect(editor.snaps.lines).toHaveLength(1) expect(editor.snaps.lines).toHaveLength(1)
}) })
@ -362,7 +360,7 @@ describe('frame shapes', () => {
// make a shape outside the frame // make a shape outside the frame
editor.setCurrentTool('geo') editor.setCurrentTool('geo')
editor.pointerDown(275, 125).pointerMove(280, 130).pointerUp(280, 130) editor.pointerDown(275, 125).pointerMove(280, 130).pointerUp(280, 130)
expect(editor.getPageBounds(editor.onlySelectedShape!)).toMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toMatchObject({
x: 275, x: 275,
y: 125, y: 125,
w: 5, w: 5,
@ -378,7 +376,7 @@ describe('frame shapes', () => {
// now try to snap // now try to snap
editor.keyDown('Control') editor.keyDown('Control')
expect(editor.getPageBounds(editor.onlySelectedShape!)).toMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toMatchObject({
x: 275, x: 275,
y: 124, y: 124,
w: 5, w: 5,
@ -390,7 +388,7 @@ describe('frame shapes', () => {
editor.pointerMove(287.5, 126.5).pointerMove(277.5, 126.5) editor.pointerMove(287.5, 126.5).pointerMove(277.5, 126.5)
expect(editor.snaps.lines).toHaveLength(1) expect(editor.snaps.lines).toHaveLength(1)
expect(editor.getPageBounds(editor.onlySelectedShape!)).toMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toMatchObject({
x: 275, x: 275,
y: 125, y: 125,
w: 5, w: 5,
@ -431,7 +429,7 @@ describe('frame shapes', () => {
editor.setCurrentTool('geo') editor.setCurrentTool('geo')
editor.pointerDown(150, 150).pointerMove(250, 250).pointerUp(250, 250) editor.pointerDown(150, 150).pointerMove(250, 250).pointerUp(250, 250)
expect(editor.getPageBounds(editor.onlySelectedShape!)).toMatchObject({ expect(editor.getShapePageBounds(editor.onlySelectedShape!)).toMatchObject({
x: 150, x: 150,
y: 150, y: 150,
w: 100, w: 100,
@ -439,13 +437,13 @@ describe('frame shapes', () => {
}) })
// mask should be a 50px box around the top left corner // mask should be a 50px box around the top left corner
expect(editor.getClipPath(editor.onlySelectedShape!.id)).toMatchInlineSnapshot( expect(editor.getShapeClipPath(editor.onlySelectedShape!.id)).toMatchInlineSnapshot(
`"polygon(-50px -50px,50px -50px,50px 50px,-50px 50px)"` `"polygon(-50px -50px,50px -50px,50px 50px,-50px 50px)"`
) )
editor.reparentShapes([editor.onlySelectedShape!.id], editor.currentPageId) editor.reparentShapes([editor.onlySelectedShape!.id], editor.currentPageId)
expect(editor.getClipPath(editor.onlySelectedShape!.id)).toBeUndefined() expect(editor.getShapeClipPath(editor.onlySelectedShape!.id)).toBeUndefined()
}) })
it('masks its nested children', () => { it('masks its nested children', () => {
@ -465,7 +463,7 @@ describe('frame shapes', () => {
editor.reparentShapes([boxId], innerFrameId) editor.reparentShapes([boxId], innerFrameId)
// should be a 50px box starting in the middle of the outer frame // should be a 50px box starting in the middle of the outer frame
expect(editor.getClipPath(boxId)).toMatchInlineSnapshot( expect(editor.getShapeClipPath(boxId)).toMatchInlineSnapshot(
`"polygon(50px 50px,100px 50px,100px 100px,50px 100px)"` `"polygon(50px 50px,100px 50px,100px 100px,50px 100px)"`
) )
}) })

View file

@ -76,7 +76,7 @@ afterEach(() => {
editor?.dispose() editor?.dispose()
}) })
const getAllShapes = () => editor.shapesOnCurrentPage const getAllShapes = () => editor.currentPageShapes
const onlySelectedId = () => { const onlySelectedId = () => {
expect(editor.selectedShapeIds).toHaveLength(1) expect(editor.selectedShapeIds).toHaveLength(1)
@ -119,7 +119,12 @@ describe('creating groups', () => {
const group = onlySelectedShape() const group = onlySelectedShape()
expect(group.type).toBe(GroupShapeUtil.type) expect(group.type).toBe(GroupShapeUtil.type)
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ x: 0, y: 0, w: 30, h: 10 }) expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: 0,
y: 0,
w: 30,
h: 10,
})
expect(children(group).has(editor.getShape(ids.boxA)!)).toBe(true) expect(children(group).has(editor.getShape(ids.boxA)!)).toBe(true)
expect(children(group).has(editor.getShape(ids.boxB)!)).toBe(true) expect(children(group).has(editor.getShape(ids.boxB)!)).toBe(true)
expect(children(group).has(editor.getShape(ids.boxC)!)).toBe(false) expect(children(group).has(editor.getShape(ids.boxC)!)).toBe(false)
@ -158,9 +163,9 @@ describe('creating groups', () => {
editor.createShapes(shapes) editor.createShapes(shapes)
const initialPageBounds = { const initialPageBounds = {
A: editor.getPageBounds(ids.boxA)!.clone(), A: editor.getShapePageBounds(ids.boxA)!.clone(),
B: editor.getPageBounds(ids.boxB)!.clone(), B: editor.getShapePageBounds(ids.boxB)!.clone(),
C: editor.getPageBounds(ids.boxC)!.clone(), C: editor.getShapePageBounds(ids.boxC)!.clone(),
} }
const initialPageRotations = { const initialPageRotations = {
@ -174,9 +179,9 @@ describe('creating groups', () => {
try { try {
expect({ expect({
A: editor.getPageBounds(ids.boxA)!.clone(), A: editor.getShapePageBounds(ids.boxA)!.clone(),
B: editor.getPageBounds(ids.boxB)!.clone(), B: editor.getShapePageBounds(ids.boxB)!.clone(),
C: editor.getPageBounds(ids.boxC)!.clone(), C: editor.getShapePageBounds(ids.boxC)!.clone(),
}).toCloselyMatchObject(initialPageBounds) }).toCloselyMatchObject(initialPageBounds)
expect({ expect({
A: editor.getPageRotationById(ids.boxA), A: editor.getPageRotationById(ids.boxA),
@ -216,7 +221,7 @@ describe('creating groups', () => {
const uberGroup = onlySelectedShape() const uberGroup = onlySelectedShape()
expect(uberGroup.type).toBe(GroupShapeUtil.type) expect(uberGroup.type).toBe(GroupShapeUtil.type)
expect(editor.getPageBounds(uberGroup.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(uberGroup.id)!).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 70, w: 70,
@ -373,14 +378,14 @@ describe('ungrouping shapes', () => {
expect(isRemoved(groupA)).toBe(true) expect(isRemoved(groupA)).toBe(true)
expect(new Set(editor.selectedShapeIds)).toEqual(new Set([ids.boxA, ids.boxB])) expect(new Set(editor.selectedShapeIds)).toEqual(new Set([ids.boxA, ids.boxB]))
expect(editor.getPageBounds(ids.boxA)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(ids.boxA)!).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 10, w: 10,
h: 10, h: 10,
}) })
expect(editor.getPageBounds(ids.boxB)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(ids.boxB)!).toCloselyMatchObject({
x: 20, x: 20,
y: 0, y: 0,
w: 10, w: 10,
@ -419,9 +424,9 @@ describe('ungrouping shapes', () => {
editor.createShapes(shapes) editor.createShapes(shapes)
const initialPageBounds = { const initialPageBounds = {
A: editor.getPageBounds(ids.boxA)!.clone(), A: editor.getShapePageBounds(ids.boxA)!.clone(),
B: editor.getPageBounds(ids.boxB)!.clone(), B: editor.getShapePageBounds(ids.boxB)!.clone(),
C: editor.getPageBounds(ids.boxC)!.clone(), C: editor.getShapePageBounds(ids.boxC)!.clone(),
} }
const initialPageRotations = { const initialPageRotations = {
@ -437,9 +442,9 @@ describe('ungrouping shapes', () => {
try { try {
expect({ expect({
A: editor.getPageBounds(ids.boxA)!.clone(), A: editor.getShapePageBounds(ids.boxA)!.clone(),
B: editor.getPageBounds(ids.boxB)!.clone(), B: editor.getShapePageBounds(ids.boxB)!.clone(),
C: editor.getPageBounds(ids.boxC)!.clone(), C: editor.getShapePageBounds(ids.boxC)!.clone(),
}).toCloselyMatchObject(initialPageBounds) }).toCloselyMatchObject(initialPageBounds)
expect({ expect({
A: editor.getPageRotationById(ids.boxA), A: editor.getPageRotationById(ids.boxA),
@ -515,7 +520,7 @@ describe('ungrouping shapes', () => {
editor.groupShapes(editor.selectedShapeIds) editor.groupShapes(editor.selectedShapeIds)
editor.ungroupShapes(editor.selectedShapeIds) editor.ungroupShapes(editor.selectedShapeIds)
const sortedShapesOnCurrentPage = editor.shapesOnCurrentPage const sortedShapesOnCurrentPage = editor.currentPageShapes
.sort(sortByIndex) .sort(sortByIndex)
.map((shape) => shape.id) .map((shape) => shape.id)
expect(sortedShapesOnCurrentPage.length).toBe(4) expect(sortedShapesOnCurrentPage.length).toBe(4)
@ -540,7 +545,7 @@ describe('ungrouping shapes', () => {
editor.groupShapes(editor.selectedShapeIds) editor.groupShapes(editor.selectedShapeIds)
editor.ungroupShapes(editor.selectedShapeIds) editor.ungroupShapes(editor.selectedShapeIds)
const sortedShapesOnCurrentPage = editor.shapesOnCurrentPage const sortedShapesOnCurrentPage = editor.currentPageShapes
.sort(sortByIndex) .sort(sortByIndex)
.map((shape) => shape.id) .map((shape) => shape.id)
expect(sortedShapesOnCurrentPage.length).toBe(4) expect(sortedShapesOnCurrentPage.length).toBe(4)
@ -572,18 +577,18 @@ describe('the bounds of a group', () => {
editor.groupShapes(editor.selectedShapeIds) editor.groupShapes(editor.selectedShapeIds)
const group = onlySelectedShape() const group = onlySelectedShape()
expect(editor.getPageBounds(group.id)!.minX).toBe(0) expect(editor.getShapePageBounds(group.id)!.minX).toBe(0)
editor.select(ids.boxA).rotateSelection(Math.PI / 4) editor.select(ids.boxA).rotateSelection(Math.PI / 4)
// pythagoras to the rescue // pythagoras to the rescue
const expectedLeftBound = 50 - Math.sqrt(2 * (100 * 100)) / 2 const expectedLeftBound = 50 - Math.sqrt(2 * (100 * 100)) / 2
expect(editor.getPageBounds(group.id)!.minX).toBeCloseTo(expectedLeftBound) expect(editor.getShapePageBounds(group.id)!.minX).toBeCloseTo(expectedLeftBound)
// rotating the circle doesn't move the right edge because it's outline doesn't change // rotating the circle doesn't move the right edge because it's outline doesn't change
expect(editor.getPageBounds(group.id)!.maxX).toBe(300) expect(editor.getShapePageBounds(group.id)!.maxX).toBe(300)
editor.select(ids.boxB).rotateSelection(Math.PI / 4) editor.select(ids.boxB).rotateSelection(Math.PI / 4)
expect(approximately(editor.getPageBounds(group.id)!.maxX, 300, 1)).toBe(true) expect(approximately(editor.getShapePageBounds(group.id)!.maxX, 300, 1)).toBe(true)
}) })
it('changes when shapes translate', () => { it('changes when shapes translate', () => {
@ -597,7 +602,7 @@ describe('the bounds of a group', () => {
editor.groupShapes(editor.selectedShapeIds) editor.groupShapes(editor.selectedShapeIds)
const group = onlySelectedShape() const group = onlySelectedShape()
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 50, w: 50,
@ -606,7 +611,7 @@ describe('the bounds of a group', () => {
// move A to the left // move A to the left
editor.select(ids.boxA).translateSelection(-10, 0) editor.select(ids.boxA).translateSelection(-10, 0)
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: -10, x: -10,
y: 0, y: 0,
w: 60, w: 60,
@ -614,7 +619,7 @@ describe('the bounds of a group', () => {
}) })
// move C up and to the right // move C up and to the right
editor.select(ids.boxC).translateSelection(10, -10) editor.select(ids.boxC).translateSelection(10, -10)
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: -10, x: -10,
y: -10, y: -10,
w: 70, w: 70,
@ -633,7 +638,7 @@ describe('the bounds of a group', () => {
editor.groupShapes(editor.selectedShapeIds) editor.groupShapes(editor.selectedShapeIds)
const group = onlySelectedShape() const group = onlySelectedShape()
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 50, w: 50,
@ -642,7 +647,7 @@ describe('the bounds of a group', () => {
// resize A to the left // resize A to the left
editor.select(ids.boxA).resizeSelection({ scaleX: 2 }, 'left') editor.select(ids.boxA).resizeSelection({ scaleX: 2 }, 'left')
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: -10, x: -10,
y: 0, y: 0,
w: 60, w: 60,
@ -650,7 +655,7 @@ describe('the bounds of a group', () => {
}) })
// resize C up and to the right // resize C up and to the right
editor.select(ids.boxC).resizeSelection({ scaleY: 2, scaleX: 2 }, 'top_right') editor.select(ids.boxC).resizeSelection({ scaleY: 2, scaleX: 2 }, 'top_right')
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: -10, x: -10,
y: -10, y: -10,
w: 70, w: 70,
@ -682,7 +687,7 @@ describe('the bounds of a rotated group', () => {
editor.rotateSelection(Math.PI / 2) editor.rotateSelection(Math.PI / 2)
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 300, w: 300,
@ -693,12 +698,12 @@ describe('the bounds of a rotated group', () => {
// pythagoras to the rescue // pythagoras to the rescue
const expectedTopBound = 50 - Math.sqrt(2 * (100 * 100)) / 2 const expectedTopBound = 50 - Math.sqrt(2 * (100 * 100)) / 2
expect(editor.getPageBounds(group.id)!.minY).toBeCloseTo(expectedTopBound) expect(editor.getShapePageBounds(group.id)!.minY).toBeCloseTo(expectedTopBound)
// rotating the circle doesn't move the right edge because it's outline doesn't change // rotating the circle doesn't move the right edge because it's outline doesn't change
expect(editor.getPageBounds(group.id)!.maxY).toBe(300) expect(editor.getShapePageBounds(group.id)!.maxY).toBe(300)
editor.select(ids.boxB).rotateSelection(Math.PI / 4) editor.select(ids.boxB).rotateSelection(Math.PI / 4)
expect(approximately(editor.getPageBounds(group.id)!.maxY, 300, 1)).toBe(true) expect(approximately(editor.getShapePageBounds(group.id)!.maxY, 300, 1)).toBe(true)
}) })
it('changes when shapes translate', () => { it('changes when shapes translate', () => {
@ -714,7 +719,7 @@ describe('the bounds of a rotated group', () => {
const group = onlySelectedShape() const group = onlySelectedShape()
editor.updateShapes([{ id: group.id, type: 'group', rotation: Math.PI / 2, x: 10, y: 0 }]) editor.updateShapes([{ id: group.id, type: 'group', rotation: Math.PI / 2, x: 10, y: 0 }])
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 10, w: 10,
@ -723,7 +728,7 @@ describe('the bounds of a rotated group', () => {
// move A up and to the left // move A up and to the left
editor.select(ids.boxA).translateSelection(-10, -10) editor.select(ids.boxA).translateSelection(-10, -10)
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: -10, x: -10,
y: -10, y: -10,
w: 20, w: 20,
@ -731,7 +736,7 @@ describe('the bounds of a rotated group', () => {
}) })
// move C up and to the right // move C up and to the right
editor.select(ids.boxC).translateSelection(10, -10) editor.select(ids.boxC).translateSelection(10, -10)
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: -10, x: -10,
y: -10, y: -10,
w: 30, w: 30,
@ -747,14 +752,14 @@ describe('the bounds of a rotated group', () => {
// rotate this all 90 degrees // rotate this all 90 degrees
editor.createShapes([box(ids.boxA, 0, 0), box(ids.boxB, 20, 0), box(ids.boxC, 40, 0)]) editor.createShapes([box(ids.boxA, 0, 0), box(ids.boxB, 20, 0), box(ids.boxC, 40, 0)])
expect(editor.getGeometry(ids.boxA)!.bounds).toMatchObject({ x: 0, y: 0, w: 10, h: 10 }) expect(editor.getShapeGeometry(ids.boxA)!.bounds).toMatchObject({ x: 0, y: 0, w: 10, h: 10 })
editor.select(ids.boxA, ids.boxB, ids.boxC) editor.select(ids.boxA, ids.boxB, ids.boxC)
editor.groupShapes(editor.selectedShapeIds) editor.groupShapes(editor.selectedShapeIds)
const group = onlySelectedShape() const group = onlySelectedShape()
editor.updateShapes([{ id: group.id, type: 'group', rotation: Math.PI / 2, x: 10, y: 0 }]) editor.updateShapes([{ id: group.id, type: 'group', rotation: Math.PI / 2, x: 10, y: 0 }])
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 10, w: 10,
@ -763,7 +768,7 @@ describe('the bounds of a rotated group', () => {
// resize A to up // resize A to up
editor.select(ids.boxA).resizeSelection({ scaleX: 2 }, 'left') editor.select(ids.boxA).resizeSelection({ scaleX: 2 }, 'left')
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: 0, x: 0,
y: -10, y: -10,
w: 10, w: 10,
@ -771,7 +776,7 @@ describe('the bounds of a rotated group', () => {
}) })
// resize C up and to the right // resize C up and to the right
editor.select(ids.boxC).resizeSelection({ scaleY: 2, scaleX: 2 }, 'top_right') editor.select(ids.boxC).resizeSelection({ scaleY: 2, scaleX: 2 }, 'top_right')
expect(editor.getPageBounds(group.id)!).toCloselyMatchObject({ expect(editor.getShapePageBounds(group.id)!).toCloselyMatchObject({
x: 0, x: 0,
y: -10, y: -10,
w: 20, w: 20,
@ -1117,7 +1122,7 @@ describe('creating new shapes', () => {
const boxC = onlySelectedShape() const boxC = onlySelectedShape()
expect(boxC.parentId).toBe(editor.currentPageId) expect(boxC.parentId).toBe(editor.currentPageId)
expect(editor.getPageBounds(boxC.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(boxC.id)).toCloselyMatchObject({
x: 20, x: 20,
y: 20, y: 20,
w: 60, w: 60,
@ -1134,7 +1139,7 @@ describe('creating new shapes', () => {
const boxC = onlySelectedShape() const boxC = onlySelectedShape()
expect(boxC.parentId).toBe(groupA.id) expect(boxC.parentId).toBe(groupA.id)
expect(editor.getPageBounds(boxC.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(boxC.id)).toCloselyMatchObject({
x: 20, x: 20,
y: 20, y: 20,
w: 60, w: 60,
@ -1150,21 +1155,21 @@ describe('creating new shapes', () => {
editor.setCurrentTool('geo') editor.setCurrentTool('geo')
editor.pointerDown(20, 20).pointerMove(-10, -10) editor.pointerDown(20, 20).pointerMove(-10, -10)
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: -10, x: -10,
y: -10, y: -10,
w: 110, w: 110,
h: 110, h: 110,
}) })
editor.pointerMove(-20, -20).pointerUp(-20, -20) editor.pointerMove(-20, -20).pointerUp(-20, -20)
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: -20, x: -20,
y: -20, y: -20,
w: 120, w: 120,
h: 120, h: 120,
}) })
const boxC = onlySelectedShape() const boxC = onlySelectedShape()
expect(editor.getPageBounds(boxC.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(boxC.id)).toCloselyMatchObject({
x: -20, x: -20,
y: -20, y: -20,
w: 40, w: 40,
@ -1179,7 +1184,7 @@ describe('creating new shapes', () => {
editor.setCurrentTool('geo') editor.setCurrentTool('geo')
editor.pointerDown(-50, -50).pointerMove(-100, -100).pointerUp() editor.pointerDown(-50, -50).pointerMove(-100, -100).pointerUp()
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: -100, x: -100,
y: -100, y: -100,
w: 200, w: 200,
@ -1187,7 +1192,7 @@ describe('creating new shapes', () => {
}) })
const boxC = onlySelectedShape() const boxC = onlySelectedShape()
expect(editor.getPageBounds(boxC.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(boxC.id)).toCloselyMatchObject({
x: -100, x: -100,
y: -100, y: -100,
w: 50, w: 50,
@ -1238,7 +1243,7 @@ describe('creating new shapes', () => {
} }
} }
expect(roundToNearestTen(editor.getPageBounds(groupA.id)!)).toCloselyMatchObject({ expect(roundToNearestTen(editor.getShapePageBounds(groupA.id)!)).toCloselyMatchObject({
x: -20, x: -20,
y: -20, y: -20,
w: 120, w: 120,
@ -1266,7 +1271,7 @@ describe('creating new shapes', () => {
} }
} }
expect(roundToNearestTen(editor.getPageBounds(groupA.id)!)).toCloselyMatchObject({ expect(roundToNearestTen(editor.getShapePageBounds(groupA.id)!)).toCloselyMatchObject({
x: -100, x: -100,
y: -100, y: -100,
w: 200, w: 200,
@ -1307,11 +1312,13 @@ describe('creating new shapes', () => {
editor.setCurrentTool('line') editor.setCurrentTool('line')
editor.pointerDown(20, 20).pointerMove(-10, -10) editor.pointerDown(20, 20).pointerMove(-10, -10)
expect(editor.getPageBounds(groupA.id)).toMatchSnapshot('group with line shape') expect(editor.getShapePageBounds(groupA.id)).toMatchSnapshot('group with line shape')
editor.pointerMove(-20, -20).pointerUp(-20, -20) editor.pointerMove(-20, -20).pointerUp(-20, -20)
expect(editor.getPageBounds(groupA.id)).toMatchSnapshot('group shape after second resize') expect(editor.getShapePageBounds(groupA.id)).toMatchSnapshot(
'group shape after second resize'
)
const boxC = onlySelectedShape() const boxC = onlySelectedShape()
expect(editor.getPageBounds(boxC.id)).toMatchSnapshot('box shape after second resize') expect(editor.getShapePageBounds(boxC.id)).toMatchSnapshot('box shape after second resize')
}) })
it('works if the shape drawing begins outside of the current group bounds', () => { it('works if the shape drawing begins outside of the current group bounds', () => {
@ -1321,10 +1328,10 @@ describe('creating new shapes', () => {
editor.setCurrentTool('line') editor.setCurrentTool('line')
editor.pointerDown(-50, -50).pointerMove(-100, -100).pointerUp() editor.pointerDown(-50, -50).pointerMove(-100, -100).pointerUp()
expect(editor.getPageBounds(groupA.id)).toMatchSnapshot('group with line') expect(editor.getShapePageBounds(groupA.id)).toMatchSnapshot('group with line')
const boxC = onlySelectedShape() const boxC = onlySelectedShape()
expect(editor.getPageBounds(boxC.id)).toMatchSnapshot('box shape after resize') expect(editor.getShapePageBounds(boxC.id)).toMatchSnapshot('box shape after resize')
}) })
}) })
@ -1355,7 +1362,7 @@ describe('creating new shapes', () => {
editor.select(ids.boxA) editor.select(ids.boxA)
expect(editor.focusedGroupId === groupA.id).toBe(true) expect(editor.focusedGroupId === groupA.id).toBe(true)
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 100, w: 100,
@ -1366,7 +1373,7 @@ describe('creating new shapes', () => {
editor.pointerDown(80, 80) editor.pointerDown(80, 80)
editor.pointerUp() editor.pointerUp()
// default size is 200x200, and it centers it, so add 100px around the pointer // default size is 200x200, and it centers it, so add 100px around the pointer
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: -20, x: -20,
y: -20, y: -20,
w: 200, w: 200,
@ -1375,7 +1382,7 @@ describe('creating new shapes', () => {
editor.pointerMove(20, 20) editor.pointerMove(20, 20)
editor.pointerUp(20, 20) editor.pointerUp(20, 20)
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: -20, x: -20,
y: -20, y: -20,
w: 200, w: 200,
@ -1388,14 +1395,14 @@ describe('creating new shapes', () => {
expect(editor.focusedGroupId === groupA.id).toBe(true) expect(editor.focusedGroupId === groupA.id).toBe(true)
editor.setCurrentTool('note') editor.setCurrentTool('note')
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 100, w: 100,
h: 100, h: 100,
}) })
editor.pointerDown(-20, -20).pointerUp(-20, -20) editor.pointerDown(-20, -20).pointerUp(-20, -20)
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: -120, x: -120,
y: -120, y: -120,
w: 220, w: 220,
@ -1687,7 +1694,7 @@ describe('moving handles within a group', () => {
editor.expectToBeIn('select.idle') editor.expectToBeIn('select.idle')
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 100, w: 100,
@ -1697,7 +1704,7 @@ describe('moving handles within a group', () => {
editor.pointerDown(60, 60, { editor.pointerDown(60, 60, {
target: 'handle', target: 'handle',
shape: arrow, shape: arrow,
handle: editor.getHandles<TLArrowShape>(arrow)!.find((h) => h.id === 'end'), handle: editor.getShapeHandles<TLArrowShape>(arrow)!.find((h) => h.id === 'end'),
}) })
editor.expectToBeIn('select.pointing_handle') editor.expectToBeIn('select.pointing_handle')
@ -1721,7 +1728,7 @@ describe('moving handles within a group', () => {
expect(arrow.props.end.y).toBe(-60) expect(arrow.props.end.y).toBe(-60)
} }
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: 0, x: 0,
y: -10, y: -10,
w: 100, w: 100,
@ -1735,7 +1742,7 @@ describe('moving handles within a group', () => {
editor.pointerUp() editor.pointerUp()
expect(editor.getPageBounds(groupA.id)).toCloselyMatchObject({ expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
x: -30, x: -30,
y: -30, y: -30,
w: 130, w: 130,

View file

@ -87,7 +87,7 @@ beforeEach(() => {
}) })
function getShapes() { function getShapes() {
const arr = editor.shapesOnCurrentPage as any[] const arr = editor.currentPageShapes as any[]
const results = { old: {}, new: {} } as { const results = { old: {}, new: {} } as {
old: Record<string, TLGeoShape | TLFrameShape> old: Record<string, TLGeoShape | TLFrameShape>
@ -110,7 +110,7 @@ it('Gets pasted shapes correctly', () => {
editor.selectNone() editor.selectNone()
let shapes = getShapes() let shapes = getShapes()
expect(editor.sortedShapesOnCurrentPage.map((m) => m.id)).toStrictEqual([ expect(editor.currentPageShapesSorted.map((m) => m.id)).toStrictEqual([
shapes.old.frame1.id, shapes.old.frame1.id,
shapes.old.frame2.id, shapes.old.frame2.id,
shapes.old.frame3.id, shapes.old.frame3.id,
@ -124,7 +124,7 @@ it('Gets pasted shapes correctly', () => {
shapes = getShapes() shapes = getShapes()
expect(editor.sortedShapesOnCurrentPage.map((m) => m.id)).toStrictEqual([ expect(editor.currentPageShapesSorted.map((m) => m.id)).toStrictEqual([
shapes.old.frame1.id, shapes.old.frame1.id,
shapes.old.frame2.id, shapes.old.frame2.id,
shapes.old.frame3.id, shapes.old.frame3.id,
@ -174,7 +174,7 @@ describe('When pasting', () => {
expect(shapes.new.box1?.parentId).toBe(editor.currentPageId) expect(shapes.new.box1?.parentId).toBe(editor.currentPageId)
expect(shapes.new.box2?.parentId).toBe(editor.currentPageId) expect(shapes.new.box2?.parentId).toBe(editor.currentPageId)
expect(editor.sortedShapesOnCurrentPage.map((m) => m.id)).toStrictEqual([ expect(editor.currentPageShapesSorted.map((m) => m.id)).toStrictEqual([
shapes.old.frame1.id, shapes.old.frame1.id,
shapes.old.frame2.id, shapes.old.frame2.id,
shapes.old.frame3.id, shapes.old.frame3.id,
@ -270,8 +270,8 @@ describe('When pasting', () => {
// Should put the pasted shapes centered in the frame // Should put the pasted shapes centered in the frame
editor.select(shapes.new.box1!.id, shapes.new.box1!.id) editor.select(shapes.new.box1!.id, shapes.new.box1!.id)
expect(editor.getPageBounds(shapes.old.box1)).toMatchObject( expect(editor.getShapePageBounds(shapes.old.box1)).toMatchObject(
editor.getPageBounds(shapes.new.box1)! editor.getShapePageBounds(shapes.new.box1)!
) )
}) })
@ -424,11 +424,11 @@ describe('When pasting into frames...', () => {
// Copy box 1 (should be out of viewport) // Copy box 1 (should be out of viewport)
editor.select(ids.box1).copy() editor.select(ids.box1).copy()
const shapesBefore = editor.shapesOnCurrentPage const shapesBefore = editor.currentPageShapes
// Paste it // Paste it
editor.paste() editor.paste()
const newShape = editor.shapesOnCurrentPage.find((s) => !shapesBefore.includes(s))! const newShape = editor.currentPageShapes.find((s) => !shapesBefore.includes(s))!
// it should be on the canvas, NOT a child of frame2 // it should be on the canvas, NOT a child of frame2
expect(newShape.parentId).not.toBe(ids.frame2) expect(newShape.parentId).not.toBe(ids.frame2)

View file

@ -4,7 +4,7 @@ import { TestEditor } from './TestEditor'
let editor: TestEditor let editor: TestEditor
function expectShapesInOrder(editor: TestEditor, ...ids: TLShapeId[]) { function expectShapesInOrder(editor: TestEditor, ...ids: TLShapeId[]) {
expect(editor.sortedShapesOnCurrentPage.map((shape) => shape.id)).toMatchObject(ids) expect(editor.currentPageShapesSorted.map((shape) => shape.id)).toMatchObject(ids)
} }
function getSiblingBelow(editor: TestEditor, id: TLShapeId) { function getSiblingBelow(editor: TestEditor, id: TLShapeId) {
@ -68,7 +68,7 @@ beforeEach(() => {
describe('When running zindex tests', () => { describe('When running zindex tests', () => {
it('Correctly initializes indices', () => { it('Correctly initializes indices', () => {
expect(editor.sortedShapesOnCurrentPage.map((shape) => shape.index)).toMatchObject([ expect(editor.currentPageShapesSorted.map((shape) => shape.index)).toMatchObject([
'a1', 'a1',
'a2', 'a2',
'a3', 'a3',

View file

@ -47,7 +47,7 @@ const box = (id: TLShapeId, x: number, y: number, w = 10, h = 10): TLShapePartia
}) })
const roundedPageBounds = (shapeId: TLShapeId, accuracy = 0.01) => { const roundedPageBounds = (shapeId: TLShapeId, accuracy = 0.01) => {
return roundedBox(editor.getPageBounds(shapeId)!, accuracy) return roundedBox(editor.getShapePageBounds(shapeId)!, accuracy)
} }
// function getGapAndPointLines(snaps: SnapLine[]) { // function getGapAndPointLines(snaps: SnapLine[]) {
@ -240,7 +240,7 @@ describe('When resizing a rotated shape...', () => {
editor.select(ids.boxA) editor.select(ids.boxA)
const initialPagePoint = editor.getPageTransform(ids.boxA)!.point() const initialPagePoint = editor.getShapePageTransform(ids.boxA)!.point()
const pt0 = Vec2d.From(initialPagePoint) const pt0 = Vec2d.From(initialPagePoint)
const pt1 = Vec2d.RotWith(initialPagePoint, editor.selectionPageBounds!.center, rotation) const pt1 = Vec2d.RotWith(initialPagePoint, editor.selectionPageBounds!.center, rotation)
@ -259,12 +259,14 @@ describe('When resizing a rotated shape...', () => {
// The shape's point should now be at pt1 (it rotates from the top left corner) // The shape's point should now be at pt1 (it rotates from the top left corner)
expect(editor.getPageTransform(ids.boxA)!.rotation()).toBeCloseTo(rotation) expect(editor.getShapePageTransform(ids.boxA)!.rotation()).toBeCloseTo(rotation)
expect(editor.getPageTransform(ids.boxA)!.point()).toCloselyMatchObject(pt1) expect(editor.getShapePageTransform(ids.boxA)!.point()).toCloselyMatchObject(pt1)
// Resize by moving the top left resize handle to pt2. Should be a delta of [10, 10]. // Resize by moving the top left resize handle to pt2. Should be a delta of [10, 10].
expect(Vec2d.Dist(editor.getPageTransform(ids.boxA)!.point(), pt2)).toBeCloseTo(offset.len()) expect(Vec2d.Dist(editor.getShapePageTransform(ids.boxA)!.point(), pt2)).toBeCloseTo(
offset.len()
)
editor editor
.pointerDown(pt1.x, pt1.y, { .pointerDown(pt1.x, pt1.y, {
@ -276,7 +278,7 @@ describe('When resizing a rotated shape...', () => {
// The shape should have moved its point to pt2 and be delta bigger. // The shape should have moved its point to pt2 and be delta bigger.
expect(editor.getPageTransform(ids.boxA)!.point()).toCloselyMatchObject(pt2) expect(editor.getShapePageTransform(ids.boxA)!.point()).toCloselyMatchObject(pt2)
editor.expectShapeToMatch({ id: ids.boxA, props: { w: 110, h: 110 } }) editor.expectShapeToMatch({ id: ids.boxA, props: { w: 110, h: 110 } })
}) })
}) })
@ -322,7 +324,7 @@ describe('When resizing mulitple shapes...', () => {
// Rotate the shape by $rotation from its top left corner // Rotate the shape by $rotation from its top left corner
const rotateStart = editor.getPageTransform(ids.boxA)!.point() const rotateStart = editor.getShapePageTransform(ids.boxA)!.point()
const rotateCenter = editor.getPageCenter(shapeA)! const rotateCenter = editor.getPageCenter(shapeA)!
const rotateEnd = Vec2d.RotWith(rotateStart, rotateCenter, rotation) const rotateEnd = Vec2d.RotWith(rotateStart, rotateCenter, rotation)
@ -356,7 +358,10 @@ describe('When resizing mulitple shapes...', () => {
expect(Vec2d.Dist(resizeStart, resizeEnd)).toBeCloseTo(offset.len()) expect(Vec2d.Dist(resizeStart, resizeEnd)).toBeCloseTo(offset.len())
expect( expect(
Vec2d.Min(editor.getPageBounds(shapeB)!.point, editor.getPageBounds(shapeC)!.point) Vec2d.Min(
editor.getShapePageBounds(shapeB)!.point,
editor.getShapePageBounds(shapeC)!.point
)
).toCloselyMatchObject(resizeStart) ).toCloselyMatchObject(resizeStart)
editor editor
@ -2326,10 +2331,10 @@ describe('snapping while resizing a shape that has been rotated by multiples of
.pointerUp(100, 40, { shiftKey: true }) .pointerUp(100, 40, { shiftKey: true })
} }
expect(editor.getPageBounds(ids.boxX)!.x).toBeCloseTo(40) expect(editor.getShapePageBounds(ids.boxX)!.x).toBeCloseTo(40)
expect(editor.getPageBounds(ids.boxX)!.y).toBeCloseTo(40) expect(editor.getShapePageBounds(ids.boxX)!.y).toBeCloseTo(40)
expect(editor.getPageBounds(ids.boxX)!.w).toBeCloseTo(60) expect(editor.getShapePageBounds(ids.boxX)!.w).toBeCloseTo(60)
expect(editor.getPageBounds(ids.boxX)!.h).toBeCloseTo(60) expect(editor.getShapePageBounds(ids.boxX)!.h).toBeCloseTo(60)
expect(editor.getShape(ids.boxX)!.rotation).toEqual( expect(editor.getShape(ids.boxX)!.rotation).toEqual(
canonicalizeRotation(((PI / 2) * times) % (PI * 2)) canonicalizeRotation(((PI / 2) * times) % (PI * 2))
) )
@ -2359,7 +2364,7 @@ describe('snapping while resizing a shape that has been rotated by multiples of
.pointerMove(121, 70, { ctrlKey: true, shiftKey: false }) .pointerMove(121, 70, { ctrlKey: true, shiftKey: false })
jest.advanceTimersByTime(200) jest.advanceTimersByTime(200)
expect(editor.getPageBounds(ids.boxX)!).toMatchObject({ expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
x: 40, x: 40,
y: 40, y: 40,
w: 80, w: 80,
@ -2389,7 +2394,7 @@ describe('snapping while resizing a shape that has been rotated by multiples of
// 140 └───┘ // 140 └───┘
editor.keyDown('Alt', { altKey: true, ctrlKey: true }) editor.keyDown('Alt', { altKey: true, ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!).toMatchObject({ expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
x: 20, x: 20,
y: 40, y: 40,
w: 100, w: 100,
@ -2427,10 +2432,10 @@ describe('snapping while resizing a shape that has been rotated by multiples of
.pointerMove(70, 18, { ctrlKey: true, shiftKey: false }) .pointerMove(70, 18, { ctrlKey: true, shiftKey: false })
jest.advanceTimersByTime(200) jest.advanceTimersByTime(200)
expect(editor.getPageBounds(ids.boxX)!.x).toBeCloseTo(40) expect(editor.getShapePageBounds(ids.boxX)!.x).toBeCloseTo(40)
expect(editor.getPageBounds(ids.boxX)!.y).toBeCloseTo(20) expect(editor.getShapePageBounds(ids.boxX)!.y).toBeCloseTo(20)
expect(editor.getPageBounds(ids.boxX)!.w).toBeCloseTo(60) expect(editor.getShapePageBounds(ids.boxX)!.w).toBeCloseTo(60)
expect(editor.getPageBounds(ids.boxX)!.h).toBeCloseTo(80) expect(editor.getShapePageBounds(ids.boxX)!.h).toBeCloseTo(80)
expect(getSnapLines(editor)).toMatchInlineSnapshot(` expect(getSnapLines(editor)).toMatchInlineSnapshot(`
Array [ Array [
@ -2455,10 +2460,10 @@ describe('snapping while resizing a shape that has been rotated by multiples of
// │ C │ // │ C │
// 140 └───┘ // 140 └───┘
editor.keyDown('Shift', { ctrlKey: true }) editor.keyDown('Shift', { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!.x).toBeCloseTo(30) expect(editor.getShapePageBounds(ids.boxX)!.x).toBeCloseTo(30)
expect(editor.getPageBounds(ids.boxX)!.y).toBeCloseTo(20) expect(editor.getShapePageBounds(ids.boxX)!.y).toBeCloseTo(20)
expect(editor.getPageBounds(ids.boxX)!.w).toBeCloseTo(80) expect(editor.getShapePageBounds(ids.boxX)!.w).toBeCloseTo(80)
expect(editor.getPageBounds(ids.boxX)!.h).toBeCloseTo(80) expect(editor.getShapePageBounds(ids.boxX)!.h).toBeCloseTo(80)
expect(getSnapLines(editor)).toMatchInlineSnapshot(` expect(getSnapLines(editor)).toMatchInlineSnapshot(`
Array [ Array [
@ -2490,10 +2495,10 @@ describe('snapping while resizing a shape that has been rotated by multiples of
.pointerDown(40, 100, { target: 'selection', handle: 'top_left' }) .pointerDown(40, 100, { target: 'selection', handle: 'top_left' })
.pointerMove(18, 118, { ctrlKey: true, shiftKey: false }) .pointerMove(18, 118, { ctrlKey: true, shiftKey: false })
expect(editor.getPageBounds(ids.boxX)!.x).toBeCloseTo(20) expect(editor.getShapePageBounds(ids.boxX)!.x).toBeCloseTo(20)
expect(editor.getPageBounds(ids.boxX)!.y).toBeCloseTo(40) expect(editor.getShapePageBounds(ids.boxX)!.y).toBeCloseTo(40)
expect(editor.getPageBounds(ids.boxX)!.w).toBeCloseTo(80) expect(editor.getShapePageBounds(ids.boxX)!.w).toBeCloseTo(80)
expect(editor.getPageBounds(ids.boxX)!.h).toBeCloseTo(80) expect(editor.getShapePageBounds(ids.boxX)!.h).toBeCloseTo(80)
expect(getSnapLines(editor)).toMatchInlineSnapshot(` expect(getSnapLines(editor)).toMatchInlineSnapshot(`
Array [ Array [
@ -2521,10 +2526,10 @@ describe('snapping while resizing a shape that has been rotated by multiples of
editor.keyDown('Alt', { ctrlKey: true }) editor.keyDown('Alt', { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!.x).toBeCloseTo(20) expect(editor.getShapePageBounds(ids.boxX)!.x).toBeCloseTo(20)
expect(editor.getPageBounds(ids.boxX)!.y).toBeCloseTo(20) expect(editor.getShapePageBounds(ids.boxX)!.y).toBeCloseTo(20)
expect(editor.getPageBounds(ids.boxX)!.w).toBeCloseTo(100) expect(editor.getShapePageBounds(ids.boxX)!.w).toBeCloseTo(100)
expect(editor.getPageBounds(ids.boxX)!.h).toBeCloseTo(100) expect(editor.getShapePageBounds(ids.boxX)!.h).toBeCloseTo(100)
expect(getSnapLines(editor)).toMatchInlineSnapshot(` expect(getSnapLines(editor)).toMatchInlineSnapshot(`
Array [ Array [
@ -2559,10 +2564,10 @@ describe('snapping while resizing a shape that has been rotated by multiples of
.pointerMove(121, 70, { ctrlKey: true, shiftKey: false }) .pointerMove(121, 70, { ctrlKey: true, shiftKey: false })
jest.advanceTimersByTime(200) jest.advanceTimersByTime(200)
expect(editor.getPageBounds(ids.boxX)!.x).toBeCloseTo(40) expect(editor.getShapePageBounds(ids.boxX)!.x).toBeCloseTo(40)
expect(editor.getPageBounds(ids.boxX)!.y).toBeCloseTo(40) expect(editor.getShapePageBounds(ids.boxX)!.y).toBeCloseTo(40)
expect(editor.getPageBounds(ids.boxX)!.w).toBeCloseTo(80) expect(editor.getShapePageBounds(ids.boxX)!.w).toBeCloseTo(80)
expect(editor.getPageBounds(ids.boxX)!.h).toBeCloseTo(60) expect(editor.getShapePageBounds(ids.boxX)!.h).toBeCloseTo(60)
expect(getSnapLines(editor)).toMatchInlineSnapshot(` expect(getSnapLines(editor)).toMatchInlineSnapshot(`
Array [ Array [
@ -2588,10 +2593,10 @@ describe('snapping while resizing a shape that has been rotated by multiples of
// 140 └───┘ // 140 └───┘
editor.keyDown('Alt', { ctrlKey: true }) editor.keyDown('Alt', { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!.x).toBeCloseTo(20) expect(editor.getShapePageBounds(ids.boxX)!.x).toBeCloseTo(20)
expect(editor.getPageBounds(ids.boxX)!.y).toBeCloseTo(40) expect(editor.getShapePageBounds(ids.boxX)!.y).toBeCloseTo(40)
expect(editor.getPageBounds(ids.boxX)!.w).toBeCloseTo(100) expect(editor.getShapePageBounds(ids.boxX)!.w).toBeCloseTo(100)
expect(editor.getPageBounds(ids.boxX)!.h).toBeCloseTo(60) expect(editor.getShapePageBounds(ids.boxX)!.h).toBeCloseTo(60)
expect(getSnapLines(editor)).toMatchInlineSnapshot(` expect(getSnapLines(editor)).toMatchInlineSnapshot(`
Array [ Array [
@ -2654,7 +2659,7 @@ describe('snapping while resizing an inverted shape', () => {
}) })
.pointerMove(70, 123, { ctrlKey: true }) .pointerMove(70, 123, { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!).toMatchObject({ expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
x: 40, x: 40,
y: 100, y: 100,
w: 60, w: 60,
@ -2693,7 +2698,7 @@ describe('snapping while resizing an inverted shape', () => {
}) })
.pointerMove(18, 70, { ctrlKey: true }) .pointerMove(18, 70, { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!).toMatchObject({ expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
x: 20, x: 20,
y: 40, y: 40,
w: 20, w: 20,
@ -2732,7 +2737,7 @@ describe('snapping while resizing an inverted shape', () => {
}) })
.pointerMove(70, 23, { ctrlKey: true }) .pointerMove(70, 23, { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!).toMatchObject({ expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
x: 40, x: 40,
y: 20, y: 20,
w: 60, w: 60,
@ -2771,7 +2776,7 @@ describe('snapping while resizing an inverted shape', () => {
}) })
.pointerMove(122, 70, { ctrlKey: true }) .pointerMove(122, 70, { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!).toMatchObject({ expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
x: 100, x: 100,
y: 40, y: 40,
w: 20, w: 20,
@ -2809,7 +2814,7 @@ describe('snapping while resizing an inverted shape', () => {
}) })
.pointerMove(19, 121, { ctrlKey: true }) .pointerMove(19, 121, { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!).toMatchObject({ expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
x: 20, x: 20,
y: 100, y: 100,
w: 20, w: 20,
@ -2849,7 +2854,7 @@ describe('snapping while resizing an inverted shape', () => {
}) })
.pointerMove(19, 21, { ctrlKey: true }) .pointerMove(19, 21, { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!).toMatchObject({ expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
x: 20, x: 20,
y: 20, y: 20,
w: 20, w: 20,
@ -2887,7 +2892,7 @@ describe('snapping while resizing an inverted shape', () => {
}) })
.pointerMove(123, 21, { ctrlKey: true }) .pointerMove(123, 21, { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!).toMatchObject({ expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
x: 100, x: 100,
y: 20, y: 20,
w: 20, w: 20,
@ -2925,7 +2930,7 @@ describe('snapping while resizing an inverted shape', () => {
}) })
.pointerMove(123, 118, { ctrlKey: true }) .pointerMove(123, 118, { ctrlKey: true })
expect(editor.getPageBounds(ids.boxX)!).toMatchObject({ expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
x: 100, x: 100,
y: 100, y: 100,
w: 20, w: 20,
@ -2968,7 +2973,7 @@ describe('snapping while the grid is enabled', () => {
.pointerMove(59, 10) .pointerMove(59, 10)
// rounds up to nearest 10 // rounds up to nearest 10
expect(editor.getPageBounds(ids.boxA)!.w).toEqual(60) expect(editor.getShapePageBounds(ids.boxA)!.w).toEqual(60)
// engage snap mode and it should indeed snap to B // engage snap mode and it should indeed snap to B
@ -2977,7 +2982,7 @@ describe('snapping while the grid is enabled', () => {
// │ A │ B │ // │ A │ B │
// x───────────x───x // x───────────x───x
editor.keyDown('Control') editor.keyDown('Control')
expect(editor.getPageBounds(ids.boxA)!.w).toEqual(60) expect(editor.getShapePageBounds(ids.boxA)!.w).toEqual(60)
expect(getSnapLines(editor)).toMatchInlineSnapshot(` expect(getSnapLines(editor)).toMatchInlineSnapshot(`
Array [ Array [
"0,0 60,0 80,0", "0,0 60,0 80,0",
@ -2988,7 +2993,7 @@ describe('snapping while the grid is enabled', () => {
// and if not snapping we can make the box any size // and if not snapping we can make the box any size
editor.pointerMove(19, 10, { ctrlKey: true }) editor.pointerMove(19, 10, { ctrlKey: true })
expect(editor.getPageBounds(ids.boxA)!.w).toEqual(19) expect(editor.getShapePageBounds(ids.boxA)!.w).toEqual(19)
}) })
}) })
@ -3018,7 +3023,7 @@ describe('resizing a shape with a child', () => {
expect(editor.snaps.lines.length).toBe(0) expect(editor.snaps.lines.length).toBe(0)
expect(editor.getShape(ids.boxA)).toMatchObject({ x: 25, y: 25, props: { w: 25, h: 25 } }) expect(editor.getShape(ids.boxA)).toMatchObject({ x: 25, y: 25, props: { w: 25, h: 25 } })
expect(editor.getShape(ids.boxB)).toMatchObject({ x: 0.5, y: 0.5, props: { w: 5, h: 5 } }) expect(editor.getShape(ids.boxB)).toMatchObject({ x: 0.5, y: 0.5, props: { w: 5, h: 5 } })
expect(editor.getPageBounds(ids.boxB)).toMatchObject({ expect(editor.getShapePageBounds(ids.boxB)).toMatchObject({
x: 25.5, x: 25.5,
y: 25.5, y: 25.5,
w: 5, w: 5,
@ -3543,16 +3548,16 @@ describe('nodes that have do not resize', () => {
editor.createShapes([box(ids.boxA, 0, 0, 200, 200), { id: noteBId, type: 'note', x: 0, y: 0 }]) editor.createShapes([box(ids.boxA, 0, 0, 200, 200), { id: noteBId, type: 'note', x: 0, y: 0 }])
// the default width and height of a note is 200 // the default width and height of a note is 200
expect(editor.getPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 200, h: 200 }) expect(editor.getShapePageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 200, h: 200 })
expect(editor.getPageBounds(noteBId)).toMatchObject({ x: 0, y: 0, w: 200, h: 200 }) expect(editor.getShapePageBounds(noteBId)).toMatchObject({ x: 0, y: 0, w: 200, h: 200 })
editor.select(ids.boxA, noteBId) editor.select(ids.boxA, noteBId)
editor.resizeSelection({ scaleX: 2, scaleY: 2 }, 'bottom_right') editor.resizeSelection({ scaleX: 2, scaleY: 2 }, 'bottom_right')
expect(editor.getPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 400, h: 400 }) expect(editor.getShapePageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 400, h: 400 })
// noteB should be in the middle of boxA // noteB should be in the middle of boxA
expect(editor.getPageBounds(noteBId)).toMatchObject({ x: 100, y: 100, w: 200, h: 200 }) expect(editor.getShapePageBounds(noteBId)).toMatchObject({ x: 100, y: 100, w: 200, h: 200 })
}) })
it('can flip', () => { it('can flip', () => {
const noteBId = createShapeId('noteB') const noteBId = createShapeId('noteB')
@ -3567,15 +3572,20 @@ describe('nodes that have do not resize', () => {
editor.flipShapes(editor.selectedShapeIds, 'horizontal') editor.flipShapes(editor.selectedShapeIds, 'horizontal')
expect(editor.getPageBounds(ids.boxA)).toMatchObject({ x: 300, y: 0, w: 200, h: 200 }) expect(editor.getShapePageBounds(ids.boxA)).toMatchObject({ x: 300, y: 0, w: 200, h: 200 })
expect(editor.getPageBounds(noteBId)).toMatchObject({ x: 0, y: 0, w: 200, h: 200 }) expect(editor.getShapePageBounds(noteBId)).toMatchObject({ x: 0, y: 0, w: 200, h: 200 })
expect(editor.getPageBounds(noteCId)).toMatchObject({ x: 300, y: 300, w: 200, h: 200 }) expect(editor.getShapePageBounds(noteCId)).toMatchObject({ x: 300, y: 300, w: 200, h: 200 })
editor.flipShapes(editor.selectedShapeIds, 'vertical') editor.flipShapes(editor.selectedShapeIds, 'vertical')
expect(editor.getPageBounds(ids.boxA)).toMatchObject({ x: 300, y: 300, w: 200, h: 200 }) expect(editor.getShapePageBounds(ids.boxA)).toMatchObject({
expect(editor.getPageBounds(noteBId)).toMatchObject({ x: 0, y: 300, w: 200, h: 200 }) x: 300,
expect(editor.getPageBounds(noteCId)).toMatchObject({ x: 300, y: 0, w: 200, h: 200 }) y: 300,
w: 200,
h: 200,
})
expect(editor.getShapePageBounds(noteBId)).toMatchObject({ x: 0, y: 300, w: 200, h: 200 })
expect(editor.getShapePageBounds(noteCId)).toMatchObject({ x: 300, y: 0, w: 200, h: 200 })
}) })
}) })
@ -3811,9 +3821,9 @@ describe('bugs', () => {
// }, // },
// ]) // ])
// .select(shapeId) // .select(shapeId)
// expect(editor.selectionBounds!.width).toBe(0) // expect(editor.selectionRotatedBounds!.width).toBe(0)
// editor.pointerDown(0, 100, { target: 'selection', handle: 'bottom_right' }).pointerMove(10, 110) // editor.pointerDown(0, 100, { target: 'selection', handle: 'bottom_right' }).pointerMove(10, 110)
// expect(editor.selectionBounds!.width).toBe(0) // expect(editor.selectionRotatedBounds!.width).toBe(0)
// }) // })
}) })
@ -3842,7 +3852,7 @@ describe('Resizing text from the right edge', () => {
editor.select(id) editor.select(id)
const bounds = editor.getGeometry(id).bounds const bounds = editor.getShapeGeometry(id).bounds
editor.updateInstanceState({ isCoarsePointer: false }) editor.updateInstanceState({ isCoarsePointer: false })
@ -3869,7 +3879,7 @@ describe('Resizing text from the right edge', () => {
editor.select(id) editor.select(id)
const bounds = editor.getGeometry(id).bounds const bounds = editor.getShapeGeometry(id).bounds
// Resize from the right edge // Resize from the right edge
editor.pointerDown(bounds.maxX, bounds.midY, { target: 'selection', handle: 'right' }) // right edge editor.pointerDown(bounds.maxX, bounds.midY, { target: 'selection', handle: 'right' }) // right edge

View file

@ -32,7 +32,7 @@ it('lists a sorted shapes array correctly', () => {
editor.sendBackward([ids.frame1]) editor.sendBackward([ids.frame1])
editor.sendBackward([ids.frame1]) editor.sendBackward([ids.frame1])
expect(editor.sortedShapesOnCurrentPage.map((s) => s.id)).toEqual([ expect(editor.currentPageShapesSorted.map((s) => s.id)).toEqual([
ids.box1, ids.box1,
ids.frame1, ids.frame1,
ids.box4, ids.box4,
@ -329,8 +329,8 @@ describe('When a shape is behind a frame', () => {
it('does not select the shape when clicked inside', () => { it('does not select the shape when clicked inside', () => {
editor.sendToBack([ids.box1]) // send it to back! editor.sendToBack([ids.box1]) // send it to back!
expect(editor.sortedShapesOnCurrentPage.map((s) => s.index)).toEqual(['a1', 'a2']) expect(editor.currentPageShapesSorted.map((s) => s.index)).toEqual(['a1', 'a2'])
expect(editor.sortedShapesOnCurrentPage.map((s) => s.id)).toEqual([ids.box1, ids.frame1]) expect(editor.currentPageShapesSorted.map((s) => s.id)).toEqual([ids.box1, ids.frame1])
editor.pointerMove(50, 50) editor.pointerMove(50, 50)
expect(editor.hoveredShapeId).toBe(null) expect(editor.hoveredShapeId).toBe(null)
@ -690,7 +690,7 @@ describe('When shapes are overlapping', () => {
editor.bringToFront([ids.box5]) editor.bringToFront([ids.box5])
editor.bringToFront([ids.box2]) editor.bringToFront([ids.box2])
expect(editor.sortedShapesOnCurrentPage.map((s) => s.id)).toEqual([ expect(editor.currentPageShapesSorted.map((s) => s.id)).toEqual([
ids.box4, // filled ids.box4, // filled
ids.box1, // hollow ids.box1, // hollow
ids.box3, // hollow ids.box3, // hollow
@ -709,7 +709,7 @@ describe('When shapes are overlapping', () => {
}) })
it('selects the hollow above the filled shapes when in margin', () => { it('selects the hollow above the filled shapes when in margin', () => {
expect(editor.sortedShapesOnCurrentPage.map((s) => s.id)).toEqual([ expect(editor.currentPageShapesSorted.map((s) => s.id)).toEqual([
ids.box4, ids.box4,
ids.box1, ids.box1,
ids.box3, ids.box3,
@ -772,7 +772,7 @@ describe('Selects inside of groups', () => {
}) })
it('cretes the group with the correct bounds', () => { it('cretes the group with the correct bounds', () => {
expect(editor.getGeometry(ids.group1).bounds).toMatchObject({ expect(editor.getShapeGeometry(ids.group1).bounds).toMatchObject({
x: 0, x: 0,
y: 0, y: 0,
w: 300, w: 300,
@ -1492,7 +1492,7 @@ describe('scribble brushes to add to the selection', () => {
describe('creating text on double click', () => { describe('creating text on double click', () => {
it('creates text on double click', () => { it('creates text on double click', () => {
editor.doubleClick() editor.doubleClick()
expect(editor.shapesOnCurrentPage.length).toBe(1) expect(editor.currentPageShapes.length).toBe(1)
editor.pointerMove(0, 100) editor.pointerMove(0, 100)
editor.click() editor.click()
}) })

View file

@ -19,30 +19,30 @@ const ids = {
describe('shapeIdsInCurrentPage', () => { describe('shapeIdsInCurrentPage', () => {
it('keeps the shape ids in the current page', () => { it('keeps the shape ids in the current page', () => {
expect(new Set(editor.shapeIdsOnCurrentPage)).toEqual(new Set([])) expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([]))
editor.createShapes([{ type: 'geo', id: ids.box1 }]) editor.createShapes([{ type: 'geo', id: ids.box1 }])
expect(new Set(editor.shapeIdsOnCurrentPage)).toEqual(new Set([ids.box1])) expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box1]))
editor.createShapes([{ type: 'geo', id: ids.box2 }]) editor.createShapes([{ type: 'geo', id: ids.box2 }])
expect(new Set(editor.shapeIdsOnCurrentPage)).toEqual(new Set([ids.box1, ids.box2])) expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box1, ids.box2]))
editor.createShapes([{ type: 'geo', id: ids.box3 }]) editor.createShapes([{ type: 'geo', id: ids.box3 }])
expect(new Set(editor.shapeIdsOnCurrentPage)).toEqual(new Set([ids.box1, ids.box2, ids.box3])) expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box1, ids.box2, ids.box3]))
editor.deleteShapes([ids.box2]) editor.deleteShapes([ids.box2])
expect(new Set(editor.shapeIdsOnCurrentPage)).toEqual(new Set([ids.box1, ids.box3])) expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box1, ids.box3]))
editor.deleteShapes([ids.box1]) editor.deleteShapes([ids.box1])
expect(new Set(editor.shapeIdsOnCurrentPage)).toEqual(new Set([ids.box3])) expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box3]))
editor.deleteShapes([ids.box3]) editor.deleteShapes([ids.box3])
expect(new Set(editor.shapeIdsOnCurrentPage)).toEqual(new Set([])) expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([]))
}) })
it('changes when the current page changes', () => { it('changes when the current page changes', () => {
@ -60,10 +60,10 @@ describe('shapeIdsInCurrentPage', () => {
{ type: 'geo', id: ids.box6 }, { type: 'geo', id: ids.box6 },
]) ])
expect(new Set(editor.shapeIdsOnCurrentPage)).toEqual(new Set([ids.box4, ids.box5, ids.box6])) expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box4, ids.box5, ids.box6]))
editor.setCurrentPage(editor.pages[0].id) editor.setCurrentPage(editor.pages[0].id)
expect(new Set(editor.shapeIdsOnCurrentPage)).toEqual(new Set([ids.box1, ids.box2, ids.box3])) expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box1, ids.box2, ids.box3]))
}) })
}) })

Some files were not shown because too many files have changed in this diff Show more