@talrace/ngx-noder 19.0.36 → 19.0.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/fesm2022/talrace-ngx-noder.mjs +705 -1278
  2. package/fesm2022/talrace-ngx-noder.mjs.map +1 -1
  3. package/lib/editor/components/external-element/external.component.d.ts +2 -0
  4. package/lib/editor/components/shared/services/custom-content.service.d.ts +1 -8
  5. package/lib/editor/content/constants/display-values.const.d.ts +6 -2
  6. package/lib/editor/content/display-data/display-data.d.ts +10 -29
  7. package/lib/editor/content/display-data/display-token.model.d.ts +8 -17
  8. package/lib/editor/content/display-data/general-properties.model.d.ts +3 -2
  9. package/lib/editor/content/display-data/indent.model.d.ts +2 -1
  10. package/lib/editor/content/display-data/line-info.model.d.ts +3 -3
  11. package/lib/editor/content/display-data/paragraph-info.interface.d.ts +1 -1
  12. package/lib/editor/content/display-data/text-line-info.d.ts +1 -14
  13. package/lib/editor/content/helpers/display-token.helper.d.ts +9 -3
  14. package/lib/editor/content/helpers/line-info.helper.d.ts +10 -0
  15. package/lib/editor/display/layers/text.layer.d.ts +2 -4
  16. package/lib/editor/display/rendering.helper.d.ts +4 -13
  17. package/lib/editor/gadgets/font-metrics/font-metric-size.interface.d.ts +0 -4
  18. package/lib/editor/gadgets/numbering/numbering.helper.d.ts +16 -7
  19. package/lib/editor/gadgets/page-break/break.helper.d.ts +1 -2
  20. package/lib/editor/positioning/cursor-position.interface.d.ts +3 -7
  21. package/lib/editor/positioning/position.helper.d.ts +0 -3
  22. package/package.json +1 -1
  23. package/lib/editor/components/tab/tab.helper.d.ts +0 -4
  24. package/lib/editor/content/display-data/format-ext.model.d.ts +0 -5
  25. package/lib/editor/display/print/print.rendering.helper.d.ts +0 -6
  26. package/lib/editor/positioning/line-width.helper.d.ts +0 -5
@@ -530,11 +530,7 @@ class FontMetrics {
530
530
  return {
531
531
  width: textMetrics.width,
532
532
  height: textMetrics.fontBoundingBoxAscent + textMetrics.fontBoundingBoxDescent,
533
- baseline: fontBaseLine.baseline,
534
- content: fontBaseLine.content,
535
533
  font: fontBaseLine.font,
536
- line: fontBaseLine.line,
537
- multiplier: fontBaseLine.multiplier,
538
534
  ascent: textMetrics.fontBoundingBoxAscent,
539
535
  descent: textMetrics.fontBoundingBoxDescent
540
536
  };
@@ -1347,6 +1343,10 @@ class ExternalComponent extends BaseNoderComponent {
1347
1343
  constructor() {
1348
1344
  super(...arguments);
1349
1345
  this.focusSidenav = true;
1346
+ this.isText = false;
1347
+ }
1348
+ getText() {
1349
+ return '';
1350
1350
  }
1351
1351
  skipSidenav() {
1352
1352
  return this.editorService.isViewOnly;
@@ -1703,11 +1703,11 @@ const CUSTOM_ELEMENT_MARKER = '*';
1703
1703
  const TABLE_MARKER = '#';
1704
1704
 
1705
1705
  class BreakHelper {
1706
- static getBreakType(model, char, insertIndex) {
1706
+ static getBreakType(breaks, char, insertIndex) {
1707
1707
  if (char !== CUSTOM_ELEMENT_MARKER) {
1708
1708
  return null;
1709
1709
  }
1710
- return model.breaks.find(x => x.insertIndex === insertIndex)?.breakType ?? null;
1710
+ return breaks.find(x => x.insertIndex === insertIndex)?.breakType ?? null;
1711
1711
  }
1712
1712
  static removeBreakMarker(breaks, text, fragmentStartIndex) {
1713
1713
  const index = text.at(-1) === NEW_LINE_MARKUP ? -2 : -1;
@@ -5950,24 +5950,191 @@ class PageHelper {
5950
5950
  }
5951
5951
  }
5952
5952
 
5953
- const DisplayValue = {
5954
- char: 1,
5955
- customContent: 3,
5956
- punctuation: 9,
5957
- space: 10,
5958
- trailingSpace: 11,
5959
- emptyLine: 13
5960
- };
5953
+ class NumberingDataModel {
5954
+ constructor(fields) {
5955
+ if (!fields) {
5956
+ return;
5957
+ }
5958
+ Object.assign(this, fields);
5959
+ }
5960
+ }
5961
+
5962
+ class NumberingParagraphStyleModel extends ParagraphStyleModel {
5963
+ constructor(fields) {
5964
+ super();
5965
+ this.numberingType = null;
5966
+ this.numberingLevelsStyles = null;
5967
+ if (!fields) {
5968
+ return;
5969
+ }
5970
+ Object.assign(this, fields);
5971
+ }
5972
+ }
5961
5973
 
5962
- class LineWidthHelper {
5963
- static getParagraphLineDisplayTokens(session, paragraphIndex, lineIndex) {
5964
- const docPos = session.displayData.positionToIndex(new CursorParagraph(paragraphIndex, 0), 0);
5965
- const rowWrap = session.displayData.paragraphs[paragraphIndex]?.nextLineIndexes || [];
5966
- const startWrapIndex = lineIndex > 0 ? rowWrap[lineIndex - 1] : 0;
5967
- const endIndex = rowWrap[lineIndex];
5968
- const docLine = session.displayData.getParagraphContent(paragraphIndex);
5969
- const offset = startWrapIndex ? docPos + startWrapIndex : docPos;
5970
- return session.displayData.getLineTokens(session.model, docLine.substring(startWrapIndex, endIndex || undefined), offset);
5974
+ class NumberingHelper {
5975
+ static addValueToNumberingInfo(numberingId, numberingInfo, numberingLevels) {
5976
+ if (numberingInfo[numberingId]) {
5977
+ return;
5978
+ }
5979
+ numberingInfo[numberingId] = [];
5980
+ for (let numberingLevel of numberingLevels) {
5981
+ numberingInfo[numberingId][numberingLevel.level] = {
5982
+ markerIndex: numberingLevel.startValue,
5983
+ start: numberingLevel.startValue,
5984
+ needToRecalculate: true,
5985
+ needToCalculateFirstMarker: false
5986
+ };
5987
+ }
5988
+ }
5989
+ static setNumberingNeedToRecalculate(numberingInfo, numberingId) {
5990
+ numberingInfo[numberingId].forEach(x => {
5991
+ x.needToRecalculate = true;
5992
+ x.markerIndex = x.start;
5993
+ x.needToCalculateFirstMarker = false;
5994
+ });
5995
+ }
5996
+ static setAllNumberingIsCalculated(numberingInfo) {
5997
+ for (let numberingId in numberingInfo) {
5998
+ numberingInfo[numberingId].forEach(x => {
5999
+ x.needToRecalculate = false;
6000
+ x.needToCalculateFirstMarker = false;
6001
+ });
6002
+ }
6003
+ }
6004
+ static getStyles(paragraphStyle, numberings) {
6005
+ const numberingLevels = numberings.find(x => x.numberingId === paragraphStyle.numberingId).levels;
6006
+ const numberingLevelsStyles = numberingLevels.reduce((prev, next) => `${prev}${next.marker}${next.markerType}`, '');
6007
+ const level = numberingLevels.find(x => x.level === paragraphStyle.numberingLevel);
6008
+ return new NumberingParagraphStyleModel({ ...paragraphStyle, numberingType: level.markerType, numberingLevelsStyles });
6009
+ }
6010
+ static findNumberingLevel(numberings, id, level) {
6011
+ const numbering = numberings.find(x => x.numberingId === id);
6012
+ return numbering?.levels.find(x => x.level === level);
6013
+ }
6014
+ static findNumberingLevels(numberings, id) {
6015
+ const numbering = numberings.find(x => x.numberingId === id);
6016
+ return numbering?.levels;
6017
+ }
6018
+ static calculateNumberingInfo(numberingId, level, numberingInfo, numberings) {
6019
+ const numberingModel = this.findNumberingLevel(numberings, numberingId, level);
6020
+ if (numberingModel?.markerType === NumberingMarkerType.Bullet) {
6021
+ return;
6022
+ }
6023
+ this.calculateMarkerIndexes(numberingId, level, numberingInfo);
6024
+ }
6025
+ static calculateMarkerIndexes(numberingId, level, numberingInfo) {
6026
+ if (numberingInfo[numberingId][level].needToRecalculate) {
6027
+ if (numberingInfo[numberingId][level].needToCalculateFirstMarker) {
6028
+ numberingInfo[numberingId][level].markerIndex++;
6029
+ }
6030
+ else {
6031
+ numberingInfo[numberingId][level].needToCalculateFirstMarker = true;
6032
+ }
6033
+ for (let i = level + 1; i < numberingInfo[numberingId].length; i++) {
6034
+ numberingInfo[numberingId][i].markerIndex = numberingInfo[numberingId][i].start;
6035
+ numberingInfo[numberingId][i].needToCalculateFirstMarker = false;
6036
+ }
6037
+ for (let i = 0; i < level; i++) {
6038
+ if (numberingInfo[numberingId][i].markerIndex === numberingInfo[numberingId][i].start) {
6039
+ numberingInfo[numberingId][i].needToCalculateFirstMarker = true;
6040
+ }
6041
+ }
6042
+ }
6043
+ }
6044
+ static getMarker(levelModels, level, numberingId, numberingInfo) {
6045
+ let levelMarker = levelModels[level].marker;
6046
+ let index = levelMarker.indexOf('%');
6047
+ if (index === -1) {
6048
+ return levelMarker;
6049
+ }
6050
+ const splittedMarker = levelMarker.split('.');
6051
+ return this.createMarkerString(numberingInfo, numberingId, splittedMarker);
6052
+ }
6053
+ static createDataModel(numberings, paragraphs, paragraphIndex, numberingInfo) {
6054
+ const paragraph = paragraphs[paragraphIndex];
6055
+ const numberingId = paragraph?.paragraphStyle.numberingId;
6056
+ if (!numberingId) {
6057
+ return new NumberingDataModel({ numberingId: null });
6058
+ }
6059
+ const level = paragraph.paragraphStyle.numberingLevel;
6060
+ const numberingLevelModel = this.findNumberingLevels(numberings, numberingId);
6061
+ const marker = this.getMarker(numberingLevelModel, level, numberingId, numberingInfo);
6062
+ return new NumberingDataModel({ numberingId, level, marker });
6063
+ }
6064
+ static updateMarkerData(numberings, paragraph, paragraphTextStyle, paragraphStyle) {
6065
+ const numberingLevel = NumberingHelper.findNumberingLevel(numberings, paragraph.numberingData.numberingId, paragraph.numberingData.level);
6066
+ const markerTextStyle = ContentStyleHelper.combineTextStyles(numberingLevel.markerStyle, paragraphTextStyle);
6067
+ const markerSizes = NumberingHelper.getMarkerSizes(paragraph.numberingData.marker, markerTextStyle);
6068
+ paragraph.numberingData.markerTextStyle = markerTextStyle;
6069
+ paragraph.numberingData.width = markerSizes.width;
6070
+ paragraph.numberingData.height = markerSizes.height;
6071
+ const indentLeft = paragraphStyle.indentLeft !== null ? paragraphStyle.indentLeft : numberingLevel.indentLeft;
6072
+ let indent = 0;
6073
+ if (paragraphStyle.indentHanging === null && paragraphStyle.indentFirstLine === null) {
6074
+ indent = -numberingLevel.indentHanging;
6075
+ }
6076
+ else {
6077
+ indent = paragraphStyle.indentHanging !== null ? -paragraphStyle.indentHanging : paragraphStyle.indentFirstLine;
6078
+ }
6079
+ paragraph.numberingData.paddingLeft = indentLeft + indent;
6080
+ }
6081
+ static getMarkerSizes(marker, markerStyle) {
6082
+ let width = 0;
6083
+ let height = 0;
6084
+ const markerStylesString = ContentStyleHelper.getFontStylesString(markerStyle);
6085
+ for (let char of marker) {
6086
+ const markerCharSizes = FontMetrics.measureCharSize(char, markerStylesString);
6087
+ width += markerCharSizes.width;
6088
+ if (height < markerCharSizes.height) {
6089
+ height = markerCharSizes.height;
6090
+ }
6091
+ }
6092
+ return { height, width };
6093
+ }
6094
+ static updateNumberingInfo(numberingInfo, marker, numberingId, level) {
6095
+ const markerLevels = this.getLevelInfo(marker);
6096
+ const lastMarkerLevel = markerLevels.length - 1;
6097
+ numberingInfo[numberingId][level].markerIndex = markerLevels[lastMarkerLevel];
6098
+ numberingInfo[numberingId][level].needToRecalculate = true;
6099
+ }
6100
+ static getLevelInfo(input) {
6101
+ return input
6102
+ .split('.')
6103
+ .filter(x => !!x)
6104
+ .map(x => parseInt(x));
6105
+ }
6106
+ static createMarkerString(numberingInfo, numberingId, splittedMarker) {
6107
+ const markers = splittedMarker.map(x => {
6108
+ if (x === '') {
6109
+ return '';
6110
+ }
6111
+ if (x.indexOf('%') === -1) {
6112
+ return x;
6113
+ }
6114
+ const markerLevel = parseInt(x.slice(1));
6115
+ const markerIndex = numberingInfo[numberingId][markerLevel - 1]?.markerIndex;
6116
+ return `${markerIndex}`;
6117
+ });
6118
+ return markers.join('.');
6119
+ }
6120
+ static getMarkerOffset(paragraphSettings) {
6121
+ const numberingData = paragraphSettings.numberingData;
6122
+ const info = paragraphSettings.textLinesInfo[0];
6123
+ if (numberingData.numberingId === null) {
6124
+ return { offset: 0, markerWidth: 0 };
6125
+ }
6126
+ const offset = numberingData.width + numberingData.paddingLeft;
6127
+ let markerWidth = info.indentFirstLine !== null || (offset - info.indentLeft > 0 && offset - info.indentLeft < info.indent.markerWidth)
6128
+ ? info.indent.markerWidth
6129
+ : 0;
6130
+ return { offset, markerWidth };
6131
+ }
6132
+ static getOffsetCausedByMarker(numberingData, info) {
6133
+ if (!info.isNumbering) {
6134
+ return 0;
6135
+ }
6136
+ const offset = numberingData.width + numberingData.paddingLeft - info.indentLeft;
6137
+ return info.indentFirstLine !== null || (offset > 0 && offset <= info.indent.markerWidth) ? info.indent.markerWidth : 0;
5971
6138
  }
5972
6139
  }
5973
6140
 
@@ -5995,8 +6162,8 @@ class PositionHelper {
5995
6162
  paragraphIndex,
5996
6163
  lineIndex,
5997
6164
  lineTopOffset,
5998
- indentBefore: paragraphLineInfo.offsetBefore,
5999
- lineHeight: paragraphLineInfo.height
6165
+ lineHeight: paragraphLineInfo.height,
6166
+ lineAscent: paragraphLineInfo.ascent
6000
6167
  };
6001
6168
  }
6002
6169
  static documentToScreen(session, paragraph, indexInParagraph) {
@@ -6034,34 +6201,14 @@ class PositionHelper {
6034
6201
  static screenToPixel(session, row, column) {
6035
6202
  const paragraphs = session.displayData.paragraphs;
6036
6203
  const paragraphInfo = this.getParagraphInfoByRow(paragraphs, row);
6037
- const tokens = LineWidthHelper.getParagraphLineDisplayTokens(session, paragraphInfo.paragraphIndex, paragraphInfo.lineIndex);
6038
- let size = {
6039
- width: 8,
6040
- height: paragraphInfo.lineHeight,
6041
- baseline: paragraphInfo.lineHeight,
6042
- content: paragraphInfo.lineHeight,
6043
- font: paragraphInfo.lineHeight,
6044
- line: paragraphInfo.lineHeight,
6045
- multiplier: paragraphInfo.lineHeight,
6046
- ascent: 0,
6047
- descent: 0
6048
- };
6204
+ const tokens = session.displayData.getParagraphLineTokens(paragraphInfo.paragraphIndex, paragraphInfo.lineIndex);
6049
6205
  let tokenIndex = column > 0 ? column - 1 : column;
6050
- if (tokens.length > 0) {
6051
- size = tokens[tokenIndex];
6052
- }
6053
- const sizeNext = tokens[tokenIndex + 1];
6054
- let sizeMax = { ...size };
6206
+ let sizeMax = { ...tokens[tokenIndex] };
6055
6207
  let lineWidthToPosition = session.displayData.pagesFormat[0].pageFormatModel.marginLeft; // this value is the same for all page formats.
6056
- const { paragraphIndex, lineIndex } = this.findLineInParagraphs(paragraphs, row);
6057
- const lineInfo = paragraphs[paragraphIndex].paragraphSettings.textLinesInfo[lineIndex];
6058
6208
  for (let currentColumn = 0; currentColumn < tokens.length; currentColumn++) {
6059
6209
  const currentToken = tokens[currentColumn];
6060
6210
  if (currentColumn < column) {
6061
6211
  lineWidthToPosition += currentToken.width;
6062
- if (currentToken.displayValue === DisplayValue.space && lineInfo.wordSpacing) {
6063
- lineWidthToPosition += lineInfo.wordSpacing;
6064
- }
6065
6212
  }
6066
6213
  if (sizeMax.ascent < currentToken.ascent) {
6067
6214
  sizeMax = currentToken;
@@ -6072,18 +6219,14 @@ class PositionHelper {
6072
6219
  }
6073
6220
  const paragraph = paragraphs[paragraphInfo.paragraphIndex];
6074
6221
  const paragraphTop = paragraph.paragraphSettings.distanceFromTop || 0;
6075
- const linePaddingLeft = paragraph.paragraphSettings.textLinesInfo[paragraphInfo.lineIndex].paddingLeft;
6076
- const offsetMargin = paragraph.paragraphSettings.textLinesInfo[paragraphInfo.lineIndex].offsetMargin;
6077
- const markerWidth = this.getMarkerWidth(paragraph.paragraphSettings, paragraph.paragraphSettings.textLinesInfo[0], paragraphInfo.lineIndex);
6222
+ const info = paragraph.paragraphSettings.textLinesInfo[paragraphInfo.lineIndex];
6223
+ const markerOffset = NumberingHelper.getOffsetCausedByMarker(paragraph.paragraphSettings.numberingData, info); // todo: verify (case - 1) numbering paragraph with multi-lines; 2) marker is moved far left so it not affect line offset)
6078
6224
  return {
6079
- pageX: lineWidthToPosition + linePaddingLeft + offsetMargin + markerWidth,
6225
+ pageX: lineWidthToPosition + info.paddingLeft + info.offsetMargin + markerOffset,
6080
6226
  pageY: paragraphTop + paragraphInfo.lineTopOffset - session.scrollTop,
6081
- lineHeight: paragraphInfo.lineHeight,
6082
- sizeCurrent: size,
6083
- sizeMax,
6084
- sizeNext,
6085
- firstChar: column === 0,
6086
- lastChar: column === tokens.length - 1
6227
+ width: tokens[tokenIndex].width,
6228
+ height: paragraphInfo.lineHeight,
6229
+ ascent: paragraphInfo.lineAscent
6087
6230
  };
6088
6231
  }
6089
6232
  /**
@@ -6119,24 +6262,17 @@ class PositionHelper {
6119
6262
  static mapPixelToClosestTokenMidpoint(session, xPixel, paragraphIndex, lineIndex, leftOffset) {
6120
6263
  const paragraphSettings = session.displayData.paragraphs[paragraphIndex].paragraphSettings;
6121
6264
  const marginLeft = session.displayData.pagesFormat[0].pageFormatModel.marginLeft; // this value is the same for all page formats.
6122
- const tokens = LineWidthHelper.getParagraphLineDisplayTokens(session, paragraphIndex, lineIndex);
6265
+ const tokens = session.displayData.getParagraphLineTokens(paragraphIndex, lineIndex);
6123
6266
  const lineInfo = paragraphSettings.textLinesInfo[lineIndex];
6124
6267
  const line = lineInfo.screenLine;
6125
- if (tokens[0].displayValue === DisplayValue.emptyLine) {
6268
+ if (tokens[0].isParagraph) {
6126
6269
  return { line, indexInLine: 0 };
6127
6270
  }
6128
6271
  let indexInLine = 0;
6129
- const markerWidth = this.getMarkerWidth(paragraphSettings, lineInfo, lineIndex);
6130
- let relativeX = xPixel - leftOffset - marginLeft - lineInfo.paddingLeft - lineInfo.offsetMargin - markerWidth;
6131
- const wordSpacing = lineInfo.wordSpacing ?? 0;
6132
- while (indexInLine < tokens.length) {
6133
- const token = tokens[indexInLine];
6134
- const isSpace = token.displayValue === DisplayValue.space;
6135
- const width = token.width + (isSpace ? wordSpacing : 0);
6136
- if (relativeX < width / 2) {
6137
- break;
6138
- }
6139
- relativeX -= width;
6272
+ const markerOffset = NumberingHelper.getOffsetCausedByMarker(paragraphSettings.numberingData, lineInfo);
6273
+ let relativeX = xPixel - leftOffset - marginLeft - lineInfo.paddingLeft - lineInfo.offsetMargin - markerOffset;
6274
+ while (indexInLine < tokens.length && relativeX >= tokens[indexInLine].width / 2) {
6275
+ relativeX -= tokens[indexInLine].width;
6140
6276
  indexInLine++;
6141
6277
  }
6142
6278
  return { line, indexInLine };
@@ -6147,24 +6283,17 @@ class PositionHelper {
6147
6283
  static mapPixelToNextTokenBoundary(session, xPixel, paragraphIndex, lineIndex, leftOffset) {
6148
6284
  const paragraphSettings = session.displayData.paragraphs[paragraphIndex].paragraphSettings;
6149
6285
  const marginLeft = session.displayData.pagesFormat[0].pageFormatModel.marginLeft; // this value is the same for all page formats.
6150
- const tokens = LineWidthHelper.getParagraphLineDisplayTokens(session, paragraphIndex, lineIndex);
6286
+ const tokens = session.displayData.getParagraphLineTokens(paragraphIndex, lineIndex);
6151
6287
  const lineInfo = paragraphSettings.textLinesInfo[lineIndex];
6152
6288
  const line = lineInfo.screenLine;
6153
- if (tokens[0].displayValue === DisplayValue.emptyLine) {
6289
+ if (tokens[0].isParagraph) {
6154
6290
  return { line, indexInLine: 0 };
6155
6291
  }
6156
6292
  let indexInLine = 0;
6157
- const markerWidth = this.getMarkerWidth(paragraphSettings, lineInfo, lineIndex);
6158
- let relativeX = xPixel - leftOffset - marginLeft - lineInfo.paddingLeft - lineInfo.offsetMargin - markerWidth;
6159
- const wordSpacing = lineInfo.wordSpacing ?? 0;
6160
- while (indexInLine < tokens.length) {
6161
- const token = tokens[indexInLine];
6162
- const isSpace = token.displayValue === DisplayValue.space;
6163
- const width = token.width + (isSpace ? wordSpacing : 0);
6164
- if (relativeX < width) {
6165
- break;
6166
- }
6167
- relativeX -= width;
6293
+ const markerOffset = NumberingHelper.getOffsetCausedByMarker(paragraphSettings.numberingData, lineInfo);
6294
+ let relativeX = xPixel - leftOffset - marginLeft - lineInfo.paddingLeft - lineInfo.offsetMargin - markerOffset;
6295
+ while (indexInLine < tokens.length && relativeX >= tokens[indexInLine].width) {
6296
+ relativeX -= tokens[indexInLine].width;
6168
6297
  indexInLine++;
6169
6298
  }
6170
6299
  return { line, indexInLine };
@@ -6186,38 +6315,19 @@ class PositionHelper {
6186
6315
  const paragraphs = session.displayData.paragraphs;
6187
6316
  const marginLeft = session.displayData.pagesFormat[0].pageFormatModel.marginLeft; // this value is the same for all page formats.
6188
6317
  const { paragraphIndex, lineIndex } = PositionHelper.findLineInParagraphs(paragraphs, documentLine);
6189
- let column = 0;
6190
- const tokens = LineWidthHelper.getParagraphLineDisplayTokens(session, paragraphIndex, lineIndex);
6191
- if (tokens.length === 1 && tokens[0].displayValue === DisplayValue.emptyLine) {
6192
- return column;
6193
- }
6194
- const textLineInfo = paragraphs[paragraphIndex].paragraphSettings.textLinesInfo[lineIndex];
6195
- const wordSpacing = textLineInfo.wordSpacing ?? 0;
6196
- const markerWidth = this.getMarkerWidth(paragraphs[paragraphIndex].paragraphSettings, textLineInfo, lineIndex);
6197
- let width = positionWidth - textLineInfo.paddingLeft - marginLeft - textLineInfo.offsetMargin - markerWidth;
6198
- while (column < tokens.length) {
6199
- const token = tokens[column];
6200
- if (width < token.width) {
6201
- break;
6202
- }
6203
- const isSpace = token.displayValue === DisplayValue.space;
6204
- width -= token.width + (isSpace ? wordSpacing : 0);
6205
- column++;
6318
+ const tokens = session.displayData.getParagraphLineTokens(paragraphIndex, lineIndex);
6319
+ if (tokens[0].isParagraph) {
6320
+ return 0;
6206
6321
  }
6207
- return column;
6208
- }
6209
- static getMarkerWidth(paragraphSettings, textLineInfo, lineIndex) {
6210
- const numberingOffsetLeft = paragraphSettings.numberingData.numberingId === null
6211
- ? 0
6212
- : paragraphSettings.numberingData.width + paragraphSettings.numberingData.paddingLeft;
6213
- if (textLineInfo.isNumbering &&
6214
- lineIndex === 0 &&
6215
- (textLineInfo.indentFirstLine !== null ||
6216
- (numberingOffsetLeft - textLineInfo.indentLeft > 0 &&
6217
- numberingOffsetLeft - textLineInfo.indentLeft <= textLineInfo.markerWidth))) {
6218
- return textLineInfo.markerWidth;
6322
+ let index = 0;
6323
+ const lineInfo = paragraphs[paragraphIndex].paragraphSettings.textLinesInfo[lineIndex];
6324
+ const markerOffset = NumberingHelper.getOffsetCausedByMarker(paragraphs[paragraphIndex].paragraphSettings.numberingData, lineInfo);
6325
+ let width = positionWidth - lineInfo.paddingLeft - marginLeft - lineInfo.offsetMargin - markerOffset;
6326
+ while (index < tokens.length && width >= tokens[index].width) {
6327
+ width -= tokens[index].width;
6328
+ index++;
6219
6329
  }
6220
- return 0;
6330
+ return index;
6221
6331
  }
6222
6332
  }
6223
6333
 
@@ -6268,15 +6378,6 @@ class EdgeElementModel {
6268
6378
  }
6269
6379
  }
6270
6380
 
6271
- class FormatExtModel extends FormatModel {
6272
- constructor(fields) {
6273
- super(fields);
6274
- if (fields) {
6275
- Object.assign(this, fields);
6276
- }
6277
- }
6278
- }
6279
-
6280
6381
  class ScalingHelper {
6281
6382
  static getRatio(current, original) {
6282
6383
  return parseFloat((current / original).toFixed(1));
@@ -6290,100 +6391,55 @@ class RenderingHelper {
6290
6391
  static createLineElement(lineInfo, numberingOffsetLeft, scalingRatio) {
6291
6392
  let lineEl = document.createElement('div');
6292
6393
  lineEl.className = 'noder-line';
6293
- if (lineInfo) {
6294
- const paddingLeft = ScalingHelper.scale(lineInfo.paddingLeft, scalingRatio);
6295
- const marginLeft = numberingOffsetLeft !== null ? -numberingOffsetLeft : 0;
6296
- // eslint-disable-next-line prettier/prettier
6297
- 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};`;
6298
- if (lineInfo.wordSpacing) {
6299
- styleString += `word-spacing:${lineInfo.wordSpacing}px;`;
6300
- }
6301
- lineEl.setAttribute('style', styleString);
6302
- lineEl.setAttribute('screen-index', `${lineInfo.screenLine}`);
6303
- }
6394
+ const paddingLeft = ScalingHelper.scale(lineInfo.paddingLeft, scalingRatio);
6395
+ const marginLeft = numberingOffsetLeft !== null ? -numberingOffsetLeft : 0;
6396
+ 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};`;
6397
+ lineEl.setAttribute('style', styleString);
6398
+ lineEl.setAttribute('screen-index', `${lineInfo.screenLine}`);
6304
6399
  return lineEl;
6305
6400
  }
6306
- static renderContentSimpleLine(domContent, formatsExt, rowDistance, customContentService, customComponents, lineInfo, breaks = []) {
6307
- const valueFragment = DomHelper.createFragment(domContent.currentElement);
6308
- for (const formatExt of formatsExt) {
6309
- const fragmentDocumentStartIndex = rowDistance.start > formatExt.startIndex ? rowDistance.start : formatExt.startIndex;
6310
- const fragmentDocumentEndIndex = formatExt.endIndex > rowDistance.end ? rowDistance.end : formatExt.endIndex;
6311
- const fragmentDocumentDistance = new DistanceModel({ start: fragmentDocumentStartIndex, end: fragmentDocumentEndIndex });
6312
- const fragmentStartIndex = rowDistance.start > formatExt.startIndex ? rowDistance.start - formatExt.startIndex : 0;
6313
- const fragmentEndIndex = formatExt.endIndex > rowDistance.end ? rowDistance.end - formatExt.startIndex : formatExt.endIndex - formatExt.startIndex;
6314
- const fragmentDistance = new DistanceModel({ start: fragmentStartIndex, end: fragmentEndIndex });
6315
- this.renderFormatContent(valueFragment, formatExt, fragmentDocumentDistance, fragmentDistance, customContentService, customComponents, breaks, lineInfo, true);
6316
- }
6317
- domContent.parentNode.appendChild(valueFragment);
6318
- }
6319
- static renderContentWrappedLine(domContent, splits, currentParagraph, formatsExt, distance, customContentService, customComponents, scalingRatio, breaks = []) {
6320
- let splitIndex = 0;
6321
- const numberingOffsetLeft = currentParagraph.numberingData.numberingId === null
6322
- ? 0
6323
- : currentParagraph.numberingData.width + currentParagraph.numberingData.paddingLeft;
6324
- let markerWidth = 0;
6325
- if (currentParagraph.textLinesInfo[0].isNumbering &&
6326
- (currentParagraph.textLinesInfo[0].indentFirstLine !== null ||
6327
- (numberingOffsetLeft - currentParagraph.textLinesInfo[0].indentLeft > 0 &&
6328
- numberingOffsetLeft - currentParagraph.textLinesInfo[0].indentLeft < currentParagraph.textLinesInfo[0].markerWidth))) {
6329
- markerWidth = currentParagraph.textLinesInfo[0].markerWidth;
6330
- }
6331
- let lineEl = RenderingHelper.createLineElement(currentParagraph.textLinesInfo[splitIndex], numberingOffsetLeft - markerWidth, scalingRatio);
6332
- domContent.parentNode.appendChild(lineEl);
6333
- const valueFragment = DomHelper.createFragment(domContent.currentElement);
6334
- let isLastLineFragment = false;
6335
- let paragraphChars = 0;
6336
- let split = splits[splitIndex];
6337
- let lineInfo = currentParagraph.textLinesInfo[splitIndex];
6338
- for (const formatExt of formatsExt) {
6339
- const beforeSplitIndex = split ? split - 1 : distance.end - distance.start;
6340
- const beforeSplitDocumentIndex = distance.start + beforeSplitIndex;
6341
- const fragmentDocumentStartIndex = distance.start + paragraphChars;
6342
- const fragmentDocumentEndIndex = formatExt.endIndex < beforeSplitDocumentIndex ? formatExt.endIndex : beforeSplitDocumentIndex;
6343
- const fragmentDocumentDistance = new DistanceModel({ start: fragmentDocumentStartIndex, end: fragmentDocumentEndIndex });
6344
- const fragmentStartIndex = distance.start > formatExt.startIndex ? distance.start - formatExt.startIndex : 0;
6345
- const fragmentEndIndex = formatExt.endIndex < beforeSplitDocumentIndex
6346
- ? fragmentStartIndex + formatExt.endIndex - formatExt.startIndex
6347
- : distance.start + beforeSplitIndex - formatExt.startIndex;
6348
- const fragmentDistance = new DistanceModel({ start: fragmentStartIndex, end: fragmentEndIndex });
6349
- isLastLineFragment = split === fragmentDocumentDistance.end + 1;
6350
- paragraphChars += this.renderFormatContent(valueFragment, formatExt, fragmentDocumentDistance, fragmentDistance, customContentService, customComponents, breaks, lineInfo, isLastLineFragment);
6351
- lineEl.appendChild(valueFragment);
6352
- let nextFragmentStartIndex = fragmentEndIndex + 1;
6353
- while (paragraphChars === split && nextFragmentStartIndex !== distance.end) {
6354
- split = splits[++splitIndex];
6355
- lineInfo = currentParagraph.textLinesInfo[splitIndex];
6356
- const nextFragmentDocumentStartIndex = fragmentDocumentStartIndex + nextFragmentStartIndex - fragmentStartIndex;
6357
- lineEl = RenderingHelper.createLineElement(lineInfo, numberingOffsetLeft, scalingRatio);
6358
- if (split > formatExt.endIndex) {
6359
- const nextFragmentEndIndex = formatExt.content.length - 1;
6360
- const nextFragmentDistance = new DistanceModel({ start: nextFragmentStartIndex, end: nextFragmentEndIndex });
6361
- const nextFragmentDocumentEndIndex = nextFragmentDocumentStartIndex + nextFragmentEndIndex - nextFragmentStartIndex;
6362
- const nextFragmentDocumentDistance = new DistanceModel({
6363
- start: nextFragmentDocumentStartIndex,
6364
- end: nextFragmentDocumentEndIndex
6365
- });
6366
- isLastLineFragment = split === nextFragmentDocumentDistance.end + 1;
6367
- paragraphChars += this.renderFormatContent(valueFragment, formatExt, nextFragmentDocumentDistance, nextFragmentDistance, customContentService, customComponents, breaks, lineInfo, isLastLineFragment);
6368
- lineEl.appendChild(valueFragment);
6401
+ static renderParagraph(domContent, paragraph, formats, customContentService, customComponents, scalingRatio, breaks = []) {
6402
+ const { offset, markerWidth } = NumberingHelper.getMarkerOffset(paragraph.paragraphSettings);
6403
+ const lineInfos = paragraph.paragraphSettings.textLinesInfo;
6404
+ const start = paragraph.startIndex;
6405
+ const end = paragraph.startIndex + paragraph.content.length;
6406
+ const fragment = DomHelper.createFragment(domContent.currentElement);
6407
+ let lineIndex = 0;
6408
+ let renderedCount = 0;
6409
+ let lineEl = RenderingHelper.createLineElement(paragraph.paragraphSettings.textLinesInfo[0], offset - markerWidth, scalingRatio);
6410
+ for (const format of formats) {
6411
+ do {
6412
+ const lineEnd = paragraph.nextLineIndexes[lineIndex]
6413
+ ? paragraph.startIndex + paragraph.nextLineIndexes[lineIndex] - 1
6414
+ : end;
6415
+ let fragmentEnd = format.endIndex < lineEnd ? format.endIndex : lineEnd;
6416
+ let wordSpacing = lineInfos[lineIndex].wordSpacing;
6417
+ if (wordSpacing) {
6418
+ const lineStart = lineIndex > 0 ? paragraph.nextLineIndexes[lineIndex - 1] : 0;
6419
+ const lineStartIndex = start + lineStart;
6420
+ const wordSpacingStart = lineInfos[lineIndex].wordSpacingStart;
6421
+ const wordSpacingEnd = lineInfos[lineIndex].wordSpacingEnd;
6422
+ if (renderedCount - lineStart < wordSpacingStart && lineStartIndex + wordSpacingStart < fragmentEnd) {
6423
+ fragmentEnd = lineStartIndex + wordSpacingStart;
6424
+ }
6425
+ else if (renderedCount - lineStart < wordSpacingEnd && lineStartIndex + wordSpacingEnd < fragmentEnd) {
6426
+ fragmentEnd = lineStartIndex + wordSpacingEnd;
6427
+ }
6428
+ if (renderedCount - lineStart < wordSpacingStart || renderedCount - lineStart > wordSpacingEnd) {
6429
+ wordSpacing = null;
6430
+ }
6431
+ }
6432
+ const fragmentLength = fragmentEnd - start - renderedCount + 1;
6433
+ this.renderFormatContent(fragment, format.textStyle, start + renderedCount, fragmentEnd, paragraph.content.substring(renderedCount, renderedCount + fragmentLength), customContentService, customComponents, breaks, wordSpacing);
6434
+ lineEl.appendChild(fragment);
6435
+ renderedCount += fragmentLength;
6436
+ if (paragraph.nextLineIndexes.length > lineIndex && start + renderedCount > lineEnd) {
6437
+ lineIndex++;
6369
6438
  domContent.parentNode.appendChild(lineEl);
6370
- break;
6439
+ lineEl = RenderingHelper.createLineElement(lineInfos[lineIndex], offset, scalingRatio);
6371
6440
  }
6372
- const textIndexLength = RenderingHelper.getTextIndexLengthForInsert(formatExt, nextFragmentDocumentStartIndex, distance, split, paragraphChars);
6373
- const nextFragmentDocumentEndIndex = nextFragmentDocumentStartIndex + textIndexLength;
6374
- const nextFragmentEndIndex = nextFragmentStartIndex + textIndexLength;
6375
- const nextFragmentDistance = new DistanceModel({ start: nextFragmentStartIndex, end: nextFragmentEndIndex });
6376
- const nextFragmentDocumentDistance = new DistanceModel({
6377
- start: nextFragmentDocumentStartIndex,
6378
- end: nextFragmentDocumentEndIndex
6379
- });
6380
- isLastLineFragment = split === nextFragmentDocumentDistance.end + 1;
6381
- const renderedChars = this.renderFormatContent(valueFragment, formatExt, nextFragmentDocumentDistance, nextFragmentDistance, customContentService, customComponents, breaks, lineInfo, isLastLineFragment);
6382
- lineEl.appendChild(valueFragment);
6383
- domContent.parentNode.appendChild(lineEl);
6384
- nextFragmentStartIndex += renderedChars;
6385
- paragraphChars += renderedChars;
6386
- }
6441
+ } while (renderedCount < paragraph.content.length && format.endIndex > start + renderedCount);
6442
+ domContent.parentNode.appendChild(lineEl);
6387
6443
  }
6388
6444
  }
6389
6445
  static renderNumberingMarker(paragraph, layerElement, scalingRatio) {
@@ -6400,11 +6456,7 @@ class RenderingHelper {
6400
6456
  const numberingLineEl = this.createLineElement(markerLineInfo, 0, scalingRatio);
6401
6457
  const markerFragment = DomHelper.createFragment(layerElement);
6402
6458
  const marker = paragraph.numberingData.marker;
6403
- const markerExtModel = new FormatExtModel({
6404
- textStyle: paragraph.numberingData.markerTextStyle,
6405
- content: marker
6406
- });
6407
- this.renderText(markerFragment, markerExtModel, marker);
6459
+ this.renderText(markerFragment, paragraph.numberingData.markerTextStyle, marker, null);
6408
6460
  numberingLineEl.appendChild(markerFragment);
6409
6461
  return numberingLineEl;
6410
6462
  }
@@ -6413,60 +6465,35 @@ class RenderingHelper {
6413
6465
  containerElement.className = className;
6414
6466
  return containerElement;
6415
6467
  }
6416
- static renderFormatContent(fragment, formatExt, fragmentDocumentDistance, fragmentDistance, customContentService, customComponents, breaks, lineInfo, isLastLineFragment) {
6417
- let textFragment = formatExt.content.substring(fragmentDistance.start, fragmentDistance.end + 1);
6468
+ static renderFormatContent(fragment, textStyle, start, end, textFragment, customContentService, customComponents, breaks, wordSpacing) {
6418
6469
  if (!textFragment) {
6419
- return 0;
6420
- }
6421
- const textFragmentWithoutBreaks = BreakHelper.removeBreakMarker(breaks, textFragment, fragmentDocumentDistance.start);
6422
- if (customContentService.isFragmentContainComponent(customComponents, textFragment, fragmentDocumentDistance)) {
6423
- this.renderTextWithCustomContent(fragment, formatExt, fragmentDocumentDistance, textFragmentWithoutBreaks, customContentService, customComponents, lineInfo);
6424
- }
6425
- else if (isLastLineFragment) {
6426
- this.renderTextWithSpacingHandling(fragment, formatExt, textFragmentWithoutBreaks, lineInfo);
6427
- }
6428
- else {
6429
- const paddingLeft = textFragment.startsWith(' ') && lineInfo.wordSpacing ? lineInfo.wordSpacing : null;
6430
- this.renderText(fragment, formatExt, textFragmentWithoutBreaks, paddingLeft);
6431
- }
6432
- return textFragment.length;
6433
- }
6434
- static renderTextWithCustomContent(fragment, formatExt, fragmentDocumentDistance, textFragment, customContentService, customComponents, lineInfo) {
6435
- const components = customContentService.getComponents(customComponents, fragmentDocumentDistance);
6436
- if (!components.length) {
6437
- this.renderTextWithSpacingHandling(fragment, formatExt, textFragment, lineInfo);
6438
6470
  return;
6439
6471
  }
6440
- let newTextFragmentStartIndex = fragmentDocumentDistance.start;
6441
- let nextTextFragment = textFragment;
6442
- for (const component of components) {
6443
- const textBeforeElement = nextTextFragment.substring(0, component.instance.insertIndex - newTextFragmentStartIndex);
6444
- nextTextFragment = nextTextFragment.substring(textBeforeElement.length + 1, nextTextFragment.length);
6445
- newTextFragmentStartIndex = newTextFragmentStartIndex + (textBeforeElement.length ? textBeforeElement.length + 1 : 1);
6446
- if (textBeforeElement.length) {
6447
- const paddingLeft = textBeforeElement.startsWith(' ') && lineInfo.wordSpacing ? lineInfo.wordSpacing : null;
6448
- this.renderText(fragment, formatExt, textBeforeElement, paddingLeft);
6472
+ const textFragmentWithoutBreaks = BreakHelper.removeBreakMarker(breaks, textFragment, start);
6473
+ const components = customContentService.getComponents(customComponents, start, end);
6474
+ if (components.length) {
6475
+ let newTextFragmentStartIndex = start;
6476
+ let nextTextFragment = textFragmentWithoutBreaks;
6477
+ for (const component of components) {
6478
+ const textBeforeElement = nextTextFragment.substring(0, component.instance.insertIndex - newTextFragmentStartIndex);
6479
+ nextTextFragment = nextTextFragment.substring(textBeforeElement.length + 1, nextTextFragment.length);
6480
+ newTextFragmentStartIndex = newTextFragmentStartIndex + (textBeforeElement.length ? textBeforeElement.length + 1 : 1);
6481
+ if (textBeforeElement.length) {
6482
+ this.renderText(fragment, textStyle, textBeforeElement, wordSpacing);
6483
+ }
6484
+ customContentService.componentService.attachComponent(fragment, component);
6485
+ }
6486
+ if (nextTextFragment.length) {
6487
+ this.renderText(fragment, textStyle, nextTextFragment, wordSpacing);
6449
6488
  }
6450
- this.attachComponent(fragment, component, customContentService);
6451
- }
6452
- if (nextTextFragment.length) {
6453
- this.renderTextWithSpacingHandling(fragment, formatExt, nextTextFragment, lineInfo);
6454
- }
6455
- }
6456
- static renderTextWithSpacingHandling(fragment, formatExt, textFragment, lineInfo) {
6457
- const paddingLeft = textFragment.startsWith(' ') && lineInfo.wordSpacing ? lineInfo.wordSpacing : null;
6458
- if (lineInfo.wordSpacing && textFragment.endsWith(' ')) {
6459
- this.renderText(fragment, formatExt, textFragment.slice(0, -1), paddingLeft);
6460
- this.renderText(fragment, formatExt, ' ');
6461
6489
  }
6462
6490
  else {
6463
- this.renderText(fragment, formatExt, textFragment, paddingLeft);
6491
+ this.renderText(fragment, textStyle, textFragmentWithoutBreaks, wordSpacing);
6464
6492
  }
6465
6493
  }
6466
- static renderText(fragment, formatExt, textFragment, paddingLeft = null) {
6494
+ static renderText(fragment, textStyle, content, wordSpacing) {
6467
6495
  const span = document.createElement('span');
6468
- const textStyle = new TextStyleModel({ ...formatExt.textStyle });
6469
- if (textFragment === NEW_LINE_MARKUP) {
6496
+ if (content === NEW_LINE_MARKUP) {
6470
6497
  span.className = 'paragraph-symbol';
6471
6498
  }
6472
6499
  if (textStyle.headingStyleId === HYPERLINK_HEADING_STYLE_ID) {
@@ -6481,21 +6508,14 @@ class RenderingHelper {
6481
6508
  };
6482
6509
  span.onmouseleave = () => span.classList.remove('hyperlink-hover');
6483
6510
  }
6484
- span.textContent = textFragment;
6511
+ span.textContent = content;
6485
6512
  let styleString = ContentStyleHelper.getTextStylesString(textStyle);
6486
- if (paddingLeft) {
6487
- styleString += `padding-left:${paddingLeft}px;`;
6513
+ if (wordSpacing) {
6514
+ styleString += `word-spacing:${wordSpacing}px;`;
6488
6515
  }
6489
6516
  span.setAttribute('style', styleString);
6490
6517
  fragment.appendChild(span);
6491
6518
  }
6492
- static getTextIndexLengthForInsert(formatExt, fragmentDocumentStartIndex, paragraphDistance, split, paragraphChars) {
6493
- const maxLength = Math.max(paragraphDistance.end - paragraphChars - paragraphDistance.start, 0);
6494
- return (Math.min(split - paragraphChars || Number.MAX_VALUE, maxLength, formatExt.endIndex - fragmentDocumentStartIndex + 1, formatExt.content.length) - 1);
6495
- }
6496
- static attachComponent(fragment, component, customContentService) {
6497
- customContentService.componentService.attachComponent(fragment, component);
6498
- }
6499
6519
  }
6500
6520
 
6501
6521
  class EdgesLayer {
@@ -6810,12 +6830,6 @@ class PrintPagesLayer extends PagesLayer {
6810
6830
  }
6811
6831
  }
6812
6832
 
6813
- class PrintRenderingHelper extends RenderingHelper {
6814
- static attachComponent(fragment, component, customContentService) {
6815
- customContentService.componentService.cloneAndAttachComponent(fragment, component);
6816
- }
6817
- }
6818
-
6819
6833
  class Lines {
6820
6834
  get length() {
6821
6835
  return this.cells.length;
@@ -7091,10 +7105,9 @@ class ParagraphHelper {
7091
7105
  }
7092
7106
 
7093
7107
  class TextLayer {
7094
- constructor(parentElement, session, renderingHelper = RenderingHelper) {
7108
+ constructor(parentElement, session) {
7095
7109
  this.parentElement = parentElement;
7096
7110
  this.session = session;
7097
- this.renderingHelper = renderingHelper;
7098
7111
  this.pagesCountChangedHandler = (event) => {
7099
7112
  this.lines.setSizes(event.pagesCount, event.pageHeight);
7100
7113
  };
@@ -7169,46 +7182,22 @@ class TextLayer {
7169
7182
  DomHelper.setStyle(paragraphCell.element.style, 'margin-right', `${offsetForLittlePages}px`);
7170
7183
  const paragraphSettings = this.session.displayData.getParagraphSettings(row);
7171
7184
  if (paragraphSettings.numberingData.numberingId !== null) {
7172
- const numberingElement = this.renderingHelper.renderNumberingMarker(paragraphSettings, this.element, this.session.generalProperties.scalingRatio);
7185
+ const numberingElement = RenderingHelper.renderNumberingMarker(paragraphSettings, this.element, this.session.generalProperties.scalingRatio);
7173
7186
  numberingElement.className = 'numberingMarker';
7174
7187
  paragraphCell.element.appendChild(numberingElement);
7175
7188
  }
7176
- this.renderTextLines(paragraphCell.element, row);
7189
+ this.renderParagraph(paragraphCell.element, this.session.displayData.paragraphs[row]);
7177
7190
  fragment.push(paragraphCell);
7178
7191
  }
7179
7192
  return fragment;
7180
7193
  }
7181
- renderTextLines(parent, row) {
7182
- const linesContainerElement = this.renderingHelper.createDivContainer('lines-container');
7183
- const paragraphSettings = this.session.displayData.getParagraphSettings(row);
7184
- const paragraphHeight = ParagraphHelper.getParagraphHeight(paragraphSettings.textLinesInfo);
7194
+ renderParagraph(parent, paragraph) {
7195
+ const linesContainerElement = RenderingHelper.createDivContainer('lines-container');
7196
+ const paragraphHeight = ParagraphHelper.getParagraphHeight(paragraph.paragraphSettings.textLinesInfo);
7185
7197
  DomHelper.setStyle(linesContainerElement.style, 'height', `${paragraphHeight}px`);
7186
7198
  parent.appendChild(linesContainerElement);
7187
- const startIndex = this.session.displayData.positionToIndex({ row, column: 0 });
7188
- const endIndex = this.session.displayData.positionToIndex({ row: row + 1, column: 0 }) - 1;
7189
- const combinedFormats = FormatStyleHelper.combineSection(this.session.model.formats, this.session.model.links, startIndex, endIndex).map(x => new FormatExtModel({ ...x, content: this.session.model.content.substring(x.startIndex, x.endIndex + 1) }));
7190
- const splits = this.session.displayData.paragraphs[row].nextLineIndexes;
7191
- if (splits?.length) {
7192
- const distance = new DistanceModel({ start: startIndex, end: endIndex });
7193
- this.renderingHelper.renderContentWrappedLine({ currentElement: this.element, parentNode: linesContainerElement }, splits, paragraphSettings, combinedFormats, distance, this.session.customContentService, this.session.customComponents, this.session.generalProperties.scalingRatio, this.session.model.breaks);
7194
- }
7195
- else {
7196
- const markerWidth = paragraphSettings.textLinesInfo[0].indentFirstLine ? paragraphSettings.textLinesInfo[0].markerWidth : 0;
7197
- const numberingOffsetLeft = paragraphSettings.numberingData.numberingId === null
7198
- ? 0
7199
- : paragraphSettings.numberingData.width + paragraphSettings.numberingData.paddingLeft - markerWidth;
7200
- let offset = 0;
7201
- if (paragraphSettings.textLinesInfo[0].isNumbering &&
7202
- numberingOffsetLeft - paragraphSettings.textLinesInfo[0].indentLeft > 0 &&
7203
- numberingOffsetLeft - paragraphSettings.textLinesInfo[0].indentLeft < paragraphSettings.textLinesInfo[0].markerWidth) {
7204
- offset = paragraphSettings.textLinesInfo[0].markerWidth;
7205
- }
7206
- const lineInfo = paragraphSettings.textLinesInfo[0];
7207
- const lastLineEl = this.renderingHelper.createLineElement(lineInfo, numberingOffsetLeft - offset, this.session.generalProperties.scalingRatio);
7208
- linesContainerElement.appendChild(lastLineEl);
7209
- const rowDistance = new DistanceModel({ start: startIndex, end: endIndex });
7210
- this.renderingHelper.renderContentSimpleLine({ currentElement: this.element, parentNode: lastLineEl }, combinedFormats, rowDistance, this.session.customContentService, this.session.customComponents, lineInfo, this.session.model.breaks);
7211
- }
7199
+ const combinedFormats = FormatStyleHelper.combineSection(this.session.model.formats, this.session.model.links, paragraph.startIndex, paragraph.startIndex + paragraph.content.length);
7200
+ RenderingHelper.renderParagraph({ currentElement: this.element, parentNode: linesContainerElement }, paragraph, combinedFormats, this.session.customContentService, this.session.customComponents, this.session.generalProperties.scalingRatio, this.session.model.breaks);
7212
7201
  }
7213
7202
  }
7214
7203
 
@@ -7254,7 +7243,7 @@ class PrintRenderer {
7254
7243
  this.content.className = 'noder-content print';
7255
7244
  }
7256
7245
  createLayers() {
7257
- this.textLayer = new PrintTextLayer(this.content, this.mainSession, PrintRenderingHelper);
7246
+ this.textLayer = new PrintTextLayer(this.content, this.mainSession);
7258
7247
  this.pagesLayer = new PrintPagesLayer(this.content, this.mainSession);
7259
7248
  this.edgesLayer = new EdgesLayer(this.content, this.mainSession);
7260
7249
  }
@@ -8656,7 +8645,7 @@ class Editor {
8656
8645
  const cursor = PositionHelper.documentToPixel(this.session, this.session.selection.cursor);
8657
8646
  const rect = this.renderer.container.getBoundingClientRect();
8658
8647
  const x = rect.left + cursor.pageX;
8659
- const y = rect.top + cursor.pageY + cursor.lineHeight;
8648
+ const y = rect.top + cursor.pageY + cursor.height;
8660
8649
  this.overlayService.open(component, { textKey }, x, y);
8661
8650
  }
8662
8651
  cut() {
@@ -9306,7 +9295,7 @@ class Editor {
9306
9295
  saveInsertBreakToHistory(model) {
9307
9296
  model.isOnNewParagraph =
9308
9297
  model.breakType === BreakTypes.Page &&
9309
- BreakHelper.getBreakType(this.session.model, CUSTOM_ELEMENT_MARKER, model.insertIndex - 1) !== BreakTypes.Page;
9298
+ BreakHelper.getBreakType(this.session.model.breaks, CUSTOM_ELEMENT_MARKER, model.insertIndex - 1) !== BreakTypes.Page;
9310
9299
  const count = model.isOnNewParagraph ? NEW_LINE_MARKUP.length + 1 : 1;
9311
9300
  this.history.pushInsertBreak(model, count);
9312
9301
  this.commandsService.createCommand(SaveCommandsHelper.getInsertBreakCommand(model, this.targets));
@@ -9900,7 +9889,7 @@ class Editor {
9900
9889
  const mainRect = this.mainRenderer.container.getBoundingClientRect();
9901
9890
  const rect = this.renderer.container.getBoundingClientRect();
9902
9891
  const hintX = mainRect.right - 20;
9903
- const hintY = rect.top + cursor.pageY + cursor.lineHeight / 2 - 20;
9892
+ const hintY = rect.top + cursor.pageY + cursor.height / 2 - 20;
9904
9893
  this.overlayService.open(CommentPopupComponent, {}, hintX, hintY);
9905
9894
  }
9906
9895
  }
@@ -9950,9 +9939,7 @@ class Editor {
9950
9939
  changedTableSize(insertIndex, sessionId) {
9951
9940
  const session = this.regulatorService.getSession(sessionId);
9952
9941
  const paragraph = ContentHelper.documentIndexToParagraphIndex(session.displayData.paragraphs, insertIndex).row;
9953
- session.displayData.resetAllNumberingInfo(paragraph);
9954
9942
  session.displayData.updateNextLineIndexes(paragraph, paragraph);
9955
- session.displayData.updateNumberingsDataOnChange(paragraph + 1);
9956
9943
  this.focus();
9957
9944
  this.onContentChange();
9958
9945
  }
@@ -10412,18 +10399,12 @@ class Editor {
10412
10399
  let existed = this.mainSession.customComponents.edges.headersComponents.findIndex(x => x.instance.sessionId === sessionId);
10413
10400
  if (existed !== -1) {
10414
10401
  const headers = this.mainSession.customComponents.edges.headersComponents.slice(existed + 1);
10415
- headers.forEach(x => {
10416
- x.instance.session.displayData.resetAllNumberingInfo(0);
10417
- x.instance.session.displayData.updateNextLineIndexes(0, x.instance.session.displayData.paragraphs.length - 1);
10418
- });
10402
+ headers.forEach(x => x.instance.session.displayData.updateNextLineIndexes(0, x.instance.session.displayData.paragraphs.length - 1));
10419
10403
  }
10420
10404
  else {
10421
10405
  existed = this.mainSession.customComponents.edges.footersComponents.findIndex(x => x.instance.sessionId === sessionId);
10422
10406
  const footers = this.mainSession.customComponents.edges.footersComponents.slice(existed + 1);
10423
- footers.forEach(x => {
10424
- x.instance.session.displayData.resetAllNumberingInfo(0);
10425
- x.instance.session.displayData.updateNextLineIndexes(0, x.instance.session.displayData.paragraphs.length - 1);
10426
- });
10407
+ footers.forEach(x => x.instance.session.displayData.updateNextLineIndexes(0, x.instance.session.displayData.paragraphs.length - 1));
10427
10408
  }
10428
10409
  });
10429
10410
  }
@@ -10502,7 +10483,7 @@ class Editor {
10502
10483
  const mainRect = this.mainRenderer.container.getBoundingClientRect();
10503
10484
  const rect = this.renderer.container.getBoundingClientRect();
10504
10485
  const hintX = mainRect.right - 20;
10505
- const hintY = rect.top + cursor.pageY + cursor.lineHeight / 2 - 20;
10486
+ const hintY = rect.top + cursor.pageY + cursor.height / 2 - 20;
10506
10487
  this.overlayService.open(CommentPopupComponent, {}, hintX, hintY);
10507
10488
  event?.stopPropagation();
10508
10489
  }
@@ -10687,10 +10668,47 @@ class CellSessionSourceModel {
10687
10668
  }
10688
10669
  }
10689
10670
 
10671
+ const DisplayValue = {
10672
+ char: 1,
10673
+ customContent: 3,
10674
+ table: 4,
10675
+ pageBreak: 5,
10676
+ lineBreak: 6,
10677
+ punctuation: 9,
10678
+ space: 10,
10679
+ tab: 11,
10680
+ paragraph: 13,
10681
+ hyphen: 14
10682
+ };
10683
+
10690
10684
  class DisplayToken {
10685
+ get isSpace() {
10686
+ return this.displayValue === DisplayValue.space;
10687
+ }
10688
+ get isParagraph() {
10689
+ return this.displayValue === DisplayValue.paragraph;
10690
+ }
10691
+ get isPageBreak() {
10692
+ return this.displayValue === DisplayValue.pageBreak;
10693
+ }
10694
+ get isLineBreak() {
10695
+ return this.displayValue === DisplayValue.lineBreak;
10696
+ }
10697
+ get isTab() {
10698
+ return this.displayValue === DisplayValue.tab;
10699
+ }
10700
+ get isTable() {
10701
+ return this.displayValue === DisplayValue.table;
10702
+ }
10703
+ get isWhiteSpace() {
10704
+ return this.isSpace || this.isParagraph;
10705
+ }
10691
10706
  get breaksLine() {
10692
10707
  return this.isPageBreak || this.isLineBreak;
10693
10708
  }
10709
+ get breakable() {
10710
+ return this.displayValue !== DisplayValue.char && this.displayValue !== DisplayValue.punctuation;
10711
+ }
10694
10712
  constructor(fields) {
10695
10713
  if (!fields) {
10696
10714
  return;
@@ -10699,79 +10717,28 @@ class DisplayToken {
10699
10717
  }
10700
10718
  }
10701
10719
 
10702
- class IndentModel {
10703
- constructor(firstLine, hanging, left, right) {
10704
- this.firstLine = firstLine;
10705
- this.hanging = hanging;
10706
- this.left = left;
10707
- this.right = right;
10720
+ class NoderTabComponent extends BaseNoderComponent {
10721
+ get tab() {
10722
+ return this.content;
10708
10723
  }
10709
- }
10710
-
10711
- class LineInfoModel {
10712
- constructor(fields) {
10713
- if (!fields) {
10714
- return;
10715
- }
10716
- Object.assign(this, fields);
10724
+ set tab(val) {
10725
+ this.content = val;
10717
10726
  }
10718
- }
10719
-
10720
- class DisplayTokenHelper {
10721
- static getDisplayValue(charCode) {
10722
- if (charCode === 32) {
10723
- return DisplayValue.space;
10724
- }
10725
- if ((charCode > 39 && charCode < 48) || (charCode > 57 && charCode < 64)) {
10726
- return DisplayValue.punctuation;
10727
- }
10728
- return DisplayValue.char;
10727
+ initialize() {
10728
+ this.applySize(this.tab.width);
10729
10729
  }
10730
- static getLineInfoFromToken(prevToken, firstWrapToken, wrapTokens, isAfterPageBreak) {
10731
- const info = new LineInfoModel({
10732
- width: 0,
10733
- height: 0,
10734
- align: prevToken.align,
10735
- indent: new IndentModel(prevToken.indentFirstLine, prevToken.indentHanging, prevToken.indentLeft, prevToken.indentRight),
10736
- offsetBefore: prevToken.indentBefore,
10737
- offsetAfter: prevToken.indentAfter,
10738
- lineSpacing: prevToken.lineSpacing,
10739
- markerWidth: prevToken.markerWidth,
10740
- isAfterPageBreak,
10741
- isEndedByPageBreak: prevToken.isPageBreak,
10742
- isNumbering: prevToken.isNumbering
10743
- });
10744
- if (firstWrapToken) {
10745
- info.align = firstWrapToken.align;
10746
- info.indent.firstLine = firstWrapToken.indentFirstLine;
10747
- info.indent.hanging = firstWrapToken.indentHanging;
10748
- info.indent.left = firstWrapToken.indentLeft;
10749
- info.indent.right = firstWrapToken.indentRight;
10750
- info.offsetBefore = firstWrapToken.indentBefore;
10751
- info.offsetAfter = firstWrapToken.indentAfter;
10752
- info.lineSpacing = firstWrapToken.lineSpacing;
10753
- info.hasTable = firstWrapToken.isTable;
10754
- info.isNumbering = firstWrapToken.isNumbering;
10755
- info.markerWidth = firstWrapToken.markerWidth;
10756
- }
10757
- let maxAscent = 0;
10758
- let maxDescent = 0;
10759
- const tokens = isAfterPageBreak && !wrapTokens.length ? [prevToken] : wrapTokens;
10760
- for (const wrapToken of tokens) {
10761
- if (maxAscent < wrapToken.ascent) {
10762
- maxAscent = wrapToken.ascent;
10763
- }
10764
- if (maxDescent < wrapToken.descent) {
10765
- maxDescent = wrapToken.descent;
10766
- }
10767
- info.width += wrapToken.width;
10768
- }
10769
- info.maxAscent = maxAscent;
10770
- info.height = maxAscent + maxDescent;
10771
- info.offsetAfter = info.height * (info.lineSpacing - 1);
10772
- return info;
10730
+ applySize(width) {
10731
+ this.width.set(ScalingHelper.scale(width, this.generalProperties.scalingRatio));
10773
10732
  }
10733
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NoderTabComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
10734
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: NoderTabComponent, isStandalone: false, selector: "app-nod-tab", host: { properties: { "style.min-width.px": "width()" } }, usesInheritance: true, ngImport: i0, template: "&emsp;\n", styles: [":host{position:relative;outline:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
10774
10735
  }
10736
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NoderTabComponent, decorators: [{
10737
+ type: Component,
10738
+ args: [{ selector: 'app-nod-tab', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, host: {
10739
+ '[style.min-width.px]': 'width()'
10740
+ }, template: "&emsp;\n", styles: [":host{position:relative;outline:none}\n"] }]
10741
+ }] });
10775
10742
 
10776
10743
  class CellDataModel {
10777
10744
  constructor(cell, cellContentHeight, componentRef) {
@@ -12008,195 +11975,156 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
12008
11975
  args: [{ selector: 'app-nod-table', template: '', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, styles: [":host{position:relative}:host::ng-deep table{position:relative;border-collapse:collapse;background:transparent;empty-cells:show;border-spacing:0;overflow:visible;table-layout:fixed}:host::ng-deep td{position:relative;vertical-align:top;border:1px solid #000;margin:0;padding:0;height:inherit}:host::ng-deep .hidden-cell{display:none;cursor:not-allowed}:host::ng-deep .resizer-border{position:absolute;border:solid .5px blue;z-index:1}\n"] }]
12009
11976
  }], ctorParameters: () => [{ type: ComponentService }, { type: i0.ElementRef }, { type: OverlayService }, { type: RegulatorService }] });
12010
11977
 
12011
- class NumberingDataModel {
12012
- constructor(fields) {
12013
- if (!fields) {
12014
- return;
11978
+ class DisplayTokenHelper {
11979
+ static getDisplayValue(charCode, breakType) {
11980
+ if (breakType === BreakTypes.Page) {
11981
+ return DisplayValue.pageBreak;
12015
11982
  }
12016
- Object.assign(this, fields);
12017
- }
12018
- }
12019
-
12020
- class NumberingParagraphStyleModel extends ParagraphStyleModel {
12021
- constructor(fields) {
12022
- super();
12023
- this.numberingType = null;
12024
- this.numberingLevelsStyles = null;
12025
- if (!fields) {
12026
- return;
12027
- }
12028
- Object.assign(this, fields);
12029
- }
12030
- }
12031
-
12032
- class NumberingHelper {
12033
- static getStyles(paragraphStyle, numberings) {
12034
- const numberingLevels = numberings.find(x => x.numberingId === paragraphStyle.numberingId).levels;
12035
- const numberingLevelsStyles = numberingLevels.reduce((prev, next) => `${prev}${next.marker}${next.markerType}`, '');
12036
- const level = numberingLevels.find(x => x.level === paragraphStyle.numberingLevel);
12037
- return new NumberingParagraphStyleModel({ ...paragraphStyle, numberingType: level.markerType, numberingLevelsStyles });
12038
- }
12039
- static find(numberings, id, level) {
12040
- const numbering = numberings.find(x => x.numberingId === id);
12041
- return numbering?.levels.find(x => x.level === level);
12042
- }
12043
- static calculateNumberingInfo(numberingId, level, marker, numberingInfo, numberings) {
12044
- const numberingModel = this.find(numberings, numberingId, level);
12045
- if (numberingModel?.markerType === NumberingMarkerType.Bullet) {
12046
- return;
12047
- }
12048
- this.calculateMarkerIndexes(numberingId, level, marker, numberingInfo);
12049
- }
12050
- static calculateMarkerIndexes(numberingId, level, marker, numberingInfo) {
12051
- if (!numberingId) {
12052
- return;
11983
+ if (breakType === BreakTypes.TextWrapping) {
11984
+ return DisplayValue.lineBreak;
12053
11985
  }
12054
- if (!numberingInfo[numberingId]?.length || !numberingInfo[numberingId][level]) {
12055
- numberingInfo[numberingId] ??= [];
12056
- return;
11986
+ if (charCode === 32) {
11987
+ return DisplayValue.space;
12057
11988
  }
12058
- if (!numberingInfo[numberingId][level]?.visited) {
12059
- if (!marker) {
12060
- numberingInfo[numberingId][level].markerIndex++;
12061
- return;
12062
- }
12063
- this.updateNumberingInfo(numberingInfo, marker, numberingId, level);
11989
+ if (charCode === 45) {
11990
+ return DisplayValue.hyphen;
12064
11991
  }
12065
- else {
12066
- numberingInfo[numberingId][level].markerIndex++;
12067
- for (let i = 0; i < numberingInfo[numberingId].length; i++) {
12068
- if (i >= level + 1) {
12069
- numberingInfo[numberingId][i].markerIndex = 0;
12070
- }
12071
- else {
12072
- if (numberingInfo[numberingId][i].markerIndex === 0) {
12073
- numberingInfo[numberingId][i].markerIndex++;
12074
- }
12075
- }
12076
- }
11992
+ if ((charCode > 39 && charCode < 48) || (charCode > 57 && charCode < 64)) {
11993
+ return DisplayValue.punctuation;
12077
11994
  }
11995
+ return DisplayValue.char;
12078
11996
  }
12079
- static getMarker(levelModel, numberingId, paragraphs, paragraphIndex, numberingInfo) {
12080
- let resultMarker = levelModel.marker;
12081
- let index = resultMarker.indexOf('%');
12082
- if (index === -1) {
12083
- return resultMarker;
12084
- }
12085
- if (numberingInfo[numberingId]?.length && numberingInfo[numberingId][levelModel.level]) {
12086
- return this.createMarkerString(numberingInfo, numberingId, levelModel.level);
12087
- }
12088
- while (index !== -1) {
12089
- const symbolLevelNumber = Number(resultMarker[index + 1]) - 1;
12090
- const levelIndex = this.getLevelIndex(paragraphs, paragraphIndex, numberingId, symbolLevelNumber);
12091
- const count = levelModel.startValue + levelIndex;
12092
- resultMarker = resultMarker.slice(0, index) + count.toString() + resultMarker.slice(index + 2);
12093
- index = resultMarker.indexOf('%');
12094
- }
12095
- numberingInfo[numberingId] ??= [];
12096
- this.updateNumberingInfo(numberingInfo, resultMarker, numberingId, levelModel.level);
12097
- const markerLevels = resultMarker.split('.');
12098
- if (levelModel.level !== 0 && markerLevels[markerLevels.length - 1] === '') {
12099
- return resultMarker.slice(0, -1);
12100
- }
12101
- return resultMarker;
11997
+ static getParagraphToken(paragraphSymbolStyle) {
11998
+ const size = FontMetrics.measureCharSize('0', ContentStyleHelper.getFontStylesString(paragraphSymbolStyle));
11999
+ return new DisplayToken({ ...size, displayValue: DisplayValue.paragraph });
12102
12000
  }
12103
- static createDataModel(numberings, paragraphs, paragraphIndex, numberingInfo) {
12104
- const paragraph = paragraphs[paragraphIndex];
12105
- const numberingId = paragraph?.paragraphStyle.numberingId;
12106
- if (!numberingId) {
12107
- return new NumberingDataModel({ numberingId: null });
12001
+ static getSymbolToken(code, size, breakType) {
12002
+ const result = new DisplayToken({ ...size, displayValue: DisplayTokenHelper.getDisplayValue(code, breakType) });
12003
+ if (result.isSpace) {
12004
+ result.ascent = 0;
12005
+ result.descent = 0;
12006
+ result.height = 0;
12108
12007
  }
12109
- const level = paragraph.paragraphStyle.numberingLevel;
12110
- const numberingLevelModel = this.find(numberings, numberingId, level);
12111
- for (let i = 0; i < level; i++) {
12112
- if (!numberingInfo[numberingId] || !numberingInfo[numberingId][i]) {
12113
- const numberingLevel = this.find(numberings, numberingId, i);
12114
- this.getMarker(numberingLevel, numberingId, paragraphs, paragraphIndex, numberingInfo);
12115
- }
12116
- }
12117
- const marker = this.getMarker(numberingLevelModel, numberingId, paragraphs, paragraphIndex, numberingInfo);
12118
- return new NumberingDataModel({ numberingId, level, marker });
12008
+ return result;
12119
12009
  }
12120
- static updateMarkerData(properties, paragraph, paragraphTextStyle, paragraphStyle) {
12121
- const numberingLevel = NumberingHelper.find(properties.numberings, paragraph.numberingData.numberingId, paragraph.numberingData.level);
12122
- const markerTextStyle = ContentStyleHelper.combineTextStyles(numberingLevel.markerStyle, paragraphTextStyle);
12123
- const markerSizes = NumberingHelper.getMarkerSizes(paragraph.numberingData.marker, markerTextStyle);
12124
- paragraph.numberingData.markerTextStyle = markerTextStyle;
12125
- paragraph.numberingData.width = markerSizes.width;
12126
- paragraph.numberingData.height = markerSizes.height;
12127
- const indentLeft = paragraphStyle.indentLeft !== null ? paragraphStyle.indentLeft : numberingLevel.indentLeft;
12128
- let indent = 0;
12129
- if (paragraphStyle.indentHanging === null && paragraphStyle.indentFirstLine === null) {
12130
- indent = -numberingLevel.indentHanging;
12131
- }
12132
- else {
12133
- indent = paragraphStyle.indentHanging !== null ? -paragraphStyle.indentHanging : paragraphStyle.indentFirstLine;
12134
- }
12135
- paragraph.numberingData.paddingLeft = indentLeft + indent;
12010
+ static getComponentToken(component, size) {
12011
+ const ascent = component.instance.ascent() ?? 0;
12012
+ const descent = component.instance.descent() ?? 0;
12013
+ let displayValue = component.instance instanceof NoderTabComponent ? DisplayValue.tab : DisplayValue.customContent;
12014
+ displayValue = component.instance instanceof NoderTableComponent ? DisplayValue.table : displayValue;
12015
+ return new DisplayToken({
12016
+ width: component.instance.width(),
12017
+ height: ascent + descent,
12018
+ font: size.font,
12019
+ ascent,
12020
+ descent,
12021
+ displayValue
12022
+ });
12136
12023
  }
12137
- static getMarkerSizes(marker, markerStyle) {
12138
- let width = 0;
12139
- let height = 0;
12140
- const markerStylesString = ContentStyleHelper.getFontStylesString(markerStyle);
12141
- for (let char of marker) {
12142
- const markerCharSizes = FontMetrics.measureCharSize(char, markerStylesString);
12143
- width += markerCharSizes.width;
12144
- if (height < markerCharSizes.height) {
12145
- height = markerCharSizes.height;
12146
- }
12147
- }
12148
- return { height, width };
12024
+ }
12025
+
12026
+ class IndentModel {
12027
+ constructor(firstLine, hanging, left, right, markerWidth) {
12028
+ this.firstLine = firstLine;
12029
+ this.hanging = hanging;
12030
+ this.left = left;
12031
+ this.right = right;
12032
+ this.markerWidth = markerWidth;
12149
12033
  }
12150
- static updateNumberingInfo(numberingInfo, marker, numberingId, level) {
12151
- if (!numberingInfo[numberingId]) {
12034
+ }
12035
+
12036
+ class LineInfoModel {
12037
+ constructor(fields) {
12038
+ if (!fields) {
12152
12039
  return;
12153
12040
  }
12154
- const markerLevels = this.getLevelInfo(marker);
12155
- const lastMarkerLevel = markerLevels.length - 1;
12156
- numberingInfo[numberingId][level] = {
12157
- markerIndex: markerLevels[lastMarkerLevel],
12158
- markerLevel: Math.min(lastMarkerLevel, level),
12159
- visited: true
12160
- };
12041
+ Object.assign(this, fields);
12161
12042
  }
12162
- static getLevelIndex(paragraphs, paragraphIndex, numberingId, numberingLevel) {
12163
- let index = 0;
12164
- let isOnlySubLevelsBefore = false;
12165
- for (let i = paragraphIndex; i >= 0; i--) {
12166
- if (paragraphs[i].paragraphStyle.numberingId !== numberingId) {
12167
- continue;
12168
- }
12169
- if (paragraphs[i].paragraphStyle.numberingLevel < numberingLevel) {
12170
- break;
12171
- }
12172
- if (paragraphs[i].paragraphStyle.numberingLevel > numberingLevel) {
12173
- isOnlySubLevelsBefore = true;
12043
+ }
12044
+
12045
+ class LineInfoHelper {
12046
+ static get(tokens, isAfterPageBreak, isLastLine, style, indent, isNumbering, width, defaultHeight, defaultAscent) {
12047
+ const result = new LineInfoModel({
12048
+ isAfterPageBreak,
12049
+ isEndedByPageBreak: tokens[tokens.length - 1].isPageBreak,
12050
+ backgroundColor: style.backgroundColor,
12051
+ align: style.alignment ?? DEFAULT_PARAGRAPH_STYLE.alignment,
12052
+ indent,
12053
+ offsetBefore: DEFAULT_PARAGRAPH_STYLE.spaceBefore,
12054
+ lineSpacing: style.lineSpacing ?? DEFAULT_PARAGRAPH_STYLE.lineSpacing,
12055
+ isNumbering,
12056
+ hasTable: false,
12057
+ width: 0
12058
+ });
12059
+ let maxAscent = 0;
12060
+ let maxDescent = 0;
12061
+ for (const token of tokens) {
12062
+ if (maxAscent < token.ascent) {
12063
+ maxAscent = token.ascent;
12064
+ }
12065
+ if (maxDescent < token.descent) {
12066
+ maxDescent = token.descent;
12067
+ }
12068
+ result.width += token.width;
12069
+ }
12070
+ result.height = maxAscent + maxDescent;
12071
+ result.ascent = maxAscent;
12072
+ if (result.height === 0) {
12073
+ result.height = defaultHeight;
12074
+ result.ascent = defaultAscent;
12075
+ }
12076
+ result.offsetAfter = result.height * (result.lineSpacing - 1);
12077
+ if (style.alignment === Alignment$1.justify && !isLastLine) {
12078
+ let right = tokens.length - 1;
12079
+ let adjustableWidth = result.width;
12080
+ while (right > 0 && tokens[right].isSpace) {
12081
+ adjustableWidth -= tokens[right].width;
12082
+ right--;
12083
+ }
12084
+ let left = 0;
12085
+ while (left < tokens.length - 1 && tokens[left].isSpace) {
12086
+ left++;
12087
+ }
12088
+ let spaces = 0;
12089
+ for (let i = right; i > left; i--) {
12090
+ if (tokens[i].isTab) {
12091
+ left = i;
12092
+ }
12093
+ if (tokens[i].isSpace) {
12094
+ spaces++;
12095
+ }
12174
12096
  }
12175
- else {
12176
- index++;
12177
- isOnlySubLevelsBefore = false;
12097
+ const indentWidth = (indent.left ?? 0) + (indent.right ?? 0) + (indent.firstLine ?? 0) - (indent.hanging ?? 0);
12098
+ const availableWidth = width - indentWidth - indent.markerWidth; // todo: use NumberingHelper.getOffsetCausedByMarker
12099
+ const whitespaceDeficit = availableWidth - adjustableWidth;
12100
+ if (spaces > 0 && whitespaceDeficit > 0) {
12101
+ result.wordSpacing = whitespaceDeficit / spaces;
12102
+ result.width = availableWidth;
12103
+ result.wordSpacingStart = left;
12104
+ result.wordSpacingEnd = right;
12105
+ for (let i = right; i > left; i--) {
12106
+ if (tokens[i].isSpace) {
12107
+ tokens[i].width += result.wordSpacing;
12108
+ }
12109
+ }
12178
12110
  }
12179
12111
  }
12180
- index = isOnlySubLevelsBefore ? index + 1 : index;
12181
- return index <= 0 ? 0 : index - 1;
12182
- }
12183
- static getLevelInfo(input) {
12184
- return input
12185
- .split('.')
12186
- .filter(x => !!x)
12187
- .map(x => parseInt(x));
12112
+ return result;
12188
12113
  }
12189
- static createMarkerString(numberingInfo, numberingId, level) {
12190
- if (level === 0) {
12191
- return numberingInfo[numberingId][level].markerIndex + '.';
12192
- }
12193
- let marker = [];
12194
- let { markerLevel, markerIndex } = numberingInfo[numberingId][level];
12195
- for (let i = 0; i < markerLevel; i++) {
12196
- marker.push(numberingInfo[numberingId][i].markerIndex);
12114
+ static getFirstLineIndent(model, paragraphIndex, generalProperties) {
12115
+ const paragraph = model.paragraphs[paragraphIndex];
12116
+ const paragraphStyle = paragraph.paragraphStyle;
12117
+ if (paragraphStyle.numberingId === null) {
12118
+ return new IndentModel(paragraph.paragraphStyle.indentFirstLine ?? DEFAULT_PARAGRAPH_STYLE.indentFirstLine, paragraph.paragraphStyle.indentHanging ?? DEFAULT_PARAGRAPH_STYLE.indentHanging, paragraph.paragraphStyle.indentLeft ?? DEFAULT_PARAGRAPH_STYLE.indentLeft, paragraph.paragraphStyle.indentRight ?? DEFAULT_PARAGRAPH_STYLE.indentRight, 0);
12197
12119
  }
12198
- marker.push(markerIndex);
12199
- return marker.join('.');
12120
+ const levelsModel = NumberingHelper.findNumberingLevels(generalProperties.numberings, paragraphStyle.numberingId);
12121
+ const paragraphFormat = FormatStyleHelper.getFormatAtIndex(model.formats, paragraph.insertIndex);
12122
+ const markerTextStyle = ContentStyleHelper.combineTextStyles(levelsModel[paragraphStyle.numberingLevel].markerStyle, paragraphFormat.textStyle);
12123
+ const marker = NumberingHelper.getMarker(levelsModel, paragraphStyle.numberingLevel, paragraphStyle.numberingId, generalProperties.numberingInfo);
12124
+ const markerWidth = NumberingHelper.getMarkerSizes(marker, markerTextStyle).width;
12125
+ return new IndentModel(paragraph.paragraphStyle.indentFirstLine ?? DEFAULT_PARAGRAPH_STYLE.indentFirstLine, DEFAULT_PARAGRAPH_STYLE.indentHanging, paragraph.paragraphStyle.indentLeft !== null
12126
+ ? paragraph.paragraphStyle.indentLeft
12127
+ : levelsModel[paragraphStyle.numberingLevel].indentLeft, paragraph.paragraphStyle.indentRight ?? DEFAULT_PARAGRAPH_STYLE.indentRight, markerWidth + markerWidth / marker.length);
12200
12128
  }
12201
12129
  }
12202
12130
 
@@ -12279,20 +12207,14 @@ class PageFormat {
12279
12207
  }
12280
12208
  }
12281
12209
 
12282
- class TextLineInfo {
12210
+ class TextLineInfo extends LineInfoModel {
12283
12211
  constructor(offsetMargin, contentWidth, align, indent, fields) {
12212
+ super(fields);
12284
12213
  this.paddingLeft = 0;
12285
12214
  this.offsetMargin = 0;
12286
- this.offsetBefore = 0;
12287
- this.offsetAfter = 0;
12288
12215
  this.firstLinePageOffset = 0; // for selection
12289
12216
  this.endPageOffset = 0; // for selection
12290
12217
  this.screenLine = 0;
12291
- this.isAfterPageBreak = false;
12292
- this.isEndedByPageBreak = false;
12293
- if (fields) {
12294
- Object.assign(this, fields);
12295
- }
12296
12218
  this.indentFirstLine = indent.firstLine;
12297
12219
  this.offsetMargin = offsetMargin;
12298
12220
  this.indentLeft = indent.left;
@@ -12414,47 +12336,6 @@ class ParagraphInfosRemoved {
12414
12336
  }
12415
12337
  }
12416
12338
 
12417
- class ParagraphStyleHelper {
12418
- static getParagraphsAtRange(paragraphs, startIndex, endIndex) {
12419
- if (!paragraphs?.length) {
12420
- return [];
12421
- }
12422
- let firstModifierIndexInRange = paragraphs.findIndex(paragraph => paragraph.insertIndex >= startIndex);
12423
- firstModifierIndexInRange = firstModifierIndexInRange === -1 ? paragraphs.length : firstModifierIndexInRange;
12424
- let lastModifierIndexInRange = paragraphs.findIndex(x => x.insertIndex >= endIndex);
12425
- lastModifierIndexInRange =
12426
- startIndex === endIndex || lastModifierIndexInRange === -1 ? firstModifierIndexInRange : lastModifierIndexInRange;
12427
- return paragraphs.slice(firstModifierIndexInRange, lastModifierIndexInRange + 1);
12428
- }
12429
- static getParagraphAtIndex(paragraphs, insertIndex) {
12430
- if (!paragraphs?.length) {
12431
- return null;
12432
- }
12433
- let startIndex = 0;
12434
- let endIndex = paragraphs.length - 1;
12435
- while (startIndex <= endIndex) {
12436
- const middleIndex = Math.round((startIndex + endIndex) / 2);
12437
- const paragraph = paragraphs[middleIndex];
12438
- if (paragraph.insertIndex < insertIndex) {
12439
- startIndex = middleIndex + 1;
12440
- }
12441
- else {
12442
- endIndex = middleIndex - 1;
12443
- }
12444
- }
12445
- return paragraphs[startIndex];
12446
- }
12447
- static isEndOfParagraph(paragraphs, endIndex) {
12448
- const paragraph = this.getParagraphAtIndex(paragraphs, endIndex);
12449
- let paragraphIndex = paragraphs.findIndex(x => x === paragraph);
12450
- const endOfParagraphIsParagraph = paragraph && endIndex === paragraph.insertIndex && paragraphs.length - 1 > paragraphIndex;
12451
- if (endOfParagraphIsParagraph) {
12452
- paragraphIndex += 1;
12453
- }
12454
- return paragraphs[paragraphIndex].insertIndex === endIndex + 1;
12455
- }
12456
- }
12457
-
12458
12339
  var TabAlignment;
12459
12340
  (function (TabAlignment) {
12460
12341
  TabAlignment[TabAlignment["Left"] = 0] = "Left";
@@ -12464,14 +12345,6 @@ var TabAlignment;
12464
12345
  TabAlignment[TabAlignment["Bar"] = 4] = "Bar";
12465
12346
  })(TabAlignment || (TabAlignment = {}));
12466
12347
 
12467
- class TabHelper {
12468
- static calculateTabWidth(rowWidth, defaultTabWidth, tabSettings) {
12469
- const tabs = tabSettings ?? [];
12470
- const nextSetting = tabs.find(x => x.position > rowWidth);
12471
- return nextSetting ? nextSetting.position - rowWidth : defaultTabWidth - (rowWidth % defaultTabWidth);
12472
- }
12473
- }
12474
-
12475
12348
  class DisplayData extends EventEmitting {
12476
12349
  get maxPageWidth() {
12477
12350
  let max = 0;
@@ -12498,7 +12371,6 @@ class DisplayData extends EventEmitting {
12498
12371
  this.paragraphs = [];
12499
12372
  this.pagesFormat = [];
12500
12373
  this.allPagesHeight = 0;
12501
- this.tabTokens = [];
12502
12374
  this.ParagraphInfoChanges = new Subject();
12503
12375
  this.lastParagraphId = 0;
12504
12376
  this.updateDataForModel();
@@ -12765,26 +12637,36 @@ class DisplayData extends EventEmitting {
12765
12637
  }
12766
12638
  if (paragraphSettings.numberingData.numberingId !== null) {
12767
12639
  const paragraphFormat = FormatStyleHelper.getFormatAtIndex(this.model.formats, this.model.paragraphs[index].insertIndex);
12768
- NumberingHelper.updateMarkerData(this.generalProperties, paragraphSettings, paragraphFormat.textStyle, this.model.paragraphs[index].paragraphStyle);
12640
+ NumberingHelper.updateMarkerData(this.generalProperties.numberings, paragraphSettings, paragraphFormat.textStyle, this.model.paragraphs[index].paragraphStyle);
12769
12641
  }
12770
12642
  }
12771
12643
  updateNextLineIndexes(firstParagraph, lastParagraph) {
12772
12644
  this.updateParagraphStartIndex(firstParagraph);
12773
12645
  let indexOfParagraphAfterPageBreak = this.getParagraphSettings(firstParagraph - 1)?.isEndedByPageBreak ? firstParagraph : -1;
12774
- let firstUsedTabIndex = this.model.tabs.findIndex(x => x.insertIndex >= this.paragraphs[firstParagraph].startIndex);
12646
+ let updateNumberingFromIndex = null;
12775
12647
  for (let i = firstParagraph; i <= lastParagraph; i++) {
12776
12648
  if (!this.paragraphs[i]) {
12777
12649
  continue;
12778
12650
  }
12779
- this.tabTokens = [];
12780
- const sameNumberingIndex = this.findSameNumberingIndex(i);
12781
- let marker = this.getParagraphSettings(sameNumberingIndex)?.numberingData.marker;
12782
- if (sameNumberingIndex < 0 && this.getParagraphSettings(i)?.numberingData.numberingId) {
12783
- marker = '0.';
12651
+ const numberingId = this.model.paragraphs[i].paragraphStyle.numberingId ?? this.getParagraphSettings(i)?.numberingData.numberingId;
12652
+ if (numberingId) {
12653
+ const numberingsLevels = NumberingHelper.findNumberingLevels(this.generalProperties.numberings, numberingId);
12654
+ NumberingHelper.addValueToNumberingInfo(numberingId, this.generalProperties.numberingInfo, numberingsLevels);
12655
+ let startNumberingParagraphIndex = i;
12656
+ while (this.isSameNumberingId(startNumberingParagraphIndex, numberingId)) {
12657
+ startNumberingParagraphIndex -= 1;
12658
+ }
12659
+ if (updateNumberingFromIndex === null || updateNumberingFromIndex > startNumberingParagraphIndex) {
12660
+ updateNumberingFromIndex = startNumberingParagraphIndex;
12661
+ }
12662
+ if (this.model.paragraphs[i].paragraphStyle.numberingId !== this.getParagraphSettings(i)?.numberingData.numberingId) {
12663
+ const updatedNumberingId = this.getParagraphSettings(i)?.numberingData.numberingId ?? this.model.paragraphs[i].paragraphStyle.numberingId;
12664
+ NumberingHelper.setNumberingNeedToRecalculate(this.generalProperties.numberingInfo, updatedNumberingId);
12665
+ }
12666
+ NumberingHelper.setNumberingNeedToRecalculate(this.generalProperties.numberingInfo, numberingId);
12784
12667
  }
12785
- NumberingHelper.calculateNumberingInfo(this.model.paragraphs[i].paragraphStyle.numberingId ?? this.getParagraphSettings(i)?.numberingData.numberingId ?? null, this.model.paragraphs[i].paragraphStyle.numberingLevel ?? this.getParagraphSettings(i)?.numberingData.level ?? null, marker, this.generalProperties.numberingInfo, this.generalProperties.numberings);
12786
12668
  const numberingData = NumberingHelper.createDataModel(this.generalProperties.numberings, this.model.paragraphs, i, this.generalProperties.numberingInfo);
12787
- const { splits, rowInfos } = this.getSplits(this.model, i);
12669
+ const { splits, rowInfos } = this.splitParagraphByLines(i);
12788
12670
  this.paragraphs[i].nextLineIndexes = splits;
12789
12671
  if (indexOfParagraphAfterPageBreak === i) {
12790
12672
  rowInfos[0].isAfterPageBreak = true;
@@ -12792,235 +12674,134 @@ class DisplayData extends EventEmitting {
12792
12674
  indexOfParagraphAfterPageBreak = rowInfos[rowInfos.length - 1].isEndedByPageBreak ? i + 1 : -1;
12793
12675
  this.setParagraphSettings(i, rowInfos, numberingData);
12794
12676
  this.updateParagraphSettingsNumberingData(i);
12795
- firstUsedTabIndex = this.updateParagraphTabs(firstUsedTabIndex, i);
12796
12677
  }
12678
+ this.updateNumberingsDataOnChange(updateNumberingFromIndex);
12797
12679
  this.getParagraphSettings(lastParagraph + 1)?.setIsAfterPageBreak(indexOfParagraphAfterPageBreak > -1);
12798
12680
  this.updateParagraphLineNumber(firstParagraph);
12799
12681
  this.processParagraphsProperties(firstParagraph);
12800
12682
  }
12683
+ isSameNumberingId(paragraphIndex, numberingId) {
12684
+ if (paragraphIndex === 0) {
12685
+ return false;
12686
+ }
12687
+ const startNumberingId = this.model.paragraphs[paragraphIndex].paragraphStyle.numberingId ??
12688
+ this.getParagraphSettings(paragraphIndex)?.numberingData.numberingId;
12689
+ return numberingId === startNumberingId;
12690
+ }
12801
12691
  updateNumberingsDataOnChange(index) {
12692
+ if (index === null) {
12693
+ return;
12694
+ }
12802
12695
  for (let i = index; i < this.paragraphs.length; i++) {
12803
12696
  const paragraphStyle = this.model.paragraphs[i].paragraphStyle;
12804
12697
  const paragraphSettings = this.getParagraphSettings(i);
12805
12698
  if (this.model.paragraphs[i].paragraphStyle.numberingId !== null) {
12806
- NumberingHelper.calculateNumberingInfo(paragraphStyle.numberingId, paragraphStyle.numberingLevel, paragraphSettings.numberingData.marker, this.generalProperties.numberingInfo, this.generalProperties.numberings);
12807
- paragraphSettings.numberingData = NumberingHelper.createDataModel(this.generalProperties.numberings, this.model.paragraphs, i, this.generalProperties.numberingInfo);
12808
- const paragraphFormat = FormatStyleHelper.getFormatAtIndex(this.model.formats, this.model.paragraphs[i].insertIndex);
12809
- NumberingHelper.updateMarkerData(this.generalProperties, paragraphSettings, paragraphFormat.textStyle, paragraphStyle);
12699
+ if (this.generalProperties.numberingInfo[paragraphStyle.numberingId][paragraphStyle.numberingLevel].needToRecalculate) {
12700
+ NumberingHelper.calculateNumberingInfo(paragraphStyle.numberingId, paragraphStyle.numberingLevel, this.generalProperties.numberingInfo, this.generalProperties.numberings);
12701
+ paragraphSettings.numberingData = NumberingHelper.createDataModel(this.generalProperties.numberings, this.model.paragraphs, i, this.generalProperties.numberingInfo);
12702
+ const paragraphFormat = FormatStyleHelper.getFormatAtIndex(this.model.formats, this.model.paragraphs[i].insertIndex);
12703
+ NumberingHelper.updateMarkerData(this.generalProperties.numberings, paragraphSettings, paragraphFormat.textStyle, paragraphStyle);
12704
+ }
12810
12705
  }
12811
12706
  const table = this.customContentService.findComponent(this.customComponents.tables, paragraphSettings.startInsertIndex);
12812
12707
  if (table) {
12813
12708
  table.instance.updateCells();
12814
12709
  }
12815
12710
  }
12711
+ NumberingHelper.setAllNumberingIsCalculated(this.generalProperties.numberingInfo);
12816
12712
  if ('pageType' in this.model) {
12817
12713
  this.editorService.updateEdges(this.sessionId);
12818
12714
  }
12819
12715
  }
12820
- resetAllNumberingInfo(paragraphIndex) {
12821
- for (let i = paragraphIndex; i < this.model.paragraphs.length; i++) {
12822
- const { numberingId } = this.model.paragraphs[i].paragraphStyle;
12823
- if (numberingId !== null && this.generalProperties.numberingInfo[numberingId]) {
12824
- this.generalProperties.numberingInfo[numberingId] = [];
12825
- }
12826
- }
12827
- }
12828
- resetNumberingInfoByTableCell(table) {
12829
- for (const element of table.instance.rowMatrix) {
12830
- for (let cell of element.cells) {
12831
- const { marker, numberingId, level } = cell.componentRef.instance.session.displayData.paragraphs[0].paragraphSettings.numberingData;
12832
- if (marker && numberingId) {
12833
- NumberingHelper.updateNumberingInfo(this.generalProperties.numberingInfo, marker, numberingId, level);
12834
- this.resetAllNumberingInfo(0);
12835
- return;
12836
- }
12837
- }
12838
- }
12839
- }
12840
- updateParagraphTabs(tabIndex, paragraphIndex) {
12841
- const paragraphContentLength = this.getParagraphContent(paragraphIndex).length;
12842
- const paragraphLastIndex = this.paragraphs[paragraphIndex].startIndex + paragraphContentLength;
12843
- if (tabIndex === -1 ||
12844
- tabIndex >= this.customComponents.tabs.length ||
12845
- this.customComponents.tabs[tabIndex].instance.insertIndex > paragraphLastIndex) {
12846
- return tabIndex;
12847
- }
12848
- const startIndex = tabIndex;
12849
- while (this.customComponents.tabs[tabIndex] && this.customComponents.tabs[tabIndex].instance.insertIndex <= paragraphLastIndex) {
12850
- this.customComponents.tabs[tabIndex].instance.applySize(this.tabTokens[tabIndex - startIndex].width);
12851
- tabIndex++;
12852
- }
12853
- return tabIndex;
12854
- }
12855
- getSplits(model, paragraphIndex) {
12856
- const paragraphContent = this.getParagraphContent(paragraphIndex);
12857
- const strTokens = this.getDisplayTokens(model, paragraphContent, this.paragraphs[paragraphIndex].startIndex);
12858
- if (!strTokens.length) {
12859
- const defaultRowInfo = new LineInfoModel({
12860
- height: (DEFAULT_FONT_SIZE * 4) / 3,
12861
- width: 0,
12862
- align: DEFAULT_PARAGRAPH_STYLE.alignment,
12863
- indent: new IndentModel(DEFAULT_PARAGRAPH_STYLE.indentFirstLine, DEFAULT_PARAGRAPH_STYLE.indentHanging, DEFAULT_PARAGRAPH_STYLE.indentLeft, DEFAULT_PARAGRAPH_STYLE.indentRight),
12864
- offsetAfter: DEFAULT_PARAGRAPH_STYLE.spaceAfter,
12865
- offsetBefore: DEFAULT_PARAGRAPH_STYLE.spaceBefore,
12866
- lineSpacing: DEFAULT_PARAGRAPH_STYLE.lineSpacing,
12867
- isAfterPageBreak: false,
12868
- isEndedByPageBreak: false,
12869
- markerWidth: 0,
12870
- isNumbering: false,
12871
- backgroundColor: DEFAULT_PARAGRAPH_STYLE.backgroundColor
12872
- });
12873
- return { splits: [], rowInfos: [defaultRowInfo] };
12874
- }
12716
+ splitParagraphByLines(paragraphIndex) {
12717
+ const paragraph = this.paragraphs[paragraphIndex];
12718
+ const { paragraphTokens, paragraphToken } = this.getParagraphTokens(paragraph);
12875
12719
  const splits = [];
12876
12720
  const rowInfos = [];
12877
- let prevToken;
12878
- let index = -1;
12879
- let initial = paragraphContent;
12880
- const pageFormat = this.getPageFormatAtPosition(this.paragraphs[paragraphIndex].startIndex);
12881
- while (index) {
12882
- initial = initial.slice(index > 0 ? index : 0);
12883
- const tokens = strTokens.slice(paragraphContent.length - initial.length);
12884
- if (!tokens.length) {
12885
- tokens.push(...this.getEmptyDisplayTokens(model, this.paragraphs[paragraphIndex].startIndex + index));
12886
- }
12887
- let wrapLimit = this.computeWrapIndex(tokens, pageFormat.contentWidth, this.generalProperties.defaultTabWidth, model.paragraphs[paragraphIndex].paragraphStyle.tabSettings);
12888
- if (tokens[tokens.length - 1].isPageBreak && wrapLimit === tokens.length && this.paragraphs.length > paragraphIndex + 1) {
12889
- wrapLimit = 0;
12890
- }
12891
- const wrapSplit = tokens[wrapLimit - 1]?.breaksLine || tokens[wrapLimit - 1]?.isTable ? wrapLimit : this.computeWrapSplit(tokens, wrapLimit);
12892
- const wrapTokens = tokens.slice(0, wrapSplit || undefined);
12893
- if (wrapTokens.length) {
12894
- prevToken = wrapTokens[wrapTokens.length - 1];
12895
- }
12896
- const isAfterPageBreak = !rowInfos.length ? false : rowInfos[rowInfos.length - 1].isEndedByPageBreak;
12897
- const lineInfo = DisplayTokenHelper.getLineInfoFromToken(prevToken, wrapTokens[0], wrapTokens, isAfterPageBreak);
12898
- const paragraphStyle = model.paragraphs[paragraphIndex].paragraphStyle;
12899
- lineInfo.backgroundColor = paragraphStyle.backgroundColor;
12900
- const isLastLineOfParagraph = !wrapLimit || prevToken.isLineBreak;
12901
- if (paragraphStyle.alignment === Alignment$1.justify && !isLastLineOfParagraph && wrapTokens.length > 1) {
12902
- let currentLineWidth = 0;
12903
- let spaceCount = wrapTokens[0].markerWidth ? 1 : 0;
12904
- for (let i = 0; i < wrapTokens.length; i++) {
12905
- const token = wrapTokens[i];
12906
- currentLineWidth += token.width;
12907
- if (token.displayValue === DisplayValue.space) {
12908
- if (i === wrapTokens.length - 1) {
12909
- token.displayValue = DisplayValue.trailingSpace;
12910
- }
12911
- else {
12912
- spaceCount++;
12913
- }
12914
- }
12721
+ const style = this.model.paragraphs[paragraphIndex].paragraphStyle;
12722
+ const pageFormat = this.getPageFormatAtPosition(paragraph.startIndex);
12723
+ const defaultHeight = paragraphToken.height;
12724
+ const defaultAscent = paragraphToken.ascent;
12725
+ let index = 0;
12726
+ let indent = LineInfoHelper.getFirstLineIndent(this.model, paragraphIndex, this.generalProperties);
12727
+ do {
12728
+ let tokens = paragraphTokens.slice(index);
12729
+ const maxWidth = pageFormat.contentWidth - indent.right - indent.markerWidth;
12730
+ let startWidth = indent.left + indent.firstLine - indent.hanging || 0;
12731
+ let last = this.computeWrapIndex(tokens, startWidth, maxWidth, style.tabSettings ?? []);
12732
+ tokens = tokens.slice(0, last + 1);
12733
+ const width = pageFormat.contentWidth;
12734
+ const isNumbering = index === 0 && !!indent.markerWidth;
12735
+ const isBreak = !rowInfos.length ? false : rowInfos[rowInfos.length - 1].isEndedByPageBreak;
12736
+ const isLast = index + last + 1 === paragraphTokens.length;
12737
+ const info = LineInfoHelper.get(tokens, isBreak, isLast, style, indent, isNumbering, width, defaultHeight, defaultAscent);
12738
+ for (let i = 0; i < tokens.length; i++) {
12739
+ if (tokens[i].isTab) {
12740
+ const tab = this.customComponents.tabs.find(x => x.instance.insertIndex === paragraph.startIndex + index + i);
12741
+ tab.instance.applySize(tokens[i].width);
12915
12742
  }
12916
- const { left, right, firstLine, hanging } = lineInfo.indent;
12917
- const indent = left + right + firstLine - hanging || 0;
12918
- const availableWidth = pageFormat.contentWidth - indent - wrapTokens[0].markerWidth;
12919
- const whitespaceDeficit = availableWidth - currentLineWidth;
12920
- if (spaceCount > 0 && whitespaceDeficit > 0) {
12921
- lineInfo.wordSpacing = whitespaceDeficit / spaceCount;
12922
- lineInfo.wordSpacingWidth = whitespaceDeficit;
12743
+ else if (tokens[i].isTable) {
12744
+ info.hasTable = true;
12923
12745
  }
12924
12746
  }
12925
- rowInfos.push(lineInfo);
12926
- if (!wrapLimit) {
12927
- break;
12747
+ rowInfos.push(info);
12748
+ index += last + 1;
12749
+ if (index < paragraphTokens.length) {
12750
+ splits.push(index);
12751
+ indent = new IndentModel(null, null, indent.left, indent.right, 0);
12928
12752
  }
12929
- index = wrapSplit;
12930
- const splitsLength = splits.length;
12931
- const splitIndex = splitsLength ? index + splits[splitsLength - 1] : index;
12932
- splits.push(splitIndex);
12933
- }
12934
- this.tabTokens.push(...strTokens.filter(x => x.isTab));
12935
- ParagraphHelper.applyParagraphIndentsToLines(rowInfos, paragraphIndex, model.paragraphs);
12753
+ } while (index < paragraphTokens.length);
12754
+ ParagraphHelper.applyParagraphIndentsToLines(rowInfos, paragraphIndex, this.model.paragraphs);
12936
12755
  return { splits, rowInfos };
12937
12756
  }
12938
- /**
12939
- * Given a string, returns an array of the display characters, including tabs and spaces and custom components.
12940
- */
12941
- getDisplayTokens(model, str, startIndex) {
12942
- if (!str.length) {
12943
- return this.getEmptyDisplayTokens(model, startIndex);
12944
- }
12945
- return this.fillLineTokens(startIndex, str, model);
12757
+ getParagraphTokens(paragraphInfo) {
12758
+ const paragraphSymbolIndex = paragraphInfo.startIndex + paragraphInfo.content.length;
12759
+ const { tokens, paragraphToken } = this.getTokens(paragraphInfo.startIndex, paragraphInfo.content, paragraphSymbolIndex);
12760
+ return { paragraphTokens: tokens, paragraphToken };
12761
+ }
12762
+ getParagraphLineTokens(paragraphIndex, lineIndex) {
12763
+ const paragraph = this.paragraphs[paragraphIndex];
12764
+ const lineStart = lineIndex > 0 ? paragraph.nextLineIndexes[lineIndex - 1] : 0;
12765
+ const lineEnd = paragraph.nextLineIndexes[lineIndex] ? paragraph.nextLineIndexes[lineIndex] : paragraph.content.length;
12766
+ const lineContent = paragraph.content.substring(lineStart, lineEnd);
12767
+ const paragraphSymbolIndex = paragraph.paragraphSettings.startInsertIndex + paragraph.content.length;
12768
+ const { tokens } = this.getTokens(lineStart + paragraph.startIndex, lineContent, paragraphSymbolIndex);
12769
+ const pageFormat = this.getPageFormatAtPosition(this.paragraphs[paragraphIndex].startIndex);
12770
+ const paragraphStyle = this.model.paragraphs[paragraphIndex].paragraphStyle;
12771
+ const lineInfo = paragraph.paragraphSettings.textLinesInfo[lineIndex];
12772
+ const maxWidth = pageFormat.contentWidth - lineInfo.indent.right - lineInfo.indent.markerWidth;
12773
+ const startWidth = lineInfo.indentLeft + lineInfo.indentFirstLine - lineInfo.indent.hanging || 0;
12774
+ this.computeWrapIndex(tokens, startWidth, maxWidth, paragraphStyle.tabSettings ?? []); // needed to proceed a tab width correction according to the tabs complex positioning
12775
+ const isLast = lineIndex === paragraph.nextLineIndexes.length;
12776
+ LineInfoHelper.get(tokens, false, isLast, paragraphStyle, lineInfo.indent, lineInfo.isNumbering, pageFormat.contentWidth, 0, 0); // needed to proceed a space width correction according to the wordSpacing in case of justify alignment
12777
+ return tokens;
12946
12778
  }
12947
- fillLineTokens(startIndex, line, model) {
12948
- const lineInfo = this.getLineInfoByBreakModifier(model, startIndex + line.length);
12779
+ getTokens(contentIndex, content, paragraphSymbolIndex) {
12949
12780
  const tokens = [];
12950
- let characters = [];
12951
- let format = FormatStyleHelper.getFormatAtIndex(model.formats, startIndex);
12952
- let prevFormat = null;
12953
- let prevCharCode = null;
12954
- let prevFontString = null;
12955
- let prevChar = null;
12956
- let fontString = ContentStyleHelper.getFontStylesString(format?.textStyle);
12957
- let symbolChange = false;
12958
- for (let i = 0; i < line.length; i++) {
12959
- const char = line[i];
12960
- const size = FontMetrics.measureCharSize(char, fontString);
12961
- const customComponent = this.getOrGenerateComponent(startIndex, char);
12962
- const breakType = BreakHelper.getBreakType(model, char, startIndex);
12963
- if (customComponent && !breakType) {
12964
- const token = this.customContentService.getTokenFromComponent(customComponent, lineInfo, DisplayValue.customContent, i === 0, size);
12965
- tokens.push(token);
12966
- prevCharCode = -1;
12967
- prevChar = '';
12968
- characters = [];
12969
- }
12970
- else {
12971
- const charCode = char.charCodeAt(0);
12972
- const displayValue = DisplayTokenHelper.getDisplayValue(charCode);
12973
- const isFirstCharacter = i === 0;
12974
- const token = new DisplayToken({
12975
- ...size,
12976
- displayValue,
12977
- align: lineInfo.align,
12978
- indentFirstLine: isFirstCharacter ? lineInfo.indent.firstLine : DEFAULT_PARAGRAPH_STYLE.indentFirstLine,
12979
- indentHanging: isFirstCharacter && !lineInfo.isNumbering ? lineInfo.indent.hanging : DEFAULT_PARAGRAPH_STYLE.indentHanging,
12980
- indentLeft: lineInfo.indent.left,
12981
- indentRight: lineInfo.indent.right,
12982
- indentBefore: lineInfo.offsetBefore,
12983
- indentAfter: lineInfo.offsetAfter,
12984
- lineSpacing: lineInfo.lineSpacing,
12985
- markerWidth: isFirstCharacter && lineInfo.isNumbering ? lineInfo.markerWidth : 0,
12986
- isNumbering: lineInfo.isNumbering,
12987
- isPageBreak: breakType === BreakTypes.Page,
12988
- isLineBreak: breakType === BreakTypes.TextWrapping,
12989
- isTab: false
12990
- });
12991
- tokens.push(token);
12992
- if (charCode !== prevCharCode ||
12993
- !prevFormat ||
12994
- !ContentStyleHelper.areSameTextStyles(format?.textStyle, prevFormat?.textStyle)) {
12995
- symbolChange = true;
12996
- }
12997
- else if (i === line.length - 1) {
12998
- characters.push(token);
12999
- symbolChange = true;
13000
- }
13001
- else {
13002
- characters.push(token);
13003
- }
13004
- if (characters.length > 1 && symbolChange) {
13005
- this.processCharSizes(prevChar, prevFontString, characters);
13006
- characters = [token];
13007
- symbolChange = false;
13008
- }
13009
- else if (symbolChange) {
13010
- characters = [token];
13011
- }
13012
- prevCharCode = charCode;
13013
- prevChar = char;
13014
- }
13015
- prevFormat = format;
13016
- prevFontString = fontString;
13017
- startIndex++;
13018
- if (startIndex > format?.endIndex) {
13019
- format = FormatStyleHelper.getFormatAtIndex(model.formats, startIndex);
13020
- fontString = ContentStyleHelper.getFontStylesString(format?.textStyle);
13021
- }
13022
- }
13023
- return tokens;
12781
+ const prev = { char: '', style: null, size: null };
12782
+ let format = FormatStyleHelper.getFormatAtIndex(this.model.formats, contentIndex);
12783
+ let fontString = ContentStyleHelper.getFontStylesString(format.textStyle);
12784
+ for (let i = 0; i < content.length; i++) {
12785
+ if (content[i] !== prev.char || !prev.style || !ContentStyleHelper.areSameTextStyles(format.textStyle, prev.style)) {
12786
+ prev.size = FontMetrics.measureCharSize(content[i], fontString);
12787
+ prev.char = content[i];
12788
+ prev.style = format.textStyle;
12789
+ }
12790
+ const customComponent = this.getOrGenerateComponent(contentIndex, content[i]);
12791
+ const breakType = BreakHelper.getBreakType(this.model.breaks, content[i], contentIndex);
12792
+ const token = customComponent && !breakType
12793
+ ? DisplayTokenHelper.getComponentToken(customComponent, prev.size)
12794
+ : DisplayTokenHelper.getSymbolToken(content.charCodeAt(i), prev.size, breakType);
12795
+ contentIndex++;
12796
+ if (contentIndex > format.endIndex) {
12797
+ format = FormatStyleHelper.getFormatAtIndex(this.model.formats, contentIndex);
12798
+ fontString = ContentStyleHelper.getFontStylesString(format.textStyle);
12799
+ }
12800
+ tokens.push(token);
12801
+ }
12802
+ const paragraphFormat = FormatStyleHelper.getFormatAtIndex(this.model.formats, paragraphSymbolIndex);
12803
+ const paragraphToken = DisplayTokenHelper.getParagraphToken(paragraphFormat.textStyle);
12804
+ return tokens.length ? { tokens, paragraphToken } : { tokens: [paragraphToken], paragraphToken };
13024
12805
  }
13025
12806
  getOrGenerateComponent(charIndex, char) {
13026
12807
  if (!this.customContentService.isSpecialMarker(char)) {
@@ -13036,12 +12817,6 @@ class DisplayData extends EventEmitting {
13036
12817
  const pageFormat = this.getPageFormatAtPosition(charIndex);
13037
12818
  return this.customContentService.generateComponent(this.model, this.customComponents, this.sessionId, this.generalProperties, pageFormat.contentWidth, charIndex);
13038
12819
  }
13039
- processCharSizes(prevChar, prevFontString, characters) {
13040
- const newSize = FontMetrics.measureCharSize(prevChar, prevFontString);
13041
- for (let item of characters) {
13042
- Object.assign(item, newSize);
13043
- }
13044
- }
13045
12820
  getPageFormatParagraphs(pageFormatIndex) {
13046
12821
  if (pageFormatIndex === this.pagesFormat.length - 1) {
13047
12822
  return this.paragraphs.filter(x => x.startIndex >= this.pagesFormat[pageFormatIndex].pageFormatModel.insertIndex);
@@ -13072,303 +12847,65 @@ class DisplayData extends EventEmitting {
13072
12847
  }
13073
12848
  return -1;
13074
12849
  }
13075
- getLineTokens(model, line, startIndex) {
13076
- const lineInfo = this.getLineInfoFromTextLine(startIndex + line.length);
13077
- if (!line.length) {
13078
- return this.getEmptyLineTokens(model, startIndex, lineInfo);
13079
- }
13080
- const tokens = [];
13081
- let characters = [];
13082
- let format = FormatStyleHelper.getFormatAtIndex(model.formats, startIndex);
13083
- let prevFormat = null;
13084
- let prevCharCode = null;
13085
- let prevFontString = null;
13086
- let prevChar = null;
13087
- let fontString = ContentStyleHelper.getFontStylesString(format?.textStyle);
13088
- let symbolChange = false;
13089
- for (let i = 0; i < line.length; i++) {
13090
- const char = line[i];
13091
- const size = FontMetrics.measureCharSize(char, fontString);
13092
- const customComponent = this.customContentService.getComponent(this.customComponents, char, startIndex);
13093
- const breakType = BreakHelper.getBreakType(model, char, startIndex);
13094
- if (customComponent && !breakType) {
13095
- const token = this.customContentService.getTokenFromComponent(customComponent, lineInfo, DisplayValue.customContent, i === 0, size);
13096
- tokens.push(token);
13097
- prevCharCode = -1;
13098
- prevChar = '';
13099
- characters = [];
12850
+ // The index of a token which should be the last on the line
12851
+ computeWrapIndex(displayTokens, startWidth, maxWidth, tabSettings) {
12852
+ let width = startWidth;
12853
+ let lastBreakable = -1;
12854
+ const lastTab = { token: null, alignment: TabAlignment.Left, usedWidth: 0, tokenWidth: 0 };
12855
+ for (let i = 0; i < displayTokens.length; i++) {
12856
+ const token = displayTokens[i];
12857
+ if (token.breaksLine) {
12858
+ return i;
13100
12859
  }
13101
- else {
13102
- const charCode = char.charCodeAt(0);
13103
- const displayValue = DisplayTokenHelper.getDisplayValue(charCode);
13104
- const isFirstCharacter = i === 0;
13105
- const token = new DisplayToken({
13106
- ...size,
13107
- displayValue,
13108
- align: lineInfo.align,
13109
- indentFirstLine: isFirstCharacter ? lineInfo.indent.firstLine : DEFAULT_PARAGRAPH_STYLE.indentFirstLine,
13110
- indentHanging: isFirstCharacter && !lineInfo.isNumbering ? lineInfo.indent.hanging : DEFAULT_PARAGRAPH_STYLE.indentHanging,
13111
- indentLeft: lineInfo.indent.left,
13112
- indentRight: lineInfo.indent.right,
13113
- indentBefore: lineInfo.offsetBefore,
13114
- indentAfter: lineInfo.offsetAfter,
13115
- lineSpacing: lineInfo.lineSpacing,
13116
- markerWidth: isFirstCharacter && lineInfo.isNumbering ? lineInfo.markerWidth : 0,
13117
- isPageBreak: breakType === BreakTypes.Page,
13118
- isLineBreak: breakType === BreakTypes.TextWrapping,
13119
- isTab: false,
13120
- isNumbering: lineInfo.isNumbering
13121
- });
13122
- tokens.push(token);
13123
- if (charCode !== prevCharCode ||
13124
- !prevFormat ||
13125
- !ContentStyleHelper.areSameTextStyles(format?.textStyle, prevFormat?.textStyle)) {
13126
- symbolChange = true;
12860
+ if (token.isTable) {
12861
+ return i > 0 ? i - 1 : 0;
12862
+ }
12863
+ width += this.adjustLastTab(token, width, lastTab, tabSettings);
12864
+ if (width > maxWidth && !token.isParagraph) {
12865
+ if (i > 0) {
12866
+ i--;
13127
12867
  }
13128
- else if (i === line.length - 1) {
13129
- characters.push(token);
13130
- symbolChange = true;
12868
+ while (i + 1 < displayTokens.length && displayTokens[i + 1].isWhiteSpace) {
12869
+ i++;
13131
12870
  }
13132
- else {
13133
- characters.push(token);
12871
+ if (displayTokens[i].isTab) {
12872
+ return i > 0 ? i - 1 : 0;
13134
12873
  }
13135
- if (characters.length > 1 && symbolChange) {
13136
- this.processCharSizes(prevChar, prevFontString, characters);
13137
- characters = [token];
13138
- symbolChange = false;
12874
+ const breakable = displayTokens[i].breakable && !displayTokens[i].isTab;
12875
+ if (i + 1 === displayTokens.length || breakable || displayTokens[i + 1].breakable || lastBreakable === -1) {
12876
+ return i;
13139
12877
  }
13140
- else if (symbolChange) {
13141
- characters = [token];
12878
+ if (displayTokens[lastBreakable].isTab) {
12879
+ return lastBreakable > 0 ? lastBreakable - 1 : i;
13142
12880
  }
13143
- prevCharCode = charCode;
13144
- prevChar = char;
13145
- }
13146
- prevFormat = format;
13147
- prevFontString = fontString;
13148
- startIndex++;
13149
- if (startIndex > format?.endIndex) {
13150
- format = FormatStyleHelper.getFormatAtIndex(model.formats, startIndex);
13151
- fontString = ContentStyleHelper.getFontStylesString(format?.textStyle);
12881
+ return lastBreakable;
13152
12882
  }
13153
- }
13154
- return tokens;
13155
- }
13156
- findSameNumberingIndex(index) {
13157
- let sameNumberingIndex = index;
13158
- if (this.getParagraphSettings(index)?.numberingData.numberingId) {
13159
- while (sameNumberingIndex >= 0 &&
13160
- this.model.paragraphs[sameNumberingIndex].paragraphStyle.numberingId !==
13161
- this.getParagraphSettings(index)?.numberingData.numberingId) {
13162
- sameNumberingIndex--;
13163
- }
13164
- }
13165
- else if (this.model.paragraphs[index].paragraphStyle.numberingId) {
13166
- while (sameNumberingIndex < this.paragraphs.length &&
13167
- this.model.paragraphs[index].paragraphStyle.numberingId !==
13168
- this.getParagraphSettings(sameNumberingIndex)?.numberingData.numberingId) {
13169
- sameNumberingIndex++;
13170
- }
13171
- }
13172
- return sameNumberingIndex;
13173
- }
13174
- getEmptyDisplayTokens(model, startIndex) {
13175
- const lineInfo = this.getLineInfoByBreakModifier(model, startIndex);
13176
- return this.getEmptyLineTokens(model, startIndex, lineInfo);
13177
- }
13178
- getEmptyLineTokens(model, startIndex, lineInfo) {
13179
- const storedFormat = FormatStyleHelper.getFormatAtIndex(model.formats, startIndex);
13180
- if (!storedFormat) {
13181
- return [];
13182
- }
13183
- const size = FontMetrics.measureCharSize('EMPTY_LINE', ContentStyleHelper.getFontStylesString(storedFormat.textStyle));
13184
- size.width = 3;
13185
- return [
13186
- new DisplayToken({
13187
- ...size,
13188
- displayValue: DisplayValue.emptyLine,
13189
- align: lineInfo.align,
13190
- indentFirstLine: lineInfo.indent.firstLine,
13191
- indentHanging: lineInfo.isNumbering ? 0 : lineInfo.indent.hanging,
13192
- indentLeft: lineInfo.indent.left,
13193
- indentRight: lineInfo.indent.right,
13194
- indentBefore: lineInfo.offsetBefore,
13195
- indentAfter: lineInfo.offsetAfter,
13196
- markerWidth: lineInfo.markerWidth,
13197
- isNumbering: lineInfo.isNumbering,
13198
- isPageBreak: false,
13199
- isLineBreak: false,
13200
- isTab: false,
13201
- lineSpacing: lineInfo.lineSpacing
13202
- })
13203
- ];
13204
- }
13205
- getLineInfoByBreakModifier(model, index) {
13206
- const paragraph = ParagraphStyleHelper.getParagraphAtIndex(model.paragraphs, index);
13207
- if (!paragraph) {
13208
- return new LineInfoModel({
13209
- align: DEFAULT_PARAGRAPH_STYLE.alignment,
13210
- indent: new IndentModel(DEFAULT_PARAGRAPH_STYLE.indentFirstLine, DEFAULT_PARAGRAPH_STYLE.indentHanging, DEFAULT_PARAGRAPH_STYLE.indentLeft, DEFAULT_PARAGRAPH_STYLE.indentRight),
13211
- offsetBefore: DEFAULT_PARAGRAPH_STYLE.spaceBefore,
13212
- offsetAfter: DEFAULT_PARAGRAPH_STYLE.spaceAfter,
13213
- lineSpacing: DEFAULT_PARAGRAPH_STYLE.lineSpacing
13214
- });
13215
- }
13216
- const { indent, markerWidth } = this.getParagraphIndentLeft(model, paragraph);
13217
- return this.getLineInfoModel(paragraph, indent, markerWidth);
13218
- }
13219
- getParagraphIndentLeft(model, paragraph) {
13220
- const numberingId = paragraph.paragraphStyle.numberingId;
13221
- if (numberingId === null) {
13222
- return {
13223
- indent: new IndentModel(paragraph.paragraphStyle.indentFirstLine ?? DEFAULT_PARAGRAPH_STYLE.indentFirstLine, paragraph.paragraphStyle.indentHanging ?? DEFAULT_PARAGRAPH_STYLE.indentHanging, paragraph.paragraphStyle.indentLeft ?? DEFAULT_PARAGRAPH_STYLE.indentLeft, paragraph.paragraphStyle.indentRight ?? DEFAULT_PARAGRAPH_STYLE.indentRight),
13224
- markerWidth: 0
13225
- };
13226
- }
13227
- const level = paragraph.paragraphStyle.numberingLevel;
13228
- const paragraphIndex = model.paragraphs.indexOf(paragraph);
13229
- const levelModel = NumberingHelper.find(this.generalProperties.numberings, numberingId, level);
13230
- const paragraphFormat = FormatStyleHelper.getFormatAtIndex(model.formats, paragraph.insertIndex);
13231
- const markerTextStyle = ContentStyleHelper.combineTextStyles(levelModel.markerStyle, paragraphFormat.textStyle);
13232
- const paragraphSettings = this.getParagraphSettings(paragraphIndex);
13233
- let markerWidth = paragraphSettings?.numberingData?.width;
13234
- const marker = NumberingHelper.getMarker(levelModel, numberingId, model.paragraphs, paragraphIndex, this.generalProperties.numberingInfo);
13235
- const markerSizes = NumberingHelper.getMarkerSizes(marker, markerTextStyle);
13236
- markerWidth = markerSizes.width;
13237
- let indentHanging = levelModel.indentHanging;
13238
- let indentFirstLine = DEFAULT_PARAGRAPH_STYLE.indentFirstLine;
13239
- if (paragraph.paragraphStyle.indentFirstLine !== null || paragraph.paragraphStyle.indentHanging !== null) {
13240
- if (paragraph.paragraphStyle.indentFirstLine !== null) {
13241
- indentFirstLine = paragraph.paragraphStyle.indentFirstLine;
13242
- indentHanging = null;
13243
- }
13244
- else {
13245
- indentHanging =
13246
- paragraph.paragraphStyle.indentHanging !== null ? paragraph.paragraphStyle.indentHanging : levelModel.indentHanging;
13247
- }
13248
- }
13249
- const indent = new IndentModel(indentFirstLine, indentHanging, paragraph.paragraphStyle.indentLeft !== null ? paragraph.paragraphStyle.indentLeft : levelModel.indentLeft, paragraph.paragraphStyle.indentRight ?? DEFAULT_PARAGRAPH_STYLE.indentRight);
13250
- return { indent, markerWidth: markerWidth + markerWidth / marker.length };
13251
- }
13252
- getLineInfoFromTextLine(index) {
13253
- const paragraph = ParagraphStyleHelper.getParagraphAtIndex(this.model.paragraphs, index);
13254
- const indentLeft = this.getIndentLeftFromTextLine(index);
13255
- const indent = new IndentModel(paragraph.paragraphStyle.indentFirstLine ?? DEFAULT_PARAGRAPH_STYLE.indentFirstLine, paragraph.paragraphStyle.indentHanging ?? DEFAULT_PARAGRAPH_STYLE.indentHanging, indentLeft ?? DEFAULT_PARAGRAPH_STYLE.indentLeft, paragraph.paragraphStyle.indentRight ?? DEFAULT_PARAGRAPH_STYLE.indentRight);
13256
- return this.getLineInfoModel(paragraph, indent, 0);
13257
- }
13258
- getLineInfoModel(paragraph, indent, markerWidth) {
13259
- return new LineInfoModel({
13260
- align: paragraph.paragraphStyle.alignment ?? DEFAULT_PARAGRAPH_STYLE.alignment,
13261
- indent,
13262
- offsetBefore: DEFAULT_PARAGRAPH_STYLE.spaceBefore,
13263
- offsetAfter: DEFAULT_PARAGRAPH_STYLE.spaceAfter,
13264
- lineSpacing: paragraph.paragraphStyle.lineSpacing ?? DEFAULT_PARAGRAPH_STYLE.lineSpacing,
13265
- isNumbering: !!markerWidth,
13266
- markerWidth
13267
- });
13268
- }
13269
- getIndentLeftFromTextLine(insertIndex) {
13270
- let startIndex = 0;
13271
- let endIndex = this.paragraphs.length - 1;
13272
- while (startIndex <= endIndex) {
13273
- const middleIndex = Math.round((startIndex + endIndex) / 2);
13274
- const paragraphInfo = this.paragraphs[middleIndex];
13275
- if (paragraphInfo.startIndex > insertIndex) {
13276
- startIndex = middleIndex + 1;
13277
- }
13278
- else {
13279
- endIndex = middleIndex - 1;
13280
- }
13281
- }
13282
- const textLinesInfo = this.paragraphs[startIndex]?.paragraphSettings.textLinesInfo;
13283
- return textLinesInfo ? Math.max(...textLinesInfo.map(x => x.indentLeft)) : null;
13284
- }
13285
- computeWrapSplit(tokens, wrapLimit) {
13286
- if (!tokens.length || tokens.length <= wrapLimit) {
13287
- return null;
13288
- }
13289
- // If there is a space or tab at this split position, then making
13290
- // a split is simple.
13291
- if (wrapLimit === 0 ||
13292
- tokens[wrapLimit].displayValue === DisplayValue.customContent ||
13293
- (this.isWhiteSpace(tokens[wrapLimit - 1]) && this.isWhiteSpace(tokens[wrapLimit]))) {
13294
- return wrapLimit;
13295
- }
13296
- return this.calculateSplit(wrapLimit, tokens);
13297
- }
13298
- calculateSplit(index, tokens) {
13299
- for (let i = index; i >= 0; i--) {
13300
- if (this.isWhiteSpace(tokens[i]) || tokens[i].displayValue === DisplayValue.customContent) {
13301
- return i + 1;
12883
+ if (token.breakable) {
12884
+ lastBreakable = i;
13302
12885
  }
13303
12886
  }
13304
- return index;
13305
- }
13306
- isWhiteSpace(token) {
13307
- return [DisplayValue.space, DisplayValue.emptyLine].includes(token.displayValue);
12887
+ return displayTokens.length - 1;
13308
12888
  }
13309
- /**
13310
- * Computes wrap index based on max row width
13311
- */
13312
- computeWrapIndex(displayTokens, contentWidth, defaultTabWidth, tabSettings) {
13313
- if (!displayTokens[0]) {
13314
- return 0;
12889
+ adjustLastTab(token, position, tab, tabSettings) {
12890
+ if (token.isTab) {
12891
+ tab.token = token;
12892
+ const setting = tabSettings.find(x => x.position > position);
12893
+ const defaultTabWidth = this.generalProperties.defaultTabWidth;
12894
+ tab.token.width = setting ? setting.position - position : defaultTabWidth - (position % defaultTabWidth);
12895
+ tab.alignment = setting?.alignment ?? TabAlignment.Left;
12896
+ return token.width;
13315
12897
  }
13316
- if (displayTokens[0].isTable || (displayTokens[0].breaksLine && displayTokens.length === 1)) {
13317
- return 1;
12898
+ else if (tab.alignment === TabAlignment.Center && tab.token.width > 0) {
12899
+ const width = tab.token.width > token.width / 2 ? token.width / 2 : token.width - tab.token.width;
12900
+ tab.token.width -= tab.token.width > width ? width : tab.token.width;
12901
+ return width;
13318
12902
  }
13319
- const maxRowWidth = contentWidth - displayTokens[0].indentRight - displayTokens[0].markerWidth;
13320
- let sum = displayTokens[0].indentLeft + displayTokens[0].indentFirstLine - displayTokens[0].indentHanging || 0;
13321
- let prevTabIndex = null;
13322
- let tabCenter = null;
13323
- let prevTabAlignment = TabAlignment.Left;
13324
- for (let i = 0; i < displayTokens.length; i++) {
13325
- const token = displayTokens[i];
13326
- const prevToken = i > 0 ? displayTokens[i - 1] : null;
13327
- if (token.isTab) {
13328
- const tabs = tabSettings ?? [];
13329
- const nextSettingIndex = tabs.findIndex(x => x.position > sum);
13330
- const tokenWidth = TabHelper.calculateTabWidth(sum, defaultTabWidth, tabSettings);
13331
- if (nextSettingIndex >= 0 && tabs[nextSettingIndex].alignment === TabAlignment.Center) {
13332
- prevTabAlignment = TabAlignment.Center;
13333
- tabCenter = { stringWidth: 0, tokenWidth };
13334
- token.width = tokenWidth;
13335
- }
13336
- else {
13337
- prevTabAlignment = nextSettingIndex >= 0 ? tabs[nextSettingIndex].alignment : TabAlignment.Left;
13338
- token.width = tokenWidth;
13339
- tabCenter = null;
13340
- }
13341
- prevTabIndex = i;
13342
- }
13343
- if (prevTabAlignment === TabAlignment.Center && !token.isTab && tabCenter.stringWidth < tabCenter.tokenWidth) {
13344
- const tokenWidth = token.width / 2;
13345
- displayTokens[prevTabIndex].width -= tokenWidth;
13346
- tabCenter.stringWidth += tokenWidth;
13347
- sum += tokenWidth;
13348
- }
13349
- else if (prevTabAlignment === TabAlignment.Right && !token.isTab && displayTokens[prevTabIndex].width !== 0) {
13350
- if (displayTokens[prevTabIndex].width - token.width < 0) {
13351
- sum += token.width - displayTokens[prevTabIndex].width;
13352
- displayTokens[prevTabIndex].width = 0;
13353
- }
13354
- else {
13355
- displayTokens[prevTabIndex].width -= token.width;
13356
- }
13357
- }
13358
- else {
13359
- sum += token.width;
13360
- }
13361
- if (sum >= maxRowWidth) {
13362
- return i > 0 ? i - 1 : 0;
13363
- }
13364
- if (prevToken?.breaksLine || token.isTable) {
13365
- return i;
13366
- }
13367
- if (token.isLineBreak || (i === displayTokens.length - 1 && token.isPageBreak)) {
13368
- return i + 1;
13369
- }
12903
+ else if (tab.alignment === TabAlignment.Right && tab.token.width > 0) {
12904
+ const width = tab.token.width > token.width ? token.width : tab.token.width;
12905
+ tab.token.width -= tab.token.width > width ? width : tab.token.width;
12906
+ return token.width - width;
13370
12907
  }
13371
- return 0;
12908
+ return token.width;
13372
12909
  }
13373
12910
  getPreviousParagraphInfo(row) {
13374
12911
  if (!row || !this.paragraphs.length) {
@@ -14151,28 +13688,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
14151
13688
  args: [{ selector: 'app-nod-image', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<app-nod-resizer\n *ngIf=\"isFocused\"\n class=\"resizer\"\n [isDisabled]=\"isViewOnly$ | async\"\n [size]=\"size\"\n (resizeEnd)=\"onResizeEnd($event)\" />\n", styles: [":host{position:relative;outline:none}.resizer{position:absolute;z-index:1}\n"] }]
14152
13689
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: ImageApiService }] });
14153
13690
 
14154
- class NoderTabComponent extends BaseNoderComponent {
14155
- get tab() {
14156
- return this.content;
14157
- }
14158
- set tab(val) {
14159
- this.content = val;
13691
+ class ParagraphStyleHelper {
13692
+ static getParagraphsAtRange(paragraphs, startIndex, endIndex) {
13693
+ let firstModifierIndexInRange = paragraphs.findIndex(paragraph => paragraph.insertIndex >= startIndex);
13694
+ firstModifierIndexInRange = firstModifierIndexInRange === -1 ? paragraphs.length : firstModifierIndexInRange;
13695
+ let lastModifierIndexInRange = paragraphs.findIndex(x => x.insertIndex >= endIndex);
13696
+ lastModifierIndexInRange =
13697
+ startIndex === endIndex || lastModifierIndexInRange === -1 ? firstModifierIndexInRange : lastModifierIndexInRange;
13698
+ return paragraphs.slice(firstModifierIndexInRange, lastModifierIndexInRange + 1);
14160
13699
  }
14161
- initialize() {
14162
- this.applySize(this.tab.width);
13700
+ static getParagraphAtIndex(paragraphs, insertIndex) {
13701
+ let startIndex = 0;
13702
+ let endIndex = paragraphs.length - 1;
13703
+ while (startIndex <= endIndex) {
13704
+ const middleIndex = Math.round((startIndex + endIndex) / 2);
13705
+ const paragraph = paragraphs[middleIndex];
13706
+ if (paragraph.insertIndex < insertIndex) {
13707
+ startIndex = middleIndex + 1;
13708
+ }
13709
+ else {
13710
+ endIndex = middleIndex - 1;
13711
+ }
13712
+ }
13713
+ return paragraphs[startIndex];
14163
13714
  }
14164
- applySize(width) {
14165
- this.width.set(ScalingHelper.scale(width, this.generalProperties.scalingRatio));
13715
+ static isEndOfParagraph(paragraphs, endIndex) {
13716
+ const paragraph = this.getParagraphAtIndex(paragraphs, endIndex);
13717
+ let paragraphIndex = paragraphs.findIndex(x => x === paragraph);
13718
+ const endOfParagraphIsParagraph = paragraph && endIndex === paragraph.insertIndex && paragraphs.length - 1 > paragraphIndex;
13719
+ if (endOfParagraphIsParagraph) {
13720
+ paragraphIndex += 1;
13721
+ }
13722
+ return paragraphs[paragraphIndex].insertIndex === endIndex + 1;
14166
13723
  }
14167
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NoderTabComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
14168
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: NoderTabComponent, isStandalone: false, selector: "app-nod-tab", host: { properties: { "style.width.px": "width()" } }, usesInheritance: true, ngImport: i0, template: "&emsp;\n", styles: [":host{position:relative;outline:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
14169
13724
  }
14170
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NoderTabComponent, decorators: [{
14171
- type: Component,
14172
- args: [{ selector: 'app-nod-tab', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, host: {
14173
- '[style.width.px]': 'width()'
14174
- }, template: "&emsp;\n", styles: [":host{position:relative;outline:none}\n"] }]
14175
- }] });
14176
13725
 
14177
13726
  const CHARS = [
14178
13727
  // eslint-disable-next-line prettier/prettier
@@ -14377,7 +13926,6 @@ class EditSession {
14377
13926
  const endParagraph = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, endIndex).row;
14378
13927
  OperationsHelper.applyTextStyle(this.model, startIndex, endIndex, textStyle);
14379
13928
  this.provideTextStyle(startIndex, endIndex);
14380
- this.displayData.resetAllNumberingInfo(startParagraph);
14381
13929
  this.displayData.updateNextLineIndexes(startParagraph, endParagraph);
14382
13930
  this.setTextStyle(textStyle);
14383
13931
  }
@@ -14390,36 +13938,25 @@ class EditSession {
14390
13938
  startParagraph = this.displayData.paragraphs.findIndex(x => x.paragraphSettings.numberingData.numberingId === numberingId);
14391
13939
  endParagraph = this.displayData.paragraphs.findLastIndex(x => x.paragraphSettings.numberingData.numberingId === numberingId);
14392
13940
  }
14393
- this.displayData.resetAllNumberingInfo(startParagraph);
14394
13941
  this.displayData.updateNextLineIndexes(startParagraph, endParagraph);
14395
13942
  this.applyToolbarStyles();
14396
13943
  }
14397
13944
  rerender(insertIndex) {
14398
13945
  const paragraphIndex = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, insertIndex).row;
14399
- this.displayData.resetAllNumberingInfo(paragraphIndex);
14400
13946
  this.displayData.updateNextLineIndexes(paragraphIndex, paragraphIndex);
14401
13947
  }
14402
13948
  addNumbering(levels, startIndex, endIndex, numberingId) {
14403
13949
  const startParagraph = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, startIndex).row;
14404
13950
  const endParagraph = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, endIndex).row;
14405
13951
  OperationsHelper.addNumbering(this.model, this.generalProperties.numberings, startIndex, endIndex, levels, numberingId);
14406
- this.generalProperties.numberingInfo = {};
14407
13952
  this.displayData.updateNextLineIndexes(startParagraph, endParagraph);
14408
- for (let i = startParagraph; i <= endParagraph; i++) {
14409
- if (this.displayData.getParagraphSettings(i).numberingData.numberingId !== null) {
14410
- this.displayData.updateNumberingsDataOnChange(endParagraph + 1);
14411
- break;
14412
- }
14413
- }
14414
13953
  this.applyToolbarStyles();
14415
13954
  }
14416
13955
  removeNumberings(startIndex, endIndex) {
14417
13956
  const startParagraph = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, startIndex).row;
14418
13957
  const endParagraph = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, endIndex).row;
14419
- this.displayData.resetAllNumberingInfo(startParagraph);
14420
13958
  OperationsHelper.removeNumberings(this.model, this.generalProperties.numberings, startIndex, endIndex);
14421
13959
  this.displayData.updateNextLineIndexes(startParagraph, endParagraph);
14422
- this.displayData.updateNumberingsDataOnChange(endParagraph);
14423
13960
  this.applyToolbarStyles();
14424
13961
  }
14425
13962
  restoreNumberings(paragraphs, numberings) {
@@ -14427,15 +13964,8 @@ class EditSession {
14427
13964
  const endIndex = paragraphs[paragraphs.length - 1].insertIndex;
14428
13965
  const startParagraph = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, startIndex).row;
14429
13966
  const endPosition = ContentHelper.documentIndexToParagraphWithOffset(this.displayData.paragraphs, endIndex);
14430
- this.displayData.resetAllNumberingInfo(startParagraph);
14431
13967
  OperationsHelper.restoreNumberings(this.model, this.generalProperties.numberings, paragraphs, numberings);
14432
13968
  this.displayData.updateNextLineIndexes(startParagraph, endPosition.row);
14433
- for (const paragraph of paragraphs) {
14434
- if (paragraph.paragraphStyle.numberingId !== null) {
14435
- this.displayData.updateNumberingsDataOnChange(endPosition.row + 1);
14436
- break;
14437
- }
14438
- }
14439
13969
  this.selection.placeCursor(endPosition);
14440
13970
  this.applyToolbarStyles();
14441
13971
  }
@@ -14444,7 +13974,6 @@ class EditSession {
14444
13974
  imageComponentRef.instance.resize({ width: applyImage.width, height: applyImage.height });
14445
13975
  OperationsHelper.applyImageStyle(this.model, applyImage);
14446
13976
  const start = this.displayData.indexToPosition(applyImage.insertIndex, 0);
14447
- this.displayData.resetAllNumberingInfo(start.row);
14448
13977
  this.displayData.updateNextLineIndexes(start.row, this.displayData.paragraphs.length - 1);
14449
13978
  }
14450
13979
  restoreTextStyles(formats, linkFormats) {
@@ -14454,7 +13983,6 @@ class EditSession {
14454
13983
  const endPosition = ContentHelper.documentIndexToParagraphWithOffset(this.displayData.paragraphs, endIndex);
14455
13984
  OperationsHelper.restoreTextStyles(this.model, formats, linkFormats);
14456
13985
  this.provideTextStyle(startIndex, endIndex);
14457
- this.displayData.resetAllNumberingInfo(startParagraph);
14458
13986
  this.displayData.updateNextLineIndexes(startParagraph, endPosition.row);
14459
13987
  this.selection.placeCursor(endPosition);
14460
13988
  this.applyToolbarStyles();
@@ -14465,7 +13993,6 @@ class EditSession {
14465
13993
  const startParagraph = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, startIndex).row;
14466
13994
  const endPosition = ContentHelper.documentIndexToParagraphWithOffset(this.displayData.paragraphs, endIndex);
14467
13995
  OperationsHelper.restoreParagraphStyles(this.model, paragraphs);
14468
- this.displayData.resetAllNumberingInfo(0);
14469
13996
  this.displayData.updateNextLineIndexes(startParagraph, endPosition.row);
14470
13997
  this.selection.placeCursor(endPosition);
14471
13998
  this.applyToolbarStyles();
@@ -14476,7 +14003,6 @@ class EditSession {
14476
14003
  const startParagraph = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, startIndex).row;
14477
14004
  const endParagraph = ContentHelper.documentIndexToParagraphWithOffset(this.displayData.paragraphs, endIndex).row;
14478
14005
  OperationsHelper.applyParagraphs(this.model, paragraphs);
14479
- this.displayData.resetAllNumberingInfo(startParagraph);
14480
14006
  this.displayData.updateNextLineIndexes(startParagraph, endParagraph);
14481
14007
  this.applyToolbarStyles();
14482
14008
  }
@@ -14496,11 +14022,7 @@ class EditSession {
14496
14022
  CustomComponentHelper.applyRemovingComponents(this.customComponents.tabs, partIndexes.startIndex, partIndexes.endIndex);
14497
14023
  OperationsHelper.delete(this.model, partIndexes.startIndex, partIndexes.endIndex - partIndexes.startIndex + 1);
14498
14024
  this.selection.placeCursor(range.start);
14499
- this.displayData.resetAllNumberingInfo(range.start.row);
14500
14025
  this.displayData.updateNextLineIndexes(range.start.row, range.start.row);
14501
- if (range.end.row - range.start.row && this.type !== 'cell') {
14502
- this.displayData.updateNumberingsDataOnChange(range.start.row + 1);
14503
- }
14504
14026
  this.applyToolbarStyles();
14505
14027
  }
14506
14028
  replace(model) {
@@ -14562,11 +14084,7 @@ class EditSession {
14562
14084
  OperationsHelper.insertText(this.model, text, insertIndex);
14563
14085
  }
14564
14086
  const endPosition = this.displayData.insertText(position, text);
14565
- this.displayData.resetAllNumberingInfo(position.row);
14566
14087
  this.displayData.updateNextLineIndexes(position.row, endPosition.row);
14567
- if (endPosition.row - position.row && this.type !== 'cell') {
14568
- this.displayData.updateNumberingsDataOnChange(endPosition.row + 1);
14569
- }
14570
14088
  this.selection.placeCursor(endPosition);
14571
14089
  return endPosition;
14572
14090
  }
@@ -14589,7 +14107,6 @@ class EditSession {
14589
14107
  const model = this.model.elements.find(x => x.insertIndex === insertIndex);
14590
14108
  const type = this.customContentService.findComponentType(model.type);
14591
14109
  this.addComponent(this.customComponents.customElements, model, type);
14592
- this.displayData.resetAllNumberingInfo(position.row);
14593
14110
  this.displayData.updateNextLineIndexes(position.row, endPosition.row);
14594
14111
  this.selection.placeCursor(endPosition);
14595
14112
  return endPosition;
@@ -14597,15 +14114,11 @@ class EditSession {
14597
14114
  insertBreak(position, breakType) {
14598
14115
  const insertIndex = ContentHelper.paragraphPositionToDocumentIndex(this.displayData.paragraphs, position);
14599
14116
  const isOnNewParagraph = breakType === BreakTypes.Page &&
14600
- BreakHelper.getBreakType(this.model, CUSTOM_ELEMENT_MARKER, insertIndex - 1) !== BreakTypes.Page;
14117
+ BreakHelper.getBreakType(this.model.breaks, CUSTOM_ELEMENT_MARKER, insertIndex - 1) !== BreakTypes.Page;
14601
14118
  const text = isOnNewParagraph ? `${NEW_LINE_MARKUP}${CUSTOM_ELEMENT_MARKER}` : CUSTOM_ELEMENT_MARKER;
14602
14119
  OperationsHelper.insertBreak(this.model, text, insertIndex, breakType);
14603
14120
  const endPosition = this.displayData.insertText(position, text);
14604
- this.displayData.resetAllNumberingInfo(position.row);
14605
14121
  this.displayData.updateNextLineIndexes(position.row, endPosition.row);
14606
- if (isOnNewParagraph && endPosition.row - position.row) {
14607
- this.displayData.updateNumberingsDataOnChange(endPosition.row);
14608
- }
14609
14122
  const cursorPosition = this.displayData.getPositionAfterBreak(endPosition, breakType);
14610
14123
  this.selection.placeCursor(cursorPosition);
14611
14124
  return endPosition;
@@ -14616,7 +14129,6 @@ class EditSession {
14616
14129
  const model = this.model.tabs.find(x => x.insertIndex === insertIndex);
14617
14130
  this.addComponent(this.customComponents.tabs, model, NoderTabComponent);
14618
14131
  const endPosition = this.displayData.insertText(position, CUSTOM_ELEMENT_MARKER);
14619
- this.displayData.resetAllNumberingInfo(position.row);
14620
14132
  this.displayData.updateNextLineIndexes(position.row, position.row);
14621
14133
  this.selection.placeCursor(endPosition);
14622
14134
  return endPosition;
@@ -14627,7 +14139,6 @@ class EditSession {
14627
14139
  const model = this.model.images.find(x => x.insertIndex === insertIndex);
14628
14140
  this.addComponent(this.customComponents.images, model, NoderImageComponent);
14629
14141
  const endPosition = this.displayData.insertText(position, CUSTOM_ELEMENT_MARKER);
14630
- this.displayData.resetAllNumberingInfo(position.row);
14631
14142
  this.displayData.updateNextLineIndexes(position.row, position.row);
14632
14143
  this.selection.placeCursor(endPosition);
14633
14144
  return endPosition;
@@ -14636,7 +14147,6 @@ class EditSession {
14636
14147
  const insertIndex = ContentHelper.paragraphPositionToDocumentIndex(this.displayData.paragraphs, position);
14637
14148
  OperationsHelper.insertLink(this.model, linkData.text, linkData.link, insertIndex);
14638
14149
  const endPosition = this.displayData.insertText(position, linkData.text);
14639
- this.displayData.resetAllNumberingInfo(position.row);
14640
14150
  this.displayData.updateNextLineIndexes(position.row, position.row);
14641
14151
  this.selection.placeCursor(endPosition);
14642
14152
  return endPosition;
@@ -14647,11 +14157,7 @@ class EditSession {
14647
14157
  const model = this.model.tables.find(x => x.insertIndex >= tableModel.insertIndex);
14648
14158
  this.addComponent(this.customComponents.tables, model, NoderTableComponent);
14649
14159
  const endPosition = this.displayData.insertText(position, text);
14650
- this.displayData.resetAllNumberingInfo(position.row);
14651
14160
  this.displayData.updateNextLineIndexes(position.row, endPosition.row);
14652
- if (endPosition.row - position.row) {
14653
- this.displayData.updateNumberingsDataOnChange(endPosition.row);
14654
- }
14655
14161
  this.selection.placeCursor(endPosition);
14656
14162
  return endPosition;
14657
14163
  }
@@ -14672,11 +14178,7 @@ class EditSession {
14672
14178
  CustomComponentHelper.applyRemovingComponents(this.customComponents.tabs, moveModel.sourceStartIndex, endIndex);
14673
14179
  const restoreModel = OperationsHelper.removeMoveRange(this.model, moveModel);
14674
14180
  this.selection.placeCursor(startPosition);
14675
- this.displayData.resetAllNumberingInfo(startPosition.row);
14676
14181
  this.displayData.updateNextLineIndexes(startPosition.row, endPosition.row);
14677
- if (endPosition.row - startPosition.row && this.type !== 'cell') {
14678
- this.displayData.updateNumberingsDataOnChange(startPosition.row + 1);
14679
- }
14680
14182
  this.applyToolbarStyles();
14681
14183
  return restoreModel;
14682
14184
  }
@@ -14689,11 +14191,7 @@ class EditSession {
14689
14191
  this.restoreElementComponents(this.model.elements, moveIndex, endIndex);
14690
14192
  const startPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, moveIndex);
14691
14193
  const endPosition = this.displayData.insertText(startPosition, restoreModel.text);
14692
- this.displayData.resetAllNumberingInfo(startPosition.row);
14693
14194
  this.displayData.updateNextLineIndexes(startPosition.row, endPosition.row);
14694
- if (endPosition.row - startPosition.row && this.type !== 'cell') {
14695
- this.displayData.updateNumberingsDataOnChange(endPosition.row);
14696
- }
14697
14195
  this.selection.placeCursor(endPosition);
14698
14196
  this.applyToolbarStyles();
14699
14197
  const newStartPosition = this.displayData.indexToPosition(moveIndex, 0);
@@ -14784,11 +14282,7 @@ class EditSession {
14784
14282
  this.restoreComponents(this.model.images, this.customComponents.images, NoderImageComponent, model.insertIndex, restoreEndIndex);
14785
14283
  this.restoreComponents(this.model.tabs, this.customComponents.tabs, NoderTabComponent, model.insertIndex, restoreEndIndex);
14786
14284
  this.restoreElementComponents(this.model.elements, model.insertIndex, restoreEndIndex);
14787
- this.displayData.resetAllNumberingInfo(paragraphPosition.row);
14788
14285
  this.displayData.updateNextLineIndexes(paragraphPosition.row, endPoint.row);
14789
- if (endPoint.row - paragraphPosition.row && this.type !== 'cell') {
14790
- this.displayData.updateNumberingsDataOnChange(endPoint.row + 1);
14791
- }
14792
14286
  this.selection.placeCursor(endPoint);
14793
14287
  this.applyToolbarStyles();
14794
14288
  }
@@ -14821,33 +14315,28 @@ class EditSession {
14821
14315
  }
14822
14316
  insertTableRows(insertIndex, rowsCount, targetIndex, inheritIndex) {
14823
14317
  const table = this.customComponents.tables.find(x => x.instance.insertIndex === insertIndex);
14824
- this.displayData.resetNumberingInfoByTableCell(table);
14825
14318
  OperationsHelper.insertTableRows(this.model, insertIndex, rowsCount, targetIndex, inheritIndex);
14826
14319
  table.instance.updateTable();
14827
14320
  }
14828
14321
  insertTableColumns(insertIndex, columnsCount, targetIndex, inheritIndex) {
14829
14322
  const table = this.customComponents.tables.find(x => x.instance.insertIndex === insertIndex);
14830
14323
  const pageFormat = this.displayData.getPageFormatAtPosition(insertIndex);
14831
- this.displayData.resetNumberingInfoByTableCell(table);
14832
14324
  OperationsHelper.insertTableColumns(this.model, insertIndex, columnsCount, targetIndex, inheritIndex, pageFormat.contentWidth);
14833
14325
  table.instance.updateTable();
14834
14326
  }
14835
14327
  removeTableRows(insertIndex, startIndex, endIndex) {
14836
14328
  const table = this.customComponents.tables.find(x => x.instance.insertIndex === insertIndex);
14837
- this.displayData.resetNumberingInfoByTableCell(table);
14838
14329
  OperationsHelper.removeTableRows(this.model, insertIndex, startIndex, endIndex);
14839
14330
  table.instance.updateTable();
14840
14331
  }
14841
14332
  removeTableColumns(insertIndex, startIndex, endIndex) {
14842
14333
  const table = this.customComponents.tables.find(x => x.instance.insertIndex === insertIndex);
14843
- this.displayData.resetNumberingInfoByTableCell(table);
14844
14334
  const pageFormat = this.displayData.getPageFormatAtPosition(insertIndex);
14845
14335
  OperationsHelper.removeTableColumns(this.model, insertIndex, startIndex, endIndex, pageFormat.contentWidth);
14846
14336
  table.instance.updateTable();
14847
14337
  }
14848
14338
  resizeTableColumns(resizeTableColumns) {
14849
14339
  const table = this.customComponents.tables.find(x => x.instance.insertIndex === resizeTableColumns.insertIndex);
14850
- this.displayData.resetNumberingInfoByTableCell(table);
14851
14340
  OperationsHelper.resizeTableColumns(this.model, resizeTableColumns);
14852
14341
  table.instance.updateTable();
14853
14342
  }
@@ -15099,26 +14588,16 @@ class HighlightLayer {
15099
14588
  const results = [];
15100
14589
  for (let i = 0; i < textLinesInfo.length; i++) {
15101
14590
  const lineInfo = textLinesInfo[i].textLinesInfo;
15102
- const paragraphLineIndex = textLinesInfo[i].paragraphSettings.textLinesInfo.findIndex(x => x === textLinesInfo[i].textLinesInfo);
15103
14591
  if (i !== 0) {
15104
14592
  top += lineInfo.firstLinePageOffset;
15105
14593
  top += lineInfo.offsetBefore;
15106
14594
  }
15107
- let markerWidth = 0;
15108
- const numberingOffsetLeft = textLinesInfo[i].paragraphSettings.numberingData.numberingId === null
15109
- ? 0
15110
- : textLinesInfo[i].paragraphSettings.numberingData.width + textLinesInfo[i].paragraphSettings.numberingData.paddingLeft;
15111
- if (paragraphLineIndex === 0 &&
15112
- lineInfo.isNumbering &&
15113
- (lineInfo.indentFirstLine ||
15114
- (numberingOffsetLeft - lineInfo.indentLeft > 0 && numberingOffsetLeft - lineInfo.indentLeft <= lineInfo.markerWidth))) {
15115
- markerWidth = lineInfo.markerWidth;
15116
- }
15117
- const left = lineInfo.paddingLeft + padding + lineInfo.offsetMargin + markerWidth;
14595
+ const markerOffset = NumberingHelper.getOffsetCausedByMarker(textLinesInfo[i].paragraphSettings.numberingData, lineInfo);
14596
+ const left = lineInfo.paddingLeft + padding + lineInfo.offsetMargin + markerOffset;
15118
14597
  let style;
15119
14598
  if (i === 0) {
15120
14599
  const rangeInfo = this.getRangeInfo(this.session, range);
15121
- const width = lineInfo.width - rangeInfo.leftPos + left + (lineInfo.wordSpacingWidth ?? 0);
14600
+ const width = lineInfo.width - rangeInfo.leftPos + left;
15122
14601
  style = this.getMarkerStyle(lineInfo.height, width, top, rangeInfo.leftPos);
15123
14602
  }
15124
14603
  else if (i === textLinesInfo.length - 1) {
@@ -15127,7 +14606,7 @@ class HighlightLayer {
15127
14606
  style = this.getMarkerStyle(lineInfo.height, rangeInfo.screenWidth, top, left);
15128
14607
  }
15129
14608
  else {
15130
- let width = lineInfo.width + (lineInfo.wordSpacingWidth ?? 0);
14609
+ let width = lineInfo.width;
15131
14610
  style = this.getMarkerStyle(lineInfo.height, width, top, left);
15132
14611
  }
15133
14612
  const result = this.renderHighlight(style, cssClass);
@@ -15157,7 +14636,7 @@ class HighlightLayer {
15157
14636
  }
15158
14637
  const top = this.getTop(screenParentRange.start.row);
15159
14638
  const info = this.getRangeInfo(this.session, screenParentRange);
15160
- this.renderHighlight(this.getMarkerStyle(elementInfo.location.height, elementInfo.location.width, top + lineInfo.maxAscent - elementInfo.location.height + elementInfo.location.top, info.leftPos + elementInfo.location.left), cssClass);
14639
+ this.renderHighlight(this.getMarkerStyle(elementInfo.location.height, elementInfo.location.width, top + lineInfo.ascent - elementInfo.location.height + elementInfo.location.top, info.leftPos + elementInfo.location.left), cssClass);
15161
14640
  }
15162
14641
  getRangeInfo(session, range) {
15163
14642
  const start = range.start;
@@ -15297,16 +14776,9 @@ class CursorLayer {
15297
14776
  fontSize: textStyle.fontSize,
15298
14777
  fontFamily: textStyle.fontFamily
15299
14778
  })));
15300
- const fontMetricHeight = metricSize.ascent + metricSize.descent;
15301
- const maxHeight = this.cursorPosition.sizeMax.ascent + this.cursorPosition.sizeMax.descent;
15302
- const fontShoulders = fontMetricHeight - metricSize.font;
15303
- const offset = metricSize.descent - fontShoulders;
15304
- let top = this.cursorPosition.pageY + this.cursorPosition.sizeMax.ascent - metricSize.font + offset;
15305
- if (fontMetricHeight !== maxHeight && maxHeight >= this.cursorPosition.lineHeight) {
15306
- top -= maxHeight - this.cursorPosition.lineHeight;
15307
- }
15308
- DomHelper.setStyle(this.cursor.style, 'top', `${top < 0 ? 0 : top}px`);
15309
- DomHelper.setStyle(this.cursor.style, 'height', `${fontMetricHeight}px`);
14779
+ const top = this.cursorPosition.pageY + this.cursorPosition.ascent - metricSize.ascent;
14780
+ DomHelper.setStyle(this.cursor.style, 'top', `${top}px`);
14781
+ DomHelper.setStyle(this.cursor.style, 'height', `${metricSize.height}px`);
15310
14782
  }
15311
14783
  restartAnimation() {
15312
14784
  this.removeAnimationClass();
@@ -15322,9 +14794,8 @@ class CursorLayer {
15322
14794
  return;
15323
14795
  }
15324
14796
  DomHelper.setStyle(this.cursor.style, 'display', 'block');
15325
- const currentSize = this.cursorPosition.sizeCurrent;
15326
14797
  DomHelper.setStyle(this.cursor.style, 'left', `${this.cursorPosition.pageX}px`);
15327
- DomHelper.setStyle(this.cursor.style, 'width', `${currentSize.width}px`);
14798
+ DomHelper.setStyle(this.cursor.style, 'width', `${this.cursorPosition.width}px`);
15328
14799
  this.addTextStylesToCursor();
15329
14800
  }
15330
14801
  removeAnimationClass() {
@@ -15639,7 +15110,7 @@ class Renderer extends EventEmitting {
15639
15110
  this.session = session;
15640
15111
  this.layerConfig = {
15641
15112
  width: 1,
15642
- contentRange: new DistanceModel({ start: 0, end: 0 }),
15113
+ contentRange: new DistanceModel({ start: 0, end: 0 }), // paragraphs
15643
15114
  maxHeight: 1,
15644
15115
  offset: 0,
15645
15116
  height: 1,
@@ -16396,11 +15867,11 @@ class VirtualRenderer {
16396
15867
  this.scrollBar.setScrollTop(top);
16397
15868
  this.loop.schedule({ scroll: true });
16398
15869
  }
16399
- else if (this.scrollBar.scrollTop + this.container.scrollHeight < top + position.lineHeight) {
15870
+ else if (this.scrollBar.scrollTop + this.container.scrollHeight < top + position.height) {
16400
15871
  if (offset) {
16401
15872
  top += offset * this.container.scrollHeight;
16402
15873
  }
16403
- top += position.lineHeight - this.container.scrollHeight;
15874
+ top += position.height - this.container.scrollHeight;
16404
15875
  this.scrollBar.setScrollTop(top);
16405
15876
  this.loop.schedule({ scroll: true });
16406
15877
  }
@@ -16569,22 +16040,11 @@ class CustomContentService {
16569
16040
  }
16570
16041
  return null;
16571
16042
  }
16572
- isFragmentContainComponent(components, textFragment, fragmentDistance) {
16573
- if (textFragment.includes(CUSTOM_ELEMENT_MARKER)) {
16574
- return (this.isFragmentContainComponents(components.images, fragmentDistance) ||
16575
- this.isFragmentContainComponents(components.tabs, fragmentDistance) ||
16576
- this.isFragmentContainComponents(components.customElements, fragmentDistance));
16577
- }
16578
- if (textFragment.includes(TABLE_MARKER)) {
16579
- return this.isFragmentContainComponents(components.tables, fragmentDistance);
16580
- }
16581
- return false;
16582
- }
16583
- getComponents(components, distance) {
16584
- const images = components.images.filter(x => x.instance.insertIndex >= distance.start && x.instance.insertIndex <= distance.end);
16585
- const tables = components.tables.filter(x => x.instance.insertIndex >= distance.start && x.instance.insertIndex <= distance.end);
16586
- const tabs = components.tabs.filter(x => x.instance.insertIndex >= distance.start && x.instance.insertIndex <= distance.end);
16587
- const custom = components.customElements.filter(x => x.instance.insertIndex >= distance.start && x.instance.insertIndex <= distance.end);
16043
+ getComponents(components, start, end) {
16044
+ const images = components.images.filter(x => x.instance.insertIndex >= start && x.instance.insertIndex <= end);
16045
+ const tables = components.tables.filter(x => x.instance.insertIndex >= start && x.instance.insertIndex <= end);
16046
+ const tabs = components.tabs.filter(x => x.instance.insertIndex >= start && x.instance.insertIndex <= end);
16047
+ const custom = components.customElements.filter(x => x.instance.insertIndex >= start && x.instance.insertIndex <= end);
16588
16048
  return [...images, ...tables, ...tabs, ...custom].sort((a, b) => a.instance.insertIndex - b.instance.insertIndex);
16589
16049
  }
16590
16050
  getComponent(components, char, charIndex) {
@@ -16595,45 +16055,12 @@ class CustomContentService {
16595
16055
  }
16596
16056
  return this.findComponent(components.tables, charIndex);
16597
16057
  }
16598
- getTokenFromComponent(component, lineInfo, displayValue, isFirst, size) {
16599
- const ascent = component.instance.ascent() ?? 0;
16600
- const descent = component.instance.descent() ?? 0;
16601
- return new DisplayToken({
16602
- width: component.instance.width(),
16603
- height: ascent + descent,
16604
- baseline: 0,
16605
- content: 0,
16606
- font: size.font,
16607
- ascent,
16608
- descent,
16609
- line: 0,
16610
- lineSpacing: lineInfo.lineSpacing,
16611
- multiplier: 0,
16612
- align: lineInfo.align,
16613
- indentFirstLine: isFirst ? lineInfo.indent.firstLine : DEFAULT_PARAGRAPH_STYLE.indentFirstLine,
16614
- indentHanging: isFirst && !lineInfo.isNumbering ? lineInfo.indent.hanging : DEFAULT_PARAGRAPH_STYLE.indentHanging,
16615
- indentLeft: lineInfo.indent.left,
16616
- indentRight: lineInfo.indent.right,
16617
- indentBefore: lineInfo.offsetBefore,
16618
- indentAfter: lineInfo.offsetAfter,
16619
- markerWidth: isFirst && lineInfo.isNumbering ? lineInfo.markerWidth : 0,
16620
- isNumbering: lineInfo.isNumbering,
16621
- isPageBreak: false,
16622
- isLineBreak: false,
16623
- displayValue,
16624
- isTab: component.instance instanceof NoderTabComponent,
16625
- isTable: component.instance instanceof NoderTableComponent
16626
- });
16627
- }
16628
16058
  findComponentType(type) {
16629
16059
  return this.elements.find(x => x.type === type).componentType;
16630
16060
  }
16631
16061
  findComponent(components, insertIndex) {
16632
16062
  return components.find((x) => x.instance.insertIndex === insertIndex);
16633
16063
  }
16634
- isFragmentContainComponents(components, distance) {
16635
- return components.some(x => x.instance.insertIndex >= distance.start && x.instance.insertIndex <= distance.end);
16636
- }
16637
16064
  isSpecialMarker(char) {
16638
16065
  return char === CUSTOM_ELEMENT_MARKER || char === TABLE_MARKER;
16639
16066
  }