@tldraw/editor 4.6.0-next.20de11b7e238 → 4.6.0-next.241e87d4700a
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 +668 -96
- package/dist-cjs/index.js +16 -3
- package/dist-cjs/index.js.map +3 -3
- package/dist-cjs/lib/TldrawEditor.js +55 -12
- package/dist-cjs/lib/TldrawEditor.js.map +3 -3
- package/dist-cjs/lib/components/MenuClickCapture.js +16 -1
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +3 -3
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +2 -2
- package/dist-cjs/lib/config/createTLStore.js +7 -0
- package/dist-cjs/lib/config/createTLStore.js.map +2 -2
- package/dist-cjs/lib/config/defaultAssets.js +36 -0
- package/dist-cjs/lib/config/defaultAssets.js.map +7 -0
- package/dist-cjs/lib/editor/Editor.js +215 -5
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/assets/AssetUtil.js +66 -0
- package/dist-cjs/lib/editor/assets/AssetUtil.js.map +7 -0
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js +80 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js.map +7 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js +466 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js +17 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js.map +7 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js +106 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js +586 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js.map +7 -0
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +6 -4
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +11 -2
- 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 +2 -2
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js +6 -0
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
- package/dist-cjs/lib/editor/tools/StateNode.js +14 -17
- package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
- package/dist-cjs/lib/editor/types/SvgExportContext.js.map +2 -2
- package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js +12 -7
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/globals/environment.js +18 -1
- package/dist-cjs/lib/globals/environment.js.map +2 -2
- package/dist-cjs/lib/hooks/{useIsDarkMode.js → useColorMode.js} +14 -10
- package/dist-cjs/lib/hooks/useColorMode.js.map +7 -0
- package/dist-cjs/lib/hooks/useCursor.js +3 -7
- package/dist-cjs/lib/hooks/useCursor.js.map +2 -2
- package/dist-cjs/lib/hooks/useDarkMode.js +4 -4
- package/dist-cjs/lib/hooks/useDarkMode.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js +2 -1
- package/dist-cjs/lib/utils/reparenting.js.map +2 -2
- package/dist-cjs/lib/utils/richText.js.map +2 -2
- package/dist-cjs/lib/utils/runtime.js +2 -1
- package/dist-cjs/lib/utils/runtime.js.map +2 -2
- package/dist-cjs/lib/utils/sync/hardReset.js +0 -8
- package/dist-cjs/lib/utils/sync/hardReset.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 +668 -96
- package/dist-esm/index.mjs +17 -6
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +58 -12
- package/dist-esm/lib/TldrawEditor.mjs.map +3 -3
- package/dist-esm/lib/components/MenuClickCapture.mjs +16 -1
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +3 -3
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +2 -2
- package/dist-esm/lib/config/createTLStore.mjs +10 -1
- package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
- package/dist-esm/lib/config/defaultAssets.mjs +16 -0
- package/dist-esm/lib/config/defaultAssets.mjs.map +7 -0
- package/dist-esm/lib/editor/Editor.mjs +215 -5
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/assets/AssetUtil.mjs +46 -0
- package/dist-esm/lib/editor/assets/AssetUtil.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs +60 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs +438 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs +1 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs +88 -0
- package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs +568 -0
- package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +6 -4
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +11 -2
- 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 +2 -2
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs +6 -0
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/StateNode.mjs +14 -17
- package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
- package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +12 -10
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/globals/environment.mjs +18 -1
- package/dist-esm/lib/globals/environment.mjs.map +2 -2
- package/dist-esm/lib/hooks/useColorMode.mjs +19 -0
- package/dist-esm/lib/hooks/useColorMode.mjs.map +7 -0
- package/dist-esm/lib/hooks/useCursor.mjs +3 -7
- package/dist-esm/lib/hooks/useCursor.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDarkMode.mjs +4 -4
- package/dist-esm/lib/hooks/useDarkMode.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs +2 -1
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/lib/utils/richText.mjs.map +2 -2
- package/dist-esm/lib/utils/runtime.mjs +2 -1
- package/dist-esm/lib/utils/runtime.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/hardReset.mjs +0 -8
- package/dist-esm/lib/utils/sync/hardReset.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +0 -33
- package/package.json +7 -7
- package/src/index.ts +23 -6
- package/src/lib/TldrawEditor.tsx +90 -13
- package/src/lib/components/MenuClickCapture.tsx +20 -0
- package/src/lib/components/default-components/CanvasShapeIndicators.tsx +3 -3
- package/src/lib/config/createTLStore.ts +22 -1
- package/src/lib/config/defaultAssets.ts +19 -0
- package/src/lib/editor/Editor.ts +301 -27
- package/src/lib/editor/assets/AssetUtil.ts +85 -0
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +9 -2
- package/src/lib/editor/managers/FontManager/FontManager.ts +1 -67
- package/src/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.ts +82 -0
- package/src/lib/editor/managers/PerformanceManager/PerformanceManager.test.ts +522 -0
- package/src/lib/editor/managers/PerformanceManager/PerformanceManager.ts +583 -0
- package/src/lib/editor/managers/PerformanceManager/perf-types.ts +196 -0
- package/src/lib/editor/managers/ThemeManager/ThemeManager.ts +116 -0
- package/src/lib/editor/managers/ThemeManager/defaultThemes.ts +605 -0
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +23 -29
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +5 -3
- package/src/lib/editor/shapes/ShapeUtil.ts +28 -3
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -1
- package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +7 -0
- package/src/lib/editor/tools/StateNode.ts +16 -18
- package/src/lib/editor/types/SvgExportContext.tsx +5 -0
- package/src/lib/editor/types/external-content.ts +1 -0
- package/src/lib/exports/getSvgJsx.tsx +21 -15
- package/src/lib/globals/environment.ts +18 -0
- package/src/lib/hooks/{useIsDarkMode.ts → useColorMode.ts} +9 -5
- package/src/lib/hooks/useCursor.ts +3 -7
- package/src/lib/hooks/useDarkMode.ts +4 -4
- package/src/lib/utils/reparenting.ts +6 -2
- package/src/lib/utils/richText.ts +1 -1
- package/src/lib/utils/runtime.ts +3 -1
- package/src/lib/utils/sync/hardReset.ts +0 -8
- package/src/version.ts +3 -3
- package/dist-cjs/lib/hooks/useIsDarkMode.js.map +0 -7
- package/dist-esm/lib/hooks/useIsDarkMode.mjs +0 -15
- package/dist-esm/lib/hooks/useIsDarkMode.mjs.map +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/components/MenuClickCapture.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { PointerEvent, useCallback, useRef, useState } from 'react'\nimport { useCanvasEvents } from '../hooks/useCanvasEvents'\nimport { useEditor } from '../hooks/useEditor'\nimport { Vec } from '../primitives/Vec'\nimport { getPointerInfo } from '../utils/getPointerInfo'\n\n/**\n * When a menu is open, this component prevents the user from interacting with the canvas.\n *\n * @public @react\n */\nexport function MenuClickCapture() {\n\tconst editor = useEditor()\n\n\t// Whether any menus are open\n\tconst isMenuOpen = useValue('is menu open', () => editor.menus.hasAnyOpenMenus(), [editor])\n\n\t// Whether we're pointing or not\u2014keep this component visible if we're pointing\n\tconst [isPointing, setIsPointing] = useState(false)\n\n\tconst showElement = isMenuOpen || isPointing\n\n\t// Get the same events that we use on the canvas\n\tconst canvasEvents = useCanvasEvents()\n\n\t// Keep track of the pointer state\n\tconst rPointerState = useRef({\n\t\tisDown: false,\n\t\tisDragging: false,\n\t\tstart: new Vec(),\n\t})\n\n\tconst handlePointerDown = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\tif (e.button === 0) {\n\t\t\t\tsetIsPointing(true)\n\t\t\t\trPointerState.current = {\n\t\t\t\t\tisDown: true,\n\t\t\t\t\tisDragging: false,\n\t\t\t\t\tstart: new Vec(e.clientX, e.clientY),\n\t\t\t\t}\n\t\t\t\trDidAPointerDownAndDragWhileMenuWasOpen.current = false\n\t\t\t}\n\t\t\teditor.menus.clearOpenMenus()\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst rDidAPointerDownAndDragWhileMenuWasOpen = useRef(false)\n\n\tconst handlePointerMove = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\t// Do nothing unless we're pointing\n\t\t\tif (!rPointerState.current.isDown) return\n\n\t\t\t// call the onPointerDown with the original pointer position\n\t\t\tconst { x, y } = rPointerState.current.start\n\n\t\t\tif (!rDidAPointerDownAndDragWhileMenuWasOpen.current) {\n\t\t\t\tif (\n\t\t\t\t\t// We're pointing, but are we dragging?\n\t\t\t\t\tVec.Dist2(rPointerState.current.start, new Vec(e.clientX, e.clientY)) >\n\t\t\t\t\teditor.options.dragDistanceSquared\n\t\t\t\t) {\n\t\t\t\t\trDidAPointerDownAndDragWhileMenuWasOpen.current = true\n\t\t\t\t\t// Wehaddaeventitsadrag\n\t\t\t\t\trPointerState.current = {\n\t\t\t\t\t\t...rPointerState.current,\n\t\t\t\t\t\tisDown: true,\n\t\t\t\t\t\tisDragging: true,\n\t\t\t\t\t}\n\t\t\t\t\tcanvasEvents.onPointerDown?.({\n\t\t\t\t\t\t...e,\n\t\t\t\t\t\tclientX: x,\n\t\t\t\t\t\tclientY: y,\n\t\t\t\t\t\tbutton: 0,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rDidAPointerDownAndDragWhileMenuWasOpen.current) {\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t\t[canvasEvents, editor]\n\t)\n\n\tconst handlePointerUp = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\t// Run the pointer up\n\t\t\tcanvasEvents.onPointerUp?.(e)\n\t\t\t// Then turn off pointing\n\t\t\tsetIsPointing(false)\n\t\t\t// Reset the pointer state\n\t\t\trPointerState.current = {\n\t\t\t\tisDown: false,\n\t\t\t\tisDragging: false,\n\t\t\t\tstart: new Vec(e.clientX, e.clientY),\n\t\t\t}\n\t\t\trDidAPointerDownAndDragWhileMenuWasOpen.current = false\n\t\t},\n\t\t[canvasEvents]\n\t)\n\n\treturn (\n\t\tshowElement && (\n\t\t\t<div\n\t\t\t\tclassName=\"tlui-menu-click-capture\"\n\t\t\t\tdata-testid=\"menu-click-capture.content\"\n\t\t\t\t{...canvasEvents}\n\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\tonPointerMove={handlePointerMove}\n\t\t\t\tonPointerUp={handlePointerUp}\n\t\t\t/>\n\t\t)\n\t)\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { PointerEvent, useCallback, useRef, useState } from 'react'\nimport { useCanvasEvents } from '../hooks/useCanvasEvents'\nimport { useEditor } from '../hooks/useEditor'\nimport { Vec } from '../primitives/Vec'\nimport { getPointerInfo } from '../utils/getPointerInfo'\n\n/**\n * When a menu is open, this component prevents the user from interacting with the canvas.\n *\n * @public @react\n */\nexport function MenuClickCapture() {\n\tconst editor = useEditor()\n\n\t// Whether any menus are open\n\tconst isMenuOpen = useValue('is menu open', () => editor.menus.hasAnyOpenMenus(), [editor])\n\n\t// Whether we're pointing or not\u2014keep this component visible if we're pointing\n\tconst [isPointing, setIsPointing] = useState(false)\n\n\tconst showElement = isMenuOpen || isPointing\n\n\t// Get the same events that we use on the canvas\n\tconst canvasEvents = useCanvasEvents()\n\n\t// Keep track of the pointer state\n\tconst rPointerState = useRef({\n\t\tisDown: false,\n\t\tisDragging: false,\n\t\tstart: new Vec(),\n\t})\n\n\tconst handlePointerDown = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\tif (e.button === 0) {\n\t\t\t\tsetIsPointing(true)\n\t\t\t\trPointerState.current = {\n\t\t\t\t\tisDown: true,\n\t\t\t\t\tisDragging: false,\n\t\t\t\t\tstart: new Vec(e.clientX, e.clientY),\n\t\t\t\t}\n\t\t\t\trDidAPointerDownAndDragWhileMenuWasOpen.current = false\n\t\t\t}\n\t\t\tif (e.button === 2) {\n\t\t\t\t// Swallow the contextmenu event that follows this right-click pointerdown.\n\t\t\t\t// clearOpenMenus() below triggers a synchronous render that unmounts this\n\t\t\t\t// component, so our React onContextMenu handler won't be around to catch it.\n\t\t\t\t// Without this, the contextmenu event reaches the Radix Trigger and briefly\n\t\t\t\t// opens a new context menu (which then immediately dismisses \u2014 causing a flash).\n\t\t\t\tconst ownerDocument = editor.getContainerDocument()\n\t\t\t\townerDocument.addEventListener(\n\t\t\t\t\t'contextmenu',\n\t\t\t\t\t(event) => {\n\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\tevent.stopImmediatePropagation()\n\t\t\t\t\t},\n\t\t\t\t\t{ capture: true, once: true }\n\t\t\t\t)\n\t\t\t}\n\t\t\teditor.menus.clearOpenMenus()\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst rDidAPointerDownAndDragWhileMenuWasOpen = useRef(false)\n\n\tconst handlePointerMove = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\t// Do nothing unless we're pointing\n\t\t\tif (!rPointerState.current.isDown) return\n\n\t\t\t// call the onPointerDown with the original pointer position\n\t\t\tconst { x, y } = rPointerState.current.start\n\n\t\t\tif (!rDidAPointerDownAndDragWhileMenuWasOpen.current) {\n\t\t\t\tif (\n\t\t\t\t\t// We're pointing, but are we dragging?\n\t\t\t\t\tVec.Dist2(rPointerState.current.start, new Vec(e.clientX, e.clientY)) >\n\t\t\t\t\teditor.options.dragDistanceSquared\n\t\t\t\t) {\n\t\t\t\t\trDidAPointerDownAndDragWhileMenuWasOpen.current = true\n\t\t\t\t\t// Wehaddaeventitsadrag\n\t\t\t\t\trPointerState.current = {\n\t\t\t\t\t\t...rPointerState.current,\n\t\t\t\t\t\tisDown: true,\n\t\t\t\t\t\tisDragging: true,\n\t\t\t\t\t}\n\t\t\t\t\tcanvasEvents.onPointerDown?.({\n\t\t\t\t\t\t...e,\n\t\t\t\t\t\tclientX: x,\n\t\t\t\t\t\tclientY: y,\n\t\t\t\t\t\tbutton: 0,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rDidAPointerDownAndDragWhileMenuWasOpen.current) {\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t\t[canvasEvents, editor]\n\t)\n\n\tconst handlePointerUp = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\t// Run the pointer up\n\t\t\tcanvasEvents.onPointerUp?.(e)\n\t\t\t// Then turn off pointing\n\t\t\tsetIsPointing(false)\n\t\t\t// Reset the pointer state\n\t\t\trPointerState.current = {\n\t\t\t\tisDown: false,\n\t\t\t\tisDragging: false,\n\t\t\t\tstart: new Vec(e.clientX, e.clientY),\n\t\t\t}\n\t\t\trDidAPointerDownAndDragWhileMenuWasOpen.current = false\n\t\t},\n\t\t[canvasEvents]\n\t)\n\n\treturn (\n\t\tshowElement && (\n\t\t\t<div\n\t\t\t\tclassName=\"tlui-menu-click-capture\"\n\t\t\t\tdata-testid=\"menu-click-capture.content\"\n\t\t\t\t{...canvasEvents}\n\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\tonPointerMove={handlePointerMove}\n\t\t\t\tonPointerUp={handlePointerUp}\n\t\t\t\tonContextMenu={(e) => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t}}\n\t\t\t/>\n\t\t)\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,8 +4,8 @@ import { createComputedCache } from "@tldraw/store";
|
|
|
4
4
|
import { dedupe } from "@tldraw/utils";
|
|
5
5
|
import { memo, useEffect, useRef } from "react";
|
|
6
6
|
import { getComputedStyle } from "../../exports/domUtils.mjs";
|
|
7
|
+
import { useColorMode } from "../../hooks/useColorMode.mjs";
|
|
7
8
|
import { useEditor } from "../../hooks/useEditor.mjs";
|
|
8
|
-
import { useIsDarkMode } from "../../hooks/useIsDarkMode.mjs";
|
|
9
9
|
import { useActivePeerIds$ } from "../../hooks/usePeerIds.mjs";
|
|
10
10
|
function setsEqual(a, b) {
|
|
11
11
|
if (a.size !== b.size) return false;
|
|
@@ -87,13 +87,13 @@ const CanvasShapeIndicators = memo(function CanvasShapeIndicators2() {
|
|
|
87
87
|
const editor = useEditor();
|
|
88
88
|
const canvasRef = useRef(null);
|
|
89
89
|
const rSelectedColor = useRef(null);
|
|
90
|
-
const
|
|
90
|
+
const colorMode = useColorMode();
|
|
91
91
|
useEffect(() => {
|
|
92
92
|
const timer = editor.timers.setTimeout(() => {
|
|
93
93
|
rSelectedColor.current = null;
|
|
94
94
|
}, 0);
|
|
95
95
|
return () => clearTimeout(timer);
|
|
96
|
-
}, [
|
|
96
|
+
}, [colorMode, editor]);
|
|
97
97
|
const activePeerIds$ = useActivePeerIds$();
|
|
98
98
|
const $renderData = useComputed(
|
|
99
99
|
"indicator render data",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/components/default-components/CanvasShapeIndicators.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useComputed, useQuickReactor } from '@tldraw/state-react'\nimport { createComputedCache } from '@tldraw/store'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport { dedupe } from '@tldraw/utils'\nimport { memo, useEffect, useRef } from 'react'\nimport { Editor } from '../../editor/Editor'\nimport { TLIndicatorPath } from '../../editor/shapes/ShapeUtil'\nimport { getComputedStyle } from '../../exports/domUtils'\nimport {
|
|
5
|
-
"mappings": "AA+RQ;AA/RR,SAAS,aAAa,uBAAuB;AAC7C,SAAS,2BAA2B;AAEpC,SAAS,cAAc;AACvB,SAAS,MAAM,WAAW,cAAc;AAGxC,SAAS,wBAAwB;AACjC,SAAS,
|
|
4
|
+
"sourcesContent": ["import { useComputed, useQuickReactor } from '@tldraw/state-react'\nimport { createComputedCache } from '@tldraw/store'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport { dedupe } from '@tldraw/utils'\nimport { memo, useEffect, useRef } from 'react'\nimport { Editor } from '../../editor/Editor'\nimport { TLIndicatorPath } from '../../editor/shapes/ShapeUtil'\nimport { getComputedStyle } from '../../exports/domUtils'\nimport { useColorMode } from '../../hooks/useColorMode'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useActivePeerIds$ } from '../../hooks/usePeerIds'\n\ninterface CollaboratorIndicatorData {\n\tcolor: string\n\tshapeIds: TLShapeId[]\n}\n\ninterface RenderData {\n\tidsToDisplay: Set<TLShapeId>\n\trenderingShapeIds: Set<TLShapeId>\n\thintingShapeIds: TLShapeId[]\n\tcollaboratorIndicators: CollaboratorIndicatorData[]\n}\n\nfunction setsEqual<T>(a: Set<T>, b: Set<T>): boolean {\n\tif (a.size !== b.size) return false\n\tfor (const item of a) {\n\t\tif (!b.has(item)) return false\n\t}\n\treturn true\n}\n\nfunction arraysEqual<T>(a: readonly T[], b: readonly T[]): boolean {\n\tif (a.length !== b.length) return false\n\tfor (let i = 0; i < a.length; i++) {\n\t\tif (a[i] !== b[i]) return false\n\t}\n\treturn true\n}\n\nfunction collaboratorIndicatorsEqual(\n\ta: CollaboratorIndicatorData[],\n\tb: CollaboratorIndicatorData[]\n): boolean {\n\tif (a.length !== b.length) return false\n\tfor (let i = 0; i < a.length; i++) {\n\t\tif (a[i].color !== b[i].color) return false\n\t\tif (!arraysEqual(a[i].shapeIds, b[i].shapeIds)) return false\n\t}\n\treturn true\n}\n\nfunction renderDataEqual(a: RenderData, b: RenderData): boolean {\n\treturn (\n\t\tsetsEqual(a.idsToDisplay, b.idsToDisplay) &&\n\t\tsetsEqual(a.renderingShapeIds, b.renderingShapeIds) &&\n\t\tarraysEqual(a.hintingShapeIds, b.hintingShapeIds) &&\n\t\tcollaboratorIndicatorsEqual(a.collaboratorIndicators, b.collaboratorIndicators)\n\t)\n}\n\nconst indicatorPathCache = createComputedCache(\n\t'indicatorPath',\n\t(editor: Editor, shape: TLShape) => {\n\t\tconst util = editor.getShapeUtil(shape)\n\t\treturn util.getIndicatorPath(shape)\n\t}\n)\n\nconst getIndicatorPath = (editor: Editor, shape: TLShape) => {\n\treturn indicatorPathCache.get(editor, shape.id)\n}\n\nfunction renderShapeIndicator(\n\tctx: CanvasRenderingContext2D,\n\teditor: Editor,\n\tshapeId: TLShapeId,\n\trenderingShapeIds: Set<TLShapeId>\n): boolean {\n\tif (!renderingShapeIds.has(shapeId)) return false\n\n\tconst shape = editor.getShape(shapeId)\n\tif (!shape || shape.isLocked) return false\n\n\tconst pageTransform = editor.getShapePageTransform(shape)\n\tif (!pageTransform) return false\n\n\tconst indicatorPath = getIndicatorPath(editor, shape)\n\tif (!indicatorPath) return false\n\n\tctx.save()\n\tctx.transform(\n\t\tpageTransform.a,\n\t\tpageTransform.b,\n\t\tpageTransform.c,\n\t\tpageTransform.d,\n\t\tpageTransform.e,\n\t\tpageTransform.f\n\t)\n\trenderIndicatorPath(ctx, indicatorPath)\n\tctx.restore()\n\n\treturn true\n}\n\nfunction renderIndicatorPath(ctx: CanvasRenderingContext2D, indicatorPath: TLIndicatorPath) {\n\tif (indicatorPath instanceof Path2D) {\n\t\tctx.stroke(indicatorPath)\n\t} else {\n\t\tconst { path, clipPath, additionalPaths } = indicatorPath\n\n\t\tif (clipPath) {\n\t\t\tctx.save()\n\t\t\tctx.clip(clipPath, 'evenodd')\n\t\t\tctx.stroke(path)\n\t\t\tctx.restore()\n\t\t} else {\n\t\t\tctx.stroke(path)\n\t\t}\n\n\t\tif (additionalPaths) {\n\t\t\tfor (const additionalPath of additionalPaths) {\n\t\t\t\tctx.stroke(additionalPath)\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** @internal @react */\nexport const CanvasShapeIndicators = memo(function CanvasShapeIndicators() {\n\tconst editor = useEditor()\n\tconst canvasRef = useRef<HTMLCanvasElement>(null)\n\n\t// Cache the selected color to avoid getComputedStyle on every render\n\tconst rSelectedColor = useRef<string | null>(null)\n\tconst colorMode = useColorMode()\n\n\tuseEffect(() => {\n\t\tconst timer = editor.timers.setTimeout(() => {\n\t\t\trSelectedColor.current = null\n\t\t}, 0)\n\t\treturn () => clearTimeout(timer)\n\t}, [colorMode, editor])\n\n\t// Get active peer IDs (already handles time-based state transitions)\n\tconst activePeerIds$ = useActivePeerIds$()\n\n\tconst $renderData = useComputed(\n\t\t'indicator render data',\n\t\t() => {\n\t\t\tconst renderingShapeIds = new Set(editor.getRenderingShapes().map((s) => s.id))\n\n\t\t\t// Compute ids to display for selected/hovered shapes\n\t\t\tconst idsToDisplay = new Set<TLShapeId>()\n\t\t\tconst instanceState = editor.getInstanceState()\n\t\t\tconst isChangingStyle = instanceState.isChangingStyle\n\t\t\tconst isIdleOrEditing = editor.isInAny('select.idle', 'select.editing_shape')\n\t\t\tconst isInSelectState = editor.isInAny(\n\t\t\t\t'select.brushing',\n\t\t\t\t'select.scribble_brushing',\n\t\t\t\t'select.pointing_shape',\n\t\t\t\t'select.pointing_selection',\n\t\t\t\t'select.pointing_handle'\n\t\t\t)\n\n\t\t\tif (!isChangingStyle && (isIdleOrEditing || isInSelectState)) {\n\t\t\t\tfor (const id of editor.getSelectedShapeIds()) {\n\t\t\t\t\tidsToDisplay.add(id)\n\t\t\t\t}\n\t\t\t\tif (isIdleOrEditing && instanceState.isHoveringCanvas && !instanceState.isCoarsePointer) {\n\t\t\t\t\tconst hovered = editor.getHoveredShapeId()\n\t\t\t\t\tif (hovered) idsToDisplay.add(hovered)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Compute hinting shape ids\n\t\t\tconst hintingShapeIds = dedupe(editor.getHintingShapeIds())\n\n\t\t\t// Compute collaborator indicators\n\t\t\tconst collaboratorIndicators: CollaboratorIndicatorData[] = []\n\t\t\tconst currentPageId = editor.getCurrentPageId()\n\t\t\tconst activePeerIds = activePeerIds$.get()\n\n\t\t\tconst collaborators = editor.getCollaborators()\n\t\t\tfor (const peerId of activePeerIds.values()) {\n\t\t\t\t// Skip collaborators on different pages\n\t\t\t\tconst presence = collaborators.find((c) => c.userId === peerId)\n\t\t\t\tif (!presence || presence.currentPageId !== currentPageId) continue\n\n\t\t\t\t// Filter to shapes that are visible and on the current rendering set\n\t\t\t\tconst visibleShapeIds = presence.selectedShapeIds.filter(\n\t\t\t\t\t(id) => renderingShapeIds.has(id) && !editor.isShapeHidden(id)\n\t\t\t\t)\n\n\t\t\t\tif (visibleShapeIds.length > 0) {\n\t\t\t\t\tcollaboratorIndicators.push({\n\t\t\t\t\t\tcolor: presence.color,\n\t\t\t\t\t\tshapeIds: visibleShapeIds,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tidsToDisplay,\n\t\t\t\trenderingShapeIds,\n\t\t\t\thintingShapeIds,\n\t\t\t\tcollaboratorIndicators,\n\t\t\t}\n\t\t},\n\t\t{ isEqual: renderDataEqual },\n\t\t[editor, activePeerIds$]\n\t)\n\n\tuseQuickReactor(\n\t\t'canvas indicators render',\n\t\t() => {\n\t\t\tconst canvas = canvasRef.current\n\t\t\tif (!canvas) return\n\n\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\tif (!ctx) return\n\n\t\t\tconst { idsToDisplay, renderingShapeIds, hintingShapeIds, collaboratorIndicators } =\n\t\t\t\t$renderData.get()\n\n\t\t\tconst { w, h } = editor.getViewportScreenBounds()\n\t\t\tconst dpr = editor.getInstanceState().devicePixelRatio\n\t\t\tconst { x: cx, y: cy, z: zoom } = editor.getCamera()\n\n\t\t\tconst canvasWidth = Math.ceil(w * dpr)\n\t\t\tconst canvasHeight = Math.ceil(h * dpr)\n\n\t\t\tif (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {\n\t\t\t\tcanvas.width = canvasWidth\n\t\t\t\tcanvas.height = canvasHeight\n\t\t\t\tcanvas.style.width = `${w}px`\n\t\t\t\tcanvas.style.height = `${h}px`\n\t\t\t}\n\n\t\t\tctx.resetTransform()\n\t\t\tctx.clearRect(0, 0, canvas.width, canvas.height)\n\n\t\t\tctx.scale(dpr, dpr)\n\t\t\tctx.scale(zoom, zoom)\n\t\t\tctx.translate(cx, cy)\n\n\t\t\tctx.lineCap = 'round'\n\t\t\tctx.lineJoin = 'round'\n\n\t\t\t// Draw collaborator indicators first (underneath local indicators)\n\t\t\t// Use 0.5 opacity to match the original SVG-based collaborator indicators\n\t\t\tctx.lineWidth = 1.5 / zoom\n\t\t\tfor (const collaborator of collaboratorIndicators) {\n\t\t\t\tctx.strokeStyle = collaborator.color\n\t\t\t\tctx.globalAlpha = 0.7\n\t\t\t\tfor (const shapeId of collaborator.shapeIds) {\n\t\t\t\t\trenderShapeIndicator(ctx, editor, shapeId, renderingShapeIds)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Reset alpha for local indicators\n\t\t\tctx.globalAlpha = 1.0\n\n\t\t\t// Use cached color, only call getComputedStyle when cache is empty\n\t\t\tif (!rSelectedColor.current) {\n\t\t\t\trSelectedColor.current = getComputedStyle(canvas).getPropertyValue('--tl-color-selected')\n\t\t\t}\n\n\t\t\tctx.strokeStyle = rSelectedColor.current\n\n\t\t\t// Draw selected/hovered indicators (1.5px stroke)\n\t\t\tctx.lineWidth = 1.5 / zoom\n\t\t\tfor (const shapeId of idsToDisplay) {\n\t\t\t\trenderShapeIndicator(ctx, editor, shapeId, renderingShapeIds)\n\t\t\t}\n\n\t\t\t// Draw hinted indicators with a thicker stroke (2.5px)\n\t\t\tif (hintingShapeIds.length > 0) {\n\t\t\t\tctx.lineWidth = 2.5 / zoom\n\t\t\t\tfor (const shapeId of hintingShapeIds) {\n\t\t\t\t\trenderShapeIndicator(ctx, editor, shapeId, renderingShapeIds)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, $renderData]\n\t)\n\n\treturn <canvas ref={canvasRef} className=\"tl-canvas-indicators\" />\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["CanvasShapeIndicators"]
|
|
7
7
|
}
|
|
@@ -4,10 +4,14 @@ import {
|
|
|
4
4
|
UserRecordType,
|
|
5
5
|
createCachedUserResolve,
|
|
6
6
|
createTLSchema,
|
|
7
|
-
createUserId
|
|
7
|
+
createUserId,
|
|
8
|
+
registerColorsFromThemes,
|
|
9
|
+
registerFontsFromThemes
|
|
8
10
|
} from "@tldraw/tlschema";
|
|
9
11
|
import { FileHelpers, assert } from "@tldraw/utils";
|
|
10
12
|
import { Editor } from "../editor/Editor.mjs";
|
|
13
|
+
import { resolveThemes } from "../editor/managers/ThemeManager/ThemeManager.mjs";
|
|
14
|
+
import { checkAssets } from "./defaultAssets.mjs";
|
|
11
15
|
import { checkBindings } from "./defaultBindings.mjs";
|
|
12
16
|
import { checkShapesAndAddCore } from "./defaultShapes.mjs";
|
|
13
17
|
import { loadSnapshot } from "./TLEditorSnapshot.mjs";
|
|
@@ -35,6 +39,7 @@ function createTLSchemaFromUtils(opts) {
|
|
|
35
39
|
return createTLSchema({
|
|
36
40
|
shapes: "shapeUtils" in opts && opts.shapeUtils ? utilsToMap(checkShapesAndAddCore(opts.shapeUtils)) : void 0,
|
|
37
41
|
bindings: "bindingUtils" in opts && opts.bindingUtils ? utilsToMap(checkBindings(opts.bindingUtils)) : void 0,
|
|
42
|
+
assets: "assetUtils" in opts && opts.assetUtils ? utilsToMap(checkAssets(opts.assetUtils)) : void 0,
|
|
38
43
|
records: "records" in opts ? opts.records : void 0,
|
|
39
44
|
migrations: "migrations" in opts ? opts.migrations : void 0
|
|
40
45
|
});
|
|
@@ -47,8 +52,12 @@ function createTLStore({
|
|
|
47
52
|
users = defaultUserStore,
|
|
48
53
|
onMount,
|
|
49
54
|
collaboration,
|
|
55
|
+
themes,
|
|
50
56
|
...rest
|
|
51
57
|
} = {}) {
|
|
58
|
+
const resolvedThemes = resolveThemes(themes);
|
|
59
|
+
registerColorsFromThemes(resolvedThemes);
|
|
60
|
+
registerFontsFromThemes(resolvedThemes);
|
|
52
61
|
const schema = createTLSchemaFromUtils(rest);
|
|
53
62
|
const store = new Store({
|
|
54
63
|
id,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/config/createTLStore.ts"],
|
|
4
|
-
"sourcesContent": ["import { Signal, computed } from '@tldraw/state'\nimport { HistoryEntry, MigrationSequence, SerializedStore, Store, StoreSchema } from '@tldraw/store'\nimport {\n\tCustomRecordInfo,\n\tSchemaPropsInfo,\n\tTLAssetStore,\n\tTLRecord,\n\tTLStore,\n\tTLStoreProps,\n\tTLStoreSnapshot,\n\tTLUser,\n\tTLUserStore,\n\tUserRecordType,\n\tcreateCachedUserResolve,\n\tcreateTLSchema,\n\tcreateUserId,\n} from '@tldraw/tlschema'\nimport { FileHelpers, assert } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'\nimport { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'\nimport { defaultUserPreferences, getUserPreferences } from './TLUserPreferences'\n\n/** @public */\nexport interface TLStoreBaseOptions {\n\t/** The initial data for the store. */\n\tinitialData?: SerializedStore<TLRecord>\n\n\t/** A snapshot of initial data to migrate and load into the store. */\n\tsnapshot?: Partial<TLEditorSnapshot> | TLStoreSnapshot\n\n\t/** The default name for the store. */\n\tdefaultName?: string\n\n\t/** How should this store upload & resolve assets? */\n\tassets?: TLAssetStore\n\n\t/** How should this store resolve users for attribution? */\n\tusers?: TLUserStore\n\n\t/** Called when the store is connected to an {@link @tldraw/editor#Editor}. */\n\tonMount?(editor: Editor): void | (() => void)\n}\n\n/** @public */\nexport type TLStoreSchemaOptions =\n\t| {\n\t\t\tschema?: StoreSchema<TLRecord, TLStoreProps>\n\t }\n\t| {\n\t\t\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t\t\
|
|
5
|
-
"mappings": "AAAA,SAAiB,gBAAgB;AACjC,SAA2D,aAA0B;AACrF;AAAA,
|
|
4
|
+
"sourcesContent": ["import { Signal, computed } from '@tldraw/state'\nimport { HistoryEntry, MigrationSequence, SerializedStore, Store, StoreSchema } from '@tldraw/store'\nimport {\n\tCustomRecordInfo,\n\tSchemaPropsInfo,\n\tTLAssetStore,\n\tTLRecord,\n\tTLStore,\n\tTLStoreProps,\n\tTLStoreSnapshot,\n\tTLThemes,\n\tTLUser,\n\tTLUserStore,\n\tUserRecordType,\n\tcreateCachedUserResolve,\n\tcreateTLSchema,\n\tcreateUserId,\n\tregisterColorsFromThemes,\n\tregisterFontsFromThemes,\n} from '@tldraw/tlschema'\nimport { FileHelpers, assert } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { resolveThemes } from '../editor/managers/ThemeManager/ThemeManager'\nimport { TLAnyAssetUtilConstructor, checkAssets } from './defaultAssets'\nimport { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'\nimport { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'\nimport { defaultUserPreferences, getUserPreferences } from './TLUserPreferences'\n\n/** @public */\nexport interface TLStoreBaseOptions {\n\t/** The initial data for the store. */\n\tinitialData?: SerializedStore<TLRecord>\n\n\t/** A snapshot of initial data to migrate and load into the store. */\n\tsnapshot?: Partial<TLEditorSnapshot> | TLStoreSnapshot\n\n\t/** The default name for the store. */\n\tdefaultName?: string\n\n\t/** How should this store upload & resolve assets? */\n\tassets?: TLAssetStore\n\n\t/**\n\t * Named theme definitions. When provided, custom color names are automatically\n\t * registered before the store is constructed so persisted data with those\n\t * colors passes validation on load.\n\t */\n\tthemes?: Partial<TLThemes>\n\n\t/** How should this store resolve users for attribution? */\n\tusers?: TLUserStore\n\n\t/** Called when the store is connected to an {@link @tldraw/editor#Editor}. */\n\tonMount?(editor: Editor): void | (() => void)\n}\n\n/** @public */\nexport type TLStoreSchemaOptions =\n\t| {\n\t\t\tschema?: StoreSchema<TLRecord, TLStoreProps>\n\t }\n\t| {\n\t\t\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t\t\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t\t\tassetUtils?: readonly TLAnyAssetUtilConstructor[]\n\t\t\tmigrations?: readonly MigrationSequence[]\n\t\t\trecords?: Record<string, CustomRecordInfo>\n\t }\n\n/** @public */\nexport type TLStoreOptions = TLStoreBaseOptions & {\n\tid?: string\n\t/** Collaboration options for the store. */\n\tcollaboration?: {\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n} & TLStoreSchemaOptions\n\n/** @public */\nexport type TLStoreEventInfo = HistoryEntry<TLRecord>\n\nconst defaultAssetResolve: NonNullable<TLAssetStore['resolve']> = (asset) => asset.props.src\n\nconst _defaultCurrentUser: Signal<TLUser | null> = computed('defaultCurrentUser', () => {\n\tconst prefs = getUserPreferences()\n\tif (!prefs.id) return null\n\treturn UserRecordType.create({\n\t\tid: createUserId(prefs.id),\n\t\tname: prefs.name ?? '',\n\t\tcolor: prefs.color ?? defaultUserPreferences.color,\n\t})\n})\n\n/** @public */\nexport const defaultUserStore: TLUserStore = {\n\tcurrentUser: _defaultCurrentUser,\n}\n\n/** @public */\nexport const inlineBase64AssetStore: TLAssetStore = {\n\tupload: async (_, file) => {\n\t\treturn { src: await FileHelpers.blobToDataUrl(file) }\n\t},\n}\n\n/**\n * A helper for creating a TLStore schema from either an object with shapeUtils, bindingUtils, and\n * migrations, or a schema.\n *\n * @param opts - Options for creating the schema.\n *\n * @public\n */\nexport function createTLSchemaFromUtils(\n\topts: TLStoreSchemaOptions\n): StoreSchema<TLRecord, TLStoreProps> {\n\tif ('schema' in opts && opts.schema) return opts.schema\n\n\treturn createTLSchema({\n\t\tshapes:\n\t\t\t'shapeUtils' in opts && opts.shapeUtils\n\t\t\t\t? utilsToMap(checkShapesAndAddCore(opts.shapeUtils))\n\t\t\t\t: undefined,\n\t\tbindings:\n\t\t\t'bindingUtils' in opts && opts.bindingUtils\n\t\t\t\t? utilsToMap(checkBindings(opts.bindingUtils))\n\t\t\t\t: undefined,\n\t\tassets:\n\t\t\t'assetUtils' in opts && opts.assetUtils\n\t\t\t\t? utilsToMap(checkAssets(opts.assetUtils))\n\t\t\t\t: undefined,\n\t\trecords: 'records' in opts ? opts.records : undefined,\n\t\tmigrations: 'migrations' in opts ? opts.migrations : undefined,\n\t})\n}\n\n/**\n * A helper for creating a TLStore.\n *\n * @param opts - Options for creating the store.\n *\n * @public\n */\nexport function createTLStore({\n\tinitialData,\n\tdefaultName = '',\n\tid,\n\tassets = inlineBase64AssetStore,\n\tusers = defaultUserStore,\n\tonMount,\n\tcollaboration,\n\tthemes,\n\t...rest\n}: TLStoreOptions = {}): TLStore {\n\tconst resolvedThemes = resolveThemes(themes)\n\tregisterColorsFromThemes(resolvedThemes)\n\tregisterFontsFromThemes(resolvedThemes)\n\tconst schema = createTLSchemaFromUtils(rest)\n\n\tconst store = new Store({\n\t\tid,\n\t\tschema,\n\t\tinitialData,\n\t\tprops: {\n\t\t\tdefaultName,\n\t\t\tassets: {\n\t\t\t\tupload: assets.upload,\n\t\t\t\tresolve: assets.resolve ?? defaultAssetResolve,\n\t\t\t\tremove: assets.remove ?? (() => Promise.resolve()),\n\t\t\t},\n\t\t\tusers: {\n\t\t\t\tcurrentUser: users.currentUser,\n\t\t\t\tresolve:\n\t\t\t\t\tusers.resolve ??\n\t\t\t\t\tcreateCachedUserResolve((userId) => {\n\t\t\t\t\t\tconst current = users.currentUser.get()\n\t\t\t\t\t\treturn current && current.id === createUserId(userId) ? current : null\n\t\t\t\t\t}),\n\t\t\t},\n\t\t\tonMount: (editor) => {\n\t\t\t\tassert(editor instanceof Editor)\n\t\t\t\tonMount?.(editor)\n\t\t\t},\n\t\t\tcollaboration,\n\t\t},\n\t})\n\n\tif (rest.snapshot) {\n\t\tif (initialData) throw new Error('Cannot provide both initialData and snapshot')\n\t\tloadSnapshot(store, rest.snapshot, { forceOverwriteSessionState: true })\n\t}\n\n\treturn store\n}\n\nfunction utilsToMap<T extends SchemaPropsInfo & { type: string }>(utils: T[]) {\n\treturn Object.fromEntries(\n\t\tutils.map((s): [string, SchemaPropsInfo] => [\n\t\t\ts.type,\n\t\t\t{\n\t\t\t\tprops: s.props,\n\t\t\t\tmigrations: s.migrations,\n\t\t\t},\n\t\t])\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function checkAssets(customAssets) {
|
|
2
|
+
const assets = [];
|
|
3
|
+
const addedCustomAssetTypes = /* @__PURE__ */ new Set();
|
|
4
|
+
for (const customAsset of customAssets) {
|
|
5
|
+
if (addedCustomAssetTypes.has(customAsset.type)) {
|
|
6
|
+
throw new Error(`Asset type "${customAsset.type}" is defined more than once`);
|
|
7
|
+
}
|
|
8
|
+
assets.push(customAsset);
|
|
9
|
+
addedCustomAssetTypes.add(customAsset.type);
|
|
10
|
+
}
|
|
11
|
+
return assets;
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
checkAssets
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=defaultAssets.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/config/defaultAssets.ts"],
|
|
4
|
+
"sourcesContent": ["import { TLAssetUtilConstructor } from '../editor/assets/AssetUtil'\n\n/** @public */\nexport type TLAnyAssetUtilConstructor = TLAssetUtilConstructor<any>\n\nexport function checkAssets(customAssets: readonly TLAnyAssetUtilConstructor[]) {\n\tconst assets = [] as TLAnyAssetUtilConstructor[]\n\n\tconst addedCustomAssetTypes = new Set<string>()\n\tfor (const customAsset of customAssets) {\n\t\tif (addedCustomAssetTypes.has(customAsset.type)) {\n\t\t\tthrow new Error(`Asset type \"${customAsset.type}\" is defined more than once`)\n\t\t}\n\t\tassets.push(customAsset)\n\t\taddedCustomAssetTypes.add(customAsset.type)\n\t}\n\n\treturn assets\n}\n"],
|
|
5
|
+
"mappings": "AAKO,SAAS,YAAY,cAAoD;AAC/E,QAAM,SAAS,CAAC;AAEhB,QAAM,wBAAwB,oBAAI,IAAY;AAC9C,aAAW,eAAe,cAAc;AACvC,QAAI,sBAAsB,IAAI,YAAY,IAAI,GAAG;AAChD,YAAM,IAAI,MAAM,eAAe,YAAY,IAAI,6BAA6B;AAAA,IAC7E;AACA,WAAO,KAAK,WAAW;AACvB,0BAAsB,IAAI,YAAY,IAAI;AAAA,EAC3C;AAEA,SAAO;AACR;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -65,6 +65,7 @@ import {
|
|
|
65
65
|
} from "@tldraw/utils";
|
|
66
66
|
import EventEmitter from "eventemitter3";
|
|
67
67
|
import { createTLCurrentUser } from "../config/createTLCurrentUser.mjs";
|
|
68
|
+
import { checkAssets } from "../config/defaultAssets.mjs";
|
|
68
69
|
import { checkBindings } from "../config/defaultBindings.mjs";
|
|
69
70
|
import { checkShapesAndAddCore } from "../config/defaultShapes.mjs";
|
|
70
71
|
import {
|
|
@@ -115,10 +116,12 @@ import { FocusManager } from "./managers/FocusManager/FocusManager.mjs";
|
|
|
115
116
|
import { FontManager } from "./managers/FontManager/FontManager.mjs";
|
|
116
117
|
import { HistoryManager } from "./managers/HistoryManager/HistoryManager.mjs";
|
|
117
118
|
import { InputsManager } from "./managers/InputsManager/InputsManager.mjs";
|
|
119
|
+
import { PerformanceManager } from "./managers/PerformanceManager/PerformanceManager.mjs";
|
|
118
120
|
import { ScribbleManager } from "./managers/ScribbleManager/ScribbleManager.mjs";
|
|
119
121
|
import { SnapManager } from "./managers/SnapManager/SnapManager.mjs";
|
|
120
122
|
import { SpatialIndexManager } from "./managers/SpatialIndexManager/SpatialIndexManager.mjs";
|
|
121
123
|
import { TextManager } from "./managers/TextManager/TextManager.mjs";
|
|
124
|
+
import { resolveThemes, ThemeManager } from "./managers/ThemeManager/ThemeManager.mjs";
|
|
122
125
|
import { TickManager } from "./managers/TickManager/TickManager.mjs";
|
|
123
126
|
import { UserPreferencesManager } from "./managers/UserPreferencesManager/UserPreferencesManager.mjs";
|
|
124
127
|
import { RootState } from "./tools/RootState.mjs";
|
|
@@ -129,6 +132,7 @@ class Editor extends EventEmitter {
|
|
|
129
132
|
user,
|
|
130
133
|
shapeUtils,
|
|
131
134
|
bindingUtils,
|
|
135
|
+
assetUtils: assetUtilConstructors,
|
|
132
136
|
tools,
|
|
133
137
|
getContainer,
|
|
134
138
|
// needs to be here for backwards compatibility with TldrawEditor
|
|
@@ -136,13 +140,15 @@ class Editor extends EventEmitter {
|
|
|
136
140
|
cameraOptions,
|
|
137
141
|
initialState,
|
|
138
142
|
autoFocus,
|
|
139
|
-
inferDarkMode,
|
|
140
143
|
options: _options,
|
|
141
144
|
// needs to be here for backwards compatibility with TldrawEditor
|
|
142
145
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
143
146
|
textOptions: _textOptions,
|
|
144
147
|
getShapeVisibility,
|
|
145
|
-
|
|
148
|
+
colorScheme,
|
|
149
|
+
fontAssetUrls,
|
|
150
|
+
themes,
|
|
151
|
+
initialTheme
|
|
146
152
|
}) {
|
|
147
153
|
super();
|
|
148
154
|
this._getShapeVisibility = getShapeVisibility;
|
|
@@ -165,19 +171,27 @@ class Editor extends EventEmitter {
|
|
|
165
171
|
...cameraOptions,
|
|
166
172
|
...options?.camera
|
|
167
173
|
});
|
|
174
|
+
this.getContainer = getContainer;
|
|
168
175
|
this._textOptions = atom("text options", options?.text ?? null);
|
|
169
|
-
this.user = new UserPreferencesManager(user ?? createTLCurrentUser(),
|
|
176
|
+
this.user = new UserPreferencesManager(user ?? createTLCurrentUser(), colorScheme ?? "light");
|
|
170
177
|
this.disposables.add(() => this.user.dispose());
|
|
171
|
-
this.getContainer = getContainer;
|
|
172
178
|
this.textMeasure = new TextManager(this);
|
|
173
179
|
this.disposables.add(() => this.textMeasure.dispose());
|
|
174
|
-
this.
|
|
180
|
+
this._themeManager = new ThemeManager(this, {
|
|
181
|
+
themes: resolveThemes(themes),
|
|
182
|
+
initial: initialTheme ?? "default"
|
|
183
|
+
});
|
|
184
|
+
this.disposables.add(() => this._themeManager.dispose());
|
|
175
185
|
this._tickManager = new TickManager(this);
|
|
186
|
+
this.disposables.add(() => this._tickManager.dispose());
|
|
176
187
|
this.disposables.add(() => {
|
|
177
188
|
this.off("tick", this._decayCameraStateTimeout);
|
|
178
189
|
this._setCameraState("idle");
|
|
179
190
|
});
|
|
191
|
+
this.fonts = new FontManager(this, fontAssetUrls);
|
|
180
192
|
this.inputs = new InputsManager(this);
|
|
193
|
+
this.performance = new PerformanceManager(this);
|
|
194
|
+
this.disposables.add(() => this.performance.dispose());
|
|
181
195
|
class NewRoot extends RootState {
|
|
182
196
|
static initial = initialState ?? "";
|
|
183
197
|
}
|
|
@@ -205,6 +219,16 @@ class Editor extends EventEmitter {
|
|
|
205
219
|
}
|
|
206
220
|
this.shapeUtils = _shapeUtils;
|
|
207
221
|
this.styleProps = _styleProps;
|
|
222
|
+
const _shapeUtilsByAssetType = {};
|
|
223
|
+
for (const Util of allShapeUtils) {
|
|
224
|
+
const assetTypes = Util.handledAssetTypes;
|
|
225
|
+
if (assetTypes) {
|
|
226
|
+
for (const assetType of assetTypes) {
|
|
227
|
+
_shapeUtilsByAssetType[assetType] = _shapeUtils[Util.type];
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
this._shapeUtilsByAssetType = _shapeUtilsByAssetType;
|
|
208
232
|
const allBindingUtils = checkBindings(bindingUtils);
|
|
209
233
|
const _bindingUtils = {};
|
|
210
234
|
for (const Util of allBindingUtils) {
|
|
@@ -212,6 +236,15 @@ class Editor extends EventEmitter {
|
|
|
212
236
|
_bindingUtils[Util.type] = util;
|
|
213
237
|
}
|
|
214
238
|
this.bindingUtils = _bindingUtils;
|
|
239
|
+
if (assetUtilConstructors) {
|
|
240
|
+
const allAssetUtils = checkAssets(assetUtilConstructors);
|
|
241
|
+
const _assetUtils = {};
|
|
242
|
+
for (const Util of allAssetUtils) {
|
|
243
|
+
const util = new Util(this);
|
|
244
|
+
_assetUtils[Util.type] = util;
|
|
245
|
+
}
|
|
246
|
+
this.assetUtils = _assetUtils;
|
|
247
|
+
}
|
|
215
248
|
for (const Tool of [...tools]) {
|
|
216
249
|
if (hasOwnProperty(this.root.children, Tool.id)) {
|
|
217
250
|
throw Error(`Can't override tool with id "${Tool.id}"`);
|
|
@@ -652,6 +685,17 @@ class Editor extends EventEmitter {
|
|
|
652
685
|
* @public
|
|
653
686
|
*/
|
|
654
687
|
snaps;
|
|
688
|
+
/**
|
|
689
|
+
* A manager for performance measurement hooks.
|
|
690
|
+
*
|
|
691
|
+
* @public
|
|
692
|
+
*/
|
|
693
|
+
performance;
|
|
694
|
+
/**
|
|
695
|
+
* A manager for the spatial index, tracking where shapes exist on the canvas.
|
|
696
|
+
*
|
|
697
|
+
* @internal
|
|
698
|
+
*/
|
|
655
699
|
_spatialIndex;
|
|
656
700
|
/**
|
|
657
701
|
* A manager for the any asynchronous events and making sure they're
|
|
@@ -666,6 +710,12 @@ class Editor extends EventEmitter {
|
|
|
666
710
|
* @public
|
|
667
711
|
*/
|
|
668
712
|
user;
|
|
713
|
+
/**
|
|
714
|
+
* A manager for the editor's themes.
|
|
715
|
+
*
|
|
716
|
+
* @internal
|
|
717
|
+
*/
|
|
718
|
+
_themeManager;
|
|
669
719
|
/**
|
|
670
720
|
* A helper for measuring text.
|
|
671
721
|
*
|
|
@@ -737,12 +787,117 @@ class Editor extends EventEmitter {
|
|
|
737
787
|
* @public
|
|
738
788
|
*/
|
|
739
789
|
dispose() {
|
|
790
|
+
this.stopCameraAnimation();
|
|
791
|
+
if (this.getInstanceState().followingUserId) {
|
|
792
|
+
this.stopFollowingUser();
|
|
793
|
+
}
|
|
740
794
|
this.disposables.forEach((dispose) => dispose());
|
|
741
795
|
this.disposables.clear();
|
|
796
|
+
this.menus.clearOpenMenus();
|
|
742
797
|
this.store.dispose();
|
|
743
798
|
this.isDisposed = true;
|
|
744
799
|
this.emit("dispose");
|
|
745
800
|
}
|
|
801
|
+
/* ------------------ Themes (shadowing the theme manager) ------------------ */
|
|
802
|
+
/**
|
|
803
|
+
* Get the current color mode (`'light'` or `'dark'`), based on the user's dark mode preference.
|
|
804
|
+
*
|
|
805
|
+
* @public
|
|
806
|
+
*/
|
|
807
|
+
getColorMode() {
|
|
808
|
+
return this._themeManager.getColorMode();
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Set the color mode. Note that this is a convenience method that passes the mode to
|
|
812
|
+
* `user.updateUserPreferences`, which is the source of truth for the user's color mode preference.
|
|
813
|
+
*
|
|
814
|
+
* @public
|
|
815
|
+
*/
|
|
816
|
+
setColorMode(mode) {
|
|
817
|
+
this.user.updateUserPreferences({ colorScheme: mode });
|
|
818
|
+
return this;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Get the id of the current theme.
|
|
822
|
+
*
|
|
823
|
+
* @public
|
|
824
|
+
*/
|
|
825
|
+
getCurrentThemeId() {
|
|
826
|
+
return this._themeManager.getCurrentThemeId();
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Get the current theme definition.
|
|
830
|
+
*
|
|
831
|
+
* @public
|
|
832
|
+
*/
|
|
833
|
+
getCurrentTheme() {
|
|
834
|
+
return this._themeManager.getCurrentTheme();
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Set the current theme by id.
|
|
838
|
+
*
|
|
839
|
+
* @public
|
|
840
|
+
*/
|
|
841
|
+
setCurrentTheme(id) {
|
|
842
|
+
this._themeManager.setCurrentTheme(id);
|
|
843
|
+
return this;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Get all registered theme definitions.
|
|
847
|
+
*
|
|
848
|
+
* @public
|
|
849
|
+
*/
|
|
850
|
+
getThemes() {
|
|
851
|
+
return this._themeManager.getThemes();
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Get a single theme definition by id.
|
|
855
|
+
*
|
|
856
|
+
* @public
|
|
857
|
+
*/
|
|
858
|
+
getTheme(id) {
|
|
859
|
+
return this._themeManager.getTheme(id);
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Replace all theme definitions, or update them via a callback that receives a deep copy.
|
|
863
|
+
* The `'default'` theme must always be present in the result.
|
|
864
|
+
*
|
|
865
|
+
* @example
|
|
866
|
+
* ```ts
|
|
867
|
+
* // Replace all themes
|
|
868
|
+
* editor.updateThemes({ default: myDefaultTheme, ocean: myOceanTheme })
|
|
869
|
+
*
|
|
870
|
+
* // Update via callback
|
|
871
|
+
* editor.updateThemes((themes) => {
|
|
872
|
+
* delete themes.ocean
|
|
873
|
+
* return themes
|
|
874
|
+
* })
|
|
875
|
+
* ```
|
|
876
|
+
*
|
|
877
|
+
* @public
|
|
878
|
+
*/
|
|
879
|
+
updateThemes(themes) {
|
|
880
|
+
this._themeManager.updateThemes(themes);
|
|
881
|
+
return this;
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Register or update a single theme definition. The theme is keyed by its `id` property.
|
|
885
|
+
*
|
|
886
|
+
* @example
|
|
887
|
+
* ```ts
|
|
888
|
+
* // Override a property on the default theme
|
|
889
|
+
* editor.updateTheme({ ...editor.getTheme('default')!, fontSize: 24 })
|
|
890
|
+
*
|
|
891
|
+
* // Register a new theme
|
|
892
|
+
* editor.updateTheme({ id: 'ocean', ...myOceanTheme })
|
|
893
|
+
* ```
|
|
894
|
+
*
|
|
895
|
+
* @public
|
|
896
|
+
*/
|
|
897
|
+
updateTheme(theme) {
|
|
898
|
+
this._themeManager.updateTheme(theme);
|
|
899
|
+
return this;
|
|
900
|
+
}
|
|
746
901
|
/* ------------------- Shape Utils ------------------ */
|
|
747
902
|
/**
|
|
748
903
|
* A map of shape utility classes (TLShapeUtils) by shape type.
|
|
@@ -750,6 +905,8 @@ class Editor extends EventEmitter {
|
|
|
750
905
|
* @public
|
|
751
906
|
*/
|
|
752
907
|
shapeUtils;
|
|
908
|
+
/** @internal */
|
|
909
|
+
_shapeUtilsByAssetType = {};
|
|
753
910
|
styleProps;
|
|
754
911
|
getShapeUtil(arg) {
|
|
755
912
|
const type = typeof arg === "string" ? arg : arg.type;
|
|
@@ -761,6 +918,17 @@ class Editor extends EventEmitter {
|
|
|
761
918
|
const type = typeof arg === "string" ? arg : arg.type;
|
|
762
919
|
return hasOwnProperty(this.shapeUtils, type);
|
|
763
920
|
}
|
|
921
|
+
/**
|
|
922
|
+
* Get the shape util that handles the given asset type.
|
|
923
|
+
* Returns the shape util whose {@link ShapeUtil.handledAssetTypes} includes
|
|
924
|
+
* the given asset type, or undefined if none matches.
|
|
925
|
+
*
|
|
926
|
+
* @param assetType - The asset type string.
|
|
927
|
+
* @public
|
|
928
|
+
*/
|
|
929
|
+
getShapeUtilForAssetType(assetType) {
|
|
930
|
+
return getOwnProperty(this._shapeUtilsByAssetType, assetType);
|
|
931
|
+
}
|
|
764
932
|
/* ------------------- Binding Utils ------------------ */
|
|
765
933
|
/**
|
|
766
934
|
* A map of shape utility classes (TLShapeUtils) by shape type.
|
|
@@ -774,6 +942,42 @@ class Editor extends EventEmitter {
|
|
|
774
942
|
assert(bindingUtil, `No binding util found for type "${type}"`);
|
|
775
943
|
return bindingUtil;
|
|
776
944
|
}
|
|
945
|
+
/* ------------------- Asset Utils ------------------ */
|
|
946
|
+
/**
|
|
947
|
+
* A map of asset utility classes by asset type.
|
|
948
|
+
*
|
|
949
|
+
* @public
|
|
950
|
+
*/
|
|
951
|
+
assetUtils = {};
|
|
952
|
+
getAssetUtil(arg) {
|
|
953
|
+
const type = typeof arg === "string" ? arg : arg.type;
|
|
954
|
+
const assetUtil = getOwnProperty(this.assetUtils, type);
|
|
955
|
+
assert(assetUtil, `No asset util found for type "${type}"`);
|
|
956
|
+
return assetUtil;
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Returns true if the editor has an asset util for the given asset type.
|
|
960
|
+
*
|
|
961
|
+
* @public
|
|
962
|
+
*/
|
|
963
|
+
hasAssetUtil(arg) {
|
|
964
|
+
const type = typeof arg === "string" ? arg : arg.type;
|
|
965
|
+
return hasOwnProperty(this.assetUtils, type);
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Get the asset util that accepts the given MIME type.
|
|
969
|
+
* Returns null if no registered asset util accepts the MIME type.
|
|
970
|
+
*
|
|
971
|
+
* @public
|
|
972
|
+
*/
|
|
973
|
+
getAssetUtilForMimeType(mimeType) {
|
|
974
|
+
for (const util of Object.values(this.assetUtils)) {
|
|
975
|
+
if (util && util.acceptsMimeType(mimeType)) {
|
|
976
|
+
return util;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return null;
|
|
980
|
+
}
|
|
777
981
|
/* --------------------- History -------------------- */
|
|
778
982
|
/**
|
|
779
983
|
* A manager for the editor's history.
|
|
@@ -795,6 +999,7 @@ class Editor extends EventEmitter {
|
|
|
795
999
|
this._flushEventsForTick(0);
|
|
796
1000
|
this.complete();
|
|
797
1001
|
this.history.undo();
|
|
1002
|
+
this.performance._notifyUndoRedo("undo", this.history.getNumUndos(), this.history.getNumRedos());
|
|
798
1003
|
return this;
|
|
799
1004
|
}
|
|
800
1005
|
canUndo() {
|
|
@@ -817,6 +1022,7 @@ class Editor extends EventEmitter {
|
|
|
817
1022
|
this._flushEventsForTick(0);
|
|
818
1023
|
this.complete();
|
|
819
1024
|
this.history.redo();
|
|
1025
|
+
this.performance._notifyUndoRedo("redo", this.history.getNumUndos(), this.history.getNumRedos());
|
|
820
1026
|
return this;
|
|
821
1027
|
}
|
|
822
1028
|
canRedo() {
|
|
@@ -7723,6 +7929,7 @@ class Editor extends EventEmitter {
|
|
|
7723
7929
|
),
|
|
7724
7930
|
{ immediate: true }
|
|
7725
7931
|
);
|
|
7932
|
+
this.performance._notifyCameraOperation("zooming");
|
|
7726
7933
|
this.emit("event", info);
|
|
7727
7934
|
return;
|
|
7728
7935
|
}
|
|
@@ -7784,6 +7991,7 @@ class Editor extends EventEmitter {
|
|
|
7784
7991
|
immediate: true
|
|
7785
7992
|
});
|
|
7786
7993
|
this.maybeTrackPerformance("Zooming");
|
|
7994
|
+
this.performance._notifyCameraOperation("zooming");
|
|
7787
7995
|
this.root.handleEvent(info);
|
|
7788
7996
|
this.emit("event", info);
|
|
7789
7997
|
return;
|
|
@@ -7793,6 +8001,7 @@ class Editor extends EventEmitter {
|
|
|
7793
8001
|
immediate: true
|
|
7794
8002
|
});
|
|
7795
8003
|
this.maybeTrackPerformance("Panning");
|
|
8004
|
+
this.performance._notifyCameraOperation("panning");
|
|
7796
8005
|
this.root.handleEvent(info);
|
|
7797
8006
|
this.emit("event", info);
|
|
7798
8007
|
return;
|
|
@@ -7858,6 +8067,7 @@ class Editor extends EventEmitter {
|
|
|
7858
8067
|
immediate: true
|
|
7859
8068
|
});
|
|
7860
8069
|
this.maybeTrackPerformance("Panning");
|
|
8070
|
+
this.performance._notifyCameraOperation("panning");
|
|
7861
8071
|
return;
|
|
7862
8072
|
}
|
|
7863
8073
|
if (inputs.getIsPointing() && !inputs.getIsDragging() && Vec.Dist2(inputs.getOriginPagePoint(), inputs.getCurrentPagePoint()) * this.getZoomLevel() > (instanceState.isCoarsePointer ? this.options.coarseDragDistanceSquared : this.options.dragDistanceSquared) / cz) {
|