@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.
- package/fesm2022/talrace-ngx-noder.mjs +181 -72
- package/fesm2022/talrace-ngx-noder.mjs.map +1 -1
- package/lib/editor/content/constants/display-values.const.d.ts +1 -0
- package/lib/editor/content/display-data/line-info.model.d.ts +1 -0
- package/lib/editor/content/display-data/text-line-info.d.ts +1 -0
- package/lib/editor/display/rendering.helper.d.ts +2 -1
- package/lib/editor/execution/editor.d.ts +3 -0
- package/lib/editor/interaction/touch.handler.d.ts +13 -0
- package/lib/editor/operations/helpers/content-operations.helper.d.ts +1 -0
- package/package.json +1 -1
|
@@ -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 +=
|
|
3355
|
+
lineWidthToPosition += currentToken.width;
|
|
3356
|
+
if (currentToken.displayValue === DisplayValue.space && lineInfo.wordSpacing) {
|
|
3357
|
+
lineWidthToPosition += lineInfo.wordSpacing;
|
|
3358
|
+
}
|
|
3334
3359
|
}
|
|
3335
|
-
if (sizeMax.ascent <
|
|
3336
|
-
sizeMax =
|
|
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
|
-
|
|
3396
|
-
|
|
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
|
-
|
|
3414
|
-
|
|
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
|
|
3444
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
9573
|
-
|
|
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
|
-
|
|
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 (
|
|
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 =
|
|
12239
|
-
const endPosition =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|