@talrace/ngx-noder 0.0.33 → 0.0.35

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.
@@ -1112,6 +1112,24 @@ class BreakModel {
1112
1112
  }
1113
1113
  }
1114
1114
 
1115
+ class ContentOperationsHelper {
1116
+ static removeContent(content, startIndex, count) {
1117
+ return `${content.slice(0, startIndex)}${content.slice(startIndex + count, content.length)}`;
1118
+ }
1119
+ static sliceContent(content, startIndex, count) {
1120
+ return content.slice(startIndex, startIndex + count);
1121
+ }
1122
+ static insertContent(content, text, index) {
1123
+ const before = content.slice(0, index);
1124
+ const after = content.slice(index, content.length);
1125
+ return `${before}${text}${after}`;
1126
+ }
1127
+ static replaceContent(content, startIndex, endIndex, text) {
1128
+ const reduced = this.removeContent(content, startIndex, endIndex - startIndex + 1);
1129
+ return this.insertContent(reduced, text, startIndex);
1130
+ }
1131
+ }
1132
+
1115
1133
  class ElementModel {
1116
1134
  constructor(fields) {
1117
1135
  if (fields) {
@@ -1278,8 +1296,8 @@ class TabModel {
1278
1296
 
1279
1297
  class ContentsOperationsHelper {
1280
1298
  static GetRestoreFromSlice(contents, startIndex, count) {
1299
+ const text = ContentOperationsHelper.sliceContent(contents.content, startIndex, count);
1281
1300
  const endIndex = startIndex + count - 1;
1282
- const text = contents.content.slice(startIndex, endIndex + 1);
1283
1301
  const formats = FormatHelper.sliceSection(contents.formats, startIndex, endIndex);
1284
1302
  const paragraphs = IndexedElementHelper.sliceSection(contents.paragraphs, startIndex, endIndex).map(x => new ParagraphModel(x));
1285
1303
  const images = IndexedElementHelper.sliceSection(contents.images, startIndex, endIndex).map(x => new ImageModel(x));
@@ -3231,6 +3249,7 @@ const DisplayValue = {
3231
3249
  customContent: 3,
3232
3250
  punctuation: 9,
3233
3251
  space: 10,
3252
+ trailingSpace: 11,
3234
3253
  emptyLine: 13
3235
3254
  };
3236
3255
 
@@ -3328,12 +3347,18 @@ class PositionHelper {
3328
3347
  const sizeNext = tokens[tokenIndex + 1];
3329
3348
  let sizeMax = { ...size };
3330
3349
  let lineWidthToPosition = session.displayData.pageMargin.left;
3350
+ const { paragraphIndex, lineIndex } = this.findLineInParagraphs(paragraphs, row);
3351
+ const lineInfo = paragraphs[paragraphIndex].paragraphSettings.textLinesInfo[lineIndex];
3331
3352
  for (let currentColumn = 0; currentColumn < tokens.length; currentColumn++) {
3353
+ const currentToken = tokens[currentColumn];
3332
3354
  if (currentColumn < column) {
3333
- lineWidthToPosition += tokens[currentColumn].width;
3355
+ lineWidthToPosition += currentToken.width;
3356
+ if (currentToken.displayValue === DisplayValue.space && lineInfo.wordSpacing) {
3357
+ lineWidthToPosition += lineInfo.wordSpacing;
3358
+ }
3334
3359
  }
3335
- if (sizeMax.ascent < tokens[currentColumn].ascent) {
3336
- sizeMax = tokens[currentColumn];
3360
+ if (sizeMax.ascent < currentToken.ascent) {
3361
+ sizeMax = currentToken;
3337
3362
  }
3338
3363
  }
3339
3364
  if (tokens[tokenIndex]?.isTable) {
@@ -3385,15 +3410,23 @@ class PositionHelper {
3385
3410
  */
3386
3411
  static mapPixelToClosestTokenMidpoint(session, xPixel, paragraphIndex, lineIndex, leftOffset) {
3387
3412
  const paragraphSettings = session.displayData.paragraphs[paragraphIndex].paragraphSettings;
3388
- const line = paragraphSettings.textLinesInfo[lineIndex].screenLine;
3389
- let indexInLine = 0;
3390
- let relativeX = xPixel - leftOffset - session.displayData.pageMargin.left - paragraphSettings.textLinesInfo[lineIndex].paddingLeft;
3391
3413
  const tokens = LineWidthHelper.getParagraphLineDisplayTokens(session, paragraphIndex, lineIndex);
3414
+ const lineInfo = paragraphSettings.textLinesInfo[lineIndex];
3415
+ const line = lineInfo.screenLine;
3392
3416
  if (tokens[0].displayValue === DisplayValue.emptyLine) {
3393
- return { line, indexInLine };
3417
+ return { line, indexInLine: 0 };
3394
3418
  }
3395
- while (indexInLine < tokens.length && relativeX >= tokens[indexInLine].width / 2) {
3396
- relativeX -= tokens[indexInLine].width;
3419
+ let indexInLine = 0;
3420
+ let relativeX = xPixel - leftOffset - session.displayData.pageMargin.left - lineInfo.paddingLeft;
3421
+ const wordSpacing = lineInfo.wordSpacing ?? 0;
3422
+ while (indexInLine < tokens.length) {
3423
+ const token = tokens[indexInLine];
3424
+ const isSpace = token.displayValue === DisplayValue.space;
3425
+ const width = token.width + (isSpace ? wordSpacing : 0);
3426
+ if (relativeX < width / 2) {
3427
+ break;
3428
+ }
3429
+ relativeX -= width;
3397
3430
  indexInLine++;
3398
3431
  }
3399
3432
  return { line, indexInLine };
@@ -3403,15 +3436,23 @@ class PositionHelper {
3403
3436
  */
3404
3437
  static mapPixelToNextTokenBoundary(session, xPixel, paragraphIndex, lineIndex, leftOffset) {
3405
3438
  const paragraphSettings = session.displayData.paragraphs[paragraphIndex].paragraphSettings;
3406
- const line = paragraphSettings.textLinesInfo[lineIndex].screenLine;
3407
- let indexInLine = 0;
3408
- let relativeX = xPixel - leftOffset - session.displayData.pageMargin.left - paragraphSettings.textLinesInfo[lineIndex].paddingLeft;
3409
3439
  const tokens = LineWidthHelper.getParagraphLineDisplayTokens(session, paragraphIndex, lineIndex);
3440
+ const lineInfo = paragraphSettings.textLinesInfo[lineIndex];
3441
+ const line = lineInfo.screenLine;
3410
3442
  if (tokens[0].displayValue === DisplayValue.emptyLine) {
3411
- return { line, indexInLine };
3443
+ return { line, indexInLine: 0 };
3412
3444
  }
3413
- while (indexInLine < tokens.length && relativeX >= tokens[indexInLine].width) {
3414
- relativeX -= tokens[indexInLine].width;
3445
+ let indexInLine = 0;
3446
+ let relativeX = xPixel - leftOffset - session.displayData.pageMargin.left - lineInfo.paddingLeft;
3447
+ const wordSpacing = lineInfo.wordSpacing ?? 0;
3448
+ while (indexInLine < tokens.length) {
3449
+ const token = tokens[indexInLine];
3450
+ const isSpace = token.displayValue === DisplayValue.space;
3451
+ const width = token.width + (isSpace ? wordSpacing : 0);
3452
+ if (relativeX < width) {
3453
+ break;
3454
+ }
3455
+ relativeX -= width;
3415
3456
  indexInLine++;
3416
3457
  }
3417
3458
  return { line, indexInLine };
@@ -3439,9 +3480,15 @@ class PositionHelper {
3439
3480
  return column;
3440
3481
  }
3441
3482
  const textLineInfo = paragraphs[paragraphIndex].paragraphSettings.textLinesInfo[lineIndex];
3483
+ const wordSpacing = textLineInfo.wordSpacing ?? 0;
3442
3484
  let width = positionWidth - textLineInfo.paddingLeft - documentMargin.left;
3443
- while (column < tokens.length && width >= tokens[column].width) {
3444
- width -= tokens[column].width;
3485
+ while (column < tokens.length) {
3486
+ const token = tokens[column];
3487
+ if (width < token.width) {
3488
+ break;
3489
+ }
3490
+ const isSpace = token.displayValue === DisplayValue.space;
3491
+ width -= token.width + (isSpace ? wordSpacing : 0);
3445
3492
  column++;
3446
3493
  }
3447
3494
  return column;
@@ -3520,17 +3567,17 @@ class RenderingHelper {
3520
3567
  if (lineInfo) {
3521
3568
  const paddingLeft = ScalingHelper.scale(lineInfo.paddingLeft, scalingRatio);
3522
3569
  const marginLeft = numberingOffsetLeft > 0 ? -numberingOffsetLeft : 0;
3523
- lineEl.setAttribute('style',
3524
3570
  // eslint-disable-next-line prettier/prettier
3525
- `padding-left:${paddingLeft}px;height:${lineInfo.height + lineInfo.offsetAfter}px;margin-top:${lineInfo.offsetBefore}px;margin-bottom:${lineInfo.endPageOffset}px;margin-left:${marginLeft}px;background-color:${lineInfo.backgroundColor}`);
3526
- lineEl.setAttribute('screen-index', `${lineInfo.screenLine}`);
3571
+ let styleString = `padding-left:${paddingLeft}px;height:${lineInfo.height + lineInfo.offsetAfter}px;margin-top:${lineInfo.offsetBefore}px;margin-bottom:${lineInfo.endPageOffset}px;margin-left:${marginLeft}px;background-color:${lineInfo.backgroundColor};`;
3527
3572
  if (lineInfo.wordSpacing) {
3528
- lineEl.style.wordSpacing = `${lineInfo.wordSpacing}px`;
3573
+ styleString += `word-spacing:${lineInfo.wordSpacing}px;`;
3529
3574
  }
3575
+ lineEl.setAttribute('style', styleString);
3576
+ lineEl.setAttribute('screen-index', `${lineInfo.screenLine}`);
3530
3577
  }
3531
3578
  return lineEl;
3532
3579
  }
3533
- static renderContentSimpleLine(domContent, formatsExt, rowDistance, customContentService, customComponents, breaks = []) {
3580
+ static renderContentSimpleLine(domContent, formatsExt, rowDistance, customContentService, customComponents, lineInfo, breaks = []) {
3534
3581
  const valueFragment = DomHelper.createFragment(domContent.currentElement);
3535
3582
  for (const formatExt of formatsExt) {
3536
3583
  const fragmentDocumentStartIndex = rowDistance.start > formatExt.startIndex ? rowDistance.start : formatExt.startIndex;
@@ -3539,7 +3586,7 @@ class RenderingHelper {
3539
3586
  const fragmentStartIndex = rowDistance.start > formatExt.startIndex ? rowDistance.start - formatExt.startIndex : 0;
3540
3587
  const fragmentEndIndex = formatExt.endIndex > rowDistance.end ? rowDistance.end - formatExt.startIndex : formatExt.endIndex - formatExt.startIndex;
3541
3588
  const fragmentDistance = new DistanceModel({ start: fragmentStartIndex, end: fragmentEndIndex });
3542
- this.renderFormatContent(valueFragment, formatExt, fragmentDocumentDistance, fragmentDistance, customContentService, customComponents, breaks);
3589
+ this.renderFormatContent(valueFragment, formatExt, fragmentDocumentDistance, fragmentDistance, customContentService, customComponents, breaks, lineInfo, true);
3543
3590
  }
3544
3591
  domContent.parentNode.appendChild(valueFragment);
3545
3592
  }
@@ -3551,8 +3598,10 @@ class RenderingHelper {
3551
3598
  let lineEl = RenderingHelper.createLineElement(currentParagraph.textLinesInfo[splitIndex], numberingOffsetLeft, scalingRatio);
3552
3599
  domContent.parentNode.appendChild(lineEl);
3553
3600
  const valueFragment = DomHelper.createFragment(domContent.currentElement);
3601
+ let isLastLineFragment = false;
3554
3602
  let paragraphChars = 0;
3555
3603
  let split = splits[splitIndex];
3604
+ let lineInfo = currentParagraph.textLinesInfo[splitIndex];
3556
3605
  for (const formatExt of formatsExt) {
3557
3606
  const beforeSplitIndex = split ? split - 1 : distance.end - distance.start;
3558
3607
  const beforeSplitDocumentIndex = distance.start + beforeSplitIndex;
@@ -3564,13 +3613,15 @@ class RenderingHelper {
3564
3613
  ? fragmentStartIndex + formatExt.endIndex - formatExt.startIndex
3565
3614
  : distance.start + beforeSplitIndex - formatExt.startIndex;
3566
3615
  const fragmentDistance = new DistanceModel({ start: fragmentStartIndex, end: fragmentEndIndex });
3567
- paragraphChars += this.renderFormatContent(valueFragment, formatExt, fragmentDocumentDistance, fragmentDistance, customContentService, customComponents, breaks);
3616
+ isLastLineFragment = split === fragmentDocumentDistance.end + 1;
3617
+ paragraphChars += this.renderFormatContent(valueFragment, formatExt, fragmentDocumentDistance, fragmentDistance, customContentService, customComponents, breaks, lineInfo, isLastLineFragment);
3568
3618
  lineEl.appendChild(valueFragment);
3569
3619
  let nextFragmentStartIndex = fragmentEndIndex + 1;
3570
3620
  while (paragraphChars === split && nextFragmentStartIndex !== distance.end) {
3571
3621
  split = splits[++splitIndex];
3622
+ lineInfo = currentParagraph.textLinesInfo[splitIndex];
3572
3623
  const nextFragmentDocumentStartIndex = fragmentDocumentStartIndex + nextFragmentStartIndex - fragmentStartIndex;
3573
- lineEl = RenderingHelper.createLineElement(currentParagraph.textLinesInfo[splitIndex], numberingOffsetLeft, scalingRatio);
3624
+ lineEl = RenderingHelper.createLineElement(lineInfo, numberingOffsetLeft, scalingRatio);
3574
3625
  if (split > formatExt.endIndex) {
3575
3626
  const nextFragmentEndIndex = formatExt.content.length - 1;
3576
3627
  const nextFragmentDistance = new DistanceModel({ start: nextFragmentStartIndex, end: nextFragmentEndIndex });
@@ -3579,7 +3630,8 @@ class RenderingHelper {
3579
3630
  start: nextFragmentDocumentStartIndex,
3580
3631
  end: nextFragmentDocumentEndIndex
3581
3632
  });
3582
- paragraphChars += this.renderFormatContent(valueFragment, formatExt, nextFragmentDocumentDistance, nextFragmentDistance, customContentService, customComponents, breaks);
3633
+ isLastLineFragment = split === nextFragmentDocumentDistance.end + 1;
3634
+ paragraphChars += this.renderFormatContent(valueFragment, formatExt, nextFragmentDocumentDistance, nextFragmentDistance, customContentService, customComponents, breaks, lineInfo, isLastLineFragment);
3583
3635
  lineEl.appendChild(valueFragment);
3584
3636
  domContent.parentNode.appendChild(lineEl);
3585
3637
  break;
@@ -3592,7 +3644,8 @@ class RenderingHelper {
3592
3644
  start: nextFragmentDocumentStartIndex,
3593
3645
  end: nextFragmentDocumentEndIndex
3594
3646
  });
3595
- const renderedChars = this.renderFormatContent(valueFragment, formatExt, nextFragmentDocumentDistance, nextFragmentDistance, customContentService, customComponents, breaks);
3647
+ isLastLineFragment = split === nextFragmentDocumentDistance.end + 1;
3648
+ const renderedChars = this.renderFormatContent(valueFragment, formatExt, nextFragmentDocumentDistance, nextFragmentDistance, customContentService, customComponents, breaks, lineInfo, isLastLineFragment);
3596
3649
  lineEl.appendChild(valueFragment);
3597
3650
  domContent.parentNode.appendChild(lineEl);
3598
3651
  nextFragmentStartIndex += renderedChars;
@@ -3627,24 +3680,28 @@ class RenderingHelper {
3627
3680
  containerElement.className = className;
3628
3681
  return containerElement;
3629
3682
  }
3630
- static renderFormatContent(fragment, formatExt, fragmentDocumentDistance, fragmentDistance, customContentService, customComponents, breaks) {
3683
+ static renderFormatContent(fragment, formatExt, fragmentDocumentDistance, fragmentDistance, customContentService, customComponents, breaks, lineInfo, isLastLineFragment) {
3631
3684
  let textFragment = formatExt.content.substring(fragmentDistance.start, fragmentDistance.end + 1);
3632
3685
  if (!textFragment) {
3633
3686
  return 0;
3634
3687
  }
3635
3688
  const textFragmentWithoutBreaks = BreakHelper.removeBreakMarker(breaks, textFragment, fragmentDocumentDistance.start);
3636
3689
  if (customContentService.isFragmentContainComponent(customComponents, textFragment, fragmentDocumentDistance)) {
3637
- this.renderTextWithCustomContent(fragment, formatExt, fragmentDocumentDistance, textFragmentWithoutBreaks, customContentService, customComponents);
3690
+ this.renderTextWithCustomContent(fragment, formatExt, fragmentDocumentDistance, textFragmentWithoutBreaks, customContentService, customComponents, lineInfo);
3691
+ }
3692
+ else if (isLastLineFragment) {
3693
+ this.renderTextWithSpacingHandling(fragment, formatExt, textFragmentWithoutBreaks, lineInfo);
3638
3694
  }
3639
3695
  else {
3640
- RenderingHelper.renderText(fragment, formatExt, textFragmentWithoutBreaks);
3696
+ const paddingLeft = textFragment.startsWith(' ') && lineInfo.wordSpacing ? lineInfo.wordSpacing : null;
3697
+ this.renderText(fragment, formatExt, textFragment, paddingLeft);
3641
3698
  }
3642
3699
  return textFragment.length;
3643
3700
  }
3644
- static renderTextWithCustomContent(fragment, formatExt, fragmentDocumentDistance, textFragment, customContentService, customComponents) {
3701
+ static renderTextWithCustomContent(fragment, formatExt, fragmentDocumentDistance, textFragment, customContentService, customComponents, lineInfo) {
3645
3702
  const components = customContentService.getComponents(customComponents, fragmentDocumentDistance);
3646
3703
  if (!components.length) {
3647
- RenderingHelper.renderText(fragment, formatExt, textFragment);
3704
+ this.renderTextWithSpacingHandling(fragment, formatExt, textFragment, lineInfo);
3648
3705
  return;
3649
3706
  }
3650
3707
  let newTextFragmentStartIndex = fragmentDocumentDistance.start;
@@ -3654,15 +3711,26 @@ class RenderingHelper {
3654
3711
  nextTextFragment = nextTextFragment.substring(textBeforeElement.length + 1, nextTextFragment.length);
3655
3712
  newTextFragmentStartIndex = newTextFragmentStartIndex + (textBeforeElement.length ? textBeforeElement.length + 1 : 1);
3656
3713
  if (textBeforeElement.length) {
3657
- RenderingHelper.renderText(fragment, formatExt, textBeforeElement);
3714
+ const paddingLeft = textBeforeElement.startsWith(' ') && lineInfo.wordSpacing ? lineInfo.wordSpacing : null;
3715
+ this.renderText(fragment, formatExt, textBeforeElement, paddingLeft);
3658
3716
  }
3659
3717
  this.attachComponent(fragment, component, customContentService);
3660
3718
  }
3661
3719
  if (nextTextFragment.length) {
3662
- RenderingHelper.renderText(fragment, formatExt, nextTextFragment);
3720
+ this.renderTextWithSpacingHandling(fragment, formatExt, nextTextFragment, lineInfo);
3721
+ }
3722
+ }
3723
+ static renderTextWithSpacingHandling(fragment, formatExt, textFragment, lineInfo) {
3724
+ const paddingLeft = textFragment.startsWith(' ') && lineInfo.wordSpacing ? lineInfo.wordSpacing : null;
3725
+ if (lineInfo.wordSpacing && textFragment.endsWith(' ')) {
3726
+ this.renderText(fragment, formatExt, textFragment.slice(0, -1), paddingLeft);
3727
+ this.renderText(fragment, formatExt, ' ');
3728
+ }
3729
+ else {
3730
+ this.renderText(fragment, formatExt, textFragment, paddingLeft);
3663
3731
  }
3664
3732
  }
3665
- static renderText(fragment, formatExt, textFragment) {
3733
+ static renderText(fragment, formatExt, textFragment, paddingLeft = null) {
3666
3734
  const span = document.createElement('span');
3667
3735
  const textStyle = new TextStyleModel({ ...formatExt.textStyle });
3668
3736
  if (textFragment === NEW_LINE_MARKUP) {
@@ -3681,7 +3749,11 @@ class RenderingHelper {
3681
3749
  span.onmouseleave = () => span.classList.remove('hyperlink-hover');
3682
3750
  }
3683
3751
  span.textContent = textFragment;
3684
- span.setAttribute('style', ContentStyleHelper.getTextStylesString(textStyle));
3752
+ let styleString = ContentStyleHelper.getTextStylesString(textStyle);
3753
+ if (paddingLeft) {
3754
+ styleString += `padding-left:${paddingLeft}px;`;
3755
+ }
3756
+ span.setAttribute('style', styleString);
3685
3757
  fragment.appendChild(span);
3686
3758
  }
3687
3759
  static getTextIndexLengthForInsert(formatExt, fragmentDocumentStartIndex, paragraphDistance, split, paragraphChars) {
@@ -4356,10 +4428,11 @@ class TextLayer {
4356
4428
  const numberingOffsetLeft = paragraphSettings.numberingData.numberingId === null
4357
4429
  ? 0
4358
4430
  : paragraphSettings.numberingData.width + paragraphSettings.numberingData.paddingLeft;
4359
- const lastLineEl = this.renderingHelper.createLineElement(paragraphSettings.textLinesInfo[0], numberingOffsetLeft, this.session.generalProperties.scalingRatio);
4431
+ const lineInfo = paragraphSettings.textLinesInfo[0];
4432
+ const lastLineEl = this.renderingHelper.createLineElement(lineInfo, numberingOffsetLeft, this.session.generalProperties.scalingRatio);
4360
4433
  linesContainerElement.appendChild(lastLineEl);
4361
4434
  const rowDistance = new DistanceModel({ start: startIndex, end: endIndex });
4362
- this.renderingHelper.renderContentSimpleLine({ currentElement: this.element, parentNode: lastLineEl }, combinedFormats, rowDistance, this.session.customContentService, this.session.customComponents, this.session.model.breaks);
4435
+ this.renderingHelper.renderContentSimpleLine({ currentElement: this.element, parentNode: lastLineEl }, combinedFormats, rowDistance, this.session.customContentService, this.session.customComponents, lineInfo, this.session.model.breaks);
4363
4436
  }
4364
4437
  }
4365
4438
  }
@@ -5500,6 +5573,36 @@ class TextInput {
5500
5573
  }
5501
5574
  }
5502
5575
 
5576
+ class TouchHandler {
5577
+ constructor(container, editor) {
5578
+ this.editor = editor;
5579
+ this.touchStart$ = fromEvent(container, 'touchstart').subscribe((event) => this.onTouchStart(event));
5580
+ }
5581
+ destroy() {
5582
+ this.touchStart$?.unsubscribe();
5583
+ this.endTouch();
5584
+ }
5585
+ onTouchStart(startEvent) {
5586
+ this.lastY = startEvent.touches[0].clientY;
5587
+ this.touchMove$ = fromEvent(document, 'touchmove').subscribe((event) => this.onTouchMove(event));
5588
+ this.touchEnd$ = fromEvent(document, 'touchend').subscribe(() => this.endTouch());
5589
+ }
5590
+ onTouchMove(event) {
5591
+ if (this.lastY === null) {
5592
+ return;
5593
+ }
5594
+ const currentY = event.touches[0].clientY;
5595
+ const deltaY = this.lastY - currentY;
5596
+ this.editor.onScroll(deltaY);
5597
+ this.lastY = currentY;
5598
+ }
5599
+ endTouch() {
5600
+ this.touchMove$?.unsubscribe();
5601
+ this.touchEnd$?.unsubscribe();
5602
+ this.lastY = null;
5603
+ }
5604
+ }
5605
+
5503
5606
  class Editor {
5504
5607
  get mainSession() {
5505
5608
  return this.regulatorService.mainSession.session;
@@ -5552,6 +5655,7 @@ class Editor {
5552
5655
  this.textInput = new TextInput(this.mainRenderer.container);
5553
5656
  this.mainRenderer.textarea = this.textInput.input;
5554
5657
  this.mouseHandler = new MouseHandler(this.mainRenderer.container, this);
5658
+ this.touchHandler = new TouchHandler(this.mainRenderer.container, this);
5555
5659
  this.inputHandler = new InputHandler(this.textInput.input, this);
5556
5660
  this.documentHandler = new DocumentHandler(this);
5557
5661
  this.dragAndDrop = new DragAndDrop(this.container.nativeElement);
@@ -5566,6 +5670,7 @@ class Editor {
5566
5670
  this.subscriptions.forEach(s => s?.unsubscribe());
5567
5671
  this.destroyResizeListener();
5568
5672
  this.mouseHandler.destroy();
5673
+ this.touchHandler.destroy();
5569
5674
  this.inputHandler.destroy();
5570
5675
  this.documentHandler.destroy();
5571
5676
  this.dragAndDrop.destroyListeners();
@@ -6103,7 +6208,7 @@ class Editor {
6103
6208
  }
6104
6209
  saveRemoveToHistory(range) {
6105
6210
  const restoreModel = this.session.createRestoreFromSlice(range.start.row, range.start.column, range.end.row, range.end.column);
6106
- const count = restoreModel.endIndex - restoreModel.startIndex;
6211
+ const count = restoreModel.endIndex - restoreModel.startIndex + 1;
6107
6212
  restoreModel.endIndex = restoreModel.startIndex; // this is to restore in position without deleting/replacing anything in range
6108
6213
  this.history.pushDelete(restoreModel);
6109
6214
  this.commandsService.createCommand(SaveCommandsHelper.getDeleteCommand(restoreModel.startIndex, count, this.targets));
@@ -6478,10 +6583,13 @@ class Editor {
6478
6583
  const factor = 0.35;
6479
6584
  const scrollSpeed = 4;
6480
6585
  const deltaY = event.deltaY * factor * scrollSpeed;
6481
- this.mainRenderer.scrollBy(deltaY);
6586
+ this.onScroll(deltaY);
6482
6587
  event.stopPropagation();
6483
6588
  event.preventDefault();
6484
6589
  }
6590
+ onScroll(deltaY) {
6591
+ this.mainRenderer.scrollBy(deltaY);
6592
+ }
6485
6593
  onDragStart() {
6486
6594
  this.renderer.updateDragAndDropSelection(this.selection.selectedRange);
6487
6595
  this.selection.clearSelection();
@@ -6508,7 +6616,7 @@ class Editor {
6508
6616
  onDragDrop(sourceSession, sourceRange) {
6509
6617
  sourceSession.renderer.clearDragAndDropSelection();
6510
6618
  const sourceStartIndex = sourceSession.session.displayData.positionToIndex(sourceRange.start);
6511
- const sourceEndIndex = sourceSession.session.displayData.positionToIndex(sourceRange.end);
6619
+ const sourceEndIndex = sourceSession.session.displayData.positionToIndex(sourceRange.end) - 1;
6512
6620
  const targetIndex = this.session.displayData.positionToIndex(this.selection.cursor);
6513
6621
  if (sourceSession.sessionId === this.session.sessionId && sourceStartIndex <= targetIndex && sourceEndIndex >= targetIndex) {
6514
6622
  this.selection.placeSelection(sourceRange.start, sourceRange.end);
@@ -6517,7 +6625,7 @@ class Editor {
6517
6625
  }
6518
6626
  const model = new MoveRangeModel({
6519
6627
  sourceStartIndex,
6520
- sourceCount: sourceEndIndex - sourceStartIndex,
6628
+ sourceCount: sourceEndIndex - sourceStartIndex + 1,
6521
6629
  targetIndex,
6522
6630
  sourceTargets: this.regulatorService.getTargets(sourceSession),
6523
6631
  targetTargets: this.regulatorService.getCurrentSessionTargets()
@@ -9207,10 +9315,16 @@ class DisplayData extends EventEmitting {
9207
9315
  if (paragraphStyle.alignment === Alignment$1.justify && !isLastLineOfParagraph && wrapTokens.length > 1) {
9208
9316
  let currentLineWidth = 0;
9209
9317
  let spaceCount = 0;
9210
- for (const token of wrapTokens) {
9318
+ for (let i = 0; i < wrapTokens.length; i++) {
9319
+ const token = wrapTokens[i];
9211
9320
  currentLineWidth += token.width;
9212
9321
  if (token.displayValue === DisplayValue.space) {
9213
- spaceCount++;
9322
+ if (i === wrapTokens.length - 1) {
9323
+ token.displayValue = DisplayValue.trailingSpace;
9324
+ }
9325
+ else {
9326
+ spaceCount++;
9327
+ }
9214
9328
  }
9215
9329
  }
9216
9330
  const { left, right, firstLine, hanging } = lineInfo.indent;
@@ -9219,6 +9333,7 @@ class DisplayData extends EventEmitting {
9219
9333
  const whitespaceDeficit = availableWidth - currentLineWidth;
9220
9334
  if (spaceCount > 0 && whitespaceDeficit > 0) {
9221
9335
  lineInfo.wordSpacing = whitespaceDeficit / spaceCount;
9336
+ lineInfo.wordSpacingWidth = whitespaceDeficit;
9222
9337
  }
9223
9338
  }
9224
9339
  rowInfos.push(lineInfo);
@@ -9569,14 +9684,19 @@ class DisplayData extends EventEmitting {
9569
9684
  const maxRowWidth = contentWidth - indent;
9570
9685
  let sum = 0;
9571
9686
  for (let i = 0; i < displayTokens.length; i++) {
9572
- if (displayTokens[i].isTab) {
9573
- displayTokens[i].width = TabHelper.calculateTabWidth(sum, defaultTabWidth);
9687
+ const token = displayTokens[i];
9688
+ const prevToken = i > 0 ? displayTokens[i - 1] : null;
9689
+ if (token.isTab) {
9690
+ token.width = TabHelper.calculateTabWidth(sum, defaultTabWidth);
9691
+ }
9692
+ sum += token.width;
9693
+ if (sum >= maxRowWidth) {
9694
+ return i > 0 ? i - 1 : 0;
9574
9695
  }
9575
- sum += displayTokens[i].width;
9576
- if ((i > 0 && (sum >= maxRowWidth || displayTokens[i - 1].breaksLine)) || displayTokens[i].isTable) {
9696
+ if (prevToken?.breaksLine || token.isTable) {
9577
9697
  return i;
9578
9698
  }
9579
- if (displayTokens[i].isLineBreak || (i === displayTokens.length - 1 && displayTokens[i].isPageBreak)) {
9699
+ if (token.isLineBreak || (i === displayTokens.length - 1 && token.isPageBreak)) {
9580
9700
  return i + 1;
9581
9701
  }
9582
9702
  }
@@ -10271,6 +10391,7 @@ class NoderImageComponent extends BaseNoderComponent {
10271
10391
  const imageEl = document.createElement('img');
10272
10392
  imageEl.width = this.width;
10273
10393
  imageEl.height = this.height;
10394
+ imageEl.draggable = false;
10274
10395
  imageEl.src = fileSource;
10275
10396
  return imageEl;
10276
10397
  }
@@ -10381,21 +10502,6 @@ class CellModel {
10381
10502
  }
10382
10503
  }
10383
10504
 
10384
- class ContentOperationsHelper {
10385
- static removeContent(content, startIndex, count) {
10386
- return `${content.slice(0, startIndex)}${content.slice(startIndex + count, content.length)}`;
10387
- }
10388
- static insertContent(content, text, index) {
10389
- const before = content.slice(0, index);
10390
- const after = content.slice(index, content.length);
10391
- return `${before}${text}${after}`;
10392
- }
10393
- static replaceContent(content, startIndex, endIndex, text) {
10394
- const reduced = this.removeContent(content, startIndex, endIndex - startIndex + 1);
10395
- return this.insertContent(reduced, text, startIndex);
10396
- }
10397
- }
10398
-
10399
10505
  class EdgeModel {
10400
10506
  constructor(fields) {
10401
10507
  if (fields) {
@@ -12234,9 +12340,9 @@ class EditSession {
12234
12340
  return endPoint;
12235
12341
  }
12236
12342
  removeMoveRange(moveModel) {
12237
- const endIndex = moveModel.sourceStartIndex + moveModel.sourceCount;
12238
- const startPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, moveModel.sourceStartIndex);
12239
- const endPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, endIndex);
12343
+ const endIndex = moveModel.sourceStartIndex + moveModel.sourceCount - 1;
12344
+ const startPosition = this.displayData.indexToPosition(moveModel.sourceStartIndex, 0);
12345
+ const endPosition = this.displayData.indexToPosition(endIndex + 1, 0);
12240
12346
  const sourceRange = new Range(startPosition, endPosition);
12241
12347
  this.displayData.removeRange(sourceRange);
12242
12348
  CustomComponentHelper.applyRemovingComponents(this.customComponents.tables, moveModel.sourceStartIndex, endIndex);
@@ -12281,8 +12387,9 @@ class EditSession {
12281
12387
  }
12282
12388
  createRestoreFromSlice(paragraphStart, indexInStart, paragraphEnd, indexInEnd) {
12283
12389
  const startIndex = ContentHelper.paragraphToDocumentIndex(this.displayData.paragraphs, paragraphStart, indexInStart);
12284
- const endIndex = ContentHelper.paragraphToDocumentIndex(this.displayData.paragraphs, paragraphEnd, indexInEnd);
12285
- return ContentsOperationsHelper.GetRestoreFromSlice(this.model, startIndex, endIndex - startIndex);
12390
+ const endIndex = ContentHelper.paragraphToDocumentIndex(this.displayData.paragraphs, paragraphEnd, indexInEnd) - 1;
12391
+ const count = endIndex - startIndex + 1;
12392
+ return ContentsOperationsHelper.GetRestoreFromSlice(this.model, startIndex, count);
12286
12393
  }
12287
12394
  addComponent(customElements, model, componentType) {
12288
12395
  const customElement = this.customContentService.componentService.createComponent(componentType, {
@@ -12726,7 +12833,8 @@ class SelectionLayer {
12726
12833
  let style;
12727
12834
  if (i === 0) {
12728
12835
  const rangeInfo = this.getRangeInfo(this.session, range);
12729
- style = this.getMarkerStyle(lineInfo.height, lineInfo.width - rangeInfo.leftPos + lineInfo.paddingLeft + padding, top, rangeInfo.leftPos);
12836
+ const width = lineInfo.width - rangeInfo.leftPos + lineInfo.paddingLeft + padding + (lineInfo.wordSpacingWidth ?? 0);
12837
+ style = this.getMarkerStyle(lineInfo.height, width, top, rangeInfo.leftPos);
12730
12838
  }
12731
12839
  else if (i === textLinesInfo.length - 1) {
12732
12840
  const lastRowRange = new Range(new CursorParagraph(range.end.row, 0), range.end);
@@ -12734,7 +12842,8 @@ class SelectionLayer {
12734
12842
  style = this.getMarkerStyle(lineInfo.height, rangeInfo.screenWidth, top, padding + lineInfo.paddingLeft);
12735
12843
  }
12736
12844
  else {
12737
- style = this.getMarkerStyle(lineInfo.height, lineInfo.width, top, padding + lineInfo.paddingLeft);
12845
+ let width = lineInfo.width + (lineInfo.wordSpacingWidth ?? 0);
12846
+ style = this.getMarkerStyle(lineInfo.height, width, top, padding + lineInfo.paddingLeft);
12738
12847
  }
12739
12848
  this.renderSelection(style);
12740
12849
  top += lineInfo.height + lineInfo.offsetAfter + lineInfo.endPageOffset;