@talrace/ngx-noder 19.0.40 → 19.0.42
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 +436 -332
- package/fesm2022/talrace-ngx-noder.mjs.map +1 -1
- package/lib/editor/content/display-data/display-data.d.ts +2 -6
- package/lib/editor/content/display-data/display-token.model.d.ts +3 -1
- package/lib/editor/content/display-data/line-info.model.d.ts +8 -2
- package/lib/editor/content/display-data/models/custom-text.model.d.ts +8 -0
- package/lib/editor/content/display-data/models/paragraph-info.model.d.ts +0 -1
- package/lib/editor/content/helpers/display-token.helper.d.ts +7 -5
- package/lib/editor/content/helpers/line-info.helper.d.ts +8 -1
- package/lib/editor/display/rendering.helper.d.ts +1 -0
- package/lib/editor/execution/constants/editor-tags.const.d.ts +5 -0
- package/lib/editor/execution/editor.d.ts +3 -8
- package/lib/editor/gadgets/page-break/break.helper.d.ts +0 -1
- package/lib/editor/positioning/cursor-position.interface.d.ts +0 -1
- package/lib/editor/positioning/position.helper.d.ts +4 -7
- package/lib/editor/positioning/range.d.ts +2 -2
- package/lib/editor/positioning/selection.d.ts +2 -2
- package/package.json +1 -1
- package/src/scss/base-editor.scss +8 -8
|
@@ -1378,7 +1378,7 @@ class ExternalComponent extends BaseNoderComponent {
|
|
|
1378
1378
|
constructor() {
|
|
1379
1379
|
super(...arguments);
|
|
1380
1380
|
this.focusSidenav = true;
|
|
1381
|
-
this.isText = false;
|
|
1381
|
+
this.isText = false; // this will substitute component block by in editor text (getText() will be used as a value)
|
|
1382
1382
|
}
|
|
1383
1383
|
getText() {
|
|
1384
1384
|
return '';
|
|
@@ -1772,13 +1772,6 @@ class BreakHelper {
|
|
|
1772
1772
|
}
|
|
1773
1773
|
return breaks.find(x => x.insertIndex === insertIndex)?.breakType ?? null;
|
|
1774
1774
|
}
|
|
1775
|
-
static removeBreakMarker(breaks, text, fragmentStartIndex) {
|
|
1776
|
-
const index = text.at(-1) === NEW_LINE_MARKUP ? -2 : -1;
|
|
1777
|
-
if (text.at(index) === CUSTOM_ELEMENT_MARKER && breaks.some(x => x.insertIndex === fragmentStartIndex + text.length + index)) {
|
|
1778
|
-
return index === -1 ? text.substring(0, text.length + index) : text.substring(0, text.length + index).concat(text.at(-1));
|
|
1779
|
-
}
|
|
1780
|
-
return text;
|
|
1781
|
-
}
|
|
1782
1775
|
}
|
|
1783
1776
|
|
|
1784
1777
|
const COMMENT_TYPES = new InjectionToken('COMMENT_TYPES');
|
|
@@ -1922,6 +1915,12 @@ class CreateEdgesModel {
|
|
|
1922
1915
|
}
|
|
1923
1916
|
}
|
|
1924
1917
|
|
|
1918
|
+
const PARENT_TAG = 'APP-NOD-EDITOR';
|
|
1919
|
+
const TABLE_CELL_TAG = 'APP-NOD-TABLE-CELL';
|
|
1920
|
+
const EDGE_TAG = 'APP-NOD-EDGE';
|
|
1921
|
+
const IMAGE_TAG = 'APP-NOD-IMAGE';
|
|
1922
|
+
const CUSTOM_TAG = 'APP-NOD-CUSTOM-ELEMENT';
|
|
1923
|
+
|
|
1925
1924
|
class CustomElementSearchResult {
|
|
1926
1925
|
constructor(init) {
|
|
1927
1926
|
Object.assign(this, init);
|
|
@@ -6308,36 +6307,26 @@ class PositionHelper {
|
|
|
6308
6307
|
const paragraphLine = documentLine - index;
|
|
6309
6308
|
return { paragraph, paragraphLine };
|
|
6310
6309
|
}
|
|
6311
|
-
static paragraphToParagraphLine(
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
const indexInLine = indexInParagraph - nextLineIndexes[index];
|
|
6317
|
-
return { paragraphLine: index + 1, indexInLine };
|
|
6310
|
+
static paragraphToParagraphLine(paragraph, indexInParagraph) {
|
|
6311
|
+
const lines = paragraph.paragraphSettings.textLinesInfo;
|
|
6312
|
+
const paragraphLine = lines.findIndex(x => x.endIndex >= indexInParagraph);
|
|
6313
|
+
const indexInLine = indexInParagraph - lines[paragraphLine].startIndex;
|
|
6314
|
+
return { paragraphLine, indexInLine };
|
|
6318
6315
|
}
|
|
6319
|
-
static paragraphToDocumentLine(
|
|
6320
|
-
const paragraphLine =
|
|
6321
|
-
|
|
6322
|
-
if (!nextLineIndexes.length || nextLineIndexes[0] > indexInParagraph) {
|
|
6323
|
-
return new CursorParagraph(paragraphLine, indexInParagraph);
|
|
6324
|
-
}
|
|
6325
|
-
let line = 0;
|
|
6326
|
-
while (nextLineIndexes[line] <= indexInParagraph && line < nextLineIndexes.length) {
|
|
6327
|
-
line++;
|
|
6328
|
-
}
|
|
6329
|
-
return new CursorParagraph(paragraphLine + line, indexInParagraph - nextLineIndexes[line - 1]);
|
|
6316
|
+
static paragraphToDocumentLine(paragraph, indexInParagraph) {
|
|
6317
|
+
const { paragraphLine, indexInLine } = this.paragraphToParagraphLine(paragraph, indexInParagraph);
|
|
6318
|
+
return new CursorParagraph(paragraph.lineNumber + paragraphLine, indexInLine);
|
|
6330
6319
|
}
|
|
6331
6320
|
static documentLineToParagraph(session, documentLine, indexInLine) {
|
|
6332
|
-
|
|
6333
|
-
paragraphIndex = paragraphIndex === -1 ? session.displayData.paragraphs.length - 1 : paragraphIndex - 1;
|
|
6321
|
+
const paragraphIndex = session.displayData.paragraphs.findLastIndex(x => x.lineNumber <= documentLine);
|
|
6334
6322
|
const paragraph = session.displayData.paragraphs[paragraphIndex];
|
|
6335
|
-
|
|
6336
|
-
const
|
|
6323
|
+
const paragraphLine = documentLine - paragraph.lineNumber;
|
|
6324
|
+
const lines = paragraph.paragraphSettings.textLinesInfo;
|
|
6325
|
+
const indexInParagraph = lines[paragraphLine].startIndex + indexInLine;
|
|
6337
6326
|
return new CursorParagraph(paragraphIndex, indexInParagraph);
|
|
6338
6327
|
}
|
|
6339
6328
|
static paragraphToPixel(session, paragraph, indexInParagraph) {
|
|
6340
|
-
const line = this.paragraphToParagraphLine(session.displayData.paragraphs[paragraph]
|
|
6329
|
+
const line = this.paragraphToParagraphLine(session.displayData.paragraphs[paragraph], indexInParagraph);
|
|
6341
6330
|
return this.paragraphLineToPixel(session, paragraph, line.paragraphLine, line.indexInLine);
|
|
6342
6331
|
}
|
|
6343
6332
|
static documentLineToPixel(session, documentLine, indexInLine) {
|
|
@@ -6348,26 +6337,17 @@ class PositionHelper {
|
|
|
6348
6337
|
const marginLeft = session.displayData.pagesFormat[0].pageFormatModel.marginLeft; // this value is the same for all page formats.
|
|
6349
6338
|
const paragraphs = session.displayData.paragraphs;
|
|
6350
6339
|
const tokens = session.displayData.getParagraphLineTokens(paragraph, paragraphLine);
|
|
6351
|
-
let
|
|
6352
|
-
let
|
|
6353
|
-
|
|
6354
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
6355
|
-
const currentToken = tokens[i];
|
|
6356
|
-
if (i < indexInLine) {
|
|
6357
|
-
lineWidthToPosition += currentToken.width;
|
|
6358
|
-
}
|
|
6359
|
-
if (sizeMax.ascent < currentToken.ascent) {
|
|
6360
|
-
sizeMax = currentToken;
|
|
6361
|
-
}
|
|
6340
|
+
let width = marginLeft;
|
|
6341
|
+
for (let i = 0; i < tokens.length && !tokens[i].isParagraph && tokens[i].index - tokens[0].index < indexInLine; i++) {
|
|
6342
|
+
width += tokens[i].width;
|
|
6362
6343
|
}
|
|
6363
6344
|
const lineTopOffset = this.getLineTopOffset(paragraphs[paragraph].paragraphSettings.textLinesInfo, paragraphLine);
|
|
6364
6345
|
const paragraphTop = paragraphs[paragraph].paragraphSettings.distanceFromTop || 0;
|
|
6365
6346
|
const info = paragraphs[paragraph].paragraphSettings.textLinesInfo[paragraphLine];
|
|
6366
6347
|
const markerOffset = NumberingHelper.getOffsetCausedByMarker(paragraphs[paragraph].paragraphSettings.numberingData, info);
|
|
6367
6348
|
return {
|
|
6368
|
-
pageX:
|
|
6349
|
+
pageX: width + info.paddingLeft + info.offsetMargin + markerOffset,
|
|
6369
6350
|
pageY: paragraphTop + lineTopOffset - session.scrollTop,
|
|
6370
|
-
width: tokens[tokenIndex].width,
|
|
6371
6351
|
height: info.height,
|
|
6372
6352
|
ascent: info.ascent
|
|
6373
6353
|
};
|
|
@@ -6394,37 +6374,42 @@ class PositionHelper {
|
|
|
6394
6374
|
}
|
|
6395
6375
|
return { paragraph, paragraphLine };
|
|
6396
6376
|
}
|
|
6397
|
-
static
|
|
6377
|
+
static pixelToIndexInParagraph(session, pageX, paragraph, paragraphLine, tokenDivider) {
|
|
6398
6378
|
const marginLeft = session.displayData.pagesFormat[0].pageFormatModel.marginLeft; // this value is the same for all page formats.
|
|
6399
6379
|
const paragraphs = session.displayData.paragraphs;
|
|
6400
|
-
const { paragraph, paragraphLine } = this.pixelToParagraphLine(paragraphs, pageY);
|
|
6401
|
-
const settings = paragraphs[paragraph].paragraphSettings;
|
|
6402
6380
|
const tokens = session.displayData.getParagraphLineTokens(paragraph, paragraphLine);
|
|
6403
|
-
const
|
|
6404
|
-
const
|
|
6405
|
-
const
|
|
6406
|
-
return
|
|
6407
|
-
}
|
|
6408
|
-
static pixelToIndexInLine(session, documentLine, pageX, tokenDivider) {
|
|
6409
|
-
const marginLeft = session.displayData.pagesFormat[0].pageFormatModel.marginLeft; // this value is the same for all page formats.
|
|
6410
|
-
const { paragraph, paragraphLine } = this.documentLineToParagraphLine(session.displayData.paragraphs, documentLine);
|
|
6411
|
-
const settings = session.displayData.paragraphs[paragraph].paragraphSettings;
|
|
6412
|
-
const tokens = session.displayData.getParagraphLineTokens(paragraph, paragraphLine);
|
|
6413
|
-
const lineInfo = settings.textLinesInfo[paragraphLine];
|
|
6414
|
-
return this.getIndexInLine(tokens, lineInfo, settings.numberingData, marginLeft, pageX, tokenDivider);
|
|
6381
|
+
const lines = paragraphs[paragraph].paragraphSettings.textLinesInfo;
|
|
6382
|
+
const numberingData = paragraphs[paragraph].paragraphSettings.numberingData;
|
|
6383
|
+
const indexInLine = this.getIndexInLine(tokens, lines[paragraphLine], numberingData, marginLeft, pageX, tokenDivider);
|
|
6384
|
+
return lines[paragraphLine].startIndex + indexInLine;
|
|
6415
6385
|
}
|
|
6416
6386
|
static getIndexInLine(tokens, lineInfo, numberingData, marginLeft, pageX, tokenDivider) {
|
|
6417
|
-
|
|
6418
|
-
return 0;
|
|
6419
|
-
}
|
|
6420
|
-
let indexInLine = 0;
|
|
6387
|
+
let index = 0;
|
|
6421
6388
|
const markerOffset = NumberingHelper.getOffsetCausedByMarker(numberingData, lineInfo);
|
|
6422
6389
|
let width = pageX - marginLeft - lineInfo.paddingLeft - lineInfo.offsetMargin - markerOffset;
|
|
6423
|
-
while (
|
|
6424
|
-
|
|
6425
|
-
|
|
6390
|
+
while (index < tokens.length && !tokens[index].isParagraph) {
|
|
6391
|
+
const merged = this.mergeCustomTokens(tokens, index);
|
|
6392
|
+
if (width >= merged.width / tokenDivider) {
|
|
6393
|
+
width -= merged.width;
|
|
6394
|
+
index += merged.count;
|
|
6395
|
+
}
|
|
6396
|
+
else {
|
|
6397
|
+
break;
|
|
6398
|
+
}
|
|
6399
|
+
}
|
|
6400
|
+
return index === 0 ? 0 : tokens[index - 1].index - tokens[0].index + 1;
|
|
6401
|
+
}
|
|
6402
|
+
static mergeCustomTokens(tokens, index) {
|
|
6403
|
+
let count = 1;
|
|
6404
|
+
let width = tokens[index].width;
|
|
6405
|
+
if (!(tokens[index].customIndex >= 0)) {
|
|
6406
|
+
return { width, count };
|
|
6407
|
+
}
|
|
6408
|
+
while (index + count < tokens.length && tokens[index].index === tokens[index + count].index) {
|
|
6409
|
+
width += tokens[index + count].width;
|
|
6410
|
+
count++;
|
|
6426
6411
|
}
|
|
6427
|
-
return
|
|
6412
|
+
return { width, count };
|
|
6428
6413
|
}
|
|
6429
6414
|
}
|
|
6430
6415
|
|
|
@@ -6498,45 +6483,44 @@ class RenderingHelper {
|
|
|
6498
6483
|
static renderParagraph(domContent, paragraph, formats, customContentService, customComponents, scalingRatio, breaks = []) {
|
|
6499
6484
|
const { offset, markerWidth } = NumberingHelper.getMarkerOffset(paragraph.paragraphSettings);
|
|
6500
6485
|
const lineInfos = paragraph.paragraphSettings.textLinesInfo;
|
|
6501
|
-
const
|
|
6502
|
-
const end = paragraph.startIndex + paragraph.content.length;
|
|
6486
|
+
const lastLine = paragraph.paragraphSettings.textLinesInfo.length - 1;
|
|
6503
6487
|
const fragment = DomHelper.createFragment(domContent.currentElement);
|
|
6504
6488
|
let lineIndex = 0;
|
|
6505
|
-
let
|
|
6489
|
+
let renderedIndexes = 0;
|
|
6490
|
+
let renderedTokensInLine = 0;
|
|
6491
|
+
let lineEndIndex = lineInfos[0].endIndex + paragraph.startIndex;
|
|
6506
6492
|
let lineEl = RenderingHelper.createLineElement(paragraph.paragraphSettings.textLinesInfo[0], offset - markerWidth, scalingRatio);
|
|
6507
6493
|
for (const format of formats) {
|
|
6508
6494
|
do {
|
|
6509
|
-
|
|
6510
|
-
? paragraph.startIndex + paragraph.nextLineIndexes[lineIndex] - 1
|
|
6511
|
-
: end;
|
|
6512
|
-
let fragmentEnd = format.endIndex < lineEnd ? format.endIndex : lineEnd;
|
|
6495
|
+
let fragmentEndIndex = format.endIndex < lineEndIndex ? format.endIndex : lineEndIndex;
|
|
6513
6496
|
let wordSpacing = lineInfos[lineIndex].wordSpacing;
|
|
6514
6497
|
if (wordSpacing) {
|
|
6515
|
-
const
|
|
6516
|
-
const
|
|
6517
|
-
const
|
|
6518
|
-
const
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
fragmentEnd = lineStartIndex + wordSpacingStart;
|
|
6498
|
+
const wordSpacingStartToken = lineInfos[lineIndex].wordSpacingStartToken;
|
|
6499
|
+
const wordSpacingEndToken = lineInfos[lineIndex].wordSpacingEndToken;
|
|
6500
|
+
const wordSpacingStartIndex = lineInfos[lineIndex].wordSpacingStartIndex + paragraph.startIndex;
|
|
6501
|
+
const wordSpacingEndIndex = lineInfos[lineIndex].wordSpacingEndIndex + paragraph.startIndex;
|
|
6502
|
+
if (renderedTokensInLine < wordSpacingStartToken && wordSpacingStartIndex < fragmentEndIndex) {
|
|
6503
|
+
fragmentEndIndex = wordSpacingStartIndex;
|
|
6522
6504
|
}
|
|
6523
|
-
else if (
|
|
6524
|
-
|
|
6505
|
+
else if (renderedTokensInLine < wordSpacingEndToken && wordSpacingEndIndex < fragmentEndIndex) {
|
|
6506
|
+
fragmentEndIndex = wordSpacingEndIndex;
|
|
6525
6507
|
}
|
|
6526
|
-
if (
|
|
6508
|
+
if (renderedTokensInLine < wordSpacingStartToken || renderedTokensInLine > wordSpacingEndToken) {
|
|
6527
6509
|
wordSpacing = null;
|
|
6528
6510
|
}
|
|
6529
6511
|
}
|
|
6530
|
-
const
|
|
6531
|
-
this.renderFormatContent(fragment, format.textStyle, start + renderedCount, fragmentEnd, paragraph.content.substring(renderedCount, renderedCount + fragmentLength), customContentService, customComponents, breaks, wordSpacing);
|
|
6512
|
+
const rendered = this.renderFormatContent(fragment, paragraph.content.substring(renderedIndexes, fragmentEndIndex - paragraph.startIndex + 1), paragraph.startIndex + renderedIndexes, fragmentEndIndex, renderedTokensInLine, format.textStyle, lineInfos[lineIndex], customContentService, customComponents, breaks, wordSpacing, paragraph.startIndex);
|
|
6532
6513
|
lineEl.appendChild(fragment);
|
|
6533
|
-
|
|
6534
|
-
|
|
6514
|
+
renderedIndexes += rendered.renderedIndexes;
|
|
6515
|
+
renderedTokensInLine += rendered.renderedTokens;
|
|
6516
|
+
if (lineIndex < lastLine && fragmentEndIndex === lineEndIndex) {
|
|
6535
6517
|
lineIndex++;
|
|
6518
|
+
lineEndIndex = lineInfos[lineIndex].endIndex + paragraph.startIndex;
|
|
6536
6519
|
domContent.parentNode.appendChild(lineEl);
|
|
6537
6520
|
lineEl = RenderingHelper.createLineElement(lineInfos[lineIndex], offset, scalingRatio);
|
|
6521
|
+
renderedTokensInLine = 0;
|
|
6538
6522
|
}
|
|
6539
|
-
} while (
|
|
6523
|
+
} while (renderedIndexes < paragraph.content.length && format.endIndex >= paragraph.startIndex + renderedIndexes);
|
|
6540
6524
|
domContent.parentNode.appendChild(lineEl);
|
|
6541
6525
|
}
|
|
6542
6526
|
}
|
|
@@ -6563,36 +6547,88 @@ class RenderingHelper {
|
|
|
6563
6547
|
containerElement.className = className;
|
|
6564
6548
|
return containerElement;
|
|
6565
6549
|
}
|
|
6566
|
-
static renderFormatContent(fragment,
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6550
|
+
static renderFormatContent(fragment, fragmentText, fragmentStartIndex, // model content index
|
|
6551
|
+
fragmentEndIndex, // model content index
|
|
6552
|
+
renderedTokensInLine, textStyle, line, customContentService, customComponents, breaks, wordSpacing, paragraphStartIndex) {
|
|
6553
|
+
let renderedIndexes = 0;
|
|
6554
|
+
if (!fragmentText) {
|
|
6555
|
+
return { renderedIndexes, renderedTokens: 0 };
|
|
6556
|
+
}
|
|
6557
|
+
let additionalTokens = 0;
|
|
6558
|
+
if (fragmentText.at(-1) === CUSTOM_ELEMENT_MARKER &&
|
|
6559
|
+
breaks.some(x => x.insertIndex === fragmentStartIndex + fragmentText.length - 1)) {
|
|
6560
|
+
fragmentText = fragmentText.substring(0, fragmentText.length - 1);
|
|
6561
|
+
renderedIndexes = 1;
|
|
6562
|
+
}
|
|
6563
|
+
const components = customContentService.getComponents(customComponents, fragmentStartIndex, fragmentEndIndex);
|
|
6564
|
+
for (const component of components) {
|
|
6565
|
+
const textBeforeElement = fragmentText.substring(0, component.instance.insertIndex - fragmentStartIndex);
|
|
6566
|
+
fragmentText = fragmentText.substring(textBeforeElement.length + 1, fragmentText.length);
|
|
6567
|
+
this.renderText(fragment, textStyle, textBeforeElement, wordSpacing);
|
|
6568
|
+
renderedIndexes += textBeforeElement.length;
|
|
6569
|
+
if (component.instance instanceof ExternalComponent && component.instance.isText) {
|
|
6570
|
+
const rendered = this.renderExternalText(fragment, textStyle, wordSpacing, component.instance, line, renderedTokensInLine, paragraphStartIndex);
|
|
6571
|
+
renderedIndexes += rendered.renderedIndexes;
|
|
6572
|
+
additionalTokens += rendered.additionalTokens;
|
|
6583
6573
|
}
|
|
6584
|
-
|
|
6585
|
-
|
|
6574
|
+
else {
|
|
6575
|
+
customContentService.componentService.attachComponent(fragment, component);
|
|
6576
|
+
renderedIndexes++;
|
|
6586
6577
|
}
|
|
6578
|
+
fragmentStartIndex = fragmentStartIndex + textBeforeElement.length + 1;
|
|
6579
|
+
}
|
|
6580
|
+
this.renderText(fragment, textStyle, fragmentText, wordSpacing);
|
|
6581
|
+
renderedIndexes += fragmentText.length;
|
|
6582
|
+
return { renderedIndexes, renderedTokens: renderedIndexes + additionalTokens };
|
|
6583
|
+
}
|
|
6584
|
+
static renderExternalText(fragment, textStyle, wordSpacing, instance, line, renderedTokensInLine, paragraphStartIndex) {
|
|
6585
|
+
let additionalTokens = 0;
|
|
6586
|
+
let renderedIndexes = 0;
|
|
6587
|
+
const attributes = [
|
|
6588
|
+
{ name: 'data-session-id', value: `${instance.sessionId}` },
|
|
6589
|
+
{ name: 'data-insert-index', value: `${instance.insertIndex}` }
|
|
6590
|
+
];
|
|
6591
|
+
let text = instance.getText();
|
|
6592
|
+
text = !text.length ? ' ' : text;
|
|
6593
|
+
const customText = line.customTexts.find(x => x.index === instance.insertIndex - paragraphStartIndex);
|
|
6594
|
+
const customTextFragment = text.substring(customText.start, customText.end);
|
|
6595
|
+
if (!line.wordSpacing) {
|
|
6596
|
+
this.renderText(fragment, textStyle, customTextFragment, wordSpacing, [CUSTOM_TAG, 'noder-pointing'], attributes);
|
|
6597
|
+
additionalTokens += customTextFragment.length;
|
|
6587
6598
|
}
|
|
6588
6599
|
else {
|
|
6589
|
-
|
|
6600
|
+
const wordSpacingStart = line.wordSpacingStartToken - renderedTokensInLine - renderedIndexes - additionalTokens;
|
|
6601
|
+
const wordSpacingEnd = line.wordSpacingEndToken - renderedTokensInLine - renderedIndexes - additionalTokens;
|
|
6602
|
+
if (wordSpacingStart > 0) {
|
|
6603
|
+
const leftText = customTextFragment.substring(0, wordSpacingStart);
|
|
6604
|
+
this.renderText(fragment, textStyle, leftText, null, [CUSTOM_TAG, 'noder-pointing'], attributes);
|
|
6605
|
+
additionalTokens += leftText.length;
|
|
6606
|
+
}
|
|
6607
|
+
const middleText = customTextFragment.substring(wordSpacingStart, wordSpacingEnd + 1);
|
|
6608
|
+
this.renderText(fragment, textStyle, middleText, line.wordSpacing, [CUSTOM_TAG, 'noder-pointing'], attributes);
|
|
6609
|
+
additionalTokens += middleText.length;
|
|
6610
|
+
if (wordSpacingEnd >= 0) {
|
|
6611
|
+
const rightText = customTextFragment.substring(wordSpacingEnd + 1);
|
|
6612
|
+
this.renderText(fragment, textStyle, rightText, null, [CUSTOM_TAG, 'noder-pointing'], attributes);
|
|
6613
|
+
additionalTokens += rightText.length;
|
|
6614
|
+
}
|
|
6615
|
+
}
|
|
6616
|
+
if (text.length === customText.end) {
|
|
6617
|
+
renderedIndexes++;
|
|
6618
|
+
additionalTokens--;
|
|
6619
|
+
}
|
|
6620
|
+
return { renderedIndexes, additionalTokens };
|
|
6621
|
+
}
|
|
6622
|
+
static renderText(fragment, textStyle, content, wordSpacing, additionalClasses = [], additionalAttributes = []) {
|
|
6623
|
+
if (!content.length) {
|
|
6624
|
+
return;
|
|
6590
6625
|
}
|
|
6591
|
-
}
|
|
6592
|
-
static renderText(fragment, textStyle, content, wordSpacing) {
|
|
6593
6626
|
const span = document.createElement('span');
|
|
6594
|
-
|
|
6595
|
-
span.
|
|
6627
|
+
for (const additionalClass of additionalClasses) {
|
|
6628
|
+
span.classList.add(additionalClass);
|
|
6629
|
+
}
|
|
6630
|
+
for (const attribute of additionalAttributes) {
|
|
6631
|
+
span.setAttribute(attribute.name, attribute.value);
|
|
6596
6632
|
}
|
|
6597
6633
|
if (textStyle.headingStyleId === HYPERLINK_HEADING_STYLE_ID) {
|
|
6598
6634
|
span.classList.add('hyperlink');
|
|
@@ -7057,6 +7093,7 @@ class ParagraphHelper {
|
|
|
7057
7093
|
const { splitsCount, leftHeight, tableHeight, tableInsertIndex } = ParagraphHelper.processTableSplit(tables, startInsertIndex, leftSpaceOnPage, spaceBetweenPagesContent, currentPageVerticalData.contentHeight);
|
|
7058
7094
|
previousTableInsertIndex = tableInsertIndex;
|
|
7059
7095
|
textLineInfo.height = tableHeight;
|
|
7096
|
+
textLineInfo.ascent = tableHeight;
|
|
7060
7097
|
textLineInfo.page = currentPage;
|
|
7061
7098
|
currentPage += splitsCount;
|
|
7062
7099
|
if (splitsCount) {
|
|
@@ -7435,9 +7472,9 @@ class Range {
|
|
|
7435
7472
|
const compare = this.compareSingleLine(position);
|
|
7436
7473
|
return compare ?? this.compareMultiLine(position);
|
|
7437
7474
|
}
|
|
7438
|
-
paragraphToDocumentLine(
|
|
7439
|
-
const screenPosStart = PositionHelper.paragraphToDocumentLine(
|
|
7440
|
-
const screenPosEnd = PositionHelper.paragraphToDocumentLine(
|
|
7475
|
+
paragraphToDocumentLine(paragraphs) {
|
|
7476
|
+
const screenPosStart = PositionHelper.paragraphToDocumentLine(paragraphs[this.start.row], this.start.column);
|
|
7477
|
+
const screenPosEnd = PositionHelper.paragraphToDocumentLine(paragraphs[this.end.row], this.end.column);
|
|
7441
7478
|
return new Range(screenPosStart, screenPosEnd);
|
|
7442
7479
|
}
|
|
7443
7480
|
/**
|
|
@@ -8302,12 +8339,12 @@ class Selection {
|
|
|
8302
8339
|
this.anchor = null;
|
|
8303
8340
|
}
|
|
8304
8341
|
selectRight(session) {
|
|
8305
|
-
const position = this.
|
|
8342
|
+
const position = this.getRight(session.displayData.paragraphs, this.cursor.row, this.cursor.column);
|
|
8306
8343
|
this.moveSelection(position);
|
|
8307
8344
|
}
|
|
8308
8345
|
navigateRight(session) {
|
|
8309
8346
|
if (this.isEmpty) {
|
|
8310
|
-
const position = this.
|
|
8347
|
+
const position = this.getRight(session.displayData.paragraphs, this.cursor.row, this.cursor.column);
|
|
8311
8348
|
this.placeCursor(position);
|
|
8312
8349
|
}
|
|
8313
8350
|
else {
|
|
@@ -8316,12 +8353,12 @@ class Selection {
|
|
|
8316
8353
|
}
|
|
8317
8354
|
}
|
|
8318
8355
|
selectLeft(session) {
|
|
8319
|
-
const position = this.
|
|
8356
|
+
const position = this.getLeft(session.displayData.paragraphs, this.cursor.row, this.cursor.column);
|
|
8320
8357
|
this.moveSelection(position);
|
|
8321
8358
|
}
|
|
8322
8359
|
navigateLeft(session) {
|
|
8323
8360
|
if (this.isEmpty) {
|
|
8324
|
-
const position = this.
|
|
8361
|
+
const position = this.getLeft(session.displayData.paragraphs, this.cursor.row, this.cursor.column);
|
|
8325
8362
|
this.placeCursor(position);
|
|
8326
8363
|
}
|
|
8327
8364
|
else {
|
|
@@ -8347,12 +8384,12 @@ class Selection {
|
|
|
8347
8384
|
}
|
|
8348
8385
|
selectFileEnd(session) {
|
|
8349
8386
|
const paragraph = session.displayData.paragraphs.length - 1;
|
|
8350
|
-
const paragraphIndex = session.displayData.
|
|
8387
|
+
const paragraphIndex = session.displayData.paragraphs[paragraph].content.length;
|
|
8351
8388
|
this.moveSelection(new CursorParagraph(paragraph, paragraphIndex));
|
|
8352
8389
|
}
|
|
8353
8390
|
navigateFileEnd(session) {
|
|
8354
8391
|
const paragraph = session.displayData.paragraphs.length - 1;
|
|
8355
|
-
const paragraphIndex = session.displayData.
|
|
8392
|
+
const paragraphIndex = session.displayData.paragraphs[paragraph].content.length;
|
|
8356
8393
|
this.placeCursor(new CursorParagraph(paragraph, paragraphIndex));
|
|
8357
8394
|
}
|
|
8358
8395
|
selectFileStart() {
|
|
@@ -8378,73 +8415,80 @@ class Selection {
|
|
|
8378
8415
|
this.placeCursor(position);
|
|
8379
8416
|
}
|
|
8380
8417
|
moveCursorUp(session, position) {
|
|
8381
|
-
const
|
|
8418
|
+
const paragraphs = session.displayData.paragraphs;
|
|
8419
|
+
const line = PositionHelper.paragraphToDocumentLine(paragraphs[position.row], position.column);
|
|
8382
8420
|
if (line.row === 0) {
|
|
8383
8421
|
this.selectLineStart(session);
|
|
8422
|
+
return;
|
|
8423
|
+
}
|
|
8424
|
+
const moved = this.moveToLine(session, line.row - 1, line);
|
|
8425
|
+
if (moved.paragraph !== position.row || moved.indexInParagraph !== position.column) {
|
|
8426
|
+
this.cursor = new CursorParagraph(moved.paragraph, moved.indexInParagraph);
|
|
8384
8427
|
}
|
|
8385
8428
|
else {
|
|
8386
|
-
this.
|
|
8429
|
+
this.cursor = this.getLeft(paragraphs, moved.paragraph, moved.indexInParagraph);
|
|
8387
8430
|
}
|
|
8388
8431
|
}
|
|
8389
8432
|
moveCursorDown(session, position) {
|
|
8390
|
-
const
|
|
8391
|
-
const
|
|
8392
|
-
const
|
|
8393
|
-
const
|
|
8394
|
-
if (line.row ===
|
|
8433
|
+
const paragraphs = session.displayData.paragraphs;
|
|
8434
|
+
const line = PositionHelper.paragraphToDocumentLine(paragraphs[position.row], position.column);
|
|
8435
|
+
const lastParagraphLines = paragraphs[paragraphs.length - 1].paragraphSettings.textLinesInfo;
|
|
8436
|
+
const lastDocumentLine = lastParagraphLines[lastParagraphLines.length - 1].screenLine;
|
|
8437
|
+
if (line.row === lastDocumentLine) {
|
|
8395
8438
|
this.selectLineEnd(session);
|
|
8439
|
+
return;
|
|
8440
|
+
}
|
|
8441
|
+
const moved = this.moveToLine(session, line.row + 1, line);
|
|
8442
|
+
if (moved.paragraph !== position.row || moved.indexInParagraph !== position.column) {
|
|
8443
|
+
this.cursor = new CursorParagraph(moved.paragraph, moved.indexInParagraph);
|
|
8396
8444
|
}
|
|
8397
8445
|
else {
|
|
8398
|
-
this.
|
|
8446
|
+
this.cursor = this.getRight(paragraphs, moved.paragraph, moved.indexInParagraph);
|
|
8399
8447
|
}
|
|
8400
8448
|
}
|
|
8401
8449
|
moveToLine(session, line, fromLine) {
|
|
8402
8450
|
if (!this.keepLinePositionX) {
|
|
8403
8451
|
this.keepLinePositionX = PositionHelper.documentLineToPixel(session, fromLine.row, fromLine.column).pageX;
|
|
8404
8452
|
}
|
|
8405
|
-
const
|
|
8406
|
-
|
|
8407
|
-
|
|
8453
|
+
const { paragraph, paragraphLine } = PositionHelper.documentLineToParagraphLine(session.displayData.paragraphs, line);
|
|
8454
|
+
const indexInParagraph = PositionHelper.pixelToIndexInParagraph(session, this.keepLinePositionX, paragraph, paragraphLine, 2);
|
|
8455
|
+
return { paragraph, indexInParagraph };
|
|
8408
8456
|
}
|
|
8409
|
-
|
|
8410
|
-
if (
|
|
8411
|
-
|
|
8457
|
+
getLeft(paragraphs, paragraph, indexInParagraph) {
|
|
8458
|
+
if (paragraph === 0) {
|
|
8459
|
+
indexInParagraph -= indexInParagraph > 0 ? 1 : 0;
|
|
8460
|
+
return new CursorParagraph(paragraph, indexInParagraph);
|
|
8461
|
+
}
|
|
8462
|
+
indexInParagraph--;
|
|
8463
|
+
if (indexInParagraph >= 0) {
|
|
8464
|
+
return new CursorParagraph(paragraph, indexInParagraph);
|
|
8412
8465
|
}
|
|
8413
|
-
|
|
8414
|
-
return ContentHelper.documentIndexToParagraphIndex(session.displayData.paragraphs, index - 1);
|
|
8466
|
+
return new CursorParagraph(paragraph - 1, paragraphs[paragraph].startIndex - paragraphs[paragraph - 1].startIndex - 1);
|
|
8415
8467
|
}
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
return
|
|
8468
|
+
getRight(paragraphs, paragraph, indexInParagraph) {
|
|
8469
|
+
if (paragraph === paragraphs.length - 1) {
|
|
8470
|
+
indexInParagraph += indexInParagraph < paragraphs[paragraphs.length - 1].content.length ? 1 : 0;
|
|
8471
|
+
return new CursorParagraph(paragraph, indexInParagraph);
|
|
8420
8472
|
}
|
|
8421
|
-
|
|
8422
|
-
|
|
8473
|
+
indexInParagraph++;
|
|
8474
|
+
if (paragraphs[paragraph + 1].startIndex === paragraphs[paragraph].startIndex + indexInParagraph) {
|
|
8475
|
+
return new CursorParagraph(paragraph + 1, 0);
|
|
8476
|
+
}
|
|
8477
|
+
return new CursorParagraph(paragraph, indexInParagraph);
|
|
8423
8478
|
}
|
|
8424
8479
|
getLineStart(session, position) {
|
|
8425
|
-
const line = PositionHelper.paragraphToDocumentLine(session
|
|
8480
|
+
const line = PositionHelper.paragraphToDocumentLine(session.displayData.paragraphs[position.row], position.column);
|
|
8426
8481
|
return PositionHelper.documentLineToParagraph(session, line.row, 0);
|
|
8427
8482
|
}
|
|
8428
8483
|
getLineEnd(session, position) {
|
|
8429
|
-
const
|
|
8430
|
-
const
|
|
8431
|
-
|
|
8432
|
-
|
|
8433
|
-
return PositionHelper.documentLineToParagraph(session, line.row, paragraphLength);
|
|
8434
|
-
}
|
|
8435
|
-
const paragraphLine = line.row - session.displayData.paragraphs[position.row].lineNumber;
|
|
8436
|
-
const nextLineIndexes = session.displayData.paragraphs[position.row].nextLineIndexes;
|
|
8437
|
-
let index;
|
|
8438
|
-
if (paragraphLine === 0) {
|
|
8439
|
-
index = nextLineIndexes[0];
|
|
8440
|
-
}
|
|
8441
|
-
else if (paragraphLine === linesCount - 1) {
|
|
8442
|
-
index = paragraphLength - nextLineIndexes[paragraphLine - 1];
|
|
8484
|
+
const paragraph = session.displayData.paragraphs[position.row];
|
|
8485
|
+
const documentLine = PositionHelper.paragraphToDocumentLine(paragraph, position.column);
|
|
8486
|
+
if (documentLine.row - paragraph.lineNumber === paragraph.paragraphSettings.textLinesInfo.length - 1) {
|
|
8487
|
+
return new CursorParagraph(position.row, paragraph.content.length);
|
|
8443
8488
|
}
|
|
8444
|
-
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
return PositionHelper.documentLineToParagraph(session, line.row, index);
|
|
8489
|
+
const paragraphLine = paragraph.paragraphSettings.textLinesInfo[documentLine.row - paragraph.lineNumber];
|
|
8490
|
+
const endOfLineIndex = paragraphLine.endIndex - paragraphLine.startIndex + 1;
|
|
8491
|
+
return PositionHelper.documentLineToParagraph(session, documentLine.row, endOfLineIndex);
|
|
8448
8492
|
}
|
|
8449
8493
|
getWordRight(session, position) {
|
|
8450
8494
|
let row = position.row;
|
|
@@ -8640,7 +8684,7 @@ class Editor {
|
|
|
8640
8684
|
get grammarChecker() {
|
|
8641
8685
|
return this.regulatorService.grammarChecker;
|
|
8642
8686
|
}
|
|
8643
|
-
constructor(model, container, editorService, overlayService, regulatorService, commandsService, clipboard,
|
|
8687
|
+
constructor(model, container, editorService, overlayService, regulatorService, commandsService, clipboard, externalElementTags, insertOverlays, customPageWidth) {
|
|
8644
8688
|
this.model = model;
|
|
8645
8689
|
this.container = container;
|
|
8646
8690
|
this.editorService = editorService;
|
|
@@ -8648,14 +8692,9 @@ class Editor {
|
|
|
8648
8692
|
this.regulatorService = regulatorService;
|
|
8649
8693
|
this.commandsService = commandsService;
|
|
8650
8694
|
this.clipboard = clipboard;
|
|
8651
|
-
this.
|
|
8695
|
+
this.externalElementTags = externalElementTags;
|
|
8652
8696
|
this.insertOverlays = insertOverlays;
|
|
8653
8697
|
this.customPageWidth = customPageWidth;
|
|
8654
|
-
this.MAX_COUNT = 999;
|
|
8655
|
-
this.parentTagName = 'APP-NOD-EDITOR';
|
|
8656
|
-
this.tableCellTagName = 'APP-NOD-TABLE-CELL';
|
|
8657
|
-
this.edgeElementTagName = 'APP-NOD-EDGE';
|
|
8658
|
-
this.imageTagName = 'APP-NOD-IMAGE';
|
|
8659
8698
|
this.subscriptions = [];
|
|
8660
8699
|
this.commentCreateRequests = [];
|
|
8661
8700
|
this.emojiRegex = /\p{Extended_Pictographic}(?:\p{Emoji_Modifier}|\u{200D}\p{Extended_Pictographic})*/gu;
|
|
@@ -8670,7 +8709,7 @@ class Editor {
|
|
|
8670
8709
|
this.renderer.updateCursor();
|
|
8671
8710
|
};
|
|
8672
8711
|
this.subscriptions.push(this.receiveTextStyleSubscription());
|
|
8673
|
-
this.
|
|
8712
|
+
this.customElementTags = [...this.externalElementTags, IMAGE_TAG, TABLE_CELL_TAG, EDGE_TAG, CUSTOM_TAG];
|
|
8674
8713
|
this.history = new OperationHistory(editorService, regulatorService);
|
|
8675
8714
|
this.selection = new Selection(this.overlayService);
|
|
8676
8715
|
this.regulatorService.setSelection(this.selection);
|
|
@@ -9758,7 +9797,7 @@ class Editor {
|
|
|
9758
9797
|
}
|
|
9759
9798
|
onMouseClick(event) {
|
|
9760
9799
|
const customElement = this.setCurrentSession(event.target);
|
|
9761
|
-
if (customElement && customElement.tagName !==
|
|
9800
|
+
if (customElement && customElement.tagName !== TABLE_CELL_TAG && customElement.tagName !== EDGE_TAG) {
|
|
9762
9801
|
this.focusCustomComponent(customElement);
|
|
9763
9802
|
}
|
|
9764
9803
|
else {
|
|
@@ -9789,7 +9828,7 @@ class Editor {
|
|
|
9789
9828
|
}
|
|
9790
9829
|
onShortLeftClick(event, isSelectionClick = false) {
|
|
9791
9830
|
const customElement = this.setCurrentSession(event.target);
|
|
9792
|
-
if (customElement && customElement.tagName !==
|
|
9831
|
+
if (customElement && customElement.tagName !== TABLE_CELL_TAG && customElement.tagName !== EDGE_TAG) {
|
|
9793
9832
|
this.focusCustomComponent(customElement);
|
|
9794
9833
|
return;
|
|
9795
9834
|
}
|
|
@@ -9842,7 +9881,7 @@ class Editor {
|
|
|
9842
9881
|
this.regulatorService.setMainSessionAsCurrent();
|
|
9843
9882
|
}
|
|
9844
9883
|
}
|
|
9845
|
-
if (customElement && customElement.tagName !==
|
|
9884
|
+
if (customElement && customElement.tagName !== TABLE_CELL_TAG && customElement.tagName !== EDGE_TAG) {
|
|
9846
9885
|
this.focusCustomComponent(customElement);
|
|
9847
9886
|
return;
|
|
9848
9887
|
}
|
|
@@ -9860,7 +9899,7 @@ class Editor {
|
|
|
9860
9899
|
}
|
|
9861
9900
|
onTripleClick(event) {
|
|
9862
9901
|
const customElement = this.setCurrentSession(event.target);
|
|
9863
|
-
if (customElement && customElement.tagName !==
|
|
9902
|
+
if (customElement && customElement.tagName !== TABLE_CELL_TAG && customElement.tagName !== EDGE_TAG) {
|
|
9864
9903
|
this.focusCustomComponent(customElement);
|
|
9865
9904
|
return;
|
|
9866
9905
|
}
|
|
@@ -9874,7 +9913,7 @@ class Editor {
|
|
|
9874
9913
|
}
|
|
9875
9914
|
onQuadClick(event) {
|
|
9876
9915
|
const customElement = this.setCurrentSession(event.target);
|
|
9877
|
-
if (customElement && customElement.tagName !==
|
|
9916
|
+
if (customElement && customElement.tagName !== TABLE_CELL_TAG && customElement.tagName !== EDGE_TAG) {
|
|
9878
9917
|
this.focusCustomComponent(customElement);
|
|
9879
9918
|
return;
|
|
9880
9919
|
}
|
|
@@ -9984,17 +10023,17 @@ class Editor {
|
|
|
9984
10023
|
const isEdgeEdit = this.mainSession.customComponents.edges.isEdit;
|
|
9985
10024
|
if (!customElement || (!isEdgeEdit && isInsideEdge)) {
|
|
9986
10025
|
this.regulatorService.setMainSessionAsCurrent();
|
|
9987
|
-
return this.
|
|
10026
|
+
return this.customElementTags.includes(customElement?.tagName) ? customElement : null;
|
|
9988
10027
|
}
|
|
9989
10028
|
const elementSessionId = +customElement.attributes.getNamedItem('data-session-id').value;
|
|
9990
10029
|
this.regulatorService.setCustomSessionAsCurrent(elementSessionId);
|
|
9991
|
-
return customElement.tagName !==
|
|
10030
|
+
return customElement.tagName !== EDGE_TAG ? customElement : null;
|
|
9992
10031
|
}
|
|
9993
10032
|
getCustomElement(element) {
|
|
9994
|
-
if (!element || element.tagName ===
|
|
10033
|
+
if (!element || element.tagName === PARENT_TAG) {
|
|
9995
10034
|
return null;
|
|
9996
10035
|
}
|
|
9997
|
-
else if (this.
|
|
10036
|
+
else if (this.customElementTags.includes(element.tagName) || element.classList.contains(CUSTOM_TAG)) {
|
|
9998
10037
|
return element;
|
|
9999
10038
|
}
|
|
10000
10039
|
else {
|
|
@@ -10005,10 +10044,10 @@ class Editor {
|
|
|
10005
10044
|
return !!this.getParentEdge(element);
|
|
10006
10045
|
}
|
|
10007
10046
|
getParentEdge(element) {
|
|
10008
|
-
if (!element || element.tagName ===
|
|
10047
|
+
if (!element || element.tagName === PARENT_TAG) {
|
|
10009
10048
|
return null;
|
|
10010
10049
|
}
|
|
10011
|
-
else if (element.tagName ===
|
|
10050
|
+
else if (element.tagName === EDGE_TAG) {
|
|
10012
10051
|
return element;
|
|
10013
10052
|
}
|
|
10014
10053
|
else {
|
|
@@ -10084,7 +10123,7 @@ class Editor {
|
|
|
10084
10123
|
return;
|
|
10085
10124
|
}
|
|
10086
10125
|
const customElement = this.container.nativeElement.querySelector(`[data-session-id="${this.session.sessionId}"]`);
|
|
10087
|
-
if (customElement.tagName ===
|
|
10126
|
+
if (customElement.tagName === TABLE_CELL_TAG) {
|
|
10088
10127
|
const tableSession = this.regulatorService.getSession(this.regulatorService.currentSession.parentSessionId);
|
|
10089
10128
|
const table = tableSession.customComponents.tables.find(x => x.instance.sessionId === this.regulatorService.currentSession.parentSessionId);
|
|
10090
10129
|
table.instance.tableSelection.clearSelection();
|
|
@@ -10900,7 +10939,7 @@ class DisplayToken {
|
|
|
10900
10939
|
get isWhiteSpace() {
|
|
10901
10940
|
return this.isSpace || this.isParagraph;
|
|
10902
10941
|
}
|
|
10903
|
-
get
|
|
10942
|
+
get isBreak() {
|
|
10904
10943
|
return this.isPageBreak || this.isLineBreak;
|
|
10905
10944
|
}
|
|
10906
10945
|
get breakable() {
|
|
@@ -12173,13 +12212,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
12173
12212
|
}], ctorParameters: () => [{ type: ComponentService }, { type: i0.ElementRef }, { type: OverlayService }, { type: RegulatorService }] });
|
|
12174
12213
|
|
|
12175
12214
|
class DisplayTokenHelper {
|
|
12176
|
-
static
|
|
12215
|
+
static getParagraphToken(paragraphSymbolStyle, index) {
|
|
12216
|
+
const size = FontMetrics.measureCharSize('0', ContentStyleHelper.getFontStylesString(paragraphSymbolStyle));
|
|
12217
|
+
return new DisplayToken({ ...size, displayValue: DisplayValue.paragraph, index });
|
|
12218
|
+
}
|
|
12219
|
+
static getBreakToken(symbol, fontString, breakType, index) {
|
|
12220
|
+
return new DisplayToken({
|
|
12221
|
+
...FontMetrics.measureCharSize(symbol, fontString),
|
|
12222
|
+
displayValue: this.getBreakDisplayValue(breakType),
|
|
12223
|
+
index
|
|
12224
|
+
});
|
|
12225
|
+
}
|
|
12226
|
+
static getSymbolToken(symbol, fontString, index) {
|
|
12227
|
+
const result = new DisplayToken({
|
|
12228
|
+
...FontMetrics.measureCharSize(symbol, fontString),
|
|
12229
|
+
displayValue: this.getSymbolDisplayValue(symbol),
|
|
12230
|
+
index
|
|
12231
|
+
});
|
|
12232
|
+
if (result.isSpace) {
|
|
12233
|
+
result.ascent = 0;
|
|
12234
|
+
result.descent = 0;
|
|
12235
|
+
result.height = 0;
|
|
12236
|
+
}
|
|
12237
|
+
return result;
|
|
12238
|
+
}
|
|
12239
|
+
static getComponentTokens(component, fontString, index) {
|
|
12240
|
+
if (component.instance instanceof ExternalComponent && component.instance.isText) {
|
|
12241
|
+
const result = [];
|
|
12242
|
+
let text = component.instance.getText();
|
|
12243
|
+
text = !text.length ? ' ' : text;
|
|
12244
|
+
for (let i = 0; i < text.length; i++) {
|
|
12245
|
+
result.push(this.getSymbolToken(text[i], fontString, index));
|
|
12246
|
+
result[i].customIndex = i;
|
|
12247
|
+
}
|
|
12248
|
+
return result.length ? result : [this.getSymbolToken(' ', fontString, index)];
|
|
12249
|
+
}
|
|
12250
|
+
const ascent = component.instance.ascent() ?? 0;
|
|
12251
|
+
const descent = component.instance.descent() ?? 0;
|
|
12252
|
+
return [
|
|
12253
|
+
new DisplayToken({
|
|
12254
|
+
width: component.instance.width(),
|
|
12255
|
+
height: ascent + descent,
|
|
12256
|
+
font: FontMetrics.measureCharSize('0', fontString).font,
|
|
12257
|
+
ascent,
|
|
12258
|
+
descent,
|
|
12259
|
+
displayValue: this.getComponentDisplayValue(component.instance),
|
|
12260
|
+
index
|
|
12261
|
+
})
|
|
12262
|
+
];
|
|
12263
|
+
}
|
|
12264
|
+
static getBreakDisplayValue(breakType) {
|
|
12177
12265
|
if (breakType === BreakTypes.Page) {
|
|
12178
12266
|
return DisplayValue.pageBreak;
|
|
12179
12267
|
}
|
|
12180
12268
|
if (breakType === BreakTypes.TextWrapping) {
|
|
12181
12269
|
return DisplayValue.lineBreak;
|
|
12182
12270
|
}
|
|
12271
|
+
return DisplayValue.char;
|
|
12272
|
+
}
|
|
12273
|
+
static getSymbolDisplayValue(symbol) {
|
|
12274
|
+
const charCode = symbol.charCodeAt(0);
|
|
12183
12275
|
if (charCode === 32) {
|
|
12184
12276
|
return DisplayValue.space;
|
|
12185
12277
|
}
|
|
@@ -12191,32 +12283,14 @@ class DisplayTokenHelper {
|
|
|
12191
12283
|
}
|
|
12192
12284
|
return DisplayValue.char;
|
|
12193
12285
|
}
|
|
12194
|
-
static
|
|
12195
|
-
|
|
12196
|
-
|
|
12197
|
-
}
|
|
12198
|
-
static getSymbolToken(code, size, breakType) {
|
|
12199
|
-
const result = new DisplayToken({ ...size, displayValue: DisplayTokenHelper.getDisplayValue(code, breakType) });
|
|
12200
|
-
if (result.isSpace) {
|
|
12201
|
-
result.ascent = 0;
|
|
12202
|
-
result.descent = 0;
|
|
12203
|
-
result.height = 0;
|
|
12286
|
+
static getComponentDisplayValue(instance) {
|
|
12287
|
+
if (instance instanceof NoderTabComponent) {
|
|
12288
|
+
return DisplayValue.tab;
|
|
12204
12289
|
}
|
|
12205
|
-
|
|
12206
|
-
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
const descent = component.instance.descent() ?? 0;
|
|
12210
|
-
let displayValue = component.instance instanceof NoderTabComponent ? DisplayValue.tab : DisplayValue.customContent;
|
|
12211
|
-
displayValue = component.instance instanceof NoderTableComponent ? DisplayValue.table : displayValue;
|
|
12212
|
-
return new DisplayToken({
|
|
12213
|
-
width: component.instance.width(),
|
|
12214
|
-
height: ascent + descent,
|
|
12215
|
-
font: size.font,
|
|
12216
|
-
ascent,
|
|
12217
|
-
descent,
|
|
12218
|
-
displayValue
|
|
12219
|
-
});
|
|
12290
|
+
if (instance instanceof NoderTableComponent) {
|
|
12291
|
+
return DisplayValue.table;
|
|
12292
|
+
}
|
|
12293
|
+
return DisplayValue.customContent;
|
|
12220
12294
|
}
|
|
12221
12295
|
}
|
|
12222
12296
|
|
|
@@ -12240,72 +12314,26 @@ class LineInfoModel {
|
|
|
12240
12314
|
}
|
|
12241
12315
|
|
|
12242
12316
|
class LineInfoHelper {
|
|
12243
|
-
static get(tokens,
|
|
12317
|
+
static get(tokens, style, indent, width, paragraphStartIndex, position) {
|
|
12244
12318
|
const result = new LineInfoModel({
|
|
12245
|
-
isAfterPageBreak,
|
|
12246
|
-
isEndedByPageBreak: tokens[tokens.length - 1].isPageBreak,
|
|
12319
|
+
isAfterPageBreak: position.isAfterPageBreak,
|
|
12320
|
+
isEndedByPageBreak: tokens[tokens.length - 1].isPageBreak || (tokens.length > 1 && tokens[tokens.length - 2].isPageBreak),
|
|
12247
12321
|
backgroundColor: style.backgroundColor,
|
|
12248
12322
|
align: style.alignment ?? DEFAULT_PARAGRAPH_STYLE.alignment,
|
|
12249
12323
|
indent,
|
|
12250
12324
|
offsetBefore: DEFAULT_PARAGRAPH_STYLE.spaceBefore,
|
|
12251
12325
|
lineSpacing: style.lineSpacing ?? DEFAULT_PARAGRAPH_STYLE.lineSpacing,
|
|
12252
|
-
|
|
12326
|
+
startIndex: tokens[0].index - paragraphStartIndex,
|
|
12327
|
+
endIndex: tokens[tokens.length - 1].index - paragraphStartIndex,
|
|
12328
|
+
isNumbering: position.isNumbering,
|
|
12253
12329
|
hasTable: false,
|
|
12254
12330
|
width: 0
|
|
12255
12331
|
});
|
|
12256
|
-
|
|
12257
|
-
|
|
12258
|
-
|
|
12259
|
-
if (maxAscent < token.ascent) {
|
|
12260
|
-
maxAscent = token.ascent;
|
|
12261
|
-
}
|
|
12262
|
-
if (maxDescent < token.descent) {
|
|
12263
|
-
maxDescent = token.descent;
|
|
12264
|
-
}
|
|
12265
|
-
result.width += token.width;
|
|
12266
|
-
}
|
|
12267
|
-
result.height = maxAscent + maxDescent;
|
|
12268
|
-
result.ascent = maxAscent;
|
|
12269
|
-
if (result.height === 0) {
|
|
12270
|
-
result.height = defaultHeight;
|
|
12271
|
-
result.ascent = defaultAscent;
|
|
12272
|
-
}
|
|
12273
|
-
result.offsetAfter = result.height * (result.lineSpacing - 1);
|
|
12274
|
-
if (style.alignment === Alignment$1.justify && !isLastLine) {
|
|
12275
|
-
let right = tokens.length - 1;
|
|
12276
|
-
let adjustableWidth = result.width;
|
|
12277
|
-
while (right > 0 && tokens[right].isSpace) {
|
|
12278
|
-
adjustableWidth -= tokens[right].width;
|
|
12279
|
-
right--;
|
|
12280
|
-
}
|
|
12281
|
-
let left = 0;
|
|
12282
|
-
while (left < tokens.length - 1 && tokens[left].isSpace) {
|
|
12283
|
-
left++;
|
|
12284
|
-
}
|
|
12285
|
-
let spaces = 0;
|
|
12286
|
-
for (let i = right; i > left; i--) {
|
|
12287
|
-
if (tokens[i].isTab) {
|
|
12288
|
-
left = i;
|
|
12289
|
-
}
|
|
12290
|
-
if (tokens[i].isSpace) {
|
|
12291
|
-
spaces++;
|
|
12292
|
-
}
|
|
12293
|
-
}
|
|
12294
|
-
const indentWidth = (indent.left ?? 0) + (indent.right ?? 0) + (indent.firstLine ?? 0) - (indent.hanging ?? 0);
|
|
12295
|
-
const availableWidth = width - indentWidth - indent.markerWidth; // todo: use NumberingHelper.getOffsetCausedByMarker
|
|
12296
|
-
const whitespaceDeficit = availableWidth - adjustableWidth;
|
|
12297
|
-
if (spaces > 0 && whitespaceDeficit > 0) {
|
|
12298
|
-
result.wordSpacing = whitespaceDeficit / spaces;
|
|
12299
|
-
result.width = availableWidth;
|
|
12300
|
-
result.wordSpacingStart = left;
|
|
12301
|
-
result.wordSpacingEnd = right;
|
|
12302
|
-
for (let i = right; i > left; i--) {
|
|
12303
|
-
if (tokens[i].isSpace) {
|
|
12304
|
-
tokens[i].width += result.wordSpacing;
|
|
12305
|
-
}
|
|
12306
|
-
}
|
|
12307
|
-
}
|
|
12332
|
+
this.applySizeToLine(result, tokens);
|
|
12333
|
+
if (style.alignment === Alignment$1.justify && !position.isLastLine) {
|
|
12334
|
+
this.applyWordSpacingToLine(result, tokens, indent, width, paragraphStartIndex);
|
|
12308
12335
|
}
|
|
12336
|
+
this.applyCustomTextsToLine(result, tokens, paragraphStartIndex);
|
|
12309
12337
|
return result;
|
|
12310
12338
|
}
|
|
12311
12339
|
static getFirstLineIndent(model, paragraphIndex, generalProperties) {
|
|
@@ -12323,6 +12351,86 @@ class LineInfoHelper {
|
|
|
12323
12351
|
? paragraph.paragraphStyle.indentLeft
|
|
12324
12352
|
: levelsModel[paragraphStyle.numberingLevel].indentLeft, paragraph.paragraphStyle.indentRight ?? DEFAULT_PARAGRAPH_STYLE.indentRight, markerWidth + markerWidth / marker.length);
|
|
12325
12353
|
}
|
|
12354
|
+
static applySizeToLine(line, tokens) {
|
|
12355
|
+
const lastToken = tokens[tokens.length - 1];
|
|
12356
|
+
let maxAscent = 0;
|
|
12357
|
+
let maxDescent = 0;
|
|
12358
|
+
let i = 0;
|
|
12359
|
+
const length = lastToken.isParagraph && tokens.length > 1 ? tokens.length - 1 : tokens.length;
|
|
12360
|
+
do {
|
|
12361
|
+
if (maxAscent < tokens[i].ascent) {
|
|
12362
|
+
maxAscent = tokens[i].ascent;
|
|
12363
|
+
}
|
|
12364
|
+
if (maxDescent < tokens[i].descent) {
|
|
12365
|
+
maxDescent = tokens[i].descent;
|
|
12366
|
+
}
|
|
12367
|
+
line.width += tokens[i].width;
|
|
12368
|
+
i++;
|
|
12369
|
+
} while (i < length);
|
|
12370
|
+
line.height = maxAscent + maxDescent;
|
|
12371
|
+
line.ascent = maxAscent;
|
|
12372
|
+
if (line.height === 0) {
|
|
12373
|
+
line.height = lastToken.ascent + lastToken.descent;
|
|
12374
|
+
line.ascent = lastToken.ascent;
|
|
12375
|
+
}
|
|
12376
|
+
line.offsetAfter = line.height * (line.lineSpacing - 1);
|
|
12377
|
+
}
|
|
12378
|
+
static applyWordSpacingToLine(line, tokens, indent, width, paragraphStartIndex) {
|
|
12379
|
+
const lastToken = tokens[tokens.length - 1].isParagraph ? tokens.length - 2 : tokens.length - 1;
|
|
12380
|
+
let right = lastToken;
|
|
12381
|
+
let adjustableWidth = line.width;
|
|
12382
|
+
while (right > 0 && tokens[right].isSpace) {
|
|
12383
|
+
adjustableWidth -= tokens[right].width;
|
|
12384
|
+
right--;
|
|
12385
|
+
}
|
|
12386
|
+
let left = 0;
|
|
12387
|
+
while (left < lastToken && tokens[left].isSpace) {
|
|
12388
|
+
left++;
|
|
12389
|
+
}
|
|
12390
|
+
let spaces = 0;
|
|
12391
|
+
for (let i = right; i > left; i--) {
|
|
12392
|
+
if (tokens[i].isTab) {
|
|
12393
|
+
left = i;
|
|
12394
|
+
}
|
|
12395
|
+
if (tokens[i].isSpace) {
|
|
12396
|
+
spaces++;
|
|
12397
|
+
}
|
|
12398
|
+
}
|
|
12399
|
+
const indentWidth = (indent.left ?? 0) + (indent.right ?? 0) + (indent.firstLine ?? 0) - (indent.hanging ?? 0);
|
|
12400
|
+
const availableWidth = width - indentWidth - indent.markerWidth; // todo: use NumberingHelper.getOffsetCausedByMarker
|
|
12401
|
+
const whitespaceDeficit = availableWidth - adjustableWidth;
|
|
12402
|
+
if (spaces > 0 && whitespaceDeficit > 0) {
|
|
12403
|
+
line.wordSpacing = whitespaceDeficit / spaces;
|
|
12404
|
+
line.width = availableWidth;
|
|
12405
|
+
line.wordSpacingStartToken = left;
|
|
12406
|
+
line.wordSpacingEndToken = right;
|
|
12407
|
+
line.wordSpacingStartIndex = tokens[left].index - paragraphStartIndex;
|
|
12408
|
+
line.wordSpacingEndIndex = tokens[right].index - paragraphStartIndex;
|
|
12409
|
+
for (let i = right; i > left; i--) {
|
|
12410
|
+
if (tokens[i].isSpace) {
|
|
12411
|
+
tokens[i].width += line.wordSpacing;
|
|
12412
|
+
}
|
|
12413
|
+
}
|
|
12414
|
+
}
|
|
12415
|
+
}
|
|
12416
|
+
static applyCustomTextsToLine(line, tokens, paragraphStartIndex) {
|
|
12417
|
+
for (const token of tokens) {
|
|
12418
|
+
if (token.customIndex >= 0) {
|
|
12419
|
+
const indexInParagraph = token.index - paragraphStartIndex;
|
|
12420
|
+
if (line.customTexts && line.customTexts[line.customTexts.length - 1].index === indexInParagraph) {
|
|
12421
|
+
line.customTexts[line.customTexts.length - 1].end++;
|
|
12422
|
+
}
|
|
12423
|
+
else {
|
|
12424
|
+
line.customTexts ??= [];
|
|
12425
|
+
line.customTexts.push({
|
|
12426
|
+
index: indexInParagraph,
|
|
12427
|
+
start: token.customIndex,
|
|
12428
|
+
end: token.customIndex + 1
|
|
12429
|
+
});
|
|
12430
|
+
}
|
|
12431
|
+
}
|
|
12432
|
+
}
|
|
12433
|
+
}
|
|
12326
12434
|
}
|
|
12327
12435
|
|
|
12328
12436
|
class PageVerticalDataModel {
|
|
@@ -12809,13 +12917,13 @@ class DisplayData extends EventEmitting {
|
|
|
12809
12917
|
this.removeAllListeners('pagesCountChanged');
|
|
12810
12918
|
}
|
|
12811
12919
|
updateParagraphLineNumber(first) {
|
|
12812
|
-
const count = this.paragraphs.length;
|
|
12813
12920
|
if (first === 0) {
|
|
12814
12921
|
this.paragraphs[first].lineNumber = 0;
|
|
12815
12922
|
first++;
|
|
12816
12923
|
}
|
|
12817
|
-
for (let i = first; i <
|
|
12818
|
-
this.paragraphs[i].lineNumber =
|
|
12924
|
+
for (let i = first; i < this.paragraphs.length; i++) {
|
|
12925
|
+
this.paragraphs[i].lineNumber =
|
|
12926
|
+
this.paragraphs[i - 1].lineNumber + this.paragraphs[i - 1].paragraphSettings.textLinesInfo.length;
|
|
12819
12927
|
}
|
|
12820
12928
|
}
|
|
12821
12929
|
updateParagraphStartIndex(first) {
|
|
@@ -12863,8 +12971,7 @@ class DisplayData extends EventEmitting {
|
|
|
12863
12971
|
NumberingHelper.setNumberingNeedToRecalculate(this.generalProperties.numberingInfo, numberingId);
|
|
12864
12972
|
}
|
|
12865
12973
|
const numberingData = NumberingHelper.createDataModel(this.generalProperties.numberings, this.model.paragraphs, i, this.generalProperties.numberingInfo);
|
|
12866
|
-
const
|
|
12867
|
-
this.paragraphs[i].nextLineIndexes = splits;
|
|
12974
|
+
const rowInfos = this.splitParagraphByLines(i);
|
|
12868
12975
|
if (indexOfParagraphAfterPageBreak === i) {
|
|
12869
12976
|
rowInfos[0].isAfterPageBreak = true;
|
|
12870
12977
|
}
|
|
@@ -12912,29 +13019,29 @@ class DisplayData extends EventEmitting {
|
|
|
12912
13019
|
}
|
|
12913
13020
|
splitParagraphByLines(paragraphIndex) {
|
|
12914
13021
|
const paragraph = this.paragraphs[paragraphIndex];
|
|
12915
|
-
const
|
|
12916
|
-
const
|
|
13022
|
+
const isLastParagraph = paragraphIndex === this.paragraphs.length - 1;
|
|
13023
|
+
const paragraphSymbolIndex = paragraph.startIndex + paragraph.content.length;
|
|
13024
|
+
const paragraphTokens = this.getTokens(paragraph.startIndex, paragraph.content, paragraphSymbolIndex);
|
|
12917
13025
|
const rowInfos = [];
|
|
12918
13026
|
const style = this.model.paragraphs[paragraphIndex].paragraphStyle;
|
|
12919
13027
|
const pageFormat = this.getPageFormatAtPosition(paragraph.startIndex);
|
|
12920
|
-
const defaultHeight = paragraphToken.height;
|
|
12921
|
-
const defaultAscent = paragraphToken.ascent;
|
|
12922
13028
|
let index = 0;
|
|
12923
13029
|
let indent = LineInfoHelper.getFirstLineIndent(this.model, paragraphIndex, this.generalProperties);
|
|
12924
13030
|
do {
|
|
12925
13031
|
let tokens = paragraphTokens.slice(index);
|
|
12926
13032
|
const maxWidth = pageFormat.contentWidth - indent.right - indent.markerWidth;
|
|
12927
|
-
|
|
12928
|
-
|
|
13033
|
+
const startWidth = indent.left + indent.firstLine - indent.hanging || 0;
|
|
13034
|
+
const last = this.computeWrapToken(tokens, startWidth, maxWidth, style.tabSettings ?? [], isLastParagraph);
|
|
12929
13035
|
tokens = tokens.slice(0, last + 1);
|
|
12930
13036
|
const width = pageFormat.contentWidth;
|
|
12931
13037
|
const isNumbering = index === 0 && !!indent.markerWidth;
|
|
12932
|
-
const
|
|
12933
|
-
const
|
|
12934
|
-
const
|
|
13038
|
+
const isAfterPageBreak = !rowInfos.length ? false : rowInfos[rowInfos.length - 1].isEndedByPageBreak;
|
|
13039
|
+
const isLastLine = index + last + 1 === paragraphTokens.length;
|
|
13040
|
+
const position = { isLastLine, isNumbering, isAfterPageBreak };
|
|
13041
|
+
const info = LineInfoHelper.get(tokens, style, indent, width, paragraph.startIndex, position);
|
|
12935
13042
|
for (let i = 0; i < tokens.length; i++) {
|
|
12936
13043
|
if (tokens[i].isTab) {
|
|
12937
|
-
const tab = this.customComponents.tabs.find(x => x.instance.insertIndex ===
|
|
13044
|
+
const tab = this.customComponents.tabs.find(x => x.instance.insertIndex === tokens[i].index);
|
|
12938
13045
|
tab.instance.applySize(tokens[i].width);
|
|
12939
13046
|
}
|
|
12940
13047
|
else if (tokens[i].isTable) {
|
|
@@ -12944,61 +13051,57 @@ class DisplayData extends EventEmitting {
|
|
|
12944
13051
|
rowInfos.push(info);
|
|
12945
13052
|
index += last + 1;
|
|
12946
13053
|
if (index < paragraphTokens.length) {
|
|
12947
|
-
splits.push(index);
|
|
12948
13054
|
indent = new IndentModel(null, null, indent.left, indent.right, 0);
|
|
12949
13055
|
}
|
|
12950
13056
|
} while (index < paragraphTokens.length);
|
|
12951
13057
|
ParagraphHelper.applyParagraphIndentsToLines(rowInfos, paragraphIndex, this.model.paragraphs);
|
|
12952
|
-
return
|
|
12953
|
-
}
|
|
12954
|
-
getParagraphTokens(paragraphInfo) {
|
|
12955
|
-
const paragraphSymbolIndex = paragraphInfo.startIndex + paragraphInfo.content.length;
|
|
12956
|
-
const { tokens, paragraphToken } = this.getTokens(paragraphInfo.startIndex, paragraphInfo.content, paragraphSymbolIndex);
|
|
12957
|
-
return { paragraphTokens: tokens, paragraphToken };
|
|
13058
|
+
return rowInfos;
|
|
12958
13059
|
}
|
|
12959
13060
|
getParagraphLineTokens(paragraphIndex, paragraphLine) {
|
|
12960
13061
|
const paragraph = this.paragraphs[paragraphIndex];
|
|
12961
|
-
const
|
|
12962
|
-
const
|
|
12963
|
-
const lineContent = paragraph.content.substring(
|
|
13062
|
+
const isLastParagraph = paragraphIndex === this.paragraphs.length - 1;
|
|
13063
|
+
const line = paragraph.paragraphSettings.textLinesInfo[paragraphLine];
|
|
13064
|
+
const lineContent = paragraph.content.substring(line.startIndex, line.endIndex + 1);
|
|
12964
13065
|
const paragraphSymbolIndex = paragraph.paragraphSettings.startInsertIndex + paragraph.content.length;
|
|
12965
|
-
const
|
|
13066
|
+
const tokens = this.getTokens(line.startIndex + paragraph.startIndex, lineContent, paragraphSymbolIndex);
|
|
13067
|
+
if (line.customTexts && line.customTexts[0].index === line.startIndex) {
|
|
13068
|
+
tokens.splice(0, line.customTexts[0].start); // cut additional tokens in case when line starts from the middle of the textual custom component
|
|
13069
|
+
}
|
|
12966
13070
|
const pageFormat = this.getPageFormatAtPosition(this.paragraphs[paragraphIndex].startIndex);
|
|
12967
13071
|
const paragraphStyle = this.model.paragraphs[paragraphIndex].paragraphStyle;
|
|
12968
|
-
const
|
|
12969
|
-
const
|
|
12970
|
-
const
|
|
12971
|
-
|
|
12972
|
-
const
|
|
12973
|
-
|
|
13072
|
+
const maxWidth = pageFormat.contentWidth - line.indent.right - line.indent.markerWidth;
|
|
13073
|
+
const startWidth = line.indentLeft + line.indentFirstLine - line.indent.hanging || 0;
|
|
13074
|
+
const last = this.computeWrapToken(tokens, startWidth, maxWidth, paragraphStyle.tabSettings ?? [], isLastParagraph); // tab width correction for tokens according to the tabs complex positioning
|
|
13075
|
+
tokens.splice(last + 1); // cut additional tokens in case when line ends in the middle of the textual custom component
|
|
13076
|
+
const isLastLine = paragraphLine === paragraph.paragraphSettings.textLinesInfo.length - 1;
|
|
13077
|
+
const position = { isLastLine, isNumbering: line.isNumbering, isAfterPageBreak: false };
|
|
13078
|
+
LineInfoHelper.get(tokens, paragraphStyle, line.indent, pageFormat.contentWidth, 0, position); // space width correction for tokens according to the wordSpacing in case of justify alignment
|
|
12974
13079
|
return tokens;
|
|
12975
13080
|
}
|
|
12976
13081
|
getTokens(contentIndex, content, paragraphSymbolIndex) {
|
|
12977
13082
|
const tokens = [];
|
|
12978
|
-
const prev = { char: '', style: null, size: null };
|
|
12979
13083
|
let format = FormatStyleHelper.getFormatAtIndex(this.model.formats, contentIndex);
|
|
12980
13084
|
let fontString = ContentStyleHelper.getFontStylesString(format.textStyle);
|
|
12981
13085
|
for (let i = 0; i < content.length; i++) {
|
|
12982
|
-
if (content[i] !== prev.char || !prev.style || !ContentStyleHelper.areSameTextStyles(format.textStyle, prev.style)) {
|
|
12983
|
-
prev.size = FontMetrics.measureCharSize(content[i], fontString);
|
|
12984
|
-
prev.char = content[i];
|
|
12985
|
-
prev.style = format.textStyle;
|
|
12986
|
-
}
|
|
12987
|
-
const customComponent = this.getOrGenerateComponent(contentIndex, content[i]);
|
|
12988
13086
|
const breakType = BreakHelper.getBreakType(this.model.breaks, content[i], contentIndex);
|
|
12989
|
-
const
|
|
12990
|
-
|
|
12991
|
-
|
|
13087
|
+
const customComponent = breakType === null ? this.getOrGenerateComponent(contentIndex, content[i]) : null;
|
|
13088
|
+
let newTokens = breakType !== null ? [DisplayTokenHelper.getBreakToken(content[i], fontString, breakType, contentIndex)] : null;
|
|
13089
|
+
newTokens ??= customComponent
|
|
13090
|
+
? DisplayTokenHelper.getComponentTokens(customComponent, fontString, contentIndex)
|
|
13091
|
+
: [DisplayTokenHelper.getSymbolToken(content[i], fontString, contentIndex)];
|
|
12992
13092
|
contentIndex++;
|
|
12993
13093
|
if (contentIndex > format.endIndex) {
|
|
12994
13094
|
format = FormatStyleHelper.getFormatAtIndex(this.model.formats, contentIndex);
|
|
12995
13095
|
fontString = ContentStyleHelper.getFontStylesString(format.textStyle);
|
|
12996
13096
|
}
|
|
12997
|
-
tokens.push(
|
|
13097
|
+
tokens.push(...newTokens);
|
|
12998
13098
|
}
|
|
12999
|
-
|
|
13000
|
-
|
|
13001
|
-
|
|
13099
|
+
if (contentIndex === paragraphSymbolIndex) {
|
|
13100
|
+
const paragraphFormat = FormatStyleHelper.getFormatAtIndex(this.model.formats, contentIndex);
|
|
13101
|
+
const paragraphToken = DisplayTokenHelper.getParagraphToken(paragraphFormat.textStyle, contentIndex);
|
|
13102
|
+
tokens.push(paragraphToken);
|
|
13103
|
+
}
|
|
13104
|
+
return tokens;
|
|
13002
13105
|
}
|
|
13003
13106
|
getOrGenerateComponent(charIndex, char) {
|
|
13004
13107
|
if (!this.customContentService.isSpecialMarker(char)) {
|
|
@@ -13006,9 +13109,6 @@ class DisplayData extends EventEmitting {
|
|
|
13006
13109
|
}
|
|
13007
13110
|
const existingComponent = this.customContentService.getComponent(this.customComponents, char, charIndex);
|
|
13008
13111
|
if (existingComponent) {
|
|
13009
|
-
if (existingComponent.instance instanceof NoderTableComponent) {
|
|
13010
|
-
existingComponent.instance.updateCells();
|
|
13011
|
-
}
|
|
13012
13112
|
return existingComponent;
|
|
13013
13113
|
}
|
|
13014
13114
|
const pageFormat = this.getPageFormatAtPosition(charIndex);
|
|
@@ -13044,16 +13144,19 @@ class DisplayData extends EventEmitting {
|
|
|
13044
13144
|
}
|
|
13045
13145
|
return -1;
|
|
13046
13146
|
}
|
|
13047
|
-
//
|
|
13048
|
-
|
|
13147
|
+
// Compute token which should be the last on the line
|
|
13148
|
+
computeWrapToken(displayTokens, startWidth, maxWidth, tabSettings, isLastParagraph) {
|
|
13049
13149
|
let width = startWidth;
|
|
13050
13150
|
let lastBreakable = -1;
|
|
13051
13151
|
const lastTab = { token: null, alignment: TabAlignment.Left, usedWidth: 0, tokenWidth: 0 };
|
|
13052
13152
|
for (let i = 0; i < displayTokens.length; i++) {
|
|
13053
13153
|
const token = displayTokens[i];
|
|
13054
|
-
if (token.
|
|
13154
|
+
if (token.isParagraph) {
|
|
13055
13155
|
return i;
|
|
13056
13156
|
}
|
|
13157
|
+
if (token.isBreak) {
|
|
13158
|
+
return i + 1 < displayTokens.length && displayTokens[i + 1].isParagraph && !isLastParagraph ? i + 1 : i;
|
|
13159
|
+
}
|
|
13057
13160
|
if (token.isTable) {
|
|
13058
13161
|
return i > 0 ? i - 1 : 0;
|
|
13059
13162
|
}
|
|
@@ -13202,7 +13305,7 @@ class DisplayData extends EventEmitting {
|
|
|
13202
13305
|
const right = this.paragraphs[position.row].content.slice(position.column);
|
|
13203
13306
|
const originalParagraphId = this.paragraphs[position.row].id;
|
|
13204
13307
|
const insertParagraphs = this.splitByParagraphs(`${left}${text}${right}`).map((x, i) => {
|
|
13205
|
-
const newParagraph = new ParagraphInfoModel({ content: x
|
|
13308
|
+
const newParagraph = new ParagraphInfoModel({ content: x });
|
|
13206
13309
|
if (i === 0) {
|
|
13207
13310
|
newParagraph.id = originalParagraphId;
|
|
13208
13311
|
}
|
|
@@ -14826,9 +14929,9 @@ class HighlightLayer {
|
|
|
14826
14929
|
}
|
|
14827
14930
|
drawCustomElementHighlight(elementInfo, cssClass, screenParentRange) {
|
|
14828
14931
|
const paragraphPos = elementInfo.parentRange.start;
|
|
14829
|
-
const documentLine = PositionHelper.paragraphToDocumentLine(this.session, paragraphPos.row, paragraphPos.column);
|
|
14830
14932
|
const paragraph = this.session.displayData.paragraphs[paragraphPos.row];
|
|
14831
|
-
const
|
|
14933
|
+
const documentLine = PositionHelper.paragraphToDocumentLine(paragraph, paragraphPos.column);
|
|
14934
|
+
const lineInfo = paragraph.paragraphSettings.textLinesInfo.find(x => x.screenLine === documentLine.row);
|
|
14832
14935
|
const elementIndex = paragraph.startIndex + paragraphPos.column;
|
|
14833
14936
|
const element = this.session.customComponents.customElements.find(x => x.instance.content.insertIndex === elementIndex);
|
|
14834
14937
|
if (!element) {
|
|
@@ -14876,7 +14979,7 @@ class CommentHighlightLayer extends HighlightLayer {
|
|
|
14876
14979
|
const startPosition = ContentHelper.documentIndexToParagraphIndex(this.session.displayData.paragraphs, comment.startIndex);
|
|
14877
14980
|
const endPosition = ContentHelper.documentIndexToParagraphIndex(this.session.displayData.paragraphs, comment.endIndex + 1);
|
|
14878
14981
|
const range = new Range(startPosition, endPosition);
|
|
14879
|
-
const screenRange = range.paragraphToDocumentLine(this.session);
|
|
14982
|
+
const screenRange = range.paragraphToDocumentLine(this.session.displayData.paragraphs);
|
|
14880
14983
|
if (config.visibleRange &&
|
|
14881
14984
|
(screenRange.end.row < config.visibleRange.startScreenLine || screenRange.start.row > config.visibleRange.endScreenLine)) {
|
|
14882
14985
|
this.commentService.removeCommentFromRender(this.session.sessionId, comment.commentId);
|
|
@@ -14988,14 +15091,14 @@ class CursorLayer {
|
|
|
14988
15091
|
this.addAnimationClass();
|
|
14989
15092
|
}
|
|
14990
15093
|
drawCursor(maxLayerHeight) {
|
|
14991
|
-
|
|
15094
|
+
// check does not make much sense, as right condition is true all the time (maybe it should be height instead of maxHeight), also it ignores scroll in virtual renderer case
|
|
15095
|
+
const isCursorInView = this.cursorPosition.pageY + this.cursorPosition.height >= 0 && this.cursorPosition.pageY < maxLayerHeight;
|
|
14992
15096
|
if (!isCursorInView) {
|
|
14993
15097
|
DomHelper.setStyle(this.cursor.style, 'display', 'none');
|
|
14994
15098
|
return;
|
|
14995
15099
|
}
|
|
14996
15100
|
DomHelper.setStyle(this.cursor.style, 'display', 'block');
|
|
14997
15101
|
DomHelper.setStyle(this.cursor.style, 'left', `${this.cursorPosition.pageX}px`);
|
|
14998
|
-
DomHelper.setStyle(this.cursor.style, 'width', `${this.cursorPosition.width}px`);
|
|
14999
15102
|
this.addTextStylesToCursor();
|
|
15000
15103
|
}
|
|
15001
15104
|
removeAnimationClass() {
|
|
@@ -15026,7 +15129,7 @@ class GrammarHighlightLayer extends HighlightLayer {
|
|
|
15026
15129
|
continue;
|
|
15027
15130
|
}
|
|
15028
15131
|
for (const error of grammarErrors) {
|
|
15029
|
-
const range = new Range(new CursorParagraph(index, error.offset), new CursorParagraph(index, error.offset + error.length)).paragraphToDocumentLine(this.session);
|
|
15132
|
+
const range = new Range(new CursorParagraph(index, error.offset), new CursorParagraph(index, error.offset + error.length)).paragraphToDocumentLine(this.session.displayData.paragraphs);
|
|
15030
15133
|
if (config.visibleRange &&
|
|
15031
15134
|
(range.end.row < config.visibleRange.startScreenLine || range.start.row > config.visibleRange.endScreenLine)) {
|
|
15032
15135
|
continue;
|
|
@@ -15156,7 +15259,7 @@ class SearchHighlightLayer extends HighlightLayer {
|
|
|
15156
15259
|
this.getVisibleCustomElementResults(config);
|
|
15157
15260
|
if (this.active) {
|
|
15158
15261
|
if (this.active instanceof Range) {
|
|
15159
|
-
const screenRange = this.active.paragraphToDocumentLine(this.session);
|
|
15262
|
+
const screenRange = this.active.paragraphToDocumentLine(this.session.displayData.paragraphs);
|
|
15160
15263
|
if (!screenRange.isEmpty &&
|
|
15161
15264
|
(!config.visibleRange ||
|
|
15162
15265
|
(screenRange.start.row >= config.visibleRange.startScreenLine &&
|
|
@@ -15171,13 +15274,13 @@ class SearchHighlightLayer extends HighlightLayer {
|
|
|
15171
15274
|
}
|
|
15172
15275
|
else {
|
|
15173
15276
|
this.updateActiveResult();
|
|
15174
|
-
const screenParentRange = this.active.parentRange.paragraphToDocumentLine(this.session);
|
|
15277
|
+
const screenParentRange = this.active.parentRange.paragraphToDocumentLine(this.session.displayData.paragraphs);
|
|
15175
15278
|
this.drawCustomElementHighlight(this.active, this.selectedClassName, screenParentRange);
|
|
15176
15279
|
}
|
|
15177
15280
|
}
|
|
15178
15281
|
if (this.markers?.length) {
|
|
15179
15282
|
const ranges = this.markers
|
|
15180
|
-
.map(x => x.paragraphToDocumentLine(this.session))
|
|
15283
|
+
.map(x => x.paragraphToDocumentLine(this.session.displayData.paragraphs))
|
|
15181
15284
|
.filter(x => !x.isEmpty &&
|
|
15182
15285
|
(!config.visibleRange ||
|
|
15183
15286
|
(x.start.row >= config.visibleRange.startScreenLine && x.end.row <= config.visibleRange.endScreenLine)) &&
|
|
@@ -15202,7 +15305,7 @@ class SearchHighlightLayer extends HighlightLayer {
|
|
|
15202
15305
|
this.active.location.isEqual(element.location))) {
|
|
15203
15306
|
continue;
|
|
15204
15307
|
}
|
|
15205
|
-
const screenParentRange = element.parentRange.paragraphToDocumentLine(this.session);
|
|
15308
|
+
const screenParentRange = element.parentRange.paragraphToDocumentLine(this.session.displayData.paragraphs);
|
|
15206
15309
|
if (!config.visibleRange ||
|
|
15207
15310
|
(screenParentRange.start.row >= config.visibleRange.startScreenLine &&
|
|
15208
15311
|
screenParentRange.end.row <= config.visibleRange.endScreenLine)) {
|
|
@@ -15240,7 +15343,7 @@ class SearchHighlightLayer extends HighlightLayer {
|
|
|
15240
15343
|
return;
|
|
15241
15344
|
}
|
|
15242
15345
|
for (const group of groupedByParentRange) {
|
|
15243
|
-
const screenParentRange = group.range.paragraphToDocumentLine(this.session);
|
|
15346
|
+
const screenParentRange = group.range.paragraphToDocumentLine(this.session.displayData.paragraphs);
|
|
15244
15347
|
if (config.visibleRange &&
|
|
15245
15348
|
(screenParentRange.start.row < config.visibleRange.startScreenLine ||
|
|
15246
15349
|
screenParentRange.end.row > config.visibleRange.endScreenLine)) {
|
|
@@ -15284,7 +15387,7 @@ class SelectionLayer extends HighlightLayer {
|
|
|
15284
15387
|
if (this.marker) {
|
|
15285
15388
|
let range = this.marker.clipRows(config.contentRange.start, config.contentRange.end);
|
|
15286
15389
|
if (!range.isEmpty) {
|
|
15287
|
-
range = range.paragraphToDocumentLine(this.session);
|
|
15390
|
+
range = range.paragraphToDocumentLine(this.session.displayData.paragraphs);
|
|
15288
15391
|
if (range.isSingleLine) {
|
|
15289
15392
|
this.drawSingleLineMarker(range, this.className);
|
|
15290
15393
|
}
|
|
@@ -15515,7 +15618,8 @@ class Renderer extends EventEmitting {
|
|
|
15515
15618
|
const { left, top } = rect ?? this.container.getBoundingClientRect();
|
|
15516
15619
|
const pageX = x - left;
|
|
15517
15620
|
const pageY = y + this.session.scrollTop - top;
|
|
15518
|
-
const { paragraph,
|
|
15621
|
+
const { paragraph, paragraphLine } = PositionHelper.pixelToParagraphLine(this.session.displayData.paragraphs, pageY);
|
|
15622
|
+
const indexInParagraph = PositionHelper.pixelToIndexInParagraph(this.session, pageX, paragraph, paragraphLine, tokenDivider);
|
|
15519
15623
|
return new CursorParagraph(paragraph, indexInParagraph);
|
|
15520
15624
|
}
|
|
15521
15625
|
showCursor() {
|