@myoc/excalidraw 0.19.528 → 0.19.530
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/CHANGELOG.md +108 -0
- package/dist/dev/{chunk-NY5S5VQK.js → chunk-ROEGCKS3.js} +63 -51
- package/dist/dev/{chunk-NY5S5VQK.js.map → chunk-ROEGCKS3.js.map} +2 -2
- package/dist/dev/{chunk-6FFT5HLH.js → chunk-XSA46KXZ.js} +2 -2
- package/dist/dev/data/{image-V7WKCORB.js → image-AYT4E6ZF.js} +3 -3
- package/dist/dev/index.css +3 -3
- package/dist/dev/index.css.map +2 -2
- package/dist/dev/index.js +185 -73
- package/dist/dev/index.js.map +3 -3
- package/dist/dev/subset-shared.chunk.js +1 -1
- package/dist/dev/subset-worker.chunk.js +1 -1
- package/dist/prod/{chunk-JCJ2YNSV.js → chunk-6OYCXZJM.js} +3 -3
- package/dist/prod/{chunk-ELA2R5XK.js → chunk-MDZUVLV6.js} +1 -1
- package/dist/prod/data/image-EAYKVQSH.js +1 -0
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +13 -13
- package/dist/prod/subset-shared.chunk.js +1 -1
- package/dist/prod/subset-worker.chunk.js +1 -1
- package/dist/types/excalidraw/components/App.d.ts +3 -0
- package/dist/types/excalidraw/components/shapeActionPredicates.d.ts +1 -0
- package/dist/types/excalidraw/types.d.ts +18 -0
- package/package.json +4 -4
- package/dist/prod/data/image-OSFJHW22.js +0 -1
- /package/dist/dev/{chunk-6FFT5HLH.js.map → chunk-XSA46KXZ.js.map} +0 -0
- /package/dist/dev/data/{image-V7WKCORB.js.map → image-AYT4E6ZF.js.map} +0 -0
package/dist/dev/index.js
CHANGED
|
@@ -62,10 +62,10 @@ import {
|
|
|
62
62
|
serializeAsJSON,
|
|
63
63
|
strokeRectWithRotation_simple,
|
|
64
64
|
zoomToFitBounds
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-ROEGCKS3.js";
|
|
66
66
|
import {
|
|
67
67
|
define_import_meta_env_default
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-XSA46KXZ.js";
|
|
69
69
|
import {
|
|
70
70
|
en_default
|
|
71
71
|
} from "./chunk-SKCAT7JG.js";
|
|
@@ -10936,7 +10936,7 @@ var exportCanvas = async (type, elements, appState, files, {
|
|
|
10936
10936
|
let blob = canvasToBlob(tempCanvas);
|
|
10937
10937
|
if (appState.exportEmbedScene) {
|
|
10938
10938
|
blob = blob.then(
|
|
10939
|
-
(blob2) => import("./data/image-
|
|
10939
|
+
(blob2) => import("./data/image-AYT4E6ZF.js").then(
|
|
10940
10940
|
({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
|
|
10941
10941
|
blob: blob2,
|
|
10942
10942
|
metadata: serializeAsJSON(elements, appState, files, "local")
|
|
@@ -13009,6 +13009,7 @@ var actionSmartZoom = register({
|
|
|
13009
13009
|
type: "button",
|
|
13010
13010
|
icon: arrowsToEyeIcon,
|
|
13011
13011
|
"aria-label": t("labels.smartZoom"),
|
|
13012
|
+
title: `${t("labels.smartZoom")} - ${KEYS26.F.toLocaleUpperCase()}`,
|
|
13012
13013
|
onClick: () => updateData(null),
|
|
13013
13014
|
size: data?.size || "medium",
|
|
13014
13015
|
"data-testid": "button-smart-zoom",
|
|
@@ -16832,12 +16833,13 @@ var actionToggleViewMode = register({
|
|
|
16832
16833
|
if (appState.viewModeOnly || appProps.viewModeOnly) {
|
|
16833
16834
|
return null;
|
|
16834
16835
|
}
|
|
16836
|
+
const label = appState.viewModeEnabled ? "Edit mode" : t("labels.viewMode");
|
|
16835
16837
|
return /* @__PURE__ */ jsx58(
|
|
16836
16838
|
IconButton,
|
|
16837
16839
|
{
|
|
16838
16840
|
type: "button",
|
|
16839
|
-
icon: eyeIcon,
|
|
16840
|
-
"aria-label":
|
|
16841
|
+
icon: appState.viewModeEnabled ? pencilIcon : eyeIcon,
|
|
16842
|
+
"aria-label": label,
|
|
16841
16843
|
onClick: () => updateData(null),
|
|
16842
16844
|
size: data?.size || "medium",
|
|
16843
16845
|
"data-testid": "button-view-mode",
|
|
@@ -25567,6 +25569,7 @@ var getShapeActionPredicates = (appState, targetElements, elementsMap, app) => {
|
|
|
25567
25569
|
),
|
|
25568
25570
|
align: !isSingleElementBoundContainer && alignActionsPredicate(appState, app),
|
|
25569
25571
|
distribute: targetElements.length > 2,
|
|
25572
|
+
imageLayout: targetElements.length > 1 && targetElements.every(isImageElement4) && alignActionsPredicate(appState, app),
|
|
25570
25573
|
// per-element actions
|
|
25571
25574
|
// NOTE: the full panel treats a bound container as linkable; the compact /
|
|
25572
25575
|
// mobile layouts only link a truly single selection. Both are preserved via
|
|
@@ -25597,7 +25600,8 @@ var LayersFieldset = ({
|
|
|
25597
25600
|
] });
|
|
25598
25601
|
var AlignFieldset = ({
|
|
25599
25602
|
renderAction,
|
|
25600
|
-
showDistribute
|
|
25603
|
+
showDistribute,
|
|
25604
|
+
showImageLayout
|
|
25601
25605
|
}) => {
|
|
25602
25606
|
const isRTL3 = document.documentElement.getAttribute("dir") === "rtl";
|
|
25603
25607
|
return /* @__PURE__ */ jsxs33("fieldset", { children: [
|
|
@@ -25630,7 +25634,12 @@ var AlignFieldset = ({
|
|
|
25630
25634
|
showDistribute && renderAction("distributeVertically")
|
|
25631
25635
|
]
|
|
25632
25636
|
}
|
|
25633
|
-
)
|
|
25637
|
+
),
|
|
25638
|
+
showImageLayout && /* @__PURE__ */ jsxs33(Fragment9, { children: [
|
|
25639
|
+
/* @__PURE__ */ jsx66("div", { style: { flexBasis: "100%", height: 0 } }),
|
|
25640
|
+
renderAction("arrangeElements"),
|
|
25641
|
+
renderAction("normaliseElements")
|
|
25642
|
+
] })
|
|
25634
25643
|
] })
|
|
25635
25644
|
] });
|
|
25636
25645
|
};
|
|
@@ -25677,7 +25686,8 @@ var SelectedShapeActions = ({
|
|
|
25677
25686
|
AlignFieldset,
|
|
25678
25687
|
{
|
|
25679
25688
|
renderAction,
|
|
25680
|
-
showDistribute: predicates.distribute
|
|
25689
|
+
showDistribute: predicates.distribute,
|
|
25690
|
+
showImageLayout: predicates.imageLayout
|
|
25681
25691
|
}
|
|
25682
25692
|
),
|
|
25683
25693
|
predicates.showExtraActions && /* @__PURE__ */ jsxs33("fieldset", { children: [
|
|
@@ -25689,7 +25699,8 @@ var SelectedShapeActions = ({
|
|
|
25689
25699
|
renderAction("ungroup"),
|
|
25690
25700
|
predicates.link && renderAction("hyperlink"),
|
|
25691
25701
|
predicates.cropEditor && renderAction("cropEditor"),
|
|
25692
|
-
predicates.lineEditor && renderAction("toggleLinearEditor")
|
|
25702
|
+
predicates.lineEditor && renderAction("toggleLinearEditor"),
|
|
25703
|
+
renderAction("smartZoom")
|
|
25693
25704
|
] })
|
|
25694
25705
|
] })
|
|
25695
25706
|
] });
|
|
@@ -25975,7 +25986,8 @@ var CombinedExtraActions = ({
|
|
|
25975
25986
|
AlignFieldset,
|
|
25976
25987
|
{
|
|
25977
25988
|
renderAction,
|
|
25978
|
-
showDistribute: predicates.distribute
|
|
25989
|
+
showDistribute: predicates.distribute,
|
|
25990
|
+
showImageLayout: predicates.imageLayout
|
|
25979
25991
|
}
|
|
25980
25992
|
),
|
|
25981
25993
|
/* @__PURE__ */ jsxs33("fieldset", { children: [
|
|
@@ -25985,6 +25997,7 @@ var CombinedExtraActions = ({
|
|
|
25985
25997
|
renderAction("ungroup"),
|
|
25986
25998
|
predicates.linkSingleOnly && renderAction("hyperlink"),
|
|
25987
25999
|
predicates.cropEditor && renderAction("cropEditor"),
|
|
26000
|
+
renderAction("smartZoom"),
|
|
25988
26001
|
showDuplicate && renderAction("duplicateSelection"),
|
|
25989
26002
|
showDelete && renderAction("deleteSelectedElements")
|
|
25990
26003
|
] })
|
|
@@ -26238,17 +26251,6 @@ var ExitZenModeButton = ({
|
|
|
26238
26251
|
children: t("buttons.exitZenMode")
|
|
26239
26252
|
}
|
|
26240
26253
|
);
|
|
26241
|
-
var ExitViewModeButton = ({
|
|
26242
|
-
actionManager
|
|
26243
|
-
}) => /* @__PURE__ */ jsx66(
|
|
26244
|
-
"button",
|
|
26245
|
-
{
|
|
26246
|
-
type: "button",
|
|
26247
|
-
className: "disable-view-mode",
|
|
26248
|
-
onClick: () => actionManager.executeAction(actionToggleViewMode),
|
|
26249
|
-
children: pencilIcon
|
|
26250
|
-
}
|
|
26251
|
-
);
|
|
26252
26254
|
|
|
26253
26255
|
// components/LoadingMessage.tsx
|
|
26254
26256
|
import clsx29 from "clsx";
|
|
@@ -27038,22 +27040,19 @@ var MobileMenu = ({
|
|
|
27038
27040
|
if (appState.openDialog?.name === "elementLinkSelector") {
|
|
27039
27041
|
return null;
|
|
27040
27042
|
}
|
|
27041
|
-
const topRightUI = /* @__PURE__ */
|
|
27042
|
-
|
|
27043
|
-
|
|
27044
|
-
|
|
27045
|
-
|
|
27046
|
-
|
|
27047
|
-
|
|
27048
|
-
|
|
27049
|
-
|
|
27050
|
-
|
|
27051
|
-
|
|
27052
|
-
|
|
27053
|
-
|
|
27054
|
-
] })),
|
|
27055
|
-
defaultUIEnabled && appState.viewModeEnabled && app.isInteractionEnabled() && /* @__PURE__ */ jsx80(ExitViewModeButton, { actionManager })
|
|
27056
|
-
] });
|
|
27043
|
+
const topRightUI = /* @__PURE__ */ jsx80("div", { className: "excalidraw-ui-top-right", children: renderTopRightUI?.(true, appState) ?? (!appState.viewModeEnabled && /* @__PURE__ */ jsxs39(Fragment11, { children: [
|
|
27044
|
+
defaultUIEnabled && /* @__PURE__ */ jsx80(
|
|
27045
|
+
PenModeButton,
|
|
27046
|
+
{
|
|
27047
|
+
checked: appState.penMode,
|
|
27048
|
+
onChange: () => onPenModeToggle(null),
|
|
27049
|
+
title: t("toolBar.penMode"),
|
|
27050
|
+
isMobile: true,
|
|
27051
|
+
penDetected: appState.penDetected
|
|
27052
|
+
}
|
|
27053
|
+
),
|
|
27054
|
+
/* @__PURE__ */ jsx80(DefaultSidebarTriggerTunnel.Out, {})
|
|
27055
|
+
] })) });
|
|
27057
27056
|
const topLeftUI = /* @__PURE__ */ jsxs39("div", { className: "excalidraw-ui-top-left", children: [
|
|
27058
27057
|
renderTopLeftUI?.(true, appState),
|
|
27059
27058
|
/* @__PURE__ */ jsx80(MainMenuTunnel.Out, {})
|
|
@@ -27116,7 +27115,9 @@ var MobileMenu = ({
|
|
|
27116
27115
|
{
|
|
27117
27116
|
className: "App-bottom-bar",
|
|
27118
27117
|
style: {
|
|
27119
|
-
marginBottom: SCROLLBAR_WIDTH + SCROLLBAR_MARGIN
|
|
27118
|
+
marginBottom: SCROLLBAR_WIDTH + SCROLLBAR_MARGIN,
|
|
27119
|
+
left: 14,
|
|
27120
|
+
transform: "none"
|
|
27120
27121
|
},
|
|
27121
27122
|
"data-viewport-ui": "bottom",
|
|
27122
27123
|
children: [
|
|
@@ -27137,7 +27138,14 @@ var MobileMenu = ({
|
|
|
27137
27138
|
}
|
|
27138
27139
|
)
|
|
27139
27140
|
] }),
|
|
27140
|
-
!appState.viewModeEnabled && /* @__PURE__ */ jsx80(
|
|
27141
|
+
!appState.viewModeEnabled && /* @__PURE__ */ jsx80(
|
|
27142
|
+
Island,
|
|
27143
|
+
{
|
|
27144
|
+
className: "App-toolbar",
|
|
27145
|
+
style: { justifyContent: "flex-start" },
|
|
27146
|
+
children: appState.openDialog?.name !== "elementLinkSelector" && renderToolbar()
|
|
27147
|
+
}
|
|
27148
|
+
)
|
|
27141
27149
|
]
|
|
27142
27150
|
}
|
|
27143
27151
|
),
|
|
@@ -27816,7 +27824,13 @@ var Footer = ({
|
|
|
27816
27824
|
}
|
|
27817
27825
|
),
|
|
27818
27826
|
children: /* @__PURE__ */ jsx87(Stack_default.Col, { gap: 2, children: /* @__PURE__ */ jsxs45(Section, { heading: "canvasActions", children: [
|
|
27819
|
-
!appState.viewModeOnly && /* @__PURE__ */ jsx87(
|
|
27827
|
+
!appState.viewModeOnly && /* @__PURE__ */ jsx87(
|
|
27828
|
+
Tooltip,
|
|
27829
|
+
{
|
|
27830
|
+
label: appState.viewModeEnabled ? "Edit mode" : t("labels.viewMode"),
|
|
27831
|
+
children: /* @__PURE__ */ jsx87("div", { className: clsx39("view-mode-button"), children: actionManager.renderAction("viewMode") })
|
|
27832
|
+
}
|
|
27833
|
+
),
|
|
27820
27834
|
/* @__PURE__ */ jsx87(Tooltip, { label: t("buttons.smartZoom"), children: /* @__PURE__ */ jsx87("div", { className: clsx39("smart-zoom-button"), children: actionManager.renderAction("smartZoom") }) }),
|
|
27821
27835
|
zoomUIEnabled && app.isNavigationEnabled() && /* @__PURE__ */ jsx87(ZoomActions, { renderAction: actionManager.renderAction }),
|
|
27822
27836
|
defaultUIEnabled && !appState.viewModeEnabled && /* @__PURE__ */ jsx87(
|
|
@@ -33418,10 +33432,14 @@ var DefaultSidebar = Object.assign(
|
|
|
33418
33432
|
children,
|
|
33419
33433
|
className,
|
|
33420
33434
|
docked,
|
|
33435
|
+
onDock,
|
|
33421
33436
|
...rest
|
|
33422
33437
|
}) => {
|
|
33423
33438
|
const appState = useUIAppState();
|
|
33439
|
+
const setAppState = useExcalidrawSetAppState();
|
|
33424
33440
|
const isSearchSidebar = appState.openSidebar?.tab === CANVAS_SEARCH_TAB2;
|
|
33441
|
+
const isDocked = isSearchSidebar ? false : docked ?? appState.defaultSidebarDockedPreference;
|
|
33442
|
+
const canDock = !isSearchSidebar && docked == null && onDock !== false;
|
|
33425
33443
|
return /* @__PURE__ */ createElement2(
|
|
33426
33444
|
Sidebar,
|
|
33427
33445
|
{
|
|
@@ -33433,8 +33451,13 @@ var DefaultSidebar = Object.assign(
|
|
|
33433
33451
|
{ "default-sidebar--search-only": isSearchSidebar },
|
|
33434
33452
|
className
|
|
33435
33453
|
),
|
|
33436
|
-
docked:
|
|
33437
|
-
onDock:
|
|
33454
|
+
docked: isDocked,
|
|
33455
|
+
onDock: canDock ? (nextDocked) => {
|
|
33456
|
+
setAppState({
|
|
33457
|
+
defaultSidebarDockedPreference: nextDocked
|
|
33458
|
+
});
|
|
33459
|
+
onDock?.(nextDocked);
|
|
33460
|
+
} : void 0
|
|
33438
33461
|
},
|
|
33439
33462
|
/* @__PURE__ */ jsxs64(Sidebar.Tabs, { children: [
|
|
33440
33463
|
!isSearchSidebar && /* @__PURE__ */ jsx124(Sidebar.Header, {}),
|
|
@@ -34302,7 +34325,8 @@ var LayerUI = ({
|
|
|
34302
34325
|
const renderCanvasActions = () => /* @__PURE__ */ jsxs67("div", { style: { position: "relative" }, children: [
|
|
34303
34326
|
/* @__PURE__ */ jsxs67("div", { className: "excalidraw-ui-top-left", children: [
|
|
34304
34327
|
renderTopLeftUI?.(false, appState),
|
|
34305
|
-
/* @__PURE__ */ jsx131(tunnels.MainMenuTunnel.Out, {})
|
|
34328
|
+
/* @__PURE__ */ jsx131(tunnels.MainMenuTunnel.Out, {}),
|
|
34329
|
+
/* @__PURE__ */ jsx131(tunnels.DefaultSidebarTriggerTunnel.Out, {})
|
|
34306
34330
|
] }),
|
|
34307
34331
|
renderWelcomeScreen && /* @__PURE__ */ jsx131(tunnels.WelcomeScreenMenuHintTunnel.Out, {})
|
|
34308
34332
|
] });
|
|
@@ -34642,9 +34666,9 @@ var LayerUI = ({
|
|
|
34642
34666
|
] })
|
|
34643
34667
|
]
|
|
34644
34668
|
}
|
|
34645
|
-
)
|
|
34646
|
-
|
|
34647
|
-
|
|
34669
|
+
)
|
|
34670
|
+
] }),
|
|
34671
|
+
renderSidebars()
|
|
34648
34672
|
] });
|
|
34649
34673
|
return /* @__PURE__ */ jsx131(UIAppStateContext.Provider, { value: appState, children: /* @__PURE__ */ jsx131(TunnelsJotaiProvider, { children: /* @__PURE__ */ jsx131(TunnelsContext.Provider, { value: tunnels, children: layerUIJSX }) }) });
|
|
34650
34674
|
};
|
|
@@ -36644,6 +36668,20 @@ var App = class _App extends React40.Component {
|
|
|
36644
36668
|
const dataTransferList = await parseDataTransferEvent(event);
|
|
36645
36669
|
const filesList = dataTransferList.getFiles();
|
|
36646
36670
|
const data = await parseClipboard(dataTransferList, isPlainPaste);
|
|
36671
|
+
if (this.state.viewModeEnabled) {
|
|
36672
|
+
if (!this.containsImagePaste(data, filesList, isPlainPaste)) {
|
|
36673
|
+
return;
|
|
36674
|
+
}
|
|
36675
|
+
if (!this.shouldInsertImageInViewMode({
|
|
36676
|
+
source: "paste",
|
|
36677
|
+
files: filesList.map((file2) => file2.file),
|
|
36678
|
+
data,
|
|
36679
|
+
event
|
|
36680
|
+
})) {
|
|
36681
|
+
event?.preventDefault();
|
|
36682
|
+
return;
|
|
36683
|
+
}
|
|
36684
|
+
}
|
|
36647
36685
|
if (this.props.onPaste) {
|
|
36648
36686
|
try {
|
|
36649
36687
|
if (await this.props.onPaste(data, event) === false) {
|
|
@@ -40373,9 +40411,8 @@ var App = class _App extends React40.Component {
|
|
|
40373
40411
|
if (!isSupportedImageFile(imageFile)) {
|
|
40374
40412
|
throw new Error(t("errors.unsupportedFileType"));
|
|
40375
40413
|
}
|
|
40376
|
-
const mimeType = imageFile.type;
|
|
40377
40414
|
this.cursor.set("wait");
|
|
40378
|
-
if (
|
|
40415
|
+
if (imageFile.type === MIME_TYPES9.svg) {
|
|
40379
40416
|
try {
|
|
40380
40417
|
imageFile = SVGStringToFile(
|
|
40381
40418
|
normalizeSVG(await imageFile.text()),
|
|
@@ -40385,7 +40422,18 @@ var App = class _App extends React40.Component {
|
|
|
40385
40422
|
console.warn(error);
|
|
40386
40423
|
throw new Error(t("errors.svgImageInsertError"));
|
|
40387
40424
|
}
|
|
40425
|
+
} else {
|
|
40426
|
+
const { maxWidthOrHeight } = this.props.imageOptions;
|
|
40427
|
+
try {
|
|
40428
|
+
imageFile = await (this.props.compressImageFile ?? resizeImageFile)(
|
|
40429
|
+
imageFile,
|
|
40430
|
+
{ maxWidthOrHeight }
|
|
40431
|
+
);
|
|
40432
|
+
} catch (error) {
|
|
40433
|
+
console.error("Error trying to resize image file on insertion", error);
|
|
40434
|
+
}
|
|
40388
40435
|
}
|
|
40436
|
+
const mimeType = imageFile.type;
|
|
40389
40437
|
const fileId = await (this.props.generateIdForFile?.(
|
|
40390
40438
|
imageFile
|
|
40391
40439
|
) || generateIdFromFile(imageFile));
|
|
@@ -40397,15 +40445,7 @@ var App = class _App extends React40.Component {
|
|
|
40397
40445
|
}
|
|
40398
40446
|
const existingFileData = this.files[fileId];
|
|
40399
40447
|
if (!existingFileData?.dataURL) {
|
|
40400
|
-
const {
|
|
40401
|
-
try {
|
|
40402
|
-
imageFile = await (this.props.compressImageFile ?? resizeImageFile)(
|
|
40403
|
-
imageFile,
|
|
40404
|
-
{ maxWidthOrHeight }
|
|
40405
|
-
);
|
|
40406
|
-
} catch (error) {
|
|
40407
|
-
console.error("Error trying to resize image file on insertion", error);
|
|
40408
|
-
}
|
|
40448
|
+
const { maxFileSizeBytes } = this.props.imageOptions;
|
|
40409
40449
|
if (imageFile.size > maxFileSizeBytes) {
|
|
40410
40450
|
throw new Error(
|
|
40411
40451
|
t("errors.fileTooBig", {
|
|
@@ -40709,6 +40749,29 @@ var App = class _App extends React40.Component {
|
|
|
40709
40749
|
const dragDataSnapshot = captureDragEventData(event);
|
|
40710
40750
|
const dataTransferList = await parseDataTransferEvent(event);
|
|
40711
40751
|
const fileItems = dataTransferList.getFiles();
|
|
40752
|
+
const imageFiles = fileItems.map((data) => data.file).filter((file2) => isSupportedImageFile(file2));
|
|
40753
|
+
if (this.state.viewModeEnabled) {
|
|
40754
|
+
if (imageFiles.length === 0 || !this.isToolSupported("image")) {
|
|
40755
|
+
return;
|
|
40756
|
+
}
|
|
40757
|
+
if (!this.shouldInsertImageInViewMode({
|
|
40758
|
+
source: "drop",
|
|
40759
|
+
files: imageFiles,
|
|
40760
|
+
event
|
|
40761
|
+
})) {
|
|
40762
|
+
return;
|
|
40763
|
+
}
|
|
40764
|
+
return this.insertImages(
|
|
40765
|
+
imageFiles,
|
|
40766
|
+
sceneX,
|
|
40767
|
+
sceneY,
|
|
40768
|
+
parseDragImageMetadata(
|
|
40769
|
+
dataTransferList,
|
|
40770
|
+
imageFiles.length,
|
|
40771
|
+
dragDataSnapshot
|
|
40772
|
+
)
|
|
40773
|
+
);
|
|
40774
|
+
}
|
|
40712
40775
|
if (fileItems.length === 1) {
|
|
40713
40776
|
const { file: file2, fileHandle } = fileItems[0];
|
|
40714
40777
|
if (file2 && (file2.type === MIME_TYPES9.png || file2.type === MIME_TYPES9.svg)) {
|
|
@@ -40736,7 +40799,6 @@ var App = class _App extends React40.Component {
|
|
|
40736
40799
|
}
|
|
40737
40800
|
}
|
|
40738
40801
|
}
|
|
40739
|
-
const imageFiles = fileItems.map((data) => data.file).filter((file2) => isSupportedImageFile(file2));
|
|
40740
40802
|
if (imageFiles.length > 0 && this.isToolSupported("image")) {
|
|
40741
40803
|
return this.insertImages(
|
|
40742
40804
|
imageFiles,
|
|
@@ -41143,6 +41205,13 @@ var App = class _App extends React40.Component {
|
|
|
41143
41205
|
}
|
|
41144
41206
|
return [];
|
|
41145
41207
|
});
|
|
41208
|
+
__publicField(this, "getImageActionContextMenuItems", (hitElement) => {
|
|
41209
|
+
const selectedElements = this.scene.getSelectedElements(this.state);
|
|
41210
|
+
if (selectedElements.length > 0 && selectedElements.every((element) => isImageElement9(element)) && (!hitElement || this.state.selectedElementIds[hitElement.id])) {
|
|
41211
|
+
return [actionArrangeElements, actionNormaliseElements];
|
|
41212
|
+
}
|
|
41213
|
+
return [];
|
|
41214
|
+
});
|
|
41146
41215
|
__publicField(this, "getElementLinkContextMenuItems", (hitElement) => {
|
|
41147
41216
|
if (!hitElement?.link) {
|
|
41148
41217
|
return [];
|
|
@@ -41172,6 +41241,7 @@ var App = class _App extends React40.Component {
|
|
|
41172
41241
|
});
|
|
41173
41242
|
__publicField(this, "getContextMenuItems", (type, hitElement) => {
|
|
41174
41243
|
const imageContextMenuItems = this.getImageContextMenuItems(hitElement);
|
|
41244
|
+
const imageActionContextMenuItems = this.getImageActionContextMenuItems(hitElement);
|
|
41175
41245
|
const elementLinkContextMenuItems = this.getElementLinkContextMenuItems(hitElement);
|
|
41176
41246
|
if (type === "canvas") {
|
|
41177
41247
|
if (this.state.viewModeEnabled) {
|
|
@@ -41222,6 +41292,8 @@ var App = class _App extends React40.Component {
|
|
|
41222
41292
|
actionPaste,
|
|
41223
41293
|
imageContextMenuItems.length > 0 && CONTEXT_MENU_SEPARATOR,
|
|
41224
41294
|
...imageContextMenuItems,
|
|
41295
|
+
imageActionContextMenuItems.length > 0 && CONTEXT_MENU_SEPARATOR,
|
|
41296
|
+
...imageActionContextMenuItems,
|
|
41225
41297
|
CONTEXT_MENU_SEPARATOR,
|
|
41226
41298
|
actionSelectAllElementsInFrame,
|
|
41227
41299
|
actionRemoveAllElementsFromFrame,
|
|
@@ -42644,6 +42716,21 @@ var App = class _App extends React40.Component {
|
|
|
42644
42716
|
EVENT11.GESTURE_END,
|
|
42645
42717
|
this.onGestureEnd,
|
|
42646
42718
|
false
|
|
42719
|
+
),
|
|
42720
|
+
addEventListener2(document, EVENT11.PASTE, this.pasteFromClipboard, {
|
|
42721
|
+
passive: false
|
|
42722
|
+
}),
|
|
42723
|
+
addEventListener2(
|
|
42724
|
+
this.excalidrawContainerRef.current,
|
|
42725
|
+
EVENT11.DRAG_OVER,
|
|
42726
|
+
this.disableEvent,
|
|
42727
|
+
false
|
|
42728
|
+
),
|
|
42729
|
+
addEventListener2(
|
|
42730
|
+
this.excalidrawContainerRef.current,
|
|
42731
|
+
EVENT11.DROP,
|
|
42732
|
+
this.disableEvent,
|
|
42733
|
+
false
|
|
42647
42734
|
)
|
|
42648
42735
|
);
|
|
42649
42736
|
if (this.state.viewModeEnabled) {
|
|
@@ -42656,9 +42743,6 @@ var App = class _App extends React40.Component {
|
|
|
42656
42743
|
this.onFullscreenChange,
|
|
42657
42744
|
{ passive: false }
|
|
42658
42745
|
),
|
|
42659
|
-
addEventListener2(document, EVENT11.PASTE, this.pasteFromClipboard, {
|
|
42660
|
-
passive: false
|
|
42661
|
-
}),
|
|
42662
42746
|
addEventListener2(document, EVENT11.CUT, this.onCut, { passive: false }),
|
|
42663
42747
|
addEventListener2(window, EVENT11.RESIZE, this.onResize, false),
|
|
42664
42748
|
addEventListener2(window, EVENT11.UNLOAD, this.onUnload, false),
|
|
@@ -42668,18 +42752,6 @@ var App = class _App extends React40.Component {
|
|
|
42668
42752
|
EVENT11.WHEEL,
|
|
42669
42753
|
this.handleWheel,
|
|
42670
42754
|
{ passive: false }
|
|
42671
|
-
),
|
|
42672
|
-
addEventListener2(
|
|
42673
|
-
this.excalidrawContainerRef.current,
|
|
42674
|
-
EVENT11.DRAG_OVER,
|
|
42675
|
-
this.disableEvent,
|
|
42676
|
-
false
|
|
42677
|
-
),
|
|
42678
|
-
addEventListener2(
|
|
42679
|
-
this.excalidrawContainerRef.current,
|
|
42680
|
-
EVENT11.DROP,
|
|
42681
|
-
this.disableEvent,
|
|
42682
|
-
false
|
|
42683
42755
|
)
|
|
42684
42756
|
);
|
|
42685
42757
|
if (this.props.detectScroll) {
|
|
@@ -42902,6 +42974,42 @@ var App = class _App extends React40.Component {
|
|
|
42902
42974
|
}
|
|
42903
42975
|
this.addTextFromPaste(data.text, isPlainPaste);
|
|
42904
42976
|
}
|
|
42977
|
+
containsImagePaste(data, dataTransferFiles, isPlainPaste) {
|
|
42978
|
+
if (dataTransferFiles.some((data2) => isSupportedImageFile(data2.file))) {
|
|
42979
|
+
return true;
|
|
42980
|
+
}
|
|
42981
|
+
if (!isPlainPaste && data.mixedContent?.some((node) => node.type === "imageUrl")) {
|
|
42982
|
+
return true;
|
|
42983
|
+
}
|
|
42984
|
+
if (isPlainPaste || !data.text) {
|
|
42985
|
+
return false;
|
|
42986
|
+
}
|
|
42987
|
+
const trimmedText = data.text.trim();
|
|
42988
|
+
return trimmedText.startsWith("<svg") && trimmedText.endsWith("</svg>");
|
|
42989
|
+
}
|
|
42990
|
+
shouldInsertImageInViewMode({
|
|
42991
|
+
source,
|
|
42992
|
+
files,
|
|
42993
|
+
data,
|
|
42994
|
+
event
|
|
42995
|
+
}) {
|
|
42996
|
+
if (!this.state.viewModeEnabled) {
|
|
42997
|
+
return true;
|
|
42998
|
+
}
|
|
42999
|
+
if (this.state.viewModeOnly || this.props.viewModeImageInsertBehavior === "reject") {
|
|
43000
|
+
this.props.onViewModeImageInsertRejected?.({
|
|
43001
|
+
source,
|
|
43002
|
+
files,
|
|
43003
|
+
data,
|
|
43004
|
+
event
|
|
43005
|
+
});
|
|
43006
|
+
return false;
|
|
43007
|
+
}
|
|
43008
|
+
flushSync2(() => {
|
|
43009
|
+
this.setState({ viewModeEnabled: false });
|
|
43010
|
+
});
|
|
43011
|
+
return true;
|
|
43012
|
+
}
|
|
42905
43013
|
// TODO rewrite this to paste both text & images at the same time if
|
|
42906
43014
|
// pasted data contains both
|
|
42907
43015
|
async addElementsFromMixedContentPaste(mixedContent, {
|
|
@@ -45619,6 +45727,8 @@ var ExcalidrawBase = (props) => {
|
|
|
45619
45727
|
editorPreferences,
|
|
45620
45728
|
onEditorPreferencesChange,
|
|
45621
45729
|
onPaste,
|
|
45730
|
+
viewModeImageInsertBehavior,
|
|
45731
|
+
onViewModeImageInsertRejected,
|
|
45622
45732
|
detectScroll = true,
|
|
45623
45733
|
handleKeyboardGlobally = false,
|
|
45624
45734
|
autoFocus = false,
|
|
@@ -45732,6 +45842,8 @@ var ExcalidrawBase = (props) => {
|
|
|
45732
45842
|
onEditorPreferencesChange,
|
|
45733
45843
|
UIOptions,
|
|
45734
45844
|
onPaste,
|
|
45845
|
+
viewModeImageInsertBehavior,
|
|
45846
|
+
onViewModeImageInsertRejected,
|
|
45735
45847
|
detectScroll,
|
|
45736
45848
|
handleKeyboardGlobally,
|
|
45737
45849
|
autoFocus,
|