@tldraw/editor 3.14.0-canary.8ea0ff8489db → 3.14.0-canary.8f303431285f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +166 -76
- package/dist-cjs/index.js +11 -10
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/config/TLSessionStateSnapshot.js +1 -12
- package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +3 -3
- package/dist-cjs/lib/editor/Editor.js +132 -101
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/bindingsIndex.js +22 -22
- package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js +16 -16
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
- package/dist-cjs/lib/editor/managers/{ClickManager.js → ClickManager/ClickManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{EdgeScrollManager.js → EdgeScrollManager/EdgeScrollManager.js} +2 -2
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{FontManager.js → FontManager/FontManager.js} +4 -1
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{HistoryManager.js → HistoryManager/HistoryManager.js} +67 -7
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{ScribbleManager.js → ScribbleManager/ScribbleManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{TextManager.js → TextManager/TextManager.js} +73 -42
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{TickManager.js → TickManager/TickManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{UserPreferencesManager.js → UserPreferencesManager/UserPreferencesManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +7 -0
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +0 -10
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +1 -1
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +1 -1
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +10 -6
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +3 -3
- package/dist-cjs/lib/editor/tools/StateNode.js +3 -3
- package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
- package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
- package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js.map +1 -1
- package/dist-cjs/lib/hooks/useCanvasEvents.js +1 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +33 -39
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +6 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js +11 -6
- package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
- package/dist-cjs/lib/utils/areShapesContentEqual.js +1 -1
- package/dist-cjs/lib/utils/areShapesContentEqual.js.map +2 -2
- package/dist-cjs/lib/utils/dom.js +1 -1
- package/dist-cjs/lib/utils/dom.js.map +2 -2
- package/dist-cjs/lib/utils/reorderShapes.js +11 -10
- package/dist-cjs/lib/utils/reorderShapes.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js +232 -0
- package/dist-cjs/lib/utils/reparenting.js.map +7 -0
- package/dist-cjs/lib/utils/richText.js +7 -2
- package/dist-cjs/lib/utils/richText.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +166 -76
- package/dist-esm/index.mjs +15 -10
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/config/TLSessionStateSnapshot.mjs +1 -1
- package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +132 -101
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/bindingsIndex.mjs +22 -22
- package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +16 -16
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/{ClickManager.mjs → ClickManager/ClickManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{EdgeScrollManager.mjs → EdgeScrollManager/EdgeScrollManager.mjs} +2 -2
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{FontManager.mjs → FontManager/FontManager.mjs} +4 -1
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{HistoryManager.mjs → HistoryManager/HistoryManager.mjs} +63 -3
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{ScribbleManager.mjs → ScribbleManager/ScribbleManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{TextManager.mjs → TextManager/TextManager.mjs} +73 -42
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{TickManager.mjs → TickManager/TickManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{UserPreferencesManager.mjs → UserPreferencesManager/UserPreferencesManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +7 -0
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +0 -10
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +1 -1
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +10 -6
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +3 -3
- package/dist-esm/lib/editor/tools/StateNode.mjs +3 -3
- package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +1 -1
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +1 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +33 -39
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +6 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs +11 -6
- package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
- package/dist-esm/lib/utils/areShapesContentEqual.mjs +1 -1
- package/dist-esm/lib/utils/areShapesContentEqual.mjs.map +2 -2
- package/dist-esm/lib/utils/dom.mjs +1 -1
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/lib/utils/reorderShapes.mjs +11 -10
- package/dist-esm/lib/utils/reorderShapes.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs +216 -0
- package/dist-esm/lib/utils/reparenting.mjs.map +7 -0
- package/dist-esm/lib/utils/richText.mjs +8 -3
- package/dist-esm/lib/utils/richText.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +446 -489
- package/package.json +8 -9
- package/src/index.ts +20 -8
- package/src/lib/config/TLSessionStateSnapshot.ts +1 -1
- package/src/lib/editor/Editor.test.ts +252 -3
- package/src/lib/editor/Editor.ts +151 -111
- package/src/lib/editor/bindings/BindingUtil.ts +6 -0
- package/src/lib/editor/derivations/bindingsIndex.ts +27 -26
- package/src/lib/editor/derivations/parentsToChildren.ts +28 -25
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +442 -0
- package/src/lib/editor/managers/{ClickManager.ts → ClickManager/ClickManager.ts} +3 -3
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +374 -0
- package/src/lib/editor/managers/{EdgeScrollManager.ts → EdgeScrollManager/EdgeScrollManager.ts} +3 -3
- package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +455 -0
- package/src/lib/editor/managers/{FocusManager.ts → FocusManager/FocusManager.ts} +1 -1
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +263 -0
- package/src/lib/editor/managers/{FontManager.ts → FontManager/FontManager.ts} +5 -2
- package/src/lib/editor/managers/{HistoryManager.test.ts → HistoryManager/HistoryManager.test.ts} +388 -1
- package/src/lib/editor/managers/{HistoryManager.ts → HistoryManager/HistoryManager.ts} +76 -3
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +624 -0
- package/src/lib/editor/managers/{ScribbleManager.ts → ScribbleManager/ScribbleManager.ts} +2 -2
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +485 -0
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +407 -0
- package/src/lib/editor/managers/{TextManager.ts → TextManager/TextManager.ts} +119 -87
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +314 -0
- package/src/lib/editor/managers/{TickManager.ts → TickManager/TickManager.ts} +2 -2
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +591 -0
- package/src/lib/editor/managers/{UserPreferencesManager.ts → UserPreferencesManager/UserPreferencesManager.ts} +2 -2
- package/src/lib/editor/shapes/ShapeUtil.ts +48 -16
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -1
- package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +22 -17
- package/src/lib/editor/tools/StateNode.ts +3 -3
- package/src/lib/editor/types/emit-types.ts +4 -0
- package/src/lib/editor/types/external-content.ts +11 -2
- package/src/lib/exports/getSvgJsx.tsx +1 -1
- package/src/lib/hooks/useCanvasEvents.ts +0 -1
- package/src/lib/primitives/Box.test.ts +588 -7
- package/src/lib/primitives/Box.ts +33 -41
- package/src/lib/primitives/geometry/Geometry2d.ts +7 -2
- package/src/lib/primitives/geometry/Group2d.ts +11 -5
- package/src/lib/utils/areShapesContentEqual.ts +1 -2
- package/src/lib/utils/dom.ts +1 -1
- package/src/lib/utils/reorderShapes.ts +10 -13
- package/src/lib/utils/reparenting.ts +383 -0
- package/src/lib/utils/richText.ts +10 -4
- package/src/version.ts +3 -3
- package/dist-cjs/lib/editor/managers/ClickManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/EdgeScrollManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/FocusManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/FontManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/HistoryManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/ScribbleManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/Stack.js +0 -82
- package/dist-cjs/lib/editor/managers/Stack.js.map +0 -7
- package/dist-cjs/lib/editor/managers/TextManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/TickManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/UserPreferencesManager.js.map +0 -7
- package/dist-esm/lib/editor/managers/ClickManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/EdgeScrollManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/FocusManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/FontManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/HistoryManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/ScribbleManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/Stack.mjs +0 -62
- package/dist-esm/lib/editor/managers/Stack.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/TextManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/TickManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/UserPreferencesManager.mjs.map +0 -7
- package/src/lib/editor/managers/ScribbleManager.test.ts +0 -32
- package/src/lib/editor/managers/Stack.ts +0 -71
- /package/dist-cjs/lib/editor/managers/{FocusManager.js → FocusManager/FocusManager.js} +0 -0
- /package/dist-esm/lib/editor/managers/{FocusManager.mjs → FocusManager/FocusManager.mjs} +0 -0
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -148,16 +148,16 @@ import { bindingsIndex } from './derivations/bindingsIndex'
|
|
|
148
148
|
import { notVisibleShapes } from './derivations/notVisibleShapes'
|
|
149
149
|
import { parentsToChildren } from './derivations/parentsToChildren'
|
|
150
150
|
import { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'
|
|
151
|
-
import { ClickManager } from './managers/ClickManager'
|
|
152
|
-
import { EdgeScrollManager } from './managers/EdgeScrollManager'
|
|
153
|
-
import { FocusManager } from './managers/FocusManager'
|
|
154
|
-
import { FontManager } from './managers/FontManager'
|
|
155
|
-
import { HistoryManager } from './managers/HistoryManager'
|
|
156
|
-
import { ScribbleManager } from './managers/ScribbleManager'
|
|
151
|
+
import { ClickManager } from './managers/ClickManager/ClickManager'
|
|
152
|
+
import { EdgeScrollManager } from './managers/EdgeScrollManager/EdgeScrollManager'
|
|
153
|
+
import { FocusManager } from './managers/FocusManager/FocusManager'
|
|
154
|
+
import { FontManager } from './managers/FontManager/FontManager'
|
|
155
|
+
import { HistoryManager } from './managers/HistoryManager/HistoryManager'
|
|
156
|
+
import { ScribbleManager } from './managers/ScribbleManager/ScribbleManager'
|
|
157
157
|
import { SnapManager } from './managers/SnapManager/SnapManager'
|
|
158
|
-
import { TextManager } from './managers/TextManager'
|
|
159
|
-
import { TickManager } from './managers/TickManager'
|
|
160
|
-
import { UserPreferencesManager } from './managers/UserPreferencesManager'
|
|
158
|
+
import { TextManager } from './managers/TextManager/TextManager'
|
|
159
|
+
import { TickManager } from './managers/TickManager/TickManager'
|
|
160
|
+
import { UserPreferencesManager } from './managers/UserPreferencesManager/UserPreferencesManager'
|
|
161
161
|
import { ShapeUtil, TLGeometryOpts, TLResizeMode } from './shapes/ShapeUtil'
|
|
162
162
|
import { RootState } from './tools/RootState'
|
|
163
163
|
import { StateNode, TLStateNodeConstructor } from './tools/StateNode'
|
|
@@ -328,7 +328,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
328
328
|
this.store = store
|
|
329
329
|
this.history = new HistoryManager<TLRecord>({
|
|
330
330
|
store,
|
|
331
|
-
annotateError: (error) => {
|
|
331
|
+
annotateError: (error: any) => {
|
|
332
332
|
this.annotateError(error, { origin: 'history.batch', willCrashApp: true })
|
|
333
333
|
this.crash(error)
|
|
334
334
|
},
|
|
@@ -348,6 +348,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
348
348
|
this.getContainer = getContainer
|
|
349
349
|
|
|
350
350
|
this.textMeasure = new TextManager(this)
|
|
351
|
+
this.disposables.add(() => this.textMeasure.dispose())
|
|
352
|
+
|
|
351
353
|
this.fonts = new FontManager(this, fontAssetUrls)
|
|
352
354
|
|
|
353
355
|
this._tickManager = new TickManager(this)
|
|
@@ -506,14 +508,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
506
508
|
shape: {
|
|
507
509
|
afterChange: (shapeBefore, shapeAfter) => {
|
|
508
510
|
for (const binding of this.getBindingsInvolvingShape(shapeAfter)) {
|
|
509
|
-
if (areShapesContentEqual(shapeBefore, shapeAfter)) continue
|
|
510
|
-
|
|
511
511
|
invalidBindingTypes.add(binding.type)
|
|
512
512
|
if (binding.fromId === shapeAfter.id) {
|
|
513
513
|
this.getBindingUtil(binding).onAfterChangeFromShape?.({
|
|
514
514
|
binding,
|
|
515
515
|
shapeBefore,
|
|
516
516
|
shapeAfter,
|
|
517
|
+
reason: 'self',
|
|
517
518
|
})
|
|
518
519
|
}
|
|
519
520
|
if (binding.toId === shapeAfter.id) {
|
|
@@ -521,6 +522,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
521
522
|
binding,
|
|
522
523
|
shapeBefore,
|
|
523
524
|
shapeAfter,
|
|
525
|
+
reason: 'self',
|
|
524
526
|
})
|
|
525
527
|
}
|
|
526
528
|
}
|
|
@@ -539,6 +541,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
539
541
|
binding,
|
|
540
542
|
shapeBefore: descendantShape,
|
|
541
543
|
shapeAfter: descendantShape,
|
|
544
|
+
reason: 'ancestry',
|
|
542
545
|
})
|
|
543
546
|
}
|
|
544
547
|
if (binding.toId === descendantShape.id) {
|
|
@@ -546,6 +549,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
546
549
|
binding,
|
|
547
550
|
shapeBefore: descendantShape,
|
|
548
551
|
shapeAfter: descendantShape,
|
|
552
|
+
reason: 'ancestry',
|
|
549
553
|
})
|
|
550
554
|
}
|
|
551
555
|
}
|
|
@@ -2118,6 +2122,20 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2118
2122
|
return this.getShapesPageBounds(this.getSelectedShapeIds())
|
|
2119
2123
|
}
|
|
2120
2124
|
|
|
2125
|
+
/**
|
|
2126
|
+
* The bounds of the selection bounding box in the current page space.
|
|
2127
|
+
*
|
|
2128
|
+
* @readonly
|
|
2129
|
+
* @public
|
|
2130
|
+
*/
|
|
2131
|
+
getSelectionScreenBounds(): Box | undefined {
|
|
2132
|
+
const bounds = this.getSelectionPageBounds()
|
|
2133
|
+
if (!bounds) return undefined
|
|
2134
|
+
const { x, y } = this.pageToScreen(bounds.point)
|
|
2135
|
+
const zoom = this.getZoomLevel()
|
|
2136
|
+
return new Box(x, y, bounds.width * zoom, bounds.height * zoom)
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2121
2139
|
/**
|
|
2122
2140
|
* @internal
|
|
2123
2141
|
*/
|
|
@@ -3644,7 +3662,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
3644
3662
|
* @public
|
|
3645
3663
|
*/
|
|
3646
3664
|
updateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this {
|
|
3647
|
-
if (screenBounds instanceof
|
|
3665
|
+
if (!(screenBounds instanceof Box)) {
|
|
3648
3666
|
const rect = screenBounds.getBoundingClientRect()
|
|
3649
3667
|
screenBounds = new Box(
|
|
3650
3668
|
rect.left || rect.x,
|
|
@@ -3717,10 +3735,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
3717
3735
|
*/
|
|
3718
3736
|
@computed getViewportScreenCenter() {
|
|
3719
3737
|
const viewportScreenBounds = this.getViewportScreenBounds()
|
|
3720
|
-
return new Vec(
|
|
3721
|
-
viewportScreenBounds.midX - viewportScreenBounds.minX,
|
|
3722
|
-
viewportScreenBounds.midY - viewportScreenBounds.minY
|
|
3723
|
-
)
|
|
3738
|
+
return new Vec(viewportScreenBounds.w / 2, viewportScreenBounds.h / 2)
|
|
3724
3739
|
}
|
|
3725
3740
|
|
|
3726
3741
|
/**
|
|
@@ -4646,44 +4661,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4646
4661
|
)! as T
|
|
4647
4662
|
}
|
|
4648
4663
|
|
|
4649
|
-
private _shapePageGeometryCaches: Record<string, ComputedCache<Geometry2d, TLShape>> = {}
|
|
4650
|
-
|
|
4651
|
-
/**
|
|
4652
|
-
* Get the geometry of a shape in page-space.
|
|
4653
|
-
*
|
|
4654
|
-
* @example
|
|
4655
|
-
* ```ts
|
|
4656
|
-
* editor.getShapePageGeometry(myShape)
|
|
4657
|
-
* editor.getShapePageGeometry(myShapeId)
|
|
4658
|
-
* editor.getShapePageGeometry(myShapeId, { context: "arrow" })
|
|
4659
|
-
* ```
|
|
4660
|
-
*
|
|
4661
|
-
* @param shape - The shape (or shape id) to get the geometry for.
|
|
4662
|
-
* @param opts - Additional options about the request for geometry. Passed to {@link ShapeUtil.getGeometry}.
|
|
4663
|
-
*
|
|
4664
|
-
* @public
|
|
4665
|
-
*/
|
|
4666
|
-
getShapePageGeometry<T extends Geometry2d>(shape: TLShape | TLShapeId, opts?: TLGeometryOpts): T {
|
|
4667
|
-
const context = opts?.context ?? 'none'
|
|
4668
|
-
if (!this._shapePageGeometryCaches[context]) {
|
|
4669
|
-
this._shapePageGeometryCaches[context] = this.store.createComputedCache(
|
|
4670
|
-
'bounds',
|
|
4671
|
-
(shape) => {
|
|
4672
|
-
const geometry = this.getShapeGeometry(shape.id, opts)
|
|
4673
|
-
const pageTransform = this.getShapePageTransform(shape.id)
|
|
4674
|
-
return geometry.transform(pageTransform)
|
|
4675
|
-
},
|
|
4676
|
-
{
|
|
4677
|
-
// we only depend directly on the shape id, and changing geometry/transform will update us anyway
|
|
4678
|
-
areRecordsEqual: () => true,
|
|
4679
|
-
}
|
|
4680
|
-
)
|
|
4681
|
-
}
|
|
4682
|
-
return this._shapePageGeometryCaches[context].get(
|
|
4683
|
-
typeof shape === 'string' ? shape : shape.id
|
|
4684
|
-
)! as T
|
|
4685
|
-
}
|
|
4686
|
-
|
|
4687
4664
|
/** @internal */
|
|
4688
4665
|
@computed private _getShapeHandlesCache(): ComputedCache<TLHandle[] | undefined, TLShape> {
|
|
4689
4666
|
return this.store.createComputedCache(
|
|
@@ -4796,7 +4773,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4796
4773
|
/** @internal */
|
|
4797
4774
|
@computed private _getShapePageBoundsCache(): ComputedCache<Box, TLShape> {
|
|
4798
4775
|
return this.store.createComputedCache<Box, TLShape>('pageBoundsCache', (shape) => {
|
|
4799
|
-
|
|
4776
|
+
const pageTransform = this.getShapePageTransform(shape)
|
|
4777
|
+
if (!pageTransform) return undefined
|
|
4778
|
+
const geometry = this.getShapeGeometry(shape)
|
|
4779
|
+
return Box.FromPoints(pageTransform.applyToPoints(geometry.vertices))
|
|
4800
4780
|
})
|
|
4801
4781
|
}
|
|
4802
4782
|
|
|
@@ -4870,11 +4850,12 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4870
4850
|
if (frameAncestors.length === 0) return undefined
|
|
4871
4851
|
|
|
4872
4852
|
const pageMask = frameAncestors
|
|
4873
|
-
.map<Vec[] | undefined>(
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4853
|
+
.map<Vec[] | undefined>((s) => {
|
|
4854
|
+
// Apply the frame transform to the frame outline to get the frame outline in the current page space
|
|
4855
|
+
const geometry = this.getShapeGeometry(s.id)
|
|
4856
|
+
const pageTransform = this.getShapePageTransform(s.id)
|
|
4857
|
+
return pageTransform.applyToPoints(geometry.vertices)
|
|
4858
|
+
})
|
|
4878
4859
|
.reduce((acc, b) => {
|
|
4879
4860
|
if (!(b && acc)) return undefined
|
|
4880
4861
|
const intersection = intersectPolygonPolygon(acc, b)
|
|
@@ -5072,28 +5053,33 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5072
5053
|
*
|
|
5073
5054
|
* @public
|
|
5074
5055
|
*/
|
|
5075
|
-
isShapeOrAncestorLocked(shape?: TLShape): boolean
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
if (shape.isLocked) return true
|
|
5081
|
-
return this.isShapeOrAncestorLocked(this.getShapeParent(shape))
|
|
5056
|
+
isShapeOrAncestorLocked(shape?: TLShape | TLShapeId): boolean {
|
|
5057
|
+
const _shape = shape && this.getShape(shape)
|
|
5058
|
+
if (_shape === undefined) return false
|
|
5059
|
+
if (_shape.isLocked) return true
|
|
5060
|
+
return this.isShapeOrAncestorLocked(this.getShapeParent(_shape))
|
|
5082
5061
|
}
|
|
5083
5062
|
|
|
5063
|
+
/**
|
|
5064
|
+
* Get shapes that are outside of the viewport.
|
|
5065
|
+
*
|
|
5066
|
+
* @public
|
|
5067
|
+
*/
|
|
5084
5068
|
@computed
|
|
5085
|
-
|
|
5086
|
-
return
|
|
5069
|
+
getNotVisibleShapes() {
|
|
5070
|
+
return this._notVisibleShapes.get()
|
|
5087
5071
|
}
|
|
5088
5072
|
|
|
5073
|
+
private _notVisibleShapes = notVisibleShapes(this)
|
|
5074
|
+
|
|
5089
5075
|
/**
|
|
5090
|
-
* Get culled shapes.
|
|
5076
|
+
* Get culled shapes (those that should not render), taking into account which shapes are selected or editing.
|
|
5091
5077
|
*
|
|
5092
5078
|
* @public
|
|
5093
5079
|
*/
|
|
5094
5080
|
@computed
|
|
5095
5081
|
getCulledShapes() {
|
|
5096
|
-
const notVisibleShapes = this.
|
|
5082
|
+
const notVisibleShapes = this.getNotVisibleShapes()
|
|
5097
5083
|
const selectedShapeIds = this.getSelectedShapeIds()
|
|
5098
5084
|
const editingId = this.getEditingShapeId()
|
|
5099
5085
|
const culledShapes = new Set<TLShapeId>(notVisibleShapes)
|
|
@@ -5342,21 +5328,23 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5342
5328
|
* @example
|
|
5343
5329
|
* ```ts
|
|
5344
5330
|
* editor.getShapesAtPoint({ x: 100, y: 100 })
|
|
5345
|
-
* editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true,
|
|
5331
|
+
* editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, margin: 8 })
|
|
5346
5332
|
* ```
|
|
5347
5333
|
*
|
|
5348
5334
|
* @param point - The page point to test.
|
|
5349
5335
|
* @param opts - The options for the hit point testing.
|
|
5350
5336
|
*
|
|
5337
|
+
* @returns An array of shapes at the given point, sorted in reverse order of their absolute z-index (top-most shape first).
|
|
5338
|
+
*
|
|
5351
5339
|
* @public
|
|
5352
5340
|
*/
|
|
5353
5341
|
getShapesAtPoint(
|
|
5354
5342
|
point: VecLike,
|
|
5355
5343
|
opts = {} as { margin?: number; hitInside?: boolean }
|
|
5356
5344
|
): TLShape[] {
|
|
5357
|
-
return this.
|
|
5358
|
-
(shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts)
|
|
5359
|
-
|
|
5345
|
+
return this.getCurrentPageShapesSorted()
|
|
5346
|
+
.filter((shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts))
|
|
5347
|
+
.reverse()
|
|
5360
5348
|
}
|
|
5361
5349
|
|
|
5362
5350
|
/**
|
|
@@ -5540,7 +5528,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5540
5528
|
if (!id) return undefined
|
|
5541
5529
|
const freshShape = this.getShape(id)
|
|
5542
5530
|
if (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined
|
|
5543
|
-
return this.
|
|
5531
|
+
return this.getShape(freshShape.parentId)
|
|
5544
5532
|
}
|
|
5545
5533
|
|
|
5546
5534
|
/**
|
|
@@ -5723,6 +5711,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5723
5711
|
const newPoint = invertedParentTransform.applyToPoint(pagePoint)
|
|
5724
5712
|
const newRotation = pageTransform.rotation() - parentPageRotation
|
|
5725
5713
|
|
|
5714
|
+
if (shape.id === parentId) {
|
|
5715
|
+
throw Error('Attempted to reparent a shape to itself!')
|
|
5716
|
+
}
|
|
5717
|
+
|
|
5726
5718
|
changes.push({
|
|
5727
5719
|
id: shape.id,
|
|
5728
5720
|
type: shape.type,
|
|
@@ -5826,6 +5818,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5826
5818
|
return shapeIds
|
|
5827
5819
|
}
|
|
5828
5820
|
|
|
5821
|
+
/** @deprecated Use {@link Editor.getDraggingOverShape} instead */
|
|
5822
|
+
getDroppingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined {
|
|
5823
|
+
return this.getDraggingOverShape(point, droppingShapes)
|
|
5824
|
+
}
|
|
5825
|
+
|
|
5829
5826
|
/**
|
|
5830
5827
|
* Get the shape that some shapes should be dropped on at a given point.
|
|
5831
5828
|
*
|
|
@@ -5836,35 +5833,33 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5836
5833
|
*
|
|
5837
5834
|
* @public
|
|
5838
5835
|
*/
|
|
5839
|
-
|
|
5840
|
-
//
|
|
5841
|
-
const
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
if (
|
|
5846
|
-
// ignore hidden shapes
|
|
5847
|
-
this.isShapeHidden(shape) ||
|
|
5848
|
-
// don't allow dropping on selected shapes
|
|
5849
|
-
this.getSelectedShapeIds().includes(shape.id) ||
|
|
5850
|
-
// only allow shapes that can receive children
|
|
5851
|
-
!this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) ||
|
|
5852
|
-
// don't allow dropping a shape on itself or one of it's children
|
|
5853
|
-
droppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))
|
|
5854
|
-
) {
|
|
5855
|
-
continue
|
|
5856
|
-
}
|
|
5836
|
+
getDraggingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined {
|
|
5837
|
+
// get fresh moving shapes
|
|
5838
|
+
const draggingShapes = compact(droppingShapes.map((s) => this.getShape(s))).filter(
|
|
5839
|
+
(s) => !s.isLocked && !this.isShapeHidden(s)
|
|
5840
|
+
)
|
|
5857
5841
|
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5842
|
+
const maybeDraggingOverShapes = this.getShapesAtPoint(point, {
|
|
5843
|
+
hitInside: true,
|
|
5844
|
+
margin: 0,
|
|
5845
|
+
}).filter(
|
|
5846
|
+
(s) =>
|
|
5847
|
+
!droppingShapes.includes(s) &&
|
|
5848
|
+
!s.isLocked &&
|
|
5849
|
+
!this.isShapeHidden(s) &&
|
|
5850
|
+
!draggingShapes.includes(s)
|
|
5851
|
+
)
|
|
5861
5852
|
|
|
5853
|
+
for (const maybeDraggingOverShape of maybeDraggingOverShapes) {
|
|
5854
|
+
const shapeUtil = this.getShapeUtil(maybeDraggingOverShape)
|
|
5855
|
+
// Any shape that can handle any dragging interactions is a valid target
|
|
5862
5856
|
if (
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5857
|
+
shapeUtil.onDragShapesOver ||
|
|
5858
|
+
shapeUtil.onDragShapesIn ||
|
|
5859
|
+
shapeUtil.onDragShapesOut ||
|
|
5860
|
+
shapeUtil.onDropShapesOver
|
|
5866
5861
|
) {
|
|
5867
|
-
return
|
|
5862
|
+
return maybeDraggingOverShape
|
|
5868
5863
|
}
|
|
5869
5864
|
}
|
|
5870
5865
|
}
|
|
@@ -6223,11 +6218,12 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6223
6218
|
*/
|
|
6224
6219
|
duplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {
|
|
6225
6220
|
this.run(() => {
|
|
6226
|
-
const
|
|
6221
|
+
const _ids =
|
|
6227
6222
|
typeof shapes[0] === 'string'
|
|
6228
6223
|
? (shapes as TLShapeId[])
|
|
6229
6224
|
: (shapes as TLShape[]).map((s) => s.id)
|
|
6230
6225
|
|
|
6226
|
+
const ids = this._shouldIgnoreShapeLock ? _ids : this._getUnlockedShapeIds(_ids)
|
|
6231
6227
|
if (ids.length <= 0) return this
|
|
6232
6228
|
|
|
6233
6229
|
const initialIds = new Set(ids)
|
|
@@ -6307,10 +6303,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6307
6303
|
})
|
|
6308
6304
|
const shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)
|
|
6309
6305
|
|
|
6310
|
-
|
|
6311
|
-
shapesToCreate.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage
|
|
6312
|
-
|
|
6313
|
-
if (maxShapesReached) {
|
|
6306
|
+
if (!this.canCreateShapes(shapesToCreate)) {
|
|
6314
6307
|
alertMaxShapes(this)
|
|
6315
6308
|
return
|
|
6316
6309
|
}
|
|
@@ -7739,6 +7732,32 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7739
7732
|
return {}
|
|
7740
7733
|
}
|
|
7741
7734
|
|
|
7735
|
+
/**
|
|
7736
|
+
* Get whether the provided shape can be created.
|
|
7737
|
+
*
|
|
7738
|
+
* @param shape - The shape or shape IDs to check.
|
|
7739
|
+
*
|
|
7740
|
+
* @public
|
|
7741
|
+
*/
|
|
7742
|
+
canCreateShape<T extends TLUnknownShape>(
|
|
7743
|
+
shape: OptionalKeys<TLShapePartial<T>, 'id'> | T['id']
|
|
7744
|
+
): boolean {
|
|
7745
|
+
return this.canCreateShapes([shape])
|
|
7746
|
+
}
|
|
7747
|
+
|
|
7748
|
+
/**
|
|
7749
|
+
* Get whether the provided shapes can be created.
|
|
7750
|
+
*
|
|
7751
|
+
* @param shapes - The shapes or shape IDs to create.
|
|
7752
|
+
*
|
|
7753
|
+
* @public
|
|
7754
|
+
*/
|
|
7755
|
+
canCreateShapes<T extends TLUnknownShape>(
|
|
7756
|
+
shapes: (T['id'] | OptionalKeys<TLShapePartial<T>, 'id'>)[]
|
|
7757
|
+
): boolean {
|
|
7758
|
+
return shapes.length + this.getCurrentPageShapeIds().size <= this.options.maxShapesPerPage
|
|
7759
|
+
}
|
|
7760
|
+
|
|
7742
7761
|
/**
|
|
7743
7762
|
* Create a single shape.
|
|
7744
7763
|
*
|
|
@@ -7785,6 +7804,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7785
7804
|
if (maxShapesReached) {
|
|
7786
7805
|
// can't create more shapes than fit on the page
|
|
7787
7806
|
alertMaxShapes(this)
|
|
7807
|
+
// todo: throw an error here? Otherwise we'll need to check every time whether the shapes were actually created
|
|
7788
7808
|
return this
|
|
7789
7809
|
}
|
|
7790
7810
|
|
|
@@ -7817,9 +7837,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7817
7837
|
|
|
7818
7838
|
for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
|
|
7819
7839
|
const parent = currentPageShapesSorted[i]
|
|
7840
|
+
const util = this.getShapeUtil(parent)
|
|
7820
7841
|
if (
|
|
7842
|
+
util.canReceiveNewChildrenOfType(parent, partial.type) &&
|
|
7821
7843
|
!this.isShapeHidden(parent) &&
|
|
7822
|
-
this.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) &&
|
|
7823
7844
|
this.isPointInShape(
|
|
7824
7845
|
parent,
|
|
7825
7846
|
// If no parent is provided, then we can treat the
|
|
@@ -7838,7 +7859,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7838
7859
|
|
|
7839
7860
|
const prevParentId = partial.parentId
|
|
7840
7861
|
|
|
7841
|
-
// a shape cannot be
|
|
7862
|
+
// a shape cannot be its own parent. This was a rare issue with frames/groups in the syncFuzz tests.
|
|
7842
7863
|
if (parentId === partial.id) {
|
|
7843
7864
|
parentId = focusedGroupId
|
|
7844
7865
|
}
|
|
@@ -7948,6 +7969,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7948
7969
|
}
|
|
7949
7970
|
})
|
|
7950
7971
|
|
|
7972
|
+
this.emit('created-shapes', shapeRecordsToCreate)
|
|
7973
|
+
this.emit('edit')
|
|
7951
7974
|
this.store.put(shapeRecordsToCreate)
|
|
7952
7975
|
})
|
|
7953
7976
|
|
|
@@ -8342,6 +8365,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8342
8365
|
updates.push(updated)
|
|
8343
8366
|
}
|
|
8344
8367
|
|
|
8368
|
+
this.emit('edited-shapes', updates)
|
|
8369
|
+
this.emit('edit')
|
|
8345
8370
|
this.store.put(updates)
|
|
8346
8371
|
})
|
|
8347
8372
|
}
|
|
@@ -8391,6 +8416,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8391
8416
|
})
|
|
8392
8417
|
}
|
|
8393
8418
|
|
|
8419
|
+
this.emit('deleted-shapes', [...allShapeIdsToDelete])
|
|
8420
|
+
this.emit('edit')
|
|
8394
8421
|
return this.run(() => this.store.remove([...allShapeIdsToDelete]))
|
|
8395
8422
|
}
|
|
8396
8423
|
|
|
@@ -8839,6 +8866,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8839
8866
|
} = {
|
|
8840
8867
|
text: null,
|
|
8841
8868
|
files: null,
|
|
8869
|
+
'file-replace': null,
|
|
8842
8870
|
embed: null,
|
|
8843
8871
|
'svg-text': null,
|
|
8844
8872
|
url: null,
|
|
@@ -8888,6 +8916,15 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8888
8916
|
return this.externalContentHandlers[info.type]?.(info as any)
|
|
8889
8917
|
}
|
|
8890
8918
|
|
|
8919
|
+
/**
|
|
8920
|
+
* Handle replacing external content.
|
|
8921
|
+
*
|
|
8922
|
+
* @param info - Info about the external content.
|
|
8923
|
+
*/
|
|
8924
|
+
async replaceExternalContent<E>(info: TLExternalContent<E>): Promise<void> {
|
|
8925
|
+
return this.externalContentHandlers[info.type]?.(info as any)
|
|
8926
|
+
}
|
|
8927
|
+
|
|
8891
8928
|
/**
|
|
8892
8929
|
* Get content that can be exported for the given shape ids.
|
|
8893
8930
|
*
|
|
@@ -9305,6 +9342,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9305
9342
|
if (rootShapes.length === 1) {
|
|
9306
9343
|
const onlyRoot = rootShapes[0] as TLFrameShape
|
|
9307
9344
|
// If the old bounds are in the viewport...
|
|
9345
|
+
// todo: replace frame references with shapes that can accept children
|
|
9308
9346
|
if (this.isShapeOfType<TLFrameShape>(onlyRoot, 'frame')) {
|
|
9309
9347
|
while (
|
|
9310
9348
|
this.getShapesAtPoint(point).some(
|
|
@@ -9506,6 +9544,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9506
9544
|
previousPagePoint,
|
|
9507
9545
|
currentScreenPoint,
|
|
9508
9546
|
currentPagePoint,
|
|
9547
|
+
originScreenPoint,
|
|
9548
|
+
originPagePoint,
|
|
9509
9549
|
} = this.inputs
|
|
9510
9550
|
|
|
9511
9551
|
const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!
|
|
@@ -9534,8 +9574,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9534
9574
|
// Reset velocity on pointer down, or when a pinch starts or ends
|
|
9535
9575
|
if (info.name === 'pointer_down' || this.inputs.isPinching) {
|
|
9536
9576
|
pointerVelocity.set(0, 0)
|
|
9537
|
-
|
|
9538
|
-
|
|
9577
|
+
originScreenPoint.setTo(currentScreenPoint)
|
|
9578
|
+
originPagePoint.setTo(currentPagePoint)
|
|
9539
9579
|
}
|
|
9540
9580
|
|
|
9541
9581
|
// todo: We only have to do this if there are multiple users in the document
|
|
@@ -62,6 +62,12 @@ export interface BindingOnShapeChangeOptions<Binding extends TLUnknownBinding> {
|
|
|
62
62
|
shapeBefore: TLShape
|
|
63
63
|
/** The shape record after the change is made. */
|
|
64
64
|
shapeAfter: TLShape
|
|
65
|
+
/**
|
|
66
|
+
* Why did this shape change?
|
|
67
|
+
* - 'self': the shape itself changed
|
|
68
|
+
* - 'ancestry': the ancestry of the shape changed, but the shape itself may not have done
|
|
69
|
+
*/
|
|
70
|
+
reason: 'self' | 'ancestry'
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
/**
|
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
import { Computed, RESET_VALUE, computed, isUninitialized } from '@tldraw/state'
|
|
2
|
-
import { TLBinding, TLShapeId } from '@tldraw/tlschema'
|
|
2
|
+
import { TLArrowBinding, TLBinding, TLShapeId, TLUnknownBinding } from '@tldraw/tlschema'
|
|
3
3
|
import { objectMapValues } from '@tldraw/utils'
|
|
4
4
|
import { Editor } from '../Editor'
|
|
5
5
|
|
|
6
6
|
type TLBindingsIndex = Map<TLShapeId, TLBinding[]>
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const bindingsHistory = store.query.filterHistory('binding')
|
|
11
|
-
const bindingsQuery = store.query.records('binding')
|
|
12
|
-
function fromScratch() {
|
|
13
|
-
const allBindings = bindingsQuery.get() as TLBinding[]
|
|
8
|
+
function fromScratch(bindingsQuery: Computed<(TLArrowBinding | TLUnknownBinding)[], unknown>) {
|
|
9
|
+
const allBindings = bindingsQuery.get() as TLBinding[]
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
const shapesToBindings: TLBindingsIndex = new Map()
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
13
|
+
for (const binding of allBindings) {
|
|
14
|
+
const { fromId, toId } = binding
|
|
15
|
+
const bindingsForFromShape = shapesToBindings.get(fromId)
|
|
16
|
+
if (!bindingsForFromShape) {
|
|
17
|
+
shapesToBindings.set(fromId, [binding])
|
|
18
|
+
} else {
|
|
19
|
+
bindingsForFromShape.push(binding)
|
|
20
|
+
}
|
|
21
|
+
const bindingsForToShape = shapesToBindings.get(toId)
|
|
22
|
+
if (!bindingsForToShape) {
|
|
23
|
+
shapesToBindings.set(toId, [binding])
|
|
24
|
+
} else {
|
|
25
|
+
bindingsForToShape.push(binding)
|
|
31
26
|
}
|
|
32
|
-
|
|
33
|
-
return shape2Binding
|
|
34
27
|
}
|
|
35
28
|
|
|
29
|
+
return shapesToBindings
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const bindingsIndex = (editor: Editor): Computed<TLBindingsIndex> => {
|
|
33
|
+
const { store } = editor
|
|
34
|
+
const bindingsHistory = store.query.filterHistory('binding')
|
|
35
|
+
const bindingsQuery = store.query.records('binding')
|
|
36
|
+
|
|
36
37
|
return computed<TLBindingsIndex>('arrowBindingsIndex', (_lastValue, lastComputedEpoch) => {
|
|
37
38
|
if (isUninitialized(_lastValue)) {
|
|
38
|
-
return fromScratch()
|
|
39
|
+
return fromScratch(bindingsQuery)
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
const lastValue = _lastValue
|
|
@@ -43,7 +44,7 @@ export const bindingsIndex = (editor: Editor): Computed<TLBindingsIndex> => {
|
|
|
43
44
|
const diff = bindingsHistory.getDiffSince(lastComputedEpoch)
|
|
44
45
|
|
|
45
46
|
if (diff === RESET_VALUE) {
|
|
46
|
-
return fromScratch()
|
|
47
|
+
return fromScratch(bindingsQuery)
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
let nextValue: TLBindingsIndex | undefined = undefined
|