devexpress-richedit 25.2.8 → 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.
- package/bin/gulpfile.js +1 -1
- package/bin/index-custom.js +1 -1
- package/bin/localization-builder.js +1 -1
- package/bin/nspell-index.js +1 -1
- package/bin/nspell.webpack.config.js +1 -1
- package/bin/webpack-externals.js +1 -1
- package/bin/webpack.config.js +1 -1
- package/dist/dx.richedit.css +26 -0
- package/dist/dx.richedit.d.ts +1 -1
- package/dist/dx.richedit.js +6559 -5654
- package/dist/dx.richedit.min.js +3 -3
- package/dist/pdfkit.js +21908 -22350
- package/dist/pdfkit.min.js +1 -1
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/client/client-rich-edit.d.ts +0 -1
- package/lib/client/client-rich-edit.js +4 -27
- package/lib/client/default-localization.js +19 -0
- package/lib/client/dialogs/alert-dialog.d.ts +1 -1
- package/lib/client/dialogs/bookmark-dialog.d.ts +1 -1
- package/lib/client/dialogs/delete-table-cells-dialog.d.ts +1 -1
- package/lib/client/dialogs/dialog-base.d.ts +1 -1
- package/lib/client/dialogs/find-replace-dialog.d.ts +1 -1
- package/lib/client/dialogs/finish-and-merge-dialog.d.ts +1 -1
- package/lib/client/dialogs/font-dialog.d.ts +1 -1
- package/lib/client/dialogs/hyperlink-dialog.d.ts +1 -1
- package/lib/client/dialogs/insert-merge-field-dialog.d.ts +1 -1
- package/lib/client/dialogs/insert-table-cells-dialog.d.ts +1 -1
- package/lib/client/dialogs/insert-table-dialog.d.ts +1 -1
- package/lib/client/dialogs/page-setup-dialog.d.ts +1 -1
- package/lib/client/dialogs/paragraph-dialog.d.ts +1 -1
- package/lib/client/dialogs/split-table-cells-dialog.d.ts +1 -1
- package/lib/client/dialogs/tabs-dialog.d.ts +1 -1
- package/lib/client/public/rich-edit.js +2 -0
- package/lib/common/canvas/canvas-manager.d.ts +1 -1
- package/lib/common/canvas/canvas-manager.js +7 -3
- package/lib/common/canvas/double-tap-detector.d.ts +10 -0
- package/lib/common/canvas/double-tap-detector.js +28 -0
- package/lib/common/canvas/renderer-class-names.d.ts +2 -0
- package/lib/common/canvas/renderer-class-names.js +2 -0
- package/lib/common/canvas/renderes/common/document-renderer.d.ts +20 -7
- package/lib/common/canvas/renderes/common/document-renderer.js +236 -47
- package/lib/common/canvas/renderes/common/simple-view-renderer.d.ts +3 -1
- package/lib/common/canvas/renderes/common/simple-view-renderer.js +35 -2
- package/lib/common/canvas/renderes/view-manager.d.ts +3 -0
- package/lib/common/canvas/renderes/view-manager.js +34 -7
- package/lib/common/commands/command-manager.d.ts +2 -0
- package/lib/common/commands/command-manager.js +6 -0
- package/lib/common/commands/dialogs/dialog-custom-numbering-list-command.js +1 -1
- package/lib/common/commands/layout/switch-view-command.js +2 -1
- package/lib/common/commands/selection/go-to-next-word-command.d.ts +3 -4
- package/lib/common/commands/selection/go-to-next-word-command.js +2 -9
- package/lib/common/commands/selection/go-to-prev-word-command.d.ts +3 -2
- package/lib/common/commands/selection/go-to-prev-word-command.js +2 -2
- package/lib/common/commands/selection/select-all-document-command.d.ts +2 -0
- package/lib/common/commands/selection/select-all-document-command.js +6 -0
- package/lib/common/commands/selection/selection-command-base.d.ts +2 -0
- package/lib/common/commands/selection/selection-command-base.js +8 -0
- package/lib/common/event-manager.js +6 -12
- package/lib/common/formats/txt/txt-exporter.js +1 -1
- package/lib/common/input-controller.js +2 -0
- package/lib/common/interfaces/i-rich-edit-core.d.ts +2 -0
- package/lib/common/layout/main-structures/layout-boxes/layout-box.js +1 -1
- package/lib/common/layout/main-structures/layout-column.d.ts +1 -0
- package/lib/common/layout/main-structures/layout-column.js +3 -0
- package/lib/common/layout/selection/layout-selection-items.d.ts +3 -0
- package/lib/common/layout/selection/layout-selection-items.js +5 -0
- package/lib/common/layout-engine/selection/selection-formatter.js +7 -3
- package/lib/common/layout-formatter/box/generator/box-infos-generator.js +8 -4
- package/lib/common/model/sub-document.d.ts +18 -0
- package/lib/common/model/sub-document.js +71 -22
- package/lib/common/rich-edit-core.d.ts +3 -0
- package/lib/common/rich-edit-core.js +18 -0
- package/lib/common/screen-reader-manager.d.ts +48 -0
- package/lib/common/screen-reader-manager.js +326 -0
- package/lib/common/string-resources.d.ts +23 -0
- package/lib/common/string-resources.js +43 -0
- package/lib/common/utils/interval-utils.d.ts +4 -0
- package/lib/common/utils/interval-utils.js +25 -0
- 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,
|
|
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.
|
|
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))(""),
|
|
108
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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();
|
|
@@ -22,6 +22,8 @@ export declare abstract class CommandManager implements ISelectionChangesListene
|
|
|
22
22
|
dispose(): void;
|
|
23
23
|
abortClipboardCommandExecution(): void;
|
|
24
24
|
getCommand(key: RichEditClientCommand): ICommand;
|
|
25
|
+
getExecutingCommandsChainDebug(): string[];
|
|
26
|
+
getLastCommandsChainDebug(): string[];
|
|
25
27
|
beforeExecuting(command: ICommand): void;
|
|
26
28
|
afterExecuting(): void;
|
|
27
29
|
assertLastExecutedCommandsChain(checkLength: boolean, ...types: Function[]): boolean;
|
|
@@ -579,6 +579,12 @@ export class CommandManager {
|
|
|
579
579
|
getCommand(key) {
|
|
580
580
|
return this.commands[key];
|
|
581
581
|
}
|
|
582
|
+
getExecutingCommandsChainDebug() {
|
|
583
|
+
return this.executingCommandsChain.map(command => command?.constructor?.name || 'UnknownCommand');
|
|
584
|
+
}
|
|
585
|
+
getLastCommandsChainDebug() {
|
|
586
|
+
return this.lastCommandsChain.map(command => command?.constructor?.name || 'UnknownCommand');
|
|
587
|
+
}
|
|
582
588
|
beforeExecuting(command) {
|
|
583
589
|
this.executingCommandsChain.push(command);
|
|
584
590
|
this.executingCommandCounter++;
|
|
@@ -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 = [];
|
|
@@ -16,7 +16,8 @@ export class ChangeViewTypeCommand extends CommandBase {
|
|
|
16
16
|
return true;
|
|
17
17
|
}
|
|
18
18
|
executeCore(_state, options) {
|
|
19
|
-
|
|
19
|
+
const currentViewType = this.control.innerClientProperties.viewsSettings.viewType;
|
|
20
|
+
if (currentViewType != options.param) {
|
|
20
21
|
if (this.selection.activeSubDocument.isHeaderFooter())
|
|
21
22
|
this.control.commandManager.getCommand(RichEditClientCommand.ChangeActiveSubDocumentToMain)
|
|
22
23
|
.execute(this.control.commandManager.isPublicApiCall, new CommandOptions(this.control));
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ICommandOptions } from '../command-base';
|
|
2
2
|
import { SimpleCommandState } from '../command-states';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { SelectionCommandBase } from './selection-command-base';
|
|
4
|
+
export declare class GoToNextWordCommandBase extends SelectionCommandBase {
|
|
5
5
|
getStartPosition(): number;
|
|
6
|
-
isEnabledInReadOnlyMode(): boolean;
|
|
7
6
|
}
|
|
8
7
|
export declare class GoToNextWordCommand extends GoToNextWordCommandBase {
|
|
9
8
|
executeCore(_state: SimpleCommandState, _options: ICommandOptions): boolean;
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import { LayoutWordBounds } from '../../word-bounds-engine/layout-word-bounds';
|
|
2
|
-
import { CommandBase } from '../command-base';
|
|
3
|
-
import { SimpleCommandState } from '../command-states';
|
|
4
2
|
import { ExtendGoToNextCharacterCommand } from './go-to-next-character-command';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return new SimpleCommandState(this.isEnabled());
|
|
8
|
-
}
|
|
3
|
+
import { SelectionCommandBase } from './selection-command-base';
|
|
4
|
+
export class GoToNextWordCommandBase extends SelectionCommandBase {
|
|
9
5
|
getStartPosition() {
|
|
10
6
|
var selection = this.selection;
|
|
11
7
|
return selection.forwardDirection ? selection.lastSelectedInterval.end : selection.lastSelectedInterval.start;
|
|
12
8
|
}
|
|
13
|
-
isEnabledInReadOnlyMode() {
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
9
|
}
|
|
17
10
|
export class GoToNextWordCommand extends GoToNextWordCommandBase {
|
|
18
11
|
executeCore(_state, _options) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ICommandOptions } from '../command-base';
|
|
2
2
|
import { SimpleCommandState } from '../command-states';
|
|
3
|
-
|
|
3
|
+
import { SelectionCommandBase } from './selection-command-base';
|
|
4
|
+
export declare abstract class GoToPrevWordCommandBase extends SelectionCommandBase {
|
|
4
5
|
getState(): SimpleCommandState;
|
|
5
6
|
getStartPosition(): number;
|
|
6
7
|
isEnabledInReadOnlyMode(): boolean;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { LayoutPositionCreatorConflictFlags, LayoutPositionMainSubDocumentCreator, LayoutPositionOtherSubDocumentCreator } from '../../layout-engine/layout-position-creator';
|
|
2
2
|
import { DocumentLayoutDetailsLevel } from '../../layout/document-layout-details-level';
|
|
3
3
|
import { LayoutWordBounds } from '../../word-bounds-engine/layout-word-bounds';
|
|
4
|
-
import { CommandBase } from '../command-base';
|
|
5
4
|
import { SimpleCommandState } from '../command-states';
|
|
6
5
|
import { ExtendGoToPrevCharacterCommand } from './go-to-prev-character-command';
|
|
7
|
-
|
|
6
|
+
import { SelectionCommandBase } from './selection-command-base';
|
|
7
|
+
export class GoToPrevWordCommandBase extends SelectionCommandBase {
|
|
8
8
|
getState() {
|
|
9
9
|
return new SimpleCommandState(this.isEnabled());
|
|
10
10
|
}
|
|
@@ -3,5 +3,7 @@ import { SimpleCommandState } from '../command-states';
|
|
|
3
3
|
export declare class SelectAllDocumentCommand extends CommandBase<SimpleCommandState> {
|
|
4
4
|
getState(): SimpleCommandState;
|
|
5
5
|
executeCore(_state: SimpleCommandState, _options: ICommandOptions): boolean;
|
|
6
|
+
protected beforeExecute(): void;
|
|
7
|
+
protected afterExecute(): void;
|
|
6
8
|
isEnabledInReadOnlyMode(): boolean;
|
|
7
9
|
}
|
|
@@ -12,6 +12,12 @@ export class SelectAllDocumentCommand extends CommandBase {
|
|
|
12
12
|
this.control.focusManager.captureFocus();
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
15
|
+
beforeExecute() {
|
|
16
|
+
this.control.screenReaderManager.beginExecute(this.commandId);
|
|
17
|
+
}
|
|
18
|
+
afterExecute() {
|
|
19
|
+
this.control.screenReaderManager.endExecute();
|
|
20
|
+
}
|
|
15
21
|
isEnabledInReadOnlyMode() {
|
|
16
22
|
return true;
|
|
17
23
|
}
|
|
@@ -8,4 +8,6 @@ export declare class SelectionCommandBase extends CommandBase<SimpleCommandState
|
|
|
8
8
|
protected shouldCollapseSingleCellTableSelection(entryDirection: TableNavDirection, shrinkDirection: TableNavDirection): boolean;
|
|
9
9
|
protected collapseSingleCellTableSelectionToCaret(): boolean;
|
|
10
10
|
protected collapseTableCellSelectionSpatialFocus(direction: TableNavDirection): boolean;
|
|
11
|
+
beforeExecute(): void;
|
|
12
|
+
afterExecute(): void;
|
|
11
13
|
}
|
|
@@ -98,4 +98,12 @@ export class SelectionCommandBase extends CommandBase {
|
|
|
98
98
|
selection.deprecatedSetSelection(pos, pos, false, -1, true);
|
|
99
99
|
return true;
|
|
100
100
|
}
|
|
101
|
+
beforeExecute() {
|
|
102
|
+
super.beforeExecute();
|
|
103
|
+
this.control.screenReaderManager.beginExecute(this.commandId);
|
|
104
|
+
}
|
|
105
|
+
afterExecute() {
|
|
106
|
+
super.afterExecute();
|
|
107
|
+
this.control.screenReaderManager.endExecute();
|
|
108
|
+
}
|
|
101
109
|
}
|
|
@@ -54,18 +54,12 @@ export class EventManager {
|
|
|
54
54
|
clearTimeout(this.onMouseUpTimerId);
|
|
55
55
|
}
|
|
56
56
|
onShortcut(shortcutCode) {
|
|
57
|
-
this.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.
|
|
63
|
-
if (EnumUtils.isAnyOf(shortcutCode, KeyCode.Enter, KeyCode.Tab, KeyCode.Space) && this.control.selection.lastSelectedInterval.start > 0)
|
|
64
|
-
this.control.autoCorrectService.performAutoCorrect();
|
|
65
|
-
}
|
|
66
|
-
finally {
|
|
67
|
-
this.control.endUpdate();
|
|
68
|
-
}
|
|
57
|
+
if (this.accumulatedText.length)
|
|
58
|
+
this.insertFunc();
|
|
59
|
+
this.control.shortcutManager.processShortcut(shortcutCode);
|
|
60
|
+
this.mouseHandler.onShortcut(shortcutCode);
|
|
61
|
+
if (EnumUtils.isAnyOf(shortcutCode, KeyCode.Enter, KeyCode.Tab, KeyCode.Space) && this.control.selection.lastSelectedInterval.start > 0)
|
|
62
|
+
this.control.autoCorrectService.performAutoCorrect();
|
|
69
63
|
}
|
|
70
64
|
onMouseDown(evt) {
|
|
71
65
|
Log.print(LogSource.EventManager, "onMouseDown", LogObjToStrCanvas.richMouseEvent(evt));
|
|
@@ -22,7 +22,7 @@ export class TxtExporter {
|
|
|
22
22
|
this.model.mainSubDocument.paragraphs.forEach((p, index) => {
|
|
23
23
|
if (index > 0)
|
|
24
24
|
text += '\r\n';
|
|
25
|
-
text += this.model.mainSubDocument.getSimpleText(new FixedInterval(p.startLogPosition.value, p.length));
|
|
25
|
+
text += this.model.mainSubDocument.getSimpleText(new FixedInterval(p.startLogPosition.value, p.length - 1));
|
|
26
26
|
});
|
|
27
27
|
callback(new Blob([text], { type: PlainTextMimeType }));
|
|
28
28
|
});
|
|
@@ -91,6 +91,7 @@ export class InputEditorBase {
|
|
|
91
91
|
createHierarchy(parent) {
|
|
92
92
|
this.inputElement = this.createInputElement();
|
|
93
93
|
this.inputElement.classList.add(INPUT_CLASS_NAME);
|
|
94
|
+
this.inputElement.setAttribute('aria-hidden', 'true');
|
|
94
95
|
parent.appendChild(this.inputElement);
|
|
95
96
|
this.createHierarchyCore();
|
|
96
97
|
this.inputElement.addEventListener("load", () => this.recreateIfNeeded(), true);
|
|
@@ -585,6 +586,7 @@ export class IFrameInputEditor extends InputEditorBase {
|
|
|
585
586
|
}
|
|
586
587
|
createInputElement() {
|
|
587
588
|
const element = document.createElement("IFRAME");
|
|
589
|
+
element.setAttribute("aria-hidden", "true");
|
|
588
590
|
element.src = "about:blank";
|
|
589
591
|
if (Browser.Safari) {
|
|
590
592
|
element.style.width = "100%";
|
|
@@ -38,6 +38,7 @@ import { SearchManager } from '../ui/search-manager';
|
|
|
38
38
|
import { IControlOwner } from './i-control-owner';
|
|
39
39
|
import { IExportModelOptions } from '../formats/i-document-exporter';
|
|
40
40
|
import { ModelScrollManager } from '../scroll/model-scroll-manager';
|
|
41
|
+
import { ScreenReaderManager } from '../screen-reader-manager';
|
|
41
42
|
export interface IBarListener extends IEventListener {
|
|
42
43
|
NotifyBarCommandExecuted(commandID: RichEditClientCommand, parameter: any): any;
|
|
43
44
|
NotifyBarUpdateRequested(): any;
|
|
@@ -86,6 +87,7 @@ export interface IRichEditControl extends IBatchUpdatableObject, IDisposable, IR
|
|
|
86
87
|
owner: IControlOwner;
|
|
87
88
|
selectionModelChangesListener: SelectionModelChangesListener;
|
|
88
89
|
pdfHelperFrame: PdfHelperFrame;
|
|
90
|
+
screenReaderManager: ScreenReaderManager;
|
|
89
91
|
getExportModelOptions(initOptions?: Partial<IExportModelOptions>): IExportModelOptions;
|
|
90
92
|
isClientMode(): boolean;
|
|
91
93
|
createFieldRequestManager(): FieldRequestManager;
|
|
@@ -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 ==
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
410
|
-
|
|
411
|
-
|
|
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;
|
|
@@ -44,6 +44,9 @@ export declare class SubDocument {
|
|
|
44
44
|
getFirstParagraph(): Paragraph;
|
|
45
45
|
getText(interval?: FixedInterval): string;
|
|
46
46
|
getSimpleText(interval: ConstInterval): string;
|
|
47
|
+
getVisibleText(interval: ConstInterval, options?: IGetTextOptions): string;
|
|
48
|
+
private resolveChar;
|
|
49
|
+
private isPositionVisible;
|
|
47
50
|
splitRun(position: number): void;
|
|
48
51
|
getLastRun(): RunBase;
|
|
49
52
|
getFirstRun(): RunBase;
|
|
@@ -123,3 +126,18 @@ export declare class SubDocumentIntervals implements ISubDocumentIntervals {
|
|
|
123
126
|
equals(obj: SubDocumentIntervals): boolean;
|
|
124
127
|
static fromPosition(subDocument: SubDocument, pos: number): SubDocumentIntervals;
|
|
125
128
|
}
|
|
129
|
+
export declare enum TransformAction {
|
|
130
|
+
InsertBefore = 0,
|
|
131
|
+
Replace = 1,
|
|
132
|
+
InsertAfter = 2
|
|
133
|
+
}
|
|
134
|
+
export interface IGetTextOptions {
|
|
135
|
+
charMap?: Record<string, string>;
|
|
136
|
+
includeNumberedListMarks?: boolean;
|
|
137
|
+
forceFieldResultText?: boolean;
|
|
138
|
+
transform?: (info: FullChunkAndRunInfo, fieldIndexes: number[]) => ITransformResult | string | null;
|
|
139
|
+
}
|
|
140
|
+
export interface ITransformResult {
|
|
141
|
+
text?: string | null;
|
|
142
|
+
action: TransformAction;
|
|
143
|
+
}
|
|
@@ -5,13 +5,14 @@ import { SearchUtils } from '@devexpress/utils/lib/utils/search';
|
|
|
5
5
|
import { SpellCheckerIntervalsManager } from '../spelling/intervals-manager';
|
|
6
6
|
import { RunIterator } from './character/run-iterator';
|
|
7
7
|
import { ResetFormattingCacheType } from './document-model';
|
|
8
|
-
import { Field } from './fields/field';
|
|
9
8
|
import { FullChunkAndRunInfo } from './full-chunk-and-run-info';
|
|
10
9
|
import { BookmarksManipulator } from './manipulators/bookmarks-manipulator';
|
|
11
10
|
import { ModelIterator } from './model-iterator';
|
|
12
11
|
import { PositionManager } from './position/position-manager';
|
|
13
12
|
import { RichUtils } from './rich-utils';
|
|
14
13
|
import { RunType } from './runs/run-type';
|
|
14
|
+
import { ParagraphIterator } from '../layout-formatter/box/generator/one-dimension-itertors';
|
|
15
|
+
import { FieldIterator } from '../layout-formatter/box/generator/recursive-objects-iterators';
|
|
15
16
|
export class SubDocument {
|
|
16
17
|
static { this.AUTOGENERATE_ID = -1; }
|
|
17
18
|
static { this.MAIN_SUBDOCUMENT_ID = 0; }
|
|
@@ -63,36 +64,78 @@ export class SubDocument {
|
|
|
63
64
|
return buffer;
|
|
64
65
|
}
|
|
65
66
|
getSimpleText(interval) {
|
|
66
|
-
|
|
67
|
+
return this.getVisibleText(interval, {
|
|
68
|
+
forceFieldResultText: true,
|
|
69
|
+
charMap: {
|
|
70
|
+
[RichUtils.specialCharacters.LineBreak]: ' ',
|
|
71
|
+
[RichUtils.specialCharacters.SectionMark]: '\r\n',
|
|
72
|
+
[RichUtils.specialCharacters.ParagraphMark]: '\r\n'
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
getVisibleText(interval, options = {}) {
|
|
77
|
+
let result = [];
|
|
67
78
|
let pos = interval.start;
|
|
68
|
-
|
|
69
|
-
const fieldIndex = Field.normedBinaryIndexOf(this.fields, pos);
|
|
70
|
-
if (fieldIndex > -1) {
|
|
71
|
-
let field = this.fields[fieldIndex];
|
|
72
|
-
while (field.parent)
|
|
73
|
-
field = field.parent;
|
|
74
|
-
pos = field.getFieldStartPosition();
|
|
75
|
-
}
|
|
79
|
+
const { charMap = {}, forceFieldResultText = false, includeNumberedListMarks = false, transform } = options;
|
|
76
80
|
const iterator = new ModelIterator(this, true);
|
|
77
81
|
iterator.setPosition(pos);
|
|
82
|
+
const fieldIterator = new FieldIterator(this.fields);
|
|
83
|
+
fieldIterator.init(pos);
|
|
84
|
+
const paragraphIterator = new ParagraphIterator(this.paragraphs);
|
|
85
|
+
paragraphIterator.init(pos);
|
|
78
86
|
while (pos < interval.end) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (
|
|
88
|
-
|
|
87
|
+
if (this.isPositionVisible(pos, fieldIterator.indexes, forceFieldResultText)) {
|
|
88
|
+
const paragraph = this.paragraphs[paragraphIterator.index];
|
|
89
|
+
if (includeNumberedListMarks && pos === paragraph.startLogPosition.value && paragraph.isInList())
|
|
90
|
+
result.push(paragraph.getNumberingListText() + paragraph.getNumberingListSeparatorChar());
|
|
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
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else
|
|
104
|
+
this.resolveChar(iterator, result, charMap);
|
|
105
|
+
if (!iterator.moveToNextChar())
|
|
89
106
|
break;
|
|
90
107
|
}
|
|
91
|
-
if (!iterator.
|
|
108
|
+
else if (!iterator.moveToNextRun())
|
|
92
109
|
break;
|
|
93
110
|
pos = iterator.getAbsolutePosition();
|
|
111
|
+
paragraphIterator.update(pos);
|
|
112
|
+
fieldIterator.update(pos);
|
|
113
|
+
}
|
|
114
|
+
return result.join("");
|
|
115
|
+
}
|
|
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) {
|
|
129
|
+
for (const index of fieldIndexes) {
|
|
130
|
+
const field = this.fields[index];
|
|
131
|
+
const isCodeView = !forceFieldResultText && field.showCode;
|
|
132
|
+
const invisibleInterval = isCodeView
|
|
133
|
+
? field.getResultIntervalWithBorders()
|
|
134
|
+
: field.getCodeIntervalWithBorders();
|
|
135
|
+
if (invisibleInterval.contains(pos))
|
|
136
|
+
return false;
|
|
94
137
|
}
|
|
95
|
-
return
|
|
138
|
+
return true;
|
|
96
139
|
}
|
|
97
140
|
splitRun(position) {
|
|
98
141
|
var info = this.getRunAndIndexesByPosition(position);
|
|
@@ -466,6 +509,12 @@ export class SubDocumentIntervals {
|
|
|
466
509
|
return new SubDocumentIntervals(subDocument, [new FixedInterval(pos, 0)]);
|
|
467
510
|
}
|
|
468
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 = {}));
|
|
469
518
|
function internalValidateInterval(subDocument, interval) {
|
|
470
519
|
const documentEndPosition = subDocument.getDocumentEndPosition();
|
|
471
520
|
if (interval.start == 0 && interval.end == documentEndPosition)
|
|
@@ -38,6 +38,7 @@ import { RulerSettings } from './ui/ruler/settings';
|
|
|
38
38
|
import { SearchManager } from './ui/search-manager';
|
|
39
39
|
import { IExportModelOptions } from './formats/i-document-exporter';
|
|
40
40
|
import { ModelScrollManager } from './scroll/model-scroll-manager';
|
|
41
|
+
import { ScreenReaderManager } from './screen-reader-manager';
|
|
41
42
|
export declare abstract class RichEditCore implements IRichEditControl {
|
|
42
43
|
modelManager: IModelManager;
|
|
43
44
|
barHolder: IBarHolder;
|
|
@@ -71,6 +72,7 @@ export declare abstract class RichEditCore implements IRichEditControl {
|
|
|
71
72
|
owner: IControlOwner;
|
|
72
73
|
selectionModelChangesListener: SelectionModelChangesListener;
|
|
73
74
|
readonly pdfHelperFrame: PdfHelperFrame;
|
|
75
|
+
screenReaderManager: ScreenReaderManager;
|
|
74
76
|
private closed;
|
|
75
77
|
sessionGuid: string;
|
|
76
78
|
private clientGuid;
|
|
@@ -119,6 +121,7 @@ export declare abstract class RichEditCore implements IRichEditControl {
|
|
|
119
121
|
getExportModelOptions(initOptions?: Partial<IExportModelOptions>): IExportModelOptions;
|
|
120
122
|
ensureDocumentIsFullyFormatted(): void;
|
|
121
123
|
protected abstract createSpellChecker(): any;
|
|
124
|
+
protected createAriaLiveElement(element: HTMLElement): HTMLDivElement;
|
|
122
125
|
protected createViewElement(id: string, element: HTMLElement): HTMLDivElement;
|
|
123
126
|
private isUsedInnerClipboard;
|
|
124
127
|
getExportDocumentFormat(): DocumentFormat;
|