@tldraw/editor 3.14.0-canary.e95fdc82a46a → 3.14.0-canary.e989a4107be2
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 +155 -55
- package/dist-cjs/index.js +4 -3
- 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 +90 -30
- 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/managers/FontManager/FontManager.js +1 -2
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +3 -1
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +73 -42
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
- 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/hooks/useCanvasEvents.js +1 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +0 -6
- 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/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 +155 -55
- package/dist-esm/index.mjs +4 -3
- 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 +90 -30
- 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/managers/FontManager/FontManager.mjs +1 -2
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +3 -1
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +73 -42
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
- 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/hooks/useCanvasEvents.mjs +1 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +0 -6
- 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/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 +7 -1
- package/src/lib/config/TLSessionStateSnapshot.ts +1 -1
- package/src/lib/editor/Editor.ts +107 -38
- package/src/lib/editor/bindings/BindingUtil.ts +6 -0
- package/src/lib/editor/managers/FontManager/FontManager.ts +1 -2
- package/src/lib/editor/managers/HistoryManager/HistoryManager.ts +3 -1
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +1 -5
- package/src/lib/editor/managers/TextManager/TextManager.ts +118 -86
- package/src/lib/editor/shapes/ShapeUtil.ts +47 -15
- 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/hooks/useCanvasEvents.ts +0 -1
- package/src/lib/primitives/Box.ts +0 -8
- 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/reparenting.ts +383 -0
- package/src/lib/utils/richText.ts +9 -3
- package/src/version.ts +3 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/editor",
|
|
3
3
|
"description": "A tiny little drawing app (editor).",
|
|
4
|
-
"version": "3.14.0-canary.
|
|
4
|
+
"version": "3.14.0-canary.e989a4107be2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -48,20 +48,19 @@
|
|
|
48
48
|
"@tiptap/core": "^2.9.1",
|
|
49
49
|
"@tiptap/pm": "^2.9.1",
|
|
50
50
|
"@tiptap/react": "^2.9.1",
|
|
51
|
-
"@tldraw/state": "3.14.0-canary.
|
|
52
|
-
"@tldraw/state-react": "3.14.0-canary.
|
|
53
|
-
"@tldraw/store": "3.14.0-canary.
|
|
54
|
-
"@tldraw/tlschema": "3.14.0-canary.
|
|
55
|
-
"@tldraw/utils": "3.14.0-canary.
|
|
56
|
-
"@tldraw/validate": "3.14.0-canary.
|
|
51
|
+
"@tldraw/state": "3.14.0-canary.e989a4107be2",
|
|
52
|
+
"@tldraw/state-react": "3.14.0-canary.e989a4107be2",
|
|
53
|
+
"@tldraw/store": "3.14.0-canary.e989a4107be2",
|
|
54
|
+
"@tldraw/tlschema": "3.14.0-canary.e989a4107be2",
|
|
55
|
+
"@tldraw/utils": "3.14.0-canary.e989a4107be2",
|
|
56
|
+
"@tldraw/validate": "3.14.0-canary.e989a4107be2",
|
|
57
57
|
"@types/core-js": "^2.5.8",
|
|
58
58
|
"@use-gesture/react": "^10.3.1",
|
|
59
59
|
"classnames": "^2.5.1",
|
|
60
60
|
"core-js": "^3.40.0",
|
|
61
61
|
"eventemitter3": "^4.0.7",
|
|
62
62
|
"idb": "^7.1.1",
|
|
63
|
-
"is-plain-object": "^5.0.0"
|
|
64
|
-
"lodash.isequal": "^4.5.0"
|
|
63
|
+
"is-plain-object": "^5.0.0"
|
|
65
64
|
},
|
|
66
65
|
"peerDependencies": {
|
|
67
66
|
"react": "^18.2.0 || ^19.0.0",
|
package/src/index.ts
CHANGED
|
@@ -4,7 +4,6 @@ import 'core-js/stable/array/flat-map.js'
|
|
|
4
4
|
import 'core-js/stable/array/flat.js'
|
|
5
5
|
import 'core-js/stable/string/at.js'
|
|
6
6
|
import 'core-js/stable/string/replace-all.js'
|
|
7
|
-
export { areShapesContentEqual } from './lib/utils/areShapesContentEqual'
|
|
8
7
|
|
|
9
8
|
// eslint-disable-next-line local/no-export-star
|
|
10
9
|
export * from '@tldraw/state'
|
|
@@ -175,6 +174,7 @@ export {
|
|
|
175
174
|
} from './lib/editor/managers/SnapManager/SnapManager'
|
|
176
175
|
export {
|
|
177
176
|
TextManager,
|
|
177
|
+
type TLMeasureTextOpts,
|
|
178
178
|
type TLMeasureTextSpanOpts,
|
|
179
179
|
} from './lib/editor/managers/TextManager/TextManager'
|
|
180
180
|
export { UserPreferencesManager } from './lib/editor/managers/UserPreferencesManager/UserPreferencesManager'
|
|
@@ -182,6 +182,10 @@ export { BaseBoxShapeUtil, type TLBaseBoxShape } from './lib/editor/shapes/BaseB
|
|
|
182
182
|
export {
|
|
183
183
|
ShapeUtil,
|
|
184
184
|
type TLCropInfo,
|
|
185
|
+
type TLDragShapesInInfo,
|
|
186
|
+
type TLDragShapesOutInfo,
|
|
187
|
+
type TLDragShapesOverInfo,
|
|
188
|
+
type TLDropShapesOverInfo,
|
|
185
189
|
type TLGeometryOpts,
|
|
186
190
|
type TLHandleDragInfo,
|
|
187
191
|
type TLResizeInfo,
|
|
@@ -253,6 +257,7 @@ export {
|
|
|
253
257
|
type TLExternalContent,
|
|
254
258
|
type TLExternalContentSource,
|
|
255
259
|
type TLFileExternalAsset,
|
|
260
|
+
type TLFileReplaceExternalContent,
|
|
256
261
|
type TLFilesExternalContent,
|
|
257
262
|
type TLSvgTextExternalContent,
|
|
258
263
|
type TLTextExternalContent,
|
|
@@ -445,6 +450,7 @@ export { hardResetEditor } from './lib/utils/hardResetEditor'
|
|
|
445
450
|
export { isAccelKey } from './lib/utils/keyboard'
|
|
446
451
|
export { normalizeWheel } from './lib/utils/normalizeWheel'
|
|
447
452
|
export { refreshPage } from './lib/utils/refreshPage'
|
|
453
|
+
export { getDroppedShapesToNewParents, kickoutOccludedShapes } from './lib/utils/reparenting'
|
|
448
454
|
export {
|
|
449
455
|
getFontsFromRichText,
|
|
450
456
|
type RichTextFontVisitor,
|
|
@@ -14,12 +14,12 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
deleteFromSessionStorage,
|
|
16
16
|
getFromSessionStorage,
|
|
17
|
+
isEqual,
|
|
17
18
|
setInSessionStorage,
|
|
18
19
|
structuredClone,
|
|
19
20
|
uniqueId,
|
|
20
21
|
} from '@tldraw/utils'
|
|
21
22
|
import { T } from '@tldraw/validate'
|
|
22
|
-
import isEqual from 'lodash.isequal'
|
|
23
23
|
import { tlenv } from '../globals/environment'
|
|
24
24
|
|
|
25
25
|
const tabIdKey = 'TLDRAW_TAB_ID_v2' as const
|
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -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,
|
|
@@ -5510,7 +5528,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5510
5528
|
if (!id) return undefined
|
|
5511
5529
|
const freshShape = this.getShape(id)
|
|
5512
5530
|
if (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined
|
|
5513
|
-
return this.
|
|
5531
|
+
return this.getShape(freshShape.parentId)
|
|
5514
5532
|
}
|
|
5515
5533
|
|
|
5516
5534
|
/**
|
|
@@ -5693,6 +5711,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5693
5711
|
const newPoint = invertedParentTransform.applyToPoint(pagePoint)
|
|
5694
5712
|
const newRotation = pageTransform.rotation() - parentPageRotation
|
|
5695
5713
|
|
|
5714
|
+
if (shape.id === parentId) {
|
|
5715
|
+
throw Error('Attempted to reparent a shape to itself!')
|
|
5716
|
+
}
|
|
5717
|
+
|
|
5696
5718
|
changes.push({
|
|
5697
5719
|
id: shape.id,
|
|
5698
5720
|
type: shape.type,
|
|
@@ -5796,6 +5818,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5796
5818
|
return shapeIds
|
|
5797
5819
|
}
|
|
5798
5820
|
|
|
5821
|
+
/** @deprecated Use {@link Editor.getDraggingOverShape} instead */
|
|
5822
|
+
getDroppingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined {
|
|
5823
|
+
return this.getDraggingOverShape(point, droppingShapes)
|
|
5824
|
+
}
|
|
5825
|
+
|
|
5799
5826
|
/**
|
|
5800
5827
|
* Get the shape that some shapes should be dropped on at a given point.
|
|
5801
5828
|
*
|
|
@@ -5806,35 +5833,33 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5806
5833
|
*
|
|
5807
5834
|
* @public
|
|
5808
5835
|
*/
|
|
5809
|
-
|
|
5810
|
-
//
|
|
5811
|
-
const
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
if (
|
|
5816
|
-
// ignore hidden shapes
|
|
5817
|
-
this.isShapeHidden(shape) ||
|
|
5818
|
-
// don't allow dropping on selected shapes
|
|
5819
|
-
this.getSelectedShapeIds().includes(shape.id) ||
|
|
5820
|
-
// only allow shapes that can receive children
|
|
5821
|
-
!this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) ||
|
|
5822
|
-
// don't allow dropping a shape on itself or one of it's children
|
|
5823
|
-
droppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))
|
|
5824
|
-
) {
|
|
5825
|
-
continue
|
|
5826
|
-
}
|
|
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
|
+
)
|
|
5827
5841
|
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
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
|
+
)
|
|
5831
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
|
|
5832
5856
|
if (
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5857
|
+
shapeUtil.onDragShapesOver ||
|
|
5858
|
+
shapeUtil.onDragShapesIn ||
|
|
5859
|
+
shapeUtil.onDragShapesOut ||
|
|
5860
|
+
shapeUtil.onDropShapesOver
|
|
5836
5861
|
) {
|
|
5837
|
-
return
|
|
5862
|
+
return maybeDraggingOverShape
|
|
5838
5863
|
}
|
|
5839
5864
|
}
|
|
5840
5865
|
}
|
|
@@ -6193,11 +6218,12 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6193
6218
|
*/
|
|
6194
6219
|
duplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {
|
|
6195
6220
|
this.run(() => {
|
|
6196
|
-
const
|
|
6221
|
+
const _ids =
|
|
6197
6222
|
typeof shapes[0] === 'string'
|
|
6198
6223
|
? (shapes as TLShapeId[])
|
|
6199
6224
|
: (shapes as TLShape[]).map((s) => s.id)
|
|
6200
6225
|
|
|
6226
|
+
const ids = this._shouldIgnoreShapeLock ? _ids : this._getUnlockedShapeIds(_ids)
|
|
6201
6227
|
if (ids.length <= 0) return this
|
|
6202
6228
|
|
|
6203
6229
|
const initialIds = new Set(ids)
|
|
@@ -6277,10 +6303,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6277
6303
|
})
|
|
6278
6304
|
const shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)
|
|
6279
6305
|
|
|
6280
|
-
|
|
6281
|
-
shapesToCreate.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage
|
|
6282
|
-
|
|
6283
|
-
if (maxShapesReached) {
|
|
6306
|
+
if (!this.canCreateShapes(shapesToCreate)) {
|
|
6284
6307
|
alertMaxShapes(this)
|
|
6285
6308
|
return
|
|
6286
6309
|
}
|
|
@@ -7709,6 +7732,32 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7709
7732
|
return {}
|
|
7710
7733
|
}
|
|
7711
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
|
+
|
|
7712
7761
|
/**
|
|
7713
7762
|
* Create a single shape.
|
|
7714
7763
|
*
|
|
@@ -7755,6 +7804,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7755
7804
|
if (maxShapesReached) {
|
|
7756
7805
|
// can't create more shapes than fit on the page
|
|
7757
7806
|
alertMaxShapes(this)
|
|
7807
|
+
// todo: throw an error here? Otherwise we'll need to check every time whether the shapes were actually created
|
|
7758
7808
|
return this
|
|
7759
7809
|
}
|
|
7760
7810
|
|
|
@@ -7787,9 +7837,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7787
7837
|
|
|
7788
7838
|
for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
|
|
7789
7839
|
const parent = currentPageShapesSorted[i]
|
|
7840
|
+
const util = this.getShapeUtil(parent)
|
|
7790
7841
|
if (
|
|
7842
|
+
util.canReceiveNewChildrenOfType(parent, partial.type) &&
|
|
7791
7843
|
!this.isShapeHidden(parent) &&
|
|
7792
|
-
this.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) &&
|
|
7793
7844
|
this.isPointInShape(
|
|
7794
7845
|
parent,
|
|
7795
7846
|
// If no parent is provided, then we can treat the
|
|
@@ -7808,7 +7859,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7808
7859
|
|
|
7809
7860
|
const prevParentId = partial.parentId
|
|
7810
7861
|
|
|
7811
|
-
// a shape cannot be
|
|
7862
|
+
// a shape cannot be its own parent. This was a rare issue with frames/groups in the syncFuzz tests.
|
|
7812
7863
|
if (parentId === partial.id) {
|
|
7813
7864
|
parentId = focusedGroupId
|
|
7814
7865
|
}
|
|
@@ -7918,6 +7969,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7918
7969
|
}
|
|
7919
7970
|
})
|
|
7920
7971
|
|
|
7972
|
+
this.emit('created-shapes', shapeRecordsToCreate)
|
|
7973
|
+
this.emit('edit')
|
|
7921
7974
|
this.store.put(shapeRecordsToCreate)
|
|
7922
7975
|
})
|
|
7923
7976
|
|
|
@@ -8312,6 +8365,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8312
8365
|
updates.push(updated)
|
|
8313
8366
|
}
|
|
8314
8367
|
|
|
8368
|
+
this.emit('edited-shapes', updates)
|
|
8369
|
+
this.emit('edit')
|
|
8315
8370
|
this.store.put(updates)
|
|
8316
8371
|
})
|
|
8317
8372
|
}
|
|
@@ -8361,6 +8416,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8361
8416
|
})
|
|
8362
8417
|
}
|
|
8363
8418
|
|
|
8419
|
+
this.emit('deleted-shapes', [...allShapeIdsToDelete])
|
|
8420
|
+
this.emit('edit')
|
|
8364
8421
|
return this.run(() => this.store.remove([...allShapeIdsToDelete]))
|
|
8365
8422
|
}
|
|
8366
8423
|
|
|
@@ -8809,6 +8866,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8809
8866
|
} = {
|
|
8810
8867
|
text: null,
|
|
8811
8868
|
files: null,
|
|
8869
|
+
'file-replace': null,
|
|
8812
8870
|
embed: null,
|
|
8813
8871
|
'svg-text': null,
|
|
8814
8872
|
url: null,
|
|
@@ -8858,6 +8916,15 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8858
8916
|
return this.externalContentHandlers[info.type]?.(info as any)
|
|
8859
8917
|
}
|
|
8860
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
|
+
|
|
8861
8928
|
/**
|
|
8862
8929
|
* Get content that can be exported for the given shape ids.
|
|
8863
8930
|
*
|
|
@@ -9477,6 +9544,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9477
9544
|
previousPagePoint,
|
|
9478
9545
|
currentScreenPoint,
|
|
9479
9546
|
currentPagePoint,
|
|
9547
|
+
originScreenPoint,
|
|
9548
|
+
originPagePoint,
|
|
9480
9549
|
} = this.inputs
|
|
9481
9550
|
|
|
9482
9551
|
const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!
|
|
@@ -9505,8 +9574,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9505
9574
|
// Reset velocity on pointer down, or when a pinch starts or ends
|
|
9506
9575
|
if (info.name === 'pointer_down' || this.inputs.isPinching) {
|
|
9507
9576
|
pointerVelocity.set(0, 0)
|
|
9508
|
-
|
|
9509
|
-
|
|
9577
|
+
originScreenPoint.setTo(currentScreenPoint)
|
|
9578
|
+
originPagePoint.setTo(currentPagePoint)
|
|
9510
9579
|
}
|
|
9511
9580
|
|
|
9512
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
|
/**
|
|
@@ -96,8 +96,7 @@ export class FontManager {
|
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
areResultsEqual: areArraysShallowEqual,
|
|
99
|
-
|
|
100
|
-
areRecordsEqual: (a, b) => a.props.richText === b.props.richText,
|
|
99
|
+
areRecordsEqual: (a, b) => a.props === b.props && a.meta === b.meta,
|
|
101
100
|
}
|
|
102
101
|
)
|
|
103
102
|
|
|
@@ -241,7 +241,9 @@ export class HistoryManager<R extends UnknownRecord> {
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
bailToMark(id: string) {
|
|
244
|
-
|
|
244
|
+
if (id) {
|
|
245
|
+
this._undo({ pushToRedoStack: false, toMark: id })
|
|
246
|
+
}
|
|
245
247
|
|
|
246
248
|
return this
|
|
247
249
|
}
|
|
@@ -99,7 +99,7 @@ describe('TextManager', () => {
|
|
|
99
99
|
})
|
|
100
100
|
|
|
101
101
|
it('should handle empty text', () => {
|
|
102
|
-
const result = textManager.measureText('', defaultOpts)
|
|
102
|
+
const result = textManager.measureText('', { ...defaultOpts, measureScrollWidth: true })
|
|
103
103
|
expect(result).toHaveProperty('x', 0)
|
|
104
104
|
expect(result).toHaveProperty('y', 0)
|
|
105
105
|
expect(result).toHaveProperty('w')
|
|
@@ -128,7 +128,6 @@ describe('TextManager', () => {
|
|
|
128
128
|
y: 0,
|
|
129
129
|
w: expect.any(Number),
|
|
130
130
|
h: expect.any(Number),
|
|
131
|
-
scrollWidth: expect.any(Number),
|
|
132
131
|
})
|
|
133
132
|
})
|
|
134
133
|
|
|
@@ -141,7 +140,6 @@ describe('TextManager', () => {
|
|
|
141
140
|
y: 0,
|
|
142
141
|
w: expect.any(Number),
|
|
143
142
|
h: expect.any(Number),
|
|
144
|
-
scrollWidth: expect.any(Number),
|
|
145
143
|
})
|
|
146
144
|
})
|
|
147
145
|
|
|
@@ -154,7 +152,6 @@ describe('TextManager', () => {
|
|
|
154
152
|
y: 0,
|
|
155
153
|
w: expect.any(Number),
|
|
156
154
|
h: expect.any(Number),
|
|
157
|
-
scrollWidth: expect.any(Number),
|
|
158
155
|
})
|
|
159
156
|
})
|
|
160
157
|
|
|
@@ -173,7 +170,6 @@ describe('TextManager', () => {
|
|
|
173
170
|
y: 0,
|
|
174
171
|
w: expect.any(Number),
|
|
175
172
|
h: expect.any(Number),
|
|
176
|
-
scrollWidth: expect.any(Number),
|
|
177
173
|
})
|
|
178
174
|
})
|
|
179
175
|
})
|