@tldraw/editor 3.13.0-canary.bec6f90d283a → 3.13.0-canary.c0afd1f5aa1e
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 +128 -113
- 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 +37 -8
- 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 +86 -26
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- 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 +1 -1
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +0 -3
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.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 +128 -113
- 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 +37 -8
- 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 +86 -26
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- 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 +1 -1
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +0 -3
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.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 +47 -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 +43 -8
- 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 +97 -26
- 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 +23 -3
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +0 -4
- 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
|
@@ -9,13 +9,21 @@ import { useEditorComponents } from '../../hooks/useEditorComponents'
|
|
|
9
9
|
import { OptionalErrorBoundary } from '../ErrorBoundary'
|
|
10
10
|
|
|
11
11
|
// need an extra layer of indirection here to allow hooks to be used inside the indicator render
|
|
12
|
-
const EvenInnererIndicator = memo(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
const EvenInnererIndicator = memo(
|
|
13
|
+
({ shape, util }: { shape: TLShape; util: ShapeUtil<any> }) => {
|
|
14
|
+
return useStateTracking('Indicator: ' + shape.type, () =>
|
|
15
|
+
// always fetch the latest shape from the store even if the props/meta have not changed, to avoid
|
|
16
|
+
// calling the render method with stale data.
|
|
17
|
+
util.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id) as TLShape)
|
|
18
|
+
)
|
|
19
|
+
},
|
|
20
|
+
(prevProps, nextProps) => {
|
|
21
|
+
return (
|
|
22
|
+
prevProps.shape.props === nextProps.shape.props &&
|
|
23
|
+
prevProps.shape.meta === nextProps.shape.meta
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
)
|
|
19
27
|
|
|
20
28
|
const InnerIndicator = memo(({ editor, id }: { editor: Editor; id: TLShapeId }) => {
|
|
21
29
|
const shape = useValue('shape for indicator', () => editor.store.get(id), [editor, id])
|
|
@@ -61,13 +69,14 @@ export const DefaultShapeIndicator = memo(function DefaultShapeIndicator({
|
|
|
61
69
|
useQuickReactor(
|
|
62
70
|
'indicator transform',
|
|
63
71
|
() => {
|
|
72
|
+
if (hidden) return
|
|
64
73
|
const elm = rIndicator.current
|
|
65
74
|
if (!elm) return
|
|
66
75
|
const pageTransform = editor.getShapePageTransform(shapeId)
|
|
67
76
|
if (!pageTransform) return
|
|
68
77
|
elm.style.setProperty('transform', pageTransform.toCssString())
|
|
69
78
|
},
|
|
70
|
-
[editor, shapeId]
|
|
79
|
+
[editor, shapeId, hidden]
|
|
71
80
|
)
|
|
72
81
|
|
|
73
82
|
useLayoutEffect(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @public @react */
|
|
2
2
|
export function DefaultSpinner() {
|
|
3
3
|
return (
|
|
4
|
-
<svg width={16} height={16} viewBox="0 0 16 16">
|
|
4
|
+
<svg width={16} height={16} viewBox="0 0 16 16" aria-hidden="false">
|
|
5
5
|
<g strokeWidth={2} fill="none" fillRule="evenodd">
|
|
6
6
|
<circle strokeOpacity={0.25} cx={8} cy={8} r={7} stroke="currentColor" />
|
|
7
7
|
<path strokeLinecap="round" d="M15 8c0-4.5-4.5-7-7-7" stroke="currentColor">
|
|
@@ -52,7 +52,7 @@ beforeEach(() => {
|
|
|
52
52
|
shapeUtils: [CustomShape],
|
|
53
53
|
bindingUtils: [],
|
|
54
54
|
tools: [],
|
|
55
|
-
store: createTLStore({ shapeUtils: [CustomShape] }),
|
|
55
|
+
store: createTLStore({ shapeUtils: [CustomShape], bindingUtils: [] }),
|
|
56
56
|
getContainer: () => document.body,
|
|
57
57
|
})
|
|
58
58
|
editor.setCameraOptions({ isLocked: true })
|
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -129,6 +129,7 @@ import { Group2d } from '../primitives/geometry/Group2d'
|
|
|
129
129
|
import { intersectPolygonPolygon } from '../primitives/intersect'
|
|
130
130
|
import { PI, approximately, areAnglesCompatible, clamp, pointInPolygon } from '../primitives/utils'
|
|
131
131
|
import { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'
|
|
132
|
+
import { areShapesContentEqual } from '../utils/areShapesContentEqual'
|
|
132
133
|
import { dataUrlToFile } from '../utils/assets'
|
|
133
134
|
import { debugFlags } from '../utils/debug-flags'
|
|
134
135
|
import {
|
|
@@ -325,7 +326,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
325
326
|
this.options = { ...defaultTldrawOptions, ...options }
|
|
326
327
|
|
|
327
328
|
this.store = store
|
|
328
|
-
this.disposables.add(this.store.dispose.bind(this.store))
|
|
329
329
|
this.history = new HistoryManager<TLRecord>({
|
|
330
330
|
store,
|
|
331
331
|
annotateError: (error) => {
|
|
@@ -955,6 +955,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
955
955
|
dispose() {
|
|
956
956
|
this.disposables.forEach((dispose) => dispose())
|
|
957
957
|
this.disposables.clear()
|
|
958
|
+
this.store.dispose()
|
|
958
959
|
this.isDisposed = true
|
|
959
960
|
}
|
|
960
961
|
|
|
@@ -1705,8 +1706,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1705
1706
|
* @readonly
|
|
1706
1707
|
*/
|
|
1707
1708
|
@computed getSelectedShapes(): TLShape[] {
|
|
1708
|
-
|
|
1709
|
-
return compact(selectedShapeIds.map((id) => this.store.get(id)))
|
|
1709
|
+
return compact(this.getSelectedShapeIds().map((id) => this.store.get(id)))
|
|
1710
1710
|
}
|
|
1711
1711
|
|
|
1712
1712
|
/**
|
|
@@ -1815,9 +1815,28 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1815
1815
|
return this
|
|
1816
1816
|
}
|
|
1817
1817
|
|
|
1818
|
+
/**
|
|
1819
|
+
* Select the next shape in the reading order or in cardinal order.
|
|
1820
|
+
*
|
|
1821
|
+
* @example
|
|
1822
|
+
* ```ts
|
|
1823
|
+
* editor.selectAdjacentShape('next')
|
|
1824
|
+
* ```
|
|
1825
|
+
*
|
|
1826
|
+
* @public
|
|
1827
|
+
*/
|
|
1818
1828
|
selectAdjacentShape(direction: TLAdjacentDirection) {
|
|
1819
|
-
const readingOrderShapes = this.getCurrentPageShapesInReadingOrder()
|
|
1820
1829
|
const selectedShapeIds = this.getSelectedShapeIds()
|
|
1830
|
+
const firstParentId = selectedShapeIds[0] ? this.getShape(selectedShapeIds[0])?.parentId : null
|
|
1831
|
+
const isSelectedWithinContainer =
|
|
1832
|
+
firstParentId &&
|
|
1833
|
+
selectedShapeIds.every((shapeId) => this.getShape(shapeId)?.parentId === firstParentId) &&
|
|
1834
|
+
!isPageId(firstParentId)
|
|
1835
|
+
const readingOrderShapes = isSelectedWithinContainer
|
|
1836
|
+
? this._getShapesInReadingOrder(
|
|
1837
|
+
this.getCurrentPageShapes().filter((shape) => shape.parentId === firstParentId)
|
|
1838
|
+
)
|
|
1839
|
+
: this.getCurrentPageShapesInReadingOrder()
|
|
1821
1840
|
const currentShapeId: TLShapeId | undefined =
|
|
1822
1841
|
selectedShapeIds.length === 1
|
|
1823
1842
|
? selectedShapeIds[0]
|
|
@@ -1839,13 +1858,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1839
1858
|
const shape = this.getShape(adjacentShapeId)
|
|
1840
1859
|
if (!shape) return
|
|
1841
1860
|
|
|
1842
|
-
this.
|
|
1843
|
-
this.zoomToSelectionIfOffscreen(256, {
|
|
1844
|
-
animation: {
|
|
1845
|
-
duration: this.options.animationMediumMs,
|
|
1846
|
-
},
|
|
1847
|
-
inset: 0,
|
|
1848
|
-
})
|
|
1861
|
+
this._selectShapesAndZoom([shape.id])
|
|
1849
1862
|
}
|
|
1850
1863
|
|
|
1851
1864
|
/**
|
|
@@ -1855,10 +1868,14 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1855
1868
|
* @public
|
|
1856
1869
|
*/
|
|
1857
1870
|
@computed getCurrentPageShapesInReadingOrder(): TLShape[] {
|
|
1871
|
+
const shapes = this.getCurrentPageShapes().filter((shape) => isPageId(shape.parentId))
|
|
1872
|
+
return this._getShapesInReadingOrder(shapes)
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
private _getShapesInReadingOrder(shapes: TLShape[]): TLShape[] {
|
|
1858
1876
|
const SHALLOW_ANGLE = 20
|
|
1859
1877
|
const ROW_THRESHOLD = 100
|
|
1860
1878
|
|
|
1861
|
-
const shapes = this.getCurrentPageShapes()
|
|
1862
1879
|
const tabbableShapes = shapes.filter((shape) => this.getShapeUtil(shape).canTabTo(shape))
|
|
1863
1880
|
|
|
1864
1881
|
if (tabbableShapes.length <= 1) return tabbableShapes
|
|
@@ -2004,6 +2021,36 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2004
2021
|
return lowestScoringShape!.shape.id
|
|
2005
2022
|
}
|
|
2006
2023
|
|
|
2024
|
+
selectParentShape() {
|
|
2025
|
+
const selectedShape = this.getOnlySelectedShape()
|
|
2026
|
+
if (!selectedShape) return
|
|
2027
|
+
const parentShape = this.getShape(selectedShape.parentId)
|
|
2028
|
+
if (!parentShape) return
|
|
2029
|
+
this._selectShapesAndZoom([parentShape.id])
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
selectFirstChildShape() {
|
|
2033
|
+
const selectedShapes = this.getSelectedShapes()
|
|
2034
|
+
if (!selectedShapes.length) return
|
|
2035
|
+
const selectedShape = selectedShapes[0]
|
|
2036
|
+
const children = this.getSortedChildIdsForParent(selectedShape.id)
|
|
2037
|
+
.map((id) => this.getShape(id))
|
|
2038
|
+
.filter((i) => i) as TLShape[]
|
|
2039
|
+
const sortedChildren = this._getShapesInReadingOrder(children)
|
|
2040
|
+
if (sortedChildren.length === 0) return
|
|
2041
|
+
this._selectShapesAndZoom([sortedChildren[0].id])
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
private _selectShapesAndZoom(ids: TLShapeId[]) {
|
|
2045
|
+
this.setSelectedShapes(ids)
|
|
2046
|
+
this.zoomToSelectionIfOffscreen(256, {
|
|
2047
|
+
animation: {
|
|
2048
|
+
duration: this.options.animationMediumMs,
|
|
2049
|
+
},
|
|
2050
|
+
inset: 0,
|
|
2051
|
+
})
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2007
2054
|
/**
|
|
2008
2055
|
* Clear the selection.
|
|
2009
2056
|
*
|
|
@@ -2276,13 +2323,21 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2276
2323
|
setEditingShape(shape: TLShapeId | TLShape | null): this {
|
|
2277
2324
|
const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
|
|
2278
2325
|
this.setRichTextEditor(null)
|
|
2279
|
-
|
|
2326
|
+
const prevEditingShapeId = this.getEditingShapeId()
|
|
2327
|
+
if (id !== prevEditingShapeId) {
|
|
2280
2328
|
if (id) {
|
|
2281
2329
|
const shape = this.getShape(id)
|
|
2282
2330
|
if (shape && this.getShapeUtil(shape).canEdit(shape)) {
|
|
2283
2331
|
this.run(
|
|
2284
2332
|
() => {
|
|
2285
2333
|
this._updateCurrentPageState({ editingShapeId: id })
|
|
2334
|
+
if (prevEditingShapeId) {
|
|
2335
|
+
const prevEditingShape = this.getShape(prevEditingShapeId)
|
|
2336
|
+
if (prevEditingShape) {
|
|
2337
|
+
this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
this.getShapeUtil(shape).onEditStart?.(shape)
|
|
2286
2341
|
},
|
|
2287
2342
|
{ history: 'ignore' }
|
|
2288
2343
|
)
|
|
@@ -2295,6 +2350,12 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2295
2350
|
() => {
|
|
2296
2351
|
this._updateCurrentPageState({ editingShapeId: null })
|
|
2297
2352
|
this._currentRichTextEditor.set(null)
|
|
2353
|
+
if (prevEditingShapeId) {
|
|
2354
|
+
const prevEditingShape = this.getShape(prevEditingShapeId)
|
|
2355
|
+
if (prevEditingShape) {
|
|
2356
|
+
this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2298
2359
|
},
|
|
2299
2360
|
{ history: 'ignore' }
|
|
2300
2361
|
)
|
|
@@ -4575,7 +4636,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4575
4636
|
this.fonts.trackFontsForShape(shape)
|
|
4576
4637
|
return this.getShapeUtil(shape).getGeometry(shape, opts)
|
|
4577
4638
|
},
|
|
4578
|
-
{ areRecordsEqual:
|
|
4639
|
+
{ areRecordsEqual: areShapesContentEqual }
|
|
4579
4640
|
)
|
|
4580
4641
|
}
|
|
4581
4642
|
return this._shapeGeometryCaches[context].get(
|
|
@@ -4623,9 +4684,15 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4623
4684
|
|
|
4624
4685
|
/** @internal */
|
|
4625
4686
|
@computed private _getShapeHandlesCache(): ComputedCache<TLHandle[] | undefined, TLShape> {
|
|
4626
|
-
return this.store.createComputedCache(
|
|
4627
|
-
|
|
4628
|
-
|
|
4687
|
+
return this.store.createComputedCache(
|
|
4688
|
+
'handles',
|
|
4689
|
+
(shape) => {
|
|
4690
|
+
return this.getShapeUtil(shape).getHandles?.(shape)
|
|
4691
|
+
},
|
|
4692
|
+
{
|
|
4693
|
+
areRecordsEqual: areShapesContentEqual,
|
|
4694
|
+
}
|
|
4695
|
+
)
|
|
4629
4696
|
}
|
|
4630
4697
|
|
|
4631
4698
|
/**
|
|
@@ -5846,9 +5913,15 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5846
5913
|
@computed
|
|
5847
5914
|
private _getBindingsIndexCache() {
|
|
5848
5915
|
const index = bindingsIndex(this)
|
|
5849
|
-
return this.store.createComputedCache<TLBinding[], TLShape>(
|
|
5850
|
-
|
|
5851
|
-
|
|
5916
|
+
return this.store.createComputedCache<TLBinding[], TLShape>(
|
|
5917
|
+
'bindingsIndex',
|
|
5918
|
+
(shape) => {
|
|
5919
|
+
return index.get().get(shape.id)
|
|
5920
|
+
},
|
|
5921
|
+
// we can ignore the shape equality check here because the index is
|
|
5922
|
+
// computed incrementally based on what bindings are in the store
|
|
5923
|
+
{ areRecordsEqual: () => true }
|
|
5924
|
+
)
|
|
5852
5925
|
}
|
|
5853
5926
|
|
|
5854
5927
|
/**
|
|
@@ -10215,7 +10288,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10215
10288
|
|
|
10216
10289
|
// If the camera behavior is "zoom" and the ctrl key is pressed, then pan;
|
|
10217
10290
|
// If the camera behavior is "pan" and the ctrl key is not pressed, then zoom
|
|
10218
|
-
if (
|
|
10291
|
+
if (info.ctrlKey) behavior = wheelBehavior === 'pan' ? 'zoom' : 'pan'
|
|
10219
10292
|
|
|
10220
10293
|
switch (behavior) {
|
|
10221
10294
|
case 'zoom': {
|
|
@@ -10331,12 +10404,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10331
10404
|
if (this.inputs.isPanning && this.inputs.isPointing) {
|
|
10332
10405
|
// Handle spacebar / middle mouse button panning
|
|
10333
10406
|
const { currentScreenPoint, previousScreenPoint } = this.inputs
|
|
10334
|
-
const { panSpeed } = cameraOptions
|
|
10335
10407
|
const offset = Vec.Sub(currentScreenPoint, previousScreenPoint)
|
|
10336
|
-
this.setCamera(
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
)
|
|
10408
|
+
this.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
|
|
10409
|
+
immediate: true,
|
|
10410
|
+
})
|
|
10340
10411
|
this.maybeTrackPerformance('Panning')
|
|
10341
10412
|
return
|
|
10342
10413
|
}
|
|
@@ -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 */
|
|
@@ -244,7 +245,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
|
|
|
244
245
|
*
|
|
245
246
|
* @public
|
|
246
247
|
*/
|
|
247
|
-
|
|
248
|
+
canEditInReadonly(_shape: Shape): boolean {
|
|
248
249
|
return false
|
|
249
250
|
}
|
|
250
251
|
|
|
@@ -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
|
|
@@ -12,10 +12,6 @@ export class GroupShapeUtil extends ShapeUtil<TLGroupShape> {
|
|
|
12
12
|
static override props = groupShapeProps
|
|
13
13
|
static override migrations = groupShapeMigrations
|
|
14
14
|
|
|
15
|
-
override canTabTo() {
|
|
16
|
-
return false
|
|
17
|
-
}
|
|
18
|
-
|
|
19
15
|
override hideSelectionBoundsFg() {
|
|
20
16
|
return true
|
|
21
17
|
}
|
|
@@ -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
|