@univerjs/docs-ui 1.0.0-alpha.0 → 1.0.0-alpha.1

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/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { BaselineOffset, BlockType, BooleanNumber, BuildTextUtils, COLORS, ColorKit, CommandType, CustomRangeType, DEFAULT_DOCUMENT_PARAGRAPH_LINE_SPACING, DEFAULT_DOCUMENT_PARAGRAPH_SPACE_ABOVE, DEFAULT_DOCUMENT_PARAGRAPH_SPACE_BELOW, DEFAULT_EMPTY_DOCUMENT_VALUE, DEFAULT_STYLES, DOCS_FORMULA_BAR_EDITOR_UNIT_ID_KEY, DOCS_NORMAL_EDITOR_UNIT_ID_KEY, DOC_RANGE_TYPE, DashStyleType, DataStreamTreeNodeType, DataStreamTreeTokenType, DeleteDirection, DependentOn, Direction, Disposable, DisposableCollection, DocumentBlockRangeType, DocumentFlavor, DrawingTypeEnum, EDITOR_ACTIVATED, FOCUSING_COMMENT_EDITOR, FOCUSING_COMMON_DRAWINGS, FOCUSING_DOC, FOCUSING_EDITOR_STANDALONE, FOCUSING_UNIVER_EDITOR, HorizontalAlign, ICommandService, IConfigService, IConfirmService, IContextService, ILogService, IUndoRedoService, IUniverInstanceService, Inject, Injector, InterceptorManager, JSONX, LRUMap, LocaleService, MODERN_DOCUMENT_DEFAULT_MARGIN, MODERN_DOCUMENT_WIDTH, MemoryCursor, ModernDocumentWidthMode, NAMED_STYLE_MAP, NamedStyleType, ObjectRelativeFromH, ObjectRelativeFromV, PAGE_SIZE, PAPER_TYPES, PRESET_LIST_TYPE, PageOrientType, Plugin, PositionedObjectLayoutType, PresetListType, QuickListTypeMap, RANGE_DIRECTION, Rectangle, RedoCommand, RxDisposable, SHEET_EDITOR_UNITS, SliceBodyType, SpacingRule, TableAlignmentType, TableRowHeightRule, TableSizeType, TableTextWrapType, TextX, TextXActionType, ThemeService, Tools, UndoCommand, UniverInstanceType, UpdateDocsAttributeType, VerticalAlign, checkForSubstrings, createIdentifier, createInterceptorKey, createInternalEditorID, createParagraphId, debounce, deepCompare, fromEventSubject, generateRandomId, getBodySlice, getPlainText, getRichTextEditPath, isCommentEditorID, isInternalEditorID, isSafeUrl, merge, mergeOverrideWithDependencies, normalizeBody, sequenceExecuteAsync, skipParseTagNames, toDisposable, touchDependencies } from "@univerjs/core";
2
- import { DeleteTextCommand, DocContentInsertService, DocInterceptorService, DocSelectionManagerService, DocSkeletonManagerService, DocStateEmitService, IDocStateChangeInterceptorService, InsertTextCommand, RichTextEditingMutation, SetTextSelectionsOperation, UpdateTextCommand } from "@univerjs/docs";
3
- import { CURSOR_TYPE, DeviceInputEventType, DocBackground, DocumentEditArea, DocumentSkeletonPageType, Documents, GlyphType, IRenderManagerService, Layer, Liquid, NORMAL_TEXT_SELECTION_PLUGIN_STYLE, PageLayoutType, Path, Rect, RegularPolygon, ScrollBar, ScrollTimer, Shape, TRANSFORM_CHANGE_OBSERVABLE_TYPE, UniverRenderEnginePlugin, Vector2, Viewport, getColor, getDocsTableRenderViewport, getLastColumn, getLastLine, getNextWheelZoomRatio, getNumberUnitValue, getOffsetRectForDom, getPageFromPath, getParagraphByGlyph, getSystemHighlightColor, getTableIdAndSliceIndex, hasListGlyph, isFirstGlyph, isIndentByGlyph, lineIterator, parseDataStreamToTree, pixelToPt, ptToPixel, pxToNum } from "@univerjs/engine-render";
1
+ import { BaselineOffset, BlockType, BooleanNumber, BuildTextUtils, COLORS, ColorKit, CommandType, CustomRangeType, DEFAULT_DOCUMENT_PARAGRAPH_LINE_SPACING, DEFAULT_DOCUMENT_PARAGRAPH_SPACE_ABOVE, DEFAULT_DOCUMENT_PARAGRAPH_SPACE_BELOW, DEFAULT_EMPTY_DOCUMENT_VALUE, DEFAULT_STYLES, DOCS_FORMULA_BAR_EDITOR_UNIT_ID_KEY, DOCS_NORMAL_EDITOR_UNIT_ID_KEY, DOC_RANGE_TYPE, DashStyleType, DataStreamTreeNodeType, DataStreamTreeTokenType, DeleteDirection, DependentOn, Direction, Disposable, DisposableCollection, DocumentBlockRangeType, DocumentBlockType, DocumentFlavor, DrawingTypeEnum, EDITOR_ACTIVATED, FOCUSING_COMMENT_EDITOR, FOCUSING_COMMON_DRAWINGS, FOCUSING_DOC, FOCUSING_EDITOR_STANDALONE, FOCUSING_UNIVER_EDITOR, HorizontalAlign, ICommandService, IConfigService, IConfirmService, IContextService, ILogService, IUndoRedoService, IUniverInstanceService, Inject, Injector, InterceptorManager, JSONX, LRUMap, LocaleService, MODERN_DOCUMENT_DEFAULT_MARGIN, MODERN_DOCUMENT_WIDTH, MemoryCursor, ModernDocumentWidthMode, NAMED_STYLE_MAP, NamedStyleType, ObjectRelativeFromH, ObjectRelativeFromV, PAGE_SIZE, PAPER_TYPES, PRESET_LIST_TYPE, PageOrientType, Plugin, PositionedObjectLayoutType, PresetListType, QuickListTypeMap, RANGE_DIRECTION, Rectangle, RedoCommand, RxDisposable, SHEET_EDITOR_UNITS, SliceBodyType, SpacingRule, TableAlignmentType, TableRowHeightRule, TableSizeType, TableTextWrapType, TextX, TextXActionType, ThemeService, Tools, UndoCommand, UniverInstanceType, UpdateDocsAttributeType, VerticalAlign, checkForSubstrings, createIdentifier, createInterceptorKey, createInternalEditorID, createParagraphId, debounce, deepCompare, fromEventSubject, generateRandomId, getBodySlice, getPlainText, getRichTextEditPath, isCommentEditorID, isInternalEditorID, isSafeUrl, merge, mergeOverrideWithDependencies, normalizeBody, remove, sequenceExecuteAsync, skipParseTagNames, toDisposable, touchDependencies } from "@univerjs/core";
2
+ import { DeleteTextCommand, DocBlockMoveValidatorService, DocContentInsertService, DocInterceptorService, DocSelectionManagerService, DocSkeletonManagerService, DocStateEmitService, IDocStateChangeInterceptorService, InsertTextCommand, RichTextEditingMutation, SetTextSelectionsOperation, UpdateTextCommand } from "@univerjs/docs";
3
+ import { CURSOR_TYPE, DeviceInputEventType, DocBackground, DocumentEditArea, DocumentSkeletonPageType, Documents, GlyphType, IRenderManagerService, Layer, LineType, Liquid, NORMAL_TEXT_SELECTION_PLUGIN_STYLE, PageLayoutType, Path, Rect, RegularPolygon, ScrollBar, ScrollTimer, Shape, TRANSFORM_CHANGE_OBSERVABLE_TYPE, UniverRenderEnginePlugin, Vector2, Viewport, compareDocumentSkeletonNestedPagePathOrder, documentSkeletonLineIterator, documentSkeletonTableIterator, getColor, getDocsTableRenderViewport, getDocumentSkeletonColumnPagePathInfo, getDocumentSkeletonNestedPageOffset, getLastColumn, getNextWheelZoomRatio, getNumberUnitValue, getOffsetRectForDom, getPageFromPath, getParagraphByGlyph, getSystemHighlightColor, getTableIdAndSliceIndex, hasListGlyph, isFirstGlyph, isIndentByGlyph, parseDataStreamToTree, pixelToPt, ptToPixel, pxToNum } from "@univerjs/engine-render";
4
4
  import { BuiltInUIPart, COLOR_PICKER_COMPONENT, COMMON_LABEL_COMPONENT, ComponentManager, ContextMenuGroup, ContextMenuPanel, ContextMenuPosition, CopyCommand, CutCommand, FILE_PNG_CLIPBOARD_MIME_TYPE, FILE__BMP_CLIPBOARD_MIME_TYPE, FILE__JPEG_CLIPBOARD_MIME_TYPE, FILE__WEBP_CLIPBOARD_MIME_TYPE, FONT_FAMILY_COMPONENT, FONT_FAMILY_ITEM_COMPONENT, FONT_SIZE_COMPONENT, FONT_SIZE_LIST, HEADING_ITEM_COMPONENT, HEADING_LIST, HTML_CLIPBOARD_MIME_TYPE, ICanvasPopupService, IClipboardInterfaceService, IContextMenuService, ILayoutService, IMenuManagerService, IShortcutService, ISidebarService, IUIPartsService, IconManager, KeyCode, MenuItemType, MenuManagerPosition, MetaKeys, PLAIN_TEXT_CLIPBOARD_MIME_TYPE, PasteCommand, RectPopup, RibbonInsertGroup, RibbonStartGroup, Slider, ToolbarItem, connectInjector, getMenuHiddenObservable, imageMimeTypeSet, useConfigValue, useDependency, useEvent, useObservable } from "@univerjs/ui";
5
5
  import { ImageSourceType } from "@univerjs/drawing";
6
6
  import { BehaviorSubject, Observable, Subject, animationFrameScheduler, combineLatest, distinctUntilChanged, filter, first, fromEvent, map, merge as merge$1, of, switchMap, take, takeUntil, throttleTime } from "rxjs";
@@ -8,7 +8,7 @@ import { bufferTime, filter as filter$1, map as map$1 } from "rxjs/operators";
8
8
  import { Button, Checkbox, InputNumber, Select, Tooltip, borderClassName, clsx, scrollbarClassName } from "@univerjs/design";
9
9
  import { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
- import { AddImageIcon, AlignTextBothIcon, BoldIcon, CatalogueIcon, CopyDoubleIcon, CutIcon, DeleteColumnDoubleIcon, DeleteIcon, DeleteRowDoubleIcon, DocSettingIcon, FontColorDoubleIcon, GridIcon, H1Icon, H2Icon, H3Icon, H4Icon, H5Icon, HeaderFooterIcon, HorizontallyIcon, InsertDoubleIcon, InsertRowAboveDoubleIcon, InsertRowBelowDoubleIcon, ItalicIcon, KeyboardIcon, LeftIcon, LeftInsertColumnDoubleIcon, LeftJustifyingIcon, MenuIcon, MoreLeftIcon, MoreRightIcon, NoColorDoubleIcon, OrderIcon, PaintBucketDoubleIcon, PasteSpecialDoubleIcon, ReduceDoubleIcon, ReduceIcon, RightInsertColumnDoubleIcon, RightJustifyingIcon, ShapeIcon, StrikethroughIcon, SubscriptIcon, SuperscriptIcon, TextTypeIcon, TodoListDoubleIcon, UnderlineIcon, UnorderIcon } from "@univerjs/icons";
11
+ import { AddImageIcon, AlignTextBothIcon, BoldIcon, CatalogueIcon, CopyDoubleIcon, CutIcon, DeleteColumnDoubleIcon, DeleteIcon, DeleteRowDoubleIcon, DocSettingIcon, FontColorDoubleIcon, GridIcon, H1Icon, H2Icon, H3Icon, H4Icon, H5Icon, HeaderFooterIcon, HorizontallyIcon, InsertDoubleIcon, InsertRowAboveDoubleIcon, InsertRowBelowDoubleIcon, ItalicIcon, KeyboardIcon, LeftInsertColumnDoubleIcon, LeftJustifyingIcon, MenuIcon, MoreLeftIcon, MoreRightIcon, NoColorDoubleIcon, OrderIcon, PaintBucketDoubleIcon, PasteSpecialDoubleIcon, ReduceDoubleIcon, ReduceIcon, RightInsertColumnDoubleIcon, RightJustifyingIcon, ShapeIcon, StrikethroughIcon, SubscriptIcon, SuperscriptIcon, TextTypeIcon, TodoListDoubleIcon, UnderlineIcon, UnorderIcon } from "@univerjs/icons";
12
12
 
13
13
  //#region src/basics/docs-view-key.ts
14
14
  /**
@@ -3594,14 +3594,36 @@ function hasVisibleHtml(html) {
3594
3594
  return /<(?:img|br)\b/i.test(html) || html.replace(/<[^>]+>/g, "").replace(/&nbsp;/gi, " ").trim().length > 0;
3595
3595
  }
3596
3596
  var UDMToHtmlService = class {
3597
+ constructor(_docHtmlExportService) {
3598
+ this._docHtmlExportService = _docHtmlExportService;
3599
+ }
3597
3600
  convert(docList) {
3598
3601
  if (docList.length === 0) throw new Error("The bodyList length at least to be 1");
3599
3602
  let html = "";
3600
- for (const doc of Tools.deepClone(docList)) html += convertBodyToHtml(doc);
3603
+ for (const doc of Tools.deepClone(docList)) {
3604
+ var _this$_docHtmlExportS, _this$_docHtmlExportS2;
3605
+ html += convertBodyToHtml((_this$_docHtmlExportS = (_this$_docHtmlExportS2 = this._docHtmlExportService) === null || _this$_docHtmlExportS2 === void 0 ? void 0 : _this$_docHtmlExportS2.transformDocumentForHtmlExport(doc)) !== null && _this$_docHtmlExportS !== void 0 ? _this$_docHtmlExportS : doc);
3606
+ }
3601
3607
  return html;
3602
3608
  }
3603
3609
  };
3604
3610
 
3611
+ //#endregion
3612
+ //#region src/services/clipboard/udm-to-html/doc-html-export.service.ts
3613
+ var DocHtmlExportService = class extends Disposable {
3614
+ constructor(..._args) {
3615
+ super(..._args);
3616
+ _defineProperty(this, "_transformers", []);
3617
+ }
3618
+ registerTransformer(transformer) {
3619
+ this._transformers.push(transformer);
3620
+ return this.disposeWithMe(toDisposable(() => remove(this._transformers, transformer)));
3621
+ }
3622
+ transformDocumentForHtmlExport(documentData) {
3623
+ return this._transformers.reduce((doc, transformer) => transformer(doc), documentData);
3624
+ }
3625
+ };
3626
+
3605
3627
  //#endregion
3606
3628
  //#region src/services/clipboard/clipboard.service.ts
3607
3629
  HtmlToUDMService.use(LarkPastePlugin);
@@ -3639,7 +3661,7 @@ function getTableCellContentClipboardBodySlice(body, start, end) {
3639
3661
  }
3640
3662
  const IDocClipboardService = createIdentifier("doc.clipboard-service");
3641
3663
  let DocClipboardService = class DocClipboardService extends Disposable {
3642
- constructor(_univerInstanceService, _logService, _commandService, _clipboardInterfaceService, _docSelectionManagerService) {
3664
+ constructor(_univerInstanceService, _logService, _commandService, _clipboardInterfaceService, docHtmlExportService, _docSelectionManagerService) {
3643
3665
  super();
3644
3666
  this._univerInstanceService = _univerInstanceService;
3645
3667
  this._logService = _logService;
@@ -3648,7 +3670,8 @@ let DocClipboardService = class DocClipboardService extends Disposable {
3648
3670
  this._docSelectionManagerService = _docSelectionManagerService;
3649
3671
  _defineProperty(this, "_clipboardHooks", []);
3650
3672
  _defineProperty(this, "_htmlToUDM", new HtmlToUDMService());
3651
- _defineProperty(this, "_umdToHtml", new UDMToHtmlService());
3673
+ _defineProperty(this, "_umdToHtml", void 0);
3674
+ this._umdToHtml = new UDMToHtmlService(docHtmlExportService);
3652
3675
  }
3653
3676
  async copy(sliceType = SliceBodyType.copy, ranges) {
3654
3677
  var _this$_getDocumentBod;
@@ -4004,7 +4027,8 @@ DocClipboardService = __decorate([
4004
4027
  __decorateParam(1, ILogService),
4005
4028
  __decorateParam(2, ICommandService),
4006
4029
  __decorateParam(3, IClipboardInterfaceService),
4007
- __decorateParam(4, Inject(DocSelectionManagerService))
4030
+ __decorateParam(4, Inject(DocHtmlExportService)),
4031
+ __decorateParam(5, Inject(DocSelectionManagerService))
4008
4032
  ], DocClipboardService);
4009
4033
  function dataUrlToFile(dataUrl, fallbackName) {
4010
4034
  const match = /^data:([^;,]+)(;base64)?,(.*)$/i.exec(dataUrl);
@@ -4099,11 +4123,18 @@ const MoveDocBlockCommand = {
4099
4123
  const doc = params.unitId ? univerInstanceService.getUnit(params.unitId, UniverInstanceType.UNIVER_DOC) : univerInstanceService.getCurrentUniverDocInstance();
4100
4124
  if (!doc) return false;
4101
4125
  const previousDocumentData = doc.getSnapshot();
4102
- const { nextDocumentData, movedRange } = buildMoveDocBlockActions({
4126
+ const moveResult = buildMoveDocBlockActions({
4103
4127
  documentData: previousDocumentData,
4104
4128
  sourceRange: params.sourceRange,
4105
4129
  targetOffset: params.targetOffset
4106
4130
  });
4131
+ const { nextDocumentData, movedRange } = accessor.get(DocBlockMoveValidatorService).transformMoveResult({
4132
+ unitId: doc.getUnitId(),
4133
+ sourceRange: params.sourceRange,
4134
+ targetOffset: params.targetOffset,
4135
+ previousDocumentData,
4136
+ result: moveResult
4137
+ });
4107
4138
  const actions = buildReplaceDocumentBodyActions(previousDocumentData, nextDocumentData);
4108
4139
  if (!actions) return false;
4109
4140
  const textRanges = [{
@@ -4160,6 +4191,7 @@ function buildReplaceDocumentBodyActions(previousDocumentData, nextDocumentData)
4160
4191
  jsonX.replaceOp(["body", "paragraphs"], previousBody.paragraphs, nextBody.paragraphs),
4161
4192
  jsonX.replaceOp(["body", "sectionBreaks"], previousBody.sectionBreaks, nextBody.sectionBreaks),
4162
4193
  jsonX.replaceOp(["body", "tables"], previousBody.tables, nextBody.tables),
4194
+ jsonX.replaceOp(["body", "columnGroups"], previousBody.columnGroups, nextBody.columnGroups),
4163
4195
  jsonX.replaceOp(["body", "customBlocks"], previousBody.customBlocks, nextBody.customBlocks),
4164
4196
  jsonX.replaceOp(["body", "blockRanges"], previousBody.blockRanges, nextBody.blockRanges),
4165
4197
  jsonX.replaceOp(["body", "customRanges"], previousBody.customRanges, nextBody.customRanges),
@@ -4168,7 +4200,7 @@ function buildReplaceDocumentBodyActions(previousDocumentData, nextDocumentData)
4168
4200
  ].filter(Boolean).reduce((acc, cur) => JSONX.compose(acc, cur), null);
4169
4201
  }
4170
4202
  function remapBodyIndexesAfterMove(body, startOffset, endOffset, targetOffset, insertOffset, moveLength) {
4171
- var _body$paragraphs, _body$sectionBreaks, _body$customBlocks, _body$tables, _body$blockRanges, _body$customRanges, _body$customDecoratio, _body$textRuns;
4203
+ var _body$paragraphs, _body$sectionBreaks, _body$customBlocks, _body$tables, _body$columnGroups, _body$blockRanges, _body$customRanges, _body$customDecoratio, _body$textRuns;
4172
4204
  body.paragraphs = (_body$paragraphs = body.paragraphs) === null || _body$paragraphs === void 0 ? void 0 : _body$paragraphs.map((paragraph) => ({
4173
4205
  ...paragraph,
4174
4206
  startIndex: remapIndexAfterMove(paragraph.startIndex, startOffset, endOffset, targetOffset, insertOffset, moveLength)
@@ -4182,6 +4214,7 @@ function remapBodyIndexesAfterMove(body, startOffset, endOffset, targetOffset, i
4182
4214
  startIndex: remapIndexAfterMove(customBlock.startIndex, startOffset, endOffset, targetOffset, insertOffset, moveLength)
4183
4215
  })).sort((left, right) => left.startIndex - right.startIndex);
4184
4216
  body.tables = (_body$tables = body.tables) === null || _body$tables === void 0 ? void 0 : _body$tables.map((table) => remapExclusiveRange(table, startOffset, endOffset, targetOffset, insertOffset, moveLength)).sort((left, right) => left.startIndex - right.startIndex);
4217
+ body.columnGroups = (_body$columnGroups = body.columnGroups) === null || _body$columnGroups === void 0 ? void 0 : _body$columnGroups.map((columnGroup) => remapExclusiveRange(columnGroup, startOffset, endOffset, targetOffset, insertOffset, moveLength)).sort((left, right) => left.startIndex - right.startIndex);
4185
4218
  body.blockRanges = (_body$blockRanges = body.blockRanges) === null || _body$blockRanges === void 0 ? void 0 : _body$blockRanges.map((blockRange) => remapInclusiveRange(blockRange, startOffset, endOffset, targetOffset, insertOffset, moveLength)).sort((left, right) => left.startIndex - right.startIndex);
4186
4219
  body.customRanges = (_body$customRanges = body.customRanges) === null || _body$customRanges === void 0 ? void 0 : _body$customRanges.map((customRange) => remapInclusiveRange(customRange, startOffset, endOffset, targetOffset, insertOffset, moveLength)).sort((left, right) => left.startIndex - right.startIndex);
4187
4220
  body.customDecorations = (_body$customDecoratio = body.customDecorations) === null || _body$customDecoratio === void 0 ? void 0 : _body$customDecoratio.map((customDecoration) => remapInclusiveRange(customDecoration, startOffset, endOffset, targetOffset, insertOffset, moveLength)).sort((left, right) => left.startIndex - right.startIndex);
@@ -4206,7 +4239,7 @@ function remapExclusiveRange(range, startOffset, endOffset, targetOffset, insert
4206
4239
  return {
4207
4240
  ...range,
4208
4241
  startIndex: remapIndexAfterMove(range.startIndex, startOffset, endOffset, targetOffset, insertOffset, moveLength),
4209
- endIndex: remapIndexAfterMove(range.endIndex, startOffset, endOffset, targetOffset, insertOffset, moveLength)
4242
+ endIndex: remapExclusiveEndIndexAfterMove(range.endIndex, startOffset, endOffset, targetOffset, insertOffset, moveLength)
4210
4243
  };
4211
4244
  }
4212
4245
  function remapInclusiveRange(range, startOffset, endOffset, targetOffset, insertOffset, moveLength) {
@@ -4227,6 +4260,11 @@ function remapIndexAfterMove(index, startOffset, endOffset, targetOffset, insert
4227
4260
  if (targetOffset > endOffset && index >= endOffset && index < targetOffset) return index - moveLength;
4228
4261
  return index;
4229
4262
  }
4263
+ function remapExclusiveEndIndexAfterMove(index, startOffset, endOffset, targetOffset, insertOffset, moveLength) {
4264
+ if (index > startOffset && index <= endOffset) return insertOffset + index - startOffset;
4265
+ if (targetOffset > endOffset && index >= endOffset && index <= targetOffset) return index - moveLength;
4266
+ return remapIndexAfterMove(index, startOffset, endOffset, targetOffset, insertOffset, moveLength);
4267
+ }
4230
4268
  function clamp$1(value, min, max) {
4231
4269
  return Math.min(Math.max(value, min), max);
4232
4270
  }
@@ -5910,6 +5948,8 @@ const NodePositionMap = {
5910
5948
  glyph: 5
5911
5949
  };
5912
5950
  function compareNodePositionLogic(pos1, pos2) {
5951
+ const nestedPagePathOrder = compareDocumentSkeletonNestedPagePathOrder(pos1, pos2);
5952
+ if (nestedPagePathOrder != null) return nestedPagePathOrder;
5913
5953
  if (pos1.page > pos2.page) return false;
5914
5954
  if (pos1.page < pos2.page) return true;
5915
5955
  if (pos1.section > pos2.section) return false;
@@ -6205,9 +6245,18 @@ var NodePositionConvertToCursor = class {
6205
6245
  break;
6206
6246
  }
6207
6247
  case DocumentSkeletonPageType.CELL: {
6248
+ const nestedPageOffset = getDocumentSkeletonNestedPageOffset(segmentPage);
6249
+ if (nestedPageOffset) {
6250
+ this._liquid.translatePagePadding(page);
6251
+ this._liquid.translate(nestedPageOffset.left, nestedPageOffset.top);
6252
+ this._liquid.translatePagePadding(segmentPage);
6253
+ break;
6254
+ }
6208
6255
  this._liquid.translatePagePadding(page);
6209
6256
  const rowSke = segmentPage.parent;
6210
6257
  const tableSke = rowSke.parent;
6258
+ const tablePage = tableSke.parent;
6259
+ const tablePageNestedOffset = tablePage ? getDocumentSkeletonNestedPageOffset(tablePage) : void 0;
6211
6260
  const { left: cellLeft } = segmentPage;
6212
6261
  const { top: tableTop, left: tableLeft } = tableSke;
6213
6262
  const { top: rowTop } = rowSke;
@@ -6215,6 +6264,10 @@ var NodePositionConvertToCursor = class {
6215
6264
  const viewport = getDocsTableRenderViewport(getDocumentUnitId$1(skeleton), sourceTableId);
6216
6265
  const hasHorizontalViewport = hasHorizontalTableViewport$2(viewport);
6217
6266
  const scrollLeft = hasHorizontalViewport ? viewport.scrollLeft : 0;
6267
+ if (tablePageNestedOffset) {
6268
+ this._liquid.translate(tablePageNestedOffset.left, tablePageNestedOffset.top);
6269
+ this._liquid.translatePagePadding(tablePage);
6270
+ }
6218
6271
  if (hasHorizontalViewport) {
6219
6272
  var _viewport$leadingInse;
6220
6273
  const visibleLeft = this._liquid.x + tableLeft - ((_viewport$leadingInse = viewport.leadingInsetLeft) !== null && _viewport$leadingInse !== void 0 ? _viewport$leadingInse : 0);
@@ -6316,8 +6369,14 @@ function isInSameTableCell(anchorNodePosition, focusNodePosition) {
6316
6369
  const { path: anchorPath } = anchorNodePosition;
6317
6370
  const { path: focusPath } = focusNodePosition;
6318
6371
  if (anchorPath.indexOf("cells") === -1 || focusPath.indexOf("cells") === -1) return false;
6319
- if (anchorPath.length !== focusPath.length) return false;
6320
- return Tools.diffValue(anchorPath, focusPath);
6372
+ const anchorTableIdIndex = anchorPath.indexOf("skeTables") + 1;
6373
+ const anchorRowIndex = anchorPath.indexOf("rows") + 1;
6374
+ const anchorCellIndex = anchorPath.indexOf("cells") + 1;
6375
+ const focusTableIdIndex = focusPath.indexOf("skeTables") + 1;
6376
+ const focusRowIndex = focusPath.indexOf("rows") + 1;
6377
+ const focusCellIndex = focusPath.indexOf("cells") + 1;
6378
+ if (anchorTableIdIndex === 0 || anchorRowIndex === 0 || anchorCellIndex === 0 || focusTableIdIndex === 0 || focusRowIndex === 0 || focusCellIndex === 0) return false;
6379
+ return anchorPath[anchorTableIdIndex] === focusPath[focusTableIdIndex] && anchorPath[anchorRowIndex] === focusPath[focusRowIndex] && anchorPath[anchorCellIndex] === focusPath[focusCellIndex];
6321
6380
  }
6322
6381
  function isInSameTableCellData(skeleton, anchorNodePosition, focusNodePosition) {
6323
6382
  var _anchorGlyph$parent, _focusGlyph$parent;
@@ -6352,7 +6411,7 @@ function compareNodePositionInTable(a, b) {
6352
6411
  if (aRowCount > bRowCount) return false;
6353
6412
  return aCellCount <= bCellCount;
6354
6413
  }
6355
- function isEmptyCellPage$1(cell) {
6414
+ function isEmptyCellPage(cell) {
6356
6415
  return cell.sections[0].columns[0].lines.length === 0;
6357
6416
  }
6358
6417
  function findNonEmptyCellPages(cells, startCol, endCol) {
@@ -6360,14 +6419,14 @@ function findNonEmptyCellPages(cells, startCol, endCol) {
6360
6419
  let e = endCol;
6361
6420
  let startCell = cells[s];
6362
6421
  let endCell = cells[e];
6363
- while (s < e && (isEmptyCellPage$1(startCell) || isEmptyCellPage$1(endCell))) if (isEmptyCellPage$1(startCell)) {
6422
+ while (s < e && (isEmptyCellPage(startCell) || isEmptyCellPage(endCell))) if (isEmptyCellPage(startCell)) {
6364
6423
  s++;
6365
6424
  startCell = cells[s];
6366
- } else if (isEmptyCellPage$1(endCell)) {
6425
+ } else if (isEmptyCellPage(endCell)) {
6367
6426
  e--;
6368
6427
  endCell = cells[e];
6369
6428
  }
6370
- if (!isEmptyCellPage$1(startCell) && !isEmptyCellPage$1(endCell)) return [startCell, endCell];
6429
+ if (!isEmptyCellPage(startCell) && !isEmptyCellPage(endCell)) return [startCell, endCell];
6371
6430
  }
6372
6431
  function getColumnBoundary(table, column) {
6373
6432
  var _table$tableSource;
@@ -6415,6 +6474,7 @@ var NodePositionConvertToRectRange = class {
6415
6474
  _defineProperty(this, "_liquid", new Liquid());
6416
6475
  }
6417
6476
  getRangePointData(startNodePosition, endNodePosition) {
6477
+ var _this$_documentOffset, _this$_documentOffset2;
6418
6478
  const pointGroup = [];
6419
6479
  const docSkeleton = this._docSkeleton;
6420
6480
  const skeletonData = docSkeleton.getSkeletonData();
@@ -6428,6 +6488,12 @@ var NodePositionConvertToRectRange = class {
6428
6488
  const { pageLayoutType, pageMarginLeft, pageMarginTop } = this._documentOffsetConfig;
6429
6489
  const unitId = getDocumentUnitId(docSkeleton);
6430
6490
  const sourceTableId = getTableIdAndSliceIndex(tableId).tableId;
6491
+ const nestedTableContexts = documentSkeletonTableIterator(pages, {
6492
+ docsLeft: (_this$_documentOffset = this._documentOffsetConfig.docsLeft) !== null && _this$_documentOffset !== void 0 ? _this$_documentOffset : 0,
6493
+ docsTop: (_this$_documentOffset2 = this._documentOffsetConfig.docsTop) !== null && _this$_documentOffset2 !== void 0 ? _this$_documentOffset2 : 0,
6494
+ pageMarginTop,
6495
+ unitId
6496
+ });
6431
6497
  const skipPageIndex = pageType === DocumentSkeletonPageType.BODY || pageType === DocumentSkeletonPageType.CELL ? startPage : startSegmentPage;
6432
6498
  for (let p = 0; p < skipPageIndex; p++) {
6433
6499
  const page = pages[p];
@@ -6440,6 +6506,43 @@ var NodePositionConvertToRectRange = class {
6440
6506
  let table = null;
6441
6507
  for (const [id, tableSke] of skeTables.entries()) if (id.startsWith(tableId)) table = tableSke;
6442
6508
  if (table == null) {
6509
+ const nestedTableContext = nestedTableContexts.find((context) => context.pageIndex === p && context.source === "column" && context.tableId.startsWith(tableId));
6510
+ if (nestedTableContext) {
6511
+ const nestedTable = nestedTableContext.table;
6512
+ const viewport = getDocsTableRenderViewport(unitId, sourceTableId);
6513
+ const nestedX = nestedTableContext.tableRect.left - nestedTable.left;
6514
+ const nestedY = nestedTableContext.tableRect.top;
6515
+ if (intersectsMergedCell) {
6516
+ const rows = nestedTable.rows.filter((row) => row.index >= startRow && row.index <= endRow);
6517
+ const firstRow = rows[0];
6518
+ const lastRow = rows[rows.length - 1];
6519
+ const startX = getColumnBoundary(nestedTable, startColumn);
6520
+ const endX = getColumnBoundary(nestedTable, endColumn + 1);
6521
+ if (firstRow && lastRow && startX != null && endX != null) pushViewportClippedPoints(pointGroup, {
6522
+ startX: nestedX + nestedTable.left + startX,
6523
+ startY: nestedY + firstRow.top,
6524
+ endX: nestedX + nestedTable.left + endX,
6525
+ endY: nestedY + lastRow.top + lastRow.height
6526
+ }, viewport, nestedX + nestedTable.left);
6527
+ this._liquid.restorePagePadding(page);
6528
+ this._liquid.translatePage(page, pageLayoutType, pageMarginLeft, pageMarginTop);
6529
+ continue;
6530
+ }
6531
+ for (const row of nestedTable.rows) if (row.index >= startRow && row.index <= endRow) {
6532
+ const cells = findNonEmptyCellPages(row.cells, startColumn, endColumn);
6533
+ if (cells == null) continue;
6534
+ const [rowStartCell, rowEndCell] = cells;
6535
+ pushViewportClippedPoints(pointGroup, {
6536
+ startX: nestedX + rowStartCell.left + nestedTable.left,
6537
+ startY: nestedY + row.top,
6538
+ endX: nestedX + rowEndCell.left + rowEndCell.pageWidth + nestedTable.left,
6539
+ endY: nestedY + row.top + row.height
6540
+ }, viewport, nestedX + nestedTable.left);
6541
+ }
6542
+ this._liquid.restorePagePadding(page);
6543
+ this._liquid.translatePage(page, pageLayoutType, pageMarginLeft, pageMarginTop);
6544
+ continue;
6545
+ }
6443
6546
  this._liquid.restorePagePadding(page);
6444
6547
  this._liquid.translatePage(page, pageLayoutType, pageMarginLeft, pageMarginTop);
6445
6548
  continue;
@@ -6538,19 +6641,23 @@ var NodePositionConvertToRectRange = class {
6538
6641
  const { pages } = skeletonData;
6539
6642
  const { path: anchorPath } = anchorPosition;
6540
6643
  const { path: focusPath } = focusPosition;
6644
+ if (anchorPath.indexOf("cells") === -1 || focusPath.indexOf("cells") === -1) return;
6541
6645
  const anchorCell = getPageFromPath(skeletonData, anchorPath);
6542
6646
  const focusCell = getPageFromPath(skeletonData, focusPath);
6543
6647
  if (anchorCell == null || focusCell == null) return;
6648
+ const anchorRow = anchorCell.parent;
6649
+ const focusRow = focusCell.parent;
6650
+ if (!Array.isArray(anchorRow === null || anchorRow === void 0 ? void 0 : anchorRow.cells) || !Array.isArray(focusRow === null || focusRow === void 0 ? void 0 : focusRow.cells)) return;
6544
6651
  const tableId = anchorCell.segmentId;
6545
- const anchorRow = anchorCell.parent.index;
6546
- const anchorColumn = anchorCell.parent.cells.indexOf(anchorCell);
6547
- const focusRow = (focusCell === null || focusCell === void 0 ? void 0 : focusCell.parent).index;
6548
- const focusColumn = (focusCell === null || focusCell === void 0 ? void 0 : focusCell.parent).cells.indexOf(focusCell);
6652
+ const anchorRowIndex = anchorRow.index;
6653
+ const anchorColumn = anchorRow.cells.indexOf(anchorCell);
6654
+ const focusRowIndex = focusRow.index;
6655
+ const focusColumn = focusRow.cells.indexOf(focusCell);
6549
6656
  const sourceTableId = getTableIdAndSliceIndex(tableId).tableId;
6550
6657
  const tableSource = (_docSkeleton$getViewM = docSkeleton.getViewModel().getSnapshot().tableSource) === null || _docSkeleton$getViewM === void 0 ? void 0 : _docSkeleton$getViewM[sourceTableId];
6551
6658
  const rawRange = {
6552
- startRowIndex: Math.min(anchorRow, focusRow),
6553
- endRowIndex: Math.max(anchorRow, focusRow),
6659
+ startRowIndex: Math.min(anchorRowIndex, focusRowIndex),
6660
+ endRowIndex: Math.max(anchorRowIndex, focusRowIndex),
6554
6661
  startColumnIndex: Math.min(anchorColumn, focusColumn),
6555
6662
  endColumnIndex: Math.max(anchorColumn, focusColumn)
6556
6663
  };
@@ -7076,6 +7183,20 @@ var RectRange = class {
7076
7183
 
7077
7184
  //#endregion
7078
7185
  //#region src/services/selection/selection-utils.ts
7186
+ function isInSameColumnPage(anchorPosition, focusPosition) {
7187
+ const anchorColumnInfo = getDocumentSkeletonColumnPagePathInfo(anchorPosition);
7188
+ const focusColumnInfo = getDocumentSkeletonColumnPagePathInfo(focusPosition);
7189
+ return !!anchorColumnInfo && !!focusColumnInfo && anchorColumnInfo.pageIndex === focusColumnInfo.pageIndex && anchorColumnInfo.columnGroupId === focusColumnInfo.columnGroupId && anchorColumnInfo.columnIndex === focusColumnInfo.columnIndex;
7190
+ }
7191
+ function getColumnInputBoundaryCollapsedPosition(anchorPosition, focusPosition, skeleton) {
7192
+ const anchorColumnInfo = getDocumentSkeletonColumnPagePathInfo(anchorPosition);
7193
+ const focusColumnInfo = getDocumentSkeletonColumnPagePathInfo(focusPosition);
7194
+ if (!anchorColumnInfo || !focusColumnInfo || anchorColumnInfo.pageIndex !== focusColumnInfo.pageIndex || anchorColumnInfo.columnGroupId !== focusColumnInfo.columnGroupId || anchorColumnInfo.columnIndex + 1 !== focusColumnInfo.columnIndex) return;
7195
+ const anchorOffset = skeleton.findCharIndexByPosition(anchorPosition);
7196
+ const focusOffset = skeleton.findCharIndexByPosition(focusPosition);
7197
+ if (anchorOffset == null || focusOffset == null || anchorOffset <= focusOffset) return;
7198
+ return anchorPosition;
7199
+ }
7079
7200
  function getTextRangeFromCharIndex(startOffset, endOffset, scene, document, skeleton, style, segmentId, segmentPage, startIsBack = true, endIsBack = true) {
7080
7201
  const startNodePosition = skeleton.findNodePositionByCharIndex(startOffset, startIsBack, segmentId, segmentPage);
7081
7202
  const endNodePosition = skeleton.findNodePositionByCharIndex(endOffset, endIsBack, segmentId, segmentPage);
@@ -7107,6 +7228,21 @@ function getRangeListFromSelection(anchorPosition, focusPosition, scene, documen
7107
7228
  segmentId,
7108
7229
  segmentPage
7109
7230
  ];
7231
+ const collapsedColumnPosition = getColumnInputBoundaryCollapsedPosition(anchorPosition, focusPosition, skeleton);
7232
+ if (collapsedColumnPosition) {
7233
+ textRanges.push(new TextRange(scene, document, skeleton, collapsedColumnPosition, collapsedColumnPosition, style, segmentId, segmentPage));
7234
+ return {
7235
+ textRanges,
7236
+ rectRanges
7237
+ };
7238
+ }
7239
+ if (isInSameColumnPage(anchorPosition, focusPosition)) {
7240
+ textRanges.push(new TextRange(...rangeParams));
7241
+ return {
7242
+ textRanges,
7243
+ rectRanges
7244
+ };
7245
+ }
7110
7246
  if (isInSameTableCellData(skeleton, anchorPosition, focusPosition)) if (isInSameTableCell(anchorPosition, focusPosition)) {
7111
7247
  textRanges.push(new TextRange(...rangeParams));
7112
7248
  return {
@@ -8600,7 +8736,7 @@ const DocTableInsertColumnCommand = {
8600
8736
  id: DocTableInsertColumnCommandId,
8601
8737
  type: CommandType.COMMAND,
8602
8738
  handler: async (accessor, params) => {
8603
- var _documentStyle$pageSi, _documentStyle$pageSi2, _snapshot$tableSource;
8739
+ var _snapshot$tableSource, _documentStyle$pageSi, _documentStyle$pageSi2;
8604
8740
  const { position } = params;
8605
8741
  const docSelectionManagerService = accessor.get(DocSelectionManagerService);
8606
8742
  const univerInstanceService = accessor.get(IUniverInstanceService);
@@ -8665,10 +8801,11 @@ const DocTableInsertColumnCommand = {
8665
8801
  const snapshot = docDataModel.getSnapshot();
8666
8802
  const documentStyle = snapshot.documentStyle;
8667
8803
  const { marginLeft = 0, marginRight = 0 } = documentStyle;
8668
- const pageWidth = ((_documentStyle$pageSi = (_documentStyle$pageSi2 = documentStyle.pageSize) === null || _documentStyle$pageSi2 === void 0 ? void 0 : _documentStyle$pageSi2.width) !== null && _documentStyle$pageSi !== void 0 ? _documentStyle$pageSi : 800) - marginLeft - marginRight;
8669
8804
  const tableColumns = snapshot === null || snapshot === void 0 || (_snapshot$tableSource = snapshot.tableSource) === null || _snapshot$tableSource === void 0 || (_snapshot$tableSource = _snapshot$tableSource[tableId]) === null || _snapshot$tableSource === void 0 ? void 0 : _snapshot$tableSource.tableColumns;
8670
8805
  if (!tableColumns) return false;
8671
- const { newColWidth, widths } = getColumnWidths(pageWidth, tableColumns, columnIndex);
8806
+ const pageWidth = ((_documentStyle$pageSi = (_documentStyle$pageSi2 = documentStyle.pageSize) === null || _documentStyle$pageSi2 === void 0 ? void 0 : _documentStyle$pageSi2.width) !== null && _documentStyle$pageSi !== void 0 ? _documentStyle$pageSi : 800) - marginLeft - marginRight;
8807
+ const tableWidth = tableColumns.reduce((sum, column) => sum + column.size.width.v, 0);
8808
+ const { newColWidth, widths } = getColumnWidths(tableWidth > 0 ? tableWidth : pageWidth, tableColumns, columnIndex);
8672
8809
  for (let i = 0; i < widths.length; i++) {
8673
8810
  const action = jsonX.replaceOp([
8674
8811
  "tableSource",
@@ -10908,6 +11045,10 @@ function notInTableSubscriber(subscriber, docSelectionManagerService, univerInst
10908
11045
  if (activeRange && (rectRanges == null || rectRanges.length === 0)) {
10909
11046
  var _docDataModel$getSelf;
10910
11047
  const { segmentId, startOffset, endOffset } = activeRange;
11048
+ if (!(activeRange.collapsed === true || startOffset === endOffset)) {
11049
+ subscriber.next(true);
11050
+ return;
11051
+ }
10911
11052
  const docDataModel = univerInstanceService.getCurrentUniverDocInstance();
10912
11053
  const tables = docDataModel === null || docDataModel === void 0 || (_docDataModel$getSelf = docDataModel.getSelfOrHeaderFooterModel(segmentId).getBody()) === null || _docDataModel$getSelf === void 0 ? void 0 : _docDataModel$getSelf.tables;
10913
11054
  if (tables && tables.length) {
@@ -12658,7 +12799,6 @@ function ParagraphMenuInsertBelowHeadingH1MenuItemFactory(accessor) {
12658
12799
  tooltip: "docs-ui.toolbar.heading.leading1",
12659
12800
  params: {
12660
12801
  commandId: H1HeadingCommand.id,
12661
- paragraphMenuPlacement: "below",
12662
12802
  paragraphMenuInsertMode: "breakline"
12663
12803
  },
12664
12804
  hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC)
@@ -12674,7 +12814,6 @@ function ParagraphMenuInsertBelowHeadingH2MenuItemFactory(accessor) {
12674
12814
  tooltip: "docs-ui.toolbar.heading.leading2",
12675
12815
  params: {
12676
12816
  commandId: H2HeadingCommand.id,
12677
- paragraphMenuPlacement: "below",
12678
12817
  paragraphMenuInsertMode: "breakline"
12679
12818
  },
12680
12819
  hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC)
@@ -12690,7 +12829,6 @@ function ParagraphMenuInsertBelowHeadingH3MenuItemFactory(accessor) {
12690
12829
  tooltip: "docs-ui.toolbar.heading.leading3",
12691
12830
  params: {
12692
12831
  commandId: H3HeadingCommand.id,
12693
- paragraphMenuPlacement: "below",
12694
12832
  paragraphMenuInsertMode: "breakline"
12695
12833
  },
12696
12834
  hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC)
@@ -12706,7 +12844,6 @@ function ParagraphMenuInsertBelowHeadingH4MenuItemFactory(accessor) {
12706
12844
  tooltip: "docs-ui.toolbar.heading.leading4",
12707
12845
  params: {
12708
12846
  commandId: H4HeadingCommand.id,
12709
- paragraphMenuPlacement: "below",
12710
12847
  paragraphMenuInsertMode: "breakline"
12711
12848
  },
12712
12849
  hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC)
@@ -12722,7 +12859,6 @@ function ParagraphMenuInsertBelowHeadingH5MenuItemFactory(accessor) {
12722
12859
  tooltip: "docs-ui.toolbar.heading.leading5",
12723
12860
  params: {
12724
12861
  commandId: H5HeadingCommand.id,
12725
- paragraphMenuPlacement: "below",
12726
12862
  paragraphMenuInsertMode: "breakline"
12727
12863
  },
12728
12864
  hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC)
@@ -12738,8 +12874,7 @@ function ParagraphMenuInsertBelowTableMenuItemFactory(accessor) {
12738
12874
  tooltip: "docs-ui.toolbar.table.insert",
12739
12875
  params: {
12740
12876
  rowCount: 3,
12741
- colCount: 5,
12742
- paragraphMenuPlacement: "below"
12877
+ colCount: 5
12743
12878
  },
12744
12879
  hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC)
12745
12880
  };
@@ -14024,6 +14159,50 @@ const calcDocParagraphPositions = (sections, top, left, pageWidth) => {
14024
14159
  }
14025
14160
  return paragraphBounds;
14026
14161
  };
14162
+ const calcParagraphPositionsFromLineContexts = (contexts, docsLeft, docsTop) => {
14163
+ const paragraphBounds = [];
14164
+ const currentParagraphs = /* @__PURE__ */ new Map();
14165
+ for (const context of contexts) {
14166
+ const { column, line, lineWidth, pageLeft, sectionTop } = context;
14167
+ const startIndex = line.paragraphIndex;
14168
+ const columnLeft = pageLeft + column.left + docsLeft;
14169
+ const lineTop = sectionTop + line.top + docsTop;
14170
+ const lineBottom = getParagraphLineBottom(context, lineTop);
14171
+ const key = `${context.source}:${context.pageIndex}:${pageLeft}:${column.left}:${startIndex}`;
14172
+ if (line.paragraphStart) {
14173
+ const currentParagraph = currentParagraphs.get(key);
14174
+ if (currentParagraph) paragraphBounds.push(currentParagraph);
14175
+ currentParagraphs.set(key, {
14176
+ paragraphStart: line.st,
14177
+ paragraphEnd: startIndex,
14178
+ startIndex,
14179
+ rect: {
14180
+ top: lineTop,
14181
+ left: columnLeft,
14182
+ right: columnLeft + lineWidth,
14183
+ bottom: lineBottom
14184
+ },
14185
+ fisrtLine: {
14186
+ top: lineTop + line.marginTop + line.paddingTop,
14187
+ left: columnLeft,
14188
+ right: columnLeft + lineWidth,
14189
+ bottom: lineTop + line.marginTop + line.paddingTop + line.contentHeight
14190
+ }
14191
+ });
14192
+ } else {
14193
+ const currentParagraph = currentParagraphs.get(key);
14194
+ if (currentParagraph) currentParagraph.rect.bottom = lineBottom;
14195
+ }
14196
+ }
14197
+ paragraphBounds.push(...currentParagraphs.values());
14198
+ return paragraphBounds;
14199
+ };
14200
+ function getParagraphLineBottom(context, lineTop) {
14201
+ const lineBottom = lineTop + context.line.lineHeight;
14202
+ if (context.source !== "column" || context.line !== context.column.lines.at(-1) || !Number.isFinite(context.page.pageHeight)) return lineBottom;
14203
+ const pageTop = lineTop - context.line.top - context.section.top;
14204
+ return Math.max(lineBottom, pageTop + context.page.pageHeight);
14205
+ }
14027
14206
  const calcDocGlyphPosition = (glyph, documents, skeleton, pageIndex = -1) => {
14028
14207
  const start = skeleton.findPositionByGlyph(glyph, pageIndex);
14029
14208
  if (!start) return;
@@ -14075,6 +14254,21 @@ function isPointInRect(x, y, rect) {
14075
14254
  if (x >= left && x <= right && y >= top && y <= bottom) return true;
14076
14255
  return false;
14077
14256
  }
14257
+ function getRectArea(rect) {
14258
+ return Math.max(0, rect.right - rect.left) * Math.max(0, rect.bottom - rect.top);
14259
+ }
14260
+ function isRectContainingRect(outer, inner) {
14261
+ return outer.left <= inner.left && outer.right >= inner.right && outer.top <= inner.top && outer.bottom >= inner.bottom;
14262
+ }
14263
+ function getParagraphTextRangeLength(bound) {
14264
+ return Math.max(0, bound.paragraphEnd - bound.paragraphStart);
14265
+ }
14266
+ function getMostSpecificParagraphBound(bounds) {
14267
+ return bounds.sort((left, right) => getRectArea(left.rect) - getRectArea(right.rect) || getParagraphTextRangeLength(left) - getParagraphTextRangeLength(right))[0];
14268
+ }
14269
+ function removeContainerParagraphBounds(bounds) {
14270
+ return bounds.filter((bound) => !bounds.some((other) => other !== bound && getRectArea(other.rect) < getRectArea(bound.rect) && isRectContainingRect(bound.rect, other.rect)));
14271
+ }
14078
14272
  function getTableBlockMenuHoverRect(tableRect) {
14079
14273
  return {
14080
14274
  bottom: tableRect.bottom,
@@ -14184,7 +14378,10 @@ let DocEventManagerService = class DocEventManagerService extends Disposable {
14184
14378
  }));
14185
14379
  }
14186
14380
  _initEvents() {
14187
- this.disposeWithMe(fromEventSubject(this._context.scene.onPointerMove$).pipe(throttleTime(30)).subscribe((evt) => {
14381
+ this.disposeWithMe(fromEventSubject(this._context.scene.onPointerMove$).pipe(throttleTime(30, void 0, {
14382
+ leading: true,
14383
+ trailing: true
14384
+ })).subscribe((evt) => {
14188
14385
  if (evt.buttons > 0) {
14189
14386
  this._hoverBullet$.next(null);
14190
14387
  this._hoverCustomRanges$.next([]);
@@ -14378,9 +14575,9 @@ let DocEventManagerService = class DocEventManagerService extends Disposable {
14378
14575
  if (!skeletonData) return null;
14379
14576
  const calc = (pages) => {
14380
14577
  const paragraphMap = /* @__PURE__ */ new Map();
14381
- const handlePage = (page, pageIndex, top, left) => {
14382
- calcDocParagraphPositions(page.sections, top, left, page.pageWidth - page.marginLeft - page.marginRight).forEach((bound) => {
14383
- if (!paragraphMap.has(bound.startIndex)) paragraphMap.set(bound.startIndex, {
14578
+ const addParagraphBoundsToMap = (map, bounds, pageIndex, segmentId) => {
14579
+ bounds.forEach((bound) => {
14580
+ if (!map.has(bound.startIndex)) map.set(bound.startIndex, {
14384
14581
  rect: bound.rect,
14385
14582
  paragraphStart: bound.paragraphStart,
14386
14583
  paragraphEnd: bound.paragraphEnd,
@@ -14391,7 +14588,7 @@ let DocEventManagerService = class DocEventManagerService extends Disposable {
14391
14588
  firstLine: bound.fisrtLine
14392
14589
  });
14393
14590
  else {
14394
- const current = paragraphMap.get(bound.startIndex);
14591
+ const current = map.get(bound.startIndex);
14395
14592
  if (current) {
14396
14593
  current.rect.bottom = bound.rect.bottom;
14397
14594
  current.rects.push(bound.rect);
@@ -14399,76 +14596,73 @@ let DocEventManagerService = class DocEventManagerService extends Disposable {
14399
14596
  }
14400
14597
  });
14401
14598
  };
14402
- for (let i = 0; i < pages.length; i++) {
14403
- const page = pages[i];
14404
- const top = ((page.pageHeight === Infinity ? 0 : page.pageHeight) + documentOffsetConfig.pageMarginTop) * i + page.marginTop + documentOffsetConfig.docsTop;
14405
- const left = page.marginLeft + documentOffsetConfig.docsLeft;
14406
- if (page.skeTables) Array.from(page.skeTables.values()).forEach((table) => {
14407
- const tableLeft = table.left + left;
14408
- const tableTop = table.top + top;
14409
- const sourceTableId = getTableIdAndSliceIndex(table.tableId).tableId;
14410
- const tableViewport = getTableHorizontalViewportGeometry(tableLeft, table.width, getDocsTableRenderViewport(this._context.unitId, sourceTableId));
14411
- const tableRight = tableViewport.visibleRight;
14412
- const tableBottom = tableTop + table.height;
14413
- const tableId = table.tableId;
14414
- this._tableBounds.set(tableId, {
14415
- rect: {
14416
- left: tableLeft,
14417
- top: tableTop,
14418
- right: tableRight,
14419
- bottom: tableBottom
14420
- },
14421
- pageIndex: i,
14599
+ const lineContextsBySource = /* @__PURE__ */ new Map();
14600
+ documentSkeletonLineIterator(pages, {
14601
+ docsLeft: documentOffsetConfig.docsLeft,
14602
+ pageMarginTop: documentOffsetConfig.pageMarginTop,
14603
+ unitId: this._context.unitId
14604
+ }, (context) => {
14605
+ var _lineContextsBySource;
14606
+ if (context.source === "table-cell") return;
14607
+ const lineContexts = (_lineContextsBySource = lineContextsBySource.get(context.pageIndex)) !== null && _lineContextsBySource !== void 0 ? _lineContextsBySource : [];
14608
+ lineContexts.push(context);
14609
+ lineContextsBySource.set(context.pageIndex, lineContexts);
14610
+ });
14611
+ lineContextsBySource.forEach((contexts, pageIndex) => {
14612
+ addParagraphBoundsToMap(paragraphMap, calcParagraphPositionsFromLineContexts(contexts, documentOffsetConfig.docsLeft, documentOffsetConfig.docsTop), pageIndex, segmentId);
14613
+ });
14614
+ for (const tableContext of documentSkeletonTableIterator(pages, {
14615
+ docsLeft: documentOffsetConfig.docsLeft,
14616
+ docsTop: documentOffsetConfig.docsTop,
14617
+ pageMarginTop: documentOffsetConfig.pageMarginTop,
14618
+ unitId: this._context.unitId
14619
+ })) {
14620
+ const tableId = tableContext.tableId;
14621
+ const sourceTableId = getTableIdAndSliceIndex(tableId).tableId;
14622
+ const tableViewport = getTableHorizontalViewportGeometry(tableContext.tableRect.left, tableContext.table.width, getDocsTableRenderViewport(this._context.unitId, sourceTableId));
14623
+ this._tableBounds.set(tableId, {
14624
+ rect: {
14625
+ ...tableContext.tableRect,
14626
+ right: tableViewport.visibleRight
14627
+ },
14628
+ pageIndex: tableContext.pageIndex,
14629
+ tableId
14630
+ });
14631
+ for (const cellGeometry of tableContext.cells) {
14632
+ var _cell$pageWidth, _cell$marginLeft, _cell$marginRight;
14633
+ const cell = cellGeometry.cell;
14634
+ const cellContentWidth = ((_cell$pageWidth = cell.pageWidth) !== null && _cell$pageWidth !== void 0 ? _cell$pageWidth : 0) - ((_cell$marginLeft = cell.marginLeft) !== null && _cell$marginLeft !== void 0 ? _cell$marginLeft : 0) - ((_cell$marginRight = cell.marginRight) !== null && _cell$marginRight !== void 0 ? _cell$marginRight : 0);
14635
+ const bounds = calcDocParagraphPositions(cell.sections, cellGeometry.pageTop, cellGeometry.pageLeft, cellContentWidth).map((bound) => clipParagraphBoundHorizontally(bound, cellGeometry.clipLeft, cellGeometry.clipRight)).filter((bound) => bound != null);
14636
+ let arr = this._tableParagraphBounds.get(tableId);
14637
+ if (!arr) {
14638
+ arr = [];
14639
+ this._tableParagraphBounds.set(tableId, arr);
14640
+ }
14641
+ arr.push(...bounds.map((bound) => ({
14642
+ rect: bound.rect,
14643
+ paragraphStart: bound.paragraphStart,
14644
+ paragraphEnd: bound.paragraphEnd,
14645
+ startIndex: bound.startIndex,
14646
+ pageIndex: tableContext.pageIndex,
14647
+ segmentId,
14648
+ rowIndex: cellGeometry.rowIndex,
14649
+ colIndex: cellGeometry.columnIndex,
14650
+ firstLine: bound.fisrtLine,
14651
+ tableId
14652
+ })));
14653
+ let cellBounds = this._tableCellBounds.get(tableId);
14654
+ if (!cellBounds) {
14655
+ cellBounds = [];
14656
+ this._tableCellBounds.set(tableId, cellBounds);
14657
+ }
14658
+ cellBounds.push({
14659
+ rect: cellGeometry.cellRect,
14660
+ pageIndex: tableContext.pageIndex,
14661
+ rowIndex: cellGeometry.rowIndex,
14662
+ colIndex: cellGeometry.columnIndex,
14422
14663
  tableId
14423
14664
  });
14424
- table.rows.forEach((row, rowIndex) => {
14425
- row.cells.forEach((cell, colIndex) => {
14426
- const top = ((page.pageHeight === Infinity ? 0 : page.pageHeight) + documentOffsetConfig.pageMarginTop) * i + table.top + documentOffsetConfig.docsTop + page.marginTop + row.top + cell.marginTop;
14427
- const cellLeft = tableLeft + cell.left - tableViewport.scrollLeft + cell.marginLeft;
14428
- const cellContentWidth = cell.pageWidth - cell.marginLeft - cell.marginRight;
14429
- const cellRight = cellLeft + cellContentWidth;
14430
- const visibleCellLeft = Math.max(cellLeft, tableViewport.visibleLeft);
14431
- const visibleCellRight = Math.min(cellRight, tableViewport.visibleRight);
14432
- if (visibleCellRight <= visibleCellLeft) return;
14433
- const bounds = calcDocParagraphPositions(cell.sections, top, cellLeft, cellContentWidth).map((bound) => clipParagraphBoundHorizontally(bound, tableViewport.visibleLeft, tableViewport.visibleRight)).filter((bound) => bound != null);
14434
- let arr = this._tableParagraphBounds.get(tableId);
14435
- if (!arr) {
14436
- arr = [];
14437
- this._tableParagraphBounds.set(tableId, arr);
14438
- }
14439
- arr.push(...bounds.map((bound) => ({
14440
- rect: bound.rect,
14441
- paragraphStart: bound.paragraphStart,
14442
- paragraphEnd: bound.paragraphEnd,
14443
- startIndex: bound.startIndex,
14444
- pageIndex: i,
14445
- segmentId,
14446
- rowIndex,
14447
- colIndex,
14448
- firstLine: bound.fisrtLine,
14449
- tableId
14450
- })));
14451
- let cellBounds = this._tableCellBounds.get(tableId);
14452
- if (!cellBounds) {
14453
- cellBounds = [];
14454
- this._tableCellBounds.set(tableId, cellBounds);
14455
- }
14456
- cellBounds.push({
14457
- rect: {
14458
- top,
14459
- left: visibleCellLeft,
14460
- right: visibleCellRight,
14461
- bottom: top + cell.pageHeight - cell.marginBottom - cell.marginTop
14462
- },
14463
- pageIndex: i,
14464
- rowIndex,
14465
- colIndex,
14466
- tableId
14467
- });
14468
- });
14469
- });
14470
- });
14471
- handlePage(page, i, top, left);
14665
+ }
14472
14666
  }
14473
14667
  return paragraphMap;
14474
14668
  };
@@ -14525,20 +14719,12 @@ let DocEventManagerService = class DocEventManagerService extends Disposable {
14525
14719
  rects: [paragraph.rect]
14526
14720
  };
14527
14721
  }
14528
- let paragraph;
14529
- for (const bounds of this._paragraphBounds) {
14530
- const bound = bounds[1];
14531
- if (bound.rects.some((rect) => isPointInRect(x, y, rect))) {
14532
- paragraph = bound;
14533
- break;
14534
- }
14535
- }
14536
- return paragraph;
14722
+ return getMostSpecificParagraphBound([...this._paragraphBounds.values()].filter((bound) => bound.rects.some((rect) => isPointInRect(x, y, rect))));
14537
14723
  }
14538
14724
  _calcActiveParagraphLeft(evt) {
14539
14725
  this._buildParagraphBounds();
14540
14726
  const { x, y } = evt;
14541
- return this._paragraphLeftBounds.find((bound) => isPointInRect(x, y, bound.rect));
14727
+ return getMostSpecificParagraphBound(this._paragraphLeftBounds.filter((bound) => isPointInRect(x, y, bound.rect)));
14542
14728
  }
14543
14729
  get paragraphBounds() {
14544
14730
  this._buildParagraphBounds();
@@ -14577,18 +14763,19 @@ let DocEventManagerService = class DocEventManagerService extends Disposable {
14577
14763
  var _this$_skeleton$getSk4, _this$_skeleton$getSk5;
14578
14764
  const pages = (_this$_skeleton$getSk4 = (_this$_skeleton$getSk5 = this._skeleton.getSkeletonData()) === null || _this$_skeleton$getSk5 === void 0 ? void 0 : _this$_skeleton$getSk5.pages) !== null && _this$_skeleton$getSk4 !== void 0 ? _this$_skeleton$getSk4 : [];
14579
14765
  const signatures = [];
14580
- pages.forEach((page) => {
14581
- var _page$skeTables;
14582
- (_page$skeTables = page.skeTables) === null || _page$skeTables === void 0 || _page$skeTables.forEach((table) => {
14583
- const tableId = getTableIdAndSliceIndex(table.tableId).tableId;
14584
- const viewport = getDocsTableRenderViewport(this._context.unitId, tableId);
14585
- if (!viewport) {
14586
- signatures.push(`${tableId}:none`);
14587
- return;
14588
- }
14589
- signatures.push(`${tableId}:${viewport.contentWidth}:${viewport.viewportWidth}:${viewport.scrollLeft}`);
14590
- });
14591
- });
14766
+ for (const tableContext of documentSkeletonTableIterator(pages, {
14767
+ pageMarginTop: this._documents.getOffsetConfig().pageMarginTop,
14768
+ resolveViewport: false,
14769
+ unitId: this._context.unitId
14770
+ })) {
14771
+ const tableId = getTableIdAndSliceIndex(tableContext.tableId).tableId;
14772
+ const viewport = getDocsTableRenderViewport(this._context.unitId, tableId);
14773
+ if (!viewport) {
14774
+ signatures.push(`${tableId}:none`);
14775
+ continue;
14776
+ }
14777
+ signatures.push(`${tableId}:${viewport.contentWidth}:${viewport.viewportWidth}:${viewport.scrollLeft}`);
14778
+ }
14592
14779
  return signatures.join("|");
14593
14780
  }
14594
14781
  };
@@ -14596,7 +14783,7 @@ DocEventManagerService = __decorate([__decorateParam(1, Inject(DocSkeletonManage
14596
14783
  function getPreferredParagraphBoundsInRange(bodyBounds, tableBounds, startIndex, endIndex) {
14597
14784
  const matchedTableBounds = tableBounds.filter((bound) => isRangeOverlappingParagraph(bound, startIndex, endIndex));
14598
14785
  if (matchedTableBounds.length) return matchedTableBounds;
14599
- return bodyBounds.filter((bound) => isRangeOverlappingParagraph(bound, startIndex, endIndex));
14786
+ return removeContainerParagraphBounds(bodyBounds.filter((bound) => isRangeOverlappingParagraph(bound, startIndex, endIndex)));
14600
14787
  }
14601
14788
  function isRangeOverlappingParagraph(bound, startIndex, endIndex) {
14602
14789
  return Math.max(bound.paragraphStart, startIndex) <= Math.min(bound.paragraphEnd, endIndex);
@@ -14660,7 +14847,7 @@ const SideMenu = forwardRef((props, ref) => {
14660
14847
  onClick: () => onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(!open),
14661
14848
  className: clsx("univer-absolute univer-left-5 univer-top-4 univer-z-[100] univer-flex univer-size-8 univer-cursor-pointer univer-items-center univer-justify-center univer-rounded-full univer-bg-white univer-text-gray-800 univer-shadow-sm dark:!univer-bg-gray-600 dark:!univer-text-gray-200", iconClass),
14662
14849
  style: iconStyle,
14663
- children: open ? /* @__PURE__ */ jsx(LeftIcon, {}) : /* @__PURE__ */ jsx(CatalogueIcon, {})
14850
+ children: open ? /* @__PURE__ */ jsx(MoreLeftIcon, {}) : /* @__PURE__ */ jsx(CatalogueIcon, {})
14664
14851
  }), /* @__PURE__ */ jsx("div", {
14665
14852
  className: clsx(className, "univer-absolute univer-left-0 univer-top-0 univer-box-border univer-flex univer-min-w-[180px] univer-flex-col univer-px-4 univer-pb-4 univer-pt-14 univer-transition-all univer-duration-300", { "univer-rounded-r-2xl univer-bg-white univer-shadow univer-backdrop-blur-[10px] dark:!univer-bg-gray-900": isSideBar }),
14666
14853
  style: {
@@ -14933,7 +15120,7 @@ DocUIController = __decorate([
14933
15120
  //#endregion
14934
15121
  //#region package.json
14935
15122
  var name = "@univerjs/docs-ui";
14936
- var version = "1.0.0-alpha.0";
15123
+ var version = "1.0.0-alpha.1";
14937
15124
 
14938
15125
  //#endregion
14939
15126
  //#region src/commands/commands/doc-paragraph-setting.command.ts
@@ -16081,6 +16268,10 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16081
16268
  var _this$_docEventManage;
16082
16269
  const handleHoverTarget = (paragraph, tableBound) => {
16083
16270
  if (this._isBlockMenuDragging) return;
16271
+ if (this._docSelectionRenderService.isOnPointerEvent) {
16272
+ this.hideParagraphMenu(true);
16273
+ return;
16274
+ }
16084
16275
  const selectionState = this._getExpandedSelectionState(this._docSelectionManagerService.getDocRanges());
16085
16276
  if (selectionState.hasExpandedTextRange) {
16086
16277
  this.hideParagraphMenu(true);
@@ -16092,7 +16283,7 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16092
16283
  this.showTableMenu(tableBound);
16093
16284
  return;
16094
16285
  }
16095
- if (((_this$_paragrahMenu3 = this._paragrahMenu) === null || _this$_paragrahMenu3 === void 0 ? void 0 : _this$_paragrahMenu3.target.kind) === "table") return;
16286
+ if (((_this$_paragrahMenu3 = this._paragrahMenu) === null || _this$_paragrahMenu3 === void 0 ? void 0 : _this$_paragrahMenu3.target.kind) === DocumentBlockType.TABLE) return;
16096
16287
  this.hideParagraphMenu(true);
16097
16288
  return;
16098
16289
  }
@@ -16114,13 +16305,19 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16114
16305
  this._docEventManagerService.hoverParagraphRealTime$,
16115
16306
  this._docEventManagerService.hoverParagraphLeft$,
16116
16307
  (_this$_docEventManage = this._docEventManagerService.hoverTableRealTime$) !== null && _this$_docEventManage !== void 0 ? _this$_docEventManage : new BehaviorSubject(null)
16117
- ]).pipe(throttleTime(16)).subscribe(([p, left, table]) => {
16308
+ ]).pipe(throttleTime(16, void 0, {
16309
+ leading: true,
16310
+ trailing: true
16311
+ })).subscribe(([p, left, table]) => {
16118
16312
  handleHoverTarget(p !== null && p !== void 0 ? p : left, table);
16119
16313
  }));
16314
+ this.disposeWithMe(this._docSelectionRenderService.onSelectionStart$.subscribe(() => {
16315
+ this.hideParagraphMenu(true);
16316
+ }));
16120
16317
  this.disposeWithMe(this._docSelectionManagerService.textSelection$.subscribe(({ textRanges, rectRanges }) => {
16121
16318
  var _this$_paragrahMenu5;
16122
16319
  const selectionState = this._getExpandedSelectionState([...textRanges, ...rectRanges]);
16123
- if (selectionState.hasExpandedTextRange || selectionState.hasRectRange && ((_this$_paragrahMenu5 = this._paragrahMenu) === null || _this$_paragrahMenu5 === void 0 ? void 0 : _this$_paragrahMenu5.target.kind) !== "table") this.hideParagraphMenu(true);
16320
+ if (selectionState.hasExpandedTextRange || selectionState.hasRectRange && ((_this$_paragrahMenu5 = this._paragrahMenu) === null || _this$_paragrahMenu5 === void 0 ? void 0 : _this$_paragrahMenu5.target.kind) !== DocumentBlockType.TABLE) this.hideParagraphMenu(true);
16124
16321
  }));
16125
16322
  let lastScrollY = 0;
16126
16323
  this.disposeWithMe(this._context.scene.getViewport("viewMain").onScrollAfter$.subscribeEvent((e) => {
@@ -16269,8 +16466,8 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16269
16466
  const table = body === null || body === void 0 || (_body$tables = body.tables) === null || _body$tables === void 0 ? void 0 : _body$tables.find((item) => item.tableId === tableBound.tableId);
16270
16467
  if (!table) return;
16271
16468
  const target = {
16272
- kind: "table",
16273
- key: `table:${table.tableId}`,
16469
+ kind: DocumentBlockType.TABLE,
16470
+ key: `${DocumentBlockType.TABLE}:${table.tableId}`,
16274
16471
  table,
16275
16472
  icon: "GridIcon",
16276
16473
  menuRange: {
@@ -16321,7 +16518,7 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16321
16518
  _shouldKeepCurrentCellMenuForTable(table) {
16322
16519
  var _this$_paragrahMenu10;
16323
16520
  const target = (_this$_paragrahMenu10 = this._paragrahMenu) === null || _this$_paragrahMenu10 === void 0 ? void 0 : _this$_paragrahMenu10.target;
16324
- if (!target || target.kind === "table" || !target.cellRange) return false;
16521
+ if (!target || target.kind === DocumentBlockType.TABLE || !target.cellRange) return false;
16325
16522
  return target.cellRange.startOffset >= table.startIndex && target.cellRange.startOffset <= table.endIndex;
16326
16523
  }
16327
16524
  getDropTargetFromClientPoint(clientX, clientY, sourceRange) {
@@ -16385,8 +16582,8 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16385
16582
  blockRange
16386
16583
  };
16387
16584
  return {
16388
- kind: "blockRange",
16389
- key: `blockRange:${blockRange.blockId}`,
16585
+ kind: DocumentBlockType.BLOCK_RANGE,
16586
+ key: `${DocumentBlockType.BLOCK_RANGE}:${blockRange.blockId}`,
16390
16587
  paragraph: targetParagraph,
16391
16588
  blockRange,
16392
16589
  icon: BLOCK_RANGE_ICON_MAP[blockRange.blockType],
@@ -16411,8 +16608,8 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16411
16608
  const customBlock = body === null || body === void 0 || (_body$customBlocks = body.customBlocks) === null || _body$customBlocks === void 0 ? void 0 : _body$customBlocks.find((item) => item.startIndex >= paragraph.paragraphStart && item.startIndex <= paragraph.paragraphEnd);
16412
16609
  const isCustomBlockOnly = (customBlock === null || customBlock === void 0 ? void 0 : customBlock.blockType) === BlockType.CUSTOM && paragraphDataStream.replace(/[\b\r\n]/g, "") === "";
16413
16610
  if (customBlock && customBlock.blockType === BlockType.CUSTOM && isCustomBlockOnly) return {
16414
- kind: "customBlock",
16415
- key: `customBlock:${customBlock.blockId}`,
16611
+ kind: DocumentBlockType.CUSTOM_BLOCK,
16612
+ key: `${DocumentBlockType.CUSTOM_BLOCK}:${customBlock.blockId}`,
16416
16613
  paragraph,
16417
16614
  customBlock,
16418
16615
  icon: "TextTypeIcon",
@@ -16428,8 +16625,8 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16428
16625
  };
16429
16626
  if (paragraphDataStream === "\b") return null;
16430
16627
  return {
16431
- kind: "paragraph",
16432
- key: `paragraph:${paragraph.startIndex}`,
16628
+ kind: DocumentBlockType.PARAGRAPH,
16629
+ key: `${DocumentBlockType.PARAGRAPH}:${paragraph.startIndex}`,
16433
16630
  paragraph,
16434
16631
  icon: isHorizontalRuleParagraph ? "ReduceIcon" : listIcon,
16435
16632
  cellRange: cellRange !== null && cellRange !== void 0 ? cellRange : void 0,
@@ -16455,8 +16652,8 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16455
16652
  const tableBound = this._docEventManagerService.tableBounds.get(table.tableId);
16456
16653
  if (!tableBound) continue;
16457
16654
  targets.push({
16458
- kind: "table",
16459
- key: `table:${table.tableId}`,
16655
+ kind: DocumentBlockType.TABLE,
16656
+ key: `${DocumentBlockType.TABLE}:${table.tableId}`,
16460
16657
  table,
16461
16658
  icon: "GridIcon",
16462
16659
  menuRange: {
@@ -16477,8 +16674,8 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16477
16674
  const rect = unionRects(paragraphBounds.filter((bound) => Math.max(bound.paragraphStart, blockRange.startIndex) <= Math.min(bound.paragraphEnd, blockRange.endIndex)).map((bound) => bound.rect));
16478
16675
  if (!rect) continue;
16479
16676
  targets.push({
16480
- kind: "blockRange",
16481
- key: `blockRange:${blockRange.blockId}`,
16677
+ kind: DocumentBlockType.BLOCK_RANGE,
16678
+ key: `${DocumentBlockType.BLOCK_RANGE}:${blockRange.blockId}`,
16482
16679
  blockRange,
16483
16680
  icon: BLOCK_RANGE_ICON_MAP[blockRange.blockType],
16484
16681
  menuRange: {
@@ -16519,8 +16716,8 @@ let DocParagraphMenuService = class DocParagraphMenuService extends Disposable {
16519
16716
  const rect = unionRects(paragraphBounds.filter((bound) => Math.max(bound.paragraphStart, blockRange.startIndex) <= Math.min(bound.paragraphEnd, blockRange.endIndex)).map((bound) => bound.rect));
16520
16717
  if (!rect) continue;
16521
16718
  targets.push({
16522
- kind: "blockRange",
16523
- key: `blockRange:${blockRange.blockId}`,
16719
+ kind: DocumentBlockType.BLOCK_RANGE,
16720
+ key: `${DocumentBlockType.BLOCK_RANGE}:${blockRange.blockId}`,
16524
16721
  blockRange,
16525
16722
  icon: BLOCK_RANGE_ICON_MAP[blockRange.blockType],
16526
16723
  cellRange,
@@ -16655,6 +16852,9 @@ const PARAGRAPH_MENU_HOVER_BRIDGE_VERTICAL_PADDING = 8;
16655
16852
  function getParagraphMenuTriggerClassName(visible) {
16656
16853
  return clsx("univer-mr-1 univer-inline-flex univer-h-7 univer-cursor-pointer univer-items-center univer-gap-1 univer-rounded-md univer-border univer-border-gray-200 univer-bg-white univer-px-2 univer-py-0 univer-shadow-sm univer-transition-colors hover:univer-bg-gray-50 hover:univer-shadow-md dark:!univer-border-gray-700 dark:!univer-bg-gray-900 dark:hover:!univer-bg-gray-800", { "univer-bg-gray-100 univer-shadow-md dark:!univer-bg-gray-800": visible });
16657
16854
  }
16855
+ function shouldExecuteParagraphMenuMove(validatorService, context) {
16856
+ return validatorService.canMoveBlock(context);
16857
+ }
16658
16858
  function getParagraphMenuTriggerIconKey(namedStyleType) {
16659
16859
  switch (namedStyleType) {
16660
16860
  case NamedStyleType.HEADING_1: return "H1Icon";
@@ -16935,13 +17135,13 @@ function deleteBodyText(body, startOffset, endOffset) {
16935
17135
  }
16936
17136
  function stripBlockParagraphStyle(style, blockType) {
16937
17137
  const nextStyle = { ...style };
16938
- if (blockType === "quote") {
17138
+ if (blockType === DocumentBlockRangeType.QUOTE) {
16939
17139
  delete nextStyle.indentStart;
16940
17140
  delete nextStyle.spaceAbove;
16941
17141
  delete nextStyle.spaceBelow;
16942
17142
  return nextStyle;
16943
17143
  }
16944
- if (blockType === "code") {
17144
+ if (blockType === DocumentBlockRangeType.CODE) {
16945
17145
  var _nextStyle$textStyle, _nextStyle$textStyle2;
16946
17146
  delete nextStyle.indentStart;
16947
17147
  delete nextStyle.indentEnd;
@@ -16950,7 +17150,7 @@ function stripBlockParagraphStyle(style, blockType) {
16950
17150
  if (((_nextStyle$textStyle = nextStyle.textStyle) === null || _nextStyle$textStyle === void 0 ? void 0 : _nextStyle$textStyle.ff) === "monospace" && ((_nextStyle$textStyle2 = nextStyle.textStyle) === null || _nextStyle$textStyle2 === void 0 ? void 0 : _nextStyle$textStyle2.fs) === 12) delete nextStyle.textStyle;
16951
17151
  return nextStyle;
16952
17152
  }
16953
- if (blockType === "callout") {
17153
+ if (blockType === DocumentBlockRangeType.CALLOUT) {
16954
17154
  delete nextStyle.indentStart;
16955
17155
  delete nextStyle.indentEnd;
16956
17156
  delete nextStyle.spaceAbove;
@@ -17046,6 +17246,7 @@ function ParagraphMenuBase({ popup, tableBlockOnly = false }) {
17046
17246
  const docSelectionManagerService = useDependency(DocSelectionManagerService);
17047
17247
  const docClipboardService = useDependency(IDocClipboardService);
17048
17248
  const docContentInsertService = useDependency(DocContentInsertService);
17249
+ const docBlockMoveValidatorService = useDependency(DocBlockMoveValidatorService);
17049
17250
  const clipboardInterfaceService = useDependency(IClipboardInterfaceService);
17050
17251
  const layoutService = useDependency(ILayoutService);
17051
17252
  const iconManager = useDependency(IconManager);
@@ -17324,6 +17525,7 @@ function ParagraphMenuBase({ popup, tableBlockOnly = false }) {
17324
17525
  },
17325
17526
  onMouseLeave: () => {
17326
17527
  isMouseOver.current = false;
17528
+ setParagraphMenuInteractionActive(docParagraphMenuService, false);
17327
17529
  cancelOpenMenu();
17328
17530
  scheduleHideMenu();
17329
17531
  },
@@ -17376,7 +17578,11 @@ function ParagraphMenuBase({ popup, tableBlockOnly = false }) {
17376
17578
  isDraggingRef.current = false;
17377
17579
  docParagraphMenuService === null || docParagraphMenuService === void 0 || docParagraphMenuService.setBlockMenuDragging(false);
17378
17580
  setDropRect(null);
17379
- if (shouldDrop && range && targetOffset != null) commandService.executeCommand(MoveDocBlockCommand.id, {
17581
+ if (shouldDrop && range && targetOffset != null && shouldExecuteParagraphMenuMove(docBlockMoveValidatorService, {
17582
+ unitId: popup.unitId,
17583
+ sourceRange: range,
17584
+ targetOffset
17585
+ })) commandService.executeCommand(MoveDocBlockCommand.id, {
17380
17586
  unitId: popup.unitId,
17381
17587
  sourceRange: range,
17382
17588
  targetOffset
@@ -17415,6 +17621,7 @@ function ParagraphMenuBase({ popup, tableBlockOnly = false }) {
17415
17621
  },
17416
17622
  onMouseLeave: () => {
17417
17623
  isMouseOver.current = false;
17624
+ setParagraphMenuInteractionActive(docParagraphMenuService, false);
17418
17625
  scheduleHideMenu();
17419
17626
  }
17420
17627
  }),
@@ -17432,6 +17639,7 @@ function ParagraphMenuBase({ popup, tableBlockOnly = false }) {
17432
17639
  },
17433
17640
  onMouseLeave: () => {
17434
17641
  isMouseOver.current = false;
17642
+ setParagraphMenuInteractionActive(docParagraphMenuService, false);
17435
17643
  scheduleHideMenu();
17436
17644
  },
17437
17645
  children: /* @__PURE__ */ jsx(ContextMenuPanel, {
@@ -17449,6 +17657,7 @@ function ParagraphMenuBase({ popup, tableBlockOnly = false }) {
17449
17657
  },
17450
17658
  onMenuPointerLeave: () => {
17451
17659
  isMouseOver.current = false;
17660
+ setParagraphMenuInteractionActive(docParagraphMenuService, false);
17452
17661
  scheduleHideMenu();
17453
17662
  },
17454
17663
  onCancel: () => {
@@ -17512,8 +17721,7 @@ const TableBlockMenu = ({ popup }) => /* @__PURE__ */ jsx(ParagraphMenuBase, {
17512
17721
  });
17513
17722
  function shouldUseInsertBelowRange(commandId, params) {
17514
17723
  if (params.id === "doc.menu.insert-bellow") return true;
17515
- const rawParams = typeof params.params === "function" ? params.params() : params.params;
17516
- if (rawParams && typeof rawParams === "object" && "paragraphMenuPlacement" in rawParams && rawParams.paragraphMenuPlacement === "below") return true;
17724
+ if (typeof params.id === "string" && params.id.toLowerCase().includes("below")) return true;
17517
17725
  const normalized = commandId.toLowerCase();
17518
17726
  if (normalized.includes("insert") && (normalized.includes("below") || normalized.includes("bellow"))) return true;
17519
17727
  if (normalized.includes("insert") && normalized.includes("image")) return true;
@@ -17697,6 +17905,12 @@ ComponentsController = __decorate([__decorateParam(0, Inject(ComponentManager)),
17697
17905
 
17698
17906
  //#endregion
17699
17907
  //#region src/controllers/doc-auto-format.controller.ts
17908
+ function hasQuickListType(text) {
17909
+ return Object.prototype.hasOwnProperty.call(QuickListTypeMap, text);
17910
+ }
17911
+ function hasQuickHeading(text) {
17912
+ return Object.prototype.hasOwnProperty.call(QUICK_HEADING_MAP, text);
17913
+ }
17700
17914
  let DocAutoFormatController = class DocAutoFormatController extends Disposable {
17701
17915
  constructor(_docAutoFormatService, _renderManagerService) {
17702
17916
  super();
@@ -17765,14 +17979,14 @@ let DocAutoFormatController = class DocAutoFormatController extends Disposable {
17765
17979
  if (paragraphs.length !== 1) return false;
17766
17980
  if (!selection.collapsed) return false;
17767
17981
  const text = (_unit$getBody2 = unit.getBody()) === null || _unit$getBody2 === void 0 ? void 0 : _unit$getBody2.dataStream.slice(paragraphs[0].paragraphStart, selection.startOffset - 1);
17768
- if (text && (Object.keys(QuickListTypeMap).includes(text) || Object.keys(QUICK_HEADING_MAP).includes(text))) return true;
17982
+ if (text && (hasQuickListType(text) || hasQuickHeading(text))) return true;
17769
17983
  return false;
17770
17984
  },
17771
17985
  getMutations(context) {
17772
17986
  var _unit$getBody3;
17773
17987
  const { paragraphs, unit, selection } = context;
17774
17988
  const text = (_unit$getBody3 = unit.getBody()) === null || _unit$getBody3 === void 0 ? void 0 : _unit$getBody3.dataStream.slice(paragraphs[0].paragraphStart, selection.startOffset - 1);
17775
- if (text && Object.keys(QuickListTypeMap).includes(text)) {
17989
+ if (text && hasQuickListType(text)) {
17776
17990
  const type = QuickListTypeMap[text];
17777
17991
  return [{
17778
17992
  id: QuickListCommand.id,
@@ -17782,7 +17996,7 @@ let DocAutoFormatController = class DocAutoFormatController extends Disposable {
17782
17996
  }
17783
17997
  }];
17784
17998
  }
17785
- if (text && Object.keys(QUICK_HEADING_MAP).includes(text)) {
17999
+ if (text && hasQuickHeading(text)) {
17786
18000
  const type = QUICK_HEADING_MAP[text];
17787
18001
  return [{
17788
18002
  id: QuickHeadingCommand.id,
@@ -17832,14 +18046,6 @@ DocAutoFormatController = __decorate([__decorateParam(0, Inject(DocAutoFormatSer
17832
18046
 
17833
18047
  //#endregion
17834
18048
  //#region src/basics/table.ts
17835
- function firstLineInTable(table) {
17836
- return table.rows[0].cells[0].sections[0].columns[0].lines[0];
17837
- }
17838
- function lastLineInTable(table) {
17839
- const lastRow = table.rows[table.rows.length - 1];
17840
- const lastCell = lastRow.cells[lastRow.cells.length - 1];
17841
- return getLastLine(lastCell);
17842
- }
17843
18049
  function findTableAfterLine(line, page) {
17844
18050
  const { ed } = line;
17845
18051
  const { skeTables } = page;
@@ -17850,86 +18056,6 @@ function findTableAfterLine(line, page) {
17850
18056
  }
17851
18057
  return table;
17852
18058
  }
17853
- function findLineBeforeAndAfterTable(table) {
17854
- const tablePage = table === null || table === void 0 ? void 0 : table.parent;
17855
- let lineBeforeTable = null;
17856
- let lineAfterTable = null;
17857
- if (table == null || tablePage == null) return {
17858
- lineBeforeTable,
17859
- lineAfterTable
17860
- };
17861
- const { st, ed } = table;
17862
- lineIterator(tablePage.type === DocumentSkeletonPageType.CELL ? [tablePage] : tablePage.parent.pages, (l) => {
17863
- if (l.st === ed + 1) lineAfterTable = l;
17864
- else if (l.ed === st - 1) lineBeforeTable = l;
17865
- });
17866
- return {
17867
- lineBeforeTable,
17868
- lineAfterTable
17869
- };
17870
- }
17871
- function isEmptyCellPage(cell) {
17872
- return cell.sections[0].columns[0].lines.length === 0;
17873
- }
17874
- function findBellowCell(cell) {
17875
- const row = cell.parent;
17876
- const table = row === null || row === void 0 ? void 0 : row.parent;
17877
- const tableId = table === null || table === void 0 ? void 0 : table.tableId;
17878
- if (row == null || table == null) return;
17879
- const col = row.cells.indexOf(cell);
17880
- let bellowRow = table.rows[table.rows.indexOf(row) + 1];
17881
- if (bellowRow == null) {
17882
- if (tableId.indexOf("#-#")) {
17883
- var _table$parent;
17884
- const [id, index] = tableId.split("#-#");
17885
- const pages = (_table$parent = table.parent) === null || _table$parent === void 0 || (_table$parent = _table$parent.parent) === null || _table$parent === void 0 ? void 0 : _table$parent.pages;
17886
- const nextTableId = `${id}#-#${Number.parseInt(index) + 1}`;
17887
- if (pages) for (const page of pages) {
17888
- const { skeTables } = page;
17889
- if (skeTables.has(nextTableId)) {
17890
- const nextTable = skeTables.get(nextTableId);
17891
- if (nextTable === null || nextTable === void 0 ? void 0 : nextTable.rows.length) {
17892
- bellowRow = nextTable.rows.find((r) => !r.isRepeatRow);
17893
- break;
17894
- }
17895
- }
17896
- }
17897
- }
17898
- }
17899
- if (bellowRow != null) {
17900
- const cell = bellowRow.cells[col];
17901
- return isEmptyCellPage(cell) ? findBellowCell(cell) : cell;
17902
- }
17903
- }
17904
- function findAboveCell(cell) {
17905
- const row = cell.parent;
17906
- const table = row === null || row === void 0 ? void 0 : row.parent;
17907
- if (row == null || table == null) return;
17908
- let aboveRow = table.rows[table.rows.indexOf(row) - 1];
17909
- const col = row.cells.indexOf(cell);
17910
- if (aboveRow == null || aboveRow.isRepeatRow) {
17911
- if (table.tableId.indexOf("#-#")) {
17912
- var _table$parent2;
17913
- const [id, index] = table.tableId.split("#-#");
17914
- const pages = (_table$parent2 = table.parent) === null || _table$parent2 === void 0 || (_table$parent2 = _table$parent2.parent) === null || _table$parent2 === void 0 ? void 0 : _table$parent2.pages;
17915
- const nextTableId = `${id}#-#${Number.parseInt(index) - 1}`;
17916
- if (pages) for (const page of pages) {
17917
- const { skeTables } = page;
17918
- if (skeTables.has(nextTableId)) {
17919
- const nextTable = skeTables.get(nextTableId);
17920
- if (nextTable === null || nextTable === void 0 ? void 0 : nextTable.rows.length) {
17921
- aboveRow = nextTable.rows[nextTable.rows.length - 1];
17922
- break;
17923
- }
17924
- }
17925
- }
17926
- }
17927
- }
17928
- if (aboveRow != null) {
17929
- const cell = aboveRow.cells[col];
17930
- return isEmptyCellPage(cell) ? findAboveCell(cell) : cell;
17931
- }
17932
- }
17933
18059
  function findTableBeforeLine(line, page) {
17934
18060
  const { st } = line;
17935
18061
  const { skeTables } = page;
@@ -17982,7 +18108,7 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
17982
18108
  }));
17983
18109
  }
17984
18110
  _handleShiftMoveSelection(direction, granularity = "character") {
17985
- var _this$_renderManagerS, _dataStream$length;
18111
+ var _this$_renderManagerS, _body$dataStream$leng, _docDataModel$getCust;
17986
18112
  const activeRange = this._textSelectionManagerService.getActiveTextRange();
17987
18113
  const allRanges = this._textSelectionManagerService.getTextRanges();
17988
18114
  const docDataModel = this._univerInstanceService.getCurrentUniverDocInstance();
@@ -18009,16 +18135,21 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18009
18135
  }
18010
18136
  const anchorOffset = collapsed ? startOffset : rangeDirection === RANGE_DIRECTION.FORWARD ? startOffset : endOffset;
18011
18137
  let focusOffset = collapsed ? endOffset : rangeDirection === RANGE_DIRECTION.FORWARD ? endOffset : startOffset;
18012
- const dataStreamLength = (_dataStream$length = docDataModel.getSelfOrHeaderFooterModel(normalizedSegmentId).getBody().dataStream.length) !== null && _dataStream$length !== void 0 ? _dataStream$length : Number.POSITIVE_INFINITY;
18138
+ const body = docDataModel.getSelfOrHeaderFooterModel(normalizedSegmentId).getBody();
18139
+ if (body == null) return;
18140
+ const dataStreamLength = (_body$dataStream$leng = body.dataStream.length) !== null && _body$dataStream$leng !== void 0 ? _body$dataStream$leng : Number.POSITIVE_INFINITY;
18141
+ const customRanges = (_docDataModel$getCust = docDataModel.getCustomRanges()) !== null && _docDataModel$getCust !== void 0 ? _docDataModel$getCust : [];
18013
18142
  if (granularity !== "character") {
18014
- const nextOffset = this._getCursorOffsetByGranularity(skeleton, focusOffset, direction, granularity, normalizedSegmentId, normalizedSegmentPage, dataStreamLength);
18143
+ const nextOffset = this._getCursorOffsetByGranularity(skeleton, focusOffset, direction, granularity, normalizedSegmentId, normalizedSegmentPage, dataStreamLength, body.dataStream);
18015
18144
  if (nextOffset == null || nextOffset === focusOffset) return;
18145
+ const normalizedNextOffset = this._normalizeRenderableCursorOffset(skeleton, body.dataStream, customRanges, nextOffset, direction, normalizedSegmentId, normalizedSegmentPage);
18146
+ if (normalizedNextOffset == null || normalizedNextOffset === focusOffset) return;
18016
18147
  this._textSelectionManagerService.replaceTextRanges([{
18017
18148
  startOffset: anchorOffset,
18018
- endOffset: nextOffset,
18149
+ endOffset: normalizedNextOffset,
18019
18150
  style
18020
18151
  }], false);
18021
- this._scrollToFocusNodePosition(docDataModel.getUnitId(), nextOffset);
18152
+ this._scrollToFocusNodePosition(docDataModel.getUnitId(), normalizedNextOffset);
18022
18153
  return;
18023
18154
  }
18024
18155
  if (direction === Direction.LEFT || direction === Direction.RIGHT) {
@@ -18039,8 +18170,8 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18039
18170
  const focusNodePosition = collapsed ? startNodePosition : rangeDirection === RANGE_DIRECTION.FORWARD ? endNodePosition : startNodePosition;
18040
18171
  const newPos = this._getTopOrBottomPosition(skeleton, focusGlyph, focusNodePosition, direction === Direction.DOWN, true);
18041
18172
  if (newPos == null) {
18042
- const newFocusOffset = direction === Direction.UP ? 0 : dataStreamLength - 2;
18043
- if (newFocusOffset === focusOffset) return;
18173
+ const newFocusOffset = this._normalizeRenderableCursorOffset(skeleton, body.dataStream, customRanges, direction === Direction.UP ? 0 : dataStreamLength - 2, direction, normalizedSegmentId, normalizedSegmentPage);
18174
+ if (newFocusOffset == null || newFocusOffset === focusOffset) return;
18044
18175
  this._textSelectionManagerService.replaceTextRanges([{
18045
18176
  startOffset: anchorOffset,
18046
18177
  endOffset: newFocusOffset,
@@ -18049,16 +18180,18 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18049
18180
  return;
18050
18181
  }
18051
18182
  const newActiveRange = new NodePositionConvertToCursor(documentOffsetConfig, skeleton).getRangePointData(newPos, newPos).cursorList[0];
18183
+ const newFocusOffset = this._normalizeRenderableCursorOffset(skeleton, body.dataStream, customRanges, newActiveRange.endOffset, direction, normalizedSegmentId, normalizedSegmentPage);
18184
+ if (newFocusOffset == null || newFocusOffset === focusOffset) return;
18052
18185
  this._textSelectionManagerService.replaceTextRanges([{
18053
18186
  startOffset: anchorOffset,
18054
- endOffset: newActiveRange.endOffset,
18187
+ endOffset: newFocusOffset,
18055
18188
  style
18056
18189
  }], false);
18057
- this._scrollToFocusNodePosition(docDataModel.getUnitId(), newActiveRange.endOffset);
18190
+ this._scrollToFocusNodePosition(docDataModel.getUnitId(), newFocusOffset);
18058
18191
  }
18059
18192
  }
18060
18193
  _handleMoveCursor(direction, granularity = "character") {
18061
- var _this$_renderManagerS2, _body$dataStream$leng, _docDataModel$getCust;
18194
+ var _this$_renderManagerS2, _body$dataStream$leng2, _docDataModel$getCust2;
18062
18195
  const activeRange = this._textSelectionManagerService.getActiveTextRange();
18063
18196
  const allRanges = this._textSelectionManagerService.getTextRanges();
18064
18197
  const docDataModel = this._univerInstanceService.getCurrentUniverDocInstance();
@@ -18071,8 +18204,8 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18071
18204
  const normalizedSegmentPage = segmentPage !== null && segmentPage !== void 0 ? segmentPage : -1;
18072
18205
  const body = docDataModel.getSelfOrHeaderFooterModel(normalizedSegmentId).getBody();
18073
18206
  if (body == null) return;
18074
- const dataStreamLength = (_body$dataStream$leng = body.dataStream.length) !== null && _body$dataStream$leng !== void 0 ? _body$dataStream$leng : Number.POSITIVE_INFINITY;
18075
- const customRanges = (_docDataModel$getCust = docDataModel.getCustomRanges()) !== null && _docDataModel$getCust !== void 0 ? _docDataModel$getCust : [];
18207
+ const dataStreamLength = (_body$dataStream$leng2 = body.dataStream.length) !== null && _body$dataStream$leng2 !== void 0 ? _body$dataStream$leng2 : Number.POSITIVE_INFINITY;
18208
+ const customRanges = (_docDataModel$getCust2 = docDataModel.getCustomRanges()) !== null && _docDataModel$getCust2 !== void 0 ? _docDataModel$getCust2 : [];
18076
18209
  if (granularity !== "character") {
18077
18210
  let cursorOffset;
18078
18211
  if (!activeRange.collapsed || allRanges.length > 1) {
@@ -18084,9 +18217,10 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18084
18217
  }
18085
18218
  cursorOffset = direction === Direction.LEFT || direction === Direction.UP ? min : max;
18086
18219
  } else cursorOffset = direction === Direction.LEFT || direction === Direction.UP ? startOffset : endOffset;
18087
- let cursor = this._getCursorOffsetByGranularity(skeleton, cursorOffset, direction, granularity, normalizedSegmentId, normalizedSegmentPage, dataStreamLength);
18220
+ let cursor = this._getCursorOffsetByGranularity(skeleton, cursorOffset, direction, granularity, normalizedSegmentId, normalizedSegmentPage, dataStreamLength, body.dataStream);
18221
+ if (cursor == null) return;
18222
+ cursor = this._normalizeRenderableCursorOffset(skeleton, body.dataStream, customRanges, cursor, direction, normalizedSegmentId, normalizedSegmentPage);
18088
18223
  if (cursor == null) return;
18089
- cursor = this._normalizeCursorOffset(body.dataStream, customRanges, cursor, direction);
18090
18224
  this._textSelectionManagerService.replaceTextRanges([{
18091
18225
  startOffset: cursor,
18092
18226
  endOffset: cursor,
@@ -18117,13 +18251,15 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18117
18251
  const skipTokens = [...this._getCursorSkipTokens()];
18118
18252
  if (direction === Direction.LEFT) while (skipTokens.includes(body.dataStream[cursor])) cursor--;
18119
18253
  else while (skipTokens.includes(body.dataStream[cursor])) cursor++;
18120
- cursor = this._normalizeWholeEntityRanges(customRanges, cursor, direction);
18254
+ cursor = this._normalizeCursorOffset(body.dataStream, customRanges, cursor, direction);
18255
+ const normalizedCursor = this._normalizeRenderableCursorOffset(skeleton, body.dataStream, customRanges, cursor, direction, normalizedSegmentId, normalizedSegmentPage);
18256
+ if (normalizedCursor == null) return;
18121
18257
  this._textSelectionManagerService.replaceTextRanges([{
18122
- startOffset: Math.max(0, cursor),
18123
- endOffset: Math.max(0, cursor),
18258
+ startOffset: normalizedCursor,
18259
+ endOffset: normalizedCursor,
18124
18260
  style
18125
18261
  }], false);
18126
- this._scrollToFocusNodePosition(docDataModel.getUnitId(), cursor);
18262
+ this._scrollToFocusNodePosition(docDataModel.getUnitId(), normalizedCursor);
18127
18263
  } else {
18128
18264
  const startNode = skeleton.findNodeByCharIndex(startOffset, segmentId, segmentPage);
18129
18265
  const endNode = skeleton.findNodeByCharIndex(endOffset, segmentId, segmentPage);
@@ -18131,31 +18267,55 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18131
18267
  const newPos = this._getTopOrBottomPosition(skeleton, direction === Direction.UP ? startNode : collapsed ? startNode : endNode, direction === Direction.UP ? startNodePosition : collapsed ? startNodePosition : endNodePosition, direction === Direction.DOWN);
18132
18268
  if (newPos == null) {
18133
18269
  let cursor;
18134
- if (collapsed) cursor = direction === Direction.UP ? 0 : dataStreamLength - 2;
18135
- else cursor = direction === Direction.UP ? startOffset : endOffset;
18270
+ if (collapsed) cursor = this._normalizeRenderableCursorOffset(skeleton, body.dataStream, customRanges, direction === Direction.UP ? 0 : dataStreamLength - 2, direction, normalizedSegmentId, normalizedSegmentPage);
18271
+ else cursor = this._normalizeRenderableCursorOffset(skeleton, body.dataStream, customRanges, direction === Direction.UP ? startOffset : endOffset, direction, normalizedSegmentId, normalizedSegmentPage);
18272
+ if (cursor == null) return;
18136
18273
  this._textSelectionManagerService.replaceTextRanges([{
18137
- startOffset: Math.max(0, cursor),
18138
- endOffset: Math.max(0, cursor),
18274
+ startOffset: cursor,
18275
+ endOffset: cursor,
18139
18276
  style
18140
18277
  }], false);
18141
18278
  return;
18142
18279
  }
18143
18280
  const newActiveRange = new NodePositionConvertToCursor(documentOffsetConfig, skeleton).getRangePointData(newPos, newPos).cursorList[0];
18281
+ const cursor = this._normalizeRenderableCursorOffset(skeleton, body.dataStream, customRanges, newActiveRange.endOffset, direction, normalizedSegmentId, normalizedSegmentPage);
18282
+ if (cursor == null) return;
18144
18283
  this._textSelectionManagerService.replaceTextRanges([{
18145
- ...newActiveRange,
18284
+ startOffset: cursor,
18285
+ endOffset: cursor,
18146
18286
  style
18147
18287
  }], false);
18148
- this._scrollToFocusNodePosition(docDataModel.getUnitId(), newActiveRange.endOffset);
18288
+ this._scrollToFocusNodePosition(docDataModel.getUnitId(), cursor);
18149
18289
  }
18150
18290
  }
18151
- _getCursorOffsetByGranularity(skeleton, focusOffset, direction, granularity, segmentId, segmentPage, dataStreamLength) {
18291
+ _getCursorOffsetByGranularity(skeleton, focusOffset, direction, granularity, segmentId, segmentPage, dataStreamLength, dataStream = "") {
18152
18292
  switch (granularity) {
18153
18293
  case "document": return direction === Direction.LEFT || direction === Direction.UP ? 0 : dataStreamLength - 2;
18294
+ case "paragraph": return this._getParagraphBoundaryOffset(dataStream, focusOffset, direction);
18154
18295
  case "line": return this._getLineBoundaryOffset(skeleton, focusOffset, direction, segmentId, segmentPage, dataStreamLength);
18155
18296
  case "word": return this._getWordBoundaryOffset(skeleton, focusOffset, direction, segmentId, segmentPage, dataStreamLength);
18156
18297
  default: return null;
18157
18298
  }
18158
18299
  }
18300
+ _getParagraphBoundaryOffset(dataStream, focusOffset, direction) {
18301
+ if (direction !== Direction.UP && direction !== Direction.DOWN) return;
18302
+ if (dataStream.length === 0) return 0;
18303
+ const cursor = Math.min(Math.max(0, focusOffset), dataStream.length - 1);
18304
+ if (direction === Direction.UP) {
18305
+ const currentParagraphStart = this._getCurrentParagraphStartOffset(dataStream, cursor);
18306
+ if (cursor > currentParagraphStart) return currentParagraphStart;
18307
+ return this._getCurrentParagraphStartOffset(dataStream, Math.max(0, currentParagraphStart - 1));
18308
+ }
18309
+ const nextParagraphEnd = dataStream.indexOf(DataStreamTreeTokenType.PARAGRAPH, cursor);
18310
+ return nextParagraphEnd === -1 ? dataStream.length - 1 : nextParagraphEnd + 1;
18311
+ }
18312
+ _getCurrentParagraphStartOffset(dataStream, cursor) {
18313
+ for (let index = Math.min(cursor - 1, dataStream.length - 1); index >= 0; index--) {
18314
+ const token = dataStream[index];
18315
+ if (token === DataStreamTreeTokenType.PARAGRAPH || token === DataStreamTreeTokenType.SECTION_BREAK) return index + 1;
18316
+ }
18317
+ return 0;
18318
+ }
18159
18319
  _getWordBoundaryOffset(skeleton, focusOffset, direction, segmentId, segmentPage, dataStreamLength) {
18160
18320
  var _skeleton$findNodeByC;
18161
18321
  if (direction !== Direction.LEFT && direction !== Direction.RIGHT) return;
@@ -18206,6 +18366,30 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18206
18366
  else while (cursor < dataStream.length - 1 && skipTokens.includes(dataStream[cursor])) cursor++;
18207
18367
  return this._normalizeWholeEntityRanges(customRanges, cursor, direction);
18208
18368
  }
18369
+ _normalizeRenderableCursorOffset(skeleton, dataStream, customRanges, cursor, direction, segmentId, segmentPage) {
18370
+ const boundedCursor = Math.min(Math.max(0, cursor), Math.max(0, dataStream.length - 1));
18371
+ const primaryCursor = this._findNearestRenderableCursorOffset(skeleton, dataStream, customRanges, boundedCursor, direction, segmentId, segmentPage);
18372
+ if (primaryCursor != null) return primaryCursor;
18373
+ const fallbackDirection = direction === Direction.LEFT || direction === Direction.UP ? Direction.DOWN : Direction.UP;
18374
+ return this._findNearestRenderableCursorOffset(skeleton, dataStream, customRanges, boundedCursor, fallbackDirection, segmentId, segmentPage);
18375
+ }
18376
+ _findNearestRenderableCursorOffset(skeleton, dataStream, customRanges, cursor, direction, segmentId, segmentPage) {
18377
+ const step = direction === Direction.LEFT || direction === Direction.UP ? -1 : 1;
18378
+ let current = Math.min(Math.max(0, cursor), Math.max(0, dataStream.length - 1));
18379
+ const visited = /* @__PURE__ */ new Set();
18380
+ while (current >= 0 && current < dataStream.length && !visited.has(current)) {
18381
+ visited.add(current);
18382
+ const normalizedCursor = this._normalizeCursorOffset(dataStream, customRanges, current, direction);
18383
+ if (normalizedCursor < 0 || normalizedCursor >= dataStream.length) return;
18384
+ if (this._isRenderableCursorOffset(skeleton, dataStream, normalizedCursor, segmentId, segmentPage)) return normalizedCursor;
18385
+ current = normalizedCursor + step;
18386
+ }
18387
+ }
18388
+ _isRenderableCursorOffset(skeleton, dataStream, cursor, segmentId, segmentPage) {
18389
+ if (cursor < 0 || cursor >= dataStream.length) return false;
18390
+ if (this._getNonRenderableCursorTokens().includes(dataStream[cursor])) return false;
18391
+ return skeleton.findNodePositionByCharIndex(cursor, true, segmentId, segmentPage) != null;
18392
+ }
18209
18393
  _normalizeWholeEntityRanges(customRanges, cursor, direction) {
18210
18394
  customRanges.filter((range) => range.wholeEntity && range.startIndex < cursor && range.endIndex >= cursor).forEach((range) => {
18211
18395
  if (direction === Direction.LEFT || direction === Direction.UP) cursor = Math.min(range.startIndex, cursor);
@@ -18228,12 +18412,21 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18228
18412
  if (includeParagraph) tokens.push(DataStreamTreeTokenType.PARAGRAPH);
18229
18413
  return tokens;
18230
18414
  }
18415
+ _getNonRenderableCursorTokens() {
18416
+ return [
18417
+ ...this._getCursorSkipTokens(),
18418
+ DataStreamTreeTokenType.COLUMN_GROUP_START,
18419
+ DataStreamTreeTokenType.COLUMN_GROUP_END,
18420
+ DataStreamTreeTokenType.COLUMN_START,
18421
+ DataStreamTreeTokenType.COLUMN_END
18422
+ ];
18423
+ }
18231
18424
  _getTopOrBottomPosition(docSkeleton, glyph, nodePosition, direction, skipCellContent = false) {
18232
18425
  if (glyph == null || nodePosition == null) return;
18233
18426
  const offsetLeft = this._getGlyphLeftOffsetInLine(glyph);
18234
- const line = this._getNextOrPrevLine(glyph, direction, skipCellContent);
18235
- if (line == null) return;
18236
- const position = this._matchPositionByLeftOffset(docSkeleton, line, offsetLeft, nodePosition);
18427
+ const target = this._getNextOrPrevLineTarget(glyph, direction, offsetLeft, skipCellContent);
18428
+ if (target == null) return;
18429
+ const position = this._matchPositionByLeftOffset(docSkeleton, target.line, target.offsetLeft, nodePosition);
18237
18430
  if (position == null) return;
18238
18431
  return {
18239
18432
  ...position,
@@ -18248,11 +18441,24 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18248
18441
  return divideLeft + left;
18249
18442
  }
18250
18443
  _matchPositionByLeftOffset(docSkeleton, line, offsetLeft, nodePosition) {
18444
+ var _nearestNode$glyph;
18251
18445
  const nearestNode = { distance: Number.POSITIVE_INFINITY };
18446
+ const nearestEmptyParagraphNode = { distance: Number.POSITIVE_INFINITY };
18252
18447
  for (const divide of line.divides) {
18253
18448
  const divideLeft = divide.left;
18254
18449
  for (const glyph of divide.glyphGroup) {
18255
- if (!this._isCursorAddressableGlyph(glyph)) continue;
18450
+ if (!this._isCursorAddressableGlyph(glyph)) {
18451
+ if (glyph.streamType === DataStreamTreeTokenType.PARAGRAPH && glyph.count > 0) {
18452
+ const { left } = glyph;
18453
+ const leftSide = divideLeft + left;
18454
+ const distance = Math.abs(offsetLeft - leftSide);
18455
+ if (distance < nearestEmptyParagraphNode.distance) {
18456
+ nearestEmptyParagraphNode.glyph = glyph;
18457
+ nearestEmptyParagraphNode.distance = distance;
18458
+ }
18459
+ }
18460
+ continue;
18461
+ }
18256
18462
  const { left } = glyph;
18257
18463
  const leftSide = divideLeft + left;
18258
18464
  const distance = Math.abs(offsetLeft - leftSide);
@@ -18262,11 +18468,12 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18262
18468
  }
18263
18469
  }
18264
18470
  }
18265
- if (nearestNode.glyph == null) return;
18471
+ const nearestGlyph = (_nearestNode$glyph = nearestNode.glyph) !== null && _nearestNode$glyph !== void 0 ? _nearestNode$glyph : nearestEmptyParagraphNode.glyph;
18472
+ if (nearestGlyph == null) return;
18266
18473
  const { segmentPage } = nodePosition;
18267
- return docSkeleton.findPositionByGlyph(nearestNode.glyph, segmentPage);
18474
+ return docSkeleton.findPositionByGlyph(nearestGlyph, segmentPage);
18268
18475
  }
18269
- _getNextOrPrevLine(glyph, direction, skipCellContent = false) {
18476
+ _getNextOrPrevLineTarget(glyph, direction, offsetLeft, skipCellContent = false) {
18270
18477
  const divide = glyph.parent;
18271
18478
  const line = divide === null || divide === void 0 ? void 0 : divide.parent;
18272
18479
  const column = line === null || line === void 0 ? void 0 : line.parent;
@@ -18276,26 +18483,25 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18276
18483
  const currentLineIndex = column.lines.indexOf(line);
18277
18484
  if (currentLineIndex === -1) return;
18278
18485
  let newLine;
18279
- if (page.type === DocumentSkeletonPageType.CELL && skipCellContent) {
18280
- const nLine = findAboveOrBellowCellLine(page, direction);
18281
- if (nLine) return nLine;
18486
+ if (this._isTableCellContentPage(page) && skipCellContent) {
18487
+ const tableCellTarget = this._getAdjacentTableCellLineTarget(page, direction, offsetLeft);
18488
+ if (tableCellTarget != null) return tableCellTarget;
18282
18489
  }
18283
18490
  if (direction === true) {
18284
18491
  newLine = column.lines[currentLineIndex + 1];
18285
- const tableAfterLine = findTableAfterLine(line, page);
18286
- if (tableAfterLine) {
18287
- const firstLine = firstLineInTable(tableAfterLine);
18288
- if (firstLine) newLine = firstLine;
18289
- }
18492
+ const tableTarget = this._getTableLineTargetFromPageLine(line, page, direction, offsetLeft);
18493
+ if (tableTarget != null) return tableTarget;
18290
18494
  } else {
18291
18495
  newLine = column.lines[currentLineIndex - 1];
18292
- const tableBeforeLine = findTableBeforeLine(line, page);
18293
- if (tableBeforeLine) {
18294
- const lastLine = lastLineInTable(tableBeforeLine);
18295
- if (lastLine) newLine = lastLine;
18296
- }
18496
+ const tableTarget = this._getTableLineTargetFromPageLine(line, page, direction, offsetLeft);
18497
+ if (tableTarget != null) return tableTarget;
18297
18498
  }
18298
- if (newLine != null) return newLine;
18499
+ const columnGroupTarget = this._getColumnGroupLineTargetFromBlockLine(newLine, page, direction, offsetLeft);
18500
+ if (columnGroupTarget != null) return columnGroupTarget;
18501
+ if (newLine != null) return {
18502
+ line: newLine,
18503
+ offsetLeft
18504
+ };
18299
18505
  const currentColumnIndex = section.columns.indexOf(column);
18300
18506
  if (currentColumnIndex === -1) return;
18301
18507
  if (direction === true) {
@@ -18306,7 +18512,10 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18306
18512
  const prevColumnLines = (_section$columns2 = section.columns) === null || _section$columns2 === void 0 || (_section$columns2 = _section$columns2[currentColumnIndex - 1]) === null || _section$columns2 === void 0 ? void 0 : _section$columns2.lines;
18307
18513
  newLine = prevColumnLines === null || prevColumnLines === void 0 ? void 0 : prevColumnLines[prevColumnLines.length - 1];
18308
18514
  }
18309
- if (newLine != null) return newLine;
18515
+ if (newLine != null) return {
18516
+ line: newLine,
18517
+ offsetLeft
18518
+ };
18310
18519
  const currentSectionIndex = page.sections.indexOf(section);
18311
18520
  if (currentSectionIndex === -1) return;
18312
18521
  if (direction === true) {
@@ -18319,8 +18528,15 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18319
18528
  const prevColumnLines = column === null || column === void 0 ? void 0 : column.lines;
18320
18529
  newLine = prevColumnLines === null || prevColumnLines === void 0 ? void 0 : prevColumnLines[prevColumnLines.length - 1];
18321
18530
  }
18322
- if (newLine != null) return newLine;
18323
- if (page.type === DocumentSkeletonPageType.CELL) return findAboveOrBellowCellLine(page, direction);
18531
+ if (newLine != null) return {
18532
+ line: newLine,
18533
+ offsetLeft
18534
+ };
18535
+ if (this._isColumnGroupContentPage(page)) {
18536
+ const exitTarget = this._getColumnGroupExitLineTarget(page, direction, offsetLeft);
18537
+ if (exitTarget != null) return exitTarget;
18538
+ }
18539
+ if (this._isTableCellContentPage(page)) return this._getAdjacentTableCellLineTarget(page, direction, offsetLeft);
18324
18540
  const skeleton = page.parent;
18325
18541
  if (skeleton == null) return;
18326
18542
  const currentPageIndex = skeleton.pages.indexOf(page);
@@ -18337,7 +18553,189 @@ let DocMoveCursorController = class DocMoveCursorController extends Disposable {
18337
18553
  const prevColumnLines = column === null || column === void 0 ? void 0 : column.lines;
18338
18554
  newLine = prevColumnLines[prevColumnLines.length - 1];
18339
18555
  }
18340
- if (newLine != null) return newLine;
18556
+ if (newLine != null) return {
18557
+ line: newLine,
18558
+ offsetLeft
18559
+ };
18560
+ }
18561
+ _getTableLineTargetFromPageLine(line, page, direction, offsetLeft) {
18562
+ const table = direction ? findTableAfterLine(line, page) : findTableBeforeLine(line, page);
18563
+ if (table == null) return;
18564
+ return this._getTableBoundaryLineTarget(table, direction, offsetLeft);
18565
+ }
18566
+ _getTableBoundaryLineTarget(table, direction, offsetLeft) {
18567
+ const rows = direction ? table.rows : [...table.rows].reverse();
18568
+ for (const row of rows) {
18569
+ if (row.isRepeatRow) continue;
18570
+ const target = this._getNearestTableCellLineTarget(row.cells, direction, offsetLeft);
18571
+ if (target != null) return target;
18572
+ }
18573
+ }
18574
+ _getAdjacentTableCellLineTarget(cell, direction, offsetLeft) {
18575
+ const row = cell.parent;
18576
+ const table = row === null || row === void 0 ? void 0 : row.parent;
18577
+ if (row == null || table == null) return;
18578
+ const hostOffsetLeft = this._getTableCellHostOffsetLeft(cell) + offsetLeft;
18579
+ const adjacentRow = this._findAdjacentTableRow(table, row, direction);
18580
+ if (adjacentRow != null) return this._getNearestTableCellLineTarget(adjacentRow.cells, direction, hostOffsetLeft);
18581
+ const line = this._findLineAroundTable(table, direction);
18582
+ if (line == null) return;
18583
+ return {
18584
+ line,
18585
+ offsetLeft: hostOffsetLeft
18586
+ };
18587
+ }
18588
+ _findAdjacentTableRow(table, row, direction) {
18589
+ const currentRowIndex = table.rows.indexOf(row);
18590
+ if (currentRowIndex === -1) return;
18591
+ const step = direction ? 1 : -1;
18592
+ let rowIndex = currentRowIndex + step;
18593
+ while (rowIndex >= 0 && rowIndex < table.rows.length) {
18594
+ const adjacentRow = table.rows[rowIndex];
18595
+ if (!adjacentRow.isRepeatRow) return adjacentRow;
18596
+ rowIndex += step;
18597
+ }
18598
+ return this._findAdjacentTableSliceRow(table, direction);
18599
+ }
18600
+ _findAdjacentTableSliceRow(table, direction) {
18601
+ if (!table.tableId.includes("#-#")) return;
18602
+ const [sourceTableId, sliceIndexText] = table.tableId.split("#-#");
18603
+ const sliceIndex = Number.parseInt(sliceIndexText);
18604
+ const tablePage = table.parent;
18605
+ const skeleton = tablePage === null || tablePage === void 0 ? void 0 : tablePage.parent;
18606
+ if (!Number.isFinite(sliceIndex) || (skeleton === null || skeleton === void 0 ? void 0 : skeleton.pages) == null) return;
18607
+ const nextTableId = `${sourceTableId}#-#${sliceIndex + (direction ? 1 : -1)}`;
18608
+ for (const page of skeleton.pages) {
18609
+ var _page$skeTables;
18610
+ const nextTable = (_page$skeTables = page.skeTables) === null || _page$skeTables === void 0 ? void 0 : _page$skeTables.get(nextTableId);
18611
+ const row = (nextTable == null ? [] : direction ? nextTable.rows : [...nextTable.rows].reverse()).find((item) => !item.isRepeatRow);
18612
+ if (row != null) return row;
18613
+ }
18614
+ }
18615
+ _getNearestTableCellLineTarget(cells, direction, hostOffsetLeft) {
18616
+ const candidates = cells.filter((cell) => !cell.isMergedCellCovered).map((cell) => ({
18617
+ cell,
18618
+ distance: this._getDistanceToTableCell(cell, hostOffsetLeft)
18619
+ })).sort((a, b) => a.distance - b.distance);
18620
+ for (const candidate of candidates) {
18621
+ const line = direction ? firstLineInCell(candidate.cell) : lastLineInCell(candidate.cell);
18622
+ if (line != null) return {
18623
+ line,
18624
+ offsetLeft: hostOffsetLeft - this._getTableCellHostOffsetLeft(candidate.cell)
18625
+ };
18626
+ }
18627
+ }
18628
+ _findLineAroundTable(table, direction) {
18629
+ var _pages, _tablePage$parent;
18630
+ const tablePage = table.parent;
18631
+ if (tablePage == null) return;
18632
+ const pages = (_pages = (_tablePage$parent = tablePage.parent) === null || _tablePage$parent === void 0 ? void 0 : _tablePage$parent.pages) !== null && _pages !== void 0 ? _pages : [tablePage];
18633
+ const lineMatcher = direction ? (line) => line.st === table.ed + 1 : (line) => line.ed === table.st - 1;
18634
+ for (const page of pages) for (const section of page.sections) for (const column of section.columns) {
18635
+ const line = (direction ? column.lines : [...column.lines].reverse()).find(lineMatcher);
18636
+ if (line != null) return line;
18637
+ }
18638
+ }
18639
+ _getDistanceToTableCell(cell, offsetLeft) {
18640
+ const left = this._getTableCellHostOffsetLeft(cell);
18641
+ const right = left + this._getTableCellContentWidth(cell);
18642
+ if (offsetLeft >= left && offsetLeft <= right) return 0;
18643
+ return Math.min(Math.abs(offsetLeft - left), Math.abs(offsetLeft - right));
18644
+ }
18645
+ _getTableCellHostOffsetLeft(cell) {
18646
+ var _table$left, _cell$left, _cell$marginLeft;
18647
+ const row = cell.parent;
18648
+ const table = row === null || row === void 0 ? void 0 : row.parent;
18649
+ return ((_table$left = table === null || table === void 0 ? void 0 : table.left) !== null && _table$left !== void 0 ? _table$left : 0) + ((_cell$left = cell.left) !== null && _cell$left !== void 0 ? _cell$left : 0) + ((_cell$marginLeft = cell.marginLeft) !== null && _cell$marginLeft !== void 0 ? _cell$marginLeft : 0);
18650
+ }
18651
+ _getTableCellContentWidth(cell) {
18652
+ var _cell$pageWidth, _cell$marginLeft2, _cell$marginRight;
18653
+ return Math.max(0, ((_cell$pageWidth = cell.pageWidth) !== null && _cell$pageWidth !== void 0 ? _cell$pageWidth : 0) - ((_cell$marginLeft2 = cell.marginLeft) !== null && _cell$marginLeft2 !== void 0 ? _cell$marginLeft2 : 0) - ((_cell$marginRight = cell.marginRight) !== null && _cell$marginRight !== void 0 ? _cell$marginRight : 0));
18654
+ }
18655
+ _isTableCellContentPage(page) {
18656
+ var _table$rows;
18657
+ const row = page.parent;
18658
+ const table = row === null || row === void 0 ? void 0 : row.parent;
18659
+ return page.type === DocumentSkeletonPageType.CELL && row != null && (table === null || table === void 0 || (_table$rows = table.rows) === null || _table$rows === void 0 ? void 0 : _table$rows.includes(row)) === true && row.cells.includes(page);
18660
+ }
18661
+ _getColumnGroupLineTargetFromBlockLine(line, page, direction, offsetLeft) {
18662
+ if (line == null || line.type !== LineType.BLOCK) return;
18663
+ const columnGroup = this._findColumnGroupByBlockLine(page, line);
18664
+ if (columnGroup == null) return;
18665
+ return this._getColumnGroupContentLineTarget(columnGroup, direction, offsetLeft);
18666
+ }
18667
+ _getColumnGroupContentLineTarget(columnGroup, direction, offsetLeft) {
18668
+ const candidates = columnGroup.columns.map((column) => ({
18669
+ column,
18670
+ distance: this._getDistanceToColumnGroupColumn(column, offsetLeft)
18671
+ })).sort((a, b) => a.distance - b.distance);
18672
+ for (const candidate of candidates) {
18673
+ const line = this._getColumnGroupColumnBoundaryLine(candidate.column, direction);
18674
+ if (line != null) return {
18675
+ line,
18676
+ offsetLeft: offsetLeft - candidate.column.left
18677
+ };
18678
+ }
18679
+ }
18680
+ _getColumnGroupExitLineTarget(page, direction, offsetLeft) {
18681
+ const columnGroupColumn = page.parent;
18682
+ const columnGroup = columnGroupColumn === null || columnGroupColumn === void 0 ? void 0 : columnGroupColumn.parent;
18683
+ const hostPage = columnGroup === null || columnGroup === void 0 ? void 0 : columnGroup.parent;
18684
+ if (columnGroupColumn == null || columnGroup == null || hostPage == null) return;
18685
+ const blockLine = this._findColumnGroupBlockLine(columnGroup);
18686
+ const line = blockLine == null ? void 0 : this._getAdjacentLineAroundBlockLine(blockLine, direction);
18687
+ if (line == null) return;
18688
+ return {
18689
+ line,
18690
+ offsetLeft: columnGroupColumn.left + offsetLeft
18691
+ };
18692
+ }
18693
+ _findColumnGroupByBlockLine(page, line) {
18694
+ var _page$skeColumnGroups, _page$skeColumnGroups2;
18695
+ for (const columnGroup of (_page$skeColumnGroups = (_page$skeColumnGroups2 = page.skeColumnGroups) === null || _page$skeColumnGroups2 === void 0 ? void 0 : _page$skeColumnGroups2.values()) !== null && _page$skeColumnGroups !== void 0 ? _page$skeColumnGroups : []) if (line.paragraphIndex === columnGroup.ed || line.st <= columnGroup.ed && line.ed >= columnGroup.st) return columnGroup;
18696
+ }
18697
+ _findColumnGroupBlockLine(columnGroup) {
18698
+ const page = columnGroup.parent;
18699
+ if (page == null) return;
18700
+ for (const section of page.sections) for (const column of section.columns) for (const line of column.lines) if (line.type === LineType.BLOCK && this._findColumnGroupByBlockLine(page, line) === columnGroup) return line;
18701
+ }
18702
+ _getAdjacentLineAroundBlockLine(line, direction) {
18703
+ var _section$columns4;
18704
+ const column = line.parent;
18705
+ const section = column === null || column === void 0 ? void 0 : column.parent;
18706
+ const page = section === null || section === void 0 ? void 0 : section.parent;
18707
+ if (column == null || section == null || page == null) return;
18708
+ const lineIndex = column.lines.indexOf(line);
18709
+ if (lineIndex === -1) return;
18710
+ const sameColumnLine = column.lines[direction ? lineIndex + 1 : lineIndex - 1];
18711
+ if (sameColumnLine != null) return sameColumnLine;
18712
+ const columnIndex = section.columns.indexOf(column);
18713
+ if (columnIndex === -1) return;
18714
+ if (direction) {
18715
+ var _section$columns3;
18716
+ return (_section$columns3 = section.columns[columnIndex + 1]) === null || _section$columns3 === void 0 ? void 0 : _section$columns3.lines[0];
18717
+ }
18718
+ const prevColumnLines = (_section$columns4 = section.columns[columnIndex - 1]) === null || _section$columns4 === void 0 ? void 0 : _section$columns4.lines;
18719
+ return prevColumnLines === null || prevColumnLines === void 0 ? void 0 : prevColumnLines[prevColumnLines.length - 1];
18720
+ }
18721
+ _getColumnGroupColumnBoundaryLine(column, direction) {
18722
+ const sections = direction ? column.page.sections : [...column.page.sections].reverse();
18723
+ for (const section of sections) {
18724
+ const columns = direction ? section.columns : [...section.columns].reverse();
18725
+ for (const skeletonColumn of columns) {
18726
+ const line = (direction ? skeletonColumn.lines : [...skeletonColumn.lines].reverse()).find((item) => item.type !== LineType.BLOCK);
18727
+ if (line != null) return line;
18728
+ }
18729
+ }
18730
+ }
18731
+ _getDistanceToColumnGroupColumn(column, offsetLeft) {
18732
+ if (offsetLeft >= column.left && offsetLeft <= column.left + column.width) return 0;
18733
+ return Math.min(Math.abs(offsetLeft - column.left), Math.abs(offsetLeft - column.left - column.width));
18734
+ }
18735
+ _isColumnGroupContentPage(page) {
18736
+ var _parent$parent;
18737
+ const parent = page.parent;
18738
+ return (parent === null || parent === void 0 ? void 0 : parent.page) === page && ((_parent$parent = parent.parent) === null || _parent$parent === void 0 || (_parent$parent = _parent$parent.columns) === null || _parent$parent === void 0 ? void 0 : _parent$parent.includes(parent)) === true;
18341
18739
  }
18342
18740
  _scrollToFocusNodePosition(unitId, offset) {
18343
18741
  var _this$_renderManagerS3;
@@ -18359,27 +18757,6 @@ DocMoveCursorController = __decorate([
18359
18757
  __decorateParam(2, Inject(DocSelectionManagerService)),
18360
18758
  __decorateParam(3, ICommandService)
18361
18759
  ], DocMoveCursorController);
18362
- function findAboveOrBellowCellLine(page, direction) {
18363
- let newLine = null;
18364
- if (direction === true) {
18365
- const bellowCell = findBellowCell(page);
18366
- if (bellowCell) newLine = firstLineInCell(bellowCell);
18367
- else {
18368
- var _page$parent;
18369
- const { lineAfterTable } = findLineBeforeAndAfterTable((_page$parent = page.parent) === null || _page$parent === void 0 ? void 0 : _page$parent.parent);
18370
- if (lineAfterTable) newLine = lineAfterTable;
18371
- }
18372
- } else {
18373
- const aboveCell = findAboveCell(page);
18374
- if (aboveCell) newLine = lastLineInCell(aboveCell);
18375
- else {
18376
- var _page$parent2;
18377
- const { lineBeforeTable } = findLineBeforeAndAfterTable((_page$parent2 = page.parent) === null || _page$parent2 === void 0 ? void 0 : _page$parent2.parent);
18378
- if (lineBeforeTable) newLine = lineBeforeTable;
18379
- }
18380
- }
18381
- return newLine;
18382
- }
18383
18760
 
18384
18761
  //#endregion
18385
18762
  //#region src/controllers/doc-table.controller.ts
@@ -19359,6 +19736,10 @@ const MoveCursorWordLeftShortcut = moveCursorShortcut(Direction.LEFT, "word", Ke
19359
19736
  const MoveCursorWordRightShortcut = moveCursorShortcut(Direction.RIGHT, "word", KeyCode.ARROW_RIGHT | MetaKeys.CTRL_COMMAND, KeyCode.ARROW_RIGHT | MetaKeys.ALT);
19360
19737
  const MoveSelectionWordLeftShortcut = moveSelectionShortcut(Direction.LEFT, "word", KeyCode.ARROW_LEFT | MetaKeys.CTRL_COMMAND | MetaKeys.SHIFT, KeyCode.ARROW_LEFT | MetaKeys.ALT | MetaKeys.SHIFT);
19361
19738
  const MoveSelectionWordRightShortcut = moveSelectionShortcut(Direction.RIGHT, "word", KeyCode.ARROW_RIGHT | MetaKeys.CTRL_COMMAND | MetaKeys.SHIFT, KeyCode.ARROW_RIGHT | MetaKeys.ALT | MetaKeys.SHIFT);
19739
+ const MoveCursorParagraphUpShortcut = moveCursorShortcut(Direction.UP, "paragraph", KeyCode.ARROW_UP | MetaKeys.CTRL_COMMAND, KeyCode.ARROW_UP | MetaKeys.ALT);
19740
+ const MoveCursorParagraphDownShortcut = moveCursorShortcut(Direction.DOWN, "paragraph", KeyCode.ARROW_DOWN | MetaKeys.CTRL_COMMAND, KeyCode.ARROW_DOWN | MetaKeys.ALT);
19741
+ const MoveSelectionParagraphUpShortcut = moveSelectionShortcut(Direction.UP, "paragraph", KeyCode.ARROW_UP | MetaKeys.CTRL_COMMAND | MetaKeys.SHIFT, KeyCode.ARROW_UP | MetaKeys.ALT | MetaKeys.SHIFT);
19742
+ const MoveSelectionParagraphDownShortcut = moveSelectionShortcut(Direction.DOWN, "paragraph", KeyCode.ARROW_DOWN | MetaKeys.CTRL_COMMAND | MetaKeys.SHIFT, KeyCode.ARROW_DOWN | MetaKeys.ALT | MetaKeys.SHIFT);
19362
19743
  const SelectAllShortcut = {
19363
19744
  id: DocSelectAllCommand.id,
19364
19745
  binding: KeyCode.A | MetaKeys.CTRL_COMMAND,
@@ -19530,6 +19911,10 @@ let UniverDocsUIPlugin = class UniverDocsUIPlugin extends Plugin {
19530
19911
  MoveCursorLineEndShortcut,
19531
19912
  MoveSelectionLineStartShortcut,
19532
19913
  MoveSelectionLineEndShortcut,
19914
+ MoveCursorParagraphUpShortcut,
19915
+ MoveCursorParagraphDownShortcut,
19916
+ MoveSelectionParagraphUpShortcut,
19917
+ MoveSelectionParagraphDownShortcut,
19533
19918
  MoveCursorDocumentStartShortcut,
19534
19919
  MoveCursorDocumentEndShortcut,
19535
19920
  MoveSelectionDocumentStartShortcut,
@@ -19567,6 +19952,7 @@ let UniverDocsUIPlugin = class UniverDocsUIPlugin extends Plugin {
19567
19952
  [DocParagraphSettingController],
19568
19953
  [IEditorService, { useClass: EditorService }],
19569
19954
  [IDocClipboardService, { useClass: DocClipboardService }],
19955
+ [DocHtmlExportService],
19570
19956
  [DocCanvasPopManagerService],
19571
19957
  [DocsRenderService],
19572
19958
  [IDocStateChangeInterceptorService, { useClass: DocIMEStateChangeInterceptorService }],
@@ -20189,4 +20575,4 @@ const RichTextEditor = (props) => {
20189
20575
  };
20190
20576
 
20191
20577
  //#endregion
20192
- export { AfterSpaceCommand, AlignCenterCommand, AlignJustifyCommand, AlignLeftCommand, AlignMenuItemFactory, AlignOperationCommand, AlignRightCommand, BackgroundColorSelectorMenuItemFactory, BoldMenuItemFactory, BreakLineCommand, BulletListCommand, ChangeListNestingLevelCommand, ChangeListNestingLevelType, ChangeListTypeCommand, CheckListCommand, CoverContentCommand, CreateDocTableCommand, CutContentCommand, DEFAULT_DOC_FIT_TO_WIDTH_OPTIONS, DOCS_COMPONENT_BACKGROUND_LAYER_INDEX, DOCS_COMPONENT_DEFAULT_Z_INDEX, DOCS_COMPONENT_HEADER_LAYER_INDEX, DOCS_COMPONENT_MAIN_LAYER_INDEX, DOCS_VIEW_KEY, DOC_CONTENT_INSERT_MENU_ID, DOC_PARAGRAPH_T_ALIGN_MENU_ID, DOC_PARAGRAPH_T_COLORS_MENU_ID, DOC_PARAGRAPH_T_DIVIDER_MENU_ID, DOC_PARAGRAPH_T_EDIT_MENU_ID, DOC_PARAGRAPH_T_INSERT_BELOW_MENU_ID, DOC_PARAGRAPH_T_INSERT_MENU_ID, DOC_TABLE_BLOCK_MENU_ID, DOC_VERTICAL_PADDING, DeleteCustomBlockCommand, DeleteLeftCommand, DeleteRightCommand, DocAutoFormatService, DocBackScrollRenderController, DocCanvasPopManagerService, DocCopyCommand, DocCreateTableOperation, DocCutCommand, DocEventManagerService, DocIMEInputManagerService, DocParagraphMenuService, DocParagraphPlaceholderRenderController, DocPasteCommand, DocPrintInterceptorService, DocRenderController, DocSelectAllCommand, DocSelectionRenderService, DocTableDeleteColumnsCommand, DocTableDeleteRowsCommand, DocTableDeleteTableCommand, DocTableInsertColumnCommand, DocTableInsertColumnLeftCommand, DocTableInsertColumnRightCommand, DocTableInsertRowAboveCommand, DocTableInsertRowBellowCommand, DocTableInsertRowCommand, DocTableTabCommand, DocUIController, DocViewScaleService, DocsRenderService, menuSchema as DocsUIMenuSchema, EMPTY_PARAGRAPH_MENU_ID, Editor, EditorService, EnterCommand, FLOAT_TEXT_STYLE_MENU_ID, FLOAT_TOOLBAR_MENU_POSITION, FloatTextStyleMenuItemFactory, FontFamilySelectorMenuItemFactory, FontSizeSelectorMenuItemFactory, HorizontalLineCommand, IDocClipboardService, IEditorService, IMEInputCommand, INSERT_BELLOW_MENU_ID, InnerPasteCommand, InsertCustomRangeCommand, ItalicMenuItemFactory, ListOperationCommand, MergeTwoParagraphCommand, MoveCursorOperation, MoveDocBlockCommand, MoveSelectionOperation, NORMAL_TEXT_SELECTION_PLUGIN_NAME, NodePositionConvertToCursor, NodePositionConvertToRectRange, OrderListCommand, ParagraphMenuInsertBelowSubmenuItemFactory, LarkPastePlugin as PastePluginLark, UniverPastePlugin as PastePluginUniver, WordPastePlugin as PastePluginWord, QuickListCommand, RectRange, ReplaceContentCommand, ReplaceSelectionCommand, ReplaceSnapshotCommand, ReplaceTextRunsCommand, ResetInlineFormatTextBackgroundColorCommand, ResetInlineFormatTextColorCommand, RichTextEditor, SetDocZoomRatioCommand, SetDocZoomRatioOperation, SetInlineFormatBoldCommand, SetInlineFormatCommand, SetInlineFormatFontFamilyCommand, SetInlineFormatFontSizeCommand, SetInlineFormatItalicCommand, SetInlineFormatStrikethroughCommand, SetInlineFormatSubscriptCommand, SetInlineFormatSuperscriptCommand, SetInlineFormatTextBackgroundColorCommand, SetInlineFormatTextColorCommand, SetInlineFormatTextFillCommand, SetInlineFormatUnderlineCommand, SetParagraphNamedStyleCommand, StrikeThroughMenuItemFactory, SwitchDocModeCommand, TEXT_RANGE_LAYER_INDEX, TabCommand, TextColorSelectorMenuItemFactory, TextRange, ToggleCheckListCommand, UnderlineMenuItemFactory, UniverDocsUIPlugin, VIEWPORT_KEY, addCustomDecorationBySelectionFactory, addCustomDecorationFactory, buildMoveDocBlockActions, calcDocFitToWidthScale, calcDocRangePositions, convertBodyToHtml, convertPositionsToRectRanges, createEditorUndoRedoKeyboardConfig, deleteCustomDecorationFactory, docDrawingPositionToTransform, executeEditorUndoRedoCommand, genTableSource, generateParagraphs, getAnchorBounding, getCanvasOffsetByEngine, getCommandSkeleton, getCursorWhenDelete, getCustomBlockIdsInSelections, getCutActionsFromDocRanges, getDocBlockRangeMenuId, getDocObject, getDocObjectById, getEmptyTableCell, getEmptyTableRow, getLineBounding, getListMarkerFallbackBound, getListParagraphContextMenuHit, getOneTextSelectionRange, getStyleInTextRange, getTableColumn, hasParagraphInTable, hideMenuWhenSelectionInBlockRange, isInSameTableCell, isTextRangeInAnyBlockRange, isValidRectRange, neoGetDocObject, normalizeDocFitToWidthOptions, resolveDocFitBaseWidth, resolveDocViewScale, transformToDocDrawingPosition, useEditor, useEditorClickOutside, useIsFocusing, useKeyboardEvent, useLeftAndRightArrow, useOnChange, useResize, whenDocAndEditorFocused };
20578
+ export { AfterSpaceCommand, AlignCenterCommand, AlignJustifyCommand, AlignLeftCommand, AlignMenuItemFactory, AlignOperationCommand, AlignRightCommand, BackgroundColorSelectorMenuItemFactory, BoldMenuItemFactory, BreakLineCommand, BulletListCommand, ChangeListNestingLevelCommand, ChangeListNestingLevelType, ChangeListTypeCommand, CheckListCommand, CoverContentCommand, CreateDocTableCommand, CutContentCommand, DEFAULT_DOC_FIT_TO_WIDTH_OPTIONS, DOCS_COMPONENT_BACKGROUND_LAYER_INDEX, DOCS_COMPONENT_DEFAULT_Z_INDEX, DOCS_COMPONENT_HEADER_LAYER_INDEX, DOCS_COMPONENT_MAIN_LAYER_INDEX, DOCS_VIEW_KEY, DOC_CONTENT_INSERT_MENU_ID, DOC_PARAGRAPH_T_ALIGN_MENU_ID, DOC_PARAGRAPH_T_COLORS_MENU_ID, DOC_PARAGRAPH_T_DIVIDER_MENU_ID, DOC_PARAGRAPH_T_EDIT_MENU_ID, DOC_PARAGRAPH_T_INSERT_BELOW_MENU_ID, DOC_PARAGRAPH_T_INSERT_MENU_ID, DOC_TABLE_BLOCK_MENU_ID, DOC_VERTICAL_PADDING, DeleteCustomBlockCommand, DeleteLeftCommand, DeleteRightCommand, DocAutoFormatService, DocBackScrollRenderController, DocCanvasPopManagerService, DocCopyCommand, DocCreateTableOperation, DocCutCommand, DocEventManagerService, DocHtmlExportService, DocIMEInputManagerService, DocParagraphMenuService, DocParagraphPlaceholderRenderController, DocPasteCommand, DocPrintInterceptorService, DocRenderController, DocSelectAllCommand, DocSelectionRenderService, DocTableDeleteColumnsCommand, DocTableDeleteRowsCommand, DocTableDeleteTableCommand, DocTableInsertColumnCommand, DocTableInsertColumnLeftCommand, DocTableInsertColumnRightCommand, DocTableInsertRowAboveCommand, DocTableInsertRowBellowCommand, DocTableInsertRowCommand, DocTableTabCommand, DocUIController, DocViewScaleService, DocsRenderService, menuSchema as DocsUIMenuSchema, EMPTY_PARAGRAPH_MENU_ID, Editor, EditorService, EnterCommand, FLOAT_TEXT_STYLE_MENU_ID, FLOAT_TOOLBAR_MENU_POSITION, FloatTextStyleMenuItemFactory, FontFamilySelectorMenuItemFactory, FontSizeSelectorMenuItemFactory, HorizontalLineCommand, IDocClipboardService, IEditorService, IMEInputCommand, INSERT_BELLOW_MENU_ID, InnerPasteCommand, InsertCustomRangeCommand, ItalicMenuItemFactory, ListOperationCommand, MergeTwoParagraphCommand, MoveCursorOperation, MoveDocBlockCommand, MoveSelectionOperation, NORMAL_TEXT_SELECTION_PLUGIN_NAME, NodePositionConvertToCursor, NodePositionConvertToRectRange, OrderListCommand, ParagraphMenuInsertBelowSubmenuItemFactory, LarkPastePlugin as PastePluginLark, UniverPastePlugin as PastePluginUniver, WordPastePlugin as PastePluginWord, QuickListCommand, RectRange, ReplaceContentCommand, ReplaceSelectionCommand, ReplaceSnapshotCommand, ReplaceTextRunsCommand, ResetInlineFormatTextBackgroundColorCommand, ResetInlineFormatTextColorCommand, RichTextEditor, SetDocZoomRatioCommand, SetDocZoomRatioOperation, SetInlineFormatBoldCommand, SetInlineFormatCommand, SetInlineFormatFontFamilyCommand, SetInlineFormatFontSizeCommand, SetInlineFormatItalicCommand, SetInlineFormatStrikethroughCommand, SetInlineFormatSubscriptCommand, SetInlineFormatSuperscriptCommand, SetInlineFormatTextBackgroundColorCommand, SetInlineFormatTextColorCommand, SetInlineFormatTextFillCommand, SetInlineFormatUnderlineCommand, SetParagraphNamedStyleCommand, StrikeThroughMenuItemFactory, SwitchDocModeCommand, TEXT_RANGE_LAYER_INDEX, TabCommand, TextColorSelectorMenuItemFactory, TextRange, ToggleCheckListCommand, UnderlineMenuItemFactory, UniverDocsUIPlugin, VIEWPORT_KEY, addCustomDecorationBySelectionFactory, addCustomDecorationFactory, buildMoveDocBlockActions, calcDocFitToWidthScale, calcDocRangePositions, convertBodyToHtml, convertPositionsToRectRanges, createEditorUndoRedoKeyboardConfig, deleteCustomDecorationFactory, docDrawingPositionToTransform, executeEditorUndoRedoCommand, genTableSource, generateParagraphs, getAnchorBounding, getCanvasOffsetByEngine, getCommandSkeleton, getCursorWhenDelete, getCustomBlockIdsInSelections, getCutActionsFromDocRanges, getDocBlockRangeMenuId, getDocObject, getDocObjectById, getEmptyTableCell, getEmptyTableRow, getLineBounding, getListMarkerFallbackBound, getListParagraphContextMenuHit, getOneTextSelectionRange, getStyleInTextRange, getTableColumn, hasParagraphInTable, hideMenuWhenSelectionInBlockRange, isInSameTableCell, isTextRangeInAnyBlockRange, isValidRectRange, neoGetDocObject, normalizeDocFitToWidthOptions, resolveDocFitBaseWidth, resolveDocViewScale, transformToDocDrawingPosition, useEditor, useEditorClickOutside, useIsFocusing, useKeyboardEvent, useLeftAndRightArrow, useOnChange, useResize, whenDocAndEditorFocused };