devexpress-richedit 26.1.2-beta → 26.1.3

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 (56) hide show
  1. package/bin/gulpfile.js +1 -1
  2. package/bin/index-custom.js +1 -1
  3. package/bin/localization-builder.js +1 -1
  4. package/bin/nspell-index.js +1 -1
  5. package/bin/nspell.webpack.config.js +1 -1
  6. package/bin/webpack-externals.js +1 -1
  7. package/bin/webpack.config.js +1 -1
  8. package/dist/dx.richedit.css +26 -0
  9. package/dist/dx.richedit.d.ts +1 -1
  10. package/dist/dx.richedit.js +6016 -5627
  11. package/dist/dx.richedit.min.js +3 -3
  12. package/dist/pdfkit.js +21908 -22350
  13. package/dist/pdfkit.min.js +1 -1
  14. package/index.d.ts +1 -1
  15. package/index.js +1 -1
  16. package/lib/client/client-rich-edit.d.ts +0 -1
  17. package/lib/client/client-rich-edit.js +2 -25
  18. package/lib/client/default-localization.js +1 -0
  19. package/lib/common/canvas/canvas-manager.d.ts +1 -1
  20. package/lib/common/canvas/canvas-manager.js +7 -3
  21. package/lib/common/canvas/double-tap-detector.d.ts +10 -0
  22. package/lib/common/canvas/double-tap-detector.js +28 -0
  23. package/lib/common/canvas/renderer-class-names.d.ts +2 -0
  24. package/lib/common/canvas/renderer-class-names.js +2 -0
  25. package/lib/common/canvas/renderes/common/document-renderer.d.ts +20 -7
  26. package/lib/common/canvas/renderes/common/document-renderer.js +236 -47
  27. package/lib/common/canvas/renderes/common/simple-view-renderer.d.ts +3 -1
  28. package/lib/common/canvas/renderes/common/simple-view-renderer.js +35 -2
  29. package/lib/common/canvas/renderes/view-manager.d.ts +3 -0
  30. package/lib/common/canvas/renderes/view-manager.js +34 -7
  31. package/lib/common/commands/border-command-options.d.ts +7 -0
  32. package/lib/common/commands/border-command-options.js +8 -0
  33. package/lib/common/commands/dialogs/dialog-border-shading-command.js +13 -6
  34. package/lib/common/commands/dialogs/dialog-custom-numbering-list-command.js +1 -1
  35. package/lib/common/commands/tables/toggle-table-cells-border-command.d.ts +1 -1
  36. package/lib/common/commands/tables/toggle-table-cells-border-command.js +10 -3
  37. package/lib/common/event-manager.js +2 -0
  38. package/lib/common/layout/main-structures/layout-boxes/layout-box.js +1 -1
  39. package/lib/common/layout/main-structures/layout-column.d.ts +1 -0
  40. package/lib/common/layout/main-structures/layout-column.js +3 -0
  41. package/lib/common/layout/selection/layout-selection-items.d.ts +3 -0
  42. package/lib/common/layout/selection/layout-selection-items.js +5 -0
  43. package/lib/common/layout-engine/selection/selection-formatter.js +7 -3
  44. package/lib/common/layout-formatter/box/generator/box-infos-generator.js +8 -4
  45. package/lib/common/layout-formatter/row/result.d.ts +1 -0
  46. package/lib/common/layout-formatter/row/result.js +11 -1
  47. package/lib/common/layout-formatter/row/size-engine/row-formatting-info.d.ts +2 -1
  48. package/lib/common/layout-formatter/row/size-engine/row-formatting-info.js +7 -4
  49. package/lib/common/model/sub-document.d.ts +12 -5
  50. package/lib/common/model/sub-document.js +36 -31
  51. package/lib/common/rich-edit-core.js +1 -1
  52. package/lib/common/screen-reader-manager.d.ts +6 -3
  53. package/lib/common/screen-reader-manager.js +66 -49
  54. package/lib/common/string-resources.d.ts +23 -0
  55. package/lib/common/string-resources.js +43 -0
  56. package/package.json +3 -3
@@ -29,9 +29,12 @@ import { RichEditClientCommand } from '../../commands/client-command';
29
29
  import { ZoomLevelChange } from '../../model/changes/model/zoom-level';
30
30
  import { ModelChangeType } from '../../model/changes/enums';
31
31
  import { MixedSize } from '../../../common/utils/mixed-size';
32
+ import { IntervalAlgorithms } from '@devexpress/utils/lib/intervals/algorithms';
33
+ import { FixedInterval } from '@devexpress/utils/lib/intervals/fixed';
32
34
  export class ViewManager {
33
35
  get renderer() { return this.renderers[this.innerClientProperties.viewsSettings.viewType]; }
34
36
  get printLayoutRenderer() { return this.renderers[ViewType.PrintLayout]; }
37
+ get isSimpleView() { return this.innerClientProperties.viewsSettings.isSimpleView; }
35
38
  get canvasListener() { return this.canvasListeners[this.innerClientProperties.viewsSettings.viewType]; }
36
39
  constructor(control, canvas, eventManager, stringResources, horizontalRuler, inputController, innerClientProperties, readOnlyPropertyHolder, layoutFormatterManagerHolder, internalApi, fieldOptions) {
37
40
  this.cache = [];
@@ -79,11 +82,11 @@ export class ViewManager {
79
82
  }
80
83
  adjust(force) {
81
84
  if ((force || !this.sizes.isInitialized()) && this.cache.length > 0) {
82
- const firstRenderedPageIndex = Math.min(this.cache.length, Math.max(0, ListUtils.indexBy(this.layout.pages, (page) => page.flags.get(LayoutPageFlags.ContentRendered))));
85
+ const firstRenderedPageIndex = Math.min(this.cache.length - 1, Math.max(0, this.layout.pages.findIndex((page) => page.flags.get(LayoutPageFlags.ContentRendered))));
83
86
  this.sizes.initialize(this.cache[firstRenderedPageIndex].page, this.canvas);
84
87
  const oldPageIndo = this.innerClientProperties.viewsSettings.pageVerticalInfo.clone();
85
88
  this.innerClientProperties.viewsSettings.pageVerticalInfo.copyFrom(this.sizes.pageVerticalInfo);
86
- if (this.innerClientProperties.viewsSettings.isSimpleView && !this.innerClientProperties.viewsSettings.pageVerticalInfo.equals(oldPageIndo)) {
89
+ if (this.isSimpleView && !this.innerClientProperties.viewsSettings.pageVerticalInfo.equals(oldPageIndo)) {
87
90
  const page = this.layout.pages[firstRenderedPageIndex];
88
91
  if (this.layoutFormatterManagerHolder.layoutFormatterManager && page)
89
92
  this.layoutFormatterManagerHolder.layoutFormatterManager.invalidator.onChangedAllLayout();
@@ -104,11 +107,18 @@ export class ViewManager {
104
107
  NotifySelectionLayoutChanged() {
105
108
  const layoutSelection = this.selection.layoutSelection;
106
109
  this.changeActiveSubDocumentRenderer.update(layoutSelection);
107
- Log.print(LogSource.CanvasManager, "onSelectionLayoutChanged\n", LogListHelper.level_1(Log.w(2, Log.flip(LogObjToStrLayout.pageSelectionChange, 0, 1))(""), this.selection.layoutSelection.selectionInfo.changes, "", "\n"));
108
- if (this.innerClientProperties.viewsSettings.isSimpleView)
110
+ Log.print(LogSource.CanvasManager, "onSelectionLayoutChanged\n", LogListHelper.level_1(Log.w(2, Log.flip(LogObjToStrLayout.pageSelectionChange, 0, 1))(""), layoutSelection.selectionInfo.changes, "", "\n"));
111
+ const shouldUpdateSelectedContent = this.renderer.updateForcedColorsModeState();
112
+ if (shouldUpdateSelectedContent) {
113
+ const intervals = this.getSelectionIntervalsForPageChange();
114
+ this.updateSelectedContent(layoutSelection.selectionInfo, intervals, layoutSelection.subDocumentInfo.isMain);
115
+ }
116
+ if (this.isSimpleView) {
109
117
  this.selection.renderAllPageSelection(this.layout, 0, true);
110
- else
118
+ }
119
+ else {
111
120
  this.selection.applySelectionChanges(this.layout);
121
+ }
112
122
  const pageIndex = ListUtils.reverseIndexBy(layoutSelection.selectionInfo.pageInfos, pageInfo => pageInfo.oldItems.length > 0);
113
123
  if (pageIndex > -1) {
114
124
  const pageInfo = layoutSelection.selectionInfo.pageInfos[pageIndex];
@@ -128,18 +138,35 @@ export class ViewManager {
128
138
  }
129
139
  NotifyMisspelledSelectionLayoutChanged() {
130
140
  Log.print(LogSource.CanvasManager, "onMisspelledSelectionLayoutChanged\n", LogListHelper.level_1(Log.w(2, Log.flip(LogObjToStrLayout.pageSelectionChange, 0, 1))(""), this.selection.layoutSelection.misspelledInfo.changes, "", "\n"));
131
- if (this.innerClientProperties.viewsSettings.isSimpleView)
141
+ if (this.isSimpleView)
132
142
  this.misspelledSelection.renderAllPageSelection(this.layout, 0, true);
133
143
  else
134
144
  this.misspelledSelection.applySelectionChanges(this.layout);
135
145
  }
136
146
  NotifyRangePermissionLayoutChanged() {
137
147
  Log.print(LogSource.CanvasManager, "onRangePermissionsLayoutChanged\n", LogListHelper.level_1(Log.w(2, Log.flip(LogObjToStrLayout.pageSelectionChange, 0, 1))(""), this.selection.layoutSelection.rangePermissionInfo.changes, "", "\n"));
138
- if (this.innerClientProperties.viewsSettings.isSimpleView)
148
+ if (this.isSimpleView)
139
149
  this.rangePermission.renderAllPageSelection(this.layout, 0, true);
140
150
  else
141
151
  this.rangePermission.applySelectionChanges(this.layout);
142
152
  }
153
+ updateSelectedContent(selectionInfo, intervals, isMain) {
154
+ const pageIndexes = this.isSimpleView ? [0] : selectionInfo.changes.map((pageChange) => pageChange.index);
155
+ pageIndexes.forEach((pageIndex) => this.renderer.updateSelectedIntervalsPageChanges(this.layout.pages[pageIndex], pageIndex, intervals, isMain));
156
+ }
157
+ getSelectionIntervalsForPageChange() {
158
+ const selection = this.control.selection;
159
+ if (!selection)
160
+ return [];
161
+ const affectedIntervals = [];
162
+ for (const state of [selection.prevState, selection.currState]) {
163
+ state.intervalsInfo.intervals.forEach((interval) => {
164
+ if (interval.length > 0)
165
+ affectedIntervals.push(new FixedInterval(interval.start, interval.length));
166
+ });
167
+ }
168
+ return IntervalAlgorithms.getMergedIntervals(affectedIntervals, true);
169
+ }
143
170
  addTopLevelContainers() {
144
171
  this.pagesContainer = DocumentRenderer.renderContainer(RendererClassNames.PAGES);
145
172
  this.pagesContainer.style.zoom = this.zoomLevel.toString();
@@ -0,0 +1,7 @@
1
+ import { CommandSimpleOptions } from '../../common/commands/command-base';
2
+ import { BorderInfo } from '../../common/model/borders/border-info';
3
+ import { IRichEditControl } from '../../common/interfaces/i-rich-edit-core';
4
+ export declare class BorderCommandOptions extends CommandSimpleOptions<BorderInfo> {
5
+ forceApply: boolean;
6
+ constructor(control: IRichEditControl, parameter: BorderInfo, forceApply: boolean);
7
+ }
@@ -0,0 +1,8 @@
1
+ import { CommandSimpleOptions } from '../../common/commands/command-base';
2
+ export class BorderCommandOptions extends CommandSimpleOptions {
3
+ constructor(control, parameter, forceApply) {
4
+ super(control, parameter);
5
+ this.forceApply = false;
6
+ this.forceApply = forceApply;
7
+ }
8
+ }
@@ -11,6 +11,7 @@ import { CommandSimpleOptions } from '../command-base';
11
11
  import { SimpleCommandState } from '../command-states';
12
12
  import { ToggleTableCellInsideHorizontalBordersCommand, ToggleTableCellInsideVerticalBordersCommand, ToggleTableCellsBottomBorderCommand, ToggleTableCellsLeftBorderCommand, ToggleTableCellsRightBorderCommand, ToggleTableCellsTopBorderCommand } from '../tables/toggle-table-cells-border-command';
13
13
  import { DialogParametersBase, ShowDialogCommandBase } from './show-dialog-command-base';
14
+ import { BorderCommandOptions } from '../../../common/commands/border-command-options';
14
15
  export class DialogBorderShadingCommandBase extends ShowDialogCommandBase {
15
16
  getState() {
16
17
  const visible = this.selection.tableInfo.extendedData.numRows > 0;
@@ -68,27 +69,33 @@ export class DialogBorderShadingCommandBase extends ShowDialogCommandBase {
68
69
  changed = true;
69
70
  }
70
71
  if (newParams.top && !newParams.top.equals(initParams.top)) {
71
- this.topBorderCommand.execute(this.control.commandManager.isPublicApiCall, newParams.top.getBorderInfo());
72
+ const opts = new BorderCommandOptions(this.control, newParams.top.getBorderInfo(), true);
73
+ this.topBorderCommand.execute(this.control.commandManager.isPublicApiCall, opts);
72
74
  changed = true;
73
75
  }
74
76
  if (newParams.bottom && !newParams.bottom.equals(initParams.bottom)) {
75
- this.bottomBorderCommand.execute(this.control.commandManager.isPublicApiCall, newParams.bottom.getBorderInfo());
77
+ const opts = new BorderCommandOptions(this.control, newParams.bottom.getBorderInfo(), true);
78
+ this.bottomBorderCommand.execute(this.control.commandManager.isPublicApiCall, opts);
76
79
  changed = true;
77
80
  }
78
81
  if (newParams.right && !newParams.right.equals(initParams.right)) {
79
- this.rightBorderCommand.execute(this.control.commandManager.isPublicApiCall, newParams.right.getBorderInfo());
82
+ const opts = new BorderCommandOptions(this.control, newParams.right.getBorderInfo(), true);
83
+ this.rightBorderCommand.execute(this.control.commandManager.isPublicApiCall, opts);
80
84
  changed = true;
81
85
  }
82
86
  if (newParams.left && !newParams.left.equals(initParams.left)) {
83
- this.leftBorderCommand.execute(this.control.commandManager.isPublicApiCall, newParams.left.getBorderInfo());
87
+ const opts = new BorderCommandOptions(this.control, newParams.left.getBorderInfo(), true);
88
+ this.leftBorderCommand.execute(this.control.commandManager.isPublicApiCall, opts);
84
89
  changed = true;
85
90
  }
86
91
  if (newParams.insideHorizontal && !newParams.insideHorizontal.equals(initParams.insideHorizontal)) {
87
- this.insideHorizontalBordersCommand.execute(this.control.commandManager.isPublicApiCall, newParams.insideHorizontal.getBorderInfo());
92
+ const opts = new BorderCommandOptions(this.control, newParams.insideHorizontal.getBorderInfo(), true);
93
+ this.insideHorizontalBordersCommand.execute(this.control.commandManager.isPublicApiCall, opts);
88
94
  changed = true;
89
95
  }
90
96
  if (newParams.insideVertical && !newParams.insideVertical.equals(initParams.insideVertical)) {
91
- this.insideVerticalBordersCommand.execute(this.control.commandManager.isPublicApiCall, newParams.insideVertical.getBorderInfo());
97
+ const opts = new BorderCommandOptions(this.control, newParams.insideVertical.getBorderInfo(), true);
98
+ this.insideVerticalBordersCommand.execute(this.control.commandManager.isPublicApiCall, opts);
92
99
  changed = true;
93
100
  }
94
101
  history.endTransaction();
@@ -280,7 +280,7 @@ export class NumberingListFormPreviewHelper {
280
280
  layoutRow.width = layoutNumberingListBox.textBox.width + layoutTextBox.width;
281
281
  layoutRow.x = isMultiLevel ? UnitConverter.twipsToPixels(paragraphProperties.leftIndent - paragraphProperties.firstLineIndent) + margin : margin;
282
282
  layoutRow.y = index * layoutRow.height + margin;
283
- return this.richEdit.viewManager.renderer.renderRow(layoutRow, 0);
283
+ return this.richEdit.viewManager.renderer.renderRow(layoutRow, 0, 0);
284
284
  }
285
285
  getNumberingListBoxText(levelIndex, majorIndex) {
286
286
  const items = [];
@@ -17,7 +17,7 @@ export declare abstract class ToggleTableCellsBorderCommandBase extends CommandB
17
17
  static isBorderVisible(border: BorderInfo): boolean;
18
18
  DEPRECATEDConvertOptionsParameter(parameter: any): BorderInfo;
19
19
  protected getRelatedCommands(): Record<number, boolean>;
20
- getState(_options?: CommandSimpleOptions<BorderInfo>): SimpleCommandState;
20
+ getState(options?: CommandSimpleOptions<BorderInfo>): SimpleCommandState;
21
21
  isEnabled(): boolean;
22
22
  isChecked(tableInfo: SelectedTableInfo): boolean;
23
23
  executeCore(state: SimpleCommandState, options: CommandSimpleOptions<BorderInfo>): boolean;
@@ -10,6 +10,7 @@ import { TableCellMergingState } from '../../model/tables/secondary-structures/t
10
10
  import { RichEditClientCommand } from '../client-command';
11
11
  import { CommandBase } from '../command-base';
12
12
  import { SimpleCommandState } from '../command-states';
13
+ import { BorderCommandOptions } from '../../../common/commands/border-command-options';
13
14
  export class ToggleTableCellsBorderCommandBase extends CommandBase {
14
15
  constructor() {
15
16
  super(...arguments);
@@ -39,12 +40,18 @@ export class ToggleTableCellsBorderCommandBase extends CommandBase {
39
40
  [RichEditClientCommand.ToggleTableCellsTopBorder]: true,
40
41
  };
41
42
  }
42
- getState(_options = this.convertToCommandOptions(null)) {
43
+ getState(options = this.convertToCommandOptions(null)) {
43
44
  const tableInfo = this.selection.tableInfo;
44
45
  let enabled = this.isEnabled() && this.selection.tableInfo.extendedData.areCellsSelectedInSeries;
45
46
  let state = new SimpleCommandState(enabled);
46
- if (state.enabled)
47
- state.value = this.isChecked(tableInfo);
47
+ if (state.enabled) {
48
+ if (options instanceof BorderCommandOptions && options.forceApply) {
49
+ state.value = !ToggleTableCellsBorderCommandBase.isBorderVisible(options.param);
50
+ }
51
+ else {
52
+ state.value = this.isChecked(tableInfo);
53
+ }
54
+ }
48
55
  return state;
49
56
  }
50
57
  isEnabled() {
@@ -207,6 +207,8 @@ export class EventManager {
207
207
  this.control.modelManager.modelManipulator.notifyModelChanged(new TextBufferChangedSubDocumentChange(subDocument.id, state));
208
208
  }
209
209
  insertFunc() {
210
+ if (this.accumulatedText.length === 0)
211
+ return;
210
212
  const insertCommand = this.control.commandManager.getCommand(RichEditClientCommand.InsertText);
211
213
  const textWasInserted = insertCommand.execute(this.control.commandManager.isPublicApiCall, this.accumulatedText);
212
214
  this.accumulatedText = "";
@@ -42,7 +42,7 @@ export class LayoutBox extends Rectangle {
42
42
  this.colorInfo.equals(obj.colorInfo) &&
43
43
  this.rowOffset == obj.rowOffset &&
44
44
  this.hyperlinkTip == obj.hyperlinkTip &&
45
- this.fieldLevel == this.fieldLevel;
45
+ this.fieldLevel == obj.fieldLevel;
46
46
  }
47
47
  copyFrom(obj) {
48
48
  super.copyFrom(obj);
@@ -8,6 +8,7 @@ export declare class LayoutColumn extends Rectangle {
8
8
  paragraphFrames: ParagraphFrame[];
9
9
  tablesInfo: LayoutTableColumnInfo[];
10
10
  constructor();
11
+ getStartPosition(): number;
11
12
  getEndPosition(): number;
12
13
  getLastRow(): LayoutRow;
13
14
  static findSectionColumnWithMinimumWidth(columnBounds: Rectangle[]): number;
@@ -7,6 +7,9 @@ export class LayoutColumn extends Rectangle {
7
7
  this.paragraphFrames = [];
8
8
  this.tablesInfo = [];
9
9
  }
10
+ getStartPosition() {
11
+ return this.pageAreaOffset + this.rows[0].getStartPosition();
12
+ }
10
13
  getEndPosition() {
11
14
  return this.pageAreaOffset + ListUtils.last(this.rows).getEndPosition();
12
15
  }
@@ -36,3 +36,6 @@ export declare class LayoutSelectionFloatingObjectItem extends LayoutSelectionIt
36
36
  get zIndexClassType(): zIndexCssClassType;
37
37
  get baseClassName(): string;
38
38
  }
39
+ export declare class LayoutSelectionPictureItem extends LayoutSelectionItem {
40
+ get baseClassName(): string;
41
+ }
@@ -73,3 +73,8 @@ export class LayoutSelectionFloatingObjectItem extends LayoutSelectionItem {
73
73
  return [RendererClassNames.SELECTION_ROW, RendererClassNames.SELECTION_FLOATING_OBJECTS].join(" ");
74
74
  }
75
75
  }
76
+ export class LayoutSelectionPictureItem extends LayoutSelectionItem {
77
+ get baseClassName() {
78
+ return [RendererClassNames.SELECTION_ROW, RendererClassNames.SELECTION_PICTURE_ROW].join(" ");
79
+ }
80
+ }
@@ -7,7 +7,7 @@ import { LayoutChangeType } from '../../layout-formatter/changes/changes/layout-
7
7
  import { LayoutPageSelectionChange } from '../../layout-formatter/changes/changes/selection/layout-page-selection-change';
8
8
  import { DocumentLayoutDetailsLevel } from '../../layout/document-layout-details-level';
9
9
  import { LayoutBoxType } from '../../layout/main-structures/layout-boxes/layout-box';
10
- import { LayoutRangePermissionItem, LayoutSelectionCursorItem, LayoutSelectionFloatingObjectItem, LayoutSelectionItem, LayoutSelectionMisspelledItem, LayoutSelectionSearchItem } from '../../layout/selection/layout-selection-items';
10
+ import { LayoutRangePermissionItem, LayoutSelectionCursorItem, LayoutSelectionFloatingObjectItem, LayoutSelectionItem, LayoutSelectionMisspelledItem, LayoutSelectionPictureItem, LayoutSelectionSearchItem } from '../../layout/selection/layout-selection-items';
11
11
  import { TableCellBoundFlags } from '../../layout/table/layout-table-cell-info';
12
12
  import { ModelChangeType } from '../../model/changes/enums';
13
13
  import { CharacterFormattingScript } from '../../model/character/enums';
@@ -285,6 +285,7 @@ export class SelectionFormatter extends BatchUpdatableObject {
285
285
  throw new Error(Errors.InternalException);
286
286
  let currentLayoutRow = null;
287
287
  let currSelectionItem = null;
288
+ let wasPreviousBoxPicture = false;
288
289
  const selectedCellsCollector = new SelectedCellsCollector();
289
290
  let currPageIndex = -1;
290
291
  for (let isFirstBox = true; iterator.moveNext(new LayoutPositionCreatorConflictFlags().setDefault(!isFirstBox), new LayoutPositionCreatorConflictFlags().setDefault(true)); isFirstBox = false) {
@@ -324,15 +325,18 @@ export class SelectionFormatter extends BatchUpdatableObject {
324
325
  const absRowOffsetX = currPosition.pageArea.x + currPosition.column.x + currPosition.row.x;
325
326
  const absBoxOffsetX = currPosition.box.x + currentBoxLeftOffsetX + absRowOffsetX;
326
327
  const thereIsGap = !!currSelectionItem && !MathUtils.numberCloseTo(absBoxOffsetX, currSelectionItem.x + currSelectionItem.width);
327
- const isNeedCreateNewSelectionRow = row !== currentLayoutRow || thereIsGap;
328
+ const isPictureBox = currPosition.box.getType() === LayoutBoxType.Picture;
329
+ const isNeedCreateNewSelectionRow = row !== currentLayoutRow || thereIsGap || isPictureBox || wasPreviousBoxPicture;
328
330
  if (isNeedCreateNewSelectionRow) {
329
331
  currentLayoutRow = row;
330
332
  const floatingObjectId = SelectionFormatter.getFloatingObjId(activeSubDocument, currPosition.page);
331
- currSelectionItem = LayoutSelectionItem.create(currPosition, new Size(0, row.height), floatingObjectId, LayoutSelectionItem);
333
+ const itemCtor = isPictureBox ? LayoutSelectionPictureItem : LayoutSelectionItem;
334
+ currSelectionItem = LayoutSelectionItem.create(currPosition, new Size(0, row.height), floatingObjectId, itemCtor);
332
335
  currSelectionItem.x += currPosition.box.x + currentBoxLeftOffsetX;
333
336
  layoutSelectionInfo.registerItem(currPosition.pageIndex, currSelectionItem);
334
337
  }
335
338
  currSelectionItem.width += currentBoxRightOffsetX - currentBoxLeftOffsetX;
339
+ wasPreviousBoxPicture = isPictureBox;
336
340
  }
337
341
  }
338
342
  static isCellFullySelected(cell, allIntervals) {
@@ -405,10 +405,14 @@ export class BoxGenerator {
405
405
  const word = this.modelIterator.getRunText(currRunTextStart, currBoxLength);
406
406
  currRunTextStart += currBoxLength;
407
407
  const charProps = this.getActualCharacterProperties();
408
- if (this.currBoxInfoType == LayoutBoxType.Text)
409
- this.addNewBoxInfo(new LayoutTextBox(charProps, charProps.getLayoutColorInfo(this.colorProvider), word), currRunTextStart);
410
- else
411
- this.addNewBoxInfo(new LayoutDashBox(charProps, charProps.getLayoutColorInfo(this.colorProvider), word), currRunTextStart);
408
+ if (this.currBoxInfoType == LayoutBoxType.Text) {
409
+ const newBox = new LayoutTextBox(charProps, charProps.getLayoutColorInfo(this.colorProvider), word);
410
+ this.addNewBoxInfo(newBox, currRunTextStart);
411
+ }
412
+ else {
413
+ const newBox = new LayoutDashBox(charProps, charProps.getLayoutColorInfo(this.colorProvider), word);
414
+ this.addNewBoxInfo(newBox, currRunTextStart);
415
+ }
412
416
  } while (currRunTextStart < this.modelIterator.charOffset);
413
417
  }
414
418
  this.currBoxInfoType = LayoutBoxType.Text;
@@ -25,6 +25,7 @@ export declare class RowFormatterResult {
25
25
  finishLogicalRow(currLogicRowEndPos: number): void;
26
26
  private deleteSomeAnchorObjects;
27
27
  finishRow(): void;
28
+ private getLastVisibleBox;
28
29
  private addBracketBox;
29
30
  private addBrackets;
30
31
  private getBracketBox;
@@ -81,10 +81,20 @@ export class RowFormatterResult {
81
81
  this.row.columnOffset = rowStartPos -
82
82
  this.rowFormatter.manager.activeFormatter.layoutPosition.getLogPosition(DocumentLayoutDetailsLevel.Column);
83
83
  const firstBox = this.row.boxes[0];
84
- this.row.width = Math.max(this.row.width, lastBox.right - firstBox.x);
84
+ const lastVisibleBox = this.getLastVisibleBox();
85
+ if (lastVisibleBox)
86
+ this.row.width = Math.max(this.row.width, lastVisibleBox.right - firstBox.x);
85
87
  const currState = this.rowFormatter.rowSizesManager.heightCalculator.currState;
86
88
  this.row.increaseRowHeightFromSpacingBeforeAndAfter(currState.maxAscent, currState.maxDescent);
87
89
  }
90
+ getLastVisibleBox() {
91
+ for (let i = this.row.boxes.length - 1; i >= 0; i--) {
92
+ const box = this.row.boxes[i];
93
+ if (box.isVisible() && !box.isWhitespace())
94
+ return box;
95
+ }
96
+ return null;
97
+ }
88
98
  addBracketBox(boxType, color, x, layoutBox) {
89
99
  const box = new BookmarkBox(boxType);
90
100
  box.x = x - (boxType == LayoutBookmarkBoxType.EndBox ? BookmarkBox.DEFAULT_BORDER_WIDTH : 0);
@@ -4,7 +4,8 @@ import { FixedInterval } from '@devexpress/utils/lib/intervals/fixed';
4
4
  export declare class RowIntervalInfo extends FixedInterval {
5
5
  avaliableWidth: number;
6
6
  constructor(start: number, length: number, avaliableWidth?: number);
7
- get busyWidth(): number;
7
+ get rawUsedWidth(): number;
8
+ get usedWidth(): number;
8
9
  get startOfFreeSpace(): number;
9
10
  isConsiderBoxes(): boolean;
10
11
  }
@@ -11,11 +11,14 @@ export class RowIntervalInfo extends FixedInterval {
11
11
  super(start, length);
12
12
  this.avaliableWidth = avaliableWidth;
13
13
  }
14
- get busyWidth() {
14
+ get rawUsedWidth() {
15
15
  return this.length - this.avaliableWidth;
16
16
  }
17
+ get usedWidth() {
18
+ return Math.min(this.rawUsedWidth, this.length);
19
+ }
17
20
  get startOfFreeSpace() {
18
- return this.start + this.busyWidth;
21
+ return this.start + this.rawUsedWidth;
19
22
  }
20
23
  isConsiderBoxes() {
21
24
  return this.avaliableWidth != this.length;
@@ -71,7 +74,7 @@ export class RowFormattingInfo {
71
74
  recalculate(outerHorizontalRowContentBounds) {
72
75
  const currInterval = this.currInterval;
73
76
  this.calculate(outerHorizontalRowContentBounds);
74
- const pos = currInterval.start + currInterval.busyWidth;
77
+ const pos = currInterval.start + currInterval.rawUsedWidth;
75
78
  const index = this.findIntervalIndexByPosition(pos);
76
79
  const interval = this.intervals[index];
77
80
  if (interval && interval.start < pos) {
@@ -91,7 +94,7 @@ export class RowFormattingInfo {
91
94
  return index;
92
95
  }
93
96
  canIncrementHeightTo(newHeight) {
94
- const contentBounds = ListUtils.map(this.intervals, (c) => new Rectangle(c.start, this.minY, c.busyWidth, newHeight));
97
+ const contentBounds = ListUtils.map(this.intervals, (c) => new Rectangle(c.start, this.minY, c.usedWidth, newHeight));
95
98
  const intersectedObjects = this.calcIntersectObjects(newHeight);
96
99
  return !ListUtils.unsafeAnyOf(intersectedObjects, (ancBound) => ListUtils.unsafeAnyOf(contentBounds, (contentBound) => RectangleUtils.getNonCollapsedIntersection(contentBound, ancBound)));
97
100
  }
@@ -17,7 +17,6 @@ import { RunBase } from './runs/run-base';
17
17
  import { Section } from './section/section';
18
18
  import { SubDocumentInfoBase } from './sub-document-infos';
19
19
  import { Table } from './tables/main-structures/table';
20
- import { InlinePictureRun } from './runs/inline-picture-run';
21
20
  export declare class SubDocument {
22
21
  static AUTOGENERATE_ID: number;
23
22
  static MAIN_SUBDOCUMENT_ID: number;
@@ -46,6 +45,7 @@ export declare class SubDocument {
46
45
  getText(interval?: FixedInterval): string;
47
46
  getSimpleText(interval: ConstInterval): string;
48
47
  getVisibleText(interval: ConstInterval, options?: IGetTextOptions): string;
48
+ private resolveChar;
49
49
  private isPositionVisible;
50
50
  splitRun(position: number): void;
51
51
  getLastRun(): RunBase;
@@ -126,11 +126,18 @@ export declare class SubDocumentIntervals implements ISubDocumentIntervals {
126
126
  equals(obj: SubDocumentIntervals): boolean;
127
127
  static fromPosition(subDocument: SubDocument, pos: number): SubDocumentIntervals;
128
128
  }
129
+ export declare enum TransformAction {
130
+ InsertBefore = 0,
131
+ Replace = 1,
132
+ InsertAfter = 2
133
+ }
129
134
  export interface IGetTextOptions {
130
135
  charMap?: Record<string, string>;
131
136
  includeNumberedListMarks?: boolean;
132
- useFieldResult?: boolean;
133
- paragraphEndMark?: string;
134
- inlinePictureAltText?: string | ((run: InlinePictureRun) => string);
135
- resolveAdditionalText?: (fieldIndexes: number[], pos: number) => string | null;
137
+ forceFieldResultText?: boolean;
138
+ transform?: (info: FullChunkAndRunInfo, fieldIndexes: number[]) => ITransformResult | string | null;
139
+ }
140
+ export interface ITransformResult {
141
+ text?: string | null;
142
+ action: TransformAction;
136
143
  }
@@ -12,7 +12,6 @@ import { PositionManager } from './position/position-manager';
12
12
  import { RichUtils } from './rich-utils';
13
13
  import { RunType } from './runs/run-type';
14
14
  import { ParagraphIterator } from '../layout-formatter/box/generator/one-dimension-itertors';
15
- import { isDefined } from '@devexpress/utils/lib/utils/common';
16
15
  import { FieldIterator } from '../layout-formatter/box/generator/recursive-objects-iterators';
17
16
  export class SubDocument {
18
17
  static { this.AUTOGENERATE_ID = -1; }
@@ -66,7 +65,7 @@ export class SubDocument {
66
65
  }
67
66
  getSimpleText(interval) {
68
67
  return this.getVisibleText(interval, {
69
- useFieldResult: true,
68
+ forceFieldResultText: true,
70
69
  charMap: {
71
70
  [RichUtils.specialCharacters.LineBreak]: ' ',
72
71
  [RichUtils.specialCharacters.SectionMark]: '\r\n',
@@ -77,7 +76,7 @@ export class SubDocument {
77
76
  getVisibleText(interval, options = {}) {
78
77
  let result = [];
79
78
  let pos = interval.start;
80
- const { charMap = {}, useFieldResult = false, includeNumberedListMarks = false, inlinePictureAltText = null, resolveAdditionalText = undefined, } = options;
79
+ const { charMap = {}, forceFieldResultText = false, includeNumberedListMarks = false, transform } = options;
81
80
  const iterator = new ModelIterator(this, true);
82
81
  iterator.setPosition(pos);
83
82
  const fieldIterator = new FieldIterator(this.fields);
@@ -85,36 +84,24 @@ export class SubDocument {
85
84
  const paragraphIterator = new ParagraphIterator(this.paragraphs);
86
85
  paragraphIterator.init(pos);
87
86
  while (pos < interval.end) {
88
- if (this.isPositionVisible(pos, fieldIterator.indexes, useFieldResult)) {
87
+ if (this.isPositionVisible(pos, fieldIterator.indexes, forceFieldResultText)) {
89
88
  const paragraph = this.paragraphs[paragraphIterator.index];
90
89
  if (includeNumberedListMarks && pos === paragraph.startLogPosition.value && paragraph.isInList())
91
90
  result.push(paragraph.getNumberingListText() + paragraph.getNumberingListSeparatorChar());
92
- if (resolveAdditionalText) {
93
- const resolved = resolveAdditionalText(fieldIterator.indexes, pos);
94
- if (resolved)
95
- result.push(resolved);
96
- }
97
- switch (iterator.run.getType()) {
98
- case RunType.InlinePictureRun:
99
- if (inlinePictureAltText != null) {
100
- let placeholder;
101
- if (typeof inlinePictureAltText === "function")
102
- placeholder = inlinePictureAltText(iterator.run);
103
- else
104
- placeholder = inlinePictureAltText;
105
- if (isDefined(placeholder))
106
- result.push(placeholder);
107
- }
108
- break;
109
- case RunType.SectionRun:
110
- case RunType.ParagraphRun:
111
- case RunType.FieldCodeStartRun:
112
- case RunType.FieldCodeEndRun:
113
- case RunType.TextRun:
114
- const char = iterator.getCurrentChar();
115
- result.push(charMap[char] ?? char);
116
- break;
91
+ const transformResult = transform?.(iterator, fieldIterator.indexes);
92
+ if (transformResult != null) {
93
+ if (typeof transformResult === "string")
94
+ result.push(transformResult);
95
+ else if (transformResult.text != null) {
96
+ if (transformResult.action === TransformAction.InsertAfter)
97
+ this.resolveChar(iterator, result, charMap);
98
+ result.push(transformResult.text);
99
+ if (transformResult.action === TransformAction.InsertBefore)
100
+ this.resolveChar(iterator, result, charMap);
101
+ }
117
102
  }
103
+ else
104
+ this.resolveChar(iterator, result, charMap);
118
105
  if (!iterator.moveToNextChar())
119
106
  break;
120
107
  }
@@ -126,10 +113,22 @@ export class SubDocument {
126
113
  }
127
114
  return result.join("");
128
115
  }
129
- isPositionVisible(pos, fieldIndexes, useFieldResult) {
116
+ resolveChar(iterator, result, charMap) {
117
+ switch (iterator.run.getType()) {
118
+ case RunType.SectionRun:
119
+ case RunType.ParagraphRun:
120
+ case RunType.FieldCodeStartRun:
121
+ case RunType.FieldCodeEndRun:
122
+ case RunType.TextRun:
123
+ const char = iterator.getCurrentChar();
124
+ result.push(charMap[char] ?? char);
125
+ break;
126
+ }
127
+ }
128
+ isPositionVisible(pos, fieldIndexes, forceFieldResultText) {
130
129
  for (const index of fieldIndexes) {
131
130
  const field = this.fields[index];
132
- const isCodeView = !useFieldResult && field.showCode;
131
+ const isCodeView = !forceFieldResultText && field.showCode;
133
132
  const invisibleInterval = isCodeView
134
133
  ? field.getResultIntervalWithBorders()
135
134
  : field.getCodeIntervalWithBorders();
@@ -510,6 +509,12 @@ export class SubDocumentIntervals {
510
509
  return new SubDocumentIntervals(subDocument, [new FixedInterval(pos, 0)]);
511
510
  }
512
511
  }
512
+ export var TransformAction;
513
+ (function (TransformAction) {
514
+ TransformAction[TransformAction["InsertBefore"] = 0] = "InsertBefore";
515
+ TransformAction[TransformAction["Replace"] = 1] = "Replace";
516
+ TransformAction[TransformAction["InsertAfter"] = 2] = "InsertAfter";
517
+ })(TransformAction || (TransformAction = {}));
513
518
  function internalValidateInterval(subDocument, interval) {
514
519
  const documentEndPosition = subDocument.getDocumentEndPosition();
515
520
  if (interval.start == 0 && interval.end == documentEndPosition)
@@ -85,7 +85,7 @@ export class RichEditCore {
85
85
  this.commandManager = this.createCommandManager();
86
86
  this.shortcutManager = this.createShortcutManager();
87
87
  this.searchManager = new SearchManager(this);
88
- this.screenReaderManager = new ScreenReaderManager(this, this.createAriaLiveElement(element));
88
+ this.screenReaderManager = new ScreenReaderManager(this, this.createAriaLiveElement(element), this.stringResources);
89
89
  this.boxVisualizerManager.initListeners(this.viewManager);
90
90
  this.autoCorrectService = new AutoCorrectService(this, this.modelManager.richOptions.autoCorrect);
91
91
  this.clientSideEvents = new ClientSideEvents(this.owner);
@@ -3,21 +3,22 @@ import { IRichEditControl } from "./interfaces/i-rich-edit-core";
3
3
  import { LayoutPosition } from "./layout/layout-position";
4
4
  import { ISelectionChangesListener } from "./selection/i-selection-changes-listener";
5
5
  import { Selection } from "./selection/selection";
6
+ import { StringResources } from "./string-resources";
6
7
  export declare class ScreenReaderManager implements ISelectionChangesListener {
7
8
  private static _maxAnnouncedTextLength;
8
9
  private static _spaceSeparatorRegex;
9
- private static _specialCharSubstitutionTable;
10
10
  private _charNames;
11
11
  readonly _handlers: Map<RichEditClientCommand, (selection: Selection, lp: LayoutPosition) => string>;
12
12
  private _selectionIntervals;
13
13
  private _commandId;
14
14
  private _control;
15
15
  private _liveRegion;
16
+ private _announcements;
16
17
  private _announceTimeoutId;
17
18
  private _pageIndex;
18
19
  private _tableInfo;
19
20
  private _prevNavInHyperlink;
20
- constructor(control: IRichEditControl, liveRegion: HTMLDivElement);
21
+ constructor(control: IRichEditControl, liveRegion: HTMLDivElement, resources: StringResources);
21
22
  private _announce;
22
23
  private _clearAnnouncement;
23
24
  beginExecute(commandId: RichEditClientCommand): void;
@@ -36,7 +37,9 @@ export declare class ScreenReaderManager implements ISelectionChangesListener {
36
37
  private _getHyperlinkField;
37
38
  private _onHyperlinkFieldStart;
38
39
  private _getVisibleText;
39
- private static _getInlinePictureText;
40
+ private _tryResolveDocumentElements;
41
+ private _tryResolveSpecialCharacters;
42
+ private _getInlinePictureText;
40
43
  private _getPageChangePrefix;
41
44
  private _getCharName;
42
45
  private _resolveListMarker;