From 44f0a3d6d04f8128789b348073e8a47edc5e9d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mitja=20Bezen=C5=A1ek?= Date: Fri, 26 Apr 2024 14:32:41 +0200 Subject: [PATCH] Add result type. --- .../AfterCreateUpdateShapeExample.tsx | 27 +++--- .../BeforeDeleteShapeExample.tsx | 39 ++++----- packages/editor/api-report.md | 2 +- packages/editor/src/lib/editor/Editor.ts | 17 ++-- .../BaseBoxShapeTool/children/Pointing.ts | 36 +++++--- .../editor/src/lib/editor/types/misc-types.ts | 40 +++++++++ .../src/lib/defaultExternalContentHandlers.ts | 14 ++- .../lib/shapes/arrow/ArrowShapeUtil.test.ts | 4 +- .../src/lib/shapes/geo/toolStates/Pointing.ts | 46 +++++----- .../lib/shapes/text/toolStates/Pointing.ts | 29 ++++--- .../DebugMenu/DefaultDebugMenuContent.tsx | 3 +- packages/tldraw/src/test/SelectTool.test.ts | 14 ++- .../commands/getInitialMetaForShape.test.ts | 6 +- packages/tldraw/src/test/duplicate.test.ts | 20 ++--- packages/tldraw/src/test/frames.test.ts | 1 + packages/tldraw/src/test/paste.test.ts | 27 +++--- packages/tldraw/src/test/resizing.test.ts | 2 +- .../tldraw/src/test/selection-omnibus.test.ts | 85 +++++++++---------- 18 files changed, 236 insertions(+), 176 deletions(-) diff --git a/apps/examples/src/examples/after-create-update-shape/AfterCreateUpdateShapeExample.tsx b/apps/examples/src/examples/after-create-update-shape/AfterCreateUpdateShapeExample.tsx index f5414a755..b735e7cba 100644 --- a/apps/examples/src/examples/after-create-update-shape/AfterCreateUpdateShapeExample.tsx +++ b/apps/examples/src/examples/after-create-update-shape/AfterCreateUpdateShapeExample.tsx @@ -56,17 +56,18 @@ export default function AfterCreateUpdateShapeExample() { // create some shapes to demonstrate the side-effects we added function createDemoShapes(editor: Editor) { - editor - .createShapes( - 'there can only be one red shape'.split(' ').map((word, i) => ({ - id: createShapeId(), - type: 'text', - y: i * 30, - props: { - color: i === 5 ? 'red' : 'black', - text: word, - }, - })) - ) - .zoomToContent({ duration: 0 }) + const result = editor.createShapes( + 'there can only be one red shape'.split(' ').map((word, i) => ({ + id: createShapeId(), + type: 'text', + y: i * 30, + props: { + color: i === 5 ? 'red' : 'black', + text: word, + }, + })) + ) + if (result.ok) { + editor.zoomToContent({ duration: 0 }) + } } diff --git a/apps/examples/src/examples/before-delete-shape/BeforeDeleteShapeExample.tsx b/apps/examples/src/examples/before-delete-shape/BeforeDeleteShapeExample.tsx index a4ab4db37..617e17a7b 100644 --- a/apps/examples/src/examples/before-delete-shape/BeforeDeleteShapeExample.tsx +++ b/apps/examples/src/examples/before-delete-shape/BeforeDeleteShapeExample.tsx @@ -24,25 +24,26 @@ export default function BeforeDeleteShapeExample() { // create some shapes to demonstrate the side-effect we added function createDemoShapes(editor: Editor) { - editor - .createShapes([ - { - id: createShapeId(), - type: 'text', - props: { - text: "Red shapes can't be deleted", - color: 'red', - }, + const result = editor.createShapes([ + { + id: createShapeId(), + type: 'text', + props: { + text: "Red shapes can't be deleted", + color: 'red', }, - { - id: createShapeId(), - type: 'text', - y: 30, - props: { - text: 'but other shapes can', - color: 'black', - }, + }, + { + id: createShapeId(), + type: 'text', + y: 30, + props: { + text: 'but other shapes can', + color: 'black', }, - ]) - .zoomToContent({ duration: 0 }) + }, + ]) + if (result.ok) { + editor.zoomToContent({ duration: 0 }) + } } diff --git a/packages/editor/api-report.md b/packages/editor/api-report.md index 99c6779e9..0e5f1915a 100644 --- a/packages/editor/api-report.md +++ b/packages/editor/api-report.md @@ -634,7 +634,7 @@ export class Editor extends EventEmitter { }; createPage(page: Partial): this; createShape(shape: OptionalKeys, 'id'>): this; - createShapes(shapes: OptionalKeys, 'id'>[]): this; + createShapes(shapes: OptionalKeys, 'id'>[]): EditorResult; deleteAssets(assets: TLAsset[] | TLAssetId[]): this; deleteOpenMenu(id: string): this; deletePage(page: TLPage | TLPageId): this; diff --git a/packages/editor/src/lib/editor/Editor.ts b/packages/editor/src/lib/editor/Editor.ts index 88e44208f..37be641a3 100644 --- a/packages/editor/src/lib/editor/Editor.ts +++ b/packages/editor/src/lib/editor/Editor.ts @@ -129,7 +129,7 @@ import { } from './types/event-types' import { TLExternalAssetContent, TLExternalContent } from './types/external-content' import { TLHistoryBatchOptions } from './types/history-types' -import { OptionalKeys, RequiredKeys, TLSvgOptions } from './types/misc-types' +import { EditorResult, OptionalKeys, RequiredKeys, TLSvgOptions } from './types/misc-types' import { TLResizeHandle } from './types/selection-types' /** @public */ @@ -6242,12 +6242,14 @@ export class Editor extends EventEmitter { * * @public */ - createShapes(shapes: OptionalKeys, 'id'>[]): this { + createShapes( + shapes: OptionalKeys, 'id'>[] + ): EditorResult { if (!Array.isArray(shapes)) { - throw Error('Editor.createShapes: must provide an array of shapes or shape partials') + return EditorResult.error('not-an-array-of-shapes') } - if (this.getInstanceState().isReadonly) return this - if (shapes.length <= 0) return this + if (this.getInstanceState().isReadonly) return EditorResult.error('readonly-room') + if (shapes.length <= 0) return EditorResult.error('no-shapes-provied') const currentPageShapeIds = this.getCurrentPageShapeIds() @@ -6256,12 +6258,12 @@ export class Editor extends EventEmitter { if (maxShapesReached) { // can't create more shapes than fit on the page alertMaxShapes(this) - return this + return EditorResult.error('max-shapes-reached') } const focusedGroupId = this.getFocusedGroupId() - return this.batch(() => { + this.batch(() => { // 1. Parents // Make sure that each partial will become the child of either the @@ -6419,6 +6421,7 @@ export class Editor extends EventEmitter { this.store.put(shapeRecordsToCreate) }) + return EditorResult.ok() } private animatingShapes = new Map() diff --git a/packages/editor/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts b/packages/editor/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts index f9339d06d..790d4aab9 100644 --- a/packages/editor/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +++ b/packages/editor/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts @@ -28,20 +28,24 @@ export class Pointing extends StateNode { this.editor.mark(this.markId) - this.editor - .createShapes([ - { - id, - type: shapeType, - x: originPagePoint.x, - y: originPagePoint.y, - props: { - w: 1, - h: 1, - }, + const result = this.editor.createShapes([ + { + id, + type: shapeType, + x: originPagePoint.x, + y: originPagePoint.y, + props: { + w: 1, + h: 1, }, - ]) - .select(id) + }, + ]) + if (!result.ok) { + this.cancel() + return + } + + this.editor.select(id) this.editor.setCurrentTool('select.resizing', { ...info, target: 'selection', @@ -85,7 +89,7 @@ export class Pointing extends StateNode { this.editor.mark(this.markId) - this.editor.createShapes([ + const result = this.editor.createShapes([ { id, type: shapeType, @@ -93,6 +97,10 @@ export class Pointing extends StateNode { y: originPagePoint.y, }, ]) + if (!result.ok) { + this.cancel() + return + } const shape = this.editor.getShape(id)! const { w, h } = this.editor.getShapeUtil(shape).getDefaultProps() as TLBaseBoxShape['props'] diff --git a/packages/editor/src/lib/editor/types/misc-types.ts b/packages/editor/src/lib/editor/types/misc-types.ts index 6851e726d..befae341f 100644 --- a/packages/editor/src/lib/editor/types/misc-types.ts +++ b/packages/editor/src/lib/editor/types/misc-types.ts @@ -14,3 +14,43 @@ export type TLSvgOptions = { darkMode?: boolean preserveAspectRatio: React.SVGAttributes['preserveAspectRatio'] } + +export type TLEditorErrorType = keyof typeof TLEditorErrorTypeMap + +export type TLEditorError = { message: string; type: TLEditorErrorType } + +const TLEditorErrorTypeMap = { + 'not-an-array-of-shapes': { + message: 'createShapes requires an array of shapes', + type: 'not-an-array-of-shapes' as const, + }, + 'no-shapes-provied': { + message: 'No shapes provided', + type: 'no-shapes-provied' as const, + }, + 'readonly-room': { + message: 'Room is readonly', + type: 'readonly-room' as const, + }, + 'max-shapes-reached': { + message: 'Max shapes reached', + type: 'max-shapes-reached' as const, + }, +} + +export type ErrorResult = { ok: false; error: TLEditorError } +export type OkResult = { ok: true } +export type OkResultWithValue = { ok: true; value: T } + +export type EditorResult = ErrorResult | OkResult | OkResultWithValue +export const EditorResult = { + ok(): OkResult { + return { ok: true } + }, + okWithValue(value: T): OkResultWithValue { + return { ok: true, value } + }, + error(errorType: TLEditorErrorType): ErrorResult { + return { ok: false, error: TLEditorErrorTypeMap[errorType] } + }, +} diff --git a/packages/tldraw/src/lib/defaultExternalContentHandlers.ts b/packages/tldraw/src/lib/defaultExternalContentHandlers.ts index d35def4c7..01e0dd333 100644 --- a/packages/tldraw/src/lib/defaultExternalContentHandlers.ts +++ b/packages/tldraw/src/lib/defaultExternalContentHandlers.ts @@ -203,7 +203,10 @@ export function registerDefaultExternalContentHandlers( }, } - editor.createShapes([shapePartial]).select(id) + const result = editor.createShapes([shapePartial]) + if (result.ok) { + editor.select(id) + } }) // files @@ -483,7 +486,10 @@ export async function createShapesForAssets( } // Create the shapes - editor.createShapes(partials).select(...partials.map((p) => p.id)) + const result = editor.createShapes(partials) + if (!result.ok) return + + editor.select(...partials.map((p) => p.id)) // Re-position shapes so that the center of the group is at the provided point centerSelectionAroundPoint(editor, position) @@ -539,7 +545,9 @@ export function createEmptyBookmarkShape( } editor.batch(() => { - editor.createShapes([partial]).select(partial.id) + const result = editor.createShapes([partial]) + if (!result.ok) return + editor.select(partial.id) centerSelectionAroundPoint(editor, position) }) diff --git a/packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.test.ts b/packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.test.ts index 2105d6d4a..b378a43ed 100644 --- a/packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +++ b/packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.test.ts @@ -294,8 +294,8 @@ describe('Other cases when arrow are moved', () => { { id: ids.box3, type: 'geo', x: 0, y: 300, props: { w: 100, h: 100 } }, { id: ids.box4, type: 'geo', x: 0, y: 600, props: { w: 100, h: 100 } }, ]) - .selectAll() - .groupShapes(editor.getSelectedShapeIds()) + + editor.selectAll().groupShapes(editor.getSelectedShapeIds()) editor.setCurrentTool('arrow').pointerDown(1000, 1000).pointerMove(50, 350).pointerUp(50, 350) let arrow = editor.getCurrentPageShapes()[editor.getCurrentPageShapes().length - 1] diff --git a/packages/tldraw/src/lib/shapes/geo/toolStates/Pointing.ts b/packages/tldraw/src/lib/shapes/geo/toolStates/Pointing.ts index 3445efd16..214d4a37f 100644 --- a/packages/tldraw/src/lib/shapes/geo/toolStates/Pointing.ts +++ b/packages/tldraw/src/lib/shapes/geo/toolStates/Pointing.ts @@ -26,29 +26,31 @@ export class Pointing extends StateNode { this.editor.mark(this.markId) - this.editor - .createShapes([ - { - id, - type: 'geo', - x: originPagePoint.x, - y: originPagePoint.y, - props: { - w: 1, - h: 1, - geo: this.editor.getStyleForNextShape(GeoShapeGeoStyle), - }, + const result = this.editor.createShapes([ + { + id, + type: 'geo', + x: originPagePoint.x, + y: originPagePoint.y, + props: { + w: 1, + h: 1, + geo: this.editor.getStyleForNextShape(GeoShapeGeoStyle), }, - ]) - .select(id) - .setCurrentTool('select.resizing', { - ...info, - target: 'selection', - handle: 'bottom_right', - isCreating: true, - creationCursorOffset: { x: 1, y: 1 }, - onInteractionEnd: 'geo', - }) + }, + ]) + if (!result.ok) { + this.cancel() + return + } + this.editor.select(id).setCurrentTool('select.resizing', { + ...info, + target: 'selection', + handle: 'bottom_right', + isCreating: true, + creationCursorOffset: { x: 1, y: 1 }, + onInteractionEnd: 'geo', + }) } } diff --git a/packages/tldraw/src/lib/shapes/text/toolStates/Pointing.ts b/packages/tldraw/src/lib/shapes/text/toolStates/Pointing.ts index 1fc8bb648..6850ca12e 100644 --- a/packages/tldraw/src/lib/shapes/text/toolStates/Pointing.ts +++ b/packages/tldraw/src/lib/shapes/text/toolStates/Pointing.ts @@ -78,21 +78,24 @@ export class Pointing extends StateNode { this.editor.mark('creating text shape') const id = createShapeId() const { x, y } = this.editor.inputs.currentPagePoint - this.editor - .createShapes([ - { - id, - type: 'text', - x, - y, - props: { - text: '', - autoSize: true, - }, + const result = this.editor.createShapes([ + { + id, + type: 'text', + x, + y, + props: { + text: '', + autoSize: true, }, - ]) - .select(id) + }, + ]) + if (!result.ok) { + this.cancel() + return + } + this.editor.select(id) this.editor.setEditingShape(id) this.editor.setCurrentTool('select') this.editor.root.getCurrent()?.transition('editing_shape') diff --git a/packages/tldraw/src/lib/ui/components/DebugMenu/DefaultDebugMenuContent.tsx b/packages/tldraw/src/lib/ui/components/DebugMenu/DefaultDebugMenuContent.tsx index 68b69382a..8076b9f6a 100644 --- a/packages/tldraw/src/lib/ui/components/DebugMenu/DefaultDebugMenuContent.tsx +++ b/packages/tldraw/src/lib/ui/components/DebugMenu/DefaultDebugMenuContent.tsx @@ -295,6 +295,7 @@ function createNShapes(editor: Editor, n: number) { } editor.batch(() => { - editor.createShapes(shapesToCreate).setSelectedShapes(shapesToCreate.map((s) => s.id)) + editor.createShapes(shapesToCreate) + editor.setSelectedShapes(shapesToCreate.map((s) => s.id)) }) } diff --git a/packages/tldraw/src/test/SelectTool.test.ts b/packages/tldraw/src/test/SelectTool.test.ts index c02db8605..f23e8c5ba 100644 --- a/packages/tldraw/src/test/SelectTool.test.ts +++ b/packages/tldraw/src/test/SelectTool.test.ts @@ -292,6 +292,7 @@ describe('When double clicking a shape', () => { .deleteShapes(editor.getSelectedShapeIds()) .selectNone() .createShapes([{ id: createShapeId(), type: 'geo' }]) + editor .doubleClick(50, 50, { target: 'shape', shape: editor.getCurrentPageShapes()[0] }) .expectToBeIn('select.editing_shape') }) @@ -305,9 +306,7 @@ describe('When pressing enter on a selected shape', () => { .deleteShapes(editor.getSelectedShapeIds()) .selectNone() .createShapes([{ id, type: 'geo' }]) - .select(id) - .keyUp('Enter') - .expectToBeIn('select.editing_shape') + editor.select(id).keyUp('Enter').expectToBeIn('select.editing_shape') }) }) @@ -336,8 +335,7 @@ describe('When double clicking the selection edge', () => { .deleteShapes(editor.getSelectedShapeIds()) .selectNone() .createShapes([{ id, type: 'text', x: 100, y: 100, props: { scale: 2, text: 'hello' } }]) - .select(id) - .doubleClick(100, 100, { target: 'selection', handle: 'left' }) + editor.select(id).doubleClick(100, 100, { target: 'selection', handle: 'left' }) editor.expectShapeToMatch({ id, props: { scale: 1 } }) }) @@ -355,8 +353,7 @@ describe('When double clicking the selection edge', () => { props: { scale: 2, autoSize: false, w: 200, text: 'hello' }, }, ]) - .select(id) - .doubleClick(100, 100, { target: 'selection', handle: 'left' }) + editor.select(id).doubleClick(100, 100, { target: 'selection', handle: 'left' }) editor.expectShapeToMatch({ id, props: { scale: 2, autoSize: true } }) @@ -378,6 +375,7 @@ describe('When double clicking the selection edge', () => { props: { scale: 2, autoSize: false, w: 200, text: 'hello' }, }, ]) + editor .select(id) .doubleClick(100, 100, { target: 'selection', handle: 'left' }) .doubleClick(100, 100, { target: 'selection', handle: 'left' }) @@ -402,7 +400,7 @@ describe('When double clicking the selection edge', () => { type: 'geo', }, ]) - .select(id) + editor.select(id) expect(editor.getEditingShapeId()).toBe(null) editor.doubleClick(100, 100, { target: 'selection', handle: 'left' }) diff --git a/packages/tldraw/src/test/commands/getInitialMetaForShape.test.ts b/packages/tldraw/src/test/commands/getInitialMetaForShape.test.ts index 4622ec964..094f5f1da 100644 --- a/packages/tldraw/src/test/commands/getInitialMetaForShape.test.ts +++ b/packages/tldraw/src/test/commands/getInitialMetaForShape.test.ts @@ -9,13 +9,15 @@ beforeEach(() => { it('Sets shape meta by default to an empty object', () => { const id = createShapeId() - editor.createShapes([{ id, type: 'geo' }]).select(id) + editor.createShapes([{ id, type: 'geo' }]) + editor.select(id) expect(editor.getOnlySelectedShape()!.meta).toStrictEqual({}) }) it('Sets shape meta', () => { editor.getInitialMetaForShape = (shape) => ({ firstThreeCharactersOfId: shape.id.slice(0, 3) }) const id = createShapeId() - editor.createShapes([{ id, type: 'geo' }]).select(id) + editor.createShapes([{ id, type: 'geo' }]) + editor.select(id) expect(editor.getOnlySelectedShape()!.meta).toStrictEqual({ firstThreeCharactersOfId: 'sha' }) }) diff --git a/packages/tldraw/src/test/duplicate.test.ts b/packages/tldraw/src/test/duplicate.test.ts index c8461db90..b79d63428 100644 --- a/packages/tldraw/src/test/duplicate.test.ts +++ b/packages/tldraw/src/test/duplicate.test.ts @@ -182,7 +182,8 @@ describe('When duplicating shapes that include arrows', () => { }) it('Preserves the same selection bounds', () => { - editor.selectAll().deleteShapes(editor.getSelectedShapeIds()).createShapes(shapes).selectAll() + editor.selectAll().deleteShapes(editor.getSelectedShapeIds()).createShapes(shapes) + editor.selectAll() const boundsBefore = editor.getSelectionRotatedPageBounds()! editor.duplicateShapes(editor.getSelectedShapeIds()) @@ -190,16 +191,13 @@ describe('When duplicating shapes that include arrows', () => { }) it('Preserves the same selection bounds when only duplicating the arrows', () => { - editor - .selectAll() - .deleteShapes(editor.getSelectedShapeIds()) - .createShapes(shapes) - .select( - ...editor - .getCurrentPageShapes() - .filter((s) => editor.isShapeOfType(s, 'arrow')) - .map((s) => s.id) - ) + editor.selectAll().deleteShapes(editor.getSelectedShapeIds()).createShapes(shapes) + editor.select( + ...editor + .getCurrentPageShapes() + .filter((s) => editor.isShapeOfType(s, 'arrow')) + .map((s) => s.id) + ) const boundsBefore = editor.getSelectionRotatedPageBounds()! editor.duplicateShapes(editor.getSelectedShapeIds()) diff --git a/packages/tldraw/src/test/frames.test.ts b/packages/tldraw/src/test/frames.test.ts index 8631133fe..553e16ea3 100644 --- a/packages/tldraw/src/test/frames.test.ts +++ b/packages/tldraw/src/test/frames.test.ts @@ -177,6 +177,7 @@ describe('frame shapes', () => { editor // Create a frame .createShapes([{ id: frameId, type: 'frame', x: 100, y: 100, props: { w: 100, h: 100 } }]) + editor .select(frameId) // Rotate it by PI/2 .rotateSelection(Math.PI / 2) diff --git a/packages/tldraw/src/test/paste.test.ts b/packages/tldraw/src/test/paste.test.ts index cc1c26d3b..dc9a00dcf 100644 --- a/packages/tldraw/src/test/paste.test.ts +++ b/packages/tldraw/src/test/paste.test.ts @@ -395,7 +395,7 @@ describe('When pasting into frames...', () => { y: 500, }, ]) - .setScreenBounds({ x: 0, y: 0, w: 1000, h: 1000 }) + editor.setScreenBounds({ x: 0, y: 0, w: 1000, h: 1000 }) // put frame2 inside frame1 editor.reparentShapes([ids.frame2], ids.frame1) @@ -455,20 +455,19 @@ describe('When pasting into frames...', () => { editor.deleteShapes(editor.getSelectedShapeIds()) // create a big frame away from the origin, the size of the viewport - editor - .createShapes([ - { - id: ids.frame1, - type: 'frame', - x: editor.getViewportScreenBounds().w, - y: editor.getViewportScreenBounds().h, - props: { - w: editor.getViewportScreenBounds().w, - h: editor.getViewportScreenBounds().h, - }, + editor.createShapes([ + { + id: ids.frame1, + type: 'frame', + x: editor.getViewportScreenBounds().w, + y: editor.getViewportScreenBounds().h, + props: { + w: editor.getViewportScreenBounds().w, + h: editor.getViewportScreenBounds().h, }, - ]) - .selectAll() + }, + ]) + editor.selectAll() // rotate the frame for hard mode editor.rotateSelection(45) // center on the center of the frame diff --git a/packages/tldraw/src/test/resizing.test.ts b/packages/tldraw/src/test/resizing.test.ts index 651944642..2e7783d37 100644 --- a/packages/tldraw/src/test/resizing.test.ts +++ b/packages/tldraw/src/test/resizing.test.ts @@ -912,7 +912,7 @@ describe('When resizing a shape with children', () => { }, }, ]) - .select(ids.boxB, ids.lineA) + editor.select(ids.boxB, ids.lineA) editor .pointerDown(10, 10, { diff --git a/packages/tldraw/src/test/selection-omnibus.test.ts b/packages/tldraw/src/test/selection-omnibus.test.ts index e02acabf0..7259703fd 100644 --- a/packages/tldraw/src/test/selection-omnibus.test.ts +++ b/packages/tldraw/src/test/selection-omnibus.test.ts @@ -1132,13 +1132,12 @@ describe('Selects inside of groups', () => { describe('when selecting behind selection', () => { beforeEach(() => { - editor - .createShapes([ - { id: ids.box1, type: 'geo', x: 100, y: 0, props: { fill: 'solid' } }, - { id: ids.box2, type: 'geo', x: 0, y: 0 }, - { id: ids.box3, type: 'geo', x: 200, y: 0 }, - ]) - .select(ids.box2, ids.box3) + editor.createShapes([ + { id: ids.box1, type: 'geo', x: 100, y: 0, props: { fill: 'solid' } }, + { id: ids.box2, type: 'geo', x: 0, y: 0 }, + { id: ids.box3, type: 'geo', x: 200, y: 0 }, + ]) + editor.select(ids.box2, ids.box3) }) it('does not select on pointer down, only on pointer up', () => { @@ -1165,13 +1164,12 @@ describe('when selecting behind selection', () => { describe('when shift+selecting', () => { beforeEach(() => { - editor - .createShapes([ - { id: ids.box1, type: 'geo', x: 0, y: 0 }, - { id: ids.box2, type: 'geo', x: 200, y: 0 }, - { id: ids.box3, type: 'geo', x: 400, y: 0, props: { fill: 'solid' } }, - ]) - .select(ids.box1) + editor.createShapes([ + { id: ids.box1, type: 'geo', x: 0, y: 0 }, + { id: ids.box2, type: 'geo', x: 200, y: 0 }, + { id: ids.box3, type: 'geo', x: 400, y: 0, props: { fill: 'solid' } }, + ]) + editor.select(ids.box1) }) it('adds solid shape to selection on pointer down', () => { @@ -1281,15 +1279,13 @@ describe('when shift+selecting', () => { describe('when shift+selecting a group', () => { beforeEach(() => { - editor - .createShapes([ - { id: ids.box1, type: 'geo', x: 0, y: 0 }, - { id: ids.box2, type: 'geo', x: 200, y: 0 }, - { id: ids.box3, type: 'geo', x: 400, y: 0, props: { fill: 'solid' } }, - { id: ids.box4, type: 'geo', x: 600, y: 0 }, - ]) - .groupShapes([ids.box2, ids.box3], ids.group1) - .select(ids.box1) + editor.createShapes([ + { id: ids.box1, type: 'geo', x: 0, y: 0 }, + { id: ids.box2, type: 'geo', x: 200, y: 0 }, + { id: ids.box3, type: 'geo', x: 400, y: 0, props: { fill: 'solid' } }, + { id: ids.box4, type: 'geo', x: 600, y: 0 }, + ]) + editor.groupShapes([ids.box2, ids.box3], ids.group1).select(ids.box1) }) it('does not add group to selection when pointing empty space in the group', () => { @@ -1362,14 +1358,14 @@ describe('when shift+selecting a group', () => { describe('When children / descendants of a group are selected', () => { beforeEach(() => { + editor.createShapes([ + { id: ids.box1, type: 'geo', x: 0, y: 0 }, + { id: ids.box2, type: 'geo', x: 200, y: 0 }, + { id: ids.box3, type: 'geo', x: 400, y: 0, props: { fill: 'solid' } }, + { id: ids.box4, type: 'geo', x: 600, y: 0 }, + { id: ids.box5, type: 'geo', x: 800, y: 0 }, + ]) editor - .createShapes([ - { id: ids.box1, type: 'geo', x: 0, y: 0 }, - { id: ids.box2, type: 'geo', x: 200, y: 0 }, - { id: ids.box3, type: 'geo', x: 400, y: 0, props: { fill: 'solid' } }, - { id: ids.box4, type: 'geo', x: 600, y: 0 }, - { id: ids.box5, type: 'geo', x: 800, y: 0 }, - ]) .groupShapes([ids.box1, ids.box2], ids.group1) .groupShapes([ids.box3, ids.box4], ids.group2) .groupShapes([ids.group1, ids.group2], ids.group3) @@ -1437,14 +1433,14 @@ describe('When children / descendants of a group are selected', () => { describe('When pressing the enter key with groups selected', () => { beforeEach(() => { + editor.createShapes([ + { id: ids.box1, type: 'geo', x: 0, y: 0 }, + { id: ids.box2, type: 'geo', x: 200, y: 0 }, + { id: ids.box3, type: 'geo', x: 400, y: 0, props: { fill: 'solid' } }, + { id: ids.box4, type: 'geo', x: 600, y: 0 }, + { id: ids.box5, type: 'geo', x: 800, y: 0 }, + ]) editor - .createShapes([ - { id: ids.box1, type: 'geo', x: 0, y: 0 }, - { id: ids.box2, type: 'geo', x: 200, y: 0 }, - { id: ids.box3, type: 'geo', x: 400, y: 0, props: { fill: 'solid' } }, - { id: ids.box4, type: 'geo', x: 600, y: 0 }, - { id: ids.box5, type: 'geo', x: 800, y: 0 }, - ]) .groupShapes([ids.box1, ids.box2], ids.group1) .groupShapes([ids.box3, ids.box4], ids.group2) }) @@ -1545,14 +1541,13 @@ describe('When double clicking an editable shape', () => { describe('shift brushes to add to the selection', () => { beforeEach(() => { editor.user.updateUserPreferences({ isWrapMode: false }) - editor - .createShapes([ - { id: ids.box1, type: 'geo', x: 0, y: 0 }, - { id: ids.box2, type: 'geo', x: 200, y: 0 }, - { id: ids.box3, type: 'geo', x: 400, y: 0 }, - { id: ids.box4, type: 'geo', x: 600, y: 200 }, - ]) - .groupShapes([ids.box3, ids.box4], ids.group1) + editor.createShapes([ + { id: ids.box1, type: 'geo', x: 0, y: 0 }, + { id: ids.box2, type: 'geo', x: 200, y: 0 }, + { id: ids.box3, type: 'geo', x: 400, y: 0 }, + { id: ids.box4, type: 'geo', x: 600, y: 200 }, + ]) + editor.groupShapes([ids.box3, ids.box4], ids.group1) }) it('does not select when brushing into margin', () => {