@excalidraw/excalidraw 0.17.1-1ed53b1 → 0.17.1-22b3927
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-JKPJV7MZ.js → chunk-Q6A4M3MN.js} +4 -2
- package/dist/browser/dev/excalidraw-assets-dev/chunk-Q6A4M3MN.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-OKAZAA6U.js → chunk-VC7RRIDZ.js} +230 -93
- package/dist/browser/dev/excalidraw-assets-dev/chunk-VC7RRIDZ.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{dist-ITJNUBZF.js → dist-6QVAH5JA.js} +36 -14
- package/dist/browser/dev/excalidraw-assets-dev/dist-6QVAH5JA.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{en-BF4XUPIZ.js → en-Y27YPU72.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{image-LVS32KQQ.js → image-J7S3ALXP.js} +2 -2
- package/dist/browser/dev/index.js +335 -116
- package/dist/browser/dev/index.js.map +4 -4
- package/dist/browser/prod/excalidraw-assets/chunk-CWO763YJ.js +55 -0
- package/dist/browser/prod/excalidraw-assets/{chunk-O4AI3NNG.js → chunk-IZMZ6RPD.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/dist-567JAXHK.js +7 -0
- package/dist/browser/prod/excalidraw-assets/{en-N7CLNF6C.js → en-GSUSWMSH.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/image-SZBFRCU2.js +1 -0
- package/dist/browser/prod/index.js +24 -24
- package/dist/dev/{en-UQDDYCH7.json → en-OIPCBIOA.json} +3 -1
- package/dist/dev/index.js +576 -207
- package/dist/dev/index.js.map +4 -4
- package/dist/excalidraw/actions/actionAddToLibrary.d.ts +3 -3
- package/dist/excalidraw/actions/actionAlign.d.ts +6 -6
- package/dist/excalidraw/actions/actionBoundText.d.ts +3 -3
- package/dist/excalidraw/actions/actionBoundText.js +3 -1
- package/dist/excalidraw/actions/actionCanvas.d.ts +13 -13
- package/dist/excalidraw/actions/actionClipboard.d.ts +12 -12
- package/dist/excalidraw/actions/actionDeleteSelected.d.ts +3 -3
- package/dist/excalidraw/actions/actionDistribute.d.ts +2 -2
- package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +1 -1
- package/dist/excalidraw/actions/actionElementLock.d.ts +2 -2
- package/dist/excalidraw/actions/actionExport.d.ts +11 -11
- package/dist/excalidraw/actions/actionFinalize.d.ts +2 -2
- package/dist/excalidraw/actions/actionFlip.d.ts +2 -2
- package/dist/excalidraw/actions/actionFrame.d.ts +312 -4
- package/dist/excalidraw/actions/actionGroup.d.ts +312 -2
- package/dist/excalidraw/actions/actionHistory.js +4 -4
- package/dist/excalidraw/actions/actionLinearEditor.d.ts +1 -1
- package/dist/excalidraw/actions/actionLink.d.ts +1 -1
- package/dist/excalidraw/actions/actionMenu.d.ts +3 -3
- package/dist/excalidraw/actions/actionNavigate.d.ts +2 -2
- package/dist/excalidraw/actions/actionProperties.d.ts +13 -13
- package/dist/excalidraw/actions/actionProperties.js +1 -1
- package/dist/excalidraw/actions/actionSelectAll.d.ts +1 -1
- package/dist/excalidraw/actions/actionStyles.d.ts +5 -2
- package/dist/excalidraw/actions/actionTextAutoResize.d.ts +17 -0
- package/dist/excalidraw/actions/actionTextAutoResize.js +38 -0
- package/dist/excalidraw/actions/actionToggleGridMode.d.ts +1 -1
- package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +1 -1
- package/dist/excalidraw/actions/actionToggleStats.d.ts +1 -1
- package/dist/excalidraw/actions/actionToggleViewMode.d.ts +1 -1
- package/dist/excalidraw/actions/actionToggleZenMode.d.ts +1 -1
- package/dist/excalidraw/actions/actionZindex.d.ts +4 -4
- package/dist/excalidraw/actions/types.d.ts +1 -1
- package/dist/excalidraw/change.js +13 -6
- package/dist/excalidraw/components/Actions.js +1 -1
- package/dist/excalidraw/components/App.d.ts +2 -2
- package/dist/excalidraw/components/App.js +133 -51
- package/dist/excalidraw/components/ButtonIconSelect.js +1 -1
- package/dist/excalidraw/components/CheckboxItem.js +1 -1
- package/dist/excalidraw/components/CommandPalette/CommandPalette.js +2 -2
- package/dist/excalidraw/components/ContextMenu.js +1 -1
- package/dist/excalidraw/components/Dialog.js +1 -1
- package/dist/excalidraw/components/FollowMode/FollowMode.js +1 -1
- package/dist/excalidraw/components/IconPicker.js +2 -2
- package/dist/excalidraw/components/LayerUI.js +2 -2
- package/dist/excalidraw/components/MobileMenu.js +1 -1
- package/dist/excalidraw/components/PasteChartDialog.js +1 -1
- package/dist/excalidraw/components/canvases/InteractiveCanvas.d.ts +3 -2
- package/dist/excalidraw/components/canvases/InteractiveCanvas.js +4 -2
- package/dist/excalidraw/components/canvases/StaticCanvas.d.ts +1 -1
- package/dist/excalidraw/components/canvases/StaticCanvas.js +2 -2
- package/dist/excalidraw/components/icons.js +6 -2
- package/dist/excalidraw/constants.d.ts +1 -0
- package/dist/excalidraw/constants.js +5 -0
- package/dist/excalidraw/data/restore.js +3 -0
- package/dist/excalidraw/element/dragElements.d.ts +2 -2
- package/dist/excalidraw/element/dragElements.js +27 -3
- package/dist/excalidraw/element/embeddable.d.ts +1 -1
- package/dist/excalidraw/element/index.d.ts +1 -1
- package/dist/excalidraw/element/index.js +1 -1
- package/dist/excalidraw/element/mutateElement.d.ts +1 -1
- package/dist/excalidraw/element/mutateElement.js +5 -3
- package/dist/excalidraw/element/newElement.d.ts +2 -5
- package/dist/excalidraw/element/newElement.js +16 -14
- package/dist/excalidraw/element/resizeElements.js +73 -21
- package/dist/excalidraw/element/resizeTest.js +2 -4
- package/dist/excalidraw/element/textElement.d.ts +1 -0
- package/dist/excalidraw/element/textElement.js +11 -3
- package/dist/excalidraw/element/textWysiwyg.d.ts +10 -4
- package/dist/excalidraw/element/textWysiwyg.js +38 -17
- package/dist/excalidraw/element/transformHandles.js +0 -10
- package/dist/excalidraw/element/types.d.ts +7 -0
- package/dist/excalidraw/fractionalIndex.js +2 -4
- package/dist/excalidraw/locales/en.json +3 -1
- package/dist/excalidraw/mermaid.d.ts +2 -0
- package/dist/excalidraw/mermaid.js +28 -0
- package/dist/excalidraw/renderer/interactiveScene.d.ts +1 -1
- package/dist/excalidraw/renderer/interactiveScene.js +31 -5
- package/dist/excalidraw/renderer/renderElement.d.ts +2 -2
- package/dist/excalidraw/renderer/renderElement.js +2 -2
- package/dist/excalidraw/scene/Fonts.d.ts +1 -3
- package/dist/excalidraw/scene/Fonts.js +6 -12
- package/dist/excalidraw/scene/Renderer.d.ts +1 -1
- package/dist/excalidraw/scene/Renderer.js +2 -3
- package/dist/excalidraw/scene/Scene.d.ts +10 -4
- package/dist/excalidraw/scene/Scene.js +14 -8
- package/dist/excalidraw/scene/export.js +1 -1
- package/dist/excalidraw/scene/types.d.ts +2 -1
- package/dist/excalidraw/snapping.js +2 -1
- package/dist/excalidraw/store.d.ts +32 -2
- package/dist/excalidraw/store.js +27 -0
- package/dist/excalidraw/types.d.ts +1 -0
- package/dist/prod/{en-UQDDYCH7.json → en-OIPCBIOA.json} +3 -1
- package/dist/prod/index.js +42 -42
- package/package.json +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/chunk-JKPJV7MZ.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-OKAZAA6U.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/dist-ITJNUBZF.js.map +0 -7
- package/dist/browser/prod/excalidraw-assets/chunk-SXBDZOS3.js +0 -55
- package/dist/browser/prod/excalidraw-assets/dist-54276HPL.js +0 -6
- package/dist/browser/prod/excalidraw-assets/image-VAGBVQ3G.js +0 -1
- /package/dist/browser/dev/excalidraw-assets-dev/{en-BF4XUPIZ.js.map → en-Y27YPU72.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{image-LVS32KQQ.js.map → image-J7S3ALXP.js.map} +0 -0
package/dist/dev/index.js
CHANGED
|
@@ -147,7 +147,7 @@ var init_colors = __esm({
|
|
|
147
147
|
});
|
|
148
148
|
|
|
149
149
|
// constants.ts
|
|
150
|
-
var isDarwin, isWindows, isAndroid, isFirefox, isChrome, isSafari, isIOS, isBrave, supportsResizeObserver, APP_NAME, DRAGGING_THRESHOLD, LINE_CONFIRM_THRESHOLD, ELEMENT_SHIFT_TRANSLATE_AMOUNT, ELEMENT_TRANSLATE_AMOUNT, TEXT_TO_CENTER_SNAP_THRESHOLD, SHIFT_LOCKING_ANGLE, DEFAULT_LASER_COLOR, CURSOR_TYPE, POINTER_BUTTON, POINTER_EVENTS, YOUTUBE_STATES, ENV, CLASSES, FONT_FAMILY, THEME, FRAME_STYLE, WINDOWS_EMOJI_FALLBACK_FONT, MIN_FONT_SIZE, DEFAULT_FONT_SIZE, DEFAULT_FONT_FAMILY, DEFAULT_TEXT_ALIGN, DEFAULT_VERTICAL_ALIGN, DEFAULT_TRANSFORM_HANDLE_SPACING, SIDE_RESIZING_THRESHOLD, EPSILON, DEFAULT_COLLISION_THRESHOLD, COLOR_WHITE, COLOR_CHARCOAL_BLACK, COLOR_VOICE_CALL, GRID_SIZE, IMAGE_MIME_TYPES, ALLOWED_PASTE_MIME_TYPES, MIME_TYPES, EXPORT_IMAGE_TYPES, EXPORT_DATA_TYPES, EXPORT_SOURCE, IMAGE_RENDER_TIMEOUT, TAP_TWICE_TIMEOUT, TOUCH_CTX_MENU_TIMEOUT, SCROLL_TIMEOUT, ZOOM_STEP, MIN_ZOOM, MAX_ZOOM, HYPERLINK_TOOLTIP_DELAY, THEME_FILTER, URL_QUERY_KEYS, URL_HASH_KEYS, DEFAULT_UI_OPTIONS, MQ_MAX_WIDTH_PORTRAIT, MQ_MAX_WIDTH_LANDSCAPE, MQ_MAX_HEIGHT_LANDSCAPE, MQ_RIGHT_SIDEBAR_MIN_WIDTH, LIBRARY_SIDEBAR_WIDTH, MAX_DECIMALS_FOR_SVG_EXPORT, EXPORT_SCALES, DEFAULT_EXPORT_PADDING, DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT, MAX_ALLOWED_FILE_BYTES, SVG_NS, VERSIONS, BOUND_TEXT_PADDING, ARROW_LABEL_WIDTH_FRACTION, ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO, VERTICAL_ALIGN, TEXT_ALIGN, ELEMENT_READY_TO_ERASE_OPACITY, DEFAULT_PROPORTIONAL_RADIUS, DEFAULT_ADAPTIVE_RADIUS, ROUNDNESS, ROUGHNESS, STROKE_WIDTH, DEFAULT_ELEMENT_PROPS, LIBRARY_SIDEBAR_TAB, DEFAULT_SIDEBAR, LIBRARY_DISABLED_TYPES, TOOL_TYPE, EDITOR_LS_KEYS, DEFAULT_FILENAME;
|
|
150
|
+
var isDarwin, isWindows, isAndroid, isFirefox, isChrome, isSafari, isIOS, isBrave, supportsResizeObserver, APP_NAME, TEXT_AUTOWRAP_THRESHOLD, DRAGGING_THRESHOLD, LINE_CONFIRM_THRESHOLD, ELEMENT_SHIFT_TRANSLATE_AMOUNT, ELEMENT_TRANSLATE_AMOUNT, TEXT_TO_CENTER_SNAP_THRESHOLD, SHIFT_LOCKING_ANGLE, DEFAULT_LASER_COLOR, CURSOR_TYPE, POINTER_BUTTON, POINTER_EVENTS, YOUTUBE_STATES, ENV, CLASSES, FONT_FAMILY, THEME, FRAME_STYLE, WINDOWS_EMOJI_FALLBACK_FONT, MIN_FONT_SIZE, DEFAULT_FONT_SIZE, DEFAULT_FONT_FAMILY, DEFAULT_TEXT_ALIGN, DEFAULT_VERTICAL_ALIGN, DEFAULT_TRANSFORM_HANDLE_SPACING, SIDE_RESIZING_THRESHOLD, EPSILON, DEFAULT_COLLISION_THRESHOLD, COLOR_WHITE, COLOR_CHARCOAL_BLACK, COLOR_VOICE_CALL, GRID_SIZE, IMAGE_MIME_TYPES, ALLOWED_PASTE_MIME_TYPES, MIME_TYPES, EXPORT_IMAGE_TYPES, EXPORT_DATA_TYPES, EXPORT_SOURCE, IMAGE_RENDER_TIMEOUT, TAP_TWICE_TIMEOUT, TOUCH_CTX_MENU_TIMEOUT, SCROLL_TIMEOUT, ZOOM_STEP, MIN_ZOOM, MAX_ZOOM, HYPERLINK_TOOLTIP_DELAY, THEME_FILTER, URL_QUERY_KEYS, URL_HASH_KEYS, DEFAULT_UI_OPTIONS, MQ_MAX_WIDTH_PORTRAIT, MQ_MAX_WIDTH_LANDSCAPE, MQ_MAX_HEIGHT_LANDSCAPE, MQ_RIGHT_SIDEBAR_MIN_WIDTH, LIBRARY_SIDEBAR_WIDTH, MAX_DECIMALS_FOR_SVG_EXPORT, EXPORT_SCALES, DEFAULT_EXPORT_PADDING, DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT, MAX_ALLOWED_FILE_BYTES, SVG_NS, VERSIONS, BOUND_TEXT_PADDING, ARROW_LABEL_WIDTH_FRACTION, ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO, VERTICAL_ALIGN, TEXT_ALIGN, ELEMENT_READY_TO_ERASE_OPACITY, DEFAULT_PROPORTIONAL_RADIUS, DEFAULT_ADAPTIVE_RADIUS, ROUNDNESS, ROUGHNESS, STROKE_WIDTH, DEFAULT_ELEMENT_PROPS, LIBRARY_SIDEBAR_TAB, DEFAULT_SIDEBAR, LIBRARY_DISABLED_TYPES, TOOL_TYPE, EDITOR_LS_KEYS, DEFAULT_FILENAME;
|
|
151
151
|
var init_constants = __esm({
|
|
152
152
|
"constants.ts"() {
|
|
153
153
|
"use strict";
|
|
@@ -165,6 +165,7 @@ var init_constants = __esm({
|
|
|
165
165
|
isBrave = () => navigator.brave?.isBrave?.name === "isBrave";
|
|
166
166
|
supportsResizeObserver = typeof window !== "undefined" && "ResizeObserver" in window;
|
|
167
167
|
APP_NAME = "Excalidraw";
|
|
168
|
+
TEXT_AUTOWRAP_THRESHOLD = 36;
|
|
168
169
|
DRAGGING_THRESHOLD = 10;
|
|
169
170
|
LINE_CONFIRM_THRESHOLD = 8;
|
|
170
171
|
ELEMENT_SHIFT_TRANSLATE_AMOUNT = 5;
|
|
@@ -1209,18 +1210,10 @@ var init_fractionalIndex = __esm({
|
|
|
1209
1210
|
const indicesGroups = [];
|
|
1210
1211
|
let i = 0;
|
|
1211
1212
|
while (i < elements.length) {
|
|
1212
|
-
if (movedElements.has(elements[i].id)
|
|
1213
|
-
elements[i]?.index,
|
|
1214
|
-
elements[i - 1]?.index,
|
|
1215
|
-
elements[i + 1]?.index
|
|
1216
|
-
)) {
|
|
1213
|
+
if (movedElements.has(elements[i].id)) {
|
|
1217
1214
|
const indicesGroup = [i - 1, i];
|
|
1218
1215
|
while (++i < elements.length) {
|
|
1219
|
-
if (!
|
|
1220
|
-
elements[i]?.index,
|
|
1221
|
-
elements[i - 1]?.index,
|
|
1222
|
-
elements[i + 1]?.index
|
|
1223
|
-
))) {
|
|
1216
|
+
if (!movedElements.has(elements[i].id)) {
|
|
1224
1217
|
break;
|
|
1225
1218
|
}
|
|
1226
1219
|
indicesGroup.push(i);
|
|
@@ -1412,7 +1405,16 @@ var init_Scene = __esm({
|
|
|
1412
1405
|
elements: null,
|
|
1413
1406
|
cache: /* @__PURE__ */ new Map()
|
|
1414
1407
|
};
|
|
1415
|
-
|
|
1408
|
+
/**
|
|
1409
|
+
* Random integer regenerated each scene update.
|
|
1410
|
+
*
|
|
1411
|
+
* Does not relate to elements versions, it's only a renderer
|
|
1412
|
+
* cache-invalidation nonce at the moment.
|
|
1413
|
+
*/
|
|
1414
|
+
sceneNonce;
|
|
1415
|
+
getSceneNonce() {
|
|
1416
|
+
return this.sceneNonce;
|
|
1417
|
+
}
|
|
1416
1418
|
getNonDeletedElementsMap() {
|
|
1417
1419
|
return this.nonDeletedElementsMap;
|
|
1418
1420
|
}
|
|
@@ -1457,9 +1459,6 @@ var init_Scene = __esm({
|
|
|
1457
1459
|
getElement(id) {
|
|
1458
1460
|
return this.elementsMap.get(id) || null;
|
|
1459
1461
|
}
|
|
1460
|
-
getVersionNonce() {
|
|
1461
|
-
return this.versionNonce;
|
|
1462
|
-
}
|
|
1463
1462
|
getNonDeletedElement(id) {
|
|
1464
1463
|
const element = this.getElement(id);
|
|
1465
1464
|
if (element && isNonDeletedElement(element)) {
|
|
@@ -1516,15 +1515,15 @@ var init_Scene = __esm({
|
|
|
1516
1515
|
this.nonDeletedElementsMap = nonDeletedElements.elementsMap;
|
|
1517
1516
|
this.frames = nextFrameLikes;
|
|
1518
1517
|
this.nonDeletedFramesLikes = getNonDeletedElements(this.frames).elements;
|
|
1519
|
-
this.
|
|
1518
|
+
this.triggerUpdate();
|
|
1520
1519
|
}
|
|
1521
|
-
|
|
1522
|
-
this.
|
|
1520
|
+
triggerUpdate() {
|
|
1521
|
+
this.sceneNonce = randomInteger();
|
|
1523
1522
|
for (const callback of Array.from(this.callbacks)) {
|
|
1524
1523
|
callback();
|
|
1525
1524
|
}
|
|
1526
1525
|
}
|
|
1527
|
-
|
|
1526
|
+
onUpdate(cb) {
|
|
1528
1527
|
if (this.callbacks.has(cb)) {
|
|
1529
1528
|
throw new Error();
|
|
1530
1529
|
}
|
|
@@ -4996,7 +4995,7 @@ var init_containerCache = __esm({
|
|
|
4996
4995
|
});
|
|
4997
4996
|
|
|
4998
4997
|
// element/textElement.ts
|
|
4999
|
-
var normalizeText, splitIntoLines, redrawTextBoundingBox, bindTextToShapeAfterDuplication, handleBindTextResize, computeBoundTextPosition, measureText, detectLineHeight, getLineHeightInPx, getVerticalOffset, getApproxMinLineHeight, canvas, getLineWidth, getTextWidth, getTextHeight, parseTokens, wrapText, charWidth, DUMMY_TEXT, getApproxMinLineWidth, getMaxCharWidth, getBoundTextElementId, getBoundTextElement, getContainerElement, getContainerCenter, getContainerCoords, getTextElementAngle, shouldAllowVerticalAlign, suppportsHorizontalAlign, VALID_CONTAINER_TYPES, isValidTextContainer, computeContainerDimensionForBoundText, getBoundTextMaxWidth, getBoundTextMaxHeight, isMeasureTextSupported, DEFAULT_LINE_HEIGHT, FONT_METRICS, getDefaultLineHeight;
|
|
4998
|
+
var normalizeText, splitIntoLines, redrawTextBoundingBox, bindTextToShapeAfterDuplication, handleBindTextResize, computeBoundTextPosition, measureText, detectLineHeight, getLineHeightInPx, getVerticalOffset, getApproxMinLineHeight, canvas, getLineWidth, getTextWidth, getTextHeight, parseTokens, wrapText, charWidth, DUMMY_TEXT, getApproxMinLineWidth, getMaxCharWidth, getBoundTextElementId, getBoundTextElement, getContainerElement, getContainerCenter, getContainerCoords, getTextElementAngle, shouldAllowVerticalAlign, suppportsHorizontalAlign, VALID_CONTAINER_TYPES, isValidTextContainer, computeContainerDimensionForBoundText, getBoundTextMaxWidth, getBoundTextMaxHeight, isMeasureTextSupported, DEFAULT_LINE_HEIGHT, FONT_METRICS, getDefaultLineHeight, getMinTextElementWidth;
|
|
5000
4999
|
var init_textElement = __esm({
|
|
5001
5000
|
"element/textElement.ts"() {
|
|
5002
5001
|
"use strict";
|
|
@@ -5025,8 +5024,8 @@ var init_textElement = __esm({
|
|
|
5025
5024
|
angle: container?.angle ?? textElement.angle
|
|
5026
5025
|
};
|
|
5027
5026
|
boundTextUpdates.text = textElement.text;
|
|
5028
|
-
if (container) {
|
|
5029
|
-
maxWidth = getBoundTextMaxWidth(container, textElement);
|
|
5027
|
+
if (container || !textElement.autoResize) {
|
|
5028
|
+
maxWidth = container ? getBoundTextMaxWidth(container, textElement) : textElement.width;
|
|
5030
5029
|
boundTextUpdates.text = wrapText(
|
|
5031
5030
|
textElement.originalText,
|
|
5032
5031
|
getFontString(textElement),
|
|
@@ -5038,7 +5037,9 @@ var init_textElement = __esm({
|
|
|
5038
5037
|
getFontString(textElement),
|
|
5039
5038
|
textElement.lineHeight
|
|
5040
5039
|
);
|
|
5041
|
-
|
|
5040
|
+
if (textElement.autoResize) {
|
|
5041
|
+
boundTextUpdates.width = metrics.width;
|
|
5042
|
+
}
|
|
5042
5043
|
boundTextUpdates.height = metrics.height;
|
|
5043
5044
|
if (container) {
|
|
5044
5045
|
const maxContainerHeight = getBoundTextMaxHeight(
|
|
@@ -5583,6 +5584,9 @@ var init_textElement = __esm({
|
|
|
5583
5584
|
}
|
|
5584
5585
|
return DEFAULT_LINE_HEIGHT[DEFAULT_FONT_FAMILY];
|
|
5585
5586
|
};
|
|
5587
|
+
getMinTextElementWidth = (font, lineHeight) => {
|
|
5588
|
+
return measureText("", font, lineHeight).width + BOUND_TEXT_PADDING * 2;
|
|
5589
|
+
};
|
|
5586
5590
|
}
|
|
5587
5591
|
});
|
|
5588
5592
|
|
|
@@ -6757,7 +6761,7 @@ var init_cursor = __esm({
|
|
|
6757
6761
|
});
|
|
6758
6762
|
|
|
6759
6763
|
// element/newElement.ts
|
|
6760
|
-
var _newElementBase, newElement, newEmbeddableElement, newIframeElement, newFrameElement, newMagicFrameElement, getTextElementPositionOffsets, newTextElement, getAdjustedDimensions, refreshTextDimensions,
|
|
6764
|
+
var _newElementBase, newElement, newEmbeddableElement, newIframeElement, newFrameElement, newMagicFrameElement, getTextElementPositionOffsets, newTextElement, getAdjustedDimensions, refreshTextDimensions, newFreeDrawElement, newLinearElement, newImageElement, _deepCopyElement, deepCopyElement, regenerateId, duplicateElement, duplicateElements;
|
|
6761
6765
|
var init_newElement = __esm({
|
|
6762
6766
|
"element/newElement.ts"() {
|
|
6763
6767
|
"use strict";
|
|
@@ -6877,36 +6881,41 @@ var init_newElement = __esm({
|
|
|
6877
6881
|
{ textAlign, verticalAlign },
|
|
6878
6882
|
metrics
|
|
6879
6883
|
);
|
|
6884
|
+
const textElementProps = {
|
|
6885
|
+
..._newElementBase("text", opts),
|
|
6886
|
+
text,
|
|
6887
|
+
fontSize,
|
|
6888
|
+
fontFamily,
|
|
6889
|
+
textAlign,
|
|
6890
|
+
verticalAlign,
|
|
6891
|
+
x: opts.x - offsets.x,
|
|
6892
|
+
y: opts.y - offsets.y,
|
|
6893
|
+
width: metrics.width,
|
|
6894
|
+
height: metrics.height,
|
|
6895
|
+
containerId: opts.containerId || null,
|
|
6896
|
+
originalText: opts.originalText ?? text,
|
|
6897
|
+
autoResize: opts.autoResize ?? true,
|
|
6898
|
+
lineHeight
|
|
6899
|
+
};
|
|
6880
6900
|
const textElement = newElementWith(
|
|
6881
|
-
|
|
6882
|
-
..._newElementBase("text", opts),
|
|
6883
|
-
text,
|
|
6884
|
-
fontSize,
|
|
6885
|
-
fontFamily,
|
|
6886
|
-
textAlign,
|
|
6887
|
-
verticalAlign,
|
|
6888
|
-
x: opts.x - offsets.x,
|
|
6889
|
-
y: opts.y - offsets.y,
|
|
6890
|
-
width: metrics.width,
|
|
6891
|
-
height: metrics.height,
|
|
6892
|
-
containerId: opts.containerId || null,
|
|
6893
|
-
originalText: text,
|
|
6894
|
-
lineHeight
|
|
6895
|
-
},
|
|
6901
|
+
textElementProps,
|
|
6896
6902
|
{}
|
|
6897
6903
|
);
|
|
6898
6904
|
return textElement;
|
|
6899
6905
|
};
|
|
6900
6906
|
getAdjustedDimensions = (element, elementsMap, nextText) => {
|
|
6901
|
-
|
|
6907
|
+
let { width: nextWidth, height: nextHeight } = measureText(
|
|
6902
6908
|
nextText,
|
|
6903
6909
|
getFontString(element),
|
|
6904
6910
|
element.lineHeight
|
|
6905
6911
|
);
|
|
6912
|
+
if (!element.autoResize) {
|
|
6913
|
+
nextWidth = element.width;
|
|
6914
|
+
}
|
|
6906
6915
|
const { textAlign, verticalAlign } = element;
|
|
6907
6916
|
let x;
|
|
6908
6917
|
let y;
|
|
6909
|
-
if (textAlign === "center" && verticalAlign === VERTICAL_ALIGN.MIDDLE && !element.containerId) {
|
|
6918
|
+
if (textAlign === "center" && verticalAlign === VERTICAL_ALIGN.MIDDLE && !element.containerId && element.autoResize) {
|
|
6910
6919
|
const prevMetrics = measureText(
|
|
6911
6920
|
element.text,
|
|
6912
6921
|
getFontString(element),
|
|
@@ -6956,27 +6965,16 @@ var init_newElement = __esm({
|
|
|
6956
6965
|
if (textElement.isDeleted) {
|
|
6957
6966
|
return;
|
|
6958
6967
|
}
|
|
6959
|
-
if (container) {
|
|
6968
|
+
if (container || !textElement.autoResize) {
|
|
6960
6969
|
text = wrapText(
|
|
6961
6970
|
text,
|
|
6962
6971
|
getFontString(textElement),
|
|
6963
|
-
getBoundTextMaxWidth(container, textElement)
|
|
6972
|
+
container ? getBoundTextMaxWidth(container, textElement) : textElement.width
|
|
6964
6973
|
);
|
|
6965
6974
|
}
|
|
6966
6975
|
const dimensions = getAdjustedDimensions(textElement, elementsMap, text);
|
|
6967
6976
|
return { text, ...dimensions };
|
|
6968
6977
|
};
|
|
6969
|
-
updateTextElement = (textElement, container, elementsMap, {
|
|
6970
|
-
text,
|
|
6971
|
-
isDeleted,
|
|
6972
|
-
originalText
|
|
6973
|
-
}) => {
|
|
6974
|
-
return newElementWith(textElement, {
|
|
6975
|
-
originalText,
|
|
6976
|
-
isDeleted: isDeleted ?? textElement.isDeleted,
|
|
6977
|
-
...refreshTextDimensions(textElement, container, elementsMap, originalText)
|
|
6978
|
-
});
|
|
6979
|
-
};
|
|
6980
6978
|
newFreeDrawElement = (opts) => {
|
|
6981
6979
|
return {
|
|
6982
6980
|
..._newElementBase(opts.type, opts),
|
|
@@ -8078,12 +8076,22 @@ var init_change = __esm({
|
|
|
8078
8076
|
if (!flags.containsZindexDifference) {
|
|
8079
8077
|
return elements;
|
|
8080
8078
|
}
|
|
8081
|
-
const
|
|
8082
|
-
const
|
|
8083
|
-
|
|
8079
|
+
const unordered = Array.from(elements.values());
|
|
8080
|
+
const ordered = orderByFractionalIndex([...unordered]);
|
|
8081
|
+
const moved = Delta.getRightDifferences(unordered, ordered, true).reduce(
|
|
8082
|
+
(acc, arrayIndex) => {
|
|
8083
|
+
const candidate = unordered[Number(arrayIndex)];
|
|
8084
|
+
if (candidate && changed.has(candidate.id)) {
|
|
8085
|
+
acc.set(candidate.id, candidate);
|
|
8086
|
+
}
|
|
8087
|
+
return acc;
|
|
8088
|
+
},
|
|
8089
|
+
/* @__PURE__ */ new Map()
|
|
8090
|
+
);
|
|
8091
|
+
if (!flags.containsVisibleDifference && moved.size) {
|
|
8084
8092
|
flags.containsVisibleDifference = true;
|
|
8085
8093
|
}
|
|
8086
|
-
return arrayToMap(syncMovedIndices(
|
|
8094
|
+
return arrayToMap(syncMovedIndices(ordered, moved));
|
|
8087
8095
|
}
|
|
8088
8096
|
/**
|
|
8089
8097
|
* It is necessary to post process the partials in case of reference values,
|
|
@@ -8184,8 +8192,35 @@ var init_store = __esm({
|
|
|
8184
8192
|
};
|
|
8185
8193
|
isObservedAppState = (appState) => !!Reflect.get(appState, hiddenObservedAppStateProp);
|
|
8186
8194
|
StoreAction = {
|
|
8195
|
+
/**
|
|
8196
|
+
* Immediately undoable.
|
|
8197
|
+
*
|
|
8198
|
+
* Use for updates which should be captured.
|
|
8199
|
+
* Should be used for most of the local updates.
|
|
8200
|
+
*
|
|
8201
|
+
* These updates will _immediately_ make it to the local undo / redo stacks.
|
|
8202
|
+
*/
|
|
8187
8203
|
CAPTURE: "capture",
|
|
8204
|
+
/**
|
|
8205
|
+
* Never undoable.
|
|
8206
|
+
*
|
|
8207
|
+
* Use for updates which should never be recorded, such as remote updates
|
|
8208
|
+
* or scene initialization.
|
|
8209
|
+
*
|
|
8210
|
+
* These updates will _never_ make it to the local undo / redo stacks.
|
|
8211
|
+
*/
|
|
8188
8212
|
UPDATE: "update",
|
|
8213
|
+
/**
|
|
8214
|
+
* Eventually undoable.
|
|
8215
|
+
*
|
|
8216
|
+
* Use for updates which should not be captured immediately - likely
|
|
8217
|
+
* exceptions which are part of some async multi-step process. Otherwise, all
|
|
8218
|
+
* such updates would end up being captured with the next
|
|
8219
|
+
* `StoreAction.CAPTURE` - triggered either by the next `updateScene`
|
|
8220
|
+
* or internally by the editor.
|
|
8221
|
+
*
|
|
8222
|
+
* These updates will _eventually_ make it to the local undo / redo stacks.
|
|
8223
|
+
*/
|
|
8189
8224
|
NONE: "none"
|
|
8190
8225
|
};
|
|
8191
8226
|
StoreIncrementEvent = class {
|
|
@@ -9345,6 +9380,7 @@ var init_restore = __esm({
|
|
|
9345
9380
|
init_textElement();
|
|
9346
9381
|
init_url();
|
|
9347
9382
|
init_fractionalIndex();
|
|
9383
|
+
init_points();
|
|
9348
9384
|
AllowedExcalidrawActiveTools = {
|
|
9349
9385
|
selection: true,
|
|
9350
9386
|
text: true,
|
|
@@ -9446,6 +9482,7 @@ var init_restore = __esm({
|
|
|
9446
9482
|
verticalAlign: element.verticalAlign || DEFAULT_VERTICAL_ALIGN,
|
|
9447
9483
|
containerId: element.containerId ?? null,
|
|
9448
9484
|
originalText: element.originalText || text,
|
|
9485
|
+
autoResize: element.autoResize ?? true,
|
|
9449
9486
|
lineHeight
|
|
9450
9487
|
});
|
|
9451
9488
|
if (!text && !element.isDeleted) {
|
|
@@ -9495,7 +9532,8 @@ var init_restore = __esm({
|
|
|
9495
9532
|
endArrowhead,
|
|
9496
9533
|
points,
|
|
9497
9534
|
x,
|
|
9498
|
-
y
|
|
9535
|
+
y,
|
|
9536
|
+
...getSizeFromPoints(points)
|
|
9499
9537
|
});
|
|
9500
9538
|
}
|
|
9501
9539
|
case "ellipse":
|
|
@@ -11303,7 +11341,7 @@ var init_export = __esm({
|
|
|
11303
11341
|
}
|
|
11304
11342
|
let assetPath = "https://excalidraw.com/";
|
|
11305
11343
|
if (define_import_meta_env_default.VITE_IS_EXCALIDRAW_NPM_PACKAGE) {
|
|
11306
|
-
assetPath = window.EXCALIDRAW_ASSET_PATH || `https://unpkg.com/${define_import_meta_env_default.VITE_PKG_NAME}@${define_import_meta_env_default.
|
|
11344
|
+
assetPath = window.EXCALIDRAW_ASSET_PATH || `https://unpkg.com/${define_import_meta_env_default.VITE_PKG_NAME}@${define_import_meta_env_default.VITE_PKG_VERSION}`;
|
|
11307
11345
|
if (assetPath?.startsWith("/")) {
|
|
11308
11346
|
assetPath = assetPath.replace("/", `${window.location.origin}/`);
|
|
11309
11347
|
}
|
|
@@ -13196,14 +13234,14 @@ var init_renderElement = __esm({
|
|
|
13196
13234
|
}
|
|
13197
13235
|
context.restore();
|
|
13198
13236
|
};
|
|
13199
|
-
renderSelectionElement = (element, context, appState) => {
|
|
13237
|
+
renderSelectionElement = (element, context, appState, selectionColor) => {
|
|
13200
13238
|
context.save();
|
|
13201
13239
|
context.translate(element.x + appState.scrollX, element.y + appState.scrollY);
|
|
13202
13240
|
context.fillStyle = "rgba(0, 0, 200, 0.04)";
|
|
13203
13241
|
const offset2 = 0.5 / appState.zoom.value;
|
|
13204
13242
|
context.fillRect(offset2, offset2, element.width, element.height);
|
|
13205
13243
|
context.lineWidth = 1 / appState.zoom.value;
|
|
13206
|
-
context.strokeStyle =
|
|
13244
|
+
context.strokeStyle = selectionColor;
|
|
13207
13245
|
context.strokeRect(offset2, offset2, element.width, element.height);
|
|
13208
13246
|
context.restore();
|
|
13209
13247
|
};
|
|
@@ -13524,11 +13562,11 @@ var init_mutateElement = __esm({
|
|
|
13524
13562
|
element.versionNonce = randomInteger();
|
|
13525
13563
|
element.updated = getUpdatedTimestamp();
|
|
13526
13564
|
if (informMutation) {
|
|
13527
|
-
Scene_default.getScene(element)?.
|
|
13565
|
+
Scene_default.getScene(element)?.triggerUpdate();
|
|
13528
13566
|
}
|
|
13529
13567
|
return element;
|
|
13530
13568
|
};
|
|
13531
|
-
newElementWith = (element, updates) => {
|
|
13569
|
+
newElementWith = (element, updates, force = false) => {
|
|
13532
13570
|
let didChange = false;
|
|
13533
13571
|
for (const key in updates) {
|
|
13534
13572
|
const value = updates[key];
|
|
@@ -13540,7 +13578,7 @@ var init_mutateElement = __esm({
|
|
|
13540
13578
|
didChange = true;
|
|
13541
13579
|
}
|
|
13542
13580
|
}
|
|
13543
|
-
if (!didChange) {
|
|
13581
|
+
if (!didChange && !force) {
|
|
13544
13582
|
return element;
|
|
13545
13583
|
}
|
|
13546
13584
|
return {
|
|
@@ -13657,14 +13695,13 @@ var init_sizeHelpers = __esm({
|
|
|
13657
13695
|
});
|
|
13658
13696
|
|
|
13659
13697
|
// element/transformHandles.ts
|
|
13660
|
-
var transformHandleSizes, ROTATION_RESIZE_HANDLE_GAP, DEFAULT_OMIT_SIDES,
|
|
13698
|
+
var transformHandleSizes, ROTATION_RESIZE_HANDLE_GAP, DEFAULT_OMIT_SIDES, OMIT_SIDES_FOR_LINE_SLASH, OMIT_SIDES_FOR_LINE_BACKSLASH, generateTransformHandle, canResizeFromSides, getOmitSidesForDevice, getTransformHandlesFromCoords, getTransformHandles, shouldShowBoundingBox;
|
|
13661
13699
|
var init_transformHandles = __esm({
|
|
13662
13700
|
"element/transformHandles.ts"() {
|
|
13663
13701
|
"use strict";
|
|
13664
13702
|
init_define_import_meta_env();
|
|
13665
13703
|
init_bounds();
|
|
13666
13704
|
init_math();
|
|
13667
|
-
init_element();
|
|
13668
13705
|
init_typeChecks();
|
|
13669
13706
|
init_constants();
|
|
13670
13707
|
transformHandleSizes = {
|
|
@@ -13679,12 +13716,6 @@ var init_transformHandles = __esm({
|
|
|
13679
13716
|
n: true,
|
|
13680
13717
|
w: true
|
|
13681
13718
|
};
|
|
13682
|
-
OMIT_SIDES_FOR_TEXT_ELEMENT = {
|
|
13683
|
-
e: true,
|
|
13684
|
-
s: true,
|
|
13685
|
-
n: true,
|
|
13686
|
-
w: true
|
|
13687
|
-
};
|
|
13688
13719
|
OMIT_SIDES_FOR_LINE_SLASH = {
|
|
13689
13720
|
e: true,
|
|
13690
13721
|
s: true,
|
|
@@ -13845,8 +13876,6 @@ var init_transformHandles = __esm({
|
|
|
13845
13876
|
omitSides = OMIT_SIDES_FOR_LINE_BACKSLASH;
|
|
13846
13877
|
}
|
|
13847
13878
|
}
|
|
13848
|
-
} else if (isTextElement(element)) {
|
|
13849
|
-
omitSides = OMIT_SIDES_FOR_TEXT_ELEMENT;
|
|
13850
13879
|
} else if (isFrameLikeElement(element)) {
|
|
13851
13880
|
omitSides = {
|
|
13852
13881
|
...omitSides,
|
|
@@ -13920,7 +13949,7 @@ var init_resizeTest = __esm({
|
|
|
13920
13949
|
element,
|
|
13921
13950
|
elementsMap
|
|
13922
13951
|
);
|
|
13923
|
-
if (
|
|
13952
|
+
if (!(isLinearElement(element) && element.points.length <= 2)) {
|
|
13924
13953
|
const SPACING = SIDE_RESIZING_THRESHOLD / zoom.value;
|
|
13925
13954
|
const sides = getSelectionBorders(
|
|
13926
13955
|
[x1 - SPACING, y1 - SPACING],
|
|
@@ -14088,8 +14117,9 @@ var init_resizeElements = __esm({
|
|
|
14088
14117
|
shouldRotateWithDiscreteAngle2
|
|
14089
14118
|
);
|
|
14090
14119
|
updateBoundElements(element, elementsMap);
|
|
14091
|
-
} else if (isTextElement(element) &&
|
|
14120
|
+
} else if (isTextElement(element) && transformHandleType) {
|
|
14092
14121
|
resizeSingleTextElement(
|
|
14122
|
+
originalElements,
|
|
14093
14123
|
element,
|
|
14094
14124
|
elementsMap,
|
|
14095
14125
|
transformHandleType,
|
|
@@ -14191,7 +14221,7 @@ var init_resizeElements = __esm({
|
|
|
14191
14221
|
size: nextFontSize
|
|
14192
14222
|
};
|
|
14193
14223
|
};
|
|
14194
|
-
resizeSingleTextElement = (element, elementsMap, transformHandleType, shouldResizeFromCenter2, pointerX, pointerY) => {
|
|
14224
|
+
resizeSingleTextElement = (originalElements, element, elementsMap, transformHandleType, shouldResizeFromCenter2, pointerX, pointerY) => {
|
|
14195
14225
|
const [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(
|
|
14196
14226
|
element,
|
|
14197
14227
|
elementsMap
|
|
@@ -14205,17 +14235,19 @@ var init_resizeElements = __esm({
|
|
|
14205
14235
|
);
|
|
14206
14236
|
let scaleX = 0;
|
|
14207
14237
|
let scaleY = 0;
|
|
14208
|
-
if (transformHandleType
|
|
14209
|
-
|
|
14210
|
-
|
|
14211
|
-
|
|
14212
|
-
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
|
|
14216
|
-
|
|
14217
|
-
|
|
14218
|
-
|
|
14238
|
+
if (transformHandleType !== "e" && transformHandleType !== "w") {
|
|
14239
|
+
if (transformHandleType.includes("e")) {
|
|
14240
|
+
scaleX = (rotatedX - x1) / (x2 - x1);
|
|
14241
|
+
}
|
|
14242
|
+
if (transformHandleType.includes("w")) {
|
|
14243
|
+
scaleX = (x2 - rotatedX) / (x2 - x1);
|
|
14244
|
+
}
|
|
14245
|
+
if (transformHandleType.includes("n")) {
|
|
14246
|
+
scaleY = (y2 - rotatedY) / (y2 - y1);
|
|
14247
|
+
}
|
|
14248
|
+
if (transformHandleType.includes("s")) {
|
|
14249
|
+
scaleY = (rotatedY - y1) / (y2 - y1);
|
|
14250
|
+
}
|
|
14219
14251
|
}
|
|
14220
14252
|
const scale = Math.max(scaleX, scaleY);
|
|
14221
14253
|
if (scale > 0) {
|
|
@@ -14270,6 +14302,89 @@ var init_resizeElements = __esm({
|
|
|
14270
14302
|
y: nextY
|
|
14271
14303
|
});
|
|
14272
14304
|
}
|
|
14305
|
+
if (transformHandleType === "e" || transformHandleType === "w") {
|
|
14306
|
+
const stateAtResizeStart = originalElements.get(element.id);
|
|
14307
|
+
const [x12, y12, x22, y22] = getResizedElementAbsoluteCoords(
|
|
14308
|
+
stateAtResizeStart,
|
|
14309
|
+
stateAtResizeStart.width,
|
|
14310
|
+
stateAtResizeStart.height,
|
|
14311
|
+
true
|
|
14312
|
+
);
|
|
14313
|
+
const startTopLeft = [x12, y12];
|
|
14314
|
+
const startBottomRight = [x22, y22];
|
|
14315
|
+
const startCenter = centerPoint(startTopLeft, startBottomRight);
|
|
14316
|
+
const rotatedPointer = rotatePoint(
|
|
14317
|
+
[pointerX, pointerY],
|
|
14318
|
+
startCenter,
|
|
14319
|
+
-stateAtResizeStart.angle
|
|
14320
|
+
);
|
|
14321
|
+
const [esx1, , esx2] = getResizedElementAbsoluteCoords(
|
|
14322
|
+
element,
|
|
14323
|
+
element.width,
|
|
14324
|
+
element.height,
|
|
14325
|
+
true
|
|
14326
|
+
);
|
|
14327
|
+
const boundsCurrentWidth = esx2 - esx1;
|
|
14328
|
+
const atStartBoundsWidth = startBottomRight[0] - startTopLeft[0];
|
|
14329
|
+
const minWidth = getMinTextElementWidth(
|
|
14330
|
+
getFontString({
|
|
14331
|
+
fontSize: element.fontSize,
|
|
14332
|
+
fontFamily: element.fontFamily
|
|
14333
|
+
}),
|
|
14334
|
+
element.lineHeight
|
|
14335
|
+
);
|
|
14336
|
+
let scaleX2 = atStartBoundsWidth / boundsCurrentWidth;
|
|
14337
|
+
if (transformHandleType.includes("e")) {
|
|
14338
|
+
scaleX2 = (rotatedPointer[0] - startTopLeft[0]) / boundsCurrentWidth;
|
|
14339
|
+
}
|
|
14340
|
+
if (transformHandleType.includes("w")) {
|
|
14341
|
+
scaleX2 = (startBottomRight[0] - rotatedPointer[0]) / boundsCurrentWidth;
|
|
14342
|
+
}
|
|
14343
|
+
const newWidth = element.width * scaleX2 < minWidth ? minWidth : element.width * scaleX2;
|
|
14344
|
+
const text = wrapText(
|
|
14345
|
+
element.originalText,
|
|
14346
|
+
getFontString(element),
|
|
14347
|
+
Math.abs(newWidth)
|
|
14348
|
+
);
|
|
14349
|
+
const metrics = measureText(
|
|
14350
|
+
text,
|
|
14351
|
+
getFontString(element),
|
|
14352
|
+
element.lineHeight
|
|
14353
|
+
);
|
|
14354
|
+
const eleNewHeight = metrics.height;
|
|
14355
|
+
const [newBoundsX1, newBoundsY1, newBoundsX2, newBoundsY2] = getResizedElementAbsoluteCoords(
|
|
14356
|
+
stateAtResizeStart,
|
|
14357
|
+
newWidth,
|
|
14358
|
+
eleNewHeight,
|
|
14359
|
+
true
|
|
14360
|
+
);
|
|
14361
|
+
const newBoundsWidth = newBoundsX2 - newBoundsX1;
|
|
14362
|
+
const newBoundsHeight = newBoundsY2 - newBoundsY1;
|
|
14363
|
+
let newTopLeft = [...startTopLeft];
|
|
14364
|
+
if (["n", "w", "nw"].includes(transformHandleType)) {
|
|
14365
|
+
newTopLeft = [
|
|
14366
|
+
startBottomRight[0] - Math.abs(newBoundsWidth),
|
|
14367
|
+
startTopLeft[1]
|
|
14368
|
+
];
|
|
14369
|
+
}
|
|
14370
|
+
const angle = stateAtResizeStart.angle;
|
|
14371
|
+
const rotatedTopLeft = rotatePoint(newTopLeft, startCenter, angle);
|
|
14372
|
+
const newCenter = [
|
|
14373
|
+
newTopLeft[0] + Math.abs(newBoundsWidth) / 2,
|
|
14374
|
+
newTopLeft[1] + Math.abs(newBoundsHeight) / 2
|
|
14375
|
+
];
|
|
14376
|
+
const rotatedNewCenter = rotatePoint(newCenter, startCenter, angle);
|
|
14377
|
+
newTopLeft = rotatePoint(rotatedTopLeft, rotatedNewCenter, -angle);
|
|
14378
|
+
const resizedElement = {
|
|
14379
|
+
width: Math.abs(newWidth),
|
|
14380
|
+
height: Math.abs(metrics.height),
|
|
14381
|
+
x: newTopLeft[0],
|
|
14382
|
+
y: newTopLeft[1],
|
|
14383
|
+
text,
|
|
14384
|
+
autoResize: false
|
|
14385
|
+
};
|
|
14386
|
+
mutateElement(element, resizedElement);
|
|
14387
|
+
}
|
|
14273
14388
|
};
|
|
14274
14389
|
resizeSingleElement = (originalElements, shouldMaintainAspectRatio2, element, elementsMap, transformHandleDirection, shouldResizeFromCenter2, pointerX, pointerY) => {
|
|
14275
14390
|
const stateAtResizeStart = originalElements.get(element.id);
|
|
@@ -14661,7 +14776,7 @@ var init_resizeElements = __esm({
|
|
|
14661
14776
|
handleBindTextResize(element, elementsMap, transformHandleType, true);
|
|
14662
14777
|
}
|
|
14663
14778
|
}
|
|
14664
|
-
Scene_default.getScene(elementsAndUpdates[0].element)?.
|
|
14779
|
+
Scene_default.getScene(elementsAndUpdates[0].element)?.triggerUpdate();
|
|
14665
14780
|
};
|
|
14666
14781
|
rotateMultipleElements = (originalElements, elements, elementsMap, pointerX, pointerY, shouldRotateWithDiscreteAngle2, centerX, centerY) => {
|
|
14667
14782
|
let centerAngle = 5 * Math.PI / 2 + Math.atan2(pointerY - centerY, pointerX - centerX);
|
|
@@ -14706,7 +14821,7 @@ var init_resizeElements = __esm({
|
|
|
14706
14821
|
);
|
|
14707
14822
|
}
|
|
14708
14823
|
});
|
|
14709
|
-
Scene_default.getScene(elements[0])?.
|
|
14824
|
+
Scene_default.getScene(elements[0])?.triggerUpdate();
|
|
14710
14825
|
};
|
|
14711
14826
|
getResizeOffsetXY = (transformHandleType, selectedElements, elementsMap, x, y) => {
|
|
14712
14827
|
const [x1, y1, x2, y2] = selectedElements.length === 1 ? getElementAbsoluteCoords(selectedElements[0], elementsMap) : getCommonBounds(selectedElements);
|
|
@@ -14756,6 +14871,8 @@ var init_dragElements = __esm({
|
|
|
14756
14871
|
init_textElement();
|
|
14757
14872
|
init_math();
|
|
14758
14873
|
init_typeChecks();
|
|
14874
|
+
init_utils();
|
|
14875
|
+
init_constants();
|
|
14759
14876
|
dragSelectedElements = (pointerDownState, selectedElements, offset2, appState, scene, snapOffset, gridSize) => {
|
|
14760
14877
|
const elementsToUpdate = new Set(
|
|
14761
14878
|
selectedElements
|
|
@@ -14833,7 +14950,7 @@ var init_dragElements = __esm({
|
|
|
14833
14950
|
const [x1, y1] = getCommonBounds(selectedElements);
|
|
14834
14951
|
return [x - x1, y - y1];
|
|
14835
14952
|
};
|
|
14836
|
-
dragNewElement = (draggingElement, elementType, originX, originY, x, y, width, height, shouldMaintainAspectRatio2, shouldResizeFromCenter2, widthAspectRatio, originOffset = null) => {
|
|
14953
|
+
dragNewElement = (draggingElement, elementType, originX, originY, x, y, width, height, shouldMaintainAspectRatio2, shouldResizeFromCenter2, zoom, widthAspectRatio, originOffset = null) => {
|
|
14837
14954
|
if (shouldMaintainAspectRatio2 && draggingElement.type !== "selection") {
|
|
14838
14955
|
if (widthAspectRatio) {
|
|
14839
14956
|
height = width / widthAspectRatio;
|
|
@@ -14864,12 +14981,34 @@ var init_dragElements = __esm({
|
|
|
14864
14981
|
newX = originX - width / 2;
|
|
14865
14982
|
newY = originY - height / 2;
|
|
14866
14983
|
}
|
|
14984
|
+
let textAutoResize = null;
|
|
14985
|
+
if (isTextElement(draggingElement)) {
|
|
14986
|
+
height = draggingElement.height;
|
|
14987
|
+
const minWidth = getMinTextElementWidth(
|
|
14988
|
+
getFontString({
|
|
14989
|
+
fontSize: draggingElement.fontSize,
|
|
14990
|
+
fontFamily: draggingElement.fontFamily
|
|
14991
|
+
}),
|
|
14992
|
+
draggingElement.lineHeight
|
|
14993
|
+
);
|
|
14994
|
+
width = Math.max(width, minWidth);
|
|
14995
|
+
if (Math.abs(x - originX) > TEXT_AUTOWRAP_THRESHOLD / zoom) {
|
|
14996
|
+
textAutoResize = {
|
|
14997
|
+
autoResize: false
|
|
14998
|
+
};
|
|
14999
|
+
}
|
|
15000
|
+
newY = originY;
|
|
15001
|
+
if (shouldResizeFromCenter2) {
|
|
15002
|
+
newX = originX - width / 2;
|
|
15003
|
+
}
|
|
15004
|
+
}
|
|
14867
15005
|
if (width !== 0 && height !== 0) {
|
|
14868
15006
|
mutateElement(draggingElement, {
|
|
14869
15007
|
x: newX + (originOffset?.x ?? 0),
|
|
14870
15008
|
y: newY + (originOffset?.y ?? 0),
|
|
14871
15009
|
width,
|
|
14872
|
-
height
|
|
15010
|
+
height,
|
|
15011
|
+
...textAutoResize
|
|
14873
15012
|
});
|
|
14874
15013
|
}
|
|
14875
15014
|
};
|
|
@@ -15193,7 +15332,7 @@ init_define_import_meta_env();
|
|
|
15193
15332
|
|
|
15194
15333
|
// i18n.ts
|
|
15195
15334
|
init_define_import_meta_env();
|
|
15196
|
-
import fallbackLangData from "./en-
|
|
15335
|
+
import fallbackLangData from "./en-OIPCBIOA.json";
|
|
15197
15336
|
import percentages from "./percentages-UCQDHIQF.json";
|
|
15198
15337
|
|
|
15199
15338
|
// jotai.ts
|
|
@@ -15217,7 +15356,7 @@ var globImport_locales_json = __glob({
|
|
|
15217
15356
|
"./locales/da-DK.json": () => import("./da-DK-WBEQB3CJ.json"),
|
|
15218
15357
|
"./locales/de-DE.json": () => import("./de-DE-VEIMCP7R.json"),
|
|
15219
15358
|
"./locales/el-GR.json": () => import("./el-GR-TKRKG5GQ.json"),
|
|
15220
|
-
"./locales/en.json": () => import("./en-
|
|
15359
|
+
"./locales/en.json": () => import("./en-OIPCBIOA.json"),
|
|
15221
15360
|
"./locales/es-ES.json": () => import("./es-ES-TOLWEZNW.json"),
|
|
15222
15361
|
"./locales/eu-ES.json": () => import("./eu-ES-7CDRJQWJ.json"),
|
|
15223
15362
|
"./locales/fa-IR.json": () => import("./fa-IR-527E2XGU.json"),
|
|
@@ -16302,12 +16441,16 @@ var arrownNarrowUpJSX = /* @__PURE__ */ jsxs3("g", { strokeWidth: 1.5, children:
|
|
|
16302
16441
|
var BringForwardIcon = createIcon(arrownNarrowUpJSX, tablerIconProps);
|
|
16303
16442
|
var SendBackwardIcon = createIcon(arrownNarrowUpJSX, {
|
|
16304
16443
|
...tablerIconProps,
|
|
16305
|
-
|
|
16444
|
+
style: {
|
|
16445
|
+
transform: "rotate(180deg)"
|
|
16446
|
+
}
|
|
16306
16447
|
});
|
|
16307
16448
|
var BringToFrontIcon = createIcon(arrowBarToTopJSX, tablerIconProps);
|
|
16308
16449
|
var SendToBackIcon = createIcon(arrowBarToTopJSX, {
|
|
16309
16450
|
...tablerIconProps,
|
|
16310
|
-
|
|
16451
|
+
style: {
|
|
16452
|
+
transform: "rotate(180deg)"
|
|
16453
|
+
}
|
|
16311
16454
|
});
|
|
16312
16455
|
var AlignTopIcon = createIcon(
|
|
16313
16456
|
/* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
@@ -18625,6 +18768,7 @@ var ButtonIconSelect = (props) => /* @__PURE__ */ jsx9("div", { className: "butt
|
|
|
18625
18768
|
(option) => props.type === "button" ? /* @__PURE__ */ jsx9(
|
|
18626
18769
|
"button",
|
|
18627
18770
|
{
|
|
18771
|
+
type: "button",
|
|
18628
18772
|
onClick: (event) => props.onClick(option.value, event),
|
|
18629
18773
|
className: clsx4({
|
|
18630
18774
|
active: option.active ?? props.value === option.value
|
|
@@ -20133,6 +20277,7 @@ function Picker2({
|
|
|
20133
20277
|
children: /* @__PURE__ */ jsx20("div", { className: "picker-content", ref: rGallery, children: options.map((option, i) => /* @__PURE__ */ jsxs12(
|
|
20134
20278
|
"button",
|
|
20135
20279
|
{
|
|
20280
|
+
type: "button",
|
|
20136
20281
|
className: clsx11("picker-option", {
|
|
20137
20282
|
active: value === option.value
|
|
20138
20283
|
}),
|
|
@@ -20179,6 +20324,7 @@ function IconPicker({
|
|
|
20179
20324
|
"button",
|
|
20180
20325
|
{
|
|
20181
20326
|
name: group,
|
|
20327
|
+
type: "button",
|
|
20182
20328
|
className: isActive ? "active" : "",
|
|
20183
20329
|
"aria-label": label,
|
|
20184
20330
|
onClick: () => setActive(!isActive),
|
|
@@ -20262,7 +20408,7 @@ var getFormValue = function(elements, appState, getAttribute, isRelevantElement,
|
|
|
20262
20408
|
return ret;
|
|
20263
20409
|
};
|
|
20264
20410
|
var offsetElementAfterFontResize = (prevElement, nextElement) => {
|
|
20265
|
-
if (isBoundToContainer(nextElement)) {
|
|
20411
|
+
if (isBoundToContainer(nextElement) || !nextElement.autoResize) {
|
|
20266
20412
|
return nextElement;
|
|
20267
20413
|
}
|
|
20268
20414
|
return mutateElement(
|
|
@@ -22184,7 +22330,16 @@ var CheckboxItem = ({ children, checked, onChange, className }) => {
|
|
|
22184
22330
|
).focus();
|
|
22185
22331
|
},
|
|
22186
22332
|
children: [
|
|
22187
|
-
/* @__PURE__ */ jsx27(
|
|
22333
|
+
/* @__PURE__ */ jsx27(
|
|
22334
|
+
"button",
|
|
22335
|
+
{
|
|
22336
|
+
type: "button",
|
|
22337
|
+
className: "Checkbox-box",
|
|
22338
|
+
role: "checkbox",
|
|
22339
|
+
"aria-checked": checked,
|
|
22340
|
+
children: checkIcon
|
|
22341
|
+
}
|
|
22342
|
+
),
|
|
22188
22343
|
/* @__PURE__ */ jsx27("div", { className: "Checkbox-label", children })
|
|
22189
22344
|
]
|
|
22190
22345
|
}
|
|
@@ -24272,7 +24427,8 @@ var actionBindText = register({
|
|
|
24272
24427
|
mutateElement(textElement, {
|
|
24273
24428
|
containerId: container.id,
|
|
24274
24429
|
verticalAlign: VERTICAL_ALIGN.MIDDLE,
|
|
24275
|
-
textAlign: TEXT_ALIGN.CENTER
|
|
24430
|
+
textAlign: TEXT_ALIGN.CENTER,
|
|
24431
|
+
autoResize: true
|
|
24276
24432
|
});
|
|
24277
24433
|
mutateElement(container, {
|
|
24278
24434
|
boundElements: (container.boundElements || []).concat({
|
|
@@ -24394,7 +24550,8 @@ var actionWrapTextInContainer = register({
|
|
|
24394
24550
|
containerId: container.id,
|
|
24395
24551
|
verticalAlign: VERTICAL_ALIGN.MIDDLE,
|
|
24396
24552
|
boundElements: null,
|
|
24397
|
-
textAlign: TEXT_ALIGN.CENTER
|
|
24553
|
+
textAlign: TEXT_ALIGN.CENTER,
|
|
24554
|
+
autoResize: true
|
|
24398
24555
|
},
|
|
24399
24556
|
false
|
|
24400
24557
|
);
|
|
@@ -27673,6 +27830,7 @@ var Dialog = (props) => {
|
|
|
27673
27830
|
onClick: onClose,
|
|
27674
27831
|
title: t("buttons.close"),
|
|
27675
27832
|
"aria-label": t("buttons.close"),
|
|
27833
|
+
type: "button",
|
|
27676
27834
|
children: CloseIcon
|
|
27677
27835
|
}
|
|
27678
27836
|
),
|
|
@@ -28524,6 +28682,7 @@ var ExitZenModeAction = ({
|
|
|
28524
28682
|
}) => /* @__PURE__ */ jsx62(
|
|
28525
28683
|
"button",
|
|
28526
28684
|
{
|
|
28685
|
+
type: "button",
|
|
28527
28686
|
className: clsx28("disable-zen-mode", {
|
|
28528
28687
|
"disable-zen-mode--visible": showExitZenModeBtn
|
|
28529
28688
|
}),
|
|
@@ -29001,7 +29160,7 @@ function CommandPaletteInner({
|
|
|
29001
29160
|
...command,
|
|
29002
29161
|
icon: command.icon || boltIcon,
|
|
29003
29162
|
order: command.order ?? getCategoryOrder(command.category),
|
|
29004
|
-
haystack: `${deburr(command.label)} ${command.keywords?.join(" ") || ""}`
|
|
29163
|
+
haystack: `${deburr(command.label.toLocaleLowerCase())} ${command.keywords?.join(" ") || ""}`
|
|
29005
29164
|
};
|
|
29006
29165
|
});
|
|
29007
29166
|
setAllCommands(allCommands2);
|
|
@@ -29172,7 +29331,9 @@ function CommandPaletteInner({
|
|
|
29172
29331
|
setCurrentCommand(showLastUsed ? lastUsed : matchingCommands[0] || null);
|
|
29173
29332
|
return;
|
|
29174
29333
|
}
|
|
29175
|
-
const _query = deburr(
|
|
29334
|
+
const _query = deburr(
|
|
29335
|
+
commandSearch.toLocaleLowerCase().replace(/[<>_| -]/g, "")
|
|
29336
|
+
);
|
|
29176
29337
|
matchingCommands = fuzzy.filter(_query, matchingCommands, {
|
|
29177
29338
|
extract: (command) => command.haystack
|
|
29178
29339
|
}).sort((a, b) => b.score - a.score).map((item) => item.original);
|
|
@@ -29556,7 +29717,10 @@ var createUndoAction = (history, store) => ({
|
|
|
29556
29717
|
PanelComponent: ({ updateData, data }) => {
|
|
29557
29718
|
const { isUndoStackEmpty } = useEmitter(
|
|
29558
29719
|
history.onHistoryChangedEmitter,
|
|
29559
|
-
new HistoryChangedEvent(
|
|
29720
|
+
new HistoryChangedEvent(
|
|
29721
|
+
history.isUndoStackEmpty,
|
|
29722
|
+
history.isRedoStackEmpty
|
|
29723
|
+
)
|
|
29560
29724
|
);
|
|
29561
29725
|
return /* @__PURE__ */ jsx66(
|
|
29562
29726
|
ToolButton,
|
|
@@ -29566,7 +29730,8 @@ var createUndoAction = (history, store) => ({
|
|
|
29566
29730
|
"aria-label": t("buttons.undo"),
|
|
29567
29731
|
onClick: updateData,
|
|
29568
29732
|
size: data?.size || "medium",
|
|
29569
|
-
disabled: isUndoStackEmpty
|
|
29733
|
+
disabled: isUndoStackEmpty,
|
|
29734
|
+
"data-testid": "button-undo"
|
|
29570
29735
|
}
|
|
29571
29736
|
);
|
|
29572
29737
|
}
|
|
@@ -29590,7 +29755,10 @@ var createRedoAction = (history, store) => ({
|
|
|
29590
29755
|
PanelComponent: ({ updateData, data }) => {
|
|
29591
29756
|
const { isRedoStackEmpty } = useEmitter(
|
|
29592
29757
|
history.onHistoryChangedEmitter,
|
|
29593
|
-
new HistoryChangedEvent(
|
|
29758
|
+
new HistoryChangedEvent(
|
|
29759
|
+
history.isUndoStackEmpty,
|
|
29760
|
+
history.isRedoStackEmpty
|
|
29761
|
+
)
|
|
29594
29762
|
);
|
|
29595
29763
|
return /* @__PURE__ */ jsx66(
|
|
29596
29764
|
ToolButton,
|
|
@@ -29600,7 +29768,8 @@ var createRedoAction = (history, store) => ({
|
|
|
29600
29768
|
"aria-label": t("buttons.redo"),
|
|
29601
29769
|
onClick: updateData,
|
|
29602
29770
|
size: data?.size || "medium",
|
|
29603
|
-
disabled: isRedoStackEmpty
|
|
29771
|
+
disabled: isRedoStackEmpty,
|
|
29772
|
+
"data-testid": "button-redo"
|
|
29604
29773
|
}
|
|
29605
29774
|
);
|
|
29606
29775
|
}
|
|
@@ -29737,6 +29906,7 @@ init_register();
|
|
|
29737
29906
|
init_appState();
|
|
29738
29907
|
init_clipboard();
|
|
29739
29908
|
init_constants();
|
|
29909
|
+
init_constants();
|
|
29740
29910
|
init_restore();
|
|
29741
29911
|
init_element();
|
|
29742
29912
|
init_binding();
|
|
@@ -29843,6 +30013,7 @@ var ContextMenu = React24.memo(
|
|
|
29843
30013
|
children: /* @__PURE__ */ jsxs37(
|
|
29844
30014
|
"button",
|
|
29845
30015
|
{
|
|
30016
|
+
type: "button",
|
|
29846
30017
|
className: clsx30("context-menu-item", {
|
|
29847
30018
|
dangerous: actionName === "deleteSelectedElements",
|
|
29848
30019
|
checkmark: item.checked?.(appState)
|
|
@@ -30850,6 +31021,7 @@ var MobileMenu = ({
|
|
|
30850
31021
|
appState.scrolledOutside && !appState.openMenu && !appState.openSidebar && /* @__PURE__ */ jsx81(
|
|
30851
31022
|
"button",
|
|
30852
31023
|
{
|
|
31024
|
+
type: "button",
|
|
30853
31025
|
className: "scroll-back-to-content",
|
|
30854
31026
|
onClick: () => {
|
|
30855
31027
|
setAppState((appState2) => ({
|
|
@@ -30915,6 +31087,7 @@ var ChartPreviewBtn = (props) => {
|
|
|
30915
31087
|
return /* @__PURE__ */ jsx82(
|
|
30916
31088
|
"button",
|
|
30917
31089
|
{
|
|
31090
|
+
type: "button",
|
|
30918
31091
|
className: "ChartPreview",
|
|
30919
31092
|
onClick: () => {
|
|
30920
31093
|
if (chartElements) {
|
|
@@ -34303,7 +34476,7 @@ var LayerUI = ({
|
|
|
34303
34476
|
);
|
|
34304
34477
|
ShapeCache.delete(element);
|
|
34305
34478
|
}
|
|
34306
|
-
Scene_default.getScene(selectedElements[0])?.
|
|
34479
|
+
Scene_default.getScene(selectedElements[0])?.triggerUpdate();
|
|
34307
34480
|
} else if (colorPickerType === "elementBackground") {
|
|
34308
34481
|
setAppState({
|
|
34309
34482
|
currentItemBackgroundColor: color
|
|
@@ -34413,6 +34586,7 @@ var LayerUI = ({
|
|
|
34413
34586
|
appState.scrolledOutside && /* @__PURE__ */ jsx117(
|
|
34414
34587
|
"button",
|
|
34415
34588
|
{
|
|
34589
|
+
type: "button",
|
|
34416
34590
|
className: "scroll-back-to-content",
|
|
34417
34591
|
onClick: () => {
|
|
34418
34592
|
setAppState((appState2) => ({
|
|
@@ -34558,19 +34732,12 @@ init_transformHandles();
|
|
|
34558
34732
|
init_define_import_meta_env();
|
|
34559
34733
|
init_element();
|
|
34560
34734
|
init_mutateElement();
|
|
34561
|
-
init_textElement();
|
|
34562
|
-
init_typeChecks();
|
|
34563
34735
|
init_utils();
|
|
34564
34736
|
init_ShapeCache();
|
|
34565
34737
|
var Fonts = class _Fonts {
|
|
34566
34738
|
scene;
|
|
34567
|
-
|
|
34568
|
-
constructor({
|
|
34569
|
-
scene,
|
|
34570
|
-
onSceneUpdated
|
|
34571
|
-
}) {
|
|
34739
|
+
constructor({ scene }) {
|
|
34572
34740
|
this.scene = scene;
|
|
34573
|
-
this.onSceneUpdated = onSceneUpdated;
|
|
34574
34741
|
}
|
|
34575
34742
|
// it's ok to track fonts across multiple instances only once, so let's use
|
|
34576
34743
|
// a static member to reduce memory footprint
|
|
@@ -34601,21 +34768,15 @@ var Fonts = class _Fonts {
|
|
|
34601
34768
|
}
|
|
34602
34769
|
let didUpdate = false;
|
|
34603
34770
|
this.scene.mapElements((element) => {
|
|
34604
|
-
if (isTextElement(element)
|
|
34605
|
-
ShapeCache.delete(element);
|
|
34771
|
+
if (isTextElement(element)) {
|
|
34606
34772
|
didUpdate = true;
|
|
34607
|
-
|
|
34608
|
-
|
|
34609
|
-
element,
|
|
34610
|
-
getContainerElement(element, this.scene.getNonDeletedElementsMap()),
|
|
34611
|
-
this.scene.getNonDeletedElementsMap()
|
|
34612
|
-
)
|
|
34613
|
-
});
|
|
34773
|
+
ShapeCache.delete(element);
|
|
34774
|
+
return newElementWith(element, {}, true);
|
|
34614
34775
|
}
|
|
34615
34776
|
return element;
|
|
34616
34777
|
});
|
|
34617
34778
|
if (didUpdate) {
|
|
34618
|
-
this.
|
|
34779
|
+
this.scene.triggerUpdate();
|
|
34619
34780
|
}
|
|
34620
34781
|
};
|
|
34621
34782
|
loadFontsForElements = async (elements) => {
|
|
@@ -35715,7 +35876,7 @@ var getSnapLinesAtPointer = (elements, appState, pointer, event, elementsMap) =>
|
|
|
35715
35876
|
};
|
|
35716
35877
|
};
|
|
35717
35878
|
var isActiveToolNonLinearSnappable = (activeToolType) => {
|
|
35718
|
-
return activeToolType === TOOL_TYPE.rectangle || activeToolType === TOOL_TYPE.ellipse || activeToolType === TOOL_TYPE.diamond || activeToolType === TOOL_TYPE.frame || activeToolType === TOOL_TYPE.magicframe || activeToolType === TOOL_TYPE.image;
|
|
35879
|
+
return activeToolType === TOOL_TYPE.rectangle || activeToolType === TOOL_TYPE.ellipse || activeToolType === TOOL_TYPE.diamond || activeToolType === TOOL_TYPE.frame || activeToolType === TOOL_TYPE.magicframe || activeToolType === TOOL_TYPE.image || activeToolType === TOOL_TYPE.text;
|
|
35719
35880
|
};
|
|
35720
35881
|
|
|
35721
35882
|
// components/BraveMeasureTextError.tsx
|
|
@@ -36576,7 +36737,7 @@ var renderBindingHighlightForSuggestedPointBinding = (context, suggestedBinding,
|
|
|
36576
36737
|
fillCircle(context, x, y, threshold);
|
|
36577
36738
|
});
|
|
36578
36739
|
};
|
|
36579
|
-
var renderSelectionBorder = (context, appState, elementProperties
|
|
36740
|
+
var renderSelectionBorder = (context, appState, elementProperties) => {
|
|
36580
36741
|
const {
|
|
36581
36742
|
angle,
|
|
36582
36743
|
elementX1,
|
|
@@ -36591,6 +36752,7 @@ var renderSelectionBorder = (context, appState, elementProperties, padding = DEF
|
|
|
36591
36752
|
} = elementProperties;
|
|
36592
36753
|
const elementWidth = elementX2 - elementX1;
|
|
36593
36754
|
const elementHeight = elementY2 - elementY1;
|
|
36755
|
+
const padding = DEFAULT_TRANSFORM_HANDLE_SPACING * 2;
|
|
36594
36756
|
const linePadding = padding / appState.zoom.value;
|
|
36595
36757
|
const lineWidth = 8 / appState.zoom.value;
|
|
36596
36758
|
const spaceWidth = 4 / appState.zoom.value;
|
|
@@ -36775,11 +36937,28 @@ var renderTransformHandles = (context, renderConfig, appState, transformHandles,
|
|
|
36775
36937
|
}
|
|
36776
36938
|
});
|
|
36777
36939
|
};
|
|
36940
|
+
var renderTextBox = (text, context, appState, selectionColor) => {
|
|
36941
|
+
context.save();
|
|
36942
|
+
const padding = DEFAULT_TRANSFORM_HANDLE_SPACING * 2 / appState.zoom.value;
|
|
36943
|
+
const width = text.width + padding * 2;
|
|
36944
|
+
const height = text.height + padding * 2;
|
|
36945
|
+
const cx = text.x + width / 2;
|
|
36946
|
+
const cy = text.y + height / 2;
|
|
36947
|
+
const shiftX = -(width / 2 + padding);
|
|
36948
|
+
const shiftY = -(height / 2 + padding);
|
|
36949
|
+
context.translate(cx + appState.scrollX, cy + appState.scrollY);
|
|
36950
|
+
context.rotate(text.angle);
|
|
36951
|
+
context.lineWidth = 1 / appState.zoom.value;
|
|
36952
|
+
context.strokeStyle = selectionColor;
|
|
36953
|
+
context.strokeRect(shiftX, shiftY, width, height);
|
|
36954
|
+
context.restore();
|
|
36955
|
+
};
|
|
36778
36956
|
var _renderInteractiveScene = ({
|
|
36779
36957
|
canvas: canvas2,
|
|
36780
36958
|
elementsMap,
|
|
36781
36959
|
visibleElements,
|
|
36782
36960
|
selectedElements,
|
|
36961
|
+
allElementsMap,
|
|
36783
36962
|
scale,
|
|
36784
36963
|
appState,
|
|
36785
36964
|
renderConfig,
|
|
@@ -36818,11 +36997,27 @@ var _renderInteractiveScene = ({
|
|
|
36818
36997
|
}
|
|
36819
36998
|
if (appState.selectionElement) {
|
|
36820
36999
|
try {
|
|
36821
|
-
renderSelectionElement(
|
|
37000
|
+
renderSelectionElement(
|
|
37001
|
+
appState.selectionElement,
|
|
37002
|
+
context,
|
|
37003
|
+
appState,
|
|
37004
|
+
renderConfig.selectionColor
|
|
37005
|
+
);
|
|
36822
37006
|
} catch (error) {
|
|
36823
37007
|
console.error(error);
|
|
36824
37008
|
}
|
|
36825
37009
|
}
|
|
37010
|
+
if (appState.editingElement && isTextElement(appState.editingElement)) {
|
|
37011
|
+
const textElement = allElementsMap.get(appState.editingElement.id);
|
|
37012
|
+
if (textElement && !textElement.autoResize) {
|
|
37013
|
+
renderTextBox(
|
|
37014
|
+
textElement,
|
|
37015
|
+
context,
|
|
37016
|
+
appState,
|
|
37017
|
+
renderConfig.selectionColor
|
|
37018
|
+
);
|
|
37019
|
+
}
|
|
37020
|
+
}
|
|
36826
37021
|
if (appState.isBindingEnabled) {
|
|
36827
37022
|
appState.suggestedBindings.filter((binding) => binding != null).forEach((suggestedBinding) => {
|
|
36828
37023
|
renderBindingHighlight(
|
|
@@ -36946,7 +37141,8 @@ var _renderInteractiveScene = ({
|
|
|
36946
37141
|
// when we render we don't know which pointer type so use mouse,
|
|
36947
37142
|
getOmitSidesForDevice(device)
|
|
36948
37143
|
);
|
|
36949
|
-
if (!appState.viewModeEnabled && showBoundingBox
|
|
37144
|
+
if (!appState.viewModeEnabled && showBoundingBox && // do not show transform handles when text is being edited
|
|
37145
|
+
!isTextElement(appState.editingElement)) {
|
|
36950
37146
|
renderTransformHandles(
|
|
36951
37147
|
context,
|
|
36952
37148
|
renderConfig,
|
|
@@ -37105,6 +37301,7 @@ var InteractiveCanvas = (props) => {
|
|
|
37105
37301
|
elementsMap: props.elementsMap,
|
|
37106
37302
|
visibleElements: props.visibleElements,
|
|
37107
37303
|
selectedElements: props.selectedElements,
|
|
37304
|
+
allElementsMap: props.allElementsMap,
|
|
37108
37305
|
scale: window.devicePixelRatio,
|
|
37109
37306
|
appState: props.appState,
|
|
37110
37307
|
renderConfig: {
|
|
@@ -37172,11 +37369,12 @@ var getRelevantAppStateProps = (appState) => ({
|
|
|
37172
37369
|
// Necessary for collab. sessions
|
|
37173
37370
|
activeEmbeddable: appState.activeEmbeddable,
|
|
37174
37371
|
snapLines: appState.snapLines,
|
|
37175
|
-
zenModeEnabled: appState.zenModeEnabled
|
|
37372
|
+
zenModeEnabled: appState.zenModeEnabled,
|
|
37373
|
+
editingElement: appState.editingElement
|
|
37176
37374
|
});
|
|
37177
37375
|
var areEqual2 = (prevProps, nextProps) => {
|
|
37178
|
-
if (prevProps.selectionNonce !== nextProps.selectionNonce || prevProps.
|
|
37179
|
-
// even if
|
|
37376
|
+
if (prevProps.selectionNonce !== nextProps.selectionNonce || prevProps.sceneNonce !== nextProps.sceneNonce || prevProps.scale !== nextProps.scale || // we need to memoize on elementsMap because they may have renewed
|
|
37377
|
+
// even if sceneNonce didn't change (e.g. we filter elements out based
|
|
37180
37378
|
// on appState)
|
|
37181
37379
|
prevProps.elementsMap !== nextProps.elementsMap || prevProps.visibleElements !== nextProps.visibleElements || prevProps.selectedElements !== nextProps.selectedElements) {
|
|
37182
37380
|
return false;
|
|
@@ -37264,8 +37462,8 @@ var getRelevantAppStateProps2 = (appState) => ({
|
|
|
37264
37462
|
editingGroupId: appState.editingGroupId
|
|
37265
37463
|
});
|
|
37266
37464
|
var areEqual3 = (prevProps, nextProps) => {
|
|
37267
|
-
if (prevProps.
|
|
37268
|
-
// even if
|
|
37465
|
+
if (prevProps.sceneNonce !== nextProps.sceneNonce || prevProps.scale !== nextProps.scale || // we need to memoize on elementsMap because they may have renewed
|
|
37466
|
+
// even if sceneNonce didn't change (e.g. we filter elements out based
|
|
37269
37467
|
// on appState)
|
|
37270
37468
|
prevProps.elementsMap !== nextProps.elementsMap || prevProps.visibleElements !== nextProps.visibleElements) {
|
|
37271
37469
|
return false;
|
|
@@ -37353,9 +37551,8 @@ var Renderer = class {
|
|
|
37353
37551
|
width,
|
|
37354
37552
|
editingElement,
|
|
37355
37553
|
pendingImageElementId,
|
|
37356
|
-
//
|
|
37357
|
-
|
|
37358
|
-
versionNonce: _versionNonce
|
|
37554
|
+
// cache-invalidation nonce
|
|
37555
|
+
sceneNonce: _sceneNonce
|
|
37359
37556
|
}) => {
|
|
37360
37557
|
const elements = this.scene.getNonDeletedElements();
|
|
37361
37558
|
const elementsMap = getRenderableElements({
|
|
@@ -37597,7 +37794,15 @@ var FollowMode = ({
|
|
|
37597
37794
|
}
|
|
37598
37795
|
)
|
|
37599
37796
|
] }),
|
|
37600
|
-
/* @__PURE__ */ jsx125(
|
|
37797
|
+
/* @__PURE__ */ jsx125(
|
|
37798
|
+
"button",
|
|
37799
|
+
{
|
|
37800
|
+
type: "button",
|
|
37801
|
+
onClick: onDisconnect,
|
|
37802
|
+
className: "follow-mode__disconnect-btn",
|
|
37803
|
+
children: CloseIcon
|
|
37804
|
+
}
|
|
37805
|
+
)
|
|
37601
37806
|
] }) });
|
|
37602
37807
|
};
|
|
37603
37808
|
var FollowMode_default = FollowMode;
|
|
@@ -37891,7 +38096,8 @@ var textWysiwyg = ({
|
|
|
37891
38096
|
element,
|
|
37892
38097
|
canvas: canvas2,
|
|
37893
38098
|
excalidrawContainer,
|
|
37894
|
-
app
|
|
38099
|
+
app,
|
|
38100
|
+
autoSelect = true
|
|
37895
38101
|
}) => {
|
|
37896
38102
|
const textPropertiesUpdated = (updatedTextElement, editable2) => {
|
|
37897
38103
|
if (!editable2.style.fontFamily || !editable2.style.fontSize) {
|
|
@@ -37997,6 +38203,8 @@ var textWysiwyg = ({
|
|
|
37997
38203
|
if (!container) {
|
|
37998
38204
|
maxWidth = (appState.width - 8 - viewportX) / appState.zoom.value;
|
|
37999
38205
|
textElementWidth = Math.min(textElementWidth, maxWidth);
|
|
38206
|
+
} else {
|
|
38207
|
+
textElementWidth += 0.5;
|
|
38000
38208
|
}
|
|
38001
38209
|
const editorMaxHeight = (appState.height - viewportY) / appState.zoom.value;
|
|
38002
38210
|
Object.assign(editable.style, {
|
|
@@ -38037,7 +38245,7 @@ var textWysiwyg = ({
|
|
|
38037
38245
|
editable.classList.add("excalidraw-wysiwyg");
|
|
38038
38246
|
let whiteSpace = "pre";
|
|
38039
38247
|
let wordBreak = "normal";
|
|
38040
|
-
if (isBoundToContainer(element)) {
|
|
38248
|
+
if (isBoundToContainer(element) || !element.autoResize) {
|
|
38041
38249
|
whiteSpace = "pre-wrap";
|
|
38042
38250
|
wordBreak = "break-word";
|
|
38043
38251
|
}
|
|
@@ -38205,6 +38413,10 @@ var textWysiwyg = ({
|
|
|
38205
38413
|
};
|
|
38206
38414
|
let submittedViaKeyboard = false;
|
|
38207
38415
|
const handleSubmit = () => {
|
|
38416
|
+
if (isDestroyed) {
|
|
38417
|
+
return;
|
|
38418
|
+
}
|
|
38419
|
+
isDestroyed = true;
|
|
38208
38420
|
cleanup();
|
|
38209
38421
|
const updateElement = Scene_default.getScene(element)?.getElement(
|
|
38210
38422
|
element.id
|
|
@@ -38212,13 +38424,11 @@ var textWysiwyg = ({
|
|
|
38212
38424
|
if (!updateElement) {
|
|
38213
38425
|
return;
|
|
38214
38426
|
}
|
|
38215
|
-
let text = editable.value;
|
|
38216
38427
|
const container = getContainerElement(
|
|
38217
38428
|
updateElement,
|
|
38218
38429
|
app.scene.getNonDeletedElementsMap()
|
|
38219
38430
|
);
|
|
38220
38431
|
if (container) {
|
|
38221
|
-
text = updateElement.text;
|
|
38222
38432
|
if (editable.value.trim()) {
|
|
38223
38433
|
const boundTextElementId = getBoundTextElementId(container);
|
|
38224
38434
|
if (!boundTextElementId || boundTextElementId !== element.id) {
|
|
@@ -38247,16 +38457,11 @@ var textWysiwyg = ({
|
|
|
38247
38457
|
);
|
|
38248
38458
|
}
|
|
38249
38459
|
onSubmit({
|
|
38250
|
-
text,
|
|
38251
38460
|
viaKeyboard: submittedViaKeyboard,
|
|
38252
|
-
|
|
38461
|
+
nextOriginalText: editable.value
|
|
38253
38462
|
});
|
|
38254
38463
|
};
|
|
38255
38464
|
const cleanup = () => {
|
|
38256
|
-
if (isDestroyed) {
|
|
38257
|
-
return;
|
|
38258
|
-
}
|
|
38259
|
-
isDestroyed = true;
|
|
38260
38465
|
editable.onblur = null;
|
|
38261
38466
|
editable.oninput = null;
|
|
38262
38467
|
editable.onkeydown = null;
|
|
@@ -38306,9 +38511,15 @@ var textWysiwyg = ({
|
|
|
38306
38511
|
editable.onblur = null;
|
|
38307
38512
|
window.addEventListener("pointerup", bindBlurEvent);
|
|
38308
38513
|
window.addEventListener("blur", handleSubmit);
|
|
38514
|
+
} else if (event.target instanceof HTMLElement && !event.target.contains(editable) && // Vitest simply ignores stopPropagation, capture-mode, or rAF
|
|
38515
|
+
// so without introducing crazier hacks, nothing we can do
|
|
38516
|
+
!isTestEnv()) {
|
|
38517
|
+
requestAnimationFrame(() => {
|
|
38518
|
+
handleSubmit();
|
|
38519
|
+
});
|
|
38309
38520
|
}
|
|
38310
38521
|
};
|
|
38311
|
-
const unbindUpdate = Scene_default.getScene(element).
|
|
38522
|
+
const unbindUpdate = Scene_default.getScene(element).onUpdate(() => {
|
|
38312
38523
|
updateWysiwygStyle();
|
|
38313
38524
|
const isColorPickerActive = !!document.activeElement?.closest(
|
|
38314
38525
|
".color-picker-content"
|
|
@@ -38318,7 +38529,9 @@ var textWysiwyg = ({
|
|
|
38318
38529
|
}
|
|
38319
38530
|
});
|
|
38320
38531
|
let isDestroyed = false;
|
|
38321
|
-
|
|
38532
|
+
if (autoSelect) {
|
|
38533
|
+
editable.select();
|
|
38534
|
+
}
|
|
38322
38535
|
bindBlurEvent();
|
|
38323
38536
|
let observer = null;
|
|
38324
38537
|
if (canvas2 && "ResizeObserver" in window) {
|
|
@@ -38329,7 +38542,10 @@ var textWysiwyg = ({
|
|
|
38329
38542
|
} else {
|
|
38330
38543
|
window.addEventListener("resize", updateWysiwygStyle);
|
|
38331
38544
|
}
|
|
38332
|
-
|
|
38545
|
+
editable.onpointerdown = (event) => event.stopPropagation();
|
|
38546
|
+
requestAnimationFrame(() => {
|
|
38547
|
+
window.addEventListener("pointerdown", onPointerDown, { capture: true });
|
|
38548
|
+
});
|
|
38333
38549
|
window.addEventListener("wheel", stopEvent, {
|
|
38334
38550
|
passive: false,
|
|
38335
38551
|
capture: true
|
|
@@ -38341,6 +38557,84 @@ var textWysiwyg = ({
|
|
|
38341
38557
|
// components/App.tsx
|
|
38342
38558
|
init_fractionalIndex();
|
|
38343
38559
|
init_helpers();
|
|
38560
|
+
|
|
38561
|
+
// actions/actionTextAutoResize.ts
|
|
38562
|
+
init_define_import_meta_env();
|
|
38563
|
+
init_element();
|
|
38564
|
+
init_mutateElement();
|
|
38565
|
+
init_textElement();
|
|
38566
|
+
init_scene();
|
|
38567
|
+
init_store();
|
|
38568
|
+
init_utils();
|
|
38569
|
+
init_register();
|
|
38570
|
+
var actionTextAutoResize = register({
|
|
38571
|
+
name: "autoResize",
|
|
38572
|
+
label: "labels.autoResize",
|
|
38573
|
+
icon: null,
|
|
38574
|
+
trackEvent: { category: "element" },
|
|
38575
|
+
predicate: (elements, appState, _, app) => {
|
|
38576
|
+
const selectedElements = getSelectedElements(elements, appState);
|
|
38577
|
+
return selectedElements.length === 1 && isTextElement(selectedElements[0]) && !selectedElements[0].autoResize;
|
|
38578
|
+
},
|
|
38579
|
+
perform: (elements, appState, _, app) => {
|
|
38580
|
+
const selectedElements = getSelectedElements(elements, appState);
|
|
38581
|
+
return {
|
|
38582
|
+
appState,
|
|
38583
|
+
elements: elements.map((element) => {
|
|
38584
|
+
if (element.id === selectedElements[0].id && isTextElement(element)) {
|
|
38585
|
+
const metrics = measureText(
|
|
38586
|
+
element.originalText,
|
|
38587
|
+
getFontString(element),
|
|
38588
|
+
element.lineHeight
|
|
38589
|
+
);
|
|
38590
|
+
return newElementWith(element, {
|
|
38591
|
+
autoResize: true,
|
|
38592
|
+
width: metrics.width,
|
|
38593
|
+
height: metrics.height,
|
|
38594
|
+
text: element.originalText
|
|
38595
|
+
});
|
|
38596
|
+
}
|
|
38597
|
+
return element;
|
|
38598
|
+
}),
|
|
38599
|
+
storeAction: StoreAction.CAPTURE
|
|
38600
|
+
};
|
|
38601
|
+
}
|
|
38602
|
+
});
|
|
38603
|
+
|
|
38604
|
+
// components/App.tsx
|
|
38605
|
+
init_bounds();
|
|
38606
|
+
|
|
38607
|
+
// mermaid.ts
|
|
38608
|
+
init_define_import_meta_env();
|
|
38609
|
+
var isMaybeMermaidDefinition = (text) => {
|
|
38610
|
+
const chartTypes = [
|
|
38611
|
+
"flowchart",
|
|
38612
|
+
"sequenceDiagram",
|
|
38613
|
+
"classDiagram",
|
|
38614
|
+
"stateDiagram",
|
|
38615
|
+
"stateDiagram-v2",
|
|
38616
|
+
"erDiagram",
|
|
38617
|
+
"journey",
|
|
38618
|
+
"gantt",
|
|
38619
|
+
"pie",
|
|
38620
|
+
"quadrantChart",
|
|
38621
|
+
"requirementDiagram",
|
|
38622
|
+
"gitGraph",
|
|
38623
|
+
"C4Context",
|
|
38624
|
+
"mindmap",
|
|
38625
|
+
"timeline",
|
|
38626
|
+
"zenuml",
|
|
38627
|
+
"sankey",
|
|
38628
|
+
"xychart",
|
|
38629
|
+
"block"
|
|
38630
|
+
];
|
|
38631
|
+
const re = new RegExp(
|
|
38632
|
+
`^(?:%%{.*?}%%[\\s\\n]*)?\\b${chartTypes.map((x) => `${x}(-beta)?`).join("|")}\\b`
|
|
38633
|
+
);
|
|
38634
|
+
return re.test(text.trim());
|
|
38635
|
+
};
|
|
38636
|
+
|
|
38637
|
+
// components/App.tsx
|
|
38344
38638
|
import { Fragment as Fragment21, jsx as jsx126, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
38345
38639
|
var AppContext = React38.createContext(null);
|
|
38346
38640
|
var AppPropsContext = React38.createContext(null);
|
|
@@ -38545,10 +38839,7 @@ var App = class _App extends React38.Component {
|
|
|
38545
38839
|
container: this.excalidrawContainerRef.current,
|
|
38546
38840
|
id: this.id
|
|
38547
38841
|
};
|
|
38548
|
-
this.fonts = new Fonts({
|
|
38549
|
-
scene: this.scene,
|
|
38550
|
-
onSceneUpdated: this.onSceneUpdated
|
|
38551
|
-
});
|
|
38842
|
+
this.fonts = new Fonts({ scene: this.scene });
|
|
38552
38843
|
this.history = new History();
|
|
38553
38844
|
this.actionManager.registerAll(actions);
|
|
38554
38845
|
this.actionManager.registerAction(
|
|
@@ -38707,7 +38998,7 @@ var App = class _App extends React38.Component {
|
|
|
38707
38998
|
return false;
|
|
38708
38999
|
});
|
|
38709
39000
|
if (updated) {
|
|
38710
|
-
this.scene.
|
|
39001
|
+
this.scene.triggerUpdate();
|
|
38711
39002
|
}
|
|
38712
39003
|
this.iFrameRefs.forEach((ref, id) => {
|
|
38713
39004
|
if (!iframeLikes.has(id)) {
|
|
@@ -39114,9 +39405,9 @@ var App = class _App extends React38.Component {
|
|
|
39114
39405
|
render() {
|
|
39115
39406
|
const selectedElements = this.scene.getSelectedElements(this.state);
|
|
39116
39407
|
const { renderTopRightUI, renderCustomStats } = this.props;
|
|
39117
|
-
const
|
|
39408
|
+
const sceneNonce = this.scene.getSceneNonce();
|
|
39118
39409
|
const { elementsMap, visibleElements } = this.renderer.getRenderableElements({
|
|
39119
|
-
|
|
39410
|
+
sceneNonce,
|
|
39120
39411
|
zoom: this.state.zoom,
|
|
39121
39412
|
offsetLeft: this.state.offsetLeft,
|
|
39122
39413
|
offsetTop: this.state.offsetTop,
|
|
@@ -39313,7 +39604,7 @@ var App = class _App extends React38.Component {
|
|
|
39313
39604
|
elementsMap,
|
|
39314
39605
|
allElementsMap,
|
|
39315
39606
|
visibleElements,
|
|
39316
|
-
|
|
39607
|
+
sceneNonce,
|
|
39317
39608
|
selectionNonce: this.state.selectionElement?.versionNonce,
|
|
39318
39609
|
scale: window.devicePixelRatio,
|
|
39319
39610
|
appState: this.state,
|
|
@@ -39334,8 +39625,9 @@ var App = class _App extends React38.Component {
|
|
|
39334
39625
|
canvas: this.interactiveCanvas,
|
|
39335
39626
|
elementsMap,
|
|
39336
39627
|
visibleElements,
|
|
39628
|
+
allElementsMap,
|
|
39337
39629
|
selectedElements,
|
|
39338
|
-
|
|
39630
|
+
sceneNonce,
|
|
39339
39631
|
selectionNonce: this.state.selectionElement?.versionNonce,
|
|
39340
39632
|
scale: window.devicePixelRatio,
|
|
39341
39633
|
appState: this.state,
|
|
@@ -39429,7 +39721,7 @@ var App = class _App extends React38.Component {
|
|
|
39429
39721
|
);
|
|
39430
39722
|
}
|
|
39431
39723
|
this.magicGenerations.set(frameElement.id, data);
|
|
39432
|
-
this.
|
|
39724
|
+
this.triggerRender();
|
|
39433
39725
|
};
|
|
39434
39726
|
getTextFromElements(elements) {
|
|
39435
39727
|
const text = elements.reduce((acc, element) => {
|
|
@@ -39913,7 +40205,7 @@ var App = class _App extends React38.Component {
|
|
|
39913
40205
|
this.store.onStoreIncrementEmitter.on((increment) => {
|
|
39914
40206
|
this.history.record(increment.elementsChange, increment.appStateChange);
|
|
39915
40207
|
});
|
|
39916
|
-
this.scene.
|
|
40208
|
+
this.scene.onUpdate(this.triggerRender);
|
|
39917
40209
|
this.addEventListeners();
|
|
39918
40210
|
if (this.props.autoFocus && this.excalidrawContainerRef.current) {
|
|
39919
40211
|
this.focusContainer();
|
|
@@ -39949,6 +40241,7 @@ var App = class _App extends React38.Component {
|
|
|
39949
40241
|
componentWillUnmount() {
|
|
39950
40242
|
this.renderer.destroy();
|
|
39951
40243
|
this.scene = new Scene_default();
|
|
40244
|
+
this.fonts = new Fonts({ scene: this.scene });
|
|
39952
40245
|
this.renderer = new Renderer(this.scene);
|
|
39953
40246
|
this.files = {};
|
|
39954
40247
|
this.imageCache.clear();
|
|
@@ -40013,7 +40306,7 @@ var App = class _App extends React38.Component {
|
|
|
40013
40306
|
addEventListener(document, "keyup" /* KEYUP */, this.onKeyUp, { passive: true }),
|
|
40014
40307
|
addEventListener(
|
|
40015
40308
|
document,
|
|
40016
|
-
"
|
|
40309
|
+
"pointermove" /* POINTER_MOVE */,
|
|
40017
40310
|
this.updateCurrentCursorPosition
|
|
40018
40311
|
),
|
|
40019
40312
|
// rerender text elements on font load to fix #637 && #1553
|
|
@@ -40042,6 +40335,7 @@ var App = class _App extends React38.Component {
|
|
|
40042
40335
|
),
|
|
40043
40336
|
addEventListener(window, "focus" /* FOCUS */, () => {
|
|
40044
40337
|
this.maybeCleanupAfterMissingPointerUp(null);
|
|
40338
|
+
this.triggerRender(true);
|
|
40045
40339
|
})
|
|
40046
40340
|
);
|
|
40047
40341
|
if (this.state.viewModeEnabled) {
|
|
@@ -40373,6 +40667,27 @@ var App = class _App extends React38.Component {
|
|
|
40373
40667
|
retainSeed: isPlainPaste
|
|
40374
40668
|
});
|
|
40375
40669
|
} else if (data.text) {
|
|
40670
|
+
if (data.text && isMaybeMermaidDefinition(data.text)) {
|
|
40671
|
+
const api = await import("@excalidraw/mermaid-to-excalidraw");
|
|
40672
|
+
try {
|
|
40673
|
+
const { elements: skeletonElements, files } = await api.parseMermaidToExcalidraw(data.text, {
|
|
40674
|
+
fontSize: DEFAULT_FONT_SIZE
|
|
40675
|
+
});
|
|
40676
|
+
const elements = convertToExcalidrawElements(skeletonElements, {
|
|
40677
|
+
regenerateIds: true
|
|
40678
|
+
});
|
|
40679
|
+
this.addElementsFromPasteOrLibrary({
|
|
40680
|
+
elements,
|
|
40681
|
+
files,
|
|
40682
|
+
position: "cursor"
|
|
40683
|
+
});
|
|
40684
|
+
return;
|
|
40685
|
+
} catch (err) {
|
|
40686
|
+
console.warn(
|
|
40687
|
+
`parsing pasted text as mermaid definition failed: ${err.message}`
|
|
40688
|
+
);
|
|
40689
|
+
}
|
|
40690
|
+
}
|
|
40376
40691
|
const nonEmptyLines = normalizeEOL(data.text).split(/\n+/).map((s) => s.trim()).filter(Boolean);
|
|
40377
40692
|
const embbeddableUrls = nonEmptyLines.map((str) => maybeParseEmbedSrc(str)).filter((string) => {
|
|
40378
40693
|
return embeddableURLValidator(string, this.props.validateEmbeddable) && (/^(http|https):\/\/[^\s/$.?#].[^\s]*$/.test(string) || getEmbedLink(string)?.type === "video");
|
|
@@ -40592,28 +40907,42 @@ var App = class _App extends React38.Component {
|
|
|
40592
40907
|
text,
|
|
40593
40908
|
fontSize: this.state.currentItemFontSize,
|
|
40594
40909
|
fontFamily: this.state.currentItemFontFamily,
|
|
40595
|
-
textAlign:
|
|
40910
|
+
textAlign: DEFAULT_TEXT_ALIGN,
|
|
40596
40911
|
verticalAlign: DEFAULT_VERTICAL_ALIGN,
|
|
40597
40912
|
locked: false
|
|
40598
40913
|
};
|
|
40914
|
+
const fontString = getFontString({
|
|
40915
|
+
fontSize: textElementProps.fontSize,
|
|
40916
|
+
fontFamily: textElementProps.fontFamily
|
|
40917
|
+
});
|
|
40918
|
+
const lineHeight = getDefaultLineHeight(textElementProps.fontFamily);
|
|
40919
|
+
const [x1, , x2] = getVisibleSceneBounds(this.state);
|
|
40920
|
+
const maxTextWidth = Math.max(Math.min((x2 - x1) * 0.5, 800), 200);
|
|
40599
40921
|
const LINE_GAP = 10;
|
|
40600
40922
|
let currentY = y;
|
|
40601
40923
|
const lines = isPlainPaste ? [text] : text.split("\n");
|
|
40602
40924
|
const textElements = lines.reduce(
|
|
40603
40925
|
(acc, line, idx) => {
|
|
40604
|
-
const
|
|
40605
|
-
|
|
40606
|
-
if (text2.length) {
|
|
40926
|
+
const originalText = line.trim();
|
|
40927
|
+
if (originalText.length) {
|
|
40607
40928
|
const topLayerFrame = this.getTopLayerFrameAtSceneCoords({
|
|
40608
40929
|
x,
|
|
40609
40930
|
y: currentY
|
|
40610
40931
|
});
|
|
40932
|
+
let metrics = measureText(originalText, fontString, lineHeight);
|
|
40933
|
+
const isTextWrapped = metrics.width > maxTextWidth;
|
|
40934
|
+
const text2 = isTextWrapped ? wrapText(originalText, fontString, maxTextWidth) : originalText;
|
|
40935
|
+
metrics = isTextWrapped ? measureText(text2, fontString, lineHeight) : metrics;
|
|
40936
|
+
const startX = x - metrics.width / 2;
|
|
40937
|
+
const startY = currentY - metrics.height / 2;
|
|
40611
40938
|
const element = newTextElement({
|
|
40612
40939
|
...textElementProps,
|
|
40613
|
-
x,
|
|
40614
|
-
y:
|
|
40940
|
+
x: startX,
|
|
40941
|
+
y: startY,
|
|
40615
40942
|
text: text2,
|
|
40943
|
+
originalText,
|
|
40616
40944
|
lineHeight,
|
|
40945
|
+
autoResize: !isTextWrapped,
|
|
40617
40946
|
frameId: topLayerFrame ? topLayerFrame.id : null
|
|
40618
40947
|
});
|
|
40619
40948
|
acc.push(element);
|
|
@@ -40826,7 +41155,7 @@ var App = class _App extends React38.Component {
|
|
|
40826
41155
|
ShapeCache.delete(element);
|
|
40827
41156
|
}
|
|
40828
41157
|
});
|
|
40829
|
-
this.scene.
|
|
41158
|
+
this.scene.triggerUpdate();
|
|
40830
41159
|
this.addNewImagesToImageCache();
|
|
40831
41160
|
}
|
|
40832
41161
|
);
|
|
@@ -40866,8 +41195,12 @@ var App = class _App extends React38.Component {
|
|
|
40866
41195
|
}
|
|
40867
41196
|
}
|
|
40868
41197
|
);
|
|
40869
|
-
|
|
40870
|
-
|
|
41198
|
+
triggerRender = (force) => {
|
|
41199
|
+
if (force === true) {
|
|
41200
|
+
this.scene.triggerUpdate();
|
|
41201
|
+
} else {
|
|
41202
|
+
this.setState({});
|
|
41203
|
+
}
|
|
40871
41204
|
};
|
|
40872
41205
|
/**
|
|
40873
41206
|
* @returns whether the menu was toggled on or off
|
|
@@ -41270,21 +41603,22 @@ var App = class _App extends React38.Component {
|
|
|
41270
41603
|
isExistingElement = false
|
|
41271
41604
|
}) {
|
|
41272
41605
|
const elementsMap = this.scene.getElementsMapIncludingDeleted();
|
|
41273
|
-
const updateElement = (
|
|
41606
|
+
const updateElement = (nextOriginalText, isDeleted) => {
|
|
41274
41607
|
this.scene.replaceAllElements([
|
|
41275
41608
|
// Not sure why we include deleted elements as well hence using deleted elements map
|
|
41276
41609
|
...this.scene.getElementsIncludingDeleted().map((_element) => {
|
|
41277
41610
|
if (_element.id === element.id && isTextElement(_element)) {
|
|
41278
|
-
return
|
|
41279
|
-
|
|
41280
|
-
|
|
41281
|
-
|
|
41282
|
-
|
|
41283
|
-
|
|
41284
|
-
|
|
41285
|
-
|
|
41286
|
-
|
|
41287
|
-
|
|
41611
|
+
return newElementWith(_element, {
|
|
41612
|
+
originalText: nextOriginalText,
|
|
41613
|
+
isDeleted: isDeleted ?? _element.isDeleted,
|
|
41614
|
+
// returns (wrapped) text and new dimensions
|
|
41615
|
+
...refreshTextDimensions(
|
|
41616
|
+
_element,
|
|
41617
|
+
getContainerElement(_element, elementsMap),
|
|
41618
|
+
elementsMap,
|
|
41619
|
+
nextOriginalText
|
|
41620
|
+
)
|
|
41621
|
+
});
|
|
41288
41622
|
}
|
|
41289
41623
|
return _element;
|
|
41290
41624
|
})
|
|
@@ -41306,15 +41640,15 @@ var App = class _App extends React38.Component {
|
|
|
41306
41640
|
viewportY - this.state.offsetTop
|
|
41307
41641
|
];
|
|
41308
41642
|
},
|
|
41309
|
-
onChange: withBatchedUpdates((
|
|
41310
|
-
updateElement(
|
|
41643
|
+
onChange: withBatchedUpdates((nextOriginalText) => {
|
|
41644
|
+
updateElement(nextOriginalText, false);
|
|
41311
41645
|
if (isNonDeletedElement(element)) {
|
|
41312
41646
|
updateBoundElements(element, elementsMap);
|
|
41313
41647
|
}
|
|
41314
41648
|
}),
|
|
41315
|
-
onSubmit: withBatchedUpdates(({
|
|
41316
|
-
const isDeleted = !
|
|
41317
|
-
updateElement(
|
|
41649
|
+
onSubmit: withBatchedUpdates(({ viaKeyboard, nextOriginalText }) => {
|
|
41650
|
+
const isDeleted = !nextOriginalText.trim();
|
|
41651
|
+
updateElement(nextOriginalText, isDeleted);
|
|
41318
41652
|
if (!isDeleted && viaKeyboard) {
|
|
41319
41653
|
const elementIdToSelect = element.containerId ? element.containerId : element.id;
|
|
41320
41654
|
this.setState((prevState) => ({
|
|
@@ -41346,10 +41680,15 @@ var App = class _App extends React38.Component {
|
|
|
41346
41680
|
}),
|
|
41347
41681
|
element,
|
|
41348
41682
|
excalidrawContainer: this.excalidrawContainerRef.current,
|
|
41349
|
-
app: this
|
|
41683
|
+
app: this,
|
|
41684
|
+
// when text is selected, it's hard (at least on iOS) to re-position the
|
|
41685
|
+
// caret (i.e. deselect). There's not much use for always selecting
|
|
41686
|
+
// the text on edit anyway (and users can select-all from contextmenu
|
|
41687
|
+
// if needed)
|
|
41688
|
+
autoSelect: !this.device.isTouchScreen
|
|
41350
41689
|
});
|
|
41351
41690
|
this.deselectElements();
|
|
41352
|
-
updateElement(element.
|
|
41691
|
+
updateElement(element.originalText, false);
|
|
41353
41692
|
}
|
|
41354
41693
|
deselectElements() {
|
|
41355
41694
|
this.setState({
|
|
@@ -41548,7 +41887,8 @@ var App = class _App extends React38.Component {
|
|
|
41548
41887
|
sceneX,
|
|
41549
41888
|
sceneY,
|
|
41550
41889
|
insertAtParentCenter = true,
|
|
41551
|
-
container
|
|
41890
|
+
container,
|
|
41891
|
+
autoEdit = true
|
|
41552
41892
|
}) => {
|
|
41553
41893
|
let shouldBindToContainer = false;
|
|
41554
41894
|
let parentCenterPosition = insertAtParentCenter && this.getTextWysiwygSnappedToCenterPosition(
|
|
@@ -41651,12 +41991,16 @@ var App = class _App extends React38.Component {
|
|
|
41651
41991
|
this.scene.insertElement(element);
|
|
41652
41992
|
}
|
|
41653
41993
|
}
|
|
41654
|
-
|
|
41655
|
-
|
|
41656
|
-
|
|
41657
|
-
|
|
41658
|
-
|
|
41659
|
-
|
|
41994
|
+
if (autoEdit || existingTextElement || container) {
|
|
41995
|
+
this.handleTextWysiwyg(element, {
|
|
41996
|
+
isExistingElement: !!existingTextElement
|
|
41997
|
+
});
|
|
41998
|
+
} else {
|
|
41999
|
+
this.setState({
|
|
42000
|
+
draggingElement: element,
|
|
42001
|
+
multiElement: null
|
|
42002
|
+
});
|
|
42003
|
+
}
|
|
41660
42004
|
};
|
|
41661
42005
|
handleCanvasDoubleClick = (event) => {
|
|
41662
42006
|
if (this.state.multiElement) {
|
|
@@ -41848,8 +42192,11 @@ var App = class _App extends React38.Component {
|
|
|
41848
42192
|
);
|
|
41849
42193
|
this.translateCanvas({
|
|
41850
42194
|
zoom: zoomState.zoom,
|
|
41851
|
-
|
|
41852
|
-
|
|
42195
|
+
// 2x multiplier is just a magic number that makes this work correctly
|
|
42196
|
+
// on touchscreen devices (note: if we get report that panning is slower/faster
|
|
42197
|
+
// than actual movement, consider swapping with devicePixelRatio)
|
|
42198
|
+
scrollX: zoomState.scrollX + 2 * (deltaX / nextZoom),
|
|
42199
|
+
scrollY: zoomState.scrollY + 2 * (deltaY / nextZoom),
|
|
41853
42200
|
shouldCacheIgnoreZoom: true
|
|
41854
42201
|
});
|
|
41855
42202
|
});
|
|
@@ -42198,7 +42545,7 @@ var App = class _App extends React38.Component {
|
|
|
42198
42545
|
}
|
|
42199
42546
|
}
|
|
42200
42547
|
this.elementsPendingErasure = new Set(this.elementsPendingErasure);
|
|
42201
|
-
this.
|
|
42548
|
+
this.triggerRender();
|
|
42202
42549
|
}
|
|
42203
42550
|
};
|
|
42204
42551
|
// set touch moving for mobile context menu
|
|
@@ -42392,7 +42739,6 @@ var App = class _App extends React38.Component {
|
|
|
42392
42739
|
}
|
|
42393
42740
|
if (this.state.activeTool.type === "text") {
|
|
42394
42741
|
this.handleTextOnPointerDown(event, pointerDownState);
|
|
42395
|
-
return;
|
|
42396
42742
|
} else if (this.state.activeTool.type === "arrow" || this.state.activeTool.type === "line") {
|
|
42397
42743
|
this.handleLinearElementOnPointerDown(
|
|
42398
42744
|
event,
|
|
@@ -42962,7 +43308,8 @@ var App = class _App extends React38.Component {
|
|
|
42962
43308
|
sceneX,
|
|
42963
43309
|
sceneY,
|
|
42964
43310
|
insertAtParentCenter: !event.altKey,
|
|
42965
|
-
container
|
|
43311
|
+
container,
|
|
43312
|
+
autoEdit: false
|
|
42966
43313
|
});
|
|
42967
43314
|
resetCursor(this.interactiveCanvas);
|
|
42968
43315
|
if (!this.state.activeTool.locked) {
|
|
@@ -43967,6 +44314,24 @@ var App = class _App extends React38.Component {
|
|
|
43967
44314
|
}
|
|
43968
44315
|
return;
|
|
43969
44316
|
}
|
|
44317
|
+
if (isTextElement(draggingElement)) {
|
|
44318
|
+
const minWidth = getMinTextElementWidth(
|
|
44319
|
+
getFontString({
|
|
44320
|
+
fontSize: draggingElement.fontSize,
|
|
44321
|
+
fontFamily: draggingElement.fontFamily
|
|
44322
|
+
}),
|
|
44323
|
+
draggingElement.lineHeight
|
|
44324
|
+
);
|
|
44325
|
+
if (draggingElement.width < minWidth) {
|
|
44326
|
+
mutateElement(draggingElement, {
|
|
44327
|
+
autoResize: true
|
|
44328
|
+
});
|
|
44329
|
+
}
|
|
44330
|
+
this.resetCursor();
|
|
44331
|
+
this.handleTextWysiwyg(draggingElement, {
|
|
44332
|
+
isExistingElement: true
|
|
44333
|
+
});
|
|
44334
|
+
}
|
|
43970
44335
|
if (activeTool.type !== "selection" && draggingElement && isInvisiblySmallElement(draggingElement)) {
|
|
43971
44336
|
this.updateScene({
|
|
43972
44337
|
elements: this.scene.getElementsIncludingDeleted().filter((el) => el.id !== draggingElement.id),
|
|
@@ -44002,7 +44367,7 @@ var App = class _App extends React38.Component {
|
|
|
44002
44367
|
[linearElement],
|
|
44003
44368
|
this.scene.getNonDeletedElementsMap()
|
|
44004
44369
|
);
|
|
44005
|
-
this.scene.
|
|
44370
|
+
this.scene.triggerUpdate();
|
|
44006
44371
|
}
|
|
44007
44372
|
}
|
|
44008
44373
|
}
|
|
@@ -44355,7 +44720,7 @@ var App = class _App extends React38.Component {
|
|
|
44355
44720
|
}
|
|
44356
44721
|
restoreReadyToEraseElements = () => {
|
|
44357
44722
|
this.elementsPendingErasure = /* @__PURE__ */ new Set();
|
|
44358
|
-
this.
|
|
44723
|
+
this.triggerRender();
|
|
44359
44724
|
};
|
|
44360
44725
|
eraseElements = () => {
|
|
44361
44726
|
let didChange = false;
|
|
@@ -44670,7 +45035,7 @@ var App = class _App extends React38.Component {
|
|
|
44670
45035
|
files
|
|
44671
45036
|
);
|
|
44672
45037
|
if (updatedFiles.size) {
|
|
44673
|
-
this.scene.
|
|
45038
|
+
this.scene.triggerUpdate();
|
|
44674
45039
|
}
|
|
44675
45040
|
}
|
|
44676
45041
|
};
|
|
@@ -44956,7 +45321,8 @@ var App = class _App extends React38.Component {
|
|
|
44956
45321
|
distance(pointerDownState.origin.x, pointerCoords.x),
|
|
44957
45322
|
distance(pointerDownState.origin.y, pointerCoords.y),
|
|
44958
45323
|
shouldMaintainAspectRatio(event),
|
|
44959
|
-
shouldResizeFromCenter(event)
|
|
45324
|
+
shouldResizeFromCenter(event),
|
|
45325
|
+
this.state.zoom.value
|
|
44960
45326
|
);
|
|
44961
45327
|
} else {
|
|
44962
45328
|
let [gridX, gridY] = getGridPoint(
|
|
@@ -44997,6 +45363,7 @@ var App = class _App extends React38.Component {
|
|
|
44997
45363
|
distance(pointerDownState.originInGrid.y, gridY),
|
|
44998
45364
|
isImageElement(draggingElement) ? !shouldMaintainAspectRatio(event) : shouldMaintainAspectRatio(event),
|
|
44999
45365
|
shouldResizeFromCenter(event),
|
|
45366
|
+
this.state.zoom.value,
|
|
45000
45367
|
aspectRatio,
|
|
45001
45368
|
this.state.originSnapOffset
|
|
45002
45369
|
);
|
|
@@ -45143,6 +45510,7 @@ var App = class _App extends React38.Component {
|
|
|
45143
45510
|
return [actionCopy, ...options];
|
|
45144
45511
|
}
|
|
45145
45512
|
return [
|
|
45513
|
+
CONTEXT_MENU_SEPARATOR,
|
|
45146
45514
|
actionCut,
|
|
45147
45515
|
actionCopy,
|
|
45148
45516
|
actionPaste,
|
|
@@ -45155,6 +45523,7 @@ var App = class _App extends React38.Component {
|
|
|
45155
45523
|
actionPasteStyles,
|
|
45156
45524
|
CONTEXT_MENU_SEPARATOR,
|
|
45157
45525
|
actionGroup,
|
|
45526
|
+
actionTextAutoResize,
|
|
45158
45527
|
actionUnbindText,
|
|
45159
45528
|
actionBindText,
|
|
45160
45529
|
actionWrapTextInContainer,
|