@tldraw/editor 5.1.0-canary.aec92a79e54b → 5.1.0-canary.bb89313f32d2

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.
Files changed (102) hide show
  1. package/dist-cjs/index.d.ts +32 -2
  2. package/dist-cjs/index.js +1 -1
  3. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +30 -17
  4. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  5. package/dist-cjs/lib/editor/Editor.js +31 -6
  6. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  7. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +23 -21
  8. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +2 -2
  9. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +27 -8
  10. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +2 -2
  11. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +4 -2
  12. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +2 -2
  13. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +2 -2
  14. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
  15. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +8 -0
  16. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
  17. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +7 -1
  18. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
  19. package/dist-cjs/lib/editor/managers/SpatialIndexManager/RBushIndex.js +13 -15
  20. package/dist-cjs/lib/editor/managers/SpatialIndexManager/RBushIndex.js.map +2 -2
  21. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +43 -24
  22. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +2 -2
  23. package/dist-cjs/lib/editor/overlays/OverlayManager.js +5 -0
  24. package/dist-cjs/lib/editor/overlays/OverlayManager.js.map +2 -2
  25. package/dist-cjs/lib/editor/overlays/OverlayUtil.js +5 -0
  26. package/dist-cjs/lib/editor/overlays/OverlayUtil.js.map +2 -2
  27. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +1 -1
  28. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
  29. package/dist-cjs/lib/hooks/usePeerIds.js.map +2 -2
  30. package/dist-cjs/lib/license/LicenseManager.js +6 -4
  31. package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
  32. package/dist-cjs/lib/options.js +2 -0
  33. package/dist-cjs/lib/options.js.map +2 -2
  34. package/dist-cjs/lib/utils/dom.js +1 -0
  35. package/dist-cjs/lib/utils/dom.js.map +2 -2
  36. package/dist-cjs/version.js +3 -3
  37. package/dist-cjs/version.js.map +1 -1
  38. package/dist-esm/index.d.mts +32 -2
  39. package/dist-esm/index.mjs +1 -1
  40. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +30 -17
  41. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  42. package/dist-esm/lib/editor/Editor.mjs +31 -6
  43. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  44. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +23 -21
  45. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +2 -2
  46. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +27 -11
  47. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +2 -2
  48. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +4 -2
  49. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +2 -2
  50. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +2 -2
  51. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
  52. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +8 -0
  53. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
  54. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +7 -1
  55. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
  56. package/dist-esm/lib/editor/managers/SpatialIndexManager/RBushIndex.mjs +13 -15
  57. package/dist-esm/lib/editor/managers/SpatialIndexManager/RBushIndex.mjs.map +2 -2
  58. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +43 -24
  59. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +2 -2
  60. package/dist-esm/lib/editor/overlays/OverlayManager.mjs +5 -0
  61. package/dist-esm/lib/editor/overlays/OverlayManager.mjs.map +2 -2
  62. package/dist-esm/lib/editor/overlays/OverlayUtil.mjs +5 -0
  63. package/dist-esm/lib/editor/overlays/OverlayUtil.mjs.map +2 -2
  64. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +1 -1
  65. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
  66. package/dist-esm/lib/hooks/usePeerIds.mjs.map +2 -2
  67. package/dist-esm/lib/license/LicenseManager.mjs +6 -4
  68. package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
  69. package/dist-esm/lib/options.mjs +2 -0
  70. package/dist-esm/lib/options.mjs.map +2 -2
  71. package/dist-esm/lib/utils/dom.mjs +1 -0
  72. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  73. package/dist-esm/version.mjs +3 -3
  74. package/dist-esm/version.mjs.map +1 -1
  75. package/package.json +92 -92
  76. package/src/lib/components/default-components/DefaultCanvas.tsx +34 -26
  77. package/src/lib/editor/Editor.ts +44 -6
  78. package/src/lib/editor/derivations/notVisibleShapes.ts +34 -26
  79. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.test.ts +132 -0
  80. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +40 -12
  81. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts +12 -2
  82. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +7 -0
  83. package/src/lib/editor/managers/FocusManager/FocusManager.ts +2 -2
  84. package/src/lib/editor/managers/FontManager/FontManager.test.ts +33 -2
  85. package/src/lib/editor/managers/FontManager/FontManager.ts +20 -2
  86. package/src/lib/editor/managers/InputsManager/InputsManager.ts +11 -2
  87. package/src/lib/editor/managers/SpatialIndexManager/RBushIndex.ts +13 -14
  88. package/src/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.ts +67 -40
  89. package/src/lib/editor/overlays/OverlayManager.ts +6 -0
  90. package/src/lib/editor/overlays/OverlayUtil.ts +5 -0
  91. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -1
  92. package/src/lib/hooks/usePeerIds.ts +1 -0
  93. package/src/lib/license/LicenseManager.test.ts +14 -0
  94. package/src/lib/license/LicenseManager.ts +14 -5
  95. package/src/lib/options.ts +20 -0
  96. package/src/lib/utils/dom.ts +1 -0
  97. package/src/version.ts +3 -3
  98. package/dist-cjs/lib/utils/collaboratorState.js +0 -42
  99. package/dist-cjs/lib/utils/collaboratorState.js.map +0 -7
  100. package/dist-esm/lib/utils/collaboratorState.mjs +0 -22
  101. package/dist-esm/lib/utils/collaboratorState.mjs.map +0 -7
  102. package/src/lib/utils/collaboratorState.ts +0 -54
@@ -780,6 +780,8 @@ export declare function clockwiseAngleDist(a0: number, a1: number): number;
780
780
  export declare class CollaboratorsManager {
781
781
  private readonly editor;
782
782
  constructor(editor: Editor);
783
+ private _visibilityClockStarted;
784
+ private _startVisibilityClock;
783
785
  /**
784
786
  * Drives reactive re-evaluation of {@link CollaboratorsManager.getVisibleCollaborators}.
785
787
  * Ticked on a fixed interval so callers don't need to manage their own activity timers.
@@ -998,6 +1000,7 @@ export declare const DefaultSvgDefs: () => null;
998
1000
  export declare const defaultTldrawOptions: {
999
1001
  readonly actionShortcutsLocation: "swap";
1000
1002
  readonly adjacentShapeMargin: 10;
1003
+ readonly allowVideoAutoplay: true;
1001
1004
  readonly animationMediumMs: 320;
1002
1005
  readonly camera: TLCameraOptions;
1003
1006
  readonly cameraMovingTimeoutMs: 64;
@@ -1059,6 +1062,7 @@ export declare const defaultTldrawOptions: {
1059
1062
  readonly onClipboardPasteRaw: undefined;
1060
1063
  readonly quickZoomPreservesScreenBounds: true;
1061
1064
  readonly rightClickPanning: true;
1065
+ readonly selectLockedShapes: false;
1062
1066
  readonly snapThreshold: 8;
1063
1067
  readonly spacebarPanning: true;
1064
1068
  readonly temporaryAssetPreviewLifetimeMs: 180000;
@@ -2643,6 +2647,7 @@ export declare class Editor extends EventEmitter<TLEventMap> {
2643
2647
  * @public
2644
2648
  */
2645
2649
  getRenderingShapes(): TLRenderingShape[];
2650
+ private _renderingShapesSortCache;
2646
2651
  private _getAllPagesQuery;
2647
2652
  /**
2648
2653
  * Info about the project's current pages.
@@ -4576,8 +4581,9 @@ export declare class FontManager {
4576
4581
  constructor(editor: Editor, assetUrls?: {
4577
4582
  [key: string]: string | undefined;
4578
4583
  } | undefined);
4579
- private readonly shapeFontFacesCache;
4580
- private readonly shapeFontLoadStateCache;
4584
+ dispose(): void;
4585
+ private shapeFontFacesCache;
4586
+ private shapeFontLoadStateCache;
4581
4587
  getShapeFontFaces(shape: TLShape | TLShapeId): TLFontFace[];
4582
4588
  trackFontsForShape(shape: TLShape | TLShapeId): void;
4583
4589
  loadRequiredFontsForCurrentPage(limit?: number): Promise<void>;
@@ -5550,6 +5556,7 @@ export declare class OverlayManager {
5550
5556
  constructor(editor: Editor);
5551
5557
  /* Excluded from this release type: _overlayUtils */
5552
5558
  /* Excluded from this release type: registerUtil */
5559
+ dispose(): void;
5553
5560
  /**
5554
5561
  * Get an overlay util by type string, overlay instance, or by passing
5555
5562
  * a util class as a generic parameter for type-safe lookup.
@@ -5721,6 +5728,10 @@ export declare abstract class OverlayUtil<T extends TLOverlay = TLOverlay> {
5721
5728
  * at minimap scale (e.g. brushes, collaborator cursors) should opt in.
5722
5729
  */
5723
5730
  renderMinimap(_ctx: CanvasRenderingContext2D, _overlays: T[], _zoom: number): void;
5731
+ /**
5732
+ * Clean up any resources held by this overlay util.
5733
+ */
5734
+ dispose(): void;
5724
5735
  }
5725
5736
 
5726
5737
  /**
@@ -8021,6 +8032,13 @@ export declare interface TldrawOptions {
8021
8032
  * The distance (in screen pixels) at which shapes snap to guides and other shapes.
8022
8033
  */
8023
8034
  readonly snapThreshold: number;
8035
+ /**
8036
+ * Whether locked shapes can be selected with a left click. When false (default), left-clicking
8037
+ * a locked shape is treated as a click on the canvas — only right-click selects it. When true,
8038
+ * locked shapes can be selected via left click and included in brush and scribble selections,
8039
+ * but the editor's lock guards still prevent moving, resizing, editing, or deleting them.
8040
+ */
8041
+ readonly selectLockedShapes: boolean;
8024
8042
  /**
8025
8043
  * Options for the editor's camera. These are the initial camera options.
8026
8044
  * Use {@link Editor.setCameraOptions} to update camera options at runtime.
@@ -8052,6 +8070,17 @@ export declare interface TldrawOptions {
8052
8070
  * viewport's page dimensions regardless of overview zoom changes.
8053
8071
  */
8054
8072
  readonly quickZoomPreservesScreenBounds: boolean;
8073
+ /**
8074
+ * Whether video shapes are allowed to autoplay. When `true` (the default), each
8075
+ * video respects its own `shape.props.autoplay` value. When `false`, no video
8076
+ * autoplays regardless of its shape prop — useful for host apps that want to
8077
+ * disable autoplay across the board, including for pasted or restored shapes.
8078
+ *
8079
+ * This does not change the per-shape `autoplay` prop on new video shapes — that
8080
+ * default is controlled by `VideoShapeOptions.autoplay` on `VideoShapeUtil`. The
8081
+ * `prefers-reduced-motion` media query continues to suppress autoplay independently.
8082
+ */
8083
+ readonly allowVideoAutoplay: boolean;
8055
8084
  /**
8056
8085
  * Called before content is written to the clipboard during a copy or cut operation.
8057
8086
  * Receives the serialized content (shapes, bindings, assets) and can filter or transform
@@ -9629,6 +9658,7 @@ export declare function usePassThroughWheelEvents(ref: RefObject<HTMLElement | n
9629
9658
 
9630
9659
  /**
9631
9660
  * Reactive list of peer user IDs for collaborators currently shown in the UI.
9661
+ * This list includes user ids who are not on the user's current page.
9632
9662
  * Mirrors {@link Editor.getVisibleCollaborators} — peers fade out as they
9633
9663
  * transition to idle/inactive, without requiring a manual re-render.
9634
9664
  *
package/dist-cjs/index.js CHANGED
@@ -380,7 +380,7 @@ var import_uniq = require("./lib/utils/uniq");
380
380
  var import_defaultThemes2 = require("./lib/editor/managers/ThemeManager/defaultThemes");
381
381
  (0, import_utils.registerTldrawLibraryVersion)(
382
382
  "@tldraw/editor",
383
- "5.1.0-canary.aec92a79e54b",
383
+ "5.1.0-canary.bb89313f32d2",
384
384
  "cjs"
385
385
  );
386
386
  //# sourceMappingURL=index.js.map
@@ -81,28 +81,41 @@ function DefaultCanvas({ className }) {
81
81
  },
82
82
  [editor]
83
83
  );
84
- const rMemoizedStuff = (0, import_react.useRef)({ lodDisableTextOutline: false, allowTextOutline: true });
84
+ const rMemoizedStuff = (0, import_react.useRef)({ lodDisableTextOutline: false, canUpdateTextOutline: true });
85
+ (0, import_state_react.useQuickReactor)(
86
+ "set text outline",
87
+ function setTextOutline() {
88
+ if (rMemoizedStuff.current.canUpdateTextOutline) {
89
+ if (import_environment.tlenv.isSafari) {
90
+ container.style.setProperty("--tl-text-outline", "none");
91
+ rMemoizedStuff.current.canUpdateTextOutline = false;
92
+ } else {
93
+ const efficientZoom = editor.getEfficientZoomLevel();
94
+ const lodDisableTextOutline = efficientZoom < editor.options.textShadowLod;
95
+ if (lodDisableTextOutline !== rMemoizedStuff.current.lodDisableTextOutline) {
96
+ container.style.setProperty(
97
+ "--tl-text-outline",
98
+ lodDisableTextOutline ? "none" : `var(--tl-text-outline-reference)`
99
+ );
100
+ }
101
+ rMemoizedStuff.current.lodDisableTextOutline = lodDisableTextOutline;
102
+ }
103
+ }
104
+ },
105
+ [editor, container]
106
+ );
85
107
  (0, import_state_react.useQuickReactor)(
86
108
  "position layers",
87
109
  function positionLayersWhenCameraMoves() {
88
110
  const { x, y, z } = editor.getCamera();
89
- if (rMemoizedStuff.current.allowTextOutline && import_environment.tlenv.isSafari) {
90
- container.style.setProperty("--tl-text-outline", "none");
91
- rMemoizedStuff.current.allowTextOutline = false;
92
- }
93
- if (rMemoizedStuff.current.allowTextOutline && z < editor.options.textShadowLod !== rMemoizedStuff.current.lodDisableTextOutline) {
94
- const lodDisableTextOutline = z < editor.options.textShadowLod;
95
- container.style.setProperty(
96
- "--tl-text-outline",
97
- lodDisableTextOutline ? "none" : `var(--tl-text-outline-reference)`
98
- );
99
- rMemoizedStuff.current.lodDisableTextOutline = lodDisableTextOutline;
100
- }
101
111
  const offset = z >= 1 ? (0, import_utils.modulate)(z, [1, 8], [0.125, 0.5], true) : (0, import_utils.modulate)(z, [0.1, 1], [-2, 0.125], true);
102
- const transform = `scale(${(0, import_utils2.toDomPrecision)(z)}) translate(${(0, import_utils2.toDomPrecision)(
103
- x + offset
104
- )}px,${(0, import_utils2.toDomPrecision)(y + offset)}px)`;
105
- (0, import_dom.setStyleProperty)(rHtmlLayer.current, "transform", transform);
112
+ (0, import_dom.setStyleProperty)(
113
+ rHtmlLayer.current,
114
+ "transform",
115
+ `scale(${(0, import_utils2.toDomPrecision)(z)}) translate(${(0, import_utils2.toDomPrecision)(
116
+ x + offset
117
+ )}px,${(0, import_utils2.toDomPrecision)(y + offset)}px)`
118
+ );
106
119
  },
107
120
  [editor, container]
108
121
  );
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/components/default-components/DefaultCanvas.tsx"],
4
- "sourcesContent": ["import { react } from '@tldraw/state'\nimport { useQuickReactor, useValue } from '@tldraw/state-react'\nimport { TLShapeId } from '@tldraw/tlschema'\nimport { modulate, objectMapValues } from '@tldraw/utils'\nimport classNames from 'classnames'\nimport { Fragment, JSX, useEffect, useRef, useState } from 'react'\nimport { tlenv } from '../../globals/environment'\nimport { useEditorComponents } from '../../hooks/EditorComponentsContext'\nimport { useCanvasEvents } from '../../hooks/useCanvasEvents'\nimport { useCoarsePointer } from '../../hooks/useCoarsePointer'\nimport { useContainer } from '../../hooks/useContainer'\nimport { useDocumentEvents } from '../../hooks/useDocumentEvents'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useFixSafariDoubleTapZoomPencilEvents } from '../../hooks/useFixSafariDoubleTapZoomPencilEvents'\nimport { useGestureEvents } from '../../hooks/useGestureEvents'\nimport { useScreenBounds } from '../../hooks/useScreenBounds'\nimport { ShapeCullingProvider, useShapeCulling } from '../../hooks/useShapeCulling'\nimport { Box } from '../../primitives/Box'\nimport { toDomPrecision } from '../../primitives/utils'\nimport { debugFlags } from '../../utils/debug-flags'\nimport { setStyleProperty } from '../../utils/dom'\nimport { MenuClickCapture } from '../MenuClickCapture'\nimport { Shape } from '../Shape'\nimport { CanvasOverlays } from './CanvasOverlays'\n\n/** @public */\nexport interface TLCanvasComponentProps {\n\tclassName?: string\n}\n\n/** @public @react */\nexport function DefaultCanvas({ className }: TLCanvasComponentProps) {\n\tconst editor = useEditor()\n\n\tconst { SelectionBackground, Background, SvgDefs } = useEditorComponents()\n\n\tconst rCanvas = useRef<HTMLDivElement>(null)\n\tconst rHtmlLayer = useRef<HTMLDivElement>(null)\n\tconst container = useContainer()\n\n\tuseScreenBounds(rCanvas)\n\tuseDocumentEvents()\n\tuseCoarsePointer()\n\n\tuseGestureEvents(rCanvas)\n\tuseFixSafariDoubleTapZoomPencilEvents(rCanvas)\n\n\tuseQuickReactor(\n\t\t'update canvas state data attributes',\n\t\t() => {\n\t\t\tconst canvas = rCanvas.current\n\t\t\tif (!canvas) return\n\n\t\t\tcanvas.setAttribute(\n\t\t\t\t'data-iseditinganything',\n\t\t\t\teditor.getEditingShapeId() === null ? 'false' : 'true'\n\t\t\t)\n\t\t\tcanvas.setAttribute(\n\t\t\t\t'data-isselectinganything',\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ? 'false' : 'true'\n\t\t\t)\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst rMemoizedStuff = useRef({ lodDisableTextOutline: false, allowTextOutline: true })\n\n\tuseQuickReactor(\n\t\t'position layers',\n\t\tfunction positionLayersWhenCameraMoves() {\n\t\t\tconst { x, y, z } = editor.getCamera()\n\n\t\t\t// This should only run once on first load\n\t\t\tif (rMemoizedStuff.current.allowTextOutline && tlenv.isSafari) {\n\t\t\t\tcontainer.style.setProperty('--tl-text-outline', 'none')\n\t\t\t\trMemoizedStuff.current.allowTextOutline = false\n\t\t\t}\n\n\t\t\t// And this should only run if we're not in Safari;\n\t\t\t// If we're below the lod distance for text shadows, turn them off\n\t\t\tif (\n\t\t\t\trMemoizedStuff.current.allowTextOutline &&\n\t\t\t\tz < editor.options.textShadowLod !== rMemoizedStuff.current.lodDisableTextOutline\n\t\t\t) {\n\t\t\t\tconst lodDisableTextOutline = z < editor.options.textShadowLod\n\t\t\t\tcontainer.style.setProperty(\n\t\t\t\t\t'--tl-text-outline',\n\t\t\t\t\tlodDisableTextOutline ? 'none' : `var(--tl-text-outline-reference)`\n\t\t\t\t)\n\t\t\t\trMemoizedStuff.current.lodDisableTextOutline = lodDisableTextOutline\n\t\t\t}\n\n\t\t\t// Because the html container has a width/height of 1px, we\n\t\t\t// need to create a small offset when zoomed to ensure that\n\t\t\t// the html container and svg container are lined up exactly.\n\t\t\tconst offset =\n\t\t\t\tz >= 1 ? modulate(z, [1, 8], [0.125, 0.5], true) : modulate(z, [0.1, 1], [-2, 0.125], true)\n\n\t\t\tconst transform = `scale(${toDomPrecision(z)}) translate(${toDomPrecision(\n\t\t\t\tx + offset\n\t\t\t)}px,${toDomPrecision(y + offset)}px)`\n\n\t\t\tsetStyleProperty(rHtmlLayer.current, 'transform', transform)\n\t\t},\n\t\t[editor, container]\n\t)\n\n\tconst events = useCanvasEvents()\n\n\tconst shapeSvgDefs = useValue(\n\t\t'shapeSvgDefs',\n\t\t() => {\n\t\t\tconst shapeSvgDefsByKey = new Map<string, JSX.Element>()\n\t\t\tfor (const util of objectMapValues(editor.shapeUtils)) {\n\t\t\t\tif (!util) return\n\t\t\t\tconst defs = util.getCanvasSvgDefs()\n\t\t\t\tfor (const { key, component: Component } of defs) {\n\t\t\t\t\tif (shapeSvgDefsByKey.has(key)) continue\n\t\t\t\t\tshapeSvgDefsByKey.set(key, <Component key={key} />)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [...shapeSvgDefsByKey.values()]\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst hideShapes = useValue('debug_shapes', () => debugFlags.hideShapes.get(), [debugFlags])\n\n\tconst isGridMode = useValue('isGridMode', () => editor.getInstanceState().isGridMode, [editor])\n\tconst { Grid } = useEditorComponents()\n\n\treturn (\n\t\t<>\n\t\t\t<div\n\t\t\t\tref={rCanvas}\n\t\t\t\tdraggable={false}\n\t\t\t\tclassName={classNames('tl-canvas', className)}\n\t\t\t\tdata-testid=\"canvas\"\n\t\t\t\t{...events}\n\t\t\t>\n\t\t\t\t<svg className=\"tl-svg-context\" aria-hidden=\"true\">\n\t\t\t\t\t<defs>\n\t\t\t\t\t\t{shapeSvgDefs}\n\t\t\t\t\t\t{SvgDefs && <SvgDefs />}\n\t\t\t\t\t</defs>\n\t\t\t\t</svg>\n\t\t\t\t{Background && (\n\t\t\t\t\t<div className=\"tl-background__wrapper\">\n\t\t\t\t\t\t<Background />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{isGridMode && Grid && <GridWrapper />}\n\t\t\t\t<div ref={rHtmlLayer} className=\"tl-html-layer tl-shapes\" draggable={false}>\n\t\t\t\t\t<OnTheCanvasWrapper />\n\t\t\t\t\t{SelectionBackground && <SelectionBackgroundWrapper />}\n\t\t\t\t\t{hideShapes ? null : <ShapesLayer canvasRef={rCanvas} />}\n\t\t\t\t</div>\n\t\t\t\t<CanvasOverlays />\n\t\t\t\t<MovingCameraHitTestBlocker />\n\t\t\t</div>\n\t\t\t<InFrontOfTheCanvasWrapper />\n\t\t\t<MenuClickCapture />\n\t\t</>\n\t)\n}\n\nfunction InFrontOfTheCanvasWrapper() {\n\tconst editor = useEditor()\n\tconst { InFrontOfTheCanvas } = useEditorComponents()\n\tif (!InFrontOfTheCanvas) return null\n\treturn (\n\t\t<div\n\t\t\tclassName=\"tl-canvas__in-front\"\n\t\t\tonPointerDown={editor.markEventAsHandled}\n\t\t\tonPointerUp={editor.markEventAsHandled}\n\t\t\tonTouchStart={editor.markEventAsHandled}\n\t\t\tonTouchEnd={editor.markEventAsHandled}\n\t\t>\n\t\t\t<InFrontOfTheCanvas />\n\t\t</div>\n\t)\n}\n\nfunction GridWrapper() {\n\tconst editor = useEditor()\n\tconst gridSize = useValue('gridSize', () => editor.getDocumentSettings().gridSize, [editor])\n\tconst { x, y, z } = useValue('camera', () => editor.getCamera(), [editor])\n\tconst { Grid } = useEditorComponents()\n\n\tif (!Grid) return null\n\n\treturn <Grid x={x} y={y} z={z} size={gridSize} />\n}\n\nfunction ShapesLayer({ canvasRef }: { canvasRef: { readonly current: HTMLDivElement | null } }) {\n\tconst editor = useEditor()\n\tconst debugSvg = useValue('debug svg', () => debugFlags.debugSvg.get(), [debugFlags])\n\tconst renderingShapes = useValue('rendering shapes', () => editor.getRenderingShapes(), [editor])\n\n\treturn (\n\t\t<ShapeCullingProvider>\n\t\t\t{renderingShapes.map((result) =>\n\t\t\t\tdebugSvg ? (\n\t\t\t\t\t<Fragment key={result.id + '_fragment'}>\n\t\t\t\t\t\t<Shape {...result} />\n\t\t\t\t\t\t<DebugSvgCopy id={result.id} mode=\"iframe\" />\n\t\t\t\t\t</Fragment>\n\t\t\t\t) : (\n\t\t\t\t\t<Shape key={result.id + '_shape'} {...result} />\n\t\t\t\t)\n\t\t\t)}\n\t\t\t<CullingController />\n\t\t\t{tlenv.isSafari && <ReflowIfNeeded canvasRef={canvasRef} />}\n\t\t</ShapeCullingProvider>\n\t)\n}\nfunction ReflowIfNeeded({ canvasRef }: { canvasRef: { readonly current: HTMLDivElement | null } }) {\n\tconst editor = useEditor()\n\tconst culledShapesRef = useRef<Set<TLShapeId>>(new Set())\n\tuseQuickReactor(\n\t\t'reflow for culled shapes',\n\t\t() => {\n\t\t\tconst culledShapes = editor.getCulledShapes()\n\t\t\tif (culledShapesRef.current === culledShapes) return\n\n\t\t\tculledShapesRef.current = culledShapes\n\t\t\tconst canvas = canvasRef.current\n\t\t\tif (!canvas) return\n\t\t\t// This causes a reflow\n\t\t\t// https://gist.github.com/paulirish/5d52fb081b3570c81e3a\n\t\t\tconst _height = canvas.offsetHeight\n\t\t},\n\t\t[editor, canvasRef]\n\t)\n\treturn null\n}\n\n/**\n * Centralized culling controller that updates shape container visibility.\n * This single reactor replaces per-shape subscriptions for O(1) instead of O(N) subscriptions.\n */\nfunction CullingController() {\n\tconst editor = useEditor()\n\tconst { updateCulling } = useShapeCulling()\n\n\tuseQuickReactor(\n\t\t'update shape culling',\n\t\t() => {\n\t\t\tconst culledShapes = editor.getCulledShapes()\n\t\t\tupdateCulling(culledShapes)\n\t\t},\n\t\t[editor, updateCulling]\n\t)\n\n\treturn null\n}\n\nfunction DebugSvgCopy({ id, mode }: { id: TLShapeId; mode: 'img' | 'iframe' }) {\n\tconst editor = useEditor()\n\n\tconst [image, setImage] = useState<{ src: string; bounds: Box } | null>(null)\n\n\tconst isInRoot = useValue(\n\t\t'is in root',\n\t\t() => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\treturn shape?.parentId === editor.getCurrentPageId()\n\t\t},\n\t\t[editor, id]\n\t)\n\n\tuseEffect(() => {\n\t\tif (!isInRoot) return\n\n\t\tlet latest = null\n\t\tconst unsubscribe = react('shape to svg', async () => {\n\t\t\tconst renderId = Math.random()\n\t\t\tlatest = renderId\n\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tconst isSingleFrame = !!shape && editor.isShapeFrameLike(shape)\n\t\t\tconst padding = isSingleFrame ? 0 : 10\n\t\t\tlet bounds = editor.getShapePageBounds(id)\n\t\t\tif (!bounds) return\n\t\t\tbounds = bounds.clone().expandBy(padding)\n\n\t\t\tconst result = await editor.getSvgString([id], { padding })\n\n\t\t\tif (latest !== renderId || !result) return\n\n\t\t\tconst svgDataUrl = `data:image/svg+xml;utf8,${encodeURIComponent(result.svg)}`\n\t\t\tsetImage({ src: svgDataUrl, bounds })\n\t\t})\n\n\t\treturn () => {\n\t\t\tlatest = null\n\t\t\tunsubscribe()\n\t\t}\n\t}, [editor, id, isInRoot])\n\n\tif (!isInRoot || !image) return null\n\n\tif (mode === 'iframe') {\n\t\treturn (\n\t\t\t<iframe\n\t\t\t\tsrc={image.src}\n\t\t\t\twidth={image.bounds.width}\n\t\t\t\theight={image.bounds.height}\n\t\t\t\treferrerPolicy=\"no-referrer\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\tborder: 'none',\n\t\t\t\t\ttransform: `translate(${image.bounds.x}px, ${image.bounds.maxY + 12}px)`,\n\t\t\t\t\toutline: '1px solid black',\n\t\t\t\t\tmaxWidth: 'none',\n\t\t\t\t}}\n\t\t\t/>\n\t\t)\n\t}\n\treturn (\n\t\t<img\n\t\t\tsrc={image.src}\n\t\t\twidth={image.bounds.width}\n\t\t\theight={image.bounds.height}\n\t\t\treferrerPolicy=\"no-referrer\"\n\t\t\tstyle={{\n\t\t\t\tposition: 'absolute',\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\ttransform: `translate(${image.bounds.x}px, ${image.bounds.maxY + 12}px)`,\n\t\t\t\toutline: '1px solid black',\n\t\t\t\tmaxWidth: 'none',\n\t\t\t}}\n\t\t/>\n\t)\n}\n\nfunction SelectionBackgroundWrapper() {\n\tconst editor = useEditor()\n\tconst selectionRotation = useValue('selection rotation', () => editor.getSelectionRotation(), [\n\t\teditor,\n\t])\n\tconst selectionBounds = useValue(\n\t\t'selection bounds',\n\t\t() => editor.getSelectionRotatedPageBounds(),\n\t\t[editor]\n\t)\n\tconst { SelectionBackground } = useEditorComponents()\n\tif (!selectionBounds || !SelectionBackground) return null\n\treturn <SelectionBackground bounds={selectionBounds} rotation={selectionRotation} />\n}\n\nfunction OnTheCanvasWrapper() {\n\tconst { OnTheCanvas } = useEditorComponents()\n\tif (!OnTheCanvas) return null\n\treturn <OnTheCanvas />\n}\n\nfunction MovingCameraHitTestBlocker() {\n\tconst editor = useEditor()\n\tconst cameraState = useValue('camera state', () => editor.getCameraState(), [editor])\n\n\treturn (\n\t\t<div\n\t\t\tclassName={classNames('tl-hit-test-blocker', {\n\t\t\t\t'tl-hit-test-blocker__hidden': cameraState === 'idle',\n\t\t\t})}\n\t\t/>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { react } from '@tldraw/state'\nimport { useQuickReactor, useValue } from '@tldraw/state-react'\nimport { TLShapeId } from '@tldraw/tlschema'\nimport { modulate, objectMapValues } from '@tldraw/utils'\nimport classNames from 'classnames'\nimport { Fragment, JSX, useEffect, useRef, useState } from 'react'\nimport { tlenv } from '../../globals/environment'\nimport { useEditorComponents } from '../../hooks/EditorComponentsContext'\nimport { useCanvasEvents } from '../../hooks/useCanvasEvents'\nimport { useCoarsePointer } from '../../hooks/useCoarsePointer'\nimport { useContainer } from '../../hooks/useContainer'\nimport { useDocumentEvents } from '../../hooks/useDocumentEvents'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useFixSafariDoubleTapZoomPencilEvents } from '../../hooks/useFixSafariDoubleTapZoomPencilEvents'\nimport { useGestureEvents } from '../../hooks/useGestureEvents'\nimport { useScreenBounds } from '../../hooks/useScreenBounds'\nimport { ShapeCullingProvider, useShapeCulling } from '../../hooks/useShapeCulling'\nimport { Box } from '../../primitives/Box'\nimport { toDomPrecision } from '../../primitives/utils'\nimport { debugFlags } from '../../utils/debug-flags'\nimport { setStyleProperty } from '../../utils/dom'\nimport { MenuClickCapture } from '../MenuClickCapture'\nimport { Shape } from '../Shape'\nimport { CanvasOverlays } from './CanvasOverlays'\n\n/** @public */\nexport interface TLCanvasComponentProps {\n\tclassName?: string\n}\n\n/** @public @react */\nexport function DefaultCanvas({ className }: TLCanvasComponentProps) {\n\tconst editor = useEditor()\n\n\tconst { SelectionBackground, Background, SvgDefs } = useEditorComponents()\n\n\tconst rCanvas = useRef<HTMLDivElement>(null)\n\tconst rHtmlLayer = useRef<HTMLDivElement>(null)\n\tconst container = useContainer()\n\n\tuseScreenBounds(rCanvas)\n\tuseDocumentEvents()\n\tuseCoarsePointer()\n\n\tuseGestureEvents(rCanvas)\n\tuseFixSafariDoubleTapZoomPencilEvents(rCanvas)\n\n\tuseQuickReactor(\n\t\t'update canvas state data attributes',\n\t\t() => {\n\t\t\tconst canvas = rCanvas.current\n\t\t\tif (!canvas) return\n\n\t\t\tcanvas.setAttribute(\n\t\t\t\t'data-iseditinganything',\n\t\t\t\teditor.getEditingShapeId() === null ? 'false' : 'true'\n\t\t\t)\n\t\t\tcanvas.setAttribute(\n\t\t\t\t'data-isselectinganything',\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ? 'false' : 'true'\n\t\t\t)\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst rMemoizedStuff = useRef({ lodDisableTextOutline: false, canUpdateTextOutline: true })\n\n\tuseQuickReactor(\n\t\t'set text outline',\n\t\tfunction setTextOutline() {\n\t\t\tif (rMemoizedStuff.current.canUpdateTextOutline) {\n\t\t\t\tif (tlenv.isSafari) {\n\t\t\t\t\t// We don't allow text outlines on safari for performance reasons\n\t\t\t\t\tcontainer.style.setProperty('--tl-text-outline', 'none')\n\t\t\t\t\trMemoizedStuff.current.canUpdateTextOutline = false // will prevent this check in the future\n\t\t\t\t} else {\n\t\t\t\t\tconst efficientZoom = editor.getEfficientZoomLevel()\n\t\t\t\t\t// If we're zoomed way out, and have this option enabled, then we hide text outline\n\t\t\t\t\tconst lodDisableTextOutline = efficientZoom < editor.options.textShadowLod\n\t\t\t\t\t// Skip the style update if the property is the same as it was before\n\t\t\t\t\tif (lodDisableTextOutline !== rMemoizedStuff.current.lodDisableTextOutline) {\n\t\t\t\t\t\tcontainer.style.setProperty(\n\t\t\t\t\t\t\t'--tl-text-outline',\n\t\t\t\t\t\t\tlodDisableTextOutline ? 'none' : `var(--tl-text-outline-reference)`\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\trMemoizedStuff.current.lodDisableTextOutline = lodDisableTextOutline\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, container]\n\t)\n\n\tuseQuickReactor(\n\t\t'position layers',\n\t\tfunction positionLayersWhenCameraMoves() {\n\t\t\tconst { x, y, z } = editor.getCamera()\n\n\t\t\t// Because the html container has a width/height of 1px, we\n\t\t\t// need to create a small offset when zoomed to ensure that\n\t\t\t// the html container and svg container are lined up exactly.\n\t\t\tconst offset =\n\t\t\t\tz >= 1 ? modulate(z, [1, 8], [0.125, 0.5], true) : modulate(z, [0.1, 1], [-2, 0.125], true)\n\n\t\t\tsetStyleProperty(\n\t\t\t\trHtmlLayer.current,\n\t\t\t\t'transform',\n\t\t\t\t`scale(${toDomPrecision(z)}) translate(${toDomPrecision(\n\t\t\t\t\tx + offset\n\t\t\t\t)}px,${toDomPrecision(y + offset)}px)`\n\t\t\t)\n\t\t},\n\t\t[editor, container]\n\t)\n\n\tconst events = useCanvasEvents()\n\n\tconst shapeSvgDefs = useValue(\n\t\t'shapeSvgDefs',\n\t\t() => {\n\t\t\tconst shapeSvgDefsByKey = new Map<string, JSX.Element>()\n\t\t\tfor (const util of objectMapValues(editor.shapeUtils)) {\n\t\t\t\tif (!util) return\n\t\t\t\tconst defs = util.getCanvasSvgDefs()\n\t\t\t\tfor (const { key, component: Component } of defs) {\n\t\t\t\t\tif (shapeSvgDefsByKey.has(key)) continue\n\t\t\t\t\tshapeSvgDefsByKey.set(key, <Component key={key} />)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [...shapeSvgDefsByKey.values()]\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst hideShapes = useValue('debug_shapes', () => debugFlags.hideShapes.get(), [debugFlags])\n\n\tconst isGridMode = useValue('isGridMode', () => editor.getInstanceState().isGridMode, [editor])\n\tconst { Grid } = useEditorComponents()\n\n\treturn (\n\t\t<>\n\t\t\t<div\n\t\t\t\tref={rCanvas}\n\t\t\t\tdraggable={false}\n\t\t\t\tclassName={classNames('tl-canvas', className)}\n\t\t\t\tdata-testid=\"canvas\"\n\t\t\t\t{...events}\n\t\t\t>\n\t\t\t\t<svg className=\"tl-svg-context\" aria-hidden=\"true\">\n\t\t\t\t\t<defs>\n\t\t\t\t\t\t{shapeSvgDefs}\n\t\t\t\t\t\t{SvgDefs && <SvgDefs />}\n\t\t\t\t\t</defs>\n\t\t\t\t</svg>\n\t\t\t\t{Background && (\n\t\t\t\t\t<div className=\"tl-background__wrapper\">\n\t\t\t\t\t\t<Background />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{isGridMode && Grid && <GridWrapper />}\n\t\t\t\t<div ref={rHtmlLayer} className=\"tl-html-layer tl-shapes\" draggable={false}>\n\t\t\t\t\t<OnTheCanvasWrapper />\n\t\t\t\t\t{SelectionBackground && <SelectionBackgroundWrapper />}\n\t\t\t\t\t{hideShapes ? null : <ShapesLayer canvasRef={rCanvas} />}\n\t\t\t\t</div>\n\t\t\t\t<CanvasOverlays />\n\t\t\t\t<MovingCameraHitTestBlocker />\n\t\t\t</div>\n\t\t\t<InFrontOfTheCanvasWrapper />\n\t\t\t<MenuClickCapture />\n\t\t</>\n\t)\n}\n\nfunction InFrontOfTheCanvasWrapper() {\n\tconst editor = useEditor()\n\tconst { InFrontOfTheCanvas } = useEditorComponents()\n\tif (!InFrontOfTheCanvas) return null\n\treturn (\n\t\t<div\n\t\t\tclassName=\"tl-canvas__in-front\"\n\t\t\tonPointerDown={editor.markEventAsHandled}\n\t\t\tonPointerUp={editor.markEventAsHandled}\n\t\t\tonTouchStart={editor.markEventAsHandled}\n\t\t\tonTouchEnd={editor.markEventAsHandled}\n\t\t>\n\t\t\t<InFrontOfTheCanvas />\n\t\t</div>\n\t)\n}\n\nfunction GridWrapper() {\n\tconst editor = useEditor()\n\tconst gridSize = useValue('gridSize', () => editor.getDocumentSettings().gridSize, [editor])\n\tconst { x, y, z } = useValue('camera', () => editor.getCamera(), [editor])\n\tconst { Grid } = useEditorComponents()\n\n\tif (!Grid) return null\n\n\treturn <Grid x={x} y={y} z={z} size={gridSize} />\n}\n\nfunction ShapesLayer({ canvasRef }: { canvasRef: { readonly current: HTMLDivElement | null } }) {\n\tconst editor = useEditor()\n\tconst debugSvg = useValue('debug svg', () => debugFlags.debugSvg.get(), [debugFlags])\n\tconst renderingShapes = useValue('rendering shapes', () => editor.getRenderingShapes(), [editor])\n\n\treturn (\n\t\t<ShapeCullingProvider>\n\t\t\t{renderingShapes.map((result) =>\n\t\t\t\tdebugSvg ? (\n\t\t\t\t\t<Fragment key={result.id + '_fragment'}>\n\t\t\t\t\t\t<Shape {...result} />\n\t\t\t\t\t\t<DebugSvgCopy id={result.id} mode=\"iframe\" />\n\t\t\t\t\t</Fragment>\n\t\t\t\t) : (\n\t\t\t\t\t<Shape key={result.id + '_shape'} {...result} />\n\t\t\t\t)\n\t\t\t)}\n\t\t\t<CullingController />\n\t\t\t{tlenv.isSafari && <ReflowIfNeeded canvasRef={canvasRef} />}\n\t\t</ShapeCullingProvider>\n\t)\n}\nfunction ReflowIfNeeded({ canvasRef }: { canvasRef: { readonly current: HTMLDivElement | null } }) {\n\tconst editor = useEditor()\n\tconst culledShapesRef = useRef<Set<TLShapeId>>(new Set())\n\tuseQuickReactor(\n\t\t'reflow for culled shapes',\n\t\t() => {\n\t\t\tconst culledShapes = editor.getCulledShapes()\n\t\t\tif (culledShapesRef.current === culledShapes) return\n\n\t\t\tculledShapesRef.current = culledShapes\n\t\t\tconst canvas = canvasRef.current\n\t\t\tif (!canvas) return\n\t\t\t// This causes a reflow\n\t\t\t// https://gist.github.com/paulirish/5d52fb081b3570c81e3a\n\t\t\tconst _height = canvas.offsetHeight\n\t\t},\n\t\t[editor, canvasRef]\n\t)\n\treturn null\n}\n\n/**\n * Centralized culling controller that updates shape container visibility.\n * This single reactor replaces per-shape subscriptions for O(1) instead of O(N) subscriptions.\n */\nfunction CullingController() {\n\tconst editor = useEditor()\n\tconst { updateCulling } = useShapeCulling()\n\n\tuseQuickReactor(\n\t\t'update shape culling',\n\t\t() => {\n\t\t\tconst culledShapes = editor.getCulledShapes()\n\t\t\tupdateCulling(culledShapes)\n\t\t},\n\t\t[editor, updateCulling]\n\t)\n\n\treturn null\n}\n\nfunction DebugSvgCopy({ id, mode }: { id: TLShapeId; mode: 'img' | 'iframe' }) {\n\tconst editor = useEditor()\n\n\tconst [image, setImage] = useState<{ src: string; bounds: Box } | null>(null)\n\n\tconst isInRoot = useValue(\n\t\t'is in root',\n\t\t() => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\treturn shape?.parentId === editor.getCurrentPageId()\n\t\t},\n\t\t[editor, id]\n\t)\n\n\tuseEffect(() => {\n\t\tif (!isInRoot) return\n\n\t\tlet latest = null\n\t\tconst unsubscribe = react('shape to svg', async () => {\n\t\t\tconst renderId = Math.random()\n\t\t\tlatest = renderId\n\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tconst isSingleFrame = !!shape && editor.isShapeFrameLike(shape)\n\t\t\tconst padding = isSingleFrame ? 0 : 10\n\t\t\tlet bounds = editor.getShapePageBounds(id)\n\t\t\tif (!bounds) return\n\t\t\tbounds = bounds.clone().expandBy(padding)\n\n\t\t\tconst result = await editor.getSvgString([id], { padding })\n\n\t\t\tif (latest !== renderId || !result) return\n\n\t\t\tconst svgDataUrl = `data:image/svg+xml;utf8,${encodeURIComponent(result.svg)}`\n\t\t\tsetImage({ src: svgDataUrl, bounds })\n\t\t})\n\n\t\treturn () => {\n\t\t\tlatest = null\n\t\t\tunsubscribe()\n\t\t}\n\t}, [editor, id, isInRoot])\n\n\tif (!isInRoot || !image) return null\n\n\tif (mode === 'iframe') {\n\t\treturn (\n\t\t\t<iframe\n\t\t\t\tsrc={image.src}\n\t\t\t\twidth={image.bounds.width}\n\t\t\t\theight={image.bounds.height}\n\t\t\t\treferrerPolicy=\"no-referrer\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\tborder: 'none',\n\t\t\t\t\ttransform: `translate(${image.bounds.x}px, ${image.bounds.maxY + 12}px)`,\n\t\t\t\t\toutline: '1px solid black',\n\t\t\t\t\tmaxWidth: 'none',\n\t\t\t\t}}\n\t\t\t/>\n\t\t)\n\t}\n\treturn (\n\t\t<img\n\t\t\tsrc={image.src}\n\t\t\twidth={image.bounds.width}\n\t\t\theight={image.bounds.height}\n\t\t\treferrerPolicy=\"no-referrer\"\n\t\t\tstyle={{\n\t\t\t\tposition: 'absolute',\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\ttransform: `translate(${image.bounds.x}px, ${image.bounds.maxY + 12}px)`,\n\t\t\t\toutline: '1px solid black',\n\t\t\t\tmaxWidth: 'none',\n\t\t\t}}\n\t\t/>\n\t)\n}\n\nfunction SelectionBackgroundWrapper() {\n\tconst editor = useEditor()\n\tconst selectionRotation = useValue('selection rotation', () => editor.getSelectionRotation(), [\n\t\teditor,\n\t])\n\tconst selectionBounds = useValue(\n\t\t'selection bounds',\n\t\t() => editor.getSelectionRotatedPageBounds(),\n\t\t[editor]\n\t)\n\tconst { SelectionBackground } = useEditorComponents()\n\tif (!selectionBounds || !SelectionBackground) return null\n\treturn <SelectionBackground bounds={selectionBounds} rotation={selectionRotation} />\n}\n\nfunction OnTheCanvasWrapper() {\n\tconst { OnTheCanvas } = useEditorComponents()\n\tif (!OnTheCanvas) return null\n\treturn <OnTheCanvas />\n}\n\nfunction MovingCameraHitTestBlocker() {\n\tconst editor = useEditor()\n\tconst cameraState = useValue('camera state', () => editor.getCameraState(), [editor])\n\n\treturn (\n\t\t<div\n\t\t\tclassName={classNames('tl-hit-test-blocker', {\n\t\t\t\t'tl-hit-test-blocker__hidden': cameraState === 'idle',\n\t\t\t})}\n\t\t/>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_utils", "classNames"]
7
7
  }
@@ -93,6 +93,7 @@ var import_TickManager = require("./managers/TickManager/TickManager");
93
93
  var import_UserPreferencesManager = require("./managers/UserPreferencesManager/UserPreferencesManager");
94
94
  var import_OverlayManager = require("./overlays/OverlayManager");
95
95
  var import_RootState = require("./tools/RootState");
96
+ const RENDERING_SHAPES_SORT_CACHE_THRESHOLD = 100;
96
97
  class Editor extends import_eventemitter3.default {
97
98
  id = (0, import_utils.uniqueId)();
98
99
  constructor({
@@ -158,6 +159,7 @@ class Editor extends import_eventemitter3.default {
158
159
  this._setCameraState("idle");
159
160
  });
160
161
  this.fonts = new import_FontManager.FontManager(this, fontAssetUrls);
162
+ this.disposables.add(() => this.fonts.dispose());
161
163
  this.inputs = new import_InputsManager.InputsManager(this);
162
164
  this.performance = new import_PerformanceManager.PerformanceManager(this);
163
165
  this.disposables.add(() => this.performance.dispose());
@@ -223,6 +225,7 @@ class Editor extends import_eventemitter3.default {
223
225
  }
224
226
  this.scribbles = new import_ScribbleManager.ScribbleManager(this);
225
227
  this.overlays = new import_OverlayManager.OverlayManager(this);
228
+ this.disposables.add(() => this.overlays.dispose());
226
229
  if (overlayUtilConstructors) {
227
230
  for (const Util of overlayUtilConstructors) {
228
231
  const util = new Util(this);
@@ -3385,8 +3388,34 @@ class Editor extends import_eventemitter3.default {
3385
3388
  }
3386
3389
  getRenderingShapes() {
3387
3390
  const renderingShapes = this.getUnorderedRenderingShapes(true);
3388
- return renderingShapes.sort(import_utils.sortById);
3391
+ if (renderingShapes.length <= RENDERING_SHAPES_SORT_CACHE_THRESHOLD) {
3392
+ this._renderingShapesSortCache = null;
3393
+ return renderingShapes.sort(import_utils.sortById);
3394
+ }
3395
+ const cache = this._renderingShapesSortCache;
3396
+ if (cache !== null && cache.size === renderingShapes.length) {
3397
+ const sorted = new Array(renderingShapes.length);
3398
+ let allMatched = true;
3399
+ for (let i = 0; i < renderingShapes.length; i++) {
3400
+ const entry = renderingShapes[i];
3401
+ const pos = cache.get(entry.id);
3402
+ if (pos === void 0) {
3403
+ allMatched = false;
3404
+ break;
3405
+ }
3406
+ sorted[pos] = entry;
3407
+ }
3408
+ if (allMatched) return sorted;
3409
+ }
3410
+ renderingShapes.sort(import_utils.sortById);
3411
+ const positionById = /* @__PURE__ */ new Map();
3412
+ for (let i = 0; i < renderingShapes.length; i++) {
3413
+ positionById.set(renderingShapes[i].id, i);
3414
+ }
3415
+ this._renderingShapesSortCache = positionById;
3416
+ return renderingShapes;
3389
3417
  }
3418
+ _renderingShapesSortCache = null;
3390
3419
  _getAllPagesQuery() {
3391
3420
  return this.store.query.records("page");
3392
3421
  }
@@ -7465,11 +7494,7 @@ class Editor extends import_eventemitter3.default {
7465
7494
  */
7466
7495
  blur({ blurContainer = true } = {}) {
7467
7496
  if (!this.getIsFocused()) return this;
7468
- if (blurContainer) {
7469
- this.focusManager.blur();
7470
- } else {
7471
- this.complete();
7472
- }
7497
+ this.focusManager.blur({ blurContainer });
7473
7498
  this.updateInstanceState({ isFocused: false });
7474
7499
  return this;
7475
7500
  }