@excalidraw/excalidraw 0.17.1-7500-ac247a0 → 0.17.1-b7babe5

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 (255) hide show
  1. package/CHANGELOG.md +56 -2
  2. package/dist/browser/dev/excalidraw-assets-dev/{chunk-2W5GQUR4.js → chunk-6NMK7JTV.js} +13 -6
  3. package/dist/browser/dev/excalidraw-assets-dev/chunk-6NMK7JTV.js.map +7 -0
  4. package/dist/browser/dev/excalidraw-assets-dev/chunk-CX3RATXT.js +20324 -0
  5. package/dist/browser/dev/excalidraw-assets-dev/chunk-CX3RATXT.js.map +7 -0
  6. package/dist/browser/dev/excalidraw-assets-dev/{en-OC6JWP3X.js → en-BZY7JRTM.js} +4 -2
  7. package/dist/browser/dev/excalidraw-assets-dev/{image-5TVMINCA.js → image-CVN3YKRW.js} +2 -4
  8. package/dist/browser/dev/excalidraw-assets-dev/image-LK4UNFRZ.css +6 -0
  9. package/dist/browser/dev/excalidraw-assets-dev/image-LK4UNFRZ.css.map +7 -0
  10. package/dist/browser/dev/excalidraw-assets-dev/roundRect-T5BX56ZF.js +161 -0
  11. package/dist/browser/dev/excalidraw-assets-dev/roundRect-T5BX56ZF.js.map +7 -0
  12. package/dist/browser/dev/index.css +189 -129
  13. package/dist/browser/dev/index.css.map +3 -3
  14. package/dist/browser/dev/index.js +34964 -37
  15. package/dist/browser/dev/index.js.map +4 -4
  16. package/dist/browser/prod/excalidraw-assets/chunk-VJAIK3AX.js +55 -0
  17. package/dist/browser/prod/excalidraw-assets/chunk-YYO5DFUW.js +11 -0
  18. package/dist/browser/prod/excalidraw-assets/en-O2YCQM2W.js +1 -0
  19. package/dist/browser/prod/excalidraw-assets/image-6FKY54X5.js +1 -0
  20. package/dist/browser/prod/excalidraw-assets/image-X66R2EM5.css +1 -0
  21. package/dist/browser/prod/excalidraw-assets/roundRect-2ACQK4DA.js +1 -0
  22. package/dist/browser/prod/index.css +1 -1
  23. package/dist/browser/prod/index.js +203 -1
  24. package/dist/{prod/en-RLIAOBCI.json → dev/en-EY7E2L5O.json} +10 -5
  25. package/dist/dev/index.css +189 -129
  26. package/dist/dev/index.css.map +3 -3
  27. package/dist/dev/index.js +38702 -39409
  28. package/dist/dev/index.js.map +4 -4
  29. package/dist/excalidraw/actions/actionAddToLibrary.d.ts +15 -15
  30. package/dist/excalidraw/actions/actionAlign.d.ts +6 -6
  31. package/dist/excalidraw/actions/actionAlign.js +2 -1
  32. package/dist/excalidraw/actions/actionBoundText.d.ts +10 -10
  33. package/dist/excalidraw/actions/actionBoundText.js +8 -8
  34. package/dist/excalidraw/actions/actionCanvas.d.ts +58 -58
  35. package/dist/excalidraw/actions/actionClipboard.d.ts +34 -34
  36. package/dist/excalidraw/actions/actionClipboard.js +9 -2
  37. package/dist/excalidraw/actions/actionDeleteSelected.d.ts +15 -15
  38. package/dist/excalidraw/actions/actionDeleteSelected.js +3 -2
  39. package/dist/excalidraw/actions/actionDistribute.d.ts +2 -2
  40. package/dist/excalidraw/actions/actionDistribute.js +1 -1
  41. package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +1 -1
  42. package/dist/excalidraw/actions/actionDuplicateSelection.js +4 -3
  43. package/dist/excalidraw/actions/actionElementLock.d.ts +10 -10
  44. package/dist/excalidraw/actions/actionExport.d.ts +43 -43
  45. package/dist/excalidraw/actions/actionExport.js +4 -4
  46. package/dist/excalidraw/actions/actionFinalize.d.ts +9 -9
  47. package/dist/excalidraw/actions/actionFinalize.js +7 -6
  48. package/dist/excalidraw/actions/actionFlip.d.ts +2 -2
  49. package/dist/excalidraw/actions/actionFlip.js +11 -11
  50. package/dist/excalidraw/actions/actionFrame.d.ts +16 -16
  51. package/dist/excalidraw/actions/actionFrame.js +1 -1
  52. package/dist/excalidraw/actions/actionGroup.d.ts +10 -10
  53. package/dist/excalidraw/actions/actionGroup.js +3 -2
  54. package/dist/excalidraw/actions/actionLinearEditor.d.ts +5 -5
  55. package/dist/excalidraw/actions/actionLinearEditor.js +1 -1
  56. package/dist/excalidraw/{element/Hyperlink.d.ts → actions/actionLink.d.ts} +29 -51
  57. package/dist/excalidraw/actions/actionLink.js +40 -0
  58. package/dist/excalidraw/actions/actionMenu.d.ts +13 -13
  59. package/dist/excalidraw/actions/actionNavigate.d.ts +10 -10
  60. package/dist/excalidraw/actions/actionNavigate.js +1 -1
  61. package/dist/excalidraw/actions/actionProperties.d.ts +77 -77
  62. package/dist/excalidraw/actions/actionProperties.js +32 -27
  63. package/dist/excalidraw/actions/actionSelectAll.d.ts +5 -5
  64. package/dist/excalidraw/actions/actionSelectAll.js +1 -1
  65. package/dist/excalidraw/actions/actionStyles.d.ts +7 -7
  66. package/dist/excalidraw/actions/actionStyles.js +4 -4
  67. package/dist/excalidraw/actions/actionToggleGridMode.d.ts +5 -5
  68. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +5 -5
  69. package/dist/excalidraw/actions/actionToggleStats.d.ts +5 -5
  70. package/dist/excalidraw/actions/actionToggleViewMode.d.ts +5 -5
  71. package/dist/excalidraw/actions/actionToggleZenMode.d.ts +5 -5
  72. package/dist/excalidraw/actions/index.d.ts +1 -1
  73. package/dist/excalidraw/actions/index.js +1 -1
  74. package/dist/excalidraw/actions/manager.js +2 -1
  75. package/dist/excalidraw/align.d.ts +2 -2
  76. package/dist/excalidraw/align.js +2 -2
  77. package/dist/excalidraw/animated-trail.d.ts +33 -0
  78. package/dist/excalidraw/animated-trail.js +96 -0
  79. package/dist/excalidraw/animation-frame-handler.d.ts +16 -0
  80. package/dist/excalidraw/animation-frame-handler.js +55 -0
  81. package/dist/excalidraw/appState.d.ts +1 -1
  82. package/dist/excalidraw/appState.js +1 -3
  83. package/dist/excalidraw/clipboard.js +5 -5
  84. package/dist/excalidraw/components/Actions.d.ts +3 -3
  85. package/dist/excalidraw/components/Actions.js +18 -7
  86. package/dist/excalidraw/components/App.d.ts +23 -16
  87. package/dist/excalidraw/components/App.js +387 -272
  88. package/dist/excalidraw/components/Button.d.ts +1 -1
  89. package/dist/excalidraw/components/FilledButton.d.ts +2 -2
  90. package/dist/excalidraw/components/FilledButton.js +27 -3
  91. package/dist/excalidraw/components/FollowMode/FollowMode.js +1 -1
  92. package/dist/excalidraw/components/ImageExportDialog.d.ts +2 -1
  93. package/dist/excalidraw/components/ImageExportDialog.js +17 -13
  94. package/dist/excalidraw/components/JSONExportDialog.js +1 -1
  95. package/dist/excalidraw/components/{LaserTool/LaserPointerButton.d.ts → LaserPointerButton.d.ts} +1 -1
  96. package/dist/excalidraw/components/{LaserTool/LaserPointerButton.js → LaserPointerButton.js} +2 -2
  97. package/dist/excalidraw/components/LayerUI.js +3 -3
  98. package/dist/excalidraw/components/MobileMenu.js +1 -1
  99. package/dist/excalidraw/components/ProjectName.d.ts +0 -1
  100. package/dist/excalidraw/components/ProjectName.js +1 -1
  101. package/dist/excalidraw/components/PublishLibrary.js +1 -1
  102. package/dist/excalidraw/components/SVGLayer.d.ts +8 -0
  103. package/dist/excalidraw/components/SVGLayer.js +20 -0
  104. package/dist/excalidraw/components/ShareableLinkDialog.js +10 -10
  105. package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
  106. package/dist/excalidraw/components/Stack.d.ts +2 -2
  107. package/dist/excalidraw/components/TTDDialog/common.js +10 -1
  108. package/dist/excalidraw/components/TextField.d.ts +5 -2
  109. package/dist/excalidraw/components/TextField.js +6 -3
  110. package/dist/excalidraw/components/Toast.d.ts +3 -2
  111. package/dist/excalidraw/components/Toast.js +2 -2
  112. package/dist/excalidraw/components/ToolButton.js +2 -1
  113. package/dist/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -2
  114. package/dist/excalidraw/components/canvases/InteractiveCanvas.js +6 -5
  115. package/dist/excalidraw/components/canvases/StaticCanvas.d.ts +4 -3
  116. package/dist/excalidraw/components/canvases/StaticCanvas.js +7 -5
  117. package/dist/excalidraw/components/dropdownMenu/DropdownMenuContent.js +22 -2
  118. package/dist/excalidraw/components/hyperlink/Hyperlink.d.ts +19 -0
  119. package/dist/excalidraw/{element → components/hyperlink}/Hyperlink.js +40 -115
  120. package/dist/excalidraw/components/hyperlink/helpers.d.ts +7 -0
  121. package/dist/excalidraw/components/hyperlink/helpers.js +49 -0
  122. package/dist/excalidraw/components/icons.d.ts +2 -1
  123. package/dist/excalidraw/components/icons.js +2 -1
  124. package/dist/excalidraw/components/live-collaboration/LiveCollaborationTrigger.js +3 -2
  125. package/dist/excalidraw/components/main-menu/DefaultItems.js +5 -2
  126. package/dist/excalidraw/constants.d.ts +6 -0
  127. package/dist/excalidraw/constants.js +6 -0
  128. package/dist/excalidraw/data/blob.js +13 -14
  129. package/dist/excalidraw/data/filesystem.d.ts +1 -1
  130. package/dist/excalidraw/data/index.d.ts +2 -1
  131. package/dist/excalidraw/data/index.js +20 -16
  132. package/dist/excalidraw/data/json.d.ts +1 -1
  133. package/dist/excalidraw/data/json.js +5 -3
  134. package/dist/excalidraw/data/library.d.ts +60 -8
  135. package/dist/excalidraw/data/library.js +302 -33
  136. package/dist/excalidraw/data/resave.d.ts +1 -1
  137. package/dist/excalidraw/data/resave.js +2 -2
  138. package/dist/excalidraw/data/restore.js +8 -13
  139. package/dist/excalidraw/data/transform.js +13 -9
  140. package/dist/excalidraw/distribute.d.ts +2 -2
  141. package/dist/excalidraw/distribute.js +2 -2
  142. package/dist/excalidraw/element/ElementCanvasButtons.d.ts +3 -2
  143. package/dist/excalidraw/element/ElementCanvasButtons.js +4 -4
  144. package/dist/excalidraw/element/binding.d.ts +9 -9
  145. package/dist/excalidraw/element/binding.js +61 -59
  146. package/dist/excalidraw/element/bounds.d.ts +5 -5
  147. package/dist/excalidraw/element/bounds.js +29 -32
  148. package/dist/excalidraw/element/collision.d.ts +11 -11
  149. package/dist/excalidraw/element/collision.js +49 -46
  150. package/dist/excalidraw/element/containerCache.d.ts +11 -0
  151. package/dist/excalidraw/element/containerCache.js +14 -0
  152. package/dist/excalidraw/element/dragElements.js +10 -19
  153. package/dist/excalidraw/element/embeddable.d.ts +12 -13
  154. package/dist/excalidraw/element/embeddable.js +17 -27
  155. package/dist/excalidraw/element/image.js +1 -2
  156. package/dist/excalidraw/element/index.d.ts +8 -1
  157. package/dist/excalidraw/element/index.js +23 -1
  158. package/dist/excalidraw/element/linearElementEditor.d.ts +36 -36
  159. package/dist/excalidraw/element/linearElementEditor.js +79 -80
  160. package/dist/excalidraw/element/newElement.d.ts +4 -6
  161. package/dist/excalidraw/element/newElement.js +11 -16
  162. package/dist/excalidraw/element/resizeElements.d.ts +6 -6
  163. package/dist/excalidraw/element/resizeElements.js +40 -46
  164. package/dist/excalidraw/element/resizeTest.d.ts +3 -3
  165. package/dist/excalidraw/element/resizeTest.js +4 -4
  166. package/dist/excalidraw/element/sizeHelpers.d.ts +2 -2
  167. package/dist/excalidraw/element/sizeHelpers.js +2 -2
  168. package/dist/excalidraw/element/textElement.d.ts +34 -21
  169. package/dist/excalidraw/element/textElement.js +87 -111
  170. package/dist/excalidraw/element/textWysiwyg.d.ts +1 -6
  171. package/dist/excalidraw/element/textWysiwyg.js +15 -37
  172. package/dist/excalidraw/element/transformHandles.d.ts +4 -4
  173. package/dist/excalidraw/element/transformHandles.js +6 -6
  174. package/dist/excalidraw/element/typeChecks.js +4 -1
  175. package/dist/excalidraw/element/types.d.ts +24 -11
  176. package/dist/excalidraw/frame.d.ts +26 -20
  177. package/dist/excalidraw/frame.js +157 -84
  178. package/dist/excalidraw/groups.d.ts +3 -3
  179. package/dist/excalidraw/groups.js +11 -3
  180. package/dist/excalidraw/history.d.ts +1 -1
  181. package/dist/excalidraw/hooks/useLibraryItemSvg.js +1 -1
  182. package/dist/excalidraw/index.d.ts +9 -10
  183. package/dist/excalidraw/index.js +16 -12
  184. package/dist/excalidraw/laser-trails.d.ts +19 -0
  185. package/dist/excalidraw/laser-trails.js +95 -0
  186. package/dist/excalidraw/locales/en.json +10 -5
  187. package/dist/excalidraw/queue.d.ts +9 -0
  188. package/dist/excalidraw/queue.js +27 -0
  189. package/dist/excalidraw/reactUtils.d.ts +14 -0
  190. package/dist/excalidraw/reactUtils.js +45 -0
  191. package/dist/excalidraw/renderer/helpers.d.ts +13 -0
  192. package/dist/excalidraw/renderer/helpers.js +39 -0
  193. package/dist/excalidraw/renderer/interactiveScene.d.ts +20 -0
  194. package/dist/excalidraw/renderer/{renderScene.js → interactiveScene.js} +199 -474
  195. package/dist/excalidraw/renderer/renderElement.d.ts +6 -6
  196. package/dist/excalidraw/renderer/renderElement.js +54 -366
  197. package/dist/excalidraw/renderer/staticScene.d.ts +11 -0
  198. package/dist/excalidraw/renderer/staticScene.js +205 -0
  199. package/dist/excalidraw/renderer/staticSvgScene.d.ts +5 -0
  200. package/dist/excalidraw/renderer/staticSvgScene.js +385 -0
  201. package/dist/excalidraw/scene/Fonts.js +2 -1
  202. package/dist/excalidraw/scene/Renderer.d.ts +1 -1
  203. package/dist/excalidraw/scene/Renderer.js +32 -20
  204. package/dist/excalidraw/scene/Scene.d.ts +10 -9
  205. package/dist/excalidraw/scene/Scene.js +45 -21
  206. package/dist/excalidraw/scene/Shape.d.ts +3 -1
  207. package/dist/excalidraw/scene/Shape.js +7 -5
  208. package/dist/excalidraw/scene/ShapeCache.d.ts +2 -1
  209. package/dist/excalidraw/scene/ShapeCache.js +1 -0
  210. package/dist/excalidraw/scene/comparisons.js +2 -1
  211. package/dist/excalidraw/scene/export.d.ts +3 -0
  212. package/dist/excalidraw/scene/export.js +20 -40
  213. package/dist/excalidraw/scene/index.d.ts +0 -1
  214. package/dist/excalidraw/scene/index.js +0 -1
  215. package/dist/excalidraw/scene/scrollbars.d.ts +1 -1
  216. package/dist/excalidraw/scene/scrollbars.js +1 -1
  217. package/dist/excalidraw/scene/selection.d.ts +5 -5
  218. package/dist/excalidraw/scene/selection.js +16 -14
  219. package/dist/excalidraw/scene/types.d.ts +11 -5
  220. package/dist/excalidraw/snapping.d.ts +7 -7
  221. package/dist/excalidraw/snapping.js +21 -20
  222. package/dist/excalidraw/types.d.ts +16 -17
  223. package/dist/excalidraw/utility-types.d.ts +7 -0
  224. package/dist/excalidraw/utils.d.ts +21 -16
  225. package/dist/excalidraw/utils.js +43 -45
  226. package/dist/{dev/en-RLIAOBCI.json → prod/en-EY7E2L5O.json} +10 -5
  227. package/dist/prod/index.css +1 -1
  228. package/dist/prod/index.js +42 -42
  229. package/dist/utils/bbox.d.ts +2 -2
  230. package/dist/utils/export.d.ts +3 -3
  231. package/dist/utils/export.js +3 -13
  232. package/dist/utils/index.d.ts +2 -2
  233. package/dist/utils/index.js +2 -2
  234. package/dist/utils/withinBounds.d.ts +1 -1
  235. package/dist/utils/withinBounds.js +5 -2
  236. package/package.json +4 -4
  237. package/dist/browser/dev/excalidraw-assets-dev/chunk-2W5GQUR4.js.map +0 -7
  238. package/dist/browser/dev/excalidraw-assets-dev/chunk-KGZXLFLR.js +0 -53497
  239. package/dist/browser/dev/excalidraw-assets-dev/chunk-KGZXLFLR.js.map +0 -7
  240. package/dist/browser/dev/excalidraw-assets-dev/image-3MFRCKYM.css +0 -5797
  241. package/dist/browser/dev/excalidraw-assets-dev/image-3MFRCKYM.css.map +0 -7
  242. package/dist/browser/prod/excalidraw-assets/chunk-4YN2HN3S.js +0 -257
  243. package/dist/browser/prod/excalidraw-assets/chunk-OWLL6VOG.js +0 -11
  244. package/dist/browser/prod/excalidraw-assets/en-ERQOR3OC.js +0 -1
  245. package/dist/browser/prod/excalidraw-assets/image-LTLHTTSE.js +0 -1
  246. package/dist/browser/prod/excalidraw-assets/image-QBL334OA.css +0 -1
  247. package/dist/excalidraw/components/LaserTool/LaserPathManager.d.ts +0 -28
  248. package/dist/excalidraw/components/LaserTool/LaserPathManager.js +0 -225
  249. package/dist/excalidraw/components/LaserTool/LaserTool.d.ts +0 -8
  250. package/dist/excalidraw/components/LaserTool/LaserTool.js +0 -15
  251. package/dist/excalidraw/renderer/renderScene.d.ts +0 -25
  252. package/dist/excalidraw/vite.config.d.mts +0 -2
  253. package/dist/excalidraw/vite.config.mjs +0 -13
  254. /package/dist/browser/dev/excalidraw-assets-dev/{en-OC6JWP3X.js.map → en-BZY7JRTM.js.map} +0 -0
  255. /package/dist/browser/dev/excalidraw-assets-dev/{image-5TVMINCA.js.map → image-CVN3YKRW.js.map} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { ExcalidrawElement } from "../element/types";
2
2
  import { AppState, BinaryFiles } from "../types";
3
- export declare const resaveAsImageWithScene: (elements: readonly ExcalidrawElement[], appState: AppState, files: BinaryFiles) => Promise<{
3
+ export declare const resaveAsImageWithScene: (elements: readonly ExcalidrawElement[], appState: AppState, files: BinaryFiles, name: string) => Promise<{
4
4
  fileHandle: import("browser-fs-access").FileSystemHandle;
5
5
  }>;
@@ -1,7 +1,7 @@
1
1
  import { exportCanvas, prepareElementsForExport } from ".";
2
2
  import { getFileHandleType, isImageFileHandleType } from "./blob";
3
- export const resaveAsImageWithScene = async (elements, appState, files) => {
4
- const { exportBackground, viewBackgroundColor, name, fileHandle } = appState;
3
+ export const resaveAsImageWithScene = async (elements, appState, files, name) => {
4
+ const { exportBackground, viewBackgroundColor, fileHandle } = appState;
5
5
  const fileHandleType = getFileHandleType(fileHandle);
6
6
  if (!fileHandle || !isImageFileHandleType(fileHandleType)) {
7
7
  throw new Error("fileHandle should exist and should be of type svg or png when resaving");
@@ -5,9 +5,9 @@ import { DEFAULT_FONT_FAMILY, DEFAULT_TEXT_ALIGN, DEFAULT_VERTICAL_ALIGN, PRECED
5
5
  import { getDefaultAppState } from "../appState";
6
6
  import { LinearElementEditor } from "../element/linearElementEditor";
7
7
  import { bumpVersion } from "../element/mutateElement";
8
- import { getFontString, getUpdatedTimestamp, updateActiveTool } from "../utils";
8
+ import { getUpdatedTimestamp, updateActiveTool } from "../utils";
9
9
  import { arrayToMap } from "../utils";
10
- import { detectLineHeight, getDefaultLineHeight, measureBaseline, } from "../element/textElement";
10
+ import { detectLineHeight, getContainerElement, getDefaultLineHeight, } from "../element/textElement";
11
11
  import { normalizeLink } from "./url";
12
12
  export const AllowedExcalidrawActiveTools = {
13
13
  selection: true,
@@ -94,7 +94,7 @@ const restoreElementWithProperties = (element, extra) => {
94
94
  ...extra,
95
95
  };
96
96
  };
97
- const restoreElement = (element, refreshDimensions = false) => {
97
+ const restoreElement = (element) => {
98
98
  switch (element.type) {
99
99
  case "text":
100
100
  let fontSize = element.fontSize;
@@ -117,7 +117,6 @@ const restoreElement = (element, refreshDimensions = false) => {
117
117
  : // no element height likely means programmatic use, so default
118
118
  // to a fixed line height
119
119
  getDefaultLineHeight(element.fontFamily));
120
- const baseline = measureBaseline(element.text, getFontString(element), lineHeight);
121
120
  element = restoreElementWithProperties(element, {
122
121
  fontSize,
123
122
  fontFamily,
@@ -127,7 +126,6 @@ const restoreElement = (element, refreshDimensions = false) => {
127
126
  containerId: element.containerId ?? null,
128
127
  originalText: element.originalText || text,
129
128
  lineHeight,
130
- baseline,
131
129
  });
132
130
  // if empty text, mark as deleted. We keep in array
133
131
  // for data integrity purposes (collab etc.)
@@ -135,9 +133,6 @@ const restoreElement = (element, refreshDimensions = false) => {
135
133
  element = { ...element, originalText: text, isDeleted: true };
136
134
  element = bumpVersion(element);
137
135
  }
138
- if (refreshDimensions) {
139
- element = { ...element, ...refreshTextDimensions(element) };
140
- }
141
136
  return element;
142
137
  case "freedraw": {
143
138
  return restoreElementWithProperties(element, {
@@ -190,11 +185,8 @@ const restoreElement = (element, refreshDimensions = false) => {
190
185
  case "rectangle":
191
186
  case "diamond":
192
187
  case "iframe":
193
- return restoreElementWithProperties(element, {});
194
188
  case "embeddable":
195
- return restoreElementWithProperties(element, {
196
- validated: null,
197
- });
189
+ return restoreElementWithProperties(element, {});
198
190
  case "magicframe":
199
191
  case "frame":
200
192
  return restoreElementWithProperties(element, {
@@ -287,7 +279,7 @@ localElements, opts) => {
287
279
  // filtering out selection, which is legacy, no longer kept in elements,
288
280
  // and causing issues if retained
289
281
  if (element.type !== "selection" && !isInvisiblySmallElement(element)) {
290
- let migratedElement = restoreElement(element, opts?.refreshDimensions);
282
+ let migratedElement = restoreElement(element);
291
283
  if (migratedElement) {
292
284
  const localElement = localElementsMap?.get(element.id);
293
285
  if (localElement && localElement.version > migratedElement.version) {
@@ -317,6 +309,9 @@ localElements, opts) => {
317
309
  else if (element.boundElements) {
318
310
  repairContainerElement(element, restoredElementsMap);
319
311
  }
312
+ if (opts.refreshDimensions && isTextElement(element)) {
313
+ Object.assign(element, refreshTextDimensions(element, getContainerElement(element, restoredElementsMap), restoredElementsMap));
314
+ }
320
315
  }
321
316
  return restoredElements;
322
317
  };
@@ -3,7 +3,7 @@ import { getCommonBounds, newElement, newLinearElement, redrawTextBoundingBox, }
3
3
  import { bindLinearElement } from "../element/binding";
4
4
  import { newFrameElement, newImageElement, newMagicFrameElement, newTextElement, } from "../element/newElement";
5
5
  import { getDefaultLineHeight, measureText, normalizeText, } from "../element/textElement";
6
- import { assertNever, cloneJSON, getFontString } from "../utils";
6
+ import { assertNever, cloneJSON, getFontString, toBrandedType } from "../utils";
7
7
  import { getSizeFromPoints } from "../points";
8
8
  import { randomId } from "../random";
9
9
  const DEFAULT_LINEAR_ELEMENT_PROPS = {
@@ -11,7 +11,7 @@ const DEFAULT_LINEAR_ELEMENT_PROPS = {
11
11
  height: 0,
12
12
  };
13
13
  const DEFAULT_DIMENSION = 100;
14
- const bindTextToContainer = (container, textProps) => {
14
+ const bindTextToContainer = (container, textProps, elementsMap) => {
15
15
  const textElement = newTextElement({
16
16
  x: 0,
17
17
  y: 0,
@@ -27,10 +27,10 @@ const bindTextToContainer = (container, textProps) => {
27
27
  id: textElement.id,
28
28
  }),
29
29
  });
30
- redrawTextBoundingBox(textElement, container);
30
+ redrawTextBoundingBox(textElement, container, elementsMap);
31
31
  return [container, textElement];
32
32
  };
33
- const bindLinearElementToElement = (linearElement, start, end, elementStore) => {
33
+ const bindLinearElementToElement = (linearElement, start, end, elementStore, elementsMap) => {
34
34
  let startBoundElement;
35
35
  let endBoundElement;
36
36
  Object.assign(linearElement, {
@@ -97,7 +97,7 @@ const bindLinearElementToElement = (linearElement, start, end, elementStore) =>
97
97
  }
98
98
  }
99
99
  }
100
- bindLinearElement(linearElement, startBoundElement, "start");
100
+ bindLinearElement(linearElement, startBoundElement, "start", elementsMap);
101
101
  }
102
102
  }
103
103
  if (end) {
@@ -159,7 +159,7 @@ const bindLinearElementToElement = (linearElement, start, end, elementStore) =>
159
159
  }
160
160
  }
161
161
  }
162
- bindLinearElement(linearElement, endBoundElement, "end");
162
+ bindLinearElement(linearElement, endBoundElement, "end", elementsMap);
163
163
  }
164
164
  }
165
165
  // Update start/end points by 0.5 so bindings don't overlap with start/end bound element coordinates.
@@ -208,6 +208,9 @@ class ElementStore {
208
208
  getElements = () => {
209
209
  return Array.from(this.excalidrawElements.values());
210
210
  };
211
+ getElementsMap = () => {
212
+ return toBrandedType(this.excalidrawElements);
213
+ };
211
214
  getElement = (id) => {
212
215
  return this.excalidrawElements.get(id);
213
216
  };
@@ -337,6 +340,7 @@ export const convertToExcalidrawElements = (elementsSkeleton, opts) => {
337
340
  }
338
341
  }
339
342
  }
343
+ const elementsMap = elementStore.getElementsMap();
340
344
  // Add labels and arrow bindings
341
345
  for (const [id, element] of elementsWithIds) {
342
346
  const excalidrawElement = elementStore.getElement(id);
@@ -346,7 +350,7 @@ export const convertToExcalidrawElements = (elementsSkeleton, opts) => {
346
350
  case "diamond":
347
351
  case "arrow": {
348
352
  if (element.label?.text) {
349
- let [container, text] = bindTextToContainer(excalidrawElement, element?.label);
353
+ let [container, text] = bindTextToContainer(excalidrawElement, element?.label, elementsMap);
350
354
  elementStore.add(container);
351
355
  elementStore.add(text);
352
356
  if (container.type === "arrow") {
@@ -364,7 +368,7 @@ export const convertToExcalidrawElements = (elementsSkeleton, opts) => {
364
368
  Object.assign(originalEnd, { id: newEndId });
365
369
  }
366
370
  }
367
- const { linearElement, startBoundElement, endBoundElement } = bindLinearElementToElement(container, originalStart, originalEnd, elementStore);
371
+ const { linearElement, startBoundElement, endBoundElement } = bindLinearElementToElement(container, originalStart, originalEnd, elementStore, elementsMap);
368
372
  container = linearElement;
369
373
  elementStore.add(linearElement);
370
374
  elementStore.add(startBoundElement);
@@ -383,7 +387,7 @@ export const convertToExcalidrawElements = (elementsSkeleton, opts) => {
383
387
  const newEndId = oldToNewElementIdMap.get(end.id);
384
388
  Object.assign(end, { id: newEndId });
385
389
  }
386
- const { linearElement, startBoundElement, endBoundElement } = bindLinearElementToElement(excalidrawElement, start, end, elementStore);
390
+ const { linearElement, startBoundElement, endBoundElement } = bindLinearElementToElement(excalidrawElement, start, end, elementStore, elementsMap);
387
391
  elementStore.add(linearElement);
388
392
  elementStore.add(startBoundElement);
389
393
  elementStore.add(endBoundElement);
@@ -1,6 +1,6 @@
1
- import { ExcalidrawElement } from "./element/types";
1
+ import type { ElementsMap, ExcalidrawElement } from "./element/types";
2
2
  export interface Distribution {
3
3
  space: "between";
4
4
  axis: "x" | "y";
5
5
  }
6
- export declare const distributeElements: (selectedElements: ExcalidrawElement[], distribution: Distribution) => ExcalidrawElement[];
6
+ export declare const distributeElements: (selectedElements: ExcalidrawElement[], elementsMap: ElementsMap, distribution: Distribution) => ExcalidrawElement[];
@@ -1,12 +1,12 @@
1
1
  import { newElementWith } from "./element/mutateElement";
2
2
  import { getMaximumGroups } from "./groups";
3
3
  import { getCommonBoundingBox } from "./element/bounds";
4
- export const distributeElements = (selectedElements, distribution) => {
4
+ export const distributeElements = (selectedElements, elementsMap, distribution) => {
5
5
  const [start, mid, end, extent] = distribution.axis === "x"
6
6
  ? ["minX", "midX", "maxX", "width"]
7
7
  : ["minY", "midY", "maxY", "height"];
8
8
  const bounds = getCommonBoundingBox(selectedElements);
9
- const groups = getMaximumGroups(selectedElements)
9
+ const groups = getMaximumGroups(selectedElements, elementsMap)
10
10
  .map((group) => [group, getCommonBoundingBox(group)])
11
11
  .sort((a, b) => a[1][mid] - b[1][mid]);
12
12
  let span = 0;
@@ -1,7 +1,8 @@
1
1
  /// <reference types="react" />
2
- import { NonDeletedExcalidrawElement } from "./types";
2
+ import { ElementsMap, NonDeletedExcalidrawElement } from "./types";
3
3
  import "./ElementCanvasButtons.scss";
4
- export declare const ElementCanvasButtons: ({ children, element, }: {
4
+ export declare const ElementCanvasButtons: ({ children, element, elementsMap, }: {
5
5
  children: React.ReactNode;
6
6
  element: NonDeletedExcalidrawElement;
7
+ elementsMap: ElementsMap;
7
8
  }) => JSX.Element | null;
@@ -4,14 +4,14 @@ import { getElementAbsoluteCoords } from ".";
4
4
  import { useExcalidrawAppState } from "../components/App";
5
5
  import "./ElementCanvasButtons.scss";
6
6
  const CONTAINER_PADDING = 5;
7
- const getContainerCoords = (element, appState) => {
8
- const [x1, y1] = getElementAbsoluteCoords(element);
7
+ const getContainerCoords = (element, appState, elementsMap) => {
8
+ const [x1, y1] = getElementAbsoluteCoords(element, elementsMap);
9
9
  const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords({ sceneX: x1 + element.width, sceneY: y1 }, appState);
10
10
  const x = viewportX - appState.offsetLeft + 10;
11
11
  const y = viewportY - appState.offsetTop;
12
12
  return { x, y };
13
13
  };
14
- export const ElementCanvasButtons = ({ children, element, }) => {
14
+ export const ElementCanvasButtons = ({ children, element, elementsMap, }) => {
15
15
  const appState = useExcalidrawAppState();
16
16
  if (appState.contextMenu ||
17
17
  appState.draggingElement ||
@@ -21,7 +21,7 @@ export const ElementCanvasButtons = ({ children, element, }) => {
21
21
  appState.viewModeEnabled) {
22
22
  return null;
23
23
  }
24
- const { x, y } = getContainerCoords(element, appState);
24
+ const { x, y } = getContainerCoords(element, appState, elementsMap);
25
25
  return (_jsx("div", { className: "excalidraw-canvas-buttons", style: {
26
26
  top: `${y}px`,
27
27
  left: `${x}px`,
@@ -1,4 +1,4 @@
1
- import { ExcalidrawLinearElement, ExcalidrawBindableElement, NonDeleted, NonDeletedExcalidrawElement, ExcalidrawElement } from "./types";
1
+ import { ExcalidrawLinearElement, ExcalidrawBindableElement, NonDeleted, NonDeletedExcalidrawElement, ExcalidrawElement, ElementsMap, NonDeletedSceneElementsMap } from "./types";
2
2
  import { AppState } from "../types";
3
3
  import Scene from "../scene/Scene";
4
4
  export type SuggestedBinding = NonDeleted<ExcalidrawBindableElement> | SuggestedPointBinding;
@@ -9,26 +9,26 @@ export type SuggestedPointBinding = [
9
9
  ];
10
10
  export declare const shouldEnableBindingForPointerEvent: (event: React.PointerEvent<HTMLElement>) => boolean;
11
11
  export declare const isBindingEnabled: (appState: AppState) => boolean;
12
- export declare const bindOrUnbindLinearElement: (linearElement: NonDeleted<ExcalidrawLinearElement>, startBindingElement: ExcalidrawBindableElement | null | "keep", endBindingElement: ExcalidrawBindableElement | null | "keep") => void;
13
- export declare const bindOrUnbindSelectedElements: (elements: NonDeleted<ExcalidrawElement>[]) => void;
12
+ export declare const bindOrUnbindLinearElement: (linearElement: NonDeleted<ExcalidrawLinearElement>, startBindingElement: ExcalidrawBindableElement | null | "keep", endBindingElement: ExcalidrawBindableElement | null | "keep", elementsMap: NonDeletedSceneElementsMap) => void;
13
+ export declare const bindOrUnbindSelectedElements: (selectedElements: NonDeleted<ExcalidrawElement>[], elements: readonly ExcalidrawElement[], elementsMap: NonDeletedSceneElementsMap) => void;
14
14
  export declare const maybeBindLinearElement: (linearElement: NonDeleted<ExcalidrawLinearElement>, appState: AppState, scene: Scene, pointerCoords: {
15
15
  x: number;
16
16
  y: number;
17
- }) => void;
18
- export declare const bindLinearElement: (linearElement: NonDeleted<ExcalidrawLinearElement>, hoveredElement: ExcalidrawBindableElement, startOrEnd: "start" | "end") => void;
17
+ }, elementsMap: NonDeletedSceneElementsMap) => void;
18
+ export declare const bindLinearElement: (linearElement: NonDeleted<ExcalidrawLinearElement>, hoveredElement: ExcalidrawBindableElement, startOrEnd: "start" | "end", elementsMap: NonDeletedSceneElementsMap) => void;
19
19
  export declare const isLinearElementSimpleAndAlreadyBound: (linearElement: NonDeleted<ExcalidrawLinearElement>, alreadyBoundToId: ExcalidrawBindableElement["id"] | undefined, bindableElement: ExcalidrawBindableElement) => boolean;
20
- export declare const unbindLinearElements: (elements: NonDeleted<ExcalidrawElement>[]) => void;
20
+ export declare const unbindLinearElements: (elements: NonDeleted<ExcalidrawElement>[], elementsMap: NonDeletedSceneElementsMap) => void;
21
21
  export declare const getHoveredElementForBinding: (pointerCoords: {
22
22
  x: number;
23
23
  y: number;
24
- }, scene: Scene) => NonDeleted<ExcalidrawBindableElement> | null;
25
- export declare const updateBoundElements: (changedElement: NonDeletedExcalidrawElement, options?: {
24
+ }, elements: readonly NonDeletedExcalidrawElement[], elementsMap: NonDeletedSceneElementsMap) => NonDeleted<ExcalidrawBindableElement> | null;
25
+ export declare const updateBoundElements: (changedElement: NonDeletedExcalidrawElement, elementsMap: ElementsMap, options?: {
26
26
  simultaneouslyUpdated?: readonly ExcalidrawElement[];
27
27
  newSize?: {
28
28
  width: number;
29
29
  height: number;
30
30
  };
31
31
  }) => void;
32
- export declare const getEligibleElementsForBinding: (elements: NonDeleted<ExcalidrawElement>[]) => SuggestedBinding[];
32
+ export declare const getEligibleElementsForBinding: (selectedElements: NonDeleted<ExcalidrawElement>[], elements: readonly ExcalidrawElement[], elementsMap: NonDeletedSceneElementsMap) => SuggestedBinding[];
33
33
  export declare const fixBindingsAfterDuplication: (sceneElements: readonly ExcalidrawElement[], oldElements: readonly ExcalidrawElement[], oldIdToDuplicatedId: Map<ExcalidrawElement["id"], ExcalidrawElement["id"]>, duplicatesServeAsOld?: "duplicatesServeAsOld" | undefined) => void;
34
34
  export declare const fixBindingsAfterDeletion: (sceneElements: readonly ExcalidrawElement[], deletedElements: readonly ExcalidrawElement[]) => void;
@@ -23,11 +23,11 @@ const getNonDeletedElements = (scene, ids) => {
23
23
  });
24
24
  return result;
25
25
  };
26
- export const bindOrUnbindLinearElement = (linearElement, startBindingElement, endBindingElement) => {
26
+ export const bindOrUnbindLinearElement = (linearElement, startBindingElement, endBindingElement, elementsMap) => {
27
27
  const boundToElementIds = new Set();
28
28
  const unboundFromElementIds = new Set();
29
- bindOrUnbindLinearElementEdge(linearElement, startBindingElement, endBindingElement, "start", boundToElementIds, unboundFromElementIds);
30
- bindOrUnbindLinearElementEdge(linearElement, endBindingElement, startBindingElement, "end", boundToElementIds, unboundFromElementIds);
29
+ bindOrUnbindLinearElementEdge(linearElement, startBindingElement, endBindingElement, "start", boundToElementIds, unboundFromElementIds, elementsMap);
30
+ bindOrUnbindLinearElementEdge(linearElement, endBindingElement, startBindingElement, "end", boundToElementIds, unboundFromElementIds, elementsMap);
31
31
  const onlyUnbound = Array.from(unboundFromElementIds).filter((id) => !boundToElementIds.has(id));
32
32
  getNonDeletedElements(Scene.getScene(linearElement), onlyUnbound).forEach((element) => {
33
33
  mutateElement(element, {
@@ -39,7 +39,7 @@ const bindOrUnbindLinearElementEdge = (linearElement, bindableElement, otherEdge
39
39
  // Is mutated
40
40
  boundToElementIds,
41
41
  // Is mutated
42
- unboundFromElementIds) => {
42
+ unboundFromElementIds, elementsMap) => {
43
43
  if (bindableElement !== "keep") {
44
44
  if (bindableElement != null) {
45
45
  // Don't bind if we're trying to bind or are already bound to the same
@@ -49,7 +49,7 @@ unboundFromElementIds) => {
49
49
  ? !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd)
50
50
  : startOrEnd === "start" ||
51
51
  otherEdgeBindableElement.id !== bindableElement.id)) {
52
- bindLinearElement(linearElement, bindableElement, startOrEnd);
52
+ bindLinearElement(linearElement, bindableElement, startOrEnd, elementsMap);
53
53
  boundToElementIds.add(bindableElement.id);
54
54
  }
55
55
  }
@@ -61,34 +61,34 @@ unboundFromElementIds) => {
61
61
  }
62
62
  }
63
63
  };
64
- export const bindOrUnbindSelectedElements = (elements) => {
65
- elements.forEach((element) => {
66
- if (isBindingElement(element)) {
67
- bindOrUnbindLinearElement(element, getElligibleElementForBindingElement(element, "start"), getElligibleElementForBindingElement(element, "end"));
64
+ export const bindOrUnbindSelectedElements = (selectedElements, elements, elementsMap) => {
65
+ selectedElements.forEach((selectedElement) => {
66
+ if (isBindingElement(selectedElement)) {
67
+ bindOrUnbindLinearElement(selectedElement, getElligibleElementForBindingElement(selectedElement, "start", elements, elementsMap), getElligibleElementForBindingElement(selectedElement, "end", elements, elementsMap), elementsMap);
68
68
  }
69
- else if (isBindableElement(element)) {
70
- maybeBindBindableElement(element);
69
+ else if (isBindableElement(selectedElement)) {
70
+ maybeBindBindableElement(selectedElement, elementsMap);
71
71
  }
72
72
  });
73
73
  };
74
- const maybeBindBindableElement = (bindableElement) => {
75
- getElligibleElementsForBindableElementAndWhere(bindableElement).forEach(([linearElement, where]) => bindOrUnbindLinearElement(linearElement, where === "end" ? "keep" : bindableElement, where === "start" ? "keep" : bindableElement));
74
+ const maybeBindBindableElement = (bindableElement, elementsMap) => {
75
+ getElligibleElementsForBindableElementAndWhere(bindableElement, elementsMap).forEach(([linearElement, where]) => bindOrUnbindLinearElement(linearElement, where === "end" ? "keep" : bindableElement, where === "start" ? "keep" : bindableElement, elementsMap));
76
76
  };
77
- export const maybeBindLinearElement = (linearElement, appState, scene, pointerCoords) => {
77
+ export const maybeBindLinearElement = (linearElement, appState, scene, pointerCoords, elementsMap) => {
78
78
  if (appState.startBoundElement != null) {
79
- bindLinearElement(linearElement, appState.startBoundElement, "start");
79
+ bindLinearElement(linearElement, appState.startBoundElement, "start", elementsMap);
80
80
  }
81
- const hoveredElement = getHoveredElementForBinding(pointerCoords, scene);
81
+ const hoveredElement = getHoveredElementForBinding(pointerCoords, scene.getNonDeletedElements(), elementsMap);
82
82
  if (hoveredElement != null &&
83
83
  !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, hoveredElement, "end")) {
84
- bindLinearElement(linearElement, hoveredElement, "end");
84
+ bindLinearElement(linearElement, hoveredElement, "end", elementsMap);
85
85
  }
86
86
  };
87
- export const bindLinearElement = (linearElement, hoveredElement, startOrEnd) => {
87
+ export const bindLinearElement = (linearElement, hoveredElement, startOrEnd, elementsMap) => {
88
88
  mutateElement(linearElement, {
89
89
  [startOrEnd === "start" ? "startBinding" : "endBinding"]: {
90
90
  elementId: hoveredElement.id,
91
- ...calculateFocusAndGap(linearElement, hoveredElement, startOrEnd),
91
+ ...calculateFocusAndGap(linearElement, hoveredElement, startOrEnd, elementsMap),
92
92
  },
93
93
  });
94
94
  const boundElementsMap = arrayToMap(hoveredElement.boundElements || []);
@@ -109,10 +109,10 @@ const isLinearElementSimpleAndAlreadyBoundOnOppositeEdge = (linearElement, binda
109
109
  export const isLinearElementSimpleAndAlreadyBound = (linearElement, alreadyBoundToId, bindableElement) => {
110
110
  return (alreadyBoundToId === bindableElement.id && linearElement.points.length < 3);
111
111
  };
112
- export const unbindLinearElements = (elements) => {
112
+ export const unbindLinearElements = (elements, elementsMap) => {
113
113
  elements.forEach((element) => {
114
114
  if (isBindingElement(element)) {
115
- bindOrUnbindLinearElement(element, null, null);
115
+ bindOrUnbindLinearElement(element, null, null, elementsMap);
116
116
  }
117
117
  });
118
118
  };
@@ -125,20 +125,20 @@ const unbindLinearElement = (linearElement, startOrEnd) => {
125
125
  mutateElement(linearElement, { [field]: null });
126
126
  return binding.elementId;
127
127
  };
128
- export const getHoveredElementForBinding = (pointerCoords, scene) => {
129
- const hoveredElement = getElementAtPosition(scene.getNonDeletedElements(), (element) => isBindableElement(element, false) &&
130
- bindingBorderTest(element, pointerCoords));
128
+ export const getHoveredElementForBinding = (pointerCoords, elements, elementsMap) => {
129
+ const hoveredElement = getElementAtPosition(elements, (element) => isBindableElement(element, false) &&
130
+ bindingBorderTest(element, pointerCoords, elementsMap));
131
131
  return hoveredElement;
132
132
  };
133
- const calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd) => {
133
+ const calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd, elementsMap) => {
134
134
  const direction = startOrEnd === "start" ? -1 : 1;
135
135
  const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;
136
136
  const adjacentPointIndex = edgePointIndex - direction;
137
- const edgePoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, edgePointIndex);
138
- const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex);
137
+ const edgePoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, edgePointIndex, elementsMap);
138
+ const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex, elementsMap);
139
139
  return {
140
- focus: determineFocusDistance(hoveredElement, adjacentPoint, edgePoint),
141
- gap: Math.max(1, distanceToBindableElement(hoveredElement, edgePoint)),
140
+ focus: determineFocusDistance(hoveredElement, adjacentPoint, edgePoint, elementsMap),
141
+ gap: Math.max(1, distanceToBindableElement(hoveredElement, edgePoint, elementsMap)),
142
142
  };
143
143
  };
144
144
  // Supports translating, rotating and scaling `changedElement` with bound
@@ -146,14 +146,15 @@ const calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd) => {
146
146
  // Because scaling involves moving the focus points as well, it is
147
147
  // done before the `changedElement` is updated, and the `newSize` is passed
148
148
  // in explicitly.
149
- export const updateBoundElements = (changedElement, options) => {
149
+ export const updateBoundElements = (changedElement, elementsMap, options) => {
150
150
  const boundLinearElements = (changedElement.boundElements ?? []).filter((el) => el.type === "arrow");
151
151
  if (boundLinearElements.length === 0) {
152
152
  return;
153
153
  }
154
154
  const { newSize, simultaneouslyUpdated } = options ?? {};
155
155
  const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(simultaneouslyUpdated);
156
- getNonDeletedElements(Scene.getScene(changedElement), boundLinearElements.map((el) => el.id)).forEach((element) => {
156
+ const scene = Scene.getScene(changedElement);
157
+ getNonDeletedElements(scene, boundLinearElements.map((el) => el.id)).forEach((element) => {
157
158
  if (!isLinearElement(element)) {
158
159
  return;
159
160
  }
@@ -169,11 +170,11 @@ export const updateBoundElements = (changedElement, options) => {
169
170
  mutateElement(element, { startBinding, endBinding });
170
171
  return;
171
172
  }
172
- updateBoundPoint(element, "start", startBinding, changedElement);
173
- updateBoundPoint(element, "end", endBinding, changedElement);
174
- const boundText = getBoundTextElement(element);
173
+ updateBoundPoint(element, "start", startBinding, changedElement, elementsMap);
174
+ updateBoundPoint(element, "end", endBinding, changedElement, elementsMap);
175
+ const boundText = getBoundTextElement(element, scene.getNonDeletedElementsMap());
175
176
  if (boundText) {
176
- handleBindTextResize(element, false);
177
+ handleBindTextResize(element, scene.getNonDeletedElementsMap(), false);
177
178
  }
178
179
  });
179
180
  };
@@ -184,7 +185,7 @@ const doesNeedUpdate = (boundElement, changedElement) => {
184
185
  const getSimultaneouslyUpdatedElementIds = (simultaneouslyUpdated) => {
185
186
  return new Set((simultaneouslyUpdated || []).map((element) => element.id));
186
187
  };
187
- const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement) => {
188
+ const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, elementsMap) => {
188
189
  if (binding == null ||
189
190
  // We only need to update the other end if this is a 2 point line element
190
191
  (binding.elementId !== changedElement.id && linearElement.points.length > 2)) {
@@ -198,8 +199,8 @@ const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement) =>
198
199
  const direction = startOrEnd === "start" ? -1 : 1;
199
200
  const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;
200
201
  const adjacentPointIndex = edgePointIndex - direction;
201
- const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex);
202
- const focusPointAbsolute = determineFocusPoint(bindingElement, binding.focus, adjacentPoint);
202
+ const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex, elementsMap);
203
+ const focusPointAbsolute = determineFocusPoint(bindingElement, binding.focus, adjacentPoint, elementsMap);
203
204
  let newEdgePoint;
204
205
  // The linear element was not originally pointing inside the bound shape,
205
206
  // we can point directly at the focus point
@@ -207,7 +208,7 @@ const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement) =>
207
208
  newEdgePoint = focusPointAbsolute;
208
209
  }
209
210
  else {
210
- const intersections = intersectElementWithLine(bindingElement, adjacentPoint, focusPointAbsolute, binding.gap);
211
+ const intersections = intersectElementWithLine(bindingElement, adjacentPoint, focusPointAbsolute, binding.gap, elementsMap);
211
212
  if (intersections.length === 0) {
212
213
  // This should never happen, since focusPoint should always be
213
214
  // inside the element, but just in case, bail out
@@ -221,7 +222,7 @@ const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement) =>
221
222
  LinearElementEditor.movePoints(linearElement, [
222
223
  {
223
224
  index: edgePointIndex,
224
- point: LinearElementEditor.pointFromAbsoluteCoords(linearElement, newEdgePoint),
225
+ point: LinearElementEditor.pointFromAbsoluteCoords(linearElement, newEdgePoint, elementsMap),
225
226
  },
226
227
  ], { [startOrEnd === "start" ? "startBinding" : "endBinding"]: binding });
227
228
  };
@@ -236,36 +237,37 @@ const maybeCalculateNewGapWhenScaling = (changedElement, currentBinding, newSize
236
237
  return { elementId, gap: newGap, focus };
237
238
  };
238
239
  // TODO: this is a bottleneck, optimise
239
- export const getEligibleElementsForBinding = (elements) => {
240
- const includedElementIds = new Set(elements.map(({ id }) => id));
241
- return elements.flatMap((element) => isBindingElement(element, false)
242
- ? getElligibleElementsForBindingElement(element).filter((element) => !includedElementIds.has(element.id))
243
- : isBindableElement(element, false)
244
- ? getElligibleElementsForBindableElementAndWhere(element).filter((binding) => !includedElementIds.has(binding[0].id))
240
+ export const getEligibleElementsForBinding = (selectedElements, elements, elementsMap) => {
241
+ const includedElementIds = new Set(selectedElements.map(({ id }) => id));
242
+ return selectedElements.flatMap((selectedElement) => isBindingElement(selectedElement, false)
243
+ ? getElligibleElementsForBindingElement(selectedElement, elements, elementsMap).filter((element) => !includedElementIds.has(element.id))
244
+ : isBindableElement(selectedElement, false)
245
+ ? getElligibleElementsForBindableElementAndWhere(selectedElement, elementsMap).filter((binding) => !includedElementIds.has(binding[0].id))
245
246
  : []);
246
247
  };
247
- const getElligibleElementsForBindingElement = (linearElement) => {
248
+ const getElligibleElementsForBindingElement = (linearElement, elements, elementsMap) => {
248
249
  return [
249
- getElligibleElementForBindingElement(linearElement, "start"),
250
- getElligibleElementForBindingElement(linearElement, "end"),
250
+ getElligibleElementForBindingElement(linearElement, "start", elements, elementsMap),
251
+ getElligibleElementForBindingElement(linearElement, "end", elements, elementsMap),
251
252
  ].filter((element) => element != null);
252
253
  };
253
- const getElligibleElementForBindingElement = (linearElement, startOrEnd) => {
254
- return getHoveredElementForBinding(getLinearElementEdgeCoors(linearElement, startOrEnd), Scene.getScene(linearElement));
254
+ const getElligibleElementForBindingElement = (linearElement, startOrEnd, elements, elementsMap) => {
255
+ return getHoveredElementForBinding(getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap), elements, elementsMap);
255
256
  };
256
- const getLinearElementEdgeCoors = (linearElement, startOrEnd) => {
257
+ const getLinearElementEdgeCoors = (linearElement, startOrEnd, elementsMap) => {
257
258
  const index = startOrEnd === "start" ? 0 : -1;
258
- return tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, index));
259
+ return tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, index, elementsMap));
259
260
  };
260
- const getElligibleElementsForBindableElementAndWhere = (bindableElement) => {
261
- return Scene.getScene(bindableElement)
261
+ const getElligibleElementsForBindableElementAndWhere = (bindableElement, elementsMap) => {
262
+ const scene = Scene.getScene(bindableElement);
263
+ return scene
262
264
  .getNonDeletedElements()
263
265
  .map((element) => {
264
266
  if (!isBindingElement(element, false)) {
265
267
  return null;
266
268
  }
267
- const canBindStart = isLinearElementEligibleForNewBindingByBindable(element, "start", bindableElement);
268
- const canBindEnd = isLinearElementEligibleForNewBindingByBindable(element, "end", bindableElement);
269
+ const canBindStart = isLinearElementEligibleForNewBindingByBindable(element, "start", bindableElement, elementsMap);
270
+ const canBindEnd = isLinearElementEligibleForNewBindingByBindable(element, "end", bindableElement, elementsMap);
269
271
  if (!canBindStart && !canBindEnd) {
270
272
  return null;
271
273
  }
@@ -277,11 +279,11 @@ const getElligibleElementsForBindableElementAndWhere = (bindableElement) => {
277
279
  })
278
280
  .filter((maybeElement) => maybeElement != null);
279
281
  };
280
- const isLinearElementEligibleForNewBindingByBindable = (linearElement, startOrEnd, bindableElement) => {
282
+ const isLinearElementEligibleForNewBindingByBindable = (linearElement, startOrEnd, bindableElement, elementsMap) => {
281
283
  const existingBinding = linearElement[startOrEnd === "start" ? "startBinding" : "endBinding"];
282
284
  return (existingBinding == null &&
283
285
  !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd) &&
284
- bindingBorderTest(bindableElement, getLinearElementEdgeCoors(linearElement, startOrEnd)));
286
+ bindingBorderTest(bindableElement, getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap), elementsMap));
285
287
  };
286
288
  // We need to:
287
289
  // 1: Update elements not selected to point to duplicated elements
@@ -1,4 +1,4 @@
1
- import { ExcalidrawElement, ExcalidrawLinearElement, Arrowhead, ExcalidrawFreeDrawElement, NonDeleted } from "./types";
1
+ import { ExcalidrawElement, ExcalidrawLinearElement, Arrowhead, ExcalidrawFreeDrawElement, NonDeleted, ElementsMap } from "./types";
2
2
  import { Drawable, Op } from "roughjs/bin/core";
3
3
  import { AppState, Point } from "../types";
4
4
  export type RectangleBox = {
@@ -25,11 +25,11 @@ export type SceneBounds = readonly [
25
25
  ];
26
26
  export declare class ElementBounds {
27
27
  private static boundsCache;
28
- static getBounds(element: ExcalidrawElement): Bounds;
28
+ static getBounds(element: ExcalidrawElement, elementsMap: ElementsMap): Bounds;
29
29
  private static calculateBounds;
30
30
  }
31
- export declare const getElementAbsoluteCoords: (element: ExcalidrawElement, includeBoundText?: boolean) => [number, number, number, number, number, number];
32
- export declare const getElementLineSegments: (element: ExcalidrawElement) => [Point, Point][];
31
+ export declare const getElementAbsoluteCoords: (element: ExcalidrawElement, elementsMap: ElementsMap, includeBoundText?: boolean) => [number, number, number, number, number, number];
32
+ export declare const getElementLineSegments: (element: ExcalidrawElement, elementsMap: ElementsMap) => [Point, Point][];
33
33
  /**
34
34
  * Scene -> Scene coords, but in x1,x2,y1,y2 format.
35
35
  *
@@ -46,7 +46,7 @@ export declare const getArrowheadSize: (arrowhead: Arrowhead) => number;
46
46
  /** @returns number in degrees */
47
47
  export declare const getArrowheadAngle: (arrowhead: Arrowhead) => number;
48
48
  export declare const getArrowheadPoints: (element: ExcalidrawLinearElement, shape: Drawable[], position: "start" | "end", arrowhead: Arrowhead) => number[] | null;
49
- export declare const getElementBounds: (element: ExcalidrawElement) => Bounds;
49
+ export declare const getElementBounds: (element: ExcalidrawElement, elementsMap: ElementsMap) => Bounds;
50
50
  export declare const getCommonBounds: (elements: readonly ExcalidrawElement[]) => Bounds;
51
51
  export declare const getDraggedElementsBounds: (elements: ExcalidrawElement[], dragOffset: {
52
52
  x: number;