oasis-editor 0.0.132 → 0.0.134

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/{OasisEditorApp-D-v1-Asf.js → OasisEditorApp-B2f15Gpe.js} +493 -9
  2. package/dist/app/controllers/EditorCommandsController.d.ts +3 -0
  3. package/dist/app/controllers/createCropSession.d.ts +26 -0
  4. package/dist/app/controllers/useEditorImageOperations.d.ts +7 -0
  5. package/dist/core/commands/builtinCommands.d.ts +1 -1
  6. package/dist/core/commands/image.d.ts +37 -1
  7. package/dist/core/commands/publicCommandTypes.d.ts +5 -0
  8. package/dist/core/pluginUiTypes.d.ts +1 -1
  9. package/dist/core/transactionMergeKeys.d.ts +2 -0
  10. package/dist/export/pdf/writer/PdfContentStream.d.ts +8 -0
  11. package/dist/export/pdf/writer/pdfTypes.d.ts +10 -0
  12. package/dist/i18n/locales/en.d.ts +13 -0
  13. package/dist/i18n/locales/pt-BR.d.ts +13 -0
  14. package/dist/{index-DEBNBBUG.js → index-ogn0S9F3.js} +819 -571
  15. package/dist/oasis-editor.css +1 -1
  16. package/dist/oasis-editor.js +49 -49
  17. package/dist/oasis-editor.umd.cjs +4 -4
  18. package/dist/plugins/internal/essentialsCapabilities.d.ts +15 -0
  19. package/dist/ui/OasisEditorEditorProps.d.ts +5 -0
  20. package/dist/ui/app/buildEditorViewProps.d.ts +2 -0
  21. package/dist/ui/app/createAppCommandsController.d.ts +6 -0
  22. package/dist/ui/app/createEditorCommandRuntime.d.ts +3 -0
  23. package/dist/ui/app/createEditorInteractionRuntime.d.ts +7 -0
  24. package/dist/ui/app/essentials/types.d.ts +5 -0
  25. package/dist/ui/components/Toolbar/LineSpacingButton.d.ts +10 -0
  26. package/dist/ui/components/Toolbar/controls/ImageSizeControls.d.ts +16 -0
  27. package/dist/ui/components/Toolbar/primitives/DropdownChevron.d.ts +20 -0
  28. package/dist/ui/cropGeometry.d.ts +23 -0
  29. package/dist/ui/utils/customIcons.d.ts +30 -0
  30. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { E as EMPTY_PROJECTION_CONTEXT, d as domTextMeasurer, g as getProjectedParagraphBlockHeight, e as estimateTableBlockHeight, p as projectParagraphLayout, a as getPageBodyBottom, b as getPageBodyTop, c as getPageContentWidth, F as FOOTNOTE_MARKER_GUTTER_PX, f as getParagraphText, h as getBlockParagraphs, i as getRunFootnoteReference, l as listReferencedEndnotes, j as getFootnoteDisplayMarker, k as createProjectionContext, m as getDocumentSections, n as getRunField, o as projectBlocksLayout, v as visitRun, q as assertNever, r as createSignal, s as createEditorStateFromDocument, t as createInitialEditorState, S as STANDARD_FONT_SIZES_PT, u as fontSizePxToPt, w as probeLocalFontFamilies, x as createEditorParagraphFromRuns, y as isInlineObjectRun, z as createEditorStyledRun, A as getParagraphLength, B as getActiveZone, C as getActiveSectionIndex, D as getParagraphs, G as normalizeSelection, H as positionToParagraphOffset, I as paragraphOffsetToPosition, J as clampPosition, K as findParagraphIndex, L as createCollapsedSelection, M as isSelectionCollapsed, N as parseFontSizePtToPx, O as formatFontSizePt, P as createEditorParagraph, Q as resolveDefaultParagraphStyleId, R as findParagraphTableLocation, T as buildTableCellLayout, U as PT_PER_PX, V as createEditorTableCell, W as createEditorTableRow, X as createEditorTable, Y as PX_PER_POINT, Z as underlineStyleToCssDecorationStyle, _ as resolveImageSrc, $ as listKindForTag, a0 as isParagraphTag, a1 as collectInlineRuns, a2 as parseParagraphStyle, a3 as getRunImage, a4 as InlineShell, a5 as BalloonShell, a6 as DocumentShell, a7 as createMemo, a8 as getCaretRectFromSnapshot, a9 as getParagraphRectFromSnapshot, aa as createComponent, ab as CaretOverlay, ac as Show, ad as createRenderEffect, ae as style, af as setStyleProperty, ag as setAttribute, ah as memo, ai as template, aj as Button, ak as useI18n, al as createEffect, am as TextField, an as Dialog, ao as insert, ap as className, aq as Grid, ar as SelectField, as as StatusText, at as ColorField, au as UNDERLINE_STYLE_OPTIONS, av as Stack, aw as For, ax as ToggleChip, ay as FormField, az as Checkbox, aA as FieldGroup, aB as Tabs, aC as NumberField, aD as parseNumber, aE as createStore, aF as reconcile, aG as RadioGroup, aH as Radio$1, aI as TextAreaField, aJ as Text, aK as SurfaceButton, aL as delegateEvents, aM as onMount, aN as onCleanup, aO as use, aP as PluginUiHost, aQ as OasisEditorEditor, aR as OasisBrandMark, aS as setPreciseFontPreference, aT as setWelcomeSeen, aU as enablePreciseFontMode, aV as TWIPS_PER_POINT, aW as PX_PER_INCH, aX as TWIPS_PER_INCH, aY as normalizeHex6, aZ as TABLE_CONDITIONAL_FLAG_ATTRIBUTES, a_ as TABLE_BORDER_EDGE_KEYS, a$ as resolveEffectiveParagraphStyle, b0 as resolveEffectiveTextStyleForParagraph, b1 as EMU_PER_PT, b2 as OOXML_ROTATION_UNITS, b3 as OOXML_PERCENT_DENOMINATOR, b4 as parseHexColorToRgb255, b5 as EMU_PER_PX, b6 as getRunEndnoteReference, b7 as iterateFootnoteReferenceRuns, b8 as iterateEndnoteReferenceRuns, b9 as imageContentTypeDefaults, ba as getRunFieldChar, bb as getRunFieldInstruction, bc as createEditorRun, bd as JSZip, be as imageExtensionFromMime, bf as pxToPt$1, bg as resolveFloatingObjectRect, bh as getTextBoxFloatingGeometry, bi as getPresetPathSegments, bj as buildListLabels, bk as DEFAULT_FONT_SIZE_PX, bl as resolveGradientAxis, bm as isDoubleUnderlineStyle, bn as isWavyUnderlineStyle, bo as underlineStyleLineWidthPx, bp as WAVY_UNDERLINE_WAVELENGTH_PX, bq as WAVY_UNDERLINE_AMPLITUDE_PX, br as DOUBLE_UNDERLINE_OFFSET_PX, bs as underlineStyleDashArray, bt as EMPHASIS_GLYPH, bu as rgb255ToHex, bv as getImageFloatingGeometry, bw as textStyleToFontSizePt, bx as resolveTextAlignmentBaselineOffset, by as TEXT_BASELINE_RATIO, bz as resolveOpenTypeFeatureTags, bA as resolveDecorationLineY, bB as DOUBLE_STRIKE_OFFSET_PX, bC as resolveListLabel, bD as getListLabelInset, bE as getAlignedListLabelInset, bF as getParagraphBorderInsets, bG as buildSegmentTable, bH as buildCanvasTableLayout, bI as resolveCanvasTableWidth, bJ as resolveFloatingTableRect, bK as paragraphBetweenBorderMatches, bL as normalizeFamily, bM as ROBOTO_FONT_FILES, bN as loadFontAsset, bO as OFFICE_COMPAT_FONT_FAMILIES, bP as BinaryReader, bQ as buildSfnt, bR as defaultFontDecoderRegistry, bS as SfntFontProgram, bT as collectPdfFontFamilies, bU as outlineFrom, bV as getPageHeaderZoneTop, bW as getPageColumnRects, bX as findFootnoteReference, bY as resolveImporterForFile, bZ as roundTo, b_ as getDocumentSectionsCanonical, b$ as getDocumentParagraphsCanonical, c0 as getDocumentParagraphs, c1 as getDocumentPageSettings, c2 as getTableCellContentWidthForParagraph, c3 as layoutMetricsEpoch, c4 as bumpLayoutMetricsEpoch, c5 as createCanvasLayoutSnapshotProvider, c6 as on, c7 as debounce, c8 as unwrap, c9 as perfTimer, ca as getRunTextBox, cb as createEditorDocument, cc as resolveResizedDimensions, cd as resolveTextBoxRenderHeight, ce as getToolbarStyleState, cf as VERTICAL_HIT_WEIGHT, cg as getCachedCanvasImage, ch as measureParagraphMinContentWidthPx, ci as getEditableBlocksForZone, cj as findParagraphLocation, ck as createSectionBoundaryParagraph, cl as normalizePageSettings, cm as DEFAULT_EDITOR_PAGE_SETTINGS, cn as markStart, co as markEnd, cp as getParagraphEntries, cq as getParagraphById, cr as createEditorFootnote, cs as createFootnoteReferenceRun, ct as renumberFootnotes, cu as preciseFontModeVersion, cv as isPreciseFontModeEnabled, cw as getHeadingLevel, cx as togglePreciseFontMode, cy as nextFontSizePt, cz as previousFontSizePt, cA as fontSizePtToPx, cB as resolveNamedTextStyle, cC as createDefaultToolbarPreset, cD as MenuRegistry, cE as createToolbarRegistry, cF as Editor, cG as resolveCommandRef, cH as commandRefName, cI as createOasisEditorClient, cJ as createEditorZoom, cK as startLongTaskObserver, cL as installGlobalReport, cM as applyStoredPreciseFontPreference, cN as getWelcomeSeen, cO as isLocalFontAccessSupported, cP as EDITOR_SCROLL_PADDING_PX, cQ as Toolbar, cR as OasisEditorLoading, cS as I18nProvider, cT as createTranslator, cU as registerDomStatsSurface, cV as createEditorLogger } from "./index-DEBNBBUG.js";
4
+ import { E as EMPTY_PROJECTION_CONTEXT, d as domTextMeasurer, g as getProjectedParagraphBlockHeight, e as estimateTableBlockHeight, p as projectParagraphLayout, a as getPageBodyBottom, b as getPageBodyTop, c as getPageContentWidth, F as FOOTNOTE_MARKER_GUTTER_PX, f as getParagraphText, h as getBlockParagraphs, i as getRunFootnoteReference, l as listReferencedEndnotes, j as getFootnoteDisplayMarker, k as createProjectionContext, m as getDocumentSections, n as getRunField, o as projectBlocksLayout, v as visitRun, q as assertNever, r as createSignal, s as createEditorStateFromDocument, t as createInitialEditorState, S as STANDARD_FONT_SIZES_PT, u as fontSizePxToPt, w as probeLocalFontFamilies, x as createEditorParagraphFromRuns, y as isInlineObjectRun, z as createEditorStyledRun, A as getParagraphLength, B as getActiveZone, C as getActiveSectionIndex, D as getParagraphs, G as normalizeSelection, H as positionToParagraphOffset, I as paragraphOffsetToPosition, J as clampPosition, K as findParagraphIndex, L as createCollapsedSelection, M as isSelectionCollapsed, N as parseFontSizePtToPx, O as formatFontSizePt, P as createEditorParagraph, Q as resolveDefaultParagraphStyleId, R as findParagraphTableLocation, T as buildTableCellLayout, U as PT_PER_PX, V as createEditorTableCell, W as createEditorTableRow, X as createEditorTable, Y as PX_PER_POINT, Z as underlineStyleToCssDecorationStyle, _ as resolveImageSrc, $ as listKindForTag, a0 as isParagraphTag, a1 as collectInlineRuns, a2 as parseParagraphStyle, a3 as getRunImage, a4 as InlineShell, a5 as BalloonShell, a6 as DocumentShell, a7 as createMemo, a8 as getCaretRectFromSnapshot, a9 as getParagraphRectFromSnapshot, aa as createComponent, ab as CaretOverlay, ac as Show, ad as createRenderEffect, ae as style, af as setStyleProperty, ag as setAttribute, ah as memo, ai as template, aj as Button, ak as useI18n, al as createEffect, am as TextField, an as Dialog, ao as insert, ap as className, aq as Grid, ar as SelectField, as as StatusText, at as ColorField, au as UNDERLINE_STYLE_OPTIONS, av as Stack, aw as For, ax as ToggleChip, ay as FormField, az as Checkbox, aA as FieldGroup, aB as Tabs, aC as NumberField, aD as parseNumber, aE as createStore, aF as reconcile, aG as RadioGroup, aH as Radio$1, aI as TextAreaField, aJ as Text, aK as SurfaceButton, aL as delegateEvents, aM as onMount, aN as onCleanup, aO as CheckIcon, aP as use, aQ as PluginUiHost, aR as OasisEditorEditor, aS as OasisBrandMark, aT as setPreciseFontPreference, aU as setWelcomeSeen, aV as enablePreciseFontMode, aW as TWIPS_PER_POINT, aX as PX_PER_INCH, aY as TWIPS_PER_INCH, aZ as normalizeHex6, a_ as TABLE_CONDITIONAL_FLAG_ATTRIBUTES, a$ as TABLE_BORDER_EDGE_KEYS, b0 as resolveEffectiveParagraphStyle, b1 as resolveEffectiveTextStyleForParagraph, b2 as EMU_PER_PT, b3 as OOXML_ROTATION_UNITS, b4 as OOXML_PERCENT_DENOMINATOR, b5 as parseHexColorToRgb255, b6 as EMU_PER_PX, b7 as getRunEndnoteReference, b8 as iterateFootnoteReferenceRuns, b9 as iterateEndnoteReferenceRuns, ba as imageContentTypeDefaults, bb as getRunFieldChar, bc as getRunFieldInstruction, bd as createEditorRun, be as JSZip, bf as imageExtensionFromMime, bg as pxToPt$1, bh as resolveFloatingObjectRect, bi as getTextBoxFloatingGeometry, bj as getPresetPathSegments, bk as buildListLabels, bl as DEFAULT_FONT_SIZE_PX, bm as resolveGradientAxis, bn as isDoubleUnderlineStyle, bo as isWavyUnderlineStyle, bp as underlineStyleLineWidthPx, bq as WAVY_UNDERLINE_WAVELENGTH_PX, br as WAVY_UNDERLINE_AMPLITUDE_PX, bs as DOUBLE_UNDERLINE_OFFSET_PX, bt as underlineStyleDashArray, bu as EMPHASIS_GLYPH, bv as rgb255ToHex, bw as getImageFloatingGeometry, bx as textStyleToFontSizePt, by as resolveTextAlignmentBaselineOffset, bz as TEXT_BASELINE_RATIO, bA as resolveOpenTypeFeatureTags, bB as resolveDecorationLineY, bC as DOUBLE_STRIKE_OFFSET_PX, bD as resolveListLabel, bE as getListLabelInset, bF as getAlignedListLabelInset, bG as getParagraphBorderInsets, bH as buildSegmentTable, bI as buildCanvasTableLayout, bJ as resolveCanvasTableWidth, bK as resolveFloatingTableRect, bL as paragraphBetweenBorderMatches, bM as normalizeFamily, bN as ROBOTO_FONT_FILES, bO as loadFontAsset, bP as OFFICE_COMPAT_FONT_FAMILIES, bQ as BinaryReader, bR as buildSfnt, bS as defaultFontDecoderRegistry, bT as SfntFontProgram, bU as collectPdfFontFamilies, bV as outlineFrom, bW as getPageHeaderZoneTop, bX as getPageColumnRects, bY as findFootnoteReference, bZ as resolveImporterForFile, b_ as roundTo, b$ as getDocumentSectionsCanonical, c0 as getDocumentParagraphsCanonical, c1 as getDocumentParagraphs, c2 as PX_PER_CM, c3 as getDocumentPageSettings, c4 as getTableCellContentWidthForParagraph, c5 as layoutMetricsEpoch, c6 as bumpLayoutMetricsEpoch, c7 as createCanvasLayoutSnapshotProvider, c8 as on, c9 as debounce, ca as unwrap, cb as perfTimer, cc as getRunTextBox, cd as createEditorDocument, ce as resolveResizedDimensions, cf as axisSignForDirection, cg as clamp$1, ch as MIN_RESIZE_SIZE_PX, ci as resolveTextBoxRenderHeight, cj as getToolbarStyleState, ck as VERTICAL_HIT_WEIGHT, cl as getCachedCanvasImage, cm as measureParagraphMinContentWidthPx, cn as getEditableBlocksForZone, co as findParagraphLocation, cp as createSectionBoundaryParagraph, cq as normalizePageSettings, cr as DEFAULT_EDITOR_PAGE_SETTINGS, cs as markStart, ct as markEnd, cu as getParagraphEntries, cv as getParagraphById, cw as createEditorFootnote, cx as createFootnoteReferenceRun, cy as renumberFootnotes, cz as preciseFontModeVersion, cA as isPreciseFontModeEnabled, cB as getHeadingLevel, cC as togglePreciseFontMode, cD as nextFontSizePt, cE as previousFontSizePt, cF as fontSizePtToPx, cG as resolveNamedTextStyle, cH as createDefaultToolbarPreset, cI as MenuRegistry, cJ as createToolbarRegistry, cK as Editor, cL as resolveCommandRef, cM as commandRefName, cN as createOasisEditorClient, cO as createEditorZoom, cP as startLongTaskObserver, cQ as installGlobalReport, cR as applyStoredPreciseFontPreference, cS as getWelcomeSeen, cT as isLocalFontAccessSupported, cU as EDITOR_SCROLL_PADDING_PX, cV as Toolbar, cW as OasisEditorLoading, cX as I18nProvider, cY as createTranslator, cZ as registerDomStatsSurface, c_ as createEditorLogger } from "./index-ogn0S9F3.js";
5
5
  function projectHeaderFooterBlocksWithDependencies(blocks, deps, context = {}) {
6
6
  const {
7
7
  pageIndex,
@@ -27476,6 +27476,7 @@ const MERGE_KEYS = {
27476
27476
  link: "link",
27477
27477
  imageAlt: "imageAlt",
27478
27478
  imageCaption: "imageCaption",
27479
+ imageResize: "imageResize",
27479
27480
  layoutWrapPolygon: "layoutWrapPolygon",
27480
27481
  specialIndent: "specialIndent",
27481
27482
  paraBorders: "paraBorders",
@@ -35629,7 +35630,7 @@ function FindReplaceDialog(props) {
35629
35630
  });
35630
35631
  }
35631
35632
  delegateEvents(["keydown"]);
35632
- var _tmpl$$3 = /* @__PURE__ */ template(`<div class=oasis-editor-context-menu role=menu data-testid=editor-context-menu>`), _tmpl$2 = /* @__PURE__ */ template(`<i>`), _tmpl$3 = /* @__PURE__ */ template(`<span class=oasis-editor-context-menu-shortcut>`), _tmpl$4 = /* @__PURE__ */ template(`<button type=button class=oasis-editor-context-menu-item role=menuitem><span class=oasis-editor-context-menu-label>`), _tmpl$5 = /* @__PURE__ */ template(`<div class=oasis-editor-context-menu-separator>`), _tmpl$6 = /* @__PURE__ */ template(`<i data-lucide=check style=visibility:hidden>`);
35633
+ var _tmpl$$3 = /* @__PURE__ */ template(`<div class=oasis-editor-context-menu role=menu data-testid=editor-context-menu>`), _tmpl$2 = /* @__PURE__ */ template(`<i>`), _tmpl$3 = /* @__PURE__ */ template(`<span class=oasis-editor-context-menu-shortcut>`), _tmpl$4 = /* @__PURE__ */ template(`<button type=button class=oasis-editor-context-menu-item role=menuitem><span class=oasis-editor-context-menu-label>`), _tmpl$5 = /* @__PURE__ */ template(`<div class=oasis-editor-context-menu-separator>`), _tmpl$6 = /* @__PURE__ */ template(`<span aria-hidden=true style=visibility:hidden;flex-shrink:0>`);
35633
35634
  function ContextMenu(props) {
35634
35635
  let menuRef;
35635
35636
  const handleKeyDown = (event) => {
@@ -35713,7 +35714,13 @@ function ContextMenu(props) {
35713
35714
  return item.icon;
35714
35715
  },
35715
35716
  get fallback() {
35716
- return _tmpl$6();
35717
+ return (() => {
35718
+ var _el$7 = _tmpl$6();
35719
+ insert(_el$7, createComponent(CheckIcon, {
35720
+ size: 16
35721
+ }));
35722
+ return _el$7;
35723
+ })();
35717
35724
  },
35718
35725
  get children() {
35719
35726
  var _el$3 = _tmpl$2();
@@ -35932,7 +35939,8 @@ function buildEditorViewProps(ctx) {
35932
35939
  hoveredRevision: overlayInput.hoveredRevision,
35933
35940
  focused: overlayInput.focused,
35934
35941
  showCaret: overlayInput.showCaret,
35935
- importProgress: overlayInput.importProgress
35942
+ importProgress: overlayInput.importProgress,
35943
+ imageCropMode: overlayInput.imageCropMode
35936
35944
  };
35937
35945
  const refs = {
35938
35946
  onViewportRef: (element) => {
@@ -35974,6 +35982,7 @@ function buildEditorViewProps(ctx) {
35974
35982
  onImageResizeHandleMouseDown: surface.handleImageResizeHandleMouseDown,
35975
35983
  onTextBoxResizeHandleMouseDown: surface.handleTextBoxResizeHandleMouseDown,
35976
35984
  onImageRotateHandleMouseDown: surface.handleImageRotateHandleMouseDown,
35985
+ onImageCropHandleMouseDown: surface.handleImageCropHandleMouseDown,
35977
35986
  onTextBoxRotateHandleMouseDown: surface.handleTextBoxRotateHandleMouseDown,
35978
35987
  onTableDragHandleMouseDown: surface.tableDrag.handleMouseDown,
35979
35988
  onTableCornerResizeHandleMouseDown: surface.tableCornerResize.handleMouseDown,
@@ -39921,7 +39930,8 @@ async function drawFloatingImagesForParagraph(options) {
39921
39930
  y: pxToPt$1(rect.y),
39922
39931
  width: pxToPt$1(rect.width),
39923
39932
  height: pxToPt$1(rect.height),
39924
- rotation: image.rotation
39933
+ rotation: image.rotation,
39934
+ crop: image.crop
39925
39935
  });
39926
39936
  }
39927
39937
  }
@@ -40024,7 +40034,8 @@ async function drawFragmentText(writer, pageIndex, paragraph, line, fragment, do
40024
40034
  y: pxToPt$1(originY + line.top + line.height - fragment.image.height),
40025
40035
  width: pxToPt$1(fragment.image.width),
40026
40036
  height: pxToPt$1(fragment.image.height),
40027
- rotation: fragment.image.rotation
40037
+ rotation: fragment.image.rotation,
40038
+ crop: fragment.image.crop
40028
40039
  });
40029
40040
  return;
40030
40041
  }
@@ -41272,6 +41283,20 @@ class PdfContentStream {
41272
41283
  page.imageResourceNames.add(options.resourceName);
41273
41284
  const bottom = page.height - options.y - options.height;
41274
41285
  const rotation = Number.isFinite(options.rotation) ? options.rotation ?? 0 : 0;
41286
+ const crop = options.crop;
41287
+ const cl = (crop == null ? void 0 : crop.left) ?? 0;
41288
+ const ct = (crop == null ? void 0 : crop.top) ?? 0;
41289
+ const cr = (crop == null ? void 0 : crop.right) ?? 0;
41290
+ const cb = (crop == null ? void 0 : crop.bottom) ?? 0;
41291
+ if (crop && (cl > 0 || ct > 0 || cr > 0 || cb > 0)) {
41292
+ this.drawCroppedImage(options, bottom, rotation, {
41293
+ left: cl,
41294
+ top: ct,
41295
+ right: cr,
41296
+ bottom: cb
41297
+ });
41298
+ return;
41299
+ }
41275
41300
  if (rotation === 0) {
41276
41301
  page.commands.push(
41277
41302
  [
@@ -41317,6 +41342,63 @@ class PdfContentStream {
41317
41342
  ].join("\n")
41318
41343
  );
41319
41344
  }
41345
+ /**
41346
+ * Draws a cropped image by clipping to the displayed box and scaling the full
41347
+ * image so only the cropped sub-region fills it — mirroring the canvas/DOCX
41348
+ * `a:srcRect` semantics. Works with rotation by mapping box-local space to the
41349
+ * page (rotation about the box centre), clipping in that space, then drawing
41350
+ * the enlarged image behind the clip.
41351
+ */
41352
+ drawCroppedImage(options, bottom, rotation, crop) {
41353
+ const page = this.page;
41354
+ const { width, height } = options;
41355
+ const fw = Math.max(1e-4, 1 - crop.left - crop.right);
41356
+ const fh = Math.max(1e-4, 1 - crop.top - crop.bottom);
41357
+ const fullWidth = width / fw;
41358
+ const fullHeight = height / fh;
41359
+ const originX = -crop.left * fullWidth;
41360
+ const originY = -crop.bottom * fullHeight;
41361
+ const radians = -rotation * Math.PI / 180;
41362
+ const cos = Math.cos(radians);
41363
+ const sin = Math.sin(radians);
41364
+ const cxl = width / 2;
41365
+ const cyl = height / 2;
41366
+ const cxPage = options.x + width / 2;
41367
+ const cyPage = bottom + height / 2;
41368
+ const ra = cos;
41369
+ const rb = sin;
41370
+ const rc = -sin;
41371
+ const rd = cos;
41372
+ const re = cxPage - (ra * cxl + rc * cyl);
41373
+ const rf = cyPage - (rb * cxl + rd * cyl);
41374
+ page.commands.push(
41375
+ [
41376
+ "q",
41377
+ [
41378
+ formatNumber(ra),
41379
+ formatNumber(rb),
41380
+ formatNumber(rc),
41381
+ formatNumber(rd),
41382
+ formatNumber(re),
41383
+ formatNumber(rf),
41384
+ "cm"
41385
+ ].join(" "),
41386
+ // Clip to the displayed box (box-local coordinates).
41387
+ `0 0 ${formatNumber(width)} ${formatNumber(height)} re W n`,
41388
+ [
41389
+ formatNumber(fullWidth),
41390
+ "0",
41391
+ "0",
41392
+ formatNumber(fullHeight),
41393
+ formatNumber(originX),
41394
+ formatNumber(originY),
41395
+ "cm"
41396
+ ].join(" "),
41397
+ `/${options.resourceName} Do`,
41398
+ "Q"
41399
+ ].join("\n")
41400
+ );
41401
+ }
41320
41402
  }
41321
41403
  function parseExtensionLookup(reader, offset, parseSubtable2) {
41322
41404
  reader.seek(offset);
@@ -44227,6 +44309,118 @@ function resizeSelectedImage(state, width, height) {
44227
44309
  height: Math.max(24, Math.round(height))
44228
44310
  }));
44229
44311
  }
44312
+ const MIN_IMAGE_PX = 24;
44313
+ function getSelectedImageSizeCm(state) {
44314
+ const selectedImage = getSelectedImageRun(state);
44315
+ const image = selectedImage && getRunImage(selectedImage.run);
44316
+ if (!image) {
44317
+ return null;
44318
+ }
44319
+ return {
44320
+ width: image.width / PX_PER_CM,
44321
+ height: image.height / PX_PER_CM
44322
+ };
44323
+ }
44324
+ function setSelectedImageWidthCm(state, cm) {
44325
+ const selectedImage = getSelectedImageRun(state);
44326
+ const image = selectedImage && getRunImage(selectedImage.run);
44327
+ if (!image || !Number.isFinite(cm) || cm <= 0) {
44328
+ return state;
44329
+ }
44330
+ const nextWidth = Math.max(MIN_IMAGE_PX, Math.round(cm * PX_PER_CM));
44331
+ const ratio = image.height / image.width;
44332
+ return resizeSelectedImage(state, nextWidth, nextWidth * ratio);
44333
+ }
44334
+ function setSelectedImageHeightCm(state, cm) {
44335
+ const selectedImage = getSelectedImageRun(state);
44336
+ const image = selectedImage && getRunImage(selectedImage.run);
44337
+ if (!image || !Number.isFinite(cm) || cm <= 0) {
44338
+ return state;
44339
+ }
44340
+ const nextHeight = Math.max(MIN_IMAGE_PX, Math.round(cm * PX_PER_CM));
44341
+ const ratio = image.width / image.height;
44342
+ return resizeSelectedImage(state, nextHeight * ratio, nextHeight);
44343
+ }
44344
+ function clampCropSide(value) {
44345
+ if (!value || !Number.isFinite(value) || value < 0) {
44346
+ return 0;
44347
+ }
44348
+ return Math.min(value, 0.99);
44349
+ }
44350
+ function normalizeCrop(crop) {
44351
+ if (!crop) {
44352
+ return void 0;
44353
+ }
44354
+ const left = clampCropSide(crop.left);
44355
+ const top = clampCropSide(crop.top);
44356
+ const right = clampCropSide(crop.right);
44357
+ const bottom = clampCropSide(crop.bottom);
44358
+ const safeRight = Math.min(right, Math.max(0, 0.99 - left));
44359
+ const safeBottom = Math.min(bottom, Math.max(0, 0.99 - top));
44360
+ if (left === 0 && top === 0 && safeRight === 0 && safeBottom === 0) {
44361
+ return void 0;
44362
+ }
44363
+ return { left, top, right: safeRight, bottom: safeBottom };
44364
+ }
44365
+ function setSelectedImageCrop(state, update) {
44366
+ return patchSelectedImage(state, (image) => {
44367
+ const next = { ...image };
44368
+ const crop = normalizeCrop(update.crop);
44369
+ if (crop) {
44370
+ next.crop = crop;
44371
+ } else {
44372
+ delete next.crop;
44373
+ }
44374
+ if (update.width !== void 0) {
44375
+ next.width = Math.max(MIN_IMAGE_PX, Math.round(update.width));
44376
+ }
44377
+ if (update.height !== void 0) {
44378
+ next.height = Math.max(MIN_IMAGE_PX, Math.round(update.height));
44379
+ }
44380
+ return next;
44381
+ });
44382
+ }
44383
+ function computeImageAspectCrop(image, mode) {
44384
+ if (mode === "reset") {
44385
+ return { crop: null };
44386
+ }
44387
+ const target = mode;
44388
+ const { width: W, height: H } = image;
44389
+ if (!Number.isFinite(target) || target <= 0 || W <= 0 || H <= 0) {
44390
+ return { crop: image.crop ?? null };
44391
+ }
44392
+ const c = image.crop ?? {};
44393
+ const l0 = clampCropSide(c.left);
44394
+ const t0 = clampCropSide(c.top);
44395
+ const r0 = clampCropSide(c.right);
44396
+ const b0 = clampCropSide(c.bottom);
44397
+ const currentRatio = W / H;
44398
+ if (currentRatio > target) {
44399
+ const newWidth = H * target;
44400
+ const addFrac = (W - newWidth) / W * Math.max(0, 1 - l0 - r0);
44401
+ return {
44402
+ crop: { ...c, left: l0 + addFrac / 2, right: r0 + addFrac / 2 },
44403
+ width: newWidth
44404
+ };
44405
+ }
44406
+ if (currentRatio < target) {
44407
+ const newHeight = W / target;
44408
+ const addFrac = (H - newHeight) / H * Math.max(0, 1 - t0 - b0);
44409
+ return {
44410
+ crop: { ...c, top: t0 + addFrac / 2, bottom: b0 + addFrac / 2 },
44411
+ height: newHeight
44412
+ };
44413
+ }
44414
+ return { crop: image.crop ?? null };
44415
+ }
44416
+ function applySelectedImageCropAspect(state, mode) {
44417
+ const selectedImage = getSelectedImageRun(state);
44418
+ const image = selectedImage && getRunImage(selectedImage.run);
44419
+ if (!image) {
44420
+ return state;
44421
+ }
44422
+ return setSelectedImageCrop(state, computeImageAspectCrop(image, mode));
44423
+ }
44230
44424
  function normalizeRotation$1(rotation) {
44231
44425
  if (!Number.isFinite(rotation)) {
44232
44426
  return void 0;
@@ -47704,12 +47898,168 @@ function createRotateSession(adapter, deps) {
47704
47898
  };
47705
47899
  return { start, stop };
47706
47900
  }
47901
+ function visibleFraction(near, far) {
47902
+ return Math.max(1e-4, 1 - near - far);
47903
+ }
47904
+ function resolveCroppedImage(geometry, deltaX, deltaY) {
47905
+ const { startWidth: W, startHeight: H } = geometry;
47906
+ const l0 = geometry.startCrop.left ?? 0;
47907
+ const t0 = geometry.startCrop.top ?? 0;
47908
+ const r0 = geometry.startCrop.right ?? 0;
47909
+ const b0 = geometry.startCrop.bottom ?? 0;
47910
+ const kx = visibleFraction(l0, r0) / W;
47911
+ const ky = visibleFraction(t0, b0) / H;
47912
+ const xs = axisSignForDirection(geometry.handleDirection, "x");
47913
+ const ys = axisSignForDirection(geometry.handleDirection, "y");
47914
+ let left = l0;
47915
+ let right = r0;
47916
+ let width = W;
47917
+ if (xs !== 0) {
47918
+ const maxGrow = (xs > 0 ? r0 : l0) / kx;
47919
+ width = clamp$1(W + deltaX * xs, MIN_RESIZE_SIZE_PX, W + maxGrow);
47920
+ const widthDelta = width - W;
47921
+ if (xs > 0) {
47922
+ right = Math.max(0, r0 - widthDelta * kx);
47923
+ } else {
47924
+ left = Math.max(0, l0 - widthDelta * kx);
47925
+ }
47926
+ }
47927
+ let top = t0;
47928
+ let bottom = b0;
47929
+ let height = H;
47930
+ if (ys !== 0) {
47931
+ const maxGrow = (ys > 0 ? b0 : t0) / ky;
47932
+ height = clamp$1(H + deltaY * ys, MIN_RESIZE_SIZE_PX, H + maxGrow);
47933
+ const heightDelta = height - H;
47934
+ if (ys > 0) {
47935
+ bottom = Math.max(0, b0 - heightDelta * ky);
47936
+ } else {
47937
+ top = Math.max(0, t0 - heightDelta * ky);
47938
+ }
47939
+ }
47940
+ return {
47941
+ crop: { left, top, right, bottom },
47942
+ width: Math.round(width),
47943
+ height: Math.round(height)
47944
+ };
47945
+ }
47946
+ function createCropSession(deps) {
47947
+ let active = null;
47948
+ const selectionForObject = (state, paragraphId, paragraphOffset) => {
47949
+ const paragraph = getParagraphs(state).find(
47950
+ (p) => p.id === paragraphId
47951
+ );
47952
+ if (!paragraph) {
47953
+ return null;
47954
+ }
47955
+ return {
47956
+ anchor: paragraphOffsetToPosition(paragraph, paragraphOffset),
47957
+ focus: paragraphOffsetToPosition(paragraph, paragraphOffset + 1)
47958
+ };
47959
+ };
47960
+ const withSelection2 = (state, selection) => ({
47961
+ ...state,
47962
+ selection: {
47963
+ anchor: { ...selection.anchor },
47964
+ focus: { ...selection.focus }
47965
+ }
47966
+ });
47967
+ const handleMouseMove = (event) => {
47968
+ var _a2;
47969
+ const crop = active;
47970
+ if (!crop) {
47971
+ return;
47972
+ }
47973
+ const z = ((_a2 = deps.zoomFactor) == null ? void 0 : _a2.call(deps)) ?? 1;
47974
+ const deltaX = (event.clientX - crop.startClientX) / z;
47975
+ const deltaY = (event.clientY - crop.startClientY) / z;
47976
+ const result = resolveCroppedImage(crop, deltaX, deltaY);
47977
+ const selection = selectionForObject(
47978
+ deps.state,
47979
+ crop.paragraphId,
47980
+ crop.paragraphOffset
47981
+ );
47982
+ if (!selection) {
47983
+ deps.logger.warn("image crop:missing paragraph", crop);
47984
+ return;
47985
+ }
47986
+ deps.applyState(
47987
+ setSelectedImageCrop(withSelection2(deps.state, selection), {
47988
+ crop: result.crop,
47989
+ width: result.width,
47990
+ height: result.height
47991
+ })
47992
+ );
47993
+ };
47994
+ const handleMouseUp = () => {
47995
+ const crop = active;
47996
+ if (crop) {
47997
+ deps.updateHistoryState((current) => ({
47998
+ ...current,
47999
+ undoStack: [...current.undoStack, deps.cloneState(crop.initialState)],
48000
+ redoStack: []
48001
+ }));
48002
+ }
48003
+ stop();
48004
+ deps.focusInput();
48005
+ };
48006
+ const stop = () => {
48007
+ active = null;
48008
+ window.removeEventListener("mousemove", handleMouseMove);
48009
+ window.removeEventListener("mouseup", handleMouseUp);
48010
+ };
48011
+ const start = (paragraphId, paragraphOffset, handleDirection, event, initialState) => {
48012
+ const selection = selectionForObject(
48013
+ initialState,
48014
+ paragraphId,
48015
+ paragraphOffset
48016
+ );
48017
+ if (!selection) {
48018
+ return;
48019
+ }
48020
+ const selected = getSelectedImageRun(
48021
+ withSelection2(initialState, selection)
48022
+ );
48023
+ const image = selected && getRunImage(selected.run);
48024
+ if (!image) {
48025
+ return;
48026
+ }
48027
+ const startCrop = { ...image.crop ?? {} };
48028
+ active = {
48029
+ paragraphId,
48030
+ paragraphOffset,
48031
+ handleDirection,
48032
+ startClientX: event.clientX,
48033
+ startClientY: event.clientY,
48034
+ startWidth: image.width,
48035
+ startHeight: image.height,
48036
+ startCrop,
48037
+ initialState: deps.cloneState(initialState)
48038
+ };
48039
+ window.addEventListener("mousemove", handleMouseMove);
48040
+ window.addEventListener("mouseup", handleMouseUp);
48041
+ };
48042
+ return { start, stop };
48043
+ }
47707
48044
  function createEditorImageOperations(deps) {
47708
48045
  return createEditorImageOperationsImpl(deps);
47709
48046
  }
47710
48047
  function createEditorImageOperationsImpl(deps) {
47711
48048
  const [dragging, setDragging] = createSignal(false);
48049
+ const [cropMode, setCropMode] = createSignal(false);
47712
48050
  const [draggedImageInfo, setDraggedImageInfo] = createSignal(null);
48051
+ createEffect(() => {
48052
+ if (cropMode() && !getSelectedImageInfo(deps.state)) {
48053
+ setCropMode(false);
48054
+ }
48055
+ });
48056
+ const toggleCropMode = () => {
48057
+ if (!getSelectedImageInfo(deps.state)) {
48058
+ setCropMode(false);
48059
+ return;
48060
+ }
48061
+ setCropMode((value) => !value);
48062
+ };
47713
48063
  const [mousePos, setMousePos] = createSignal({ x: 0, y: 0 });
47714
48064
  const [dropTargetPos, setDropTargetPos] = createSignal(
47715
48065
  null
@@ -47811,6 +48161,15 @@ function createEditorImageOperationsImpl(deps) {
47811
48161
  logger: deps.logger
47812
48162
  }
47813
48163
  );
48164
+ const imageCropSession = createCropSession({
48165
+ state: deps.state,
48166
+ applyState: deps.applyState,
48167
+ updateHistoryState: deps.updateHistoryState,
48168
+ cloneState: deps.cloneState,
48169
+ focusInput: deps.focusInput,
48170
+ logger: deps.logger,
48171
+ zoomFactor: deps.zoomFactor
48172
+ });
47814
48173
  const handleImageDragMouseMove = (event) => {
47815
48174
  let dragState = activeImageDrag;
47816
48175
  if (!dragState) {
@@ -47939,8 +48298,22 @@ function createEditorImageOperationsImpl(deps) {
47939
48298
  event.stopPropagation();
47940
48299
  imageRotateSession.start(paragraphId, paragraphOffset, event, deps.state);
47941
48300
  };
48301
+ const handleImageCropHandleMouseDown = (paragraphId, paragraphOffset, direction, event) => {
48302
+ event.preventDefault();
48303
+ event.stopPropagation();
48304
+ imageCropSession.start(
48305
+ paragraphId,
48306
+ paragraphOffset,
48307
+ direction,
48308
+ event,
48309
+ deps.state
48310
+ );
48311
+ };
47942
48312
  return {
47943
48313
  dragging,
48314
+ cropMode,
48315
+ setCropMode,
48316
+ toggleCropMode,
47944
48317
  draggedImageInfo,
47945
48318
  mousePos,
47946
48319
  dropTargetPos,
@@ -47949,9 +48322,11 @@ function createEditorImageOperationsImpl(deps) {
47949
48322
  stopImageDrag,
47950
48323
  stopImageResize: imageResizeSession.stop,
47951
48324
  stopImageRotate: imageRotateSession.stop,
48325
+ stopImageCrop: imageCropSession.stop,
47952
48326
  handleImageMouseDown,
47953
48327
  handleImageResizeHandleMouseDown,
47954
- handleImageRotateHandleMouseDown
48328
+ handleImageRotateHandleMouseDown,
48329
+ handleImageCropHandleMouseDown
47955
48330
  };
47956
48331
  }
47957
48332
  function createEditorTextBoxOperations(deps) {
@@ -51986,6 +52361,22 @@ function setParagraphListStartAt(state, startAt) {
51986
52361
  preserveSelectionByParagraphOffsets(nextParagraphs, normalized)
51987
52362
  );
51988
52363
  }
52364
+ function parseCropAspectPreset(preset) {
52365
+ const value = preset.trim().toLowerCase();
52366
+ if (value === "reset" || value === "fit" || value === "fill") {
52367
+ return "reset";
52368
+ }
52369
+ const parts = value.split(/[:/]/);
52370
+ if (parts.length !== 2) {
52371
+ return null;
52372
+ }
52373
+ const a = Number(parts[0]);
52374
+ const b = Number(parts[1]);
52375
+ if (!Number.isFinite(a) || !Number.isFinite(b) || a <= 0 || b <= 0) {
52376
+ return null;
52377
+ }
52378
+ return a / b;
52379
+ }
51989
52380
  function createEditorCommandsController(deps) {
51990
52381
  return createEditorCommandsControllerImpl(deps);
51991
52382
  }
@@ -52280,6 +52671,36 @@ function createEditorCommandsControllerImpl(deps) {
52280
52671
  }
52281
52672
  deps.openImageCaptionDialog(getSelectedImageCaption(state) ?? "");
52282
52673
  };
52674
+ const applyImageWidthCmCommand = (cm) => {
52675
+ if (!selectedImageRun() || !Number.isFinite(cm) || cm <= 0) {
52676
+ return;
52677
+ }
52678
+ execTransactional(
52679
+ (current) => setSelectedImageWidthCm(current, cm),
52680
+ { mergeKey: MERGE_KEYS.imageResize }
52681
+ );
52682
+ };
52683
+ const applyImageHeightCmCommand = (cm) => {
52684
+ if (!selectedImageRun() || !Number.isFinite(cm) || cm <= 0) {
52685
+ return;
52686
+ }
52687
+ execTransactional(
52688
+ (current) => setSelectedImageHeightCm(current, cm),
52689
+ { mergeKey: MERGE_KEYS.imageResize }
52690
+ );
52691
+ };
52692
+ const applyImageCropAspectCommand = (preset) => {
52693
+ if (!selectedImageRun()) {
52694
+ return;
52695
+ }
52696
+ const mode = parseCropAspectPreset(preset);
52697
+ if (mode === null) {
52698
+ return;
52699
+ }
52700
+ execTransactional(
52701
+ (current) => applySelectedImageCropAspect(current, mode)
52702
+ );
52703
+ };
52283
52704
  return {
52284
52705
  applyBooleanStyleCommand,
52285
52706
  applyValueStyleCommand,
@@ -52308,6 +52729,9 @@ function createEditorCommandsControllerImpl(deps) {
52308
52729
  promptForImageAlt,
52309
52730
  applyImageCaptionCommand,
52310
52731
  promptForImageCaption,
52732
+ applyImageWidthCmCommand,
52733
+ applyImageHeightCmCommand,
52734
+ applyImageCropAspectCommand,
52311
52735
  handleListTab,
52312
52736
  handleListEnter,
52313
52737
  handleListBoundaryBackspace
@@ -53311,6 +53735,53 @@ function buildDocumentAndBrowserCommands({
53311
53735
  isEnabled: image.isSelected(),
53312
53736
  isActive: image.isSelected()
53313
53737
  })
53738
+ ),
53739
+ imageContext: actionCommand(
53740
+ "imageContext",
53741
+ () => {
53742
+ },
53743
+ () => ({
53744
+ isEnabled: image.isSelected(),
53745
+ isActive: image.isSelected(),
53746
+ value: null
53747
+ })
53748
+ ),
53749
+ imageWidthCm: actionCommand(
53750
+ "imageWidthCm",
53751
+ (p) => image.setWidthCm(Number(p)),
53752
+ () => {
53753
+ var _a2;
53754
+ return {
53755
+ isEnabled: image.isSelected(),
53756
+ value: ((_a2 = image.getSizeCm()) == null ? void 0 : _a2.width) ?? null
53757
+ };
53758
+ }
53759
+ ),
53760
+ imageHeightCm: actionCommand(
53761
+ "imageHeightCm",
53762
+ (p) => image.setHeightCm(Number(p)),
53763
+ () => {
53764
+ var _a2;
53765
+ return {
53766
+ isEnabled: image.isSelected(),
53767
+ value: ((_a2 = image.getSizeCm()) == null ? void 0 : _a2.height) ?? null
53768
+ };
53769
+ }
53770
+ ),
53771
+ imageCrop: actionCommand(
53772
+ "imageCrop",
53773
+ () => image.toggleCrop(),
53774
+ () => ({
53775
+ isEnabled: image.isSelected(),
53776
+ isActive: image.isCropActive()
53777
+ })
53778
+ ),
53779
+ imageCropAspect: actionCommand(
53780
+ "imageCropAspect",
53781
+ (p) => image.applyCropAspect(String(p)),
53782
+ () => ({
53783
+ isEnabled: image.isSelected()
53784
+ })
53314
53785
  )
53315
53786
  };
53316
53787
  }
@@ -54128,7 +54599,13 @@ function buildEssentialsImage(options) {
54128
54599
  return {
54129
54600
  promptAlt: () => options.commandsController.promptForImageAlt(),
54130
54601
  promptCaption: () => options.commandsController.promptForImageCaption(),
54131
- isSelected: () => Boolean(options.selectedImageRun())
54602
+ isSelected: () => Boolean(options.selectedImageRun()),
54603
+ getSizeCm: () => getSelectedImageSizeCm(options.state()),
54604
+ setWidthCm: (cm) => options.commandsController.applyImageWidthCmCommand(cm),
54605
+ setHeightCm: (cm) => options.commandsController.applyImageHeightCmCommand(cm),
54606
+ isCropActive: () => options.imageCropMode.isActive(),
54607
+ toggleCrop: () => options.imageCropMode.toggle(),
54608
+ applyCropAspect: (preset) => options.commandsController.applyImageCropAspectCommand(preset)
54132
54609
  };
54133
54610
  }
54134
54611
  function buildEssentialsBrowser() {
@@ -55077,6 +55554,10 @@ function createEditorCommandRuntimeImpl(deps) {
55077
55554
  importInputRef: deps.importInputRef,
55078
55555
  imageInputRef: deps.imageInputRef,
55079
55556
  selectedImageRun: interaction.selectedImageRun,
55557
+ imageCropMode: {
55558
+ isActive: interaction.imageOps.cropMode,
55559
+ toggle: interaction.imageOps.toggleCropMode
55560
+ },
55080
55561
  selectionBoxes: doc.selectionBoxes,
55081
55562
  focusInput: deps.focusInput,
55082
55563
  applyState: deps.applyState,
@@ -55403,7 +55884,8 @@ function OasisEditorApp(props = {}) {
55403
55884
  hoveredRevision: revisionController.hoveredRevision,
55404
55885
  focused,
55405
55886
  showCaret: shouldShowCaret,
55406
- importProgress: docIO.importProgress
55887
+ importProgress: docIO.importProgress,
55888
+ imageCropMode: imageOps.cropMode
55407
55889
  },
55408
55890
  refs: {
55409
55891
  focusController
@@ -55424,6 +55906,7 @@ function OasisEditorApp(props = {}) {
55424
55906
  handleImageResizeHandleMouseDown: imageOps.handleImageResizeHandleMouseDown,
55425
55907
  handleTextBoxResizeHandleMouseDown: textBoxOps.handleTextBoxResizeHandleMouseDown,
55426
55908
  handleImageRotateHandleMouseDown: imageOps.handleImageRotateHandleMouseDown,
55909
+ handleImageCropHandleMouseDown: imageOps.handleImageCropHandleMouseDown,
55427
55910
  handleTextBoxRotateHandleMouseDown: textBoxOps.handleTextBoxRotateHandleMouseDown,
55428
55911
  handleEditorContextMenu
55429
55912
  },
@@ -55452,6 +55935,7 @@ function OasisEditorApp(props = {}) {
55452
55935
  textDrag.stopDrag();
55453
55936
  imageOps.stopImageDrag();
55454
55937
  imageOps.stopImageResize();
55938
+ imageOps.stopImageCrop();
55455
55939
  textBoxOps.stopTextBoxResize();
55456
55940
  stopIconObserver();
55457
55941
  });