@tldraw/editor 3.13.0-canary.52e2314962c1 → 3.13.0-canary.62d76a25592d
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 +114 -111
- package/dist-cjs/index.js +7 -22
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +2 -1
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/Shape.js +12 -8
- package/dist-cjs/lib/components/Shape.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +36 -7
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +14 -12
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +17 -11
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +65 -35
- package/dist-cjs/lib/editor/Editor.js.map +3 -3
- package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager.js +10 -0
- package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
- package/dist-cjs/lib/exports/getSvgJsx.js +12 -3
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js +3 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js +16 -16
- package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
- package/dist-cjs/lib/license/LicenseManager.js +8 -1
- package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +16 -0
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/Mat.js +1 -1
- package/dist-cjs/lib/primitives/Mat.js.map +2 -2
- package/dist-cjs/lib/primitives/Vec.js +20 -0
- package/dist-cjs/lib/primitives/Vec.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Edge2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +91 -20
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js +55 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Point2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
- package/dist-cjs/lib/utils/areShapesContentEqual.js +25 -0
- package/dist-cjs/lib/utils/areShapesContentEqual.js.map +7 -0
- package/dist-cjs/lib/utils/debug-flags.js +5 -2
- package/dist-cjs/lib/utils/debug-flags.js.map +2 -2
- package/dist-cjs/lib/utils/dom.js +3 -3
- package/dist-cjs/lib/utils/dom.js.map +2 -2
- package/dist-cjs/lib/utils/nearestMultiple.js +34 -0
- package/dist-cjs/lib/utils/nearestMultiple.js.map +7 -0
- package/dist-cjs/lib/utils/rotation.js +5 -5
- package/dist-cjs/lib/utils/rotation.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 +114 -111
- package/dist-esm/index.mjs +9 -41
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +2 -1
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/Shape.mjs +12 -8
- package/dist-esm/lib/components/Shape.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +36 -7
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +14 -12
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +17 -11
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +65 -35
- package/dist-esm/lib/editor/Editor.mjs.map +3 -3
- package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager.mjs +10 -0
- package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +12 -3
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs +3 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditorComponents.mjs +16 -18
- package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseManager.mjs +8 -1
- package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +16 -0
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/Mat.mjs +1 -1
- package/dist-esm/lib/primitives/Mat.mjs.map +2 -2
- package/dist-esm/lib/primitives/Vec.mjs +20 -0
- package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +92 -21
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs +55 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Point2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
- package/dist-esm/lib/utils/areShapesContentEqual.mjs +5 -0
- package/dist-esm/lib/utils/areShapesContentEqual.mjs.map +7 -0
- package/dist-esm/lib/utils/debug-flags.mjs +5 -2
- package/dist-esm/lib/utils/debug-flags.mjs.map +2 -2
- package/dist-esm/lib/utils/dom.mjs +3 -3
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/lib/utils/nearestMultiple.mjs +14 -0
- package/dist-esm/lib/utils/nearestMultiple.mjs.map +7 -0
- package/dist-esm/lib/utils/rotation.mjs +5 -5
- package/dist-esm/lib/utils/rotation.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +42 -4
- package/package.json +7 -7
- package/src/index.ts +16 -31
- package/src/lib/TldrawEditor.tsx +6 -1
- package/src/lib/components/Shape.tsx +14 -10
- package/src/lib/components/default-components/DefaultCanvas.tsx +41 -7
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +25 -14
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +17 -8
- package/src/lib/components/default-components/DefaultSpinner.tsx +1 -1
- package/src/lib/editor/Editor.test.ts +1 -1
- package/src/lib/editor/Editor.ts +62 -34
- package/src/lib/editor/managers/SnapManager/HandleSnaps.ts +0 -1
- package/src/lib/editor/managers/TextManager.ts +12 -0
- package/src/lib/editor/shapes/ShapeUtil.ts +22 -2
- package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +9 -9
- package/src/lib/exports/getSvgJsx.tsx +16 -7
- package/src/lib/hooks/useDocumentEvents.ts +7 -2
- package/src/lib/hooks/useEditorComponents.tsx +33 -32
- package/src/lib/license/LicenseManager.test.ts +40 -0
- package/src/lib/license/LicenseManager.ts +13 -1
- package/src/lib/options.ts +4 -0
- package/src/lib/primitives/Box.ts +20 -0
- package/src/lib/primitives/Mat.ts +5 -4
- package/src/lib/primitives/Vec.ts +23 -0
- package/src/lib/primitives/geometry/Arc2d.ts +5 -5
- package/src/lib/primitives/geometry/Circle2d.ts +4 -4
- package/src/lib/primitives/geometry/CubicBezier2d.ts +4 -4
- package/src/lib/primitives/geometry/CubicSpline2d.ts +3 -3
- package/src/lib/primitives/geometry/Edge2d.ts +3 -3
- package/src/lib/primitives/geometry/Ellipse2d.ts +3 -3
- package/src/lib/primitives/geometry/Geometry2d.test.ts +42 -0
- package/src/lib/primitives/geometry/Geometry2d.ts +123 -35
- package/src/lib/primitives/geometry/Group2d.ts +70 -7
- package/src/lib/primitives/geometry/Point2d.ts +2 -2
- package/src/lib/primitives/geometry/Polyline2d.ts +3 -3
- package/src/lib/primitives/geometry/Stadium2d.ts +3 -3
- package/src/lib/test/currentToolIdMask.test.ts +1 -1
- package/src/lib/test/user.test.ts +1 -1
- package/src/lib/utils/areShapesContentEqual.ts +4 -0
- package/src/lib/utils/debug-flags.ts +7 -2
- package/src/lib/utils/dom.ts +4 -4
- package/src/lib/utils/nearestMultiple.ts +13 -0
- package/src/lib/utils/rotation.ts +8 -6
- package/src/lib/utils/sync/LocalIndexedDb.test.ts +1 -1
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +1 -1
- package/src/version.ts +3 -3
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
TLImageAsset,
|
|
43
43
|
TLInstance,
|
|
44
44
|
TLInstancePageState,
|
|
45
|
+
TLInstancePresence,
|
|
45
46
|
TLNoteShape,
|
|
46
47
|
TLPOINTER_ID,
|
|
47
48
|
TLPage,
|
|
@@ -128,6 +129,7 @@ import { Group2d } from '../primitives/geometry/Group2d'
|
|
|
128
129
|
import { intersectPolygonPolygon } from '../primitives/intersect'
|
|
129
130
|
import { PI, approximately, areAnglesCompatible, clamp, pointInPolygon } from '../primitives/utils'
|
|
130
131
|
import { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'
|
|
132
|
+
import { areShapesContentEqual } from '../utils/areShapesContentEqual'
|
|
131
133
|
import { dataUrlToFile } from '../utils/assets'
|
|
132
134
|
import { debugFlags } from '../utils/debug-flags'
|
|
133
135
|
import {
|
|
@@ -324,7 +326,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
324
326
|
this.options = { ...defaultTldrawOptions, ...options }
|
|
325
327
|
|
|
326
328
|
this.store = store
|
|
327
|
-
this.disposables.add(this.store.dispose.bind(this.store))
|
|
328
329
|
this.history = new HistoryManager<TLRecord>({
|
|
329
330
|
store,
|
|
330
331
|
annotateError: (error) => {
|
|
@@ -954,6 +955,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
954
955
|
dispose() {
|
|
955
956
|
this.disposables.forEach((dispose) => dispose())
|
|
956
957
|
this.disposables.clear()
|
|
958
|
+
this.store.dispose()
|
|
957
959
|
this.isDisposed = true
|
|
958
960
|
}
|
|
959
961
|
|
|
@@ -1704,8 +1706,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1704
1706
|
* @readonly
|
|
1705
1707
|
*/
|
|
1706
1708
|
@computed getSelectedShapes(): TLShape[] {
|
|
1707
|
-
|
|
1708
|
-
return compact(selectedShapeIds.map((id) => this.store.get(id)))
|
|
1709
|
+
return compact(this.getSelectedShapeIds().map((id) => this.store.get(id)))
|
|
1709
1710
|
}
|
|
1710
1711
|
|
|
1711
1712
|
/**
|
|
@@ -2275,13 +2276,21 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2275
2276
|
setEditingShape(shape: TLShapeId | TLShape | null): this {
|
|
2276
2277
|
const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
|
|
2277
2278
|
this.setRichTextEditor(null)
|
|
2278
|
-
|
|
2279
|
+
const prevEditingShapeId = this.getEditingShapeId()
|
|
2280
|
+
if (id !== prevEditingShapeId) {
|
|
2279
2281
|
if (id) {
|
|
2280
2282
|
const shape = this.getShape(id)
|
|
2281
2283
|
if (shape && this.getShapeUtil(shape).canEdit(shape)) {
|
|
2282
2284
|
this.run(
|
|
2283
2285
|
() => {
|
|
2284
2286
|
this._updateCurrentPageState({ editingShapeId: id })
|
|
2287
|
+
if (prevEditingShapeId) {
|
|
2288
|
+
const prevEditingShape = this.getShape(prevEditingShapeId)
|
|
2289
|
+
if (prevEditingShape) {
|
|
2290
|
+
this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
this.getShapeUtil(shape).onEditStart?.(shape)
|
|
2285
2294
|
},
|
|
2286
2295
|
{ history: 'ignore' }
|
|
2287
2296
|
)
|
|
@@ -2294,6 +2303,12 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2294
2303
|
() => {
|
|
2295
2304
|
this._updateCurrentPageState({ editingShapeId: null })
|
|
2296
2305
|
this._currentRichTextEditor.set(null)
|
|
2306
|
+
if (prevEditingShapeId) {
|
|
2307
|
+
const prevEditingShape = this.getShape(prevEditingShapeId)
|
|
2308
|
+
if (prevEditingShape) {
|
|
2309
|
+
this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2297
2312
|
},
|
|
2298
2313
|
{ history: 'ignore' }
|
|
2299
2314
|
)
|
|
@@ -2575,14 +2590,25 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2575
2590
|
return baseCamera
|
|
2576
2591
|
}
|
|
2577
2592
|
|
|
2593
|
+
private _getFollowingPresence(targetUserId: string | null) {
|
|
2594
|
+
const visited = [this.user.getId()]
|
|
2595
|
+
const collaborators = this.getCollaborators()
|
|
2596
|
+
let leaderPresence = null as null | TLInstancePresence
|
|
2597
|
+
while (targetUserId && !visited.includes(targetUserId)) {
|
|
2598
|
+
leaderPresence = collaborators.find((c) => c.userId === targetUserId) ?? null
|
|
2599
|
+
targetUserId = leaderPresence?.followingUserId ?? null
|
|
2600
|
+
if (leaderPresence) {
|
|
2601
|
+
visited.push(leaderPresence.userId)
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
return leaderPresence
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2578
2607
|
@computed
|
|
2579
2608
|
private getViewportPageBoundsForFollowing(): null | Box {
|
|
2580
|
-
const
|
|
2581
|
-
if (!followingUserId) return null
|
|
2582
|
-
const leaderPresence = this.getCollaborators().find((c) => c.userId === followingUserId)
|
|
2583
|
-
if (!leaderPresence) return null
|
|
2609
|
+
const leaderPresence = this._getFollowingPresence(this.getInstanceState().followingUserId)
|
|
2584
2610
|
|
|
2585
|
-
if (!leaderPresence
|
|
2611
|
+
if (!leaderPresence?.camera || !leaderPresence?.screenBounds) return null
|
|
2586
2612
|
|
|
2587
2613
|
// Fit their viewport inside of our screen bounds
|
|
2588
2614
|
// 1. calculate their viewport in page space
|
|
@@ -3781,15 +3807,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
3781
3807
|
// if we were already following someone, stop following them
|
|
3782
3808
|
this.stopFollowingUser()
|
|
3783
3809
|
|
|
3784
|
-
const leaderPresences = this._getCollaboratorsQuery()
|
|
3785
|
-
.get()
|
|
3786
|
-
.filter((p) => p.userId === userId)
|
|
3787
|
-
|
|
3788
|
-
if (!leaderPresences.length) {
|
|
3789
|
-
console.warn('User not found')
|
|
3790
|
-
return this
|
|
3791
|
-
}
|
|
3792
|
-
|
|
3793
3810
|
const thisUserId = this.user.getId()
|
|
3794
3811
|
|
|
3795
3812
|
if (!thisUserId) {
|
|
@@ -3797,13 +3814,14 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
3797
3814
|
// allow to continue since it's probably fine most of the time.
|
|
3798
3815
|
}
|
|
3799
3816
|
|
|
3800
|
-
|
|
3801
|
-
|
|
3817
|
+
const leaderPresence = this._getFollowingPresence(userId)
|
|
3818
|
+
|
|
3819
|
+
if (!leaderPresence) {
|
|
3802
3820
|
return this
|
|
3803
3821
|
}
|
|
3804
3822
|
|
|
3805
3823
|
const latestLeaderPresence = computed('latestLeaderPresence', () => {
|
|
3806
|
-
return this.
|
|
3824
|
+
return this._getFollowingPresence(userId)
|
|
3807
3825
|
})
|
|
3808
3826
|
|
|
3809
3827
|
transact(() => {
|
|
@@ -4571,7 +4589,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4571
4589
|
this.fonts.trackFontsForShape(shape)
|
|
4572
4590
|
return this.getShapeUtil(shape).getGeometry(shape, opts)
|
|
4573
4591
|
},
|
|
4574
|
-
{ areRecordsEqual:
|
|
4592
|
+
{ areRecordsEqual: areShapesContentEqual }
|
|
4575
4593
|
)
|
|
4576
4594
|
}
|
|
4577
4595
|
return this._shapeGeometryCaches[context].get(
|
|
@@ -4619,9 +4637,15 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4619
4637
|
|
|
4620
4638
|
/** @internal */
|
|
4621
4639
|
@computed private _getShapeHandlesCache(): ComputedCache<TLHandle[] | undefined, TLShape> {
|
|
4622
|
-
return this.store.createComputedCache(
|
|
4623
|
-
|
|
4624
|
-
|
|
4640
|
+
return this.store.createComputedCache(
|
|
4641
|
+
'handles',
|
|
4642
|
+
(shape) => {
|
|
4643
|
+
return this.getShapeUtil(shape).getHandles?.(shape)
|
|
4644
|
+
},
|
|
4645
|
+
{
|
|
4646
|
+
areRecordsEqual: areShapesContentEqual,
|
|
4647
|
+
}
|
|
4648
|
+
)
|
|
4625
4649
|
}
|
|
4626
4650
|
|
|
4627
4651
|
/**
|
|
@@ -5842,9 +5866,15 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5842
5866
|
@computed
|
|
5843
5867
|
private _getBindingsIndexCache() {
|
|
5844
5868
|
const index = bindingsIndex(this)
|
|
5845
|
-
return this.store.createComputedCache<TLBinding[], TLShape>(
|
|
5846
|
-
|
|
5847
|
-
|
|
5869
|
+
return this.store.createComputedCache<TLBinding[], TLShape>(
|
|
5870
|
+
'bindingsIndex',
|
|
5871
|
+
(shape) => {
|
|
5872
|
+
return index.get().get(shape.id)
|
|
5873
|
+
},
|
|
5874
|
+
// we can ignore the shape equality check here because the index is
|
|
5875
|
+
// computed incrementally based on what bindings are in the store
|
|
5876
|
+
{ areRecordsEqual: () => true }
|
|
5877
|
+
)
|
|
5848
5878
|
}
|
|
5849
5879
|
|
|
5850
5880
|
/**
|
|
@@ -10211,7 +10241,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10211
10241
|
|
|
10212
10242
|
// If the camera behavior is "zoom" and the ctrl key is pressed, then pan;
|
|
10213
10243
|
// If the camera behavior is "pan" and the ctrl key is not pressed, then zoom
|
|
10214
|
-
if (
|
|
10244
|
+
if (info.ctrlKey) behavior = wheelBehavior === 'pan' ? 'zoom' : 'pan'
|
|
10215
10245
|
|
|
10216
10246
|
switch (behavior) {
|
|
10217
10247
|
case 'zoom': {
|
|
@@ -10327,12 +10357,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10327
10357
|
if (this.inputs.isPanning && this.inputs.isPointing) {
|
|
10328
10358
|
// Handle spacebar / middle mouse button panning
|
|
10329
10359
|
const { currentScreenPoint, previousScreenPoint } = this.inputs
|
|
10330
|
-
const { panSpeed } = cameraOptions
|
|
10331
10360
|
const offset = Vec.Sub(currentScreenPoint, previousScreenPoint)
|
|
10332
|
-
this.setCamera(
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
)
|
|
10361
|
+
this.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
|
|
10362
|
+
immediate: true,
|
|
10363
|
+
})
|
|
10336
10364
|
this.maybeTrackPerformance('Panning')
|
|
10337
10365
|
return
|
|
10338
10366
|
}
|
|
@@ -32,6 +32,7 @@ export interface TLMeasureTextSpanOpts {
|
|
|
32
32
|
fontStyle: string
|
|
33
33
|
lineHeight: number
|
|
34
34
|
textAlign: TLDefaultHorizontalAlignStyle
|
|
35
|
+
otherStyles?: Record<string, string>
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
const spaceCharacterRegex = /\s/
|
|
@@ -86,6 +87,7 @@ export class TextManager {
|
|
|
86
87
|
*/
|
|
87
88
|
maxWidth: null | number
|
|
88
89
|
minWidth?: null | number
|
|
90
|
+
otherStyles?: Record<string, string>
|
|
89
91
|
padding: string
|
|
90
92
|
disableOverflowWrapBreaking?: boolean
|
|
91
93
|
}
|
|
@@ -112,6 +114,11 @@ export class TextManager {
|
|
|
112
114
|
'overflow-wrap',
|
|
113
115
|
opts.disableOverflowWrapBreaking ? 'normal' : 'break-word'
|
|
114
116
|
)
|
|
117
|
+
if (opts.otherStyles) {
|
|
118
|
+
for (const [key, value] of Object.entries(opts.otherStyles)) {
|
|
119
|
+
wrapperElm.style.setProperty(key, value)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
115
122
|
|
|
116
123
|
const scrollWidth = wrapperElm.scrollWidth
|
|
117
124
|
const rect = wrapperElm.getBoundingClientRect()
|
|
@@ -256,6 +263,11 @@ export class TextManager {
|
|
|
256
263
|
elm.style.setProperty('line-height', `${opts.lineHeight * opts.fontSize}px`)
|
|
257
264
|
elm.style.setProperty('text-align', textAlignmentsForLtr[opts.textAlign])
|
|
258
265
|
elm.style.setProperty('font-style', opts.fontStyle)
|
|
266
|
+
if (opts.otherStyles) {
|
|
267
|
+
for (const [key, value] of Object.entries(opts.otherStyles)) {
|
|
268
|
+
elm.style.setProperty(key, value)
|
|
269
|
+
}
|
|
270
|
+
}
|
|
259
271
|
|
|
260
272
|
const shouldTruncateToFirstLine =
|
|
261
273
|
opts.overflow === 'truncate-ellipsis' || opts.overflow === 'truncate-clip'
|
|
@@ -19,6 +19,7 @@ import { TLFontFace } from '../managers/FontManager'
|
|
|
19
19
|
import { BoundsSnapGeometry } from '../managers/SnapManager/BoundsSnaps'
|
|
20
20
|
import { HandleSnapGeometry } from '../managers/SnapManager/HandleSnaps'
|
|
21
21
|
import { SvgExportContext } from '../types/SvgExportContext'
|
|
22
|
+
import { TLClickEventInfo } from '../types/event-types'
|
|
22
23
|
import { TLResizeHandle } from '../types/selection-types'
|
|
23
24
|
|
|
24
25
|
/** @public */
|
|
@@ -671,10 +672,21 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
|
|
|
671
672
|
* A callback called when a shape's edge is double clicked.
|
|
672
673
|
*
|
|
673
674
|
* @param shape - The shape.
|
|
675
|
+
* @param info - Info about the edge.
|
|
674
676
|
* @returns A change to apply to the shape, or void.
|
|
675
677
|
* @public
|
|
676
678
|
*/
|
|
677
|
-
onDoubleClickEdge?(shape: Shape): TLShapePartial<Shape> | void
|
|
679
|
+
onDoubleClickEdge?(shape: Shape, info: TLClickEventInfo): TLShapePartial<Shape> | void
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* A callback called when a shape's corner is double clicked.
|
|
683
|
+
*
|
|
684
|
+
* @param shape - The shape.
|
|
685
|
+
* @param info - Info about the corner.
|
|
686
|
+
* @returns A change to apply to the shape, or void.
|
|
687
|
+
* @public
|
|
688
|
+
*/
|
|
689
|
+
onDoubleClickCorner?(shape: Shape, info: TLClickEventInfo): TLShapePartial<Shape> | void
|
|
678
690
|
|
|
679
691
|
/**
|
|
680
692
|
* A callback called when a shape is double clicked.
|
|
@@ -695,7 +707,15 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
|
|
|
695
707
|
onClick?(shape: Shape): TLShapePartial<Shape> | void
|
|
696
708
|
|
|
697
709
|
/**
|
|
698
|
-
* A callback called when a shape
|
|
710
|
+
* A callback called when a shape starts being edited.
|
|
711
|
+
*
|
|
712
|
+
* @param shape - The shape.
|
|
713
|
+
* @public
|
|
714
|
+
*/
|
|
715
|
+
onEditStart?(shape: Shape): void
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* A callback called when a shape finishes being edited.
|
|
699
719
|
*
|
|
700
720
|
* @param shape - The shape.
|
|
701
721
|
* @public
|
|
@@ -4,15 +4,15 @@ import { TLDefaultDashStyle } from '@tldraw/tlschema'
|
|
|
4
4
|
export function getPerfectDashProps(
|
|
5
5
|
totalLength: number,
|
|
6
6
|
strokeWidth: number,
|
|
7
|
-
opts
|
|
8
|
-
style
|
|
9
|
-
snap
|
|
10
|
-
end
|
|
11
|
-
start
|
|
12
|
-
lengthRatio
|
|
13
|
-
closed
|
|
14
|
-
forceSolid
|
|
15
|
-
}
|
|
7
|
+
opts: {
|
|
8
|
+
style?: TLDefaultDashStyle
|
|
9
|
+
snap?: number
|
|
10
|
+
end?: 'skip' | 'outset' | 'none'
|
|
11
|
+
start?: 'skip' | 'outset' | 'none'
|
|
12
|
+
lengthRatio?: number
|
|
13
|
+
closed?: boolean
|
|
14
|
+
forceSolid?: boolean
|
|
15
|
+
} = {}
|
|
16
16
|
): {
|
|
17
17
|
strokeDasharray: string
|
|
18
18
|
strokeDashoffset: string
|
|
@@ -365,6 +365,21 @@ function SvgExport({
|
|
|
365
365
|
onMount()
|
|
366
366
|
}, [onMount, shapeElements])
|
|
367
367
|
|
|
368
|
+
let backgroundColor = background ? theme.background : 'transparent'
|
|
369
|
+
|
|
370
|
+
if (singleFrameShapeId && background) {
|
|
371
|
+
const frameShapeUtil = editor.getShapeUtil('frame') as any as
|
|
372
|
+
| undefined
|
|
373
|
+
| { options: { showColors: boolean } }
|
|
374
|
+
if (frameShapeUtil?.options.showColors) {
|
|
375
|
+
const shape = editor.getShape(singleFrameShapeId)! as TLFrameShape
|
|
376
|
+
const color = theme[shape.props.color]
|
|
377
|
+
backgroundColor = color.frame.fill
|
|
378
|
+
} else {
|
|
379
|
+
backgroundColor = theme.solid
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
368
383
|
return (
|
|
369
384
|
<SvgExportContextProvider editor={editor} context={exportContext}>
|
|
370
385
|
<svg
|
|
@@ -375,13 +390,7 @@ function SvgExport({
|
|
|
375
390
|
viewBox={`${bbox.minX} ${bbox.minY} ${bbox.width} ${bbox.height}`}
|
|
376
391
|
strokeLinecap="round"
|
|
377
392
|
strokeLinejoin="round"
|
|
378
|
-
style={{
|
|
379
|
-
backgroundColor: background
|
|
380
|
-
? singleFrameShapeId
|
|
381
|
-
? theme.solid
|
|
382
|
-
: theme.background
|
|
383
|
-
: 'transparent',
|
|
384
|
-
}}
|
|
393
|
+
style={{ backgroundColor }}
|
|
385
394
|
data-color-mode={isDarkMode ? 'dark' : 'light'}
|
|
386
395
|
className={`tl-container tl-theme__force-sRGB ${isDarkMode ? 'tl-theme__dark' : 'tl-theme__light'}`}
|
|
387
396
|
>
|
|
@@ -11,6 +11,7 @@ export function useDocumentEvents() {
|
|
|
11
11
|
const editor = useEditor()
|
|
12
12
|
const container = useContainer()
|
|
13
13
|
|
|
14
|
+
const isEditing = useValue('isEditing', () => editor.getEditingShapeId(), [editor])
|
|
14
15
|
const isAppFocused = useValue('isFocused', () => editor.getIsFocused(), [editor])
|
|
15
16
|
|
|
16
17
|
// Prevent the browser's default drag and drop behavior on our container (UI, etc)
|
|
@@ -125,7 +126,11 @@ export function useDocumentEvents() {
|
|
|
125
126
|
if (areShortcutsDisabled(editor)) {
|
|
126
127
|
return
|
|
127
128
|
}
|
|
128
|
-
|
|
129
|
+
// isEditing here sounds like it's about text editing
|
|
130
|
+
// but more specifically, this is so you can tab into an
|
|
131
|
+
// embed that's being 'edited'. In our world,
|
|
132
|
+
// editing an embed, means it's interactive.
|
|
133
|
+
if (hasSelectedShapes && !isEditing) {
|
|
129
134
|
// This is used in tandem with shape navigation.
|
|
130
135
|
preventDefault(e)
|
|
131
136
|
}
|
|
@@ -289,7 +294,7 @@ export function useDocumentEvents() {
|
|
|
289
294
|
container.removeEventListener('keydown', handleKeyDown)
|
|
290
295
|
container.removeEventListener('keyup', handleKeyUp)
|
|
291
296
|
}
|
|
292
|
-
}, [editor, container, isAppFocused])
|
|
297
|
+
}, [editor, container, isAppFocused, isEditing])
|
|
293
298
|
}
|
|
294
299
|
|
|
295
300
|
function areShortcutsDisabled(editor: Editor) {
|
|
@@ -19,10 +19,7 @@ import { DefaultHandle, TLHandleProps } from '../components/default-components/D
|
|
|
19
19
|
import { DefaultHandles, TLHandlesProps } from '../components/default-components/DefaultHandles'
|
|
20
20
|
import { DefaultLoadingScreen } from '../components/default-components/DefaultLoadingScreen'
|
|
21
21
|
import { DefaultScribble, TLScribbleProps } from '../components/default-components/DefaultScribble'
|
|
22
|
-
import {
|
|
23
|
-
DefaultSelectionBackground,
|
|
24
|
-
TLSelectionBackgroundProps,
|
|
25
|
-
} from '../components/default-components/DefaultSelectionBackground'
|
|
22
|
+
import { TLSelectionBackgroundProps } from '../components/default-components/DefaultSelectionBackground'
|
|
26
23
|
import {
|
|
27
24
|
DefaultSelectionForeground,
|
|
28
25
|
TLSelectionForegroundProps,
|
|
@@ -51,29 +48,30 @@ import { useShallowObjectIdentity } from './useIdentity'
|
|
|
51
48
|
/** @public */
|
|
52
49
|
export interface TLEditorComponents {
|
|
53
50
|
Background?: ComponentType | null
|
|
54
|
-
SvgDefs?: ComponentType | null
|
|
55
51
|
Brush?: ComponentType<TLBrushProps> | null
|
|
56
|
-
ZoomBrush?: ComponentType<TLBrushProps> | null
|
|
57
|
-
ShapeIndicators?: ComponentType | null
|
|
58
|
-
ShapeIndicator?: ComponentType<TLShapeIndicatorProps> | null
|
|
59
|
-
Cursor?: ComponentType<TLCursorProps> | null
|
|
60
52
|
Canvas?: ComponentType<TLCanvasComponentProps> | null
|
|
61
53
|
CollaboratorBrush?: ComponentType<TLBrushProps> | null
|
|
62
54
|
CollaboratorCursor?: ComponentType<TLCursorProps> | null
|
|
63
55
|
CollaboratorHint?: ComponentType<TLCollaboratorHintProps> | null
|
|
56
|
+
CollaboratorScribble?: ComponentType<TLScribbleProps> | null
|
|
64
57
|
CollaboratorShapeIndicator?: ComponentType<TLShapeIndicatorProps> | null
|
|
58
|
+
Cursor?: ComponentType<TLCursorProps> | null
|
|
65
59
|
Grid?: ComponentType<TLGridProps> | null
|
|
66
|
-
Scribble?: ComponentType<TLScribbleProps> | null
|
|
67
|
-
CollaboratorScribble?: ComponentType<TLScribbleProps> | null
|
|
68
|
-
SnapIndicator?: ComponentType<TLSnapIndicatorProps> | null
|
|
69
|
-
Handles?: ComponentType<TLHandlesProps> | null
|
|
70
60
|
Handle?: ComponentType<TLHandleProps> | null
|
|
71
|
-
|
|
72
|
-
SelectionForeground?: ComponentType<TLSelectionForegroundProps> | null
|
|
73
|
-
SelectionBackground?: ComponentType<TLSelectionBackgroundProps> | null
|
|
74
|
-
OnTheCanvas?: ComponentType | null
|
|
61
|
+
Handles?: ComponentType<TLHandlesProps> | null
|
|
75
62
|
InFrontOfTheCanvas?: ComponentType | null
|
|
76
63
|
LoadingScreen?: ComponentType | null
|
|
64
|
+
OnTheCanvas?: ComponentType | null
|
|
65
|
+
Overlays?: ComponentType | null
|
|
66
|
+
Scribble?: ComponentType<TLScribbleProps> | null
|
|
67
|
+
SelectionBackground?: ComponentType<TLSelectionBackgroundProps> | null
|
|
68
|
+
SelectionForeground?: ComponentType<TLSelectionForegroundProps> | null
|
|
69
|
+
ShapeIndicator?: ComponentType<TLShapeIndicatorProps> | null
|
|
70
|
+
ShapeIndicators?: ComponentType | null
|
|
71
|
+
SnapIndicator?: ComponentType<TLSnapIndicatorProps> | null
|
|
72
|
+
Spinner?: ComponentType | null
|
|
73
|
+
SvgDefs?: ComponentType | null
|
|
74
|
+
ZoomBrush?: ComponentType<TLBrushProps> | null
|
|
77
75
|
|
|
78
76
|
// These will always have defaults
|
|
79
77
|
ErrorFallback?: TLErrorFallbackComponent
|
|
@@ -96,32 +94,35 @@ export function EditorComponentsProvider({
|
|
|
96
94
|
const value = useMemo(
|
|
97
95
|
(): Required<TLEditorComponents> => ({
|
|
98
96
|
Background: DefaultBackground,
|
|
99
|
-
SvgDefs: DefaultSvgDefs,
|
|
100
97
|
Brush: DefaultBrush,
|
|
101
|
-
|
|
98
|
+
Canvas: DefaultCanvas,
|
|
102
99
|
CollaboratorBrush: DefaultBrush,
|
|
103
|
-
Cursor: DefaultCursor,
|
|
104
100
|
CollaboratorCursor: DefaultCursor,
|
|
105
101
|
CollaboratorHint: DefaultCollaboratorHint,
|
|
102
|
+
CollaboratorScribble: DefaultScribble,
|
|
106
103
|
CollaboratorShapeIndicator: DefaultShapeIndicator,
|
|
104
|
+
Cursor: DefaultCursor,
|
|
107
105
|
Grid: DefaultGrid,
|
|
106
|
+
Handle: DefaultHandle,
|
|
107
|
+
Handles: DefaultHandles,
|
|
108
|
+
InFrontOfTheCanvas: null,
|
|
109
|
+
LoadingScreen: DefaultLoadingScreen,
|
|
110
|
+
OnTheCanvas: null,
|
|
111
|
+
Overlays: null,
|
|
108
112
|
Scribble: DefaultScribble,
|
|
113
|
+
SelectionBackground: null,
|
|
114
|
+
SelectionForeground: DefaultSelectionForeground,
|
|
115
|
+
ShapeIndicator: DefaultShapeIndicator,
|
|
116
|
+
ShapeIndicators: DefaultShapeIndicators,
|
|
109
117
|
SnapIndicator: DefaultSnapIndicator,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
118
|
+
Spinner: DefaultSpinner,
|
|
119
|
+
SvgDefs: DefaultSvgDefs,
|
|
120
|
+
ZoomBrush: DefaultBrush,
|
|
121
|
+
|
|
113
122
|
ErrorFallback: DefaultErrorFallback,
|
|
114
123
|
ShapeErrorFallback: DefaultShapeErrorFallback,
|
|
115
124
|
ShapeIndicatorErrorFallback: DefaultShapeIndicatorErrorFallback,
|
|
116
|
-
|
|
117
|
-
SelectionBackground: DefaultSelectionBackground,
|
|
118
|
-
SelectionForeground: DefaultSelectionForeground,
|
|
119
|
-
ShapeIndicators: DefaultShapeIndicators,
|
|
120
|
-
ShapeIndicator: DefaultShapeIndicator,
|
|
121
|
-
OnTheCanvas: null,
|
|
122
|
-
InFrontOfTheCanvas: null,
|
|
123
|
-
Canvas: DefaultCanvas,
|
|
124
|
-
LoadingScreen: DefaultLoadingScreen,
|
|
125
|
+
|
|
125
126
|
..._overrides,
|
|
126
127
|
}),
|
|
127
128
|
[_overrides]
|
|
@@ -317,6 +317,46 @@ describe('LicenseManager', () => {
|
|
|
317
317
|
expect(result.isDomainValid).toBe(false)
|
|
318
318
|
})
|
|
319
319
|
|
|
320
|
+
it('Succeeds if it is a vscode extension', async () => {
|
|
321
|
+
// @ts-ignore
|
|
322
|
+
delete window.location
|
|
323
|
+
// @ts-ignore
|
|
324
|
+
window.location = new URL(
|
|
325
|
+
'vscode-webview:vscode-webview://1ipd8pun8ud7nd7hv9d112g7evi7m10vak9vviuvia66ou6aibp3/index.html?id=6ec2dc7a-afe9-45d9-bd71-1749f9568d28&origin=955b256f-37e1-4a72-a2f4-ad633e88239c&swVersion=4&extensionId=tldraw-org.tldraw-vscode&platform=electron&vscode-resource-base-authority=vscode-resource.vscode-cdn.net&parentOrigin=vscode-file%3A%2F%2Fvscode-app'
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
const permissiveHostsInfo = JSON.parse(STANDARD_LICENSE_INFO)
|
|
329
|
+
permissiveHostsInfo[PROPERTIES.HOSTS] = ['tldraw-org.tldraw-vscode']
|
|
330
|
+
const permissiveLicenseKey = await generateLicenseKey(
|
|
331
|
+
JSON.stringify(permissiveHostsInfo),
|
|
332
|
+
keyPair
|
|
333
|
+
)
|
|
334
|
+
const result = (await licenseManager.getLicenseFromKey(
|
|
335
|
+
permissiveLicenseKey
|
|
336
|
+
)) as ValidLicenseKeyResult
|
|
337
|
+
expect(result.isDomainValid).toBe(true)
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
it('Fails if it is a vscode extension with the wrong id', async () => {
|
|
341
|
+
// @ts-ignore
|
|
342
|
+
delete window.location
|
|
343
|
+
// @ts-ignore
|
|
344
|
+
window.location = new URL(
|
|
345
|
+
'vscode-webview:vscode-webview://1ipd8pun8ud7nd7hv9d112g7evi7m10vak9vviuvia66ou6aibp3/index.html?id=6ec2dc7a-afe9-45d9-bd71-1749f9568d28&origin=955b256f-37e1-4a72-a2f4-ad633e88239c&swVersion=4&extensionId=tldraw-org.tldraw-vscode&platform=electron&vscode-resource-base-authority=vscode-resource.vscode-cdn.net&parentOrigin=vscode-file%3A%2F%2Fvscode-app'
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
const permissiveHostsInfo = JSON.parse(STANDARD_LICENSE_INFO)
|
|
349
|
+
permissiveHostsInfo[PROPERTIES.HOSTS] = ['blah-org.blah-vscode']
|
|
350
|
+
const permissiveLicenseKey = await generateLicenseKey(
|
|
351
|
+
JSON.stringify(permissiveHostsInfo),
|
|
352
|
+
keyPair
|
|
353
|
+
)
|
|
354
|
+
const result = (await licenseManager.getLicenseFromKey(
|
|
355
|
+
permissiveLicenseKey
|
|
356
|
+
)) as ValidLicenseKeyResult
|
|
357
|
+
expect(result.isDomainValid).toBe(false)
|
|
358
|
+
})
|
|
359
|
+
|
|
320
360
|
it('Checks for internal license', async () => {
|
|
321
361
|
const internalLicenseInfo = JSON.parse(STANDARD_LICENSE_INFO)
|
|
322
362
|
internalLicenseInfo[PROPERTIES.FLAGS] = FLAGS.INTERNAL_LICENSE
|
|
@@ -111,7 +111,10 @@ export class LicenseManager {
|
|
|
111
111
|
if (testEnvironment === 'production') return false
|
|
112
112
|
|
|
113
113
|
// If we are using https on a non-localhost domain we assume it's a production env and a development one otherwise
|
|
114
|
-
return
|
|
114
|
+
return (
|
|
115
|
+
!['https:', 'vscode-webview:'].includes(window.location.protocol) ||
|
|
116
|
+
window.location.hostname === 'localhost'
|
|
117
|
+
)
|
|
115
118
|
}
|
|
116
119
|
|
|
117
120
|
private async extractLicenseKey(licenseKey: string): Promise<LicenseInfo> {
|
|
@@ -250,6 +253,15 @@ export class LicenseManager {
|
|
|
250
253
|
return globToRegex.test(currentHostname) || globToRegex.test(`www.${currentHostname}`)
|
|
251
254
|
}
|
|
252
255
|
|
|
256
|
+
// VSCode support
|
|
257
|
+
if (window.location.protocol === 'vscode-webview:') {
|
|
258
|
+
const currentUrl = new URL(window.location.href)
|
|
259
|
+
const extensionId = currentUrl.searchParams.get('extensionId')
|
|
260
|
+
if (normalizedHost === extensionId) {
|
|
261
|
+
return true
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
253
265
|
return false
|
|
254
266
|
})
|
|
255
267
|
}
|
package/src/lib/options.ts
CHANGED
|
@@ -80,6 +80,10 @@ export interface TldrawOptions {
|
|
|
80
80
|
* nonce to use in the editor's styles.
|
|
81
81
|
*/
|
|
82
82
|
readonly nonce: string | undefined
|
|
83
|
+
/**
|
|
84
|
+
* Branding name of the app, currently only used for adding aria-label for the application.
|
|
85
|
+
*/
|
|
86
|
+
readonly branding?: string
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
/** @public */
|
|
@@ -57,6 +57,11 @@ export class Box {
|
|
|
57
57
|
this.x = n
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
61
|
+
get left() {
|
|
62
|
+
return this.x
|
|
63
|
+
}
|
|
64
|
+
|
|
60
65
|
// eslint-disable-next-line no-restricted-syntax
|
|
61
66
|
get midX() {
|
|
62
67
|
return this.x + this.w / 2
|
|
@@ -67,6 +72,11 @@ export class Box {
|
|
|
67
72
|
return this.x + this.w
|
|
68
73
|
}
|
|
69
74
|
|
|
75
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
76
|
+
get right() {
|
|
77
|
+
return this.x + this.w
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
// eslint-disable-next-line no-restricted-syntax
|
|
71
81
|
get minY() {
|
|
72
82
|
return this.y
|
|
@@ -77,6 +87,11 @@ export class Box {
|
|
|
77
87
|
this.y = n
|
|
78
88
|
}
|
|
79
89
|
|
|
90
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
91
|
+
get top() {
|
|
92
|
+
return this.y
|
|
93
|
+
}
|
|
94
|
+
|
|
80
95
|
// eslint-disable-next-line no-restricted-syntax
|
|
81
96
|
get midY() {
|
|
82
97
|
return this.y + this.h / 2
|
|
@@ -87,6 +102,11 @@ export class Box {
|
|
|
87
102
|
return this.y + this.h
|
|
88
103
|
}
|
|
89
104
|
|
|
105
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
106
|
+
get bottom() {
|
|
107
|
+
return this.y + this.h
|
|
108
|
+
}
|
|
109
|
+
|
|
90
110
|
// eslint-disable-next-line no-restricted-syntax
|
|
91
111
|
get width() {
|
|
92
112
|
return this.w
|
|
@@ -157,12 +157,13 @@ export class Mat {
|
|
|
157
157
|
return Mat.Compose(Mat.Translate(cx, cy!), rotationMatrix, Mat.Translate(-cx, -cy!))
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
static Scale(x: number, y: number):
|
|
161
|
-
static Scale(x: number, y: number, cx: number, cy: number):
|
|
162
|
-
static Scale(x: number, y: number, cx?: number, cy?: number):
|
|
160
|
+
static Scale(x: number, y: number): Mat
|
|
161
|
+
static Scale(x: number, y: number, cx: number, cy: number): Mat
|
|
162
|
+
static Scale(x: number, y: number, cx?: number, cy?: number): Mat {
|
|
163
163
|
const scaleMatrix = new Mat(x, 0, 0, y, 0, 0)
|
|
164
164
|
if (cx === undefined) return scaleMatrix
|
|
165
|
-
|
|
165
|
+
|
|
166
|
+
return Mat.Translate(cx, cy!).multiply(scaleMatrix).translate(-cx, -cy!)
|
|
166
167
|
}
|
|
167
168
|
static Multiply(m1: MatModel, m2: MatModel): MatModel {
|
|
168
169
|
return {
|