@talrace/ngx-noder 0.0.28 → 0.0.29

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 (27) hide show
  1. package/assets/drag-and-drop-cursor.png +0 -0
  2. package/fesm2022/talrace-ngx-noder.mjs +409 -71
  3. package/fesm2022/talrace-ngx-noder.mjs.map +1 -1
  4. package/lib/editor/content/helpers/format.helper.d.ts +1 -0
  5. package/lib/editor/content/helpers/indexed-element.helper.d.ts +1 -0
  6. package/lib/editor/content/helpers/link.helper.d.ts +1 -0
  7. package/lib/editor/display/layers/cursor.layer.d.ts +1 -0
  8. package/lib/editor/display/render-changes.interface.d.ts +1 -0
  9. package/lib/editor/display/render-changes.model.d.ts +1 -0
  10. package/lib/editor/display/renderer.d.ts +5 -0
  11. package/lib/editor/display/virtual.renderer.d.ts +4 -0
  12. package/lib/editor/execution/edit.session.d.ts +5 -0
  13. package/lib/editor/execution/editor.d.ts +14 -2
  14. package/lib/editor/gadgets/drag-and-drop/drag-and-drop.d.ts +21 -0
  15. package/lib/editor/gadgets/history/operation-history.d.ts +3 -0
  16. package/lib/editor/gadgets/history/operation.type.d.ts +2 -1
  17. package/lib/editor/operations/enums/command-type.enum.d.ts +2 -1
  18. package/lib/editor/operations/helpers/contents-operations.helper.d.ts +5 -0
  19. package/lib/editor/operations/operations-helper.helper.d.ts +4 -1
  20. package/lib/editor/operations/save-commands.helper.d.ts +2 -0
  21. package/lib/editor/operations/target-operations.helper.d.ts +3 -1
  22. package/lib/models/generated/command.model.d.ts +2 -0
  23. package/lib/models/generated/link.model.d.ts +2 -0
  24. package/lib/models/generated/move-range.model.d.ts +9 -0
  25. package/lib/models/generated/text-style.model.d.ts +1 -0
  26. package/package.json +1 -1
  27. package/src/scss/base-editor.scss +15 -2
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Directive, Injectable, inject, ChangeDetectorRef, HostBinding, Input, InjectionToken, createComponent, Component, ChangeDetectionStrategy, ViewChild, EventEmitter, Output, HostListener, NgModule, Inject } from '@angular/core';
3
- import { Subject, BehaviorSubject, fromEvent, throttleTime, filter, take, startWith, takeUntil, catchError, debounceTime, distinctUntilChanged } from 'rxjs';
3
+ import { Subject, BehaviorSubject, fromEvent, throttleTime, take, filter, startWith, takeUntil, catchError, debounceTime, distinctUntilChanged } from 'rxjs';
4
4
  import * as i1$1 from '@angular/common/http';
5
5
  import { HttpHeaders } from '@angular/common/http';
6
6
  import * as i3 from '@angular/common';
@@ -960,6 +960,7 @@ var CommandType;
960
960
  CommandType[CommandType["RemoveEdges"] = 28] = "RemoveEdges";
961
961
  CommandType[CommandType["RemoveParagraphAndAddNumbering"] = 29] = "RemoveParagraphAndAddNumbering";
962
962
  CommandType[CommandType["RestoreParagraphAndAddNumbering"] = 30] = "RestoreParagraphAndAddNumbering";
963
+ CommandType[CommandType["MoveRange"] = 31] = "MoveRange";
963
964
  })(CommandType || (CommandType = {}));
964
965
 
965
966
  class PageNumbersModel {
@@ -1038,14 +1039,6 @@ class BreakHelper {
1038
1039
  }
1039
1040
  }
1040
1041
 
1041
- class BreakModel {
1042
- constructor(fields) {
1043
- if (fields) {
1044
- Object.assign(this, fields);
1045
- }
1046
- }
1047
- }
1048
-
1049
1042
  class CursorParagraph {
1050
1043
  constructor(row, column) {
1051
1044
  this.row = row;
@@ -1163,6 +1156,46 @@ class DocumentHandler extends BaseHandler {
1163
1156
  }
1164
1157
  }
1165
1158
 
1159
+ class DragAndDrop {
1160
+ constructor(editorContainer) {
1161
+ this.editorContainer = editorContainer;
1162
+ this.onMove$ = new Subject();
1163
+ this.onDrop$ = new Subject();
1164
+ }
1165
+ onStart(session, range) {
1166
+ if (this.isDragging) {
1167
+ return;
1168
+ }
1169
+ this.isDragging = true;
1170
+ this.editorContainer.classList.add('drag-and-drop-progress');
1171
+ this.sourceSession = session;
1172
+ this.sourceRange = range;
1173
+ this.initListeners();
1174
+ }
1175
+ destroyListeners() {
1176
+ this.mouseMove$?.unsubscribe();
1177
+ this.mouseUp$?.unsubscribe();
1178
+ }
1179
+ onEnd() {
1180
+ this.destroyListeners();
1181
+ if (!this.isDragging) {
1182
+ return;
1183
+ }
1184
+ this.isDragging = false;
1185
+ this.editorContainer.classList.remove('drag-and-drop-progress');
1186
+ this.onDrop$.next({ sourceSession: this.sourceSession, sourceRange: this.sourceRange });
1187
+ }
1188
+ initListeners() {
1189
+ this.destroyListeners();
1190
+ this.mouseMove$ = fromEvent(document, 'mousemove')
1191
+ .pipe(throttleTime(20))
1192
+ .subscribe(event => this.onMove$.next(event));
1193
+ this.mouseUp$ = fromEvent(document, 'mouseup')
1194
+ .pipe(take(1))
1195
+ .subscribe(() => this.onEnd());
1196
+ }
1197
+ }
1198
+
1166
1199
  var EdgeType;
1167
1200
  (function (EdgeType) {
1168
1201
  EdgeType[EdgeType["Header"] = 0] = "Header";
@@ -1196,6 +1229,12 @@ class FormatHelper {
1196
1229
  }
1197
1230
  return result;
1198
1231
  }
1232
+ static shiftIndexes(formats, offset) {
1233
+ for (const format of formats) {
1234
+ format.startIndex += offset;
1235
+ format.endIndex += offset;
1236
+ }
1237
+ }
1199
1238
  }
1200
1239
 
1201
1240
  class ImageDataModel {
@@ -1217,29 +1256,15 @@ class ImageHelper {
1217
1256
  }
1218
1257
  }
1219
1258
 
1220
- class BordersStyleModel {
1221
- constructor(fields) {
1222
- if (fields) {
1223
- Object.assign(this, fields);
1224
- }
1225
- }
1226
- }
1227
-
1228
- class ImageModel {
1229
- constructor(fields) {
1230
- if (fields) {
1231
- if (fields.border) {
1232
- fields.border = new BordersStyleModel(fields.border);
1233
- }
1234
- Object.assign(this, fields);
1235
- }
1236
- }
1237
- }
1238
-
1239
1259
  class IndexedElementHelper {
1240
1260
  static sliceSection(elements, startIndex, endIndex) {
1241
1261
  return elements.filter(x => x.insertIndex >= startIndex && x.insertIndex <= endIndex);
1242
1262
  }
1263
+ static shiftIndexes(elements, offset) {
1264
+ for (const element of elements) {
1265
+ element.insertIndex += offset;
1266
+ }
1267
+ }
1243
1268
  }
1244
1269
 
1245
1270
  class InputHandler extends BaseHandler {
@@ -1518,6 +1543,12 @@ class LinkHelper {
1518
1543
  static sliceSection(links, start, end) {
1519
1544
  return links.map(link => LinkHelper.getPartialLink(link, start, end)).filter((link) => link !== null);
1520
1545
  }
1546
+ static shiftIndexes(links, offset) {
1547
+ for (const link of links) {
1548
+ link.startIndex += offset;
1549
+ link.endIndex += offset;
1550
+ }
1551
+ }
1521
1552
  static sliceFormats(links, startIndex, endIndex) {
1522
1553
  const result = [];
1523
1554
  for (const link of links) {
@@ -1608,6 +1639,14 @@ class MouseHandler {
1608
1639
  }
1609
1640
  }
1610
1641
 
1642
+ class MoveRangeModel {
1643
+ constructor(fields) {
1644
+ if (fields) {
1645
+ Object.assign(this, fields);
1646
+ }
1647
+ }
1648
+ }
1649
+
1611
1650
  var Alignment;
1612
1651
  (function (Alignment) {
1613
1652
  Alignment[Alignment["Left"] = 0] = "Left";
@@ -3011,6 +3050,9 @@ class OperationHistory {
3011
3050
  const undoStep = new RestoreNumberingsModel({ numberings, paragraphs });
3012
3051
  this.addToHistory(undoStep, redoStep);
3013
3052
  }
3053
+ pushMoveRange(restore, replace, selection) {
3054
+ this.addToHistory(restore, replace, selection, []);
3055
+ }
3014
3056
  pushReplace(restore, replace) {
3015
3057
  this.addToHistory(restore, replace);
3016
3058
  }
@@ -3046,10 +3088,10 @@ class OperationHistory {
3046
3088
  this.editorService.historyInfo = new OperationsHistoryInfoModel(this.step, this.storage.length - 1);
3047
3089
  return { operation, targets, cursor, anchor };
3048
3090
  }
3049
- addToHistory(undoStep, redoStep) {
3050
- const targets = this.regulatorService.getCurrentSessionTargets();
3051
- const cursor = this.regulatorService.selection.cursor;
3052
- const anchor = this.regulatorService.selection.anchor;
3091
+ addToHistory(undoStep, redoStep, selection = null, targets = null) {
3092
+ targets ??= this.regulatorService.getCurrentSessionTargets();
3093
+ const cursor = selection?.start ?? this.regulatorService.selection.cursor;
3094
+ const anchor = selection?.end ?? this.regulatorService.selection.anchor;
3053
3095
  this.step++;
3054
3096
  this.storage.splice(this.step, this.storage.length);
3055
3097
  this.storage.push({ undo: undoStep, redo: redoStep, targets, cursor, anchor });
@@ -4567,6 +4609,9 @@ class CommandModel {
4567
4609
  if (fields.insertText) {
4568
4610
  fields.insertText = new InsertTextModel(fields.insertText);
4569
4611
  }
4612
+ if (fields.moveRange) {
4613
+ fields.moveRange = new MoveRangeModel(fields.moveRange);
4614
+ }
4570
4615
  if (fields.removeEdges) {
4571
4616
  fields.removeEdges = new RemoveEdgesModel(fields.removeEdges);
4572
4617
  }
@@ -4714,6 +4759,9 @@ class SaveCommandsHelper {
4714
4759
  static getRestoreTableCommand(restoreTable, targets) {
4715
4760
  return new CommandModel({ commandType: CommandType.RestoreTable, restoreTable, targets });
4716
4761
  }
4762
+ static getMoveRangeCommand(model, targets) {
4763
+ return new CommandModel({ commandType: CommandType.MoveRange, moveRange: model, targets });
4764
+ }
4717
4765
  static getReplaceCommand(model, targets) {
4718
4766
  return new CommandModel({ commandType: CommandType.Replace, replace: model, targets });
4719
4767
  }
@@ -5318,14 +5366,6 @@ class Selection {
5318
5366
  }
5319
5367
  }
5320
5368
 
5321
- class TabModel {
5322
- constructor(fields) {
5323
- if (fields) {
5324
- Object.assign(this, fields);
5325
- }
5326
- }
5327
- }
5328
-
5329
5369
  class TextInput {
5330
5370
  constructor(parentElement) {
5331
5371
  this.lastValue = '';
@@ -5433,12 +5473,13 @@ class Editor {
5433
5473
  this.mouseHandler = new MouseHandler(this.mainRenderer.container, this);
5434
5474
  this.inputHandler = new InputHandler(this.textInput.input, this);
5435
5475
  this.documentHandler = new DocumentHandler(this);
5476
+ this.dragAndDrop = new DragAndDrop(this.container.nativeElement);
5436
5477
  this.initResizeListener();
5437
5478
  this.focus();
5438
5479
  this.session.applyToolbarStyles();
5439
5480
  this.search = new Search();
5440
5481
  this.search.set({ wrap: true });
5441
- this.subscriptions.push(this.changedEdgeSizeSubscription(), this.changedEdgeSubscription(), this.changedTableSizeSubscription(), this.clipboardDataSubscription(), this.copySelectedSubscription(), this.createCustomComponentSubscription(), this.cutSelectedSubscription(), this.disableSelectionSubscription(), this.endMousePressSubscription(), this.imageLoadedSubscription(), this.insertBreakSubscription(), this.insertImageSubscription(), this.insertLinkSubscription(), this.insertTableColumnsSubscription(), this.insertTableRowsSubscription(), this.insertTableSubscription(), this.insertTextSubscription(), this.pasteFromClipboardSubscription(), this.printSubscription(), this.redoSubscription(), this.removeLeftSubscription(), this.removeNumberingsSubscription(), this.removeRightSubscription(), this.removeSelectedSubscription(), this.removeTableColumnsSubscription(), this.removeTableRowsSubscription(), this.replaceSubscription(), this.rerenderSubscription(), this.resizeTableColumnsSubscription(), this.searchOptionSubscription(), this.selectAllSubscription(), this.setImageStyleSubscription(), this.setNumberingTemplateTypeSubscription(), this.setParagraphStylesSubscription(), this.setTextStylesSubscription(), this.undoSubscription(), this.updateEdgeSubscription(), this.viewOnlyModeSubscription());
5482
+ this.subscriptions.push(this.changedEdgeSizeSubscription(), this.changedEdgeSubscription(), this.changedTableSizeSubscription(), this.clipboardDataSubscription(), this.copySelectedSubscription(), this.createCustomComponentSubscription(), this.cutSelectedSubscription(), this.disableSelectionSubscription(), this.endMousePressSubscription(), this.imageLoadedSubscription(), this.insertBreakSubscription(), this.insertImageSubscription(), this.insertLinkSubscription(), this.insertTableColumnsSubscription(), this.insertTableRowsSubscription(), this.insertTableSubscription(), this.insertTextSubscription(), this.pasteFromClipboardSubscription(), this.printSubscription(), this.redoSubscription(), this.removeLeftSubscription(), this.removeNumberingsSubscription(), this.removeRightSubscription(), this.removeSelectedSubscription(), this.removeTableColumnsSubscription(), this.removeTableRowsSubscription(), this.replaceSubscription(), this.rerenderSubscription(), this.resizeTableColumnsSubscription(), this.searchOptionSubscription(), this.selectAllSubscription(), this.setImageStyleSubscription(), this.setNumberingTemplateTypeSubscription(), this.setParagraphStylesSubscription(), this.setTextStylesSubscription(), this.undoSubscription(), this.updateEdgeSubscription(), this.viewOnlyModeSubscription(), this.dragMoveSubscription(), this.dragDropSubscription());
5442
5483
  }
5443
5484
  destroy() {
5444
5485
  this.subscriptions.forEach(s => s?.unsubscribe());
@@ -5446,6 +5487,7 @@ class Editor {
5446
5487
  this.mouseHandler.destroy();
5447
5488
  this.inputHandler.destroy();
5448
5489
  this.documentHandler.destroy();
5490
+ this.dragAndDrop.destroyListeners();
5449
5491
  this.selection.blur();
5450
5492
  }
5451
5493
  selectPageDown() {
@@ -5965,6 +6007,10 @@ class Editor {
5965
6007
  this.session.restoreParagraphAndAddNumbering(operation);
5966
6008
  command = SaveCommandsHelper.getRestoreParagraphAndAddNumberingCommand(operation, this.targets);
5967
6009
  }
6010
+ else if (operation instanceof MoveRangeModel) {
6011
+ this.moveRange(operation);
6012
+ command = SaveCommandsHelper.getMoveRangeCommand(operation, []);
6013
+ }
5968
6014
  else {
5969
6015
  throw new Error('Undo/redo is not implemented for the Operation');
5970
6016
  }
@@ -5972,8 +6018,8 @@ class Editor {
5972
6018
  this.renderer.updateCursor();
5973
6019
  }
5974
6020
  saveRemoveToHistory(range) {
5975
- const restoreModel = this.createRestoreFromSlice(range.start.row, range.start.column, range.end.row, range.end.column);
5976
- const count = restoreModel.endIndex - restoreModel.startIndex + 1;
6021
+ const restoreModel = this.session.createRestoreFromSlice(range.start.row, range.start.column, range.end.row, range.end.column);
6022
+ const count = restoreModel.endIndex - restoreModel.startIndex;
5977
6023
  restoreModel.endIndex = restoreModel.startIndex; // this is to restore in position without deleting/replacing anything in range
5978
6024
  this.history.pushDelete(restoreModel);
5979
6025
  this.commandsService.createCommand(SaveCommandsHelper.getDeleteCommand(restoreModel.startIndex, count, this.targets));
@@ -6073,8 +6119,24 @@ class Editor {
6073
6119
  this.history.pushApplyImageStyle(previous, image);
6074
6120
  this.commandsService.createCommand(SaveCommandsHelper.getApplyImageStyleCommand(image.height, image.width, image.insertIndex, this.targets));
6075
6121
  }
6122
+ saveMoveRangeToHistory(redoModel, sourceSession, sourceRange) {
6123
+ const { sourceStartIndex, sourceCount, targetIndex } = redoModel;
6124
+ const isSameSession = sourceSession.session.sessionId === this.session.sessionId;
6125
+ const isMovingForward = targetIndex > sourceStartIndex;
6126
+ const undoSourceIndex = isSameSession && isMovingForward ? targetIndex - sourceCount : targetIndex;
6127
+ const undoTargetIndex = (isSameSession && isMovingForward) || !isSameSession ? sourceStartIndex : sourceStartIndex + sourceCount;
6128
+ const undoModel = new MoveRangeModel({
6129
+ sourceTargets: this.regulatorService.getCurrentSessionTargets(),
6130
+ targetTargets: this.regulatorService.getTargets(sourceSession),
6131
+ sourceStartIndex: undoSourceIndex,
6132
+ sourceCount,
6133
+ targetIndex: undoTargetIndex
6134
+ });
6135
+ this.history.pushMoveRange(undoModel, redoModel, sourceRange);
6136
+ this.commandsService.createCommand(SaveCommandsHelper.getMoveRangeCommand(redoModel, []));
6137
+ }
6076
6138
  saveReplaceToHistory(range, model) {
6077
- const restoreModel = this.createRestoreFromSlice(range.start.row, range.start.column, range.end.row, range.end.column);
6139
+ const restoreModel = this.session.createRestoreFromSlice(range.start.row, range.start.column, range.end.row, range.end.column);
6078
6140
  if (model.insertParagraph) {
6079
6141
  const { startIndex, count } = this.history.getDeleteDataForInsertParagraphs(ContentHelper.getContentFromInsertParagraph(model.insertParagraph), model.insertParagraph, this.session.model.paragraphs);
6080
6142
  restoreModel.startIndex = startIndex;
@@ -6086,20 +6148,6 @@ class Editor {
6086
6148
  this.history.pushReplace(restoreModel, model);
6087
6149
  this.commandsService.createCommand(SaveCommandsHelper.getReplaceCommand(model, this.targets));
6088
6150
  }
6089
- createRestoreFromSlice(paragraphStart, indexInStart, paragraphEnd, indexInEnd) {
6090
- const startIndex = ContentHelper.paragraphToDocumentIndex(this.session.displayData.paragraphs, paragraphStart, indexInStart);
6091
- const endIndex = ContentHelper.paragraphToDocumentIndex(this.session.displayData.paragraphs, paragraphEnd, indexInEnd) - 1;
6092
- const text = this.session.model.content.slice(startIndex, endIndex + 1);
6093
- const formats = FormatHelper.sliceSection(this.session.model.formats, startIndex, endIndex);
6094
- const paragraphs = IndexedElementHelper.sliceSection(this.session.model.paragraphs, startIndex, endIndex).map(x => new ParagraphModel(x));
6095
- const images = IndexedElementHelper.sliceSection(this.session.model.images, startIndex, endIndex).map(x => new ImageModel(x));
6096
- const tables = IndexedElementHelper.sliceSection(this.session.model.tables, startIndex, endIndex).map(x => new TableModel(x));
6097
- const elements = IndexedElementHelper.sliceSection(this.session.model.elements, startIndex, endIndex).map(x => new ElementModel({ ...x, id: 0, guid: '' }));
6098
- const breaks = IndexedElementHelper.sliceSection(this.session.model.breaks, startIndex, endIndex).map(x => new BreakModel(x));
6099
- const tabs = IndexedElementHelper.sliceSection(this.session.model.tabs, startIndex, endIndex).map(x => new TabModel(x));
6100
- const links = LinkHelper.sliceSection(this.session.model.links, startIndex, endIndex).map(x => new LinkModel(x));
6101
- return new RestoreModel({ startIndex, endIndex, text, formats, paragraphs, images, tables, elements, breaks, tabs, links });
6102
- }
6103
6151
  createCustomElement(data) {
6104
6152
  const insertIndex = ContentHelper.paragraphToDocumentIndex(this.session.displayData.paragraphs, this.selection.range.start.row, this.selection.range.start.column);
6105
6153
  const insertElement = new InsertElementModel({ element: new ElementModel({ ...data, insertIndex }) });
@@ -6138,7 +6186,7 @@ class Editor {
6138
6186
  }
6139
6187
  removeParagraphAndSetParagraphToNumbering() {
6140
6188
  const numberingId = this.session.displayData.paragraphs[this.selection.range.start.row].paragraphSettings.numberingData.numberingId;
6141
- const restoreModel = this.createRestoreFromSlice(this.selection.range.start.row, this.selection.range.start.column, this.selection.range.end.row, this.selection.range.end.column);
6189
+ const restoreModel = this.session.createRestoreFromSlice(this.selection.range.start.row, this.selection.range.start.column, this.selection.range.end.row, this.selection.range.end.column);
6142
6190
  restoreModel.endIndex = restoreModel.startIndex;
6143
6191
  this.removeCustomElementsData();
6144
6192
  this.session.remove(this.selection.range);
@@ -6230,6 +6278,28 @@ class Editor {
6230
6278
  }
6231
6279
  }
6232
6280
  onLeftClick(event) {
6281
+ const position = this.renderer.screenToTextCoordinatesUsingBoundary(event.clientX, event.clientY);
6282
+ if (!this.selection.isEmpty && this.session.isPositionInRange(position, this.selection.selectedRange)) {
6283
+ this.onSelectionLeftClick(event);
6284
+ }
6285
+ else {
6286
+ this.onShortLeftClick(event);
6287
+ }
6288
+ }
6289
+ onSelectionLeftClick(event) {
6290
+ const timer = setTimeout(() => {
6291
+ mouseUpSubscription.unsubscribe();
6292
+ this.dragAndDrop.onStart(this.regulatorService.currentSession, this.selection.selectedRange);
6293
+ this.onDragStart();
6294
+ }, 200);
6295
+ const mouseUpSubscription = fromEvent(document, 'mouseup')
6296
+ .pipe(take(1))
6297
+ .subscribe(() => {
6298
+ clearTimeout(timer);
6299
+ this.onShortLeftClick(event, true);
6300
+ });
6301
+ }
6302
+ onShortLeftClick(event, isSelectionClick = false) {
6233
6303
  const customElement = this.setCurrentSession(event.target);
6234
6304
  if (customElement && customElement.tagName !== this.tableCellTagName && customElement.tagName !== this.edgeElementTagName) {
6235
6305
  this.focusCustomComponent(customElement);
@@ -6253,7 +6323,9 @@ class Editor {
6253
6323
  return;
6254
6324
  }
6255
6325
  }
6256
- this.mouseHandler.startMousePress(this);
6326
+ if (!isSelectionClick) {
6327
+ this.mouseHandler.startMousePress(this);
6328
+ }
6257
6329
  }
6258
6330
  onDoubleClick(event) {
6259
6331
  const isEdgeEdit = this.mainSession.customComponents.edges.isEdit;
@@ -6320,6 +6392,52 @@ class Editor {
6320
6392
  event.stopPropagation();
6321
6393
  event.preventDefault();
6322
6394
  }
6395
+ onDragStart() {
6396
+ this.renderer.updateDragAndDropSelection(this.selection.selectedRange);
6397
+ this.selection.clearSelection();
6398
+ this.onSelectionChange();
6399
+ }
6400
+ onDragMove(event) {
6401
+ this.setCurrentSession(event.target);
6402
+ const cursorPosition = this.renderer.screenToTextCoordinatesUsingMidpoint(event.clientX, event.clientY);
6403
+ if (cursorPosition.row === this.selection.cursor.row && cursorPosition.column === this.selection.cursor.column) {
6404
+ return;
6405
+ }
6406
+ this.selection.placeCursor(cursorPosition);
6407
+ this.renderer.showStaticCursor();
6408
+ this.renderer.updateCursor();
6409
+ }
6410
+ onDragDrop(sourceSession, sourceRange) {
6411
+ sourceSession.renderer.clearDragAndDropSelection();
6412
+ const sourceStartIndex = sourceSession.session.displayData.positionToIndex(sourceRange.start);
6413
+ const sourceEndIndex = sourceSession.session.displayData.positionToIndex(sourceRange.end);
6414
+ const targetIndex = this.session.displayData.positionToIndex(this.selection.cursor);
6415
+ if (sourceSession.sessionId === this.session.sessionId && sourceStartIndex <= targetIndex && sourceEndIndex >= targetIndex) {
6416
+ this.selection.placeSelection(sourceRange.start, sourceRange.end);
6417
+ this.onSelectionChange();
6418
+ return;
6419
+ }
6420
+ const model = new MoveRangeModel({
6421
+ sourceStartIndex,
6422
+ sourceCount: sourceEndIndex - sourceStartIndex,
6423
+ targetIndex,
6424
+ sourceTargets: this.regulatorService.getTargets(sourceSession),
6425
+ targetTargets: this.regulatorService.getCurrentSessionTargets()
6426
+ });
6427
+ this.moveRange(model);
6428
+ this.saveMoveRangeToHistory(model, sourceSession, sourceRange);
6429
+ this.onSelectionChange();
6430
+ }
6431
+ moveRange(model) {
6432
+ this.regulatorService.setTargetedSessionAsCurrent(model.targetTargets);
6433
+ const sourceSession = this.regulatorService.getTargetedSession(model.sourceTargets);
6434
+ const restoreModel = sourceSession.removeMoveRange(model);
6435
+ const movedRange = this.session.restoreMoveRange(restoreModel, model, sourceSession.sessionId);
6436
+ if (sourceSession.sessionId !== this.session.sessionId) {
6437
+ sourceSession.selection.clearSelection();
6438
+ }
6439
+ this.session.selection.placeSelection(movedRange.start, movedRange.end);
6440
+ }
6323
6441
  getLinkModel(event) {
6324
6442
  const isInsideEdge = this.isInsideEdge(event.target);
6325
6443
  const isEdgeEdit = this.mainSession.customComponents.edges.isEdit;
@@ -6371,7 +6489,7 @@ class Editor {
6371
6489
  }
6372
6490
  }
6373
6491
  /**
6374
- * Returns the string of text currently highlighted.
6492
+ * Returns the string of text range.
6375
6493
  */
6376
6494
  getSelectedText() {
6377
6495
  const selectionRange = this.selection.selectedRange;
@@ -6693,6 +6811,12 @@ class Editor {
6693
6811
  removeLeftSubscription() {
6694
6812
  return this.editorService.removeLeft$.subscribe(() => this.removeLeft());
6695
6813
  }
6814
+ dragMoveSubscription() {
6815
+ return this.dragAndDrop.onMove$.subscribe(x => this.onDragMove(x));
6816
+ }
6817
+ dragDropSubscription() {
6818
+ return this.dragAndDrop.onDrop$.subscribe(x => this.onDragDrop(x.sourceSession, x.sourceRange));
6819
+ }
6696
6820
  printSubscription() {
6697
6821
  return this.editorService.print$.subscribe(() => this.onPrint());
6698
6822
  }
@@ -7530,6 +7654,10 @@ class TableSelection {
7530
7654
  !this.canStartSelection(event.target)) {
7531
7655
  return;
7532
7656
  }
7657
+ const position = this.regulatorService.currentSession.renderer.screenToTextCoordinatesUsingBoundary(event.clientX, event.clientY);
7658
+ if (!this.session.selection.isEmpty && this.session.isPositionInRange(position, this.session.selection.selectedRange)) {
7659
+ return;
7660
+ }
7533
7661
  this.overlayService.close();
7534
7662
  this.removeMouseSubscriptions();
7535
7663
  this.clearSelectionInAllCells();
@@ -7988,7 +8116,7 @@ class NoderTableComponent extends BaseNoderComponent {
7988
8116
  let currentTargetIndex = targetIndex;
7989
8117
  while (i < cellsCount) {
7990
8118
  const modelCellIndex = modelTargetIndex + i;
7991
- if (this.table.rows[rowIndex].cells[modelCellIndex].verticalMerge === VerticalMerge.Merge) {
8119
+ if (rowIndex > 0 && this.table.rows[rowIndex].cells[modelCellIndex].verticalMerge === VerticalMerge.Merge) {
7992
8120
  const inheritCellData = this.rowMatrix[rowIndex - 1].cells[currentTargetIndex];
7993
8121
  const count = this.table.rows[rowIndex].cells[modelCellIndex].horizontalMerge ?? 1;
7994
8122
  this.addAdditionalCells(rowIndex, currentTargetIndex, count, inheritCellData);
@@ -9679,6 +9807,57 @@ class EdgeSessionSourceModel {
9679
9807
  }
9680
9808
  }
9681
9809
 
9810
+ class BreakModel {
9811
+ constructor(fields) {
9812
+ if (fields) {
9813
+ Object.assign(this, fields);
9814
+ }
9815
+ }
9816
+ }
9817
+
9818
+ class BordersStyleModel {
9819
+ constructor(fields) {
9820
+ if (fields) {
9821
+ Object.assign(this, fields);
9822
+ }
9823
+ }
9824
+ }
9825
+
9826
+ class ImageModel {
9827
+ constructor(fields) {
9828
+ if (fields) {
9829
+ if (fields.border) {
9830
+ fields.border = new BordersStyleModel(fields.border);
9831
+ }
9832
+ Object.assign(this, fields);
9833
+ }
9834
+ }
9835
+ }
9836
+
9837
+ class TabModel {
9838
+ constructor(fields) {
9839
+ if (fields) {
9840
+ Object.assign(this, fields);
9841
+ }
9842
+ }
9843
+ }
9844
+
9845
+ class ContentsOperationsHelper {
9846
+ static GetRestoreFromSlice(contents, startIndex, count) {
9847
+ const endIndex = startIndex + count;
9848
+ const text = contents.content.slice(startIndex, endIndex);
9849
+ const formats = FormatHelper.sliceSection(contents.formats, startIndex, endIndex);
9850
+ const paragraphs = IndexedElementHelper.sliceSection(contents.paragraphs, startIndex, endIndex).map(x => new ParagraphModel(x));
9851
+ const images = IndexedElementHelper.sliceSection(contents.images, startIndex, endIndex).map(x => new ImageModel(x));
9852
+ const tables = IndexedElementHelper.sliceSection(contents.tables, startIndex, endIndex).map(x => new TableModel(x));
9853
+ const elements = IndexedElementHelper.sliceSection(contents.elements, startIndex, endIndex).map(x => new ElementModel({ ...x, id: 0, guid: '' }));
9854
+ const breaks = IndexedElementHelper.sliceSection(contents.breaks, startIndex, endIndex).map(x => new BreakModel(x));
9855
+ const tabs = IndexedElementHelper.sliceSection(contents.tabs, startIndex, endIndex).map(x => new TabModel(x));
9856
+ const links = LinkHelper.sliceSection(contents.links, startIndex, endIndex).map(x => new LinkModel(x));
9857
+ return new RestoreModel({ startIndex, endIndex, text, formats, paragraphs, images, tables, elements, breaks, tabs, links });
9858
+ }
9859
+ }
9860
+
9682
9861
  class CustomComponentHelper {
9683
9862
  static applyRemovingComponents(components, startIndex, endIndex) {
9684
9863
  let firstRemovingIndex = null;
@@ -10962,7 +11141,32 @@ class TabOperationsHelper {
10962
11141
  }
10963
11142
 
10964
11143
  class TargetOperationsHelper {
10965
- static getContents(contents, target, document) {
11144
+ static getContents(document, targets) {
11145
+ let result = document;
11146
+ for (const target of targets) {
11147
+ result = this.getTargetContents(result, target, document);
11148
+ }
11149
+ return result;
11150
+ }
11151
+ static isSame(first, second) {
11152
+ if (first.length !== second.length) {
11153
+ return false;
11154
+ }
11155
+ for (let i = 0; i < first.length; i++) {
11156
+ const firstElement = first[i];
11157
+ const secondElement = second[i];
11158
+ const areEdgeSame = firstElement.edgeData?.type === secondElement.edgeData?.type &&
11159
+ firstElement.edgeData?.pageType === secondElement.edgeData?.pageType;
11160
+ const areTableCellSame = firstElement.tableCell?.row === secondElement.tableCell?.row &&
11161
+ firstElement.tableCell?.column === secondElement.tableCell?.column &&
11162
+ firstElement.tableCell?.insertIndex === secondElement.tableCell?.insertIndex;
11163
+ if (firstElement.type !== secondElement.type || !areEdgeSame || !areTableCellSame) {
11164
+ return false;
11165
+ }
11166
+ }
11167
+ return true;
11168
+ }
11169
+ static getTargetContents(contents, target, document) {
10966
11170
  switch (target.type) {
10967
11171
  case TargetType.Document:
10968
11172
  return contents;
@@ -10985,7 +11189,7 @@ class TargetOperationsHelper {
10985
11189
  class OperationsHelper {
10986
11190
  static applyOperations(document, commands) {
10987
11191
  commands.forEach(command => {
10988
- const contents = this.getTargetContents(document, command);
11192
+ const contents = TargetOperationsHelper.getContents(document, command.targets);
10989
11193
  switch (command.commandType) {
10990
11194
  case CommandType.InsertText:
10991
11195
  this.insertText(contents, command.insertText.text, command.insertText.insertIndex);
@@ -11141,15 +11345,42 @@ class OperationsHelper {
11141
11345
  this.deleteRestore(contents, model.restore);
11142
11346
  break;
11143
11347
  }
11348
+ case CommandType.MoveRange: {
11349
+ const model = command.moveRange;
11350
+ this.moveRange(document, model);
11351
+ break;
11352
+ }
11144
11353
  }
11145
11354
  });
11146
11355
  }
11147
- static getTargetContents(document, command) {
11148
- let result = document;
11149
- for (const target of command.targets) {
11150
- result = TargetOperationsHelper.getContents(result, target, document);
11151
- }
11152
- return result;
11356
+ static moveRange(document, model) {
11357
+ const sourceContents = TargetOperationsHelper.getContents(document, model.sourceTargets);
11358
+ const targetContents = TargetOperationsHelper.getContents(document, model.targetTargets);
11359
+ const restore = this.removeMoveRange(sourceContents, model);
11360
+ this.restoreMoveRange(targetContents, model, restore);
11361
+ }
11362
+ static removeMoveRange(sourceContents, model) {
11363
+ const restore = ContentsOperationsHelper.GetRestoreFromSlice(sourceContents, model.sourceStartIndex, model.sourceCount);
11364
+ this.delete(sourceContents, model.sourceStartIndex, model.sourceCount);
11365
+ return restore;
11366
+ }
11367
+ static restoreMoveRange(targetContents, model, restoreContents) {
11368
+ const moveIndex = TargetOperationsHelper.isSame(model.sourceTargets, model.targetTargets) && model.targetIndex > model.sourceStartIndex
11369
+ ? model.targetIndex - model.sourceCount
11370
+ : model.targetIndex;
11371
+ const offset = moveIndex - restoreContents.startIndex;
11372
+ FormatHelper.shiftIndexes(restoreContents.formats, offset);
11373
+ IndexedElementHelper.shiftIndexes(restoreContents.paragraphs, offset);
11374
+ IndexedElementHelper.shiftIndexes(restoreContents.images, offset);
11375
+ IndexedElementHelper.shiftIndexes(restoreContents.tables, offset);
11376
+ IndexedElementHelper.shiftIndexes(restoreContents.elements, offset);
11377
+ IndexedElementHelper.shiftIndexes(restoreContents.breaks, offset);
11378
+ IndexedElementHelper.shiftIndexes(restoreContents.tabs, offset);
11379
+ LinkHelper.shiftIndexes(restoreContents.links, offset);
11380
+ restoreContents.startIndex = moveIndex;
11381
+ restoreContents.endIndex = moveIndex;
11382
+ this.restore(targetContents, restoreContents);
11383
+ return moveIndex;
11153
11384
  }
11154
11385
  static getContentWidth(document, contents) {
11155
11386
  let contentWidth = 0;
@@ -11907,6 +12138,57 @@ class EditSession {
11907
12138
  }
11908
12139
  return endPoint;
11909
12140
  }
12141
+ removeMoveRange(moveModel) {
12142
+ const endIndex = moveModel.sourceStartIndex + moveModel.sourceCount;
12143
+ const startPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, moveModel.sourceStartIndex);
12144
+ const endPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, endIndex);
12145
+ const sourceRange = new Range(startPosition, endPosition);
12146
+ this.displayData.removeRange(sourceRange);
12147
+ CustomComponentHelper.applyRemovingComponents(this.customComponents.tables, moveModel.sourceStartIndex, endIndex);
12148
+ CustomComponentHelper.applyRemovingComponents(this.customComponents.images, moveModel.sourceStartIndex, endIndex);
12149
+ CustomComponentHelper.applyRemovingComponents(this.customComponents.customElements, moveModel.sourceStartIndex, endIndex);
12150
+ CustomComponentHelper.applyRemovingComponents(this.customComponents.tabs, moveModel.sourceStartIndex, endIndex);
12151
+ const restoreModel = OperationsHelper.removeMoveRange(this.model, moveModel);
12152
+ this.selection.placeCursor(startPosition);
12153
+ this.displayData.resetAllNumberingInfo(startPosition.row);
12154
+ this.displayData.updateNextLineIndexes(startPosition.row, endPosition.row);
12155
+ if (endPosition.row - startPosition.row && this.type !== 'cell') {
12156
+ this.displayData.updateNumberingsDataOnChange(startPosition.row + 1);
12157
+ }
12158
+ this.applyToolbarStyles();
12159
+ return restoreModel;
12160
+ }
12161
+ restoreMoveRange(restoreModel, moveModel, _sourceSessionId) {
12162
+ const moveIndex = OperationsHelper.restoreMoveRange(this.model, moveModel, restoreModel);
12163
+ const endIndex = moveIndex + moveModel.sourceCount;
12164
+ this.restoreComponents(this.model.tables, this.customComponents.tables, NoderTableComponent, moveIndex, endIndex);
12165
+ this.restoreComponents(this.model.images, this.customComponents.images, NoderImageComponent, moveIndex, endIndex);
12166
+ this.restoreComponents(this.model.tabs, this.customComponents.tabs, NoderTabComponent, moveIndex, endIndex);
12167
+ this.restoreElementComponents(this.model.elements, moveIndex, endIndex);
12168
+ const startPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, moveIndex);
12169
+ const endPosition = this.displayData.insertText(startPosition, restoreModel.text);
12170
+ this.displayData.resetAllNumberingInfo(startPosition.row);
12171
+ this.displayData.updateNextLineIndexes(startPosition.row, endPosition.row);
12172
+ if (endPosition.row - startPosition.row && this.type !== 'cell') {
12173
+ this.displayData.updateNumberingsDataOnChange(endPosition.row);
12174
+ }
12175
+ this.selection.placeCursor(endPosition);
12176
+ this.applyToolbarStyles();
12177
+ const newStartPosition = this.displayData.indexToPosition(moveIndex, 0);
12178
+ const newEndPosition = this.displayData.indexToPosition(moveIndex + moveModel.sourceCount, 0);
12179
+ return new Range(newStartPosition, newEndPosition);
12180
+ }
12181
+ isPositionInRange(position, range) {
12182
+ const positionIndex = this.displayData.positionToIndex(position);
12183
+ const startIndex = this.displayData.positionToIndex(range.start);
12184
+ const endIndex = this.displayData.positionToIndex(range.end);
12185
+ return positionIndex >= startIndex && positionIndex < endIndex;
12186
+ }
12187
+ createRestoreFromSlice(paragraphStart, indexInStart, paragraphEnd, indexInEnd) {
12188
+ const startIndex = ContentHelper.paragraphToDocumentIndex(this.displayData.paragraphs, paragraphStart, indexInStart);
12189
+ const endIndex = ContentHelper.paragraphToDocumentIndex(this.displayData.paragraphs, paragraphEnd, indexInEnd);
12190
+ return ContentsOperationsHelper.GetRestoreFromSlice(this.model, startIndex, endIndex);
12191
+ }
11910
12192
  addComponent(customElements, model, componentType) {
11911
12193
  const customElement = this.customContentService.componentService.createComponent(componentType, {
11912
12194
  content: model,
@@ -12103,6 +12385,11 @@ class CursorLayer {
12103
12385
  DomHelper.removeCssClass(this.layer, 'noder-hidden-cursors');
12104
12386
  this.addAnimationClass();
12105
12387
  }
12388
+ showStaticCursor() {
12389
+ this.isVisible = true;
12390
+ DomHelper.removeCssClass(this.layer, 'noder-hidden-cursors');
12391
+ this.removeAnimationClass();
12392
+ }
12106
12393
  detectVisibility() {
12107
12394
  const selectionRange = this.session.selection.selectedRange;
12108
12395
  if (selectionRange.isEmpty) {
@@ -12180,7 +12467,15 @@ class CursorLayer {
12180
12467
 
12181
12468
  class RenderChangesModel {
12182
12469
  get any() {
12183
- return this.cursor || this.full || this.lines || this.marker || this.selection || this.scroll || this.size || this.text;
12470
+ return (this.cursor ||
12471
+ this.full ||
12472
+ this.lines ||
12473
+ this.marker ||
12474
+ this.selection ||
12475
+ this.scroll ||
12476
+ this.size ||
12477
+ this.text ||
12478
+ this.dragAndDrop);
12184
12479
  }
12185
12480
  constructor(fields) {
12186
12481
  this.cursor = false;
@@ -12191,6 +12486,7 @@ class RenderChangesModel {
12191
12486
  this.scroll = false;
12192
12487
  this.size = false;
12193
12488
  this.text = false;
12489
+ this.dragAndDrop = false;
12194
12490
  if (!fields) {
12195
12491
  return;
12196
12492
  }
@@ -12399,6 +12695,7 @@ class Renderer extends EventEmitting {
12399
12695
  this.textLayer = new TextLayer(this.content, this.session);
12400
12696
  this.selectionLayer = new SelectionLayer(this.content, 'text-selection', this.session);
12401
12697
  this.cursorLayer = new CursorLayer(this.content, this.session);
12698
+ this.dragAndDropSelectionLayer = new SelectionLayer(this.content, 'drag-and-drop-selection', this.session);
12402
12699
  this.loop = new RenderLoop(changes => this.renderChanges(changes));
12403
12700
  this.session.displayData.addEventListener('pagesCountChanged', this.pagesCountChangedHandler);
12404
12701
  }
@@ -12430,6 +12727,9 @@ class Renderer extends EventEmitting {
12430
12727
  if (changes.marker || changes.selection) {
12431
12728
  this.renderSelection();
12432
12729
  }
12730
+ if (changes.dragAndDrop) {
12731
+ this.renderDragAndDropSelection();
12732
+ }
12433
12733
  this.session.onRendered();
12434
12734
  }
12435
12735
  /**
@@ -12471,6 +12771,23 @@ class Renderer extends EventEmitting {
12471
12771
  this.loop.schedule({ selection: true });
12472
12772
  }
12473
12773
  }
12774
+ updateDragAndDropSelection(range) {
12775
+ if (range.isEmpty && this.dragAndDropSelectionLayer.marker) {
12776
+ this.dragAndDropSelectionLayer.marker = null;
12777
+ this.loop.schedule({ dragAndDrop: true });
12778
+ }
12779
+ else if (!range.isEmpty && !this.dragAndDropSelectionLayer.marker?.isEqual(range)) {
12780
+ this.dragAndDropSelectionLayer.marker = range;
12781
+ this.loop.schedule({ dragAndDrop: true });
12782
+ }
12783
+ }
12784
+ clearDragAndDropSelection() {
12785
+ if (!this.dragAndDropSelectionLayer.marker) {
12786
+ return;
12787
+ }
12788
+ this.dragAndDropSelectionLayer.marker = null;
12789
+ this.loop.schedule({ dragAndDrop: true });
12790
+ }
12474
12791
  /**
12475
12792
  * Triggers a full update of the text, for all the rows.
12476
12793
  **/
@@ -12501,6 +12818,9 @@ class Renderer extends EventEmitting {
12501
12818
  showCursor() {
12502
12819
  this.cursorLayer.showCursor();
12503
12820
  }
12821
+ showStaticCursor() {
12822
+ this.cursorLayer.showStaticCursor();
12823
+ }
12504
12824
  hideCursor() {
12505
12825
  this.cursorLayer.hideCursor();
12506
12826
  }
@@ -12528,6 +12848,9 @@ class Renderer extends EventEmitting {
12528
12848
  this.selectionLayer.update(this.layerConfig);
12529
12849
  this.cursorLayer.detectVisibility();
12530
12850
  }
12851
+ renderDragAndDropSelection() {
12852
+ this.dragAndDropSelectionLayer.update(this.layerConfig);
12853
+ }
12531
12854
  computeLayerConfig() {
12532
12855
  const displayData = this.session.displayData;
12533
12856
  const maxHeight = displayData.allPagesHeight;
@@ -12728,6 +13051,9 @@ class VirtualRenderer {
12728
13051
  if (changes.marker || changes.selection) {
12729
13052
  this.renderSelection();
12730
13053
  }
13054
+ if (changes.dragAndDrop) {
13055
+ this.renderDragAndDropSelection();
13056
+ }
12731
13057
  }
12732
13058
  /**
12733
13059
  * Triggers a resize of the editor
@@ -12791,6 +13117,12 @@ class VirtualRenderer {
12791
13117
  updateSelection(range) {
12792
13118
  this.renderer.updateSelection(range);
12793
13119
  }
13120
+ updateDragAndDropSelection(range) {
13121
+ this.renderer.updateDragAndDropSelection(range);
13122
+ }
13123
+ clearDragAndDropSelection() {
13124
+ this.renderer.clearDragAndDropSelection();
13125
+ }
12794
13126
  /**
12795
13127
  * Triggers a full update of the text, for all the rows.
12796
13128
  **/
@@ -12850,6 +13182,9 @@ class VirtualRenderer {
12850
13182
  hideCursor() {
12851
13183
  this.renderer.hideCursor();
12852
13184
  }
13185
+ showStaticCursor() {
13186
+ this.renderer.showStaticCursor();
13187
+ }
12853
13188
  destroy() {
12854
13189
  DomHelper.removeElement(this.scrollBar.element);
12855
13190
  this.pagesLayer.destroy();
@@ -12928,6 +13263,9 @@ class VirtualRenderer {
12928
13263
  renderSelection() {
12929
13264
  this.renderer.renderSelection();
12930
13265
  }
13266
+ renderDragAndDropSelection() {
13267
+ this.renderer.renderDragAndDropSelection();
13268
+ }
12931
13269
  }
12932
13270
 
12933
13271
  class CustomContentService {