@univerjs/docs-ui 0.4.1 → 0.4.2-nightly.202410301606

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/lib/core-editing.command-DAmOCaTR.mjs +1905 -0
  2. package/lib/es/facade.js +109 -0
  3. package/lib/es/index.js +577 -2416
  4. package/lib/locale/en-US.js +85 -0
  5. package/lib/locale/fa-IR.js +85 -0
  6. package/lib/locale/ru-RU.js +85 -0
  7. package/lib/locale/vi-VN.js +85 -0
  8. package/lib/locale/zh-CN.js +85 -0
  9. package/lib/locale/zh-TW.js +85 -0
  10. package/lib/types/basics/paragraph.d.ts +85 -1
  11. package/lib/types/commands/commands/doc-header-footer.command.d.ts +4 -0
  12. package/lib/types/commands/commands/paragraph-align.command.d.ts +1 -1
  13. package/lib/types/commands/commands/switch-doc-mode.command.d.ts +4 -0
  14. package/lib/types/controllers/doc-header-footer.controller.d.ts +2 -0
  15. package/lib/types/controllers/menu/menu.d.ts +1 -0
  16. package/lib/types/controllers/render-controllers/doc-ime-input.controller.d.ts +5 -5
  17. package/lib/types/controllers/render-controllers/doc-input.controller.d.ts +5 -3
  18. package/lib/types/controllers/render-controllers/doc.render-controller.d.ts +2 -3
  19. package/lib/types/controllers/render-controllers/zoom.render-controller.d.ts +2 -2
  20. package/lib/types/facade/f-document.d.ts +34 -0
  21. package/lib/types/facade/f-univer.d.ts +34 -0
  22. package/lib/types/facade/index.d.ts +1 -0
  23. package/lib/types/index.d.ts +2 -4
  24. package/lib/types/locale/zh-CN.d.ts +1 -0
  25. package/lib/types/services/doc-auto-format.service.d.ts +2 -2
  26. package/lib/types/services/doc-event-manager.service.d.ts +2 -2
  27. package/lib/types/services/doc-ime-input-manager.service.d.ts +1 -1
  28. package/lib/types/services/doc-menu-style.service.d.ts +12 -0
  29. package/lib/types/services/doc-state-change-manager.service.d.ts +10 -0
  30. package/lib/types/services/editor/editor-manager.service.d.ts +63 -0
  31. package/lib/types/services/selection/text-range.d.ts +2 -2
  32. package/lib/types/views/doc-container/DocContainer.d.ts +1 -1
  33. package/lib/umd/facade.js +19 -0
  34. package/lib/umd/index.js +14 -14
  35. package/lib/umd/locale/en-US.js +1 -0
  36. package/lib/umd/locale/fa-IR.js +1 -0
  37. package/lib/umd/locale/ru-RU.js +1 -0
  38. package/lib/umd/locale/vi-VN.js +1 -0
  39. package/lib/umd/locale/zh-CN.js +1 -0
  40. package/lib/umd/locale/zh-TW.js +1 -0
  41. package/package.json +23 -21
  42. package/LICENSE +0 -176
  43. package/lib/cjs/index.js +0 -37
  44. package/lib/locale/en-US.json +0 -81
  45. package/lib/locale/fa-IR.json +0 -81
  46. package/lib/locale/ru-RU.json +0 -81
  47. package/lib/locale/vi-VN.json +0 -81
  48. package/lib/locale/zh-CN.json +0 -81
  49. package/lib/locale/zh-TW.json +0 -81
  50. package/lib/types/basics/custom-range-factory.d.ts +0 -25
  51. package/lib/types/basics/replace.d.ts +0 -20
  52. /package/lib/types/commands/commands/{delete.command.d.ts → doc-delete.command.d.ts} +0 -0
@@ -0,0 +1,1905 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value;
3
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: !0 });
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key != "symbol" ? key + "" : key, value);
5
+ import { Tools, DOC_RANGE_TYPE, RANGE_DIRECTION, COLORS, BooleanNumber, Rectangle, Inject, RxDisposable, UniverInstanceType, DataStreamTreeTokenType, ILogService, IUniverInstanceService, CommandType, ICommandService, BuildTextUtils, TextX, JSONX, TextXActionType } from "@univerjs/core";
6
+ import { DocSkeletonManagerService, DocSelectionManagerService, RichTextEditingMutation } from "@univerjs/docs";
7
+ import { IRenderManagerService, Liquid, GlyphType, DocumentSkeletonPageType, getPageFromPath, getTableIdAndSliceIndex, NORMAL_TEXT_SELECTION_PLUGIN_STYLE, getColor, RegularPolygon, Rect, getOffsetRectForDom, ScrollTimer, CURSOR_TYPE, getSystemHighlightColor, Vector2, PageLayoutType } from "@univerjs/engine-render";
8
+ import { ILayoutService } from "@univerjs/ui";
9
+ import { Subject, BehaviorSubject, takeUntil, fromEvent } from "rxjs";
10
+ function getCommandSkeleton(accessor, unitId) {
11
+ var _a2;
12
+ return (_a2 = accessor.get(IRenderManagerService).getRenderById(unitId)) == null ? void 0 : _a2.with(DocSkeletonManagerService);
13
+ }
14
+ __name(getCommandSkeleton, "getCommandSkeleton");
15
+ function getRichTextEditPath(docDataModel, segmentId = "") {
16
+ if (!segmentId)
17
+ return ["body"];
18
+ const { headers, footers } = docDataModel.getSnapshot();
19
+ if (headers == null && footers == null)
20
+ throw new Error("Document data model must have headers or footers when update by segment id");
21
+ if ((headers == null ? void 0 : headers[segmentId]) != null)
22
+ return ["headers", segmentId, "body"];
23
+ if ((footers == null ? void 0 : footers[segmentId]) != null)
24
+ return ["footers", segmentId, "body"];
25
+ throw new Error("Segment id not found in headers or footers");
26
+ }
27
+ __name(getRichTextEditPath, "getRichTextEditPath");
28
+ var NodePositionType = /* @__PURE__ */ ((NodePositionType2) => (NodePositionType2[NodePositionType2.page = 0] = "page", NodePositionType2[NodePositionType2.section = 1] = "section", NodePositionType2[NodePositionType2.column = 2] = "column", NodePositionType2[NodePositionType2.line = 3] = "line", NodePositionType2[NodePositionType2.divide = 4] = "divide", NodePositionType2[NodePositionType2.glyph = 5] = "glyph", NodePositionType2))(NodePositionType || {});
29
+ const NodePositionMap = {
30
+ page: 0,
31
+ section: 1,
32
+ column: 2,
33
+ line: 3,
34
+ divide: 4,
35
+ glyph: 5
36
+ };
37
+ function compareNodePositionLogic(pos1, pos2) {
38
+ return pos1.page > pos2.page ? !1 : pos1.page < pos2.page ? !0 : pos1.section > pos2.section ? !1 : pos1.section < pos2.section ? !0 : pos1.column > pos2.column ? !1 : pos1.column < pos2.column ? !0 : pos1.line > pos2.line ? !1 : pos1.line < pos2.line ? !0 : pos1.divide > pos2.divide ? !1 : pos1.divide < pos2.divide ? !0 : pos1.glyph > pos2.glyph ? !1 : (pos1.glyph < pos2.glyph, !0);
39
+ }
40
+ __name(compareNodePositionLogic, "compareNodePositionLogic");
41
+ function compareNodePosition(pos1, pos2) {
42
+ return compareNodePositionLogic(pos1, pos2) ? {
43
+ start: pos1,
44
+ end: pos2
45
+ } : {
46
+ start: pos2,
47
+ end: pos1
48
+ };
49
+ }
50
+ __name(compareNodePosition, "compareNodePosition");
51
+ function getOneTextSelectionRange(rangeList) {
52
+ const rangeCount = rangeList.length;
53
+ if (rangeCount === 0)
54
+ return;
55
+ const firstCursor = rangeList[0], lastCursor = rangeList[rangeCount - 1], collapsed = rangeList.length === 1 && firstCursor.collapsed;
56
+ return {
57
+ startOffset: firstCursor.startOffset,
58
+ endOffset: lastCursor.endOffset,
59
+ collapsed
60
+ };
61
+ }
62
+ __name(getOneTextSelectionRange, "getOneTextSelectionRange");
63
+ function getOffsetInDivide(glyphGroup, startGlyphIndex, endGlyphIndex, st) {
64
+ let startOffset = st, endOffset = st;
65
+ for (let i = 0; i < glyphGroup.length; i++) {
66
+ const contentLength = glyphGroup[i].count;
67
+ i < startGlyphIndex && (startOffset += contentLength), i < endGlyphIndex && (endOffset += contentLength);
68
+ }
69
+ return {
70
+ startOffset,
71
+ endOffset
72
+ };
73
+ }
74
+ __name(getOffsetInDivide, "getOffsetInDivide");
75
+ function pushToPoints(position) {
76
+ const { startX, startY, endX, endY } = position, points = [];
77
+ return points.push({
78
+ x: startX,
79
+ y: startY
80
+ }), points.push({
81
+ x: endX,
82
+ y: startY
83
+ }), points.push({
84
+ x: endX,
85
+ y: endY
86
+ }), points.push({
87
+ x: startX,
88
+ y: endY
89
+ }), points.push({
90
+ x: startX,
91
+ y: startY
92
+ }), points;
93
+ }
94
+ __name(pushToPoints, "pushToPoints");
95
+ const _NodePositionConvertToCursor = class _NodePositionConvertToCursor {
96
+ constructor(_documentOffsetConfig, _docSkeleton) {
97
+ __publicField(this, "_liquid", new Liquid());
98
+ __publicField(this, "_currentStartState", {
99
+ page: 0,
100
+ section: 0,
101
+ column: 0,
102
+ line: 0,
103
+ divide: 0,
104
+ glyph: 0
105
+ /* NORMAL */
106
+ });
107
+ __publicField(this, "_currentEndState", {
108
+ page: 0,
109
+ section: 0,
110
+ column: 0,
111
+ line: 0,
112
+ divide: 0,
113
+ glyph: 0
114
+ /* NORMAL */
115
+ });
116
+ this._documentOffsetConfig = _documentOffsetConfig, this._docSkeleton = _docSkeleton;
117
+ }
118
+ // eslint-disable-next-line max-lines-per-function
119
+ getRangePointData(startOrigin, endOrigin) {
120
+ const borderBoxPointGroup = [], contentBoxPointGroup = [], cursorList = [];
121
+ if (startOrigin == null || endOrigin == null)
122
+ return {
123
+ borderBoxPointGroup,
124
+ contentBoxPointGroup,
125
+ cursorList
126
+ };
127
+ if (!this._isValidPosition(startOrigin, endOrigin))
128
+ throw new Error(
129
+ `
130
+ Invalid positions in NodePositionConvertToCursor,
131
+ they are not in the same segment page when in header or footer.`
132
+ );
133
+ const { start, end } = compareNodePosition(startOrigin, endOrigin);
134
+ return this._selectionIterator(start, end, (start_sp, end_sp, isFirst, isLast, divide, line) => {
135
+ const { lineHeight, asc, paddingTop, marginTop, marginBottom } = line, { glyphGroup, st } = divide;
136
+ if (glyphGroup.length === 0)
137
+ return;
138
+ const { x: startX, y: startY } = this._liquid;
139
+ let borderBoxPosition, contentBoxPosition;
140
+ const firstGlyph = glyphGroup[start_sp], lastGlyph = glyphGroup[end_sp], preGlyph = glyphGroup[start_sp - 1], firstGlyphLeft = (firstGlyph == null ? void 0 : firstGlyph.left) || 0, firstGlyphWidth = (firstGlyph == null ? void 0 : firstGlyph.width) || 0, lastGlyphLeft = (lastGlyph == null ? void 0 : lastGlyph.left) || 0, lastGlyphWidth = (lastGlyph == null ? void 0 : lastGlyph.width) || 0, isCurrentList = (firstGlyph == null ? void 0 : firstGlyph.glyphType) === GlyphType.LIST, { startOffset, endOffset } = getOffsetInDivide(glyphGroup, start_sp, end_sp, st), isStartBack = start.glyph === start_sp && isFirst ? start.isBack : !0, isEndBack = end.glyph === end_sp && isLast ? end.isBack : !1, collapsed = start === end, anchorGlyph = isStartBack && preGlyph != null ? preGlyph : firstGlyph;
141
+ if (start_sp === 0 && end_sp === glyphGroup.length - 1)
142
+ borderBoxPosition = {
143
+ startX: startX + firstGlyphLeft + (isCurrentList ? firstGlyphWidth : 0),
144
+ startY,
145
+ endX: startX + lastGlyphLeft + (isEndBack ? 0 : lastGlyphWidth),
146
+ endY: startY + lineHeight - marginTop - marginBottom
147
+ }, contentBoxPosition = {
148
+ startX: startX + firstGlyphLeft + (isCurrentList ? firstGlyphWidth : 0),
149
+ startY: startY + paddingTop + asc - anchorGlyph.bBox.ba,
150
+ endX: startX + lastGlyphLeft + (isEndBack ? 0 : lastGlyphWidth),
151
+ endY: startY + paddingTop + asc + anchorGlyph.bBox.bd
152
+ };
153
+ else {
154
+ const isStartBackFin = isStartBack && !isCurrentList;
155
+ borderBoxPosition = {
156
+ startX: startX + firstGlyphLeft + (isStartBackFin ? 0 : firstGlyphWidth),
157
+ startY,
158
+ endX: startX + lastGlyphLeft + (isEndBack ? 0 : lastGlyphWidth),
159
+ endY: startY + lineHeight - marginTop - marginBottom
160
+ }, contentBoxPosition = {
161
+ startX: startX + firstGlyphLeft + (isStartBackFin ? 0 : firstGlyphWidth),
162
+ startY: startY + paddingTop + asc - anchorGlyph.bBox.ba,
163
+ endX: startX + lastGlyphLeft + (isEndBack ? 0 : lastGlyphWidth),
164
+ endY: startY + paddingTop + asc + anchorGlyph.bBox.bd
165
+ };
166
+ }
167
+ borderBoxPointGroup.push(pushToPoints(borderBoxPosition)), contentBoxPointGroup.push(pushToPoints(contentBoxPosition)), cursorList.push({
168
+ startOffset: isStartBack ? startOffset : startOffset + firstGlyph.count,
169
+ endOffset: isEndBack ? endOffset : endOffset + lastGlyph.count,
170
+ collapsed
171
+ });
172
+ }), {
173
+ borderBoxPointGroup,
174
+ contentBoxPointGroup,
175
+ cursorList
176
+ };
177
+ }
178
+ _isValidPosition(startOrigin, endOrigin) {
179
+ const { segmentPage: startPage, pageType: startPageType } = startOrigin, { segmentPage: endPage, pageType: endPageType } = endOrigin;
180
+ return startPageType !== endPageType ? !1 : startPageType === DocumentSkeletonPageType.HEADER || startPageType === DocumentSkeletonPageType.FOOTER ? startPage === endPage : !0;
181
+ }
182
+ _resetCurrentNodePositionState() {
183
+ this._currentStartState = {
184
+ page: 0,
185
+ section: 0,
186
+ column: 0,
187
+ line: 0,
188
+ divide: 0,
189
+ glyph: 0
190
+ /* NORMAL */
191
+ }, this._currentEndState = {
192
+ page: 0,
193
+ section: 0,
194
+ column: 0,
195
+ line: 0,
196
+ divide: 0,
197
+ glyph: 0
198
+ /* NORMAL */
199
+ };
200
+ }
201
+ _setNodePositionState(type = 0, start, end, current) {
202
+ current === start ? this._currentStartState[type] = 1 : this._currentStartState[type] = 0, current === end ? this._currentEndState[type] = 2 : this._currentEndState[type] = 0;
203
+ }
204
+ _checkPreviousNodePositionState(typeIndex, isStart = !0) {
205
+ let index = typeIndex, resultState;
206
+ for (; index >= 0; ) {
207
+ const type = NodePositionType[index];
208
+ let state;
209
+ if (isStart ? state = this._currentStartState[type] : state = this._currentEndState[type], state === void 0)
210
+ return;
211
+ if (resultState === void 0 && (resultState = state), state !== resultState)
212
+ return 0;
213
+ index--;
214
+ }
215
+ return resultState;
216
+ }
217
+ _getSelectionRuler(typeIndex, startPosition, endPosition, nextLength, current) {
218
+ let start_next = 0, end_next = nextLength;
219
+ const type = NodePositionType[typeIndex], nextType = NodePositionType[typeIndex + 1];
220
+ if (nextType === null || type === null)
221
+ return {
222
+ start_next,
223
+ end_next
224
+ };
225
+ const start = startPosition[type], end = endPosition[type];
226
+ this._setNodePositionState(type, start, end, current);
227
+ const preStartNestType = this._checkPreviousNodePositionState(typeIndex), preEndNestType = this._checkPreviousNodePositionState(typeIndex, !1);
228
+ return preStartNestType === 1 && (start_next = startPosition[nextType]), preEndNestType === 2 && (end_next = endPosition[nextType]), {
229
+ start_next,
230
+ end_next
231
+ };
232
+ }
233
+ // eslint-disable-next-line max-lines-per-function, complexity
234
+ _selectionIterator(startPosition, endPosition, func) {
235
+ var _a2, _b;
236
+ const skeleton = this._docSkeleton;
237
+ if (!skeleton)
238
+ return [];
239
+ const { pageType, path } = startPosition;
240
+ this._liquid.reset();
241
+ const skeletonData = skeleton.getSkeletonData();
242
+ if (skeletonData == null)
243
+ return [];
244
+ const { pages, skeHeaders, skeFooters } = skeletonData, { page: pageIndex, segmentPage } = startPosition, { page: endPageIndex, segmentPage: endSegmentPage } = endPosition;
245
+ if (this._resetCurrentNodePositionState(), this._documentOffsetConfig == null)
246
+ return [];
247
+ const { pageLayoutType, pageMarginLeft, pageMarginTop } = this._documentOffsetConfig, skipPageIndex = pageType === DocumentSkeletonPageType.BODY || pageType === DocumentSkeletonPageType.CELL ? pageIndex : segmentPage;
248
+ for (let p = 0; p < skipPageIndex; p++) {
249
+ const page = pages[p];
250
+ this._liquid.translatePage(page, pageLayoutType, pageMarginLeft, pageMarginTop);
251
+ }
252
+ const endIndex = pageType === DocumentSkeletonPageType.BODY || pageType === DocumentSkeletonPageType.CELL ? endPageIndex : endSegmentPage;
253
+ for (let p = skipPageIndex; p <= endIndex; p++) {
254
+ const page = pages[p], { headerId, footerId, pageWidth } = page;
255
+ let segmentPage2 = page;
256
+ if (pageType === DocumentSkeletonPageType.HEADER ? segmentPage2 = (_a2 = skeHeaders.get(headerId)) == null ? void 0 : _a2.get(pageWidth) : pageType === DocumentSkeletonPageType.FOOTER ? segmentPage2 = (_b = skeFooters.get(footerId)) == null ? void 0 : _b.get(pageWidth) : pageType === DocumentSkeletonPageType.CELL && (segmentPage2 = getPageFromPath(skeletonData, path)), segmentPage2 == null) {
257
+ this._liquid.translatePage(page, pageLayoutType, pageMarginLeft, pageMarginTop);
258
+ continue;
259
+ }
260
+ const sections = segmentPage2.sections, { start_next: start_s, end_next: end_s } = this._getSelectionRuler(
261
+ NodePositionMap.page,
262
+ startPosition,
263
+ endPosition,
264
+ sections.length - 1,
265
+ pageType === DocumentSkeletonPageType.BODY || pageType === DocumentSkeletonPageType.CELL ? p : 0
266
+ );
267
+ switch (this._liquid.translateSave(), pageType) {
268
+ case DocumentSkeletonPageType.HEADER:
269
+ this._liquid.translatePagePadding({
270
+ ...segmentPage2,
271
+ marginLeft: page.marginLeft
272
+ // Because header or footer margin Left is 0.
273
+ });
274
+ break;
275
+ case DocumentSkeletonPageType.FOOTER: {
276
+ const footerTop = page.pageHeight - segmentPage2.height - segmentPage2.marginBottom;
277
+ this._liquid.translate(page.marginLeft, footerTop);
278
+ break;
279
+ }
280
+ case DocumentSkeletonPageType.CELL: {
281
+ this._liquid.translatePagePadding(page);
282
+ const rowSke = segmentPage2.parent, tableSke = rowSke.parent, { left: cellLeft } = segmentPage2, { top: tableTop, left: tableLeft } = tableSke, { top: rowTop } = rowSke;
283
+ this._liquid.translate(tableLeft + cellLeft, tableTop + rowTop), this._liquid.translatePagePadding(segmentPage2);
284
+ break;
285
+ }
286
+ default:
287
+ this._liquid.translatePagePadding(page);
288
+ break;
289
+ }
290
+ for (let s = start_s; s <= end_s; s++) {
291
+ const section = sections[s], columns = section.columns, { start_next: start_c, end_next: end_c } = this._getSelectionRuler(
292
+ NodePositionMap.section,
293
+ startPosition,
294
+ endPosition,
295
+ columns.length - 1,
296
+ s
297
+ );
298
+ this._liquid.translateSection(section);
299
+ for (let c = start_c; c <= end_c; c++) {
300
+ const column = columns[c], lines = column.lines, { start_next: start_l, end_next: end_l } = this._getSelectionRuler(
301
+ NodePositionMap.column,
302
+ startPosition,
303
+ endPosition,
304
+ lines.length - 1,
305
+ c
306
+ );
307
+ this._liquid.translateColumn(column);
308
+ for (let l = start_l; l <= end_l; l++) {
309
+ const line = lines[l], { divides } = line, { start_next: start_d, end_next: end_d } = this._getSelectionRuler(
310
+ NodePositionMap.line,
311
+ startPosition,
312
+ endPosition,
313
+ divides.length - 1,
314
+ l
315
+ );
316
+ this._liquid.translateSave(), this._liquid.translateLine(line, !0, !1);
317
+ for (let d = start_d; d <= end_d; d++) {
318
+ const divide = divides[d];
319
+ this._liquid.translateSave(), this._liquid.translateDivide(divide);
320
+ const { glyphGroup } = divide, { start_next: start_sp, end_next: end_sp } = this._getSelectionRuler(
321
+ NodePositionMap.divide,
322
+ startPosition,
323
+ endPosition,
324
+ glyphGroup.length - 1,
325
+ d
326
+ );
327
+ let isFirst = !1, isLast = !1;
328
+ p === skipPageIndex && s === start_s && c === start_c && l === start_l && d === start_d && (isFirst = !0), p === endIndex && s === end_s && c === end_c && l === end_l && d === end_d && (isLast = !0), func && func(start_sp, end_sp, isFirst, isLast, divide, line, column, section, segmentPage2), this._liquid.translateRestore();
329
+ }
330
+ this._liquid.translateRestore();
331
+ }
332
+ }
333
+ }
334
+ this._liquid.translateRestore(), this._liquid.translatePage(page, pageLayoutType, pageMarginLeft, pageMarginTop);
335
+ }
336
+ }
337
+ };
338
+ __name(_NodePositionConvertToCursor, "NodePositionConvertToCursor");
339
+ let NodePositionConvertToCursor = _NodePositionConvertToCursor;
340
+ function isValidRectRange(anchorNodePosition, focusNodePosition) {
341
+ const { path: anchorPath } = anchorNodePosition, { path: focusPath } = focusNodePosition;
342
+ if (anchorPath.length !== focusPath.length || anchorPath.indexOf("cells") === -1)
343
+ return !1;
344
+ const tableIdIndex = anchorPath.indexOf("skeTables") + 1, rowIndex = anchorPath.indexOf("rows") + 1, cellIndex = anchorPath.indexOf("cells") + 1, anchorTableId = getTableIdAndSliceIndex(anchorPath[tableIdIndex]).tableId, focusTableId = getTableIdAndSliceIndex(focusPath[tableIdIndex]).tableId;
345
+ if (anchorTableId !== focusTableId)
346
+ return !1;
347
+ const anchorRowIndex = anchorPath[rowIndex], focusRowIndex = focusPath[rowIndex], anchorCellIndex = anchorPath[cellIndex], focusCellIndex = focusPath[cellIndex];
348
+ return !(anchorRowIndex === focusRowIndex && anchorCellIndex === focusCellIndex);
349
+ }
350
+ __name(isValidRectRange, "isValidRectRange");
351
+ function isInSameTableCell(anchorNodePosition, focusNodePosition) {
352
+ const { path: anchorPath } = anchorNodePosition, { path: focusPath } = focusNodePosition;
353
+ return anchorPath.indexOf("cells") === -1 || focusPath.indexOf("cells") === -1 ? !1 : Tools.diffValue(anchorPath, focusPath);
354
+ }
355
+ __name(isInSameTableCell, "isInSameTableCell");
356
+ function compareNodePositionInTable(a, b) {
357
+ if (isInSameTableCell(a, b))
358
+ return compareNodePositionLogic(a, b);
359
+ const { path: aPath } = a, { path: bPath } = b, aTableId = aPath[aPath.length - 5], bTableId = bPath[bPath.length - 5];
360
+ if (aTableId !== bTableId && typeof aTableId == "string" && typeof bTableId == "string") {
361
+ const aSlideId = aTableId.split("#-#")[1], bSlideId = bTableId.split("#-#")[1];
362
+ return +aSlideId < +bSlideId;
363
+ }
364
+ const aRowCount = aPath[aPath.length - 3], bRowCount = bPath[bPath.length - 3], aCellCount = aPath[aPath.length - 1], bCellCount = bPath[bPath.length - 1];
365
+ return aRowCount < bRowCount ? !0 : aRowCount > bRowCount ? !1 : aCellCount <= bCellCount;
366
+ }
367
+ __name(compareNodePositionInTable, "compareNodePositionInTable");
368
+ function firstGlyphInCellPage(cellPage) {
369
+ return cellPage.sections[0].columns[0].lines[0].divides[0].glyphGroup[0];
370
+ }
371
+ __name(firstGlyphInCellPage, "firstGlyphInCellPage");
372
+ function lastGlyphInCellPage(cellPage) {
373
+ const { sections } = cellPage, lastSection = sections[sections.length - 1], lastColumn = lastSection.columns[lastSection.columns.length - 1], lastLine = lastColumn.lines[lastColumn.lines.length - 1], lastGlyphGroup = lastLine.divides[lastLine.divides.length - 1].glyphGroup;
374
+ return lastGlyphGroup[lastGlyphGroup.length - 2];
375
+ }
376
+ __name(lastGlyphInCellPage, "lastGlyphInCellPage");
377
+ const _NodePositionConvertToRectRange = class _NodePositionConvertToRectRange {
378
+ constructor(_documentOffsetConfig, _docSkeleton) {
379
+ __publicField(this, "_liquid", new Liquid());
380
+ this._documentOffsetConfig = _documentOffsetConfig, this._docSkeleton = _docSkeleton;
381
+ }
382
+ // eslint-disable-next-line max-lines-per-function
383
+ getRangePointData(startNodePosition, endNodePosition) {
384
+ const pointGroup = [], skeletonData = this._docSkeleton.getSkeletonData();
385
+ if (skeletonData == null)
386
+ return;
387
+ const { pages } = skeletonData, { segmentPage: startSegmentPage, page: startPage, pageType } = startNodePosition, { segmentPage: endSegmentPage, page: endPage } = endNodePosition, rectInfo = this._getTableRectRangeInfo(startNodePosition, endNodePosition);
388
+ if (rectInfo == null)
389
+ return;
390
+ const {
391
+ tableId,
392
+ startRowIndex: startRow,
393
+ startColumnIndex: startColumn,
394
+ endRowIndex: endRow,
395
+ endColumnIndex: endColumn
396
+ } = rectInfo;
397
+ this._liquid.reset();
398
+ const { pageLayoutType, pageMarginLeft, pageMarginTop } = this._documentOffsetConfig, skipPageIndex = pageType === DocumentSkeletonPageType.BODY || pageType === DocumentSkeletonPageType.CELL ? startPage : startSegmentPage;
399
+ for (let p = 0; p < skipPageIndex; p++) {
400
+ const page = pages[p];
401
+ this._liquid.translatePage(page, pageLayoutType, pageMarginLeft, pageMarginTop);
402
+ }
403
+ const endIndex = pageType === DocumentSkeletonPageType.BODY || pageType === DocumentSkeletonPageType.CELL ? endPage : endSegmentPage;
404
+ for (let p = skipPageIndex; p <= endIndex; p++) {
405
+ const page = pages[p];
406
+ this._liquid.translatePagePadding(page);
407
+ const { skeTables } = page;
408
+ let table = null;
409
+ for (const [id, tableSke] of skeTables.entries())
410
+ id.startsWith(tableId) && (table = tableSke);
411
+ if (table == null) {
412
+ this._liquid.restorePagePadding(page), this._liquid.translatePage(page, pageLayoutType, pageMarginLeft, pageMarginTop);
413
+ continue;
414
+ }
415
+ this._liquid.translateSave(), this._liquid.translate(0, table.top);
416
+ const { x, y } = this._liquid;
417
+ for (const row of table.rows)
418
+ if (row.index >= startRow && row.index <= endRow) {
419
+ const rowStartCell = row.cells[startColumn], rowEndCell = row.cells[endColumn], position = {
420
+ startX: x + rowStartCell.left,
421
+ startY: y + row.top,
422
+ endX: x + rowEndCell.left + rowEndCell.pageWidth,
423
+ endY: y + row.top + row.height
424
+ };
425
+ pointGroup.push(pushToPoints(position));
426
+ }
427
+ this._liquid.translateRestore(), this._liquid.restorePagePadding(page), this._liquid.translatePage(page, pageLayoutType, pageMarginLeft, pageMarginTop);
428
+ }
429
+ return {
430
+ pointGroup,
431
+ startRow,
432
+ startColumn,
433
+ endRow,
434
+ endColumn,
435
+ tableId
436
+ };
437
+ }
438
+ getNodePositionGroup(anchorNodePosition, focusNodePosition) {
439
+ const nodePositionGroup = [], compare = compareNodePositionInTable(anchorNodePosition, focusNodePosition), startNodePosition = compare ? anchorNodePosition : focusNodePosition, endNodePosition = compare ? focusNodePosition : anchorNodePosition, { segmentPage } = startNodePosition, rectInfo = this._getTableRectRangeInfo(startNodePosition, endNodePosition);
440
+ if (rectInfo == null)
441
+ return;
442
+ const { tableId, pages, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex } = rectInfo, tables = [];
443
+ for (const page of pages) {
444
+ const { skeTables } = page;
445
+ for (const [id, table] of skeTables.entries())
446
+ id.startsWith(tableId) && tables.push(table);
447
+ }
448
+ if (tables.length === 0)
449
+ return;
450
+ for (const table of tables)
451
+ this._collectPositionGroup(table, nodePositionGroup, startRowIndex, endRowIndex, startColumnIndex, endColumnIndex, segmentPage, compare);
452
+ const totalColumns = tables[0].rows[0].cells.length;
453
+ if (startColumnIndex === 0 && endColumnIndex === totalColumns - 1) {
454
+ const firstPosition = nodePositionGroup[0], lastPosition = nodePositionGroup[nodePositionGroup.length - 1];
455
+ nodePositionGroup.length = 0, nodePositionGroup.push({
456
+ anchor: compare ? firstPosition.anchor : lastPosition.anchor,
457
+ focus: compare ? lastPosition.focus : firstPosition.focus
458
+ });
459
+ }
460
+ return nodePositionGroup;
461
+ }
462
+ _collectPositionGroup(table, nodePositionGroup, startRowIndex, endRowIndex, startColumnIndex, endColumnIndex, segmentPage, compare) {
463
+ for (let i = 0; i < table.rows.length; i++) {
464
+ const row = table.rows[i];
465
+ if (row.index < startRowIndex)
466
+ continue;
467
+ if (row.index > endRowIndex)
468
+ break;
469
+ const startCellInRow = row.cells[startColumnIndex], endCellInRow = row.cells[endColumnIndex], startCellGlyph = firstGlyphInCellPage(startCellInRow), endCellGlyph = lastGlyphInCellPage(endCellInRow);
470
+ if (startCellGlyph == null || endCellGlyph == null)
471
+ continue;
472
+ const startPosition = this._docSkeleton.findPositionByGlyph(startCellGlyph, segmentPage), endPosition = this._docSkeleton.findPositionByGlyph(endCellGlyph, segmentPage);
473
+ if (startPosition == null || endPosition == null)
474
+ continue;
475
+ const anchor = compare ? startPosition : endPosition, focus = compare ? endPosition : startPosition;
476
+ nodePositionGroup.push({
477
+ anchor: {
478
+ ...anchor,
479
+ isBack: !0
480
+ // true or false is the same.
481
+ },
482
+ focus: {
483
+ ...focus,
484
+ isBack: !0
485
+ }
486
+ });
487
+ }
488
+ }
489
+ _getTableRectRangeInfo(startNodePosition, endNodePosition) {
490
+ const skeletonData = this._docSkeleton.getSkeletonData();
491
+ if (skeletonData == null)
492
+ return;
493
+ const { pages } = skeletonData, { path: startPath } = startNodePosition, { path: endPath } = endNodePosition, startCell = getPageFromPath(skeletonData, startPath), endCell = getPageFromPath(skeletonData, endPath);
494
+ if (startCell == null || endCell == null)
495
+ return;
496
+ const tableId = startCell.segmentId, startRow = startCell.parent.index, startColumn = startCell.parent.cells.indexOf(startCell), endRow = (endCell == null ? void 0 : endCell.parent).index, endColumn = (endCell == null ? void 0 : endCell.parent).cells.indexOf(endCell);
497
+ return {
498
+ pages,
499
+ tableId,
500
+ startCell,
501
+ endCell,
502
+ startRowIndex: startRow,
503
+ startColumnIndex: startColumn,
504
+ endRowIndex: endRow,
505
+ endColumnIndex: endColumn
506
+ };
507
+ }
508
+ };
509
+ __name(_NodePositionConvertToRectRange, "NodePositionConvertToRectRange");
510
+ let NodePositionConvertToRectRange = _NodePositionConvertToRectRange;
511
+ const TEXT_RANGE_KEY_PREFIX = "__TestSelectionRange__", TEXT_ANCHOR_KEY_PREFIX = "__TestSelectionAnchor__", ID_LENGTH$1 = 6, BLINK_ON = 500, BLINK_OFF = 500, TEXT_RANGE_LAYER_INDEX = 3;
512
+ function getAnchorBounding(pointsGroup) {
513
+ const points = pointsGroup[0], startPoint = points[0], endPoint = points[2], { x: startX, y: startY } = startPoint, { x: endX, y: endY } = endPoint;
514
+ return {
515
+ left: startX,
516
+ top: startY,
517
+ width: endX - startX,
518
+ height: endY - startY
519
+ };
520
+ }
521
+ __name(getAnchorBounding, "getAnchorBounding");
522
+ function getLineBounding(pointsGroup) {
523
+ return pointsGroup.map((line) => {
524
+ let xMin = 1 / 0, xMax = -1 / 0, yMin = 1 / 0, yMax = -1 / 0;
525
+ return line.forEach((point) => {
526
+ xMin = Math.min(point.x, xMin), xMax = Math.max(point.x, xMax), yMax = Math.max(point.y, yMax), yMin = Math.min(point.y, yMin);
527
+ }), {
528
+ left: xMin,
529
+ right: xMax,
530
+ top: yMin,
531
+ bottom: yMax
532
+ };
533
+ });
534
+ }
535
+ __name(getLineBounding, "getLineBounding");
536
+ const _TextRange = class _TextRange {
537
+ constructor(_scene, _document, _docSkeleton, anchorNodePosition, focusNodePosition, style = NORMAL_TEXT_SELECTION_PLUGIN_STYLE, _segmentId = "", _segmentPage = -1) {
538
+ __publicField(this, "rangeType", DOC_RANGE_TYPE.TEXT);
539
+ // Identifies whether the range is the current one, most of which is the last range.
540
+ __publicField(this, "_current", !1);
541
+ // The rendered range graphic when collapsed is false
542
+ __publicField(this, "_rangeShape");
543
+ // The rendered range graphic when collapsed is true
544
+ __publicField(this, "_anchorShape");
545
+ __publicField(this, "_cursorList", []);
546
+ __publicField(this, "_anchorBlinkTimer", null);
547
+ this._scene = _scene, this._document = _document, this._docSkeleton = _docSkeleton, this.anchorNodePosition = anchorNodePosition, this.focusNodePosition = focusNodePosition, this.style = style, this._segmentId = _segmentId, this._segmentPage = _segmentPage, this._anchorBlink(), this.refresh();
548
+ }
549
+ _anchorBlink() {
550
+ setTimeout(() => {
551
+ this._anchorShape && this._anchorShape.visible && this.deactivateStatic();
552
+ }, BLINK_ON), this._anchorBlinkTimer = setInterval(() => {
553
+ this._anchorShape && this._anchorShape.visible && (this.activeStatic(), setTimeout(() => {
554
+ this.deactivateStatic();
555
+ }, BLINK_ON));
556
+ }, BLINK_OFF + BLINK_ON);
557
+ }
558
+ // The start position of the range
559
+ get startOffset() {
560
+ var _a2;
561
+ const { startOffset } = (_a2 = getOneTextSelectionRange(this._cursorList)) != null ? _a2 : {}, body = this._docSkeleton.getViewModel().getDataModel().getSelfOrHeaderFooterModel(this._segmentId).getBody();
562
+ if (startOffset == null || body == null)
563
+ return startOffset;
564
+ const maxLength = body.dataStream.length - 2;
565
+ return Math.min(maxLength, startOffset);
566
+ }
567
+ // The end position of the range
568
+ get endOffset() {
569
+ var _a2;
570
+ const { endOffset } = (_a2 = getOneTextSelectionRange(this._cursorList)) != null ? _a2 : {}, body = this._docSkeleton.getViewModel().getDataModel().getSelfOrHeaderFooterModel(this._segmentId).getBody();
571
+ if (endOffset == null || body == null)
572
+ return endOffset;
573
+ const maxLength = body.dataStream.length - 2;
574
+ return Math.min(endOffset, maxLength);
575
+ }
576
+ get collapsed() {
577
+ const { startOffset, endOffset } = this;
578
+ return startOffset != null && startOffset === endOffset;
579
+ }
580
+ get startNodePosition() {
581
+ if (this.anchorNodePosition == null)
582
+ return null;
583
+ if (this.focusNodePosition == null)
584
+ return this.anchorNodePosition;
585
+ const { start } = compareNodePosition(this.anchorNodePosition, this.focusNodePosition);
586
+ return start;
587
+ }
588
+ get endNodePosition() {
589
+ if (this.anchorNodePosition == null)
590
+ return this.focusNodePosition;
591
+ if (this.focusNodePosition == null)
592
+ return null;
593
+ const { end } = compareNodePosition(this.anchorNodePosition, this.focusNodePosition);
594
+ return end;
595
+ }
596
+ get direction() {
597
+ const { collapsed, anchorNodePosition, focusNodePosition } = this;
598
+ return collapsed || anchorNodePosition == null || focusNodePosition == null ? RANGE_DIRECTION.NONE : compareNodePositionLogic(anchorNodePosition, focusNodePosition) ? RANGE_DIRECTION.FORWARD : RANGE_DIRECTION.BACKWARD;
599
+ }
600
+ get segmentId() {
601
+ return this._segmentId;
602
+ }
603
+ get segmentPage() {
604
+ return this._segmentPage;
605
+ }
606
+ getAbsolutePosition() {
607
+ const anchor = this.anchorNodePosition, focus = this.focusNodePosition;
608
+ if (this._isEmpty())
609
+ return;
610
+ const documentOffsetConfig = this._document.getOffsetConfig(), { docsLeft, docsTop } = documentOffsetConfig, convertor = new NodePositionConvertToCursor(documentOffsetConfig, this._docSkeleton);
611
+ if (this._isCollapsed()) {
612
+ const { contentBoxPointGroup, cursorList: cursorList2 } = convertor.getRangePointData(anchor, anchor);
613
+ if (this._setCursorList(cursorList2), contentBoxPointGroup.length === 0)
614
+ return;
615
+ const pos2 = getAnchorBounding(contentBoxPointGroup);
616
+ return {
617
+ ...pos2,
618
+ left: pos2.left + docsLeft,
619
+ top: pos2.top + docsTop
620
+ };
621
+ }
622
+ const { borderBoxPointGroup, cursorList } = convertor.getRangePointData(anchor, focus);
623
+ if (this._setCursorList(cursorList), borderBoxPointGroup.length === 0)
624
+ return;
625
+ const pos = getAnchorBounding(borderBoxPointGroup);
626
+ return {
627
+ ...pos,
628
+ left: pos.left + docsLeft,
629
+ top: pos.top + docsTop
630
+ };
631
+ }
632
+ getAnchor() {
633
+ return this._anchorShape;
634
+ }
635
+ activeStatic() {
636
+ var _a2, _b;
637
+ (_b = this._anchorShape) == null || _b.setProps({
638
+ stroke: ((_a2 = this.style) == null ? void 0 : _a2.strokeActive) || getColor(COLORS.black, 1)
639
+ });
640
+ }
641
+ deactivateStatic() {
642
+ var _a2, _b;
643
+ (_b = this._anchorShape) == null || _b.setProps({
644
+ stroke: ((_a2 = this.style) == null ? void 0 : _a2.stroke) || getColor(COLORS.black, 0)
645
+ });
646
+ }
647
+ isActive() {
648
+ return this._current === !0;
649
+ }
650
+ activate() {
651
+ this._current = !0;
652
+ }
653
+ deactivate() {
654
+ this._current = !1;
655
+ }
656
+ dispose() {
657
+ var _a2, _b;
658
+ (_a2 = this._rangeShape) == null || _a2.dispose(), this._rangeShape = null, (_b = this._anchorShape) == null || _b.dispose(), this._anchorShape = null, this._anchorBlinkTimer && (clearInterval(this._anchorBlinkTimer), this._anchorBlinkTimer = null);
659
+ }
660
+ isIntersection(compareRange) {
661
+ const { startOffset: activeStart, endOffset: activeEnd } = this, { startOffset: compareStart, endOffset: compareEnd } = compareRange;
662
+ return activeStart == null || activeEnd == null || compareStart == null || compareEnd == null ? !1 : activeStart <= compareEnd && activeEnd >= compareStart;
663
+ }
664
+ // render cursor and selection.
665
+ refresh() {
666
+ var _a2, _b;
667
+ const { _document, _docSkeleton } = this, anchor = this.anchorNodePosition, focus = this.focusNodePosition;
668
+ if ((_a2 = this._anchorShape) == null || _a2.hide(), (_b = this._rangeShape) == null || _b.hide(), this._isEmpty())
669
+ return;
670
+ const documentOffsetConfig = _document.getOffsetConfig(), { docsLeft, docsTop } = documentOffsetConfig, convertor = new NodePositionConvertToCursor(documentOffsetConfig, _docSkeleton);
671
+ if (this._isCollapsed()) {
672
+ const { contentBoxPointGroup, cursorList: cursorList2 } = convertor.getRangePointData(anchor, anchor);
673
+ if (this._setCursorList(cursorList2), contentBoxPointGroup.length > 0) {
674
+ const glyphAtCursor = _docSkeleton.findGlyphByPosition(anchor);
675
+ this._createOrUpdateAnchor(contentBoxPointGroup, docsLeft, docsTop, glyphAtCursor);
676
+ }
677
+ return;
678
+ }
679
+ const { borderBoxPointGroup, cursorList } = convertor.getRangePointData(anchor, focus);
680
+ this._setCursorList(cursorList), borderBoxPointGroup.length > 0 && this._createOrUpdateRange(borderBoxPointGroup, docsLeft, docsTop);
681
+ }
682
+ _isEmpty() {
683
+ return this.anchorNodePosition == null && this.focusNodePosition == null;
684
+ }
685
+ _isCollapsed() {
686
+ const anchor = this.anchorNodePosition, focus = this.focusNodePosition;
687
+ if (anchor != null && focus == null)
688
+ return !0;
689
+ if (anchor == null || focus == null)
690
+ return !1;
691
+ const keys = Object.keys(NodePositionMap);
692
+ for (const key of keys) {
693
+ const startNodeValue = anchor[key], endNodeValue = focus[key];
694
+ if (startNodeValue !== endNodeValue)
695
+ return !1;
696
+ }
697
+ return anchor.isBack === focus.isBack;
698
+ }
699
+ _createOrUpdateRange(pointsGroup, left, top) {
700
+ var _a2;
701
+ if (this._rangeShape) {
702
+ this._rangeShape.translate(left, top), this._rangeShape.updatePointGroup(pointsGroup), this._rangeShape.show();
703
+ return;
704
+ }
705
+ const OPACITY = 0.3, polygon = new RegularPolygon(TEXT_RANGE_KEY_PREFIX + Tools.generateRandomId(ID_LENGTH$1), {
706
+ pointsGroup,
707
+ fill: ((_a2 = this.style) == null ? void 0 : _a2.fill) || getColor(COLORS.black, OPACITY),
708
+ left,
709
+ top,
710
+ evented: !1,
711
+ debounceParentDirty: !1
712
+ });
713
+ this._rangeShape = polygon, this._scene.addObject(polygon, TEXT_RANGE_LAYER_INDEX);
714
+ }
715
+ _createOrUpdateAnchor(pointsGroup, docsLeft, docsTop, glyph) {
716
+ var _a2, _b, _c;
717
+ const bounding = getAnchorBounding(pointsGroup), { left: boundingLeft } = bounding;
718
+ let { top: boundingTop, height } = bounding;
719
+ const MIN_CURSOR_HEIGHT = 14;
720
+ height < MIN_CURSOR_HEIGHT && (boundingTop -= MIN_CURSOR_HEIGHT - height, height = MIN_CURSOR_HEIGHT);
721
+ const ITALIC_DEGREE = 12;
722
+ let left = boundingLeft + docsLeft;
723
+ const top = boundingTop + docsTop, isItalic = ((_a2 = glyph == null ? void 0 : glyph.ts) == null ? void 0 : _a2.it) === BooleanNumber.TRUE;
724
+ if (isItalic && (left += height * Math.tan(ITALIC_DEGREE * Math.PI / 180) / 2), this._anchorShape) {
725
+ this._anchorShape.transformByState({ left, top, height }), this._anchorShape.show(), isItalic ? this._anchorShape.skew(-ITALIC_DEGREE, 0) : this._anchorShape.skew(0, 0);
726
+ return;
727
+ }
728
+ const anchor = new Rect(TEXT_ANCHOR_KEY_PREFIX + Tools.generateRandomId(ID_LENGTH$1), {
729
+ left,
730
+ top,
731
+ height,
732
+ strokeWidth: ((_b = this.style) == null ? void 0 : _b.strokeWidth) || 1.5,
733
+ stroke: ((_c = this.style) == null ? void 0 : _c.strokeActive) || getColor(COLORS.black, 1),
734
+ evented: !1
735
+ });
736
+ isItalic && anchor.skew(-ITALIC_DEGREE, 0), this._anchorShape = anchor, this._scene.addObject(anchor, TEXT_RANGE_LAYER_INDEX);
737
+ }
738
+ _setCursorList(cursorList) {
739
+ cursorList.length !== 0 && (this._cursorList = cursorList);
740
+ }
741
+ };
742
+ __name(_TextRange, "TextRange");
743
+ let TextRange = _TextRange;
744
+ const RECT_RANGE_KEY_PREFIX = "__DocTableRectRange__", ID_LENGTH = 6;
745
+ function convertPositionsToRectRanges(scene, document2, docSkeleton, anchorNodePosition, focusNodePosition, style = NORMAL_TEXT_SELECTION_PLUGIN_STYLE, segmentId = "", segmentPage = -1) {
746
+ const documentOffsetConfig = document2.getOffsetConfig(), nodePositionGroup = new NodePositionConvertToRectRange(documentOffsetConfig, docSkeleton).getNodePositionGroup(anchorNodePosition, focusNodePosition);
747
+ return (nodePositionGroup != null ? nodePositionGroup : []).map((position) => new RectRange(
748
+ scene,
749
+ document2,
750
+ docSkeleton,
751
+ position.anchor,
752
+ position.focus,
753
+ style,
754
+ segmentId,
755
+ segmentPage
756
+ ));
757
+ }
758
+ __name(convertPositionsToRectRanges, "convertPositionsToRectRanges");
759
+ const _RectRange = class _RectRange {
760
+ constructor(_scene, _document, _docSkeleton, anchorNodePosition, focusNodePosition, style = NORMAL_TEXT_SELECTION_PLUGIN_STYLE, _segmentId = "", _segmentPage = -1) {
761
+ __publicField(this, "rangeType", DOC_RANGE_TYPE.RECT);
762
+ // The rendered rect range
763
+ __publicField(this, "_rangeShape");
764
+ // Identifies whether the range is the current one, most of which is the last range.
765
+ __publicField(this, "_current", !1);
766
+ // Rect Range start row.
767
+ __publicField(this, "_startRow");
768
+ // Rect Range start column.
769
+ __publicField(this, "_startCol");
770
+ // Rect Range end row.
771
+ __publicField(this, "_endRow");
772
+ // Rect Range end column.
773
+ __publicField(this, "_endCol");
774
+ // table id in view model.
775
+ __publicField(this, "_tableId");
776
+ this._scene = _scene, this._document = _document, this._docSkeleton = _docSkeleton, this.anchorNodePosition = anchorNodePosition, this.focusNodePosition = focusNodePosition, this.style = style, this._segmentId = _segmentId, this._segmentPage = _segmentPage, this.refresh();
777
+ }
778
+ get startOffset() {
779
+ const { startNodePosition } = this;
780
+ return this._docSkeleton.findCharIndexByPosition(startNodePosition);
781
+ }
782
+ get endOffset() {
783
+ const { endNodePosition } = this;
784
+ return this._docSkeleton.findCharIndexByPosition(endNodePosition);
785
+ }
786
+ get collapsed() {
787
+ return !1;
788
+ }
789
+ get startRow() {
790
+ return this._startRow;
791
+ }
792
+ get startColumn() {
793
+ return this._startCol;
794
+ }
795
+ get endRow() {
796
+ return this._endRow;
797
+ }
798
+ get endColumn() {
799
+ return this._endCol;
800
+ }
801
+ get tableId() {
802
+ return this._tableId;
803
+ }
804
+ get segmentId() {
805
+ return this._segmentId;
806
+ }
807
+ get segmentPage() {
808
+ return this._segmentPage;
809
+ }
810
+ get spanEntireRow() {
811
+ var _a2;
812
+ const table = (_a2 = this._docSkeleton.getViewModel().getSnapshot().tableSource) == null ? void 0 : _a2[this._tableId], { _startCol, _endCol } = this;
813
+ if (table == null)
814
+ throw new Error("Table is not found.");
815
+ const { tableColumns } = table;
816
+ return _startCol === 0 && _endCol === tableColumns.length - 1;
817
+ }
818
+ get spanEntireColumn() {
819
+ var _a2;
820
+ const table = (_a2 = this._docSkeleton.getViewModel().getSnapshot().tableSource) == null ? void 0 : _a2[this._tableId], { _startRow, _endRow } = this;
821
+ if (table == null)
822
+ throw new Error("Table is not found.");
823
+ const { tableRows } = table;
824
+ return _startRow === 0 && _endRow === tableRows.length - 1;
825
+ }
826
+ get spanEntireTable() {
827
+ return this.spanEntireRow && this.spanEntireColumn;
828
+ }
829
+ get startNodePosition() {
830
+ const { anchorNodePosition, focusNodePosition } = this;
831
+ return compareNodePositionInTable(anchorNodePosition, focusNodePosition) ? anchorNodePosition : focusNodePosition;
832
+ }
833
+ get endNodePosition() {
834
+ const { anchorNodePosition, focusNodePosition } = this;
835
+ return compareNodePositionInTable(anchorNodePosition, focusNodePosition) ? focusNodePosition : anchorNodePosition;
836
+ }
837
+ get direction() {
838
+ const { anchorNodePosition, focusNodePosition } = this;
839
+ return compareNodePositionInTable(anchorNodePosition, focusNodePosition) ? RANGE_DIRECTION.FORWARD : RANGE_DIRECTION.BACKWARD;
840
+ }
841
+ isActive() {
842
+ return this._current === !0;
843
+ }
844
+ activate() {
845
+ this._current = !0;
846
+ }
847
+ deactivate() {
848
+ this._current = !1;
849
+ }
850
+ dispose() {
851
+ var _a2;
852
+ (_a2 = this._rangeShape) == null || _a2.dispose(), this._rangeShape = null;
853
+ }
854
+ isIntersection(compareRange) {
855
+ const { startRow, startColumn, endRow, endColumn } = this, { startRow: cStartRow, startColumn: cStartColumn, endRow: cEndRow, endColumn: cEndColumn } = compareRange, rect1 = {
856
+ left: startColumn,
857
+ top: startRow,
858
+ right: endColumn,
859
+ bottom: endRow
860
+ }, rect2 = {
861
+ left: cStartColumn,
862
+ top: cStartRow,
863
+ right: cEndColumn,
864
+ bottom: cEndRow
865
+ };
866
+ return Rectangle.hasIntersectionBetweenTwoRect(rect1, rect2);
867
+ }
868
+ refresh() {
869
+ var _a2;
870
+ (_a2 = this._rangeShape) == null || _a2.hide();
871
+ const { startNodePosition, endNodePosition, _document, _docSkeleton } = this, documentOffsetConfig = _document.getOffsetConfig(), { docsLeft, docsTop } = documentOffsetConfig, rectInfo = new NodePositionConvertToRectRange(documentOffsetConfig, _docSkeleton).getRangePointData(startNodePosition, endNodePosition);
872
+ if (rectInfo == null)
873
+ return;
874
+ const { pointGroup = [], startRow, endRow, startColumn, endColumn, tableId } = rectInfo;
875
+ (pointGroup == null ? void 0 : pointGroup.length) > 0 && this._createOrUpdateRange(pointGroup, docsLeft, docsTop), this._updateTableInfo(startRow, endRow, startColumn, endColumn, tableId);
876
+ }
877
+ _updateTableInfo(startRow, endRow, startCol, endCol, tableId) {
878
+ this._startRow = startRow, this._endRow = endRow, this._startCol = startCol, this._endCol = endCol, this._tableId = tableId;
879
+ }
880
+ _createOrUpdateRange(pointsGroup, left, top) {
881
+ var _a2;
882
+ if (this._rangeShape) {
883
+ this._rangeShape.translate(left, top), this._rangeShape.updatePointGroup(pointsGroup), this._rangeShape.show();
884
+ return;
885
+ }
886
+ const OPACITY = 0.3, polygon = new RegularPolygon(RECT_RANGE_KEY_PREFIX + Tools.generateRandomId(ID_LENGTH), {
887
+ pointsGroup,
888
+ fill: ((_a2 = this.style) == null ? void 0 : _a2.fill) || getColor(COLORS.black, OPACITY),
889
+ left,
890
+ top,
891
+ evented: !1,
892
+ debounceParentDirty: !1
893
+ });
894
+ this._rangeShape = polygon, this._scene.addObject(polygon, TEXT_RANGE_LAYER_INDEX);
895
+ }
896
+ };
897
+ __name(_RectRange, "RectRange");
898
+ let RectRange = _RectRange;
899
+ function getTextRangeFromCharIndex(startOffset, endOffset, scene, document2, skeleton, style, segmentId, segmentPage, startIsBack = !0, endIsBack = !0) {
900
+ const startNodePosition = skeleton.findNodePositionByCharIndex(startOffset, startIsBack, segmentId, segmentPage), endNodePosition = skeleton.findNodePositionByCharIndex(endOffset, endIsBack, segmentId, segmentPage);
901
+ if (!(startNodePosition == null || endNodePosition == null))
902
+ return new TextRange(scene, document2, skeleton, startNodePosition, endNodePosition, style, segmentId, segmentPage);
903
+ }
904
+ __name(getTextRangeFromCharIndex, "getTextRangeFromCharIndex");
905
+ function getRectRangeFromCharIndex(startOffset, endOffset, scene, document2, skeleton, style, segmentId, segmentPage) {
906
+ const startNodePosition = skeleton.findNodePositionByCharIndex(startOffset, !0, segmentId, segmentPage), endNodePosition = skeleton.findNodePositionByCharIndex(endOffset, !0, segmentId, segmentPage);
907
+ if (!(startNodePosition == null || endNodePosition == null))
908
+ return new RectRange(scene, document2, skeleton, startNodePosition, endNodePosition, style, segmentId, segmentPage);
909
+ }
910
+ __name(getRectRangeFromCharIndex, "getRectRangeFromCharIndex");
911
+ function getRangeListFromCharIndex(startOffset, endOffset, scene, document2, skeleton, style, segmentId, segmentPage) {
912
+ const startNodePosition = skeleton.findNodePositionByCharIndex(startOffset, !0, segmentId, segmentPage), endNodePosition = skeleton.findNodePositionByCharIndex(endOffset, !0, segmentId, segmentPage);
913
+ if (!(startNodePosition == null || endNodePosition == null))
914
+ return getRangeListFromSelection(
915
+ startNodePosition,
916
+ endNodePosition,
917
+ scene,
918
+ document2,
919
+ skeleton,
920
+ style,
921
+ segmentId,
922
+ segmentPage
923
+ );
924
+ }
925
+ __name(getRangeListFromCharIndex, "getRangeListFromCharIndex");
926
+ function getRangeListFromSelection(anchorPosition, focusPosition, scene, document2, skeleton, style, segmentId, segmentPage) {
927
+ const textRanges = [], rectRanges = [], rangeParams = [scene, document2, skeleton, anchorPosition, focusPosition, style, segmentId, segmentPage];
928
+ if (isInSameTableCell(anchorPosition, focusPosition))
929
+ return textRanges.push(new TextRange(...rangeParams)), {
930
+ textRanges,
931
+ rectRanges
932
+ };
933
+ if (isValidRectRange(anchorPosition, focusPosition)) {
934
+ const ranges = convertPositionsToRectRanges(
935
+ ...rangeParams
936
+ );
937
+ return rectRanges.push(...ranges), {
938
+ textRanges,
939
+ rectRanges
940
+ };
941
+ }
942
+ const viewModel = skeleton.getViewModel().getSelfOrHeaderFooterViewModel(segmentId), anchorOffset = skeleton.findCharIndexByPosition(anchorPosition), focusOffset = skeleton.findCharIndexByPosition(focusPosition);
943
+ if (anchorOffset == null || focusOffset == null)
944
+ return;
945
+ const direction = anchorOffset <= focusOffset ? RANGE_DIRECTION.FORWARD : RANGE_DIRECTION.BACKWARD, startOffset = Math.min(anchorOffset, focusOffset), endOffset = Math.max(anchorOffset, focusOffset);
946
+ let start = startOffset, end = endOffset;
947
+ for (const section of viewModel.children)
948
+ for (const paragraph of section.children) {
949
+ const { startIndex, endIndex, children } = paragraph, table = children[0];
950
+ let endInTable = !1;
951
+ if (table) {
952
+ const { startIndex: tableStart, endIndex: tableEnd, children: children2 } = table;
953
+ let tableStartPosition = null, tableEndPosition = null;
954
+ const startRow = children2.find((row) => row.startIndex <= startOffset && row.endIndex >= startOffset), endRow = children2.find((row) => row.startIndex <= endOffset && row.endIndex >= endOffset);
955
+ if (startOffset > tableStart && startOffset < tableEnd)
956
+ tableStartPosition = skeleton.findNodePositionByCharIndex(startRow.startIndex + 2, !0, segmentId, segmentPage), tableEndPosition = skeleton.findNodePositionByCharIndex(tableEnd - 4, !0, segmentId, segmentPage), start = tableEnd + 1;
957
+ else if (endOffset > tableStart && endOffset < tableEnd)
958
+ tableStartPosition = skeleton.findNodePositionByCharIndex(tableStart + 3, !0, segmentId, segmentPage), tableEndPosition = skeleton.findNodePositionByCharIndex(endRow.endIndex - 3, !0, segmentId, segmentPage), end = tableStart - 1, endInTable = !0;
959
+ else if (tableStart > startOffset && tableEnd < endOffset) {
960
+ if (tableStartPosition = skeleton.findNodePositionByCharIndex(tableStart + 3, !0, segmentId, segmentPage), tableEndPosition = skeleton.findNodePositionByCharIndex(tableEnd - 4, !0, segmentId, segmentPage), start <= tableStart - 1) {
961
+ const sp = skeleton.findNodePositionByCharIndex(start, !0, segmentId, segmentPage), ep = skeleton.findNodePositionByCharIndex(tableStart - 1, !1, segmentId, segmentPage), ap = direction === RANGE_DIRECTION.FORWARD ? sp : ep, fp = direction === RANGE_DIRECTION.FORWARD ? ep : sp;
962
+ textRanges.push(new TextRange(scene, document2, skeleton, ap, fp, style, segmentId, segmentPage));
963
+ }
964
+ start = tableEnd + 1;
965
+ }
966
+ if (tableStartPosition && tableEndPosition) {
967
+ const ap = direction === RANGE_DIRECTION.FORWARD ? tableStartPosition : tableEndPosition, fp = direction === RANGE_DIRECTION.FORWARD ? tableEndPosition : tableStartPosition;
968
+ rectRanges.push(...convertPositionsToRectRanges(
969
+ scene,
970
+ document2,
971
+ skeleton,
972
+ ap,
973
+ fp,
974
+ style,
975
+ segmentId,
976
+ segmentPage
977
+ ));
978
+ }
979
+ }
980
+ if (end >= startIndex && end <= endIndex || endInTable) {
981
+ const sp = skeleton.findNodePositionByCharIndex(start, !0, segmentId, segmentPage), ep = skeleton.findNodePositionByCharIndex(end, !endInTable, segmentId, segmentPage), ap = direction === RANGE_DIRECTION.FORWARD ? sp : ep, fp = direction === RANGE_DIRECTION.FORWARD ? ep : sp;
982
+ if (rectRanges.length && Tools.diffValue(ap, fp))
983
+ continue;
984
+ textRanges.push(new TextRange(scene, document2, skeleton, ap, fp, style, segmentId, segmentPage));
985
+ }
986
+ }
987
+ return {
988
+ textRanges,
989
+ rectRanges
990
+ };
991
+ }
992
+ __name(getRangeListFromSelection, "getRangeListFromSelection");
993
+ function getCanvasOffsetByEngine(engine) {
994
+ const canvas = engine == null ? void 0 : engine.getCanvasElement();
995
+ if (!canvas)
996
+ return {
997
+ left: 0,
998
+ top: 0
999
+ };
1000
+ const { top, left } = getOffsetRectForDom(canvas);
1001
+ return {
1002
+ left,
1003
+ top
1004
+ };
1005
+ }
1006
+ __name(getCanvasOffsetByEngine, "getCanvasOffsetByEngine");
1007
+ function getParagraphInfoByGlyph(node) {
1008
+ var _a2;
1009
+ const line = (_a2 = node.parent) == null ? void 0 : _a2.parent, column = line == null ? void 0 : line.parent;
1010
+ if (line == null || column == null)
1011
+ return;
1012
+ const { paragraphIndex } = line, lines = column.lines.filter((line2) => line2.paragraphIndex === paragraphIndex);
1013
+ let nodeIndex = -1, content = "", hasFound = !1;
1014
+ for (const line2 of lines)
1015
+ for (const divide of line2.divides)
1016
+ for (const glyph of divide.glyphGroup)
1017
+ hasFound || (nodeIndex += glyph.count), glyph === node && (hasFound = !0), content += glyph.count > 0 ? glyph.content : "";
1018
+ return {
1019
+ st: lines[0].st,
1020
+ ed: paragraphIndex,
1021
+ content,
1022
+ nodeIndex
1023
+ };
1024
+ }
1025
+ __name(getParagraphInfoByGlyph, "getParagraphInfoByGlyph");
1026
+ function serializeTextRange(textRange) {
1027
+ const { startOffset, endOffset, collapsed, rangeType, startNodePosition, endNodePosition, direction, segmentId, segmentPage } = textRange;
1028
+ return {
1029
+ startOffset,
1030
+ endOffset,
1031
+ collapsed,
1032
+ rangeType,
1033
+ startNodePosition,
1034
+ endNodePosition,
1035
+ direction,
1036
+ segmentId,
1037
+ segmentPage,
1038
+ isActive: textRange.isActive()
1039
+ };
1040
+ }
1041
+ __name(serializeTextRange, "serializeTextRange");
1042
+ function serializeRectRange(rectRange) {
1043
+ const serializedTextRange = serializeTextRange(rectRange), {
1044
+ startRow,
1045
+ startColumn,
1046
+ endRow,
1047
+ endColumn,
1048
+ tableId,
1049
+ spanEntireRow,
1050
+ spanEntireColumn,
1051
+ spanEntireTable
1052
+ } = rectRange;
1053
+ return {
1054
+ ...serializedTextRange,
1055
+ startRow,
1056
+ startColumn,
1057
+ endRow,
1058
+ endColumn,
1059
+ tableId,
1060
+ spanEntireRow,
1061
+ spanEntireColumn,
1062
+ spanEntireTable
1063
+ };
1064
+ }
1065
+ __name(serializeRectRange, "serializeRectRange");
1066
+ var __defProp2 = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyDescriptor, __decorateClass = /* @__PURE__ */ __name((decorators, target, key, kind) => {
1067
+ for (var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target, i = decorators.length - 1, decorator; i >= 0; i--)
1068
+ (decorator = decorators[i]) && (result = (kind ? decorator(target, key, result) : decorator(result)) || result);
1069
+ return kind && result && __defProp2(target, key, result), result;
1070
+ }, "__decorateClass"), __decorateParam = /* @__PURE__ */ __name((index, decorator) => (target, key) => decorator(target, key, index), "__decorateParam"), _a;
1071
+ let DocSelectionRenderService = (_a = class extends RxDisposable {
1072
+ constructor(_context, _layoutService, _logService, _univerInstanceService, _docSkeletonManagerService) {
1073
+ super();
1074
+ __publicField(this, "_onInputBefore$", new Subject());
1075
+ __publicField(this, "onInputBefore$", this._onInputBefore$.asObservable());
1076
+ __publicField(this, "_onKeydown$", new Subject());
1077
+ __publicField(this, "onKeydown$", this._onKeydown$.asObservable());
1078
+ __publicField(this, "_onInput$", new Subject());
1079
+ __publicField(this, "onInput$", this._onInput$.asObservable());
1080
+ __publicField(this, "_onCompositionstart$", new BehaviorSubject(null));
1081
+ __publicField(this, "onCompositionstart$", this._onCompositionstart$.asObservable());
1082
+ __publicField(this, "_onCompositionupdate$", new BehaviorSubject(null));
1083
+ __publicField(this, "onCompositionupdate$", this._onCompositionupdate$.asObservable());
1084
+ __publicField(this, "_onCompositionend$", new BehaviorSubject(null));
1085
+ __publicField(this, "onCompositionend$", this._onCompositionend$.asObservable());
1086
+ __publicField(this, "_onSelectionStart$", new BehaviorSubject(null));
1087
+ __publicField(this, "onSelectionStart$", this._onSelectionStart$.asObservable());
1088
+ __publicField(this, "_onPaste$", new Subject());
1089
+ __publicField(this, "onPaste$", this._onPaste$.asObservable());
1090
+ __publicField(this, "_textSelectionInner$", new BehaviorSubject(null));
1091
+ __publicField(this, "textSelectionInner$", this._textSelectionInner$.asObservable());
1092
+ __publicField(this, "_onFocus$", new Subject());
1093
+ __publicField(this, "onFocus$", this._onFocus$.asObservable());
1094
+ __publicField(this, "_onBlur$", new Subject());
1095
+ __publicField(this, "onBlur$", this._onBlur$.asObservable());
1096
+ __publicField(this, "_onPointerDown$", new Subject());
1097
+ __publicField(this, "onPointerDown$", this._onPointerDown$.asObservable());
1098
+ __publicField(this, "_container");
1099
+ __publicField(this, "_inputParent");
1100
+ __publicField(this, "_input");
1101
+ __publicField(this, "_scrollTimers", []);
1102
+ __publicField(this, "_rangeList", []);
1103
+ // Use to cache range list in moving.
1104
+ __publicField(this, "_rangeListCache", []);
1105
+ // Rect range list.
1106
+ __publicField(this, "_rectRangeList", []);
1107
+ // Use to cache rect range list in moving.
1108
+ __publicField(this, "_rectRangeListCache", []);
1109
+ __publicField(this, "_anchorNodePosition", null);
1110
+ __publicField(this, "_focusNodePosition", null);
1111
+ __publicField(this, "_currentSegmentId", "");
1112
+ __publicField(this, "_currentSegmentPage", -1);
1113
+ __publicField(this, "_selectionStyle", NORMAL_TEXT_SELECTION_PLUGIN_STYLE);
1114
+ __publicField(this, "_viewPortObserverMap", /* @__PURE__ */ new Map());
1115
+ __publicField(this, "_isIMEInputApply", !1);
1116
+ __publicField(this, "_scenePointerMoveSubs", []);
1117
+ __publicField(this, "_scenePointerUpSubs", []);
1118
+ __publicField(this, "_editorFocusing", !0);
1119
+ // When the user switches editors, whether to clear the doc ranges.
1120
+ __publicField(this, "_reserveRanges", !1);
1121
+ this._context = _context, this._layoutService = _layoutService, this._logService = _logService, this._univerInstanceService = _univerInstanceService, this._docSkeletonManagerService = _docSkeletonManagerService, this._initDOM(), this._registerContainer(), this._setSystemHighlightColorToStyle(), this._listenCurrentUnitChange();
1122
+ }
1123
+ _listenCurrentUnitChange() {
1124
+ this._univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_DOC).pipe(takeUntil(this.dispose$)).subscribe((documentModel) => {
1125
+ if (documentModel == null)
1126
+ return;
1127
+ documentModel.getUnitId() !== this._context.unitId && !this._reserveRanges && this.removeAllRanges();
1128
+ });
1129
+ }
1130
+ get activeViewPort() {
1131
+ return this._context.scene.getViewports()[0];
1132
+ }
1133
+ setSegment(id) {
1134
+ this._currentSegmentId = id;
1135
+ }
1136
+ getSegment() {
1137
+ return this._currentSegmentId;
1138
+ }
1139
+ setSegmentPage(pageIndex) {
1140
+ this._currentSegmentPage = pageIndex;
1141
+ }
1142
+ getSegmentPage() {
1143
+ return this._currentSegmentPage;
1144
+ }
1145
+ setReserveRangesStatus(status) {
1146
+ this._reserveRanges = status;
1147
+ }
1148
+ _setRangeStyle(style = NORMAL_TEXT_SELECTION_PLUGIN_STYLE) {
1149
+ this._selectionStyle = style;
1150
+ }
1151
+ // eslint-disable-next-line max-lines-per-function
1152
+ addDocRanges(ranges, isEditing = !0, options) {
1153
+ const {
1154
+ _currentSegmentId: segmentId,
1155
+ _currentSegmentPage: segmentPage,
1156
+ _selectionStyle: style
1157
+ } = this, { scene, mainComponent } = this._context, document2 = mainComponent, docSkeleton = this._docSkeletonManagerService.getSkeleton();
1158
+ for (const range of ranges) {
1159
+ const { startOffset, endOffset, rangeType, startNodePosition, endNodePosition } = range;
1160
+ if (rangeType === DOC_RANGE_TYPE.RECT) {
1161
+ const rectRange = getRectRangeFromCharIndex(
1162
+ startOffset,
1163
+ endOffset,
1164
+ scene,
1165
+ document2,
1166
+ docSkeleton,
1167
+ style,
1168
+ segmentId,
1169
+ segmentPage
1170
+ );
1171
+ rectRange && this._addRectRanges([rectRange]);
1172
+ } else if (rangeType === DOC_RANGE_TYPE.TEXT) {
1173
+ let textRange = null;
1174
+ startNodePosition && endNodePosition ? textRange = getTextRangeFromCharIndex(
1175
+ startNodePosition.isBack ? startOffset : startOffset - 1,
1176
+ endNodePosition.isBack ? endOffset : endOffset - 1,
1177
+ scene,
1178
+ document2,
1179
+ docSkeleton,
1180
+ style,
1181
+ segmentId,
1182
+ segmentPage,
1183
+ startNodePosition.isBack,
1184
+ endNodePosition.isBack
1185
+ ) : textRange = getTextRangeFromCharIndex(
1186
+ startOffset,
1187
+ endOffset,
1188
+ scene,
1189
+ document2,
1190
+ docSkeleton,
1191
+ style,
1192
+ segmentId,
1193
+ segmentPage
1194
+ ), textRange && this._addTextRange(textRange);
1195
+ } else {
1196
+ const rangeList = getRangeListFromCharIndex(
1197
+ startOffset,
1198
+ endOffset,
1199
+ scene,
1200
+ document2,
1201
+ docSkeleton,
1202
+ style,
1203
+ segmentId,
1204
+ segmentPage
1205
+ );
1206
+ if (rangeList == null)
1207
+ continue;
1208
+ const { textRanges, rectRanges } = rangeList;
1209
+ for (const textRange of textRanges)
1210
+ this._addTextRange(textRange);
1211
+ this._addRectRanges(rectRanges);
1212
+ }
1213
+ }
1214
+ this._textSelectionInner$.next({
1215
+ textRanges: this._getAllTextRanges(),
1216
+ rectRanges: this._getAllRectRanges(),
1217
+ segmentId,
1218
+ segmentPage,
1219
+ style,
1220
+ isEditing,
1221
+ options
1222
+ }), this._updateInputPosition(options == null ? void 0 : options.forceFocus);
1223
+ }
1224
+ setCursorManually(evtOffsetX, evtOffsetY) {
1225
+ const startNode = this._findNodeByCoord(evtOffsetX, evtOffsetY, {
1226
+ strict: !0,
1227
+ segmentId: this._currentSegmentId,
1228
+ segmentPage: this._currentSegmentPage
1229
+ }), position = this._getNodePosition(startNode);
1230
+ if (position == null) {
1231
+ this._removeAllRanges();
1232
+ return;
1233
+ }
1234
+ (startNode == null ? void 0 : startNode.node.streamType) === DataStreamTreeTokenType.PARAGRAPH && (position.isBack = !0), this._createTextRangeByAnchorPosition(position), this._textSelectionInner$.next({
1235
+ textRanges: this._getAllTextRanges(),
1236
+ rectRanges: this._getAllRectRanges(),
1237
+ segmentId: this._currentSegmentId,
1238
+ segmentPage: this._currentSegmentPage,
1239
+ style: this._selectionStyle,
1240
+ isEditing: !1
1241
+ });
1242
+ }
1243
+ // Sync canvas selection to dom selection.
1244
+ sync() {
1245
+ this._updateInputPosition();
1246
+ }
1247
+ /**
1248
+ * @deprecated
1249
+ */
1250
+ activate(x, y, force = !1) {
1251
+ const isFocusing = this._input === document.activeElement || document.activeElement === document.body || document.activeElement === null;
1252
+ this._container.style.left = `${x}px`, this._container.style.top = `${y}px`, this._container.style.zIndex = "1000", (isFocusing || force) && this.focus();
1253
+ }
1254
+ hasFocus() {
1255
+ return document.activeElement === this._input;
1256
+ }
1257
+ focus() {
1258
+ this._editorFocusing && this._input.focus();
1259
+ }
1260
+ blur() {
1261
+ this._input.blur();
1262
+ }
1263
+ /**
1264
+ * @deprecated
1265
+ */
1266
+ focusEditor() {
1267
+ this._editorFocusing = !0, this.focus();
1268
+ }
1269
+ /**
1270
+ * @deprecated
1271
+ */
1272
+ blurEditor() {
1273
+ this._editorFocusing = !1, this.blur();
1274
+ }
1275
+ // FIXME: for editor cell editor we don't need to blur the input element
1276
+ /**
1277
+ * @deprecated
1278
+ */
1279
+ deactivate() {
1280
+ this._container.style.left = "0px", this._container.style.top = "0px";
1281
+ }
1282
+ // Handler double click.
1283
+ __handleDblClick(evt) {
1284
+ const { offsetX: evtOffsetX, offsetY: evtOffsetY } = evt, startNode = this._findNodeByCoord(evtOffsetX, evtOffsetY, {
1285
+ strict: !1,
1286
+ segmentId: this._currentSegmentId,
1287
+ segmentPage: this._currentSegmentPage
1288
+ });
1289
+ if (startNode == null || startNode.node == null)
1290
+ return;
1291
+ const paragraphInfo = getParagraphInfoByGlyph(startNode.node);
1292
+ if (paragraphInfo == null)
1293
+ return;
1294
+ const { content, st, nodeIndex } = paragraphInfo;
1295
+ if (nodeIndex === -1 || Intl.Segmenter == null)
1296
+ return;
1297
+ const segments = new Intl.Segmenter(void 0, { granularity: "word" }).segment(content);
1298
+ let startOffset = Number.NEGATIVE_INFINITY, endOffset = Number.NEGATIVE_INFINITY;
1299
+ for (const { segment, index, isWordLike } of segments)
1300
+ if (index <= nodeIndex && nodeIndex < index + segment.length && isWordLike) {
1301
+ startOffset = index + st, endOffset = index + st + segment.length;
1302
+ break;
1303
+ }
1304
+ if (Number.isFinite(startOffset) && Number.isFinite(endOffset)) {
1305
+ this.removeAllRanges();
1306
+ const textRanges = [
1307
+ {
1308
+ startOffset,
1309
+ endOffset
1310
+ }
1311
+ ];
1312
+ this.addDocRanges(textRanges, !1, { forceFocus: !0 });
1313
+ }
1314
+ }
1315
+ __handleTripleClick(evt) {
1316
+ const { offsetX: evtOffsetX, offsetY: evtOffsetY } = evt, startNode = this._findNodeByCoord(evtOffsetX, evtOffsetY, {
1317
+ strict: !1,
1318
+ segmentId: this._currentSegmentId,
1319
+ segmentPage: this._currentSegmentPage
1320
+ });
1321
+ if (startNode == null || startNode.node == null)
1322
+ return;
1323
+ const paragraphInfo = getParagraphInfoByGlyph(startNode.node);
1324
+ if (paragraphInfo == null)
1325
+ return;
1326
+ this.removeAllRanges();
1327
+ const { st, ed } = paragraphInfo, textRanges = [
1328
+ {
1329
+ startOffset: st,
1330
+ endOffset: ed
1331
+ }
1332
+ ];
1333
+ this.addDocRanges(textRanges, !1, { forceFocus: !0 });
1334
+ }
1335
+ // Handle pointer down.
1336
+ // eslint-disable-next-line max-lines-per-function, complexity
1337
+ __onPointDown(evt) {
1338
+ var _a2, _b;
1339
+ this._editorFocusing = !0;
1340
+ const { scene, mainComponent } = this._context, skeleton = this._docSkeletonManagerService.getSkeleton(), { offsetX: evtOffsetX, offsetY: evtOffsetY } = evt, startNode = this._findNodeByCoord(evtOffsetX, evtOffsetY, {
1341
+ strict: !1,
1342
+ segmentId: this._currentSegmentId,
1343
+ segmentPage: this._currentSegmentPage
1344
+ }), position = this._getNodePosition(startNode);
1345
+ if (position == null || startNode == null) {
1346
+ this._removeAllRanges();
1347
+ return;
1348
+ }
1349
+ (startNode == null ? void 0 : startNode.node.streamType) === DataStreamTreeTokenType.PARAGRAPH && (position.isBack = !0);
1350
+ const docSelection = this._textSelectionInner$.value;
1351
+ if (startNode && evt.button === 2 && docSelection) {
1352
+ const nodeCharIndex = skeleton.findCharIndexByPosition(position);
1353
+ if (typeof nodeCharIndex == "number" && docSelection.textRanges.some((textRange) => textRange.startOffset <= nodeCharIndex && textRange.endOffset > nodeCharIndex) || typeof nodeCharIndex == "number" && docSelection.rectRanges.some((rectRange) => rectRange.startOffset <= nodeCharIndex && rectRange.endOffset >= nodeCharIndex))
1354
+ return;
1355
+ }
1356
+ const { segmentId, segmentPage } = startNode;
1357
+ segmentId && this._currentSegmentId && segmentId !== this._currentSegmentId && this.setSegment(segmentId), segmentId && segmentPage !== this._currentSegmentPage && this.setSegmentPage(segmentPage), this._anchorNodePosition = position, evt.shiftKey && this._getActiveRangeInstance() ? this._updateActiveRangePosition(position) : evt.ctrlKey ? this._removeAllCollapsedTextRanges() : this._isEmpty() || this._removeAllRanges(), scene.disableObjectsEvent();
1358
+ const scrollTimer = ScrollTimer.create(scene);
1359
+ this._scrollTimers.push(scrollTimer), scrollTimer.startScroll(evtOffsetX, evtOffsetY), this._onSelectionStart$.next((_a2 = this._getActiveRangeInstance()) == null ? void 0 : _a2.startNodePosition), (_b = scene.getTransformer()) == null || _b.clearSelectedObjects();
1360
+ let preMoveOffsetX = evtOffsetX, preMoveOffsetY = evtOffsetY;
1361
+ this._scenePointerMoveSubs.push(scene.onPointerMove$.subscribeEvent((moveEvt) => {
1362
+ const { offsetX: moveOffsetX, offsetY: moveOffsetY } = moveEvt;
1363
+ scene.setCursor(CURSOR_TYPE.TEXT), !(Math.sqrt((moveOffsetX - preMoveOffsetX) ** 2 + (moveOffsetY - preMoveOffsetY) ** 2) < 3) && (this._moving(moveOffsetX, moveOffsetY), scrollTimer.scrolling(moveOffsetX, moveOffsetY, () => {
1364
+ this._moving(moveOffsetX, moveOffsetY);
1365
+ }), preMoveOffsetX = moveOffsetX, preMoveOffsetY = moveOffsetY);
1366
+ })), this._scenePointerUpSubs.push(scene.onPointerUp$.subscribeEvent(() => {
1367
+ if ([...this._scenePointerMoveSubs, ...this._scenePointerUpSubs].forEach((e) => {
1368
+ e.unsubscribe();
1369
+ }), scene.enableObjectsEvent(), this._anchorNodePosition && !this._focusNodePosition) {
1370
+ if (evt.ctrlKey) {
1371
+ this._disposeScrollTimers();
1372
+ return;
1373
+ }
1374
+ const textRange = new TextRange(scene, mainComponent, skeleton, this._anchorNodePosition, void 0, this._selectionStyle, this._currentSegmentId, this._currentSegmentPage);
1375
+ this._addTextRange(textRange);
1376
+ } else if (this._anchorNodePosition && this._focusNodePosition) {
1377
+ for (const textRange of this._rangeListCache)
1378
+ evt.ctrlKey ? textRange.collapsed ? textRange.dispose() : this._addTextRange(textRange) : this._addTextRange(textRange);
1379
+ this._addRectRanges(this._rectRangeListCache), this._rangeListCache = [], this._rectRangeListCache = [];
1380
+ }
1381
+ this._anchorNodePosition = null, this._focusNodePosition = null;
1382
+ const selectionInfo = {
1383
+ textRanges: this._getAllTextRanges(),
1384
+ rectRanges: this._getAllRectRanges(),
1385
+ segmentId: this._currentSegmentId,
1386
+ segmentPage: this._currentSegmentPage,
1387
+ style: this._selectionStyle,
1388
+ isEditing: !1
1389
+ };
1390
+ this._textSelectionInner$.next(selectionInfo), this._disposeScrollTimers(), this._updateInputPosition(!0);
1391
+ }));
1392
+ }
1393
+ removeAllRanges() {
1394
+ this._removeAllRanges(), this.deactivate();
1395
+ }
1396
+ getActiveTextRange() {
1397
+ return this._getActiveRangeInstance();
1398
+ }
1399
+ _disposeScrollTimers() {
1400
+ this._scrollTimers.forEach((timer) => {
1401
+ timer == null || timer.dispose();
1402
+ }), this._scrollTimers = [];
1403
+ }
1404
+ _setSystemHighlightColorToStyle() {
1405
+ const { r, g, b, a } = getSystemHighlightColor(), style = {
1406
+ strokeWidth: 1.5,
1407
+ stroke: "rgba(0, 0, 0, 0)",
1408
+ strokeActive: "rgba(0, 0, 0, 1)",
1409
+ fill: `rgba(${r}, ${g}, ${b}, ${a != null ? a : 0.3})`
1410
+ };
1411
+ this._setRangeStyle(style);
1412
+ }
1413
+ _getAllTextRanges() {
1414
+ return this._rangeList.map(serializeTextRange);
1415
+ }
1416
+ _getAllRectRanges() {
1417
+ return this._rectRangeList.map(serializeRectRange);
1418
+ }
1419
+ _getActiveRange() {
1420
+ const activeRange = this._rangeList.find((range) => range.isActive());
1421
+ if (activeRange == null)
1422
+ return null;
1423
+ const { startOffset, endOffset } = activeRange;
1424
+ return startOffset == null || endOffset == null ? null : serializeTextRange(activeRange);
1425
+ }
1426
+ _getActiveRangeInstance() {
1427
+ return this._rangeList.find((range) => range.isActive());
1428
+ }
1429
+ dispose() {
1430
+ super.dispose(), this._detachEvent(), this._removeAllRanges(), this._container.remove();
1431
+ }
1432
+ _initDOM() {
1433
+ const { unitId } = this._context, container = document.createElement("div");
1434
+ container.style.position = "fixed", container.style.left = "0px", container.style.top = "0px", container.id = `univer-doc-selection-container-${unitId}`;
1435
+ const inputParent = document.createElement("div"), inputDom = document.createElement("div");
1436
+ inputParent.appendChild(inputDom), container.appendChild(inputParent), this._container = container, this._inputParent = inputParent, this._input = inputDom, this._initInput(), this._initInputEvents(), document.body.appendChild(container);
1437
+ }
1438
+ _registerContainer() {
1439
+ this.disposeWithMe(
1440
+ // the content editable div should be regarded as part of the applications container
1441
+ this._layoutService.registerContainerElement(this._container)
1442
+ );
1443
+ }
1444
+ _initInput() {
1445
+ this._inputParent.style.cssText = `
1446
+ position:absolute;
1447
+ height:1px;
1448
+ width:1px;
1449
+ overflow: hidden;
1450
+ `, this._input.contentEditable = "true", this._input.classList.add("univer-editor"), this._input.style.cssText = `
1451
+ position: absolute;
1452
+ overflow: hidden;
1453
+ opacity: 1;
1454
+ background: #000;
1455
+ color: transparent;
1456
+ outline: none;
1457
+ z-index: -2;
1458
+ caret-color: transparent;
1459
+ white-space: pre-wrap;
1460
+ user-select: text;
1461
+ `;
1462
+ }
1463
+ _getNodePosition(node) {
1464
+ if (node == null)
1465
+ return;
1466
+ const { node: glyph, ratioX, segmentPage } = node, position = this._docSkeletonManagerService.getSkeleton().findPositionByGlyph(glyph, segmentPage);
1467
+ if (position == null)
1468
+ return;
1469
+ const isBack = ratioX < 0.5;
1470
+ return {
1471
+ ...position,
1472
+ isBack
1473
+ };
1474
+ }
1475
+ _interactTextRanges(textRanges) {
1476
+ const newTextRanges = [];
1477
+ for (const range of this._rangeList) {
1478
+ if (textRanges.some((textRange) => textRange.isIntersection(range))) {
1479
+ range.dispose();
1480
+ continue;
1481
+ }
1482
+ newTextRanges.push(range);
1483
+ }
1484
+ this._rangeList = newTextRanges;
1485
+ }
1486
+ _interactRectRanges(rectRanges) {
1487
+ const newRanges = [];
1488
+ for (const range of this._rectRangeList) {
1489
+ if (rectRanges.some((rectRange) => rectRange.isIntersection(range))) {
1490
+ range.dispose();
1491
+ continue;
1492
+ }
1493
+ newRanges.push(range);
1494
+ }
1495
+ this._rectRangeList = newRanges;
1496
+ }
1497
+ _removeCollapsedTextRange() {
1498
+ const oldTextRanges = this._rangeList;
1499
+ this._rangeList = [];
1500
+ for (const textRange of oldTextRanges)
1501
+ textRange.collapsed ? textRange.dispose() : this._rangeList.push(textRange);
1502
+ }
1503
+ _removeAllRanges() {
1504
+ this._removeAllTextRanges(), this._removeAllRectRanges();
1505
+ }
1506
+ _removeAllCacheRanges() {
1507
+ this._rangeListCache.forEach((range) => {
1508
+ range.dispose();
1509
+ }), this._rectRangeListCache.forEach((range) => {
1510
+ range.dispose();
1511
+ }), this._rangeListCache = [], this._rectRangeListCache = [];
1512
+ }
1513
+ _removeAllTextRanges() {
1514
+ this._rangeList.forEach((range) => {
1515
+ range.dispose();
1516
+ }), this._rangeList = [];
1517
+ }
1518
+ _removeAllRectRanges() {
1519
+ this._rectRangeList.forEach((range) => {
1520
+ range.dispose();
1521
+ }), this._rectRangeList = [];
1522
+ }
1523
+ _removeAllCollapsedTextRanges() {
1524
+ for (const range of this._rangeList)
1525
+ range.collapsed && range.dispose();
1526
+ }
1527
+ _deactivateAllTextRanges() {
1528
+ this._rangeList.forEach((range) => {
1529
+ range.deactivate();
1530
+ });
1531
+ }
1532
+ _deactivateAllRectRanges() {
1533
+ this._rectRangeList.forEach((range) => {
1534
+ range.deactivate();
1535
+ });
1536
+ }
1537
+ _addTextRangesToCache(textRanges) {
1538
+ this._rangeListCache.push(...textRanges);
1539
+ }
1540
+ _addTextRange(textRange) {
1541
+ this._deactivateAllTextRanges(), textRange.activate(), this._rangeList.push(textRange);
1542
+ }
1543
+ _addRectRangesToCache(rectRanges) {
1544
+ this._rectRangeListCache.push(...rectRanges);
1545
+ }
1546
+ _addRectRanges(rectRanges) {
1547
+ rectRanges.length !== 0 && (this._deactivateAllRectRanges(), rectRanges[rectRanges.length - 1].activate(), this._rectRangeList.push(...rectRanges));
1548
+ }
1549
+ _createTextRangeByAnchorPosition(position) {
1550
+ this._removeAllRanges();
1551
+ const { scene, mainComponent } = this._context, skeleton = this._docSkeletonManagerService.getSkeleton(), lastRange = new TextRange(scene, mainComponent, skeleton, position, void 0, this._selectionStyle, this._currentSegmentId, this._currentSegmentPage);
1552
+ this._addTextRange(lastRange);
1553
+ }
1554
+ _updateActiveRangePosition(position) {
1555
+ const activeTextRange = this._getActiveRangeInstance();
1556
+ if (activeTextRange == null || activeTextRange.anchorNodePosition == null) {
1557
+ this._logService.error(
1558
+ "[DocSelectionRenderService] _updateActiveRangeFocusPosition: active range has no anchor"
1559
+ );
1560
+ return;
1561
+ }
1562
+ this._removeAllRanges(), this._anchorNodePosition = activeTextRange.anchorNodePosition, this._focusNodePosition = position;
1563
+ const { scene, mainComponent } = this._context, skeleton = this._docSkeletonManagerService.getSkeleton(), { _anchorNodePosition, _focusNodePosition, _selectionStyle, _currentSegmentId, _currentSegmentPage } = this;
1564
+ if (_anchorNodePosition == null || _focusNodePosition == null || mainComponent == null)
1565
+ return;
1566
+ const ranges = getRangeListFromSelection(
1567
+ _anchorNodePosition,
1568
+ _focusNodePosition,
1569
+ scene,
1570
+ mainComponent,
1571
+ skeleton,
1572
+ _selectionStyle,
1573
+ _currentSegmentId,
1574
+ _currentSegmentPage
1575
+ );
1576
+ if (ranges == null)
1577
+ return;
1578
+ const { textRanges, rectRanges } = ranges;
1579
+ this._addTextRangesToCache(textRanges), this._addRectRangesToCache(rectRanges), this.deactivate();
1580
+ }
1581
+ _isEmpty() {
1582
+ return this._rangeList.length === 0 && this._rectRangeList.length === 0;
1583
+ }
1584
+ _getCanvasOffset() {
1585
+ var _a2;
1586
+ const engine = (_a2 = this._context.scene) == null ? void 0 : _a2.getEngine();
1587
+ return getCanvasOffsetByEngine(engine);
1588
+ }
1589
+ _updateInputPosition(forceFocus = !1) {
1590
+ const activeRangeInstance = this._getActiveRangeInstance(), anchor = activeRangeInstance == null ? void 0 : activeRangeInstance.getAnchor();
1591
+ if (!anchor || anchor && !anchor.visible || this.activeViewPort == null) {
1592
+ this.focus();
1593
+ return;
1594
+ }
1595
+ const { left, top } = anchor, absoluteCoord = this.activeViewPort.getAbsoluteVector(Vector2.FromArray([left, top])), { x, y } = absoluteCoord;
1596
+ let { left: canvasLeft, top: canvasTop } = this._getCanvasOffset();
1597
+ canvasLeft += x, canvasTop += y, this.activate(canvasLeft, canvasTop, forceFocus);
1598
+ }
1599
+ _moving(moveOffsetX, moveOffsetY) {
1600
+ var _a2, _b;
1601
+ const focusNode = this._findNodeByCoord(moveOffsetX, moveOffsetY, {
1602
+ strict: !0,
1603
+ segmentId: this._currentSegmentId,
1604
+ segmentPage: this._currentSegmentPage
1605
+ }), focusNodePosition = this._getNodePosition(focusNode);
1606
+ if (!focusNodePosition || focusNode == null)
1607
+ return;
1608
+ const divide = focusNode == null ? void 0 : focusNode.node.parent, nextGlyph = divide == null ? void 0 : divide.glyphGroup[divide.glyphGroup.indexOf(focusNode.node) + 1];
1609
+ (focusNode == null ? void 0 : focusNode.node.streamType) === DataStreamTreeTokenType.PARAGRAPH && (nextGlyph == null ? void 0 : nextGlyph.streamType) === DataStreamTreeTokenType.SECTION_BREAK && (focusNodePosition.isBack = !0), this._focusNodePosition = focusNodePosition, this._removeAllCacheRanges();
1610
+ const { _anchorNodePosition, _focusNodePosition, _selectionStyle, _currentSegmentId, _currentSegmentPage } = this, { scene, mainComponent } = this._context, skeleton = this._docSkeletonManagerService.getSkeleton();
1611
+ if (_anchorNodePosition == null || _focusNodePosition == null || mainComponent == null)
1612
+ return;
1613
+ const ranges = getRangeListFromSelection(
1614
+ _anchorNodePosition,
1615
+ _focusNodePosition,
1616
+ scene,
1617
+ mainComponent,
1618
+ skeleton,
1619
+ _selectionStyle,
1620
+ _currentSegmentId,
1621
+ _currentSegmentPage
1622
+ );
1623
+ if (ranges == null)
1624
+ return;
1625
+ const { textRanges, rectRanges } = ranges;
1626
+ this._rangeList.length > 0 && textRanges.length > 0 && this._interactTextRanges(textRanges), this._rectRangeList.length > 0 && rectRanges.length > 0 && this._interactRectRanges(rectRanges), this._addTextRangesToCache(textRanges), this._addRectRangesToCache(rectRanges), this.deactivate(), (_b = (_a2 = this._context.scene) == null ? void 0 : _a2.getEngine()) == null || _b.setRemainCapture();
1627
+ }
1628
+ __attachScrollEvent() {
1629
+ const viewport = this.activeViewPort;
1630
+ if (!viewport)
1631
+ return;
1632
+ const { unitId } = this._context;
1633
+ if (this._viewPortObserverMap.has(unitId))
1634
+ return;
1635
+ const scrollBefore = viewport.onScrollAfter$.subscribeEvent((param) => {
1636
+ if (!param.viewport)
1637
+ return;
1638
+ const activeRangeInstance = this._getActiveRangeInstance();
1639
+ activeRangeInstance == null || activeRangeInstance.activeStatic();
1640
+ }), scrollStop = viewport.onScrollEnd$.subscribeEvent((param) => {
1641
+ const viewport2 = param.viewport;
1642
+ if (!viewport2)
1643
+ return;
1644
+ const bounds = viewport2.getBounding(), activeRangeInstance = this._getActiveRangeInstance(), anchor = activeRangeInstance == null ? void 0 : activeRangeInstance.getAnchor();
1645
+ if (!(!anchor || anchor && !anchor.visible)) {
1646
+ if (bounds) {
1647
+ const { left, top, right, bottom } = bounds.viewBound;
1648
+ if (anchor.left < left || anchor.left > right || anchor.top < top || anchor.top > bottom) {
1649
+ activeRangeInstance == null || activeRangeInstance.deactivateStatic();
1650
+ return;
1651
+ }
1652
+ }
1653
+ this._updateInputPosition();
1654
+ }
1655
+ });
1656
+ this._viewPortObserverMap.set(unitId, {
1657
+ scrollBefore,
1658
+ scrollStop
1659
+ });
1660
+ }
1661
+ // FIXME: listeners here are not correctly disposed
1662
+ // eslint-disable-next-line max-lines-per-function
1663
+ _initInputEvents() {
1664
+ this.disposeWithMe(
1665
+ fromEvent(this._input, "keydown").subscribe((e) => {
1666
+ this._isIMEInputApply || this._eventHandle(e, (config) => {
1667
+ this._onKeydown$.next(config);
1668
+ });
1669
+ })
1670
+ ), this.disposeWithMe(
1671
+ fromEvent(this._input, "input").subscribe((e) => {
1672
+ if (!(e.inputType === "historyUndo" || e.inputType === "historyRedo")) {
1673
+ if (this._rectRangeList.length > 0)
1674
+ return e.stopPropagation(), e.preventDefault();
1675
+ this._isIMEInputApply || this._eventHandle(e, (config) => {
1676
+ this._onInputBefore$.next(config), this._onInput$.next(config);
1677
+ });
1678
+ }
1679
+ })
1680
+ ), this.disposeWithMe(
1681
+ fromEvent(this._input, "compositionstart").subscribe((e) => {
1682
+ if (this._rectRangeList.length > 0)
1683
+ return e.stopPropagation(), e.preventDefault();
1684
+ this._isIMEInputApply = !0, this._eventHandle(e, (config) => {
1685
+ this._onCompositionstart$.next(config);
1686
+ });
1687
+ })
1688
+ ), this.disposeWithMe(
1689
+ fromEvent(this._input, "compositionend").subscribe((e) => {
1690
+ this._isIMEInputApply = !1, this._eventHandle(e, (config) => {
1691
+ this._onCompositionend$.next(config);
1692
+ });
1693
+ })
1694
+ ), this.disposeWithMe(
1695
+ fromEvent(this._input, "compositionupdate").subscribe((e) => {
1696
+ this._eventHandle(e, (config) => {
1697
+ this._onInputBefore$.next(config), this._onCompositionupdate$.next(config);
1698
+ });
1699
+ })
1700
+ ), this.disposeWithMe(
1701
+ fromEvent(this._input, "paste").subscribe((e) => {
1702
+ this._eventHandle(e, (config) => {
1703
+ this._onPaste$.next(config);
1704
+ });
1705
+ })
1706
+ ), this.disposeWithMe(
1707
+ fromEvent(this._input, "focus").subscribe((e) => {
1708
+ this._eventHandle(e, (config) => {
1709
+ this._onFocus$.next(config);
1710
+ });
1711
+ })
1712
+ ), this.disposeWithMe(
1713
+ fromEvent(this._input, "blur").subscribe((e) => {
1714
+ this._eventHandle(e, (config) => {
1715
+ this._onBlur$.next(config);
1716
+ });
1717
+ })
1718
+ );
1719
+ }
1720
+ _eventHandle(e, func) {
1721
+ const content = this._input.textContent || "";
1722
+ this._input.innerHTML = "";
1723
+ const activeRange = this._getActiveRange(), rangeList = this._getAllTextRanges();
1724
+ func({
1725
+ event: e,
1726
+ content,
1727
+ activeRange,
1728
+ rangeList
1729
+ });
1730
+ }
1731
+ _getTransformCoordForDocumentOffset(evtOffsetX, evtOffsetY) {
1732
+ const document2 = this._context.mainComponent, { documentTransform } = document2.getOffsetConfig();
1733
+ if (this.activeViewPort == null || documentTransform == null)
1734
+ return;
1735
+ const originCoord = this.activeViewPort.transformVector2SceneCoord(Vector2.FromArray([evtOffsetX, evtOffsetY]));
1736
+ if (originCoord)
1737
+ return documentTransform.clone().invert().applyPoint(originCoord);
1738
+ }
1739
+ _findNodeByCoord(evtOffsetX, evtOffsetY, restrictions) {
1740
+ const coord = this._getTransformCoordForDocumentOffset(evtOffsetX, evtOffsetY);
1741
+ if (coord == null)
1742
+ return;
1743
+ const document2 = this._context.mainComponent, skeleton = this._docSkeletonManagerService.getSkeleton(), {
1744
+ pageLayoutType = PageLayoutType.VERTICAL,
1745
+ pageMarginLeft,
1746
+ pageMarginTop
1747
+ } = document2.getOffsetConfig();
1748
+ return skeleton.findNodeByCoord(
1749
+ coord,
1750
+ pageLayoutType,
1751
+ pageMarginLeft,
1752
+ pageMarginTop,
1753
+ restrictions
1754
+ );
1755
+ }
1756
+ _detachEvent() {
1757
+ this._onInputBefore$.complete(), this._onKeydown$.complete(), this._onInput$.complete(), this._onCompositionstart$.complete(), this._onCompositionupdate$.complete(), this._onCompositionend$.complete(), this._onSelectionStart$.complete(), this._textSelectionInner$.complete(), this._onPaste$.complete(), this._onFocus$.complete(), this._onBlur$.complete(), this._onPointerDown$.complete();
1758
+ }
1759
+ }, __name(_a, "DocSelectionRenderService"), _a);
1760
+ DocSelectionRenderService = __decorateClass([
1761
+ __decorateParam(1, ILayoutService),
1762
+ __decorateParam(2, ILogService),
1763
+ __decorateParam(3, IUniverInstanceService),
1764
+ __decorateParam(4, Inject(DocSkeletonManagerService))
1765
+ ], DocSelectionRenderService);
1766
+ var DeleteDirection = /* @__PURE__ */ ((DeleteDirection2) => (DeleteDirection2[DeleteDirection2.LEFT = 0] = "LEFT", DeleteDirection2[DeleteDirection2.RIGHT = 1] = "RIGHT", DeleteDirection2))(DeleteDirection || {});
1767
+ const EditorInsertTextCommandId = "doc.command.insert-text", InsertCommand = {
1768
+ id: EditorInsertTextCommandId,
1769
+ type: CommandType.COMMAND,
1770
+ handler: /* @__PURE__ */ __name(async (accessor, params) => {
1771
+ var _a2;
1772
+ const commandService = accessor.get(ICommandService), { range, segmentId, body, unitId, cursorOffset, extendLastRange } = params, docSelectionManagerService = accessor.get(DocSelectionManagerService), docDataModel = accessor.get(IUniverInstanceService).getUnit(unitId, UniverInstanceType.UNIVER_DOC);
1773
+ if (docDataModel == null)
1774
+ return !1;
1775
+ const activeRange = docSelectionManagerService.getActiveTextRange(), originBody = docDataModel.getSelfOrHeaderFooterModel((_a2 = activeRange == null ? void 0 : activeRange.segmentId) != null ? _a2 : "").getBody();
1776
+ if (originBody == null)
1777
+ return !1;
1778
+ const actualRange = extendLastRange ? BuildTextUtils.selection.getDeleteSelection(range, originBody) : BuildTextUtils.selection.getInsertSelection(range, originBody), { startOffset, collapsed } = actualRange, cursorMove = cursorOffset != null ? cursorOffset : body.dataStream.length, textRanges = [
1779
+ {
1780
+ startOffset: startOffset + cursorMove,
1781
+ endOffset: startOffset + cursorMove,
1782
+ style: activeRange == null ? void 0 : activeRange.style,
1783
+ collapsed
1784
+ }
1785
+ ], doMutation = {
1786
+ id: RichTextEditingMutation.id,
1787
+ params: {
1788
+ unitId,
1789
+ actions: [],
1790
+ textRanges,
1791
+ debounce: !0
1792
+ }
1793
+ }, textX = new TextX(), jsonX = JSONX.getInstance();
1794
+ if (collapsed)
1795
+ startOffset > 0 && textX.push({
1796
+ t: TextXActionType.RETAIN,
1797
+ len: startOffset
1798
+ });
1799
+ else {
1800
+ const { dos, retain } = BuildTextUtils.selection.getDeleteActions(actualRange, segmentId, 0, originBody);
1801
+ textX.push(...dos), doMutation.params.textRanges = [{
1802
+ startOffset: startOffset + cursorMove + retain,
1803
+ endOffset: startOffset + cursorMove + retain,
1804
+ collapsed
1805
+ }];
1806
+ }
1807
+ textX.push({
1808
+ t: TextXActionType.INSERT,
1809
+ body,
1810
+ len: body.dataStream.length
1811
+ });
1812
+ const path = getRichTextEditPath(docDataModel, segmentId);
1813
+ return doMutation.params.actions = jsonX.editOp(textX.serialize(), path), !!commandService.syncExecuteCommand(doMutation.id, doMutation.params);
1814
+ }, "handler")
1815
+ }, DeleteCommand = {
1816
+ id: "doc.command.delete-text",
1817
+ type: CommandType.COMMAND,
1818
+ handler: /* @__PURE__ */ __name(async (accessor, params) => {
1819
+ var _a2;
1820
+ const commandService = accessor.get(ICommandService), univerInstanceService = accessor.get(IUniverInstanceService), { range, segmentId, unitId, direction, len = 1 } = params, docDataModel = univerInstanceService.getUnit(unitId, UniverInstanceType.UNIVER_DOC), body = docDataModel == null ? void 0 : docDataModel.getSelfOrHeaderFooterModel(segmentId).getBody();
1821
+ if (docDataModel == null || body == null)
1822
+ return !1;
1823
+ const { startOffset } = range, dataStream = body.dataStream, start = direction === DeleteDirection.LEFT ? startOffset - len : startOffset, end = start + len - 1, relativeCustomRanges = (_a2 = body.customRanges) == null ? void 0 : _a2.filter((customRange) => BuildTextUtils.customRange.isIntersecting(customRange.startIndex, customRange.endIndex, start, end)), toDeleteRanges = relativeCustomRanges == null ? void 0 : relativeCustomRanges.filter((customRange) => BuildTextUtils.customRange.shouldDeleteCustomRange(start, len, customRange, dataStream)), deleteIndexes = [];
1824
+ for (let i = 0; i < len; i++)
1825
+ deleteIndexes.push(start + i);
1826
+ toDeleteRanges == null || toDeleteRanges.forEach((range2) => {
1827
+ deleteIndexes.push(range2.startIndex, range2.endIndex);
1828
+ }), deleteIndexes.sort((pre, aft) => pre - aft);
1829
+ const deleteStart = deleteIndexes[0], doMutation = {
1830
+ id: RichTextEditingMutation.id,
1831
+ params: {
1832
+ unitId,
1833
+ actions: [],
1834
+ textRanges: [{
1835
+ startOffset: deleteStart,
1836
+ endOffset: deleteStart,
1837
+ collapsed: !0
1838
+ }],
1839
+ debounce: !0
1840
+ }
1841
+ }, textX = new TextX(), jsonX = JSONX.getInstance();
1842
+ let cursor = 0;
1843
+ for (let i = 0; i < deleteIndexes.length; i++) {
1844
+ const deleteIndex = deleteIndexes[i];
1845
+ deleteIndex - cursor > 0 && textX.push({
1846
+ t: TextXActionType.RETAIN,
1847
+ len: deleteIndex - cursor
1848
+ }), textX.push({
1849
+ t: TextXActionType.DELETE,
1850
+ len: 1
1851
+ }), cursor = deleteIndex + 1;
1852
+ }
1853
+ const path = getRichTextEditPath(docDataModel, segmentId);
1854
+ return doMutation.params.actions = jsonX.editOp(textX.serialize(), path), !!commandService.syncExecuteCommand(doMutation.id, doMutation.params);
1855
+ }, "handler")
1856
+ }, UpdateCommand = {
1857
+ id: "doc.command.update-text",
1858
+ type: CommandType.COMMAND,
1859
+ handler: /* @__PURE__ */ __name(async (accessor, params) => {
1860
+ const { range, segmentId, updateBody, coverType, unitId, textRanges } = params, commandService = accessor.get(ICommandService), docDataModel = accessor.get(IUniverInstanceService).getCurrentUniverDocInstance();
1861
+ if (docDataModel == null)
1862
+ return !1;
1863
+ const doMutation = {
1864
+ id: RichTextEditingMutation.id,
1865
+ params: {
1866
+ unitId,
1867
+ actions: [],
1868
+ textRanges
1869
+ }
1870
+ }, textX = new TextX(), jsonX = JSONX.getInstance(), { startOffset, endOffset } = range;
1871
+ textX.push({
1872
+ t: TextXActionType.RETAIN,
1873
+ len: startOffset
1874
+ }), textX.push({
1875
+ t: TextXActionType.RETAIN,
1876
+ body: updateBody,
1877
+ len: endOffset - startOffset,
1878
+ coverType
1879
+ });
1880
+ const path = getRichTextEditPath(docDataModel, segmentId);
1881
+ return doMutation.params.actions = jsonX.editOp(textX.serialize(), path), !!commandService.syncExecuteCommand(doMutation.id, doMutation.params);
1882
+ }, "handler")
1883
+ };
1884
+ export {
1885
+ DocSelectionRenderService as D,
1886
+ EditorInsertTextCommandId as E,
1887
+ InsertCommand as I,
1888
+ NodePositionConvertToCursor as N,
1889
+ RectRange as R,
1890
+ TEXT_RANGE_LAYER_INDEX as T,
1891
+ UpdateCommand as U,
1892
+ getCommandSkeleton as a,
1893
+ DeleteDirection as b,
1894
+ DeleteCommand as c,
1895
+ getAnchorBounding as d,
1896
+ getLineBounding as e,
1897
+ isValidRectRange as f,
1898
+ getRichTextEditPath as g,
1899
+ NodePositionConvertToRectRange as h,
1900
+ isInSameTableCell as i,
1901
+ getOneTextSelectionRange as j,
1902
+ convertPositionsToRectRanges as k,
1903
+ getCanvasOffsetByEngine as l,
1904
+ TextRange as m
1905
+ };