devexpress-richedit 24.1.8-build-24316-0102 → 24.1.8-build-24340-0103
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/dist/dx.richedit.js +139 -75
- package/dist/dx.richedit.min.js +1 -1
- package/lib/client/formats/docx/export/exporters/styles.d.ts +5 -0
- package/lib/client/formats/docx/export/exporters/styles.js +30 -1
- package/lib/client/model-api/api-utils/range-permission-finder.js +3 -1
- package/lib/client/model-api/collections/drawing-object-collection.js +1 -1
- package/lib/client/model-api/collections/range-permission-collection.js +3 -2
- package/lib/common/commands/floating-objects/floating-object-drag-drop-change-position-command.js +1 -1
- package/lib/common/commands/floating-objects/insert-anchored-text-box-command.js +1 -1
- package/lib/common/formats/html/export/html-export.d.ts +1 -0
- package/lib/common/formats/html/export/html-export.js +19 -33
- package/lib/common/formats/html/import/importers/list-base.js +4 -4
- package/lib/common/formats/rtf/export/helpers/rtf-export-helper.js +3 -2
- package/lib/common/input-controller.d.ts +14 -1
- package/lib/common/input-controller.js +54 -19
- package/lib/common/layout/document-layout.js +1 -1
- package/lib/common/layout/main-structures/layout-boxes/layout-space-box.js +1 -1
- package/lib/common/model/history/items/floating-objects/insert-anchored-picture-history-item.js +1 -0
- package/lib/common/model/history/items/switch-text-box-sub-documents-state-history-item.js +0 -1
- package/lib/common/model/manipulators/range/remove-interval-operation.js +8 -2
- package/lib/common/model/manipulators/text-box-manipulator.d.ts +1 -1
- package/lib/common/model/manipulators/text-box-manipulator.js +2 -1
- package/lib/common/model/range-permissions.js +6 -4
- package/lib/common/selection/selection.js +2 -1
- package/package.json +3 -3
@@ -4,8 +4,13 @@ export declare class StylesExporter extends ExporterBaseWithRootElement {
|
|
4
4
|
get rootElement(): string;
|
5
5
|
get rootNSPrefix(): string;
|
6
6
|
get rootNSValue(): string;
|
7
|
+
private styleNameToIndex;
|
8
|
+
private sortedStyleIndexes;
|
9
|
+
private processedStyleNames;
|
7
10
|
protected fillWriter(): void;
|
8
11
|
private exportDocumentDefaults;
|
9
12
|
private exportDocumentCharacterDefaults;
|
10
13
|
private exportDocumentParagraphDefaults;
|
14
|
+
private getSortedStyleIndexes;
|
15
|
+
private sortStyleIndexRecursive;
|
11
16
|
}
|
@@ -3,13 +3,20 @@ import { ListUtils } from '@devexpress/utils/lib/utils/list';
|
|
3
3
|
import { DocxNsType } from '../../utils/constants';
|
4
4
|
import { ExporterBaseWithRootElement } from './base';
|
5
5
|
export class StylesExporter extends ExporterBaseWithRootElement {
|
6
|
+
constructor() {
|
7
|
+
super(...arguments);
|
8
|
+
this.styleNameToIndex = new Map();
|
9
|
+
this.sortedStyleIndexes = [];
|
10
|
+
this.processedStyleNames = new Set();
|
11
|
+
}
|
6
12
|
get filePath() { return 'word/styles.xml'; }
|
7
13
|
get rootElement() { return 'styles'; }
|
8
14
|
get rootNSPrefix() { return this.data.constants.namespaces[DocxNsType.WordProcessing].prefix; }
|
9
15
|
get rootNSValue() { return this.data.constants.namespaces[DocxNsType.WordProcessing].namespace; }
|
10
16
|
fillWriter() {
|
11
17
|
this.exportDocumentDefaults();
|
12
|
-
|
18
|
+
const paragraphStyleIndexes = this.getSortedStyleIndexes();
|
19
|
+
ListUtils.forEach(paragraphStyleIndexes, (index) => this.data.parStyleExporter.export(this.data.model.paragraphStyles[index], index));
|
13
20
|
ListUtils.forEach(this.data.model.characterStyles, (style, index) => this.data.charStyleExporter.export(style, index));
|
14
21
|
ListUtils.forEach(this.data.model.tableStyles, (style, index) => this.data.tblStyleExporter.export(style, index));
|
15
22
|
}
|
@@ -33,4 +40,26 @@ export class StylesExporter extends ExporterBaseWithRootElement {
|
|
33
40
|
this.writer.endElement();
|
34
41
|
this.writer.endElement();
|
35
42
|
}
|
43
|
+
getSortedStyleIndexes() {
|
44
|
+
this.styleNameToIndex = new Map();
|
45
|
+
this.sortedStyleIndexes = [];
|
46
|
+
this.processedStyleNames = new Set();
|
47
|
+
const styles = this.data.model.paragraphStyles;
|
48
|
+
styles.forEach((style, index) => this.styleNameToIndex.set(style.styleName, index));
|
49
|
+
for (let index = 0; index < styles.length; index++)
|
50
|
+
this.sortStyleIndexRecursive(index);
|
51
|
+
return this.sortedStyleIndexes;
|
52
|
+
}
|
53
|
+
sortStyleIndexRecursive(index) {
|
54
|
+
const styles = this.data.model.paragraphStyles;
|
55
|
+
const style = styles[index];
|
56
|
+
if (this.processedStyleNames.has(style.styleName))
|
57
|
+
return;
|
58
|
+
this.processedStyleNames.add(style.styleName);
|
59
|
+
if (style.parent) {
|
60
|
+
const parentIndex = this.styleNameToIndex.get(style.parent.styleName);
|
61
|
+
this.sortStyleIndexRecursive(parentIndex);
|
62
|
+
}
|
63
|
+
this.sortedStyleIndexes.push(index);
|
64
|
+
}
|
36
65
|
}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { IntervalAlgorithms } from '@devexpress/utils/lib/intervals/algorithms';
|
2
|
+
import { Comparers } from '@devexpress/utils/lib/utils/comparers';
|
2
3
|
import { ListUtils } from '@devexpress/utils/lib/utils/list';
|
3
4
|
export function findRangePermissionsByIntervals(sourceCollection, intervals) {
|
4
5
|
const permissions = [];
|
@@ -19,5 +20,6 @@ export function findRangePermissions(sourceCollection, check) {
|
|
19
20
|
}
|
20
21
|
export function findRangePermission(sourceCollection, coreInterval, userName, group) {
|
21
22
|
const intervals = findRangePermissionsByIntervals(sourceCollection, [coreInterval]);
|
22
|
-
return ListUtils.elementBy(intervals, (permission) => permission.userName ==
|
23
|
+
return ListUtils.elementBy(intervals, (permission) => Comparers.stringIgnoreCase(permission.userName, userName) == 0 &&
|
24
|
+
Comparers.stringIgnoreCase(permission.group, group) == 0);
|
23
25
|
}
|
@@ -59,7 +59,7 @@ export class TextBoxCollection extends DrawingObjectCollectionBase {
|
|
59
59
|
const anchorInfo = new AnchorInfo();
|
60
60
|
anchorInfo.zOrder = this._processor.modelManager.modelManipulator.floatingObject.zOrder.getNewZOrder(this._subDocument);
|
61
61
|
const inputPos = new InputPositionBase().setIntervals(SelectionIntervalsInfo.fromPosition(this._subDocument, position));
|
62
|
-
this._processor.modelManager.modelManipulator.textBox.
|
62
|
+
this._processor.modelManager.modelManipulator.textBox.insertAnchoredTextBoxViaHistory(new SubDocumentPosition(this._subDocument, position), inputPos.charPropsBundle, new BaseTextBoxInfo(null, size, new Shape(ColorUtils.fromString(ColorUtils.colorNames.white), ColorHelper.BLACK_COLOR, UnitConverter.pointsToTwips(3.0 / 4)), anchorInfo, textBoxProperties, new NonVisualDrawingObjectInfo()));
|
63
63
|
const textBoxRun = this._subDocument.getRunByPosition(position);
|
64
64
|
return new TextBoxApi(this._processor.modelManager, this._subDocument, textBoxRun, position);
|
65
65
|
}
|
@@ -10,6 +10,7 @@ import { ModelParametersChecker } from '../api-utils/model-parameter-checker';
|
|
10
10
|
import { findRangePermission, findRangePermissions, findRangePermissionsByIntervals } from '../api-utils/range-permission-finder';
|
11
11
|
import { RangePermissionApi } from '../range-permission';
|
12
12
|
import { Collection } from './collection';
|
13
|
+
import { Comparers } from '@devexpress/utils/lib/utils/comparers';
|
13
14
|
export class RangePermissionCollection extends Collection {
|
14
15
|
constructor(processor, subDocument) {
|
15
16
|
super(processor);
|
@@ -81,13 +82,13 @@ function findByPosition(position, canBeUndefined, sourceCollection) {
|
|
81
82
|
}
|
82
83
|
function findByUserName(value, permissions) {
|
83
84
|
return ListUtils.map(ApiParametersChecker.check(value, 1, true, [
|
84
|
-
ApiParametersChecker.stringDescriptor("userName", (userName) => findRangePermissions(permissions, permission => permission.userName ==
|
85
|
+
ApiParametersChecker.stringDescriptor("userName", (userName) => findRangePermissions(permissions, permission => Comparers.stringIgnoreCase(permission.userName, userName) == 0), false),
|
85
86
|
ApiParametersChecker.regExpDescriptor('regexp', (regexp) => findRangePermissions(permissions, permission => regexp.test(permission.userName)))
|
86
87
|
]), (b) => b);
|
87
88
|
}
|
88
89
|
function findByGroup(value, permissions) {
|
89
90
|
return ListUtils.map(ApiParametersChecker.check(value, 1, true, [
|
90
|
-
ApiParametersChecker.stringDescriptor("group", (group) => findRangePermissions(permissions, permission => permission.group ==
|
91
|
+
ApiParametersChecker.stringDescriptor("group", (group) => findRangePermissions(permissions, permission => Comparers.stringIgnoreCase(permission.group, group) == 0), false),
|
91
92
|
ApiParametersChecker.regExpDescriptor('regexp', (regexp) => findRangePermissions(permissions, permission => regexp.test(permission.group)))
|
92
93
|
]), (b) => b);
|
93
94
|
}
|
package/lib/common/commands/floating-objects/floating-object-drag-drop-change-position-command.js
CHANGED
@@ -200,7 +200,7 @@ export class FloatingObjectDragDropChangePositionCommand extends CommandBase {
|
|
200
200
|
const newRun = this.activeSubDocument.getRunAndIndexesByPosition(position).run;
|
201
201
|
if (newRun.getType() == RunType.AnchoredTextBoxRun) {
|
202
202
|
const oldTextBoxRun = oldRun;
|
203
|
-
const originalSubDocument = this.control.modelManager.model.
|
203
|
+
const originalSubDocument = this.control.modelManager.model.subDocumentsCollection.collection[oldTextBoxRun.subDocId];
|
204
204
|
this.history.addAndRedo(new SwitchTextBoxSubDocumentsStateHistoryItem(this.modelManipulator, originalSubDocument, this.activeSubDocument, position));
|
205
205
|
}
|
206
206
|
}
|
@@ -44,7 +44,7 @@ export class InsertAnchoredTextBoxCommand extends CommandBase {
|
|
44
44
|
anchorInfo.zOrder = this.modelManipulator.floatingObject.zOrder.getNewZOrder(options.subDocument);
|
45
45
|
anchorInfo.layoutTableCell = true;
|
46
46
|
history.addTransaction(() => {
|
47
|
-
this.modelManipulator.textBox.
|
47
|
+
this.modelManipulator.textBox.insertAnchoredTextBoxViaHistory(new SubDocumentPosition(this.selection.activeSubDocument, this.selection.lastSelectedInterval.start), this.inputPosition.charPropsBundle, new BaseTextBoxInfo(null, size, new Shape(ColorUtils.fromString(ColorUtils.colorNames.white), ColorHelper.BLACK_COLOR, UnitConverter.pointsToTwips(3.0 / 4)), anchorInfo, textBoxProperties, new NonVisualDrawingObjectInfo()));
|
48
48
|
this.history.addAndRedo(new SelectionHistoryItem(this.modelManipulator, this.selection, this.selection.getState(), this.selection.getState().setInterval(new FixedInterval(this.selection.lastSelectedInterval.start, 1))));
|
49
49
|
this.control.commandManager.getCommand(RichEditClientCommand.ChangeActiveSubDocumentToTextBox)
|
50
50
|
.execute(this.control.commandManager.isPublicApiCall, options);
|
@@ -6,6 +6,7 @@ import { SubDocument } from '../../../model/sub-document';
|
|
6
6
|
import { HtmlBuilder } from './html-builder';
|
7
7
|
import { IExportModelOptions } from '../../i-document-exporter';
|
8
8
|
interface List {
|
9
|
+
parentList?: List;
|
9
10
|
numberingListIndex: number;
|
10
11
|
listLevelIndex: number;
|
11
12
|
start: number;
|
@@ -24,6 +24,7 @@ import { TableWidthUnitType } from '../../../model/tables/secondary-structures/t
|
|
24
24
|
import { HtmlConverter } from '../../../rich-utils/html-converter';
|
25
25
|
import { HtmlBuilder } from './html-builder';
|
26
26
|
import { isDefined } from '@devexpress/utils/lib/utils/common';
|
27
|
+
import { ListUtils } from '@devexpress/utils/lib/utils/list';
|
27
28
|
export class HtmlExporter {
|
28
29
|
constructor(exportModelOptions) {
|
29
30
|
this.rangeCopy = null;
|
@@ -455,42 +456,27 @@ export class HtmlExporter {
|
|
455
456
|
}
|
456
457
|
getListsByParagraphs(paragraphs) {
|
457
458
|
const listsInInterval = [];
|
459
|
+
let previousList = null;
|
458
460
|
for (let i = 0, paragraph; paragraph = paragraphs[i]; i++) {
|
459
461
|
if (paragraph.isInList()) {
|
460
|
-
const
|
461
|
-
const
|
462
|
-
const
|
463
|
-
const
|
464
|
-
let
|
465
|
-
|
466
|
-
|
467
|
-
&&
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
existingItem.end = paragraphEnd;
|
474
|
-
}
|
475
|
-
else {
|
476
|
-
listsInInterval.push({
|
477
|
-
numberingListIndex: paragraphNumberingListIndex,
|
478
|
-
listLevelIndex: paragraphListLevelIndex,
|
479
|
-
start: paragraphStart,
|
480
|
-
end: paragraphEnd,
|
481
|
-
});
|
482
|
-
}
|
483
|
-
let listLevelIndex = paragraphListLevelIndex;
|
484
|
-
while (listLevelIndex > 0) {
|
485
|
-
let parentItem = null;
|
486
|
-
for (let j = 0; j < listsInInterval.length; j++) {
|
487
|
-
if (listsInInterval[j].listLevelIndex == listLevelIndex - 1)
|
488
|
-
parentItem = listsInInterval[j];
|
489
|
-
}
|
490
|
-
if (parentItem)
|
491
|
-
parentItem.end = paragraphEnd;
|
492
|
-
listLevelIndex--;
|
462
|
+
const numberingListIndex = paragraph.getNumberingListIndex();
|
463
|
+
const listLevelIndex = paragraph.getListLevelIndex();
|
464
|
+
const start = paragraph.startLogPosition.value;
|
465
|
+
const end = paragraph.getEndPosition();
|
466
|
+
let list = ListUtils.reverseElementBy(listsInInterval, (list) => {
|
467
|
+
return list.listLevelIndex <= (previousList === null || previousList === void 0 ? void 0 : previousList.listLevelIndex)
|
468
|
+
&& list.numberingListIndex === numberingListIndex
|
469
|
+
&& list.listLevelIndex === listLevelIndex;
|
470
|
+
});
|
471
|
+
if (!list) {
|
472
|
+
const parentList = (previousList === null || previousList === void 0 ? void 0 : previousList.numberingListIndex) === numberingListIndex ? previousList : null;
|
473
|
+
list = { parentList, numberingListIndex, listLevelIndex, start, end };
|
474
|
+
listsInInterval.push(list);
|
493
475
|
}
|
476
|
+
previousList = list;
|
477
|
+
do {
|
478
|
+
list.end = end;
|
479
|
+
} while (list = list.parentList);
|
494
480
|
}
|
495
481
|
}
|
496
482
|
return listsInInterval;
|
@@ -13,9 +13,7 @@ export class HtmlListTagImporterBase extends HtmlTagImporterBase {
|
|
13
13
|
this.importer.addCurrLevelParagraphRunIfNeeded();
|
14
14
|
const listIndex = this.importer.listIndex;
|
15
15
|
const parentList = ListUtils.last(this.importer.listInfos);
|
16
|
-
const listLevel = parentList
|
17
|
-
? parentList.listLevel + 1
|
18
|
-
: 0;
|
16
|
+
const listLevel = parentList ? parentList.listLevel + 1 : 0;
|
19
17
|
if (listLevel === 9) {
|
20
18
|
this._ignored = true;
|
21
19
|
return;
|
@@ -31,6 +29,8 @@ export class HtmlListTagImporterBase extends HtmlTagImporterBase {
|
|
31
29
|
if (this._ignored)
|
32
30
|
return;
|
33
31
|
this.importer.listInfos.pop();
|
34
|
-
this.importer.
|
32
|
+
const parentList = ListUtils.last(this.importer.listInfos);
|
33
|
+
if (!parentList)
|
34
|
+
this.importer.listIndex++;
|
35
35
|
}
|
36
36
|
}
|
@@ -4,6 +4,7 @@ import { DXColor } from '../../../../model/color/dx-color';
|
|
4
4
|
import { ListUtils } from '@devexpress/utils/lib/utils/list';
|
5
5
|
import { NumberMapUtils } from '@devexpress/utils/lib/utils/map/number';
|
6
6
|
import { RtfContentExporter } from '../exporters/rtf-content-exporter';
|
7
|
+
import { Comparers } from '@devexpress/utils/lib/utils/comparers';
|
7
8
|
export class RtfExportHelper {
|
8
9
|
constructor() {
|
9
10
|
this.colorCollection = [];
|
@@ -39,11 +40,11 @@ export class RtfExportHelper {
|
|
39
40
|
return DXColor.blend(color, DXColor.white);
|
40
41
|
}
|
41
42
|
getUserIndex(rangePermission) {
|
42
|
-
let index = this.userCollection.
|
43
|
+
let index = this.userCollection.findIndex((userName) => Comparers.stringIgnoreCase(userName, rangePermission.userName) == 0);
|
43
44
|
if (index >= 0)
|
44
45
|
return index + 1;
|
45
46
|
const predefinedUserGroups = RtfContentExporter.predefinedUserGroups;
|
46
|
-
const id = NumberMapUtils.keyBy(predefinedUserGroups, (g) => g
|
47
|
+
const id = NumberMapUtils.keyBy(predefinedUserGroups, (g) => Comparers.stringIgnoreCase(g, rangePermission.group) == 0);
|
47
48
|
return id != null ? id : 0;
|
48
49
|
}
|
49
50
|
}
|
@@ -4,6 +4,11 @@ import { IEventManager } from './interfaces/i-event-manager';
|
|
4
4
|
import { IRichEditControl } from './interfaces/i-rich-edit-core';
|
5
5
|
import { HtmlBuilder } from './formats/html/export/html-builder';
|
6
6
|
export declare const INPUT_CLASS_NAME = "dxreInputTarget";
|
7
|
+
declare enum IMEState {
|
8
|
+
None = 0,
|
9
|
+
Start = 1,
|
10
|
+
Process = 2
|
11
|
+
}
|
7
12
|
export declare abstract class InputEditorBase<TInpElement extends HTMLElement> {
|
8
13
|
private newLineRegexp;
|
9
14
|
eventManager: IEventManager;
|
@@ -14,7 +19,7 @@ export declare abstract class InputEditorBase<TInpElement extends HTMLElement> {
|
|
14
19
|
needProcessShortcut: boolean;
|
15
20
|
initializedIfNotReadOnly: boolean;
|
16
21
|
prevKeyCode: number;
|
17
|
-
|
22
|
+
IMEState: IMEState;
|
18
23
|
private inputWithAlt;
|
19
24
|
private processTextOnKeyPress;
|
20
25
|
protected evtHandlersHolder: DomEventHandlersHolder;
|
@@ -68,11 +73,15 @@ export declare class DivInputEditor extends InputEditorBase<HTMLElement> {
|
|
68
73
|
private cursorWasSetOnLastPosition;
|
69
74
|
private clearInputTimerId;
|
70
75
|
private lastCursorPosition;
|
76
|
+
private composUpdateTimerId;
|
77
|
+
private composEndTimerId;
|
78
|
+
private onTextInputTimerId;
|
71
79
|
constructor(control: IRichEditControl, eventManager: IEventManager, parent: HTMLElement);
|
72
80
|
dispose(): void;
|
73
81
|
initializeIfNotReadOnlyCore(): void;
|
74
82
|
setPosition(left: number, top: number): void;
|
75
83
|
createInputElement(): HTMLElement;
|
84
|
+
initEvents(): void;
|
76
85
|
onKeyDown(evt: KeyboardEvent): void;
|
77
86
|
onKeyUp(evt: KeyboardEvent): void;
|
78
87
|
onInput(evt: InputEvent): void;
|
@@ -93,6 +102,9 @@ export declare class DivInputEditor extends InputEditorBase<HTMLElement> {
|
|
93
102
|
getEditableDocumentContent(): string | NodeListOf<ChildNode>;
|
94
103
|
getEditableDocumentCursorPosition(): number;
|
95
104
|
selectEditableDocumentContent(): void;
|
105
|
+
onCompositionStart(_evt: KeyboardEvent): void;
|
106
|
+
onCompositionUpdate(_evt: KeyboardEvent): void;
|
107
|
+
onCompositionEnd(_evt: KeyboardEvent): void;
|
96
108
|
}
|
97
109
|
export declare class IFrameInputEditor extends InputEditorBase<HTMLIFrameElement> {
|
98
110
|
editableDocument: Document;
|
@@ -145,3 +157,4 @@ export declare class InputController {
|
|
145
157
|
getEditableDocumentContent(): string | NodeListOf<ChildNode>;
|
146
158
|
selectEditableDocumentContent(): void;
|
147
159
|
}
|
160
|
+
export {};
|
@@ -23,9 +23,16 @@ export const INPUT_CLASS_NAME = "dxreInputTarget";
|
|
23
23
|
const EMPTY_KEYCODE = 229;
|
24
24
|
const TAB_KEYCODE = 9;
|
25
25
|
const IDEOGRAPHIC_SPACE_CHARCODE = 12288;
|
26
|
+
var IMEState;
|
27
|
+
(function (IMEState) {
|
28
|
+
IMEState[IMEState["None"] = 0] = "None";
|
29
|
+
IMEState[IMEState["Start"] = 1] = "Start";
|
30
|
+
IMEState[IMEState["Process"] = 2] = "Process";
|
31
|
+
})(IMEState || (IMEState = {}));
|
26
32
|
export class InputEditorBase {
|
27
33
|
constructor(control, eventManager, parent) {
|
28
34
|
this.newLineRegexp = /(\r\n|\n|\r)/gm;
|
35
|
+
this.IMEState = IMEState.None;
|
29
36
|
this.processTextOnKeyPress = false;
|
30
37
|
this.evtHandlersHolder = new DomEventHandlersHolder();
|
31
38
|
this.control = control;
|
@@ -33,7 +40,6 @@ export class InputEditorBase {
|
|
33
40
|
this.canInsertTextOnInputEvent = this.canUseInputEvent();
|
34
41
|
this.createHierarchy(parent);
|
35
42
|
this.initialize();
|
36
|
-
this.isIME = false;
|
37
43
|
this.inputWithAlt = false;
|
38
44
|
}
|
39
45
|
dispose() {
|
@@ -106,7 +112,7 @@ export class InputEditorBase {
|
|
106
112
|
}
|
107
113
|
onKeyDown(evt) {
|
108
114
|
if (!this.control.clientSideEvents.raiseKeyDown(evt)) {
|
109
|
-
if (
|
115
|
+
if (this.IMEState === IMEState.None) {
|
110
116
|
evt = this.getNormalizedEvent(evt);
|
111
117
|
const keyCode = KeyUtils.getEventKeyCode(evt);
|
112
118
|
this.needProcessShortcut = !keyCode || keyCode == EMPTY_KEYCODE;
|
@@ -271,6 +277,9 @@ export class DivInputEditor extends InputEditorBase {
|
|
271
277
|
dispose() {
|
272
278
|
super.dispose();
|
273
279
|
clearTimeout(this.clearInputTimerId);
|
280
|
+
clearTimeout(this.composUpdateTimerId);
|
281
|
+
clearTimeout(this.composEndTimerId);
|
282
|
+
clearTimeout(this.onTextInputTimerId);
|
274
283
|
}
|
275
284
|
initializeIfNotReadOnlyCore() {
|
276
285
|
this.inputElement.contentEditable = "true";
|
@@ -281,14 +290,21 @@ export class DivInputEditor extends InputEditorBase {
|
|
281
290
|
}
|
282
291
|
createInputElement() {
|
283
292
|
const element = document.createElement("DIV");
|
284
|
-
|
285
|
-
element.autocapitalize = "off";
|
293
|
+
element.autocapitalize = "off";
|
286
294
|
if (Browser.MacOSMobilePlatform && (Number(Browser.PlaformMajorVersion) >= 16
|
287
295
|
|| Browser.Safari && Browser.MajorVersion >= 16)) {
|
288
296
|
element.classList.add('dxreiOS16');
|
289
297
|
}
|
290
298
|
return element;
|
291
299
|
}
|
300
|
+
initEvents() {
|
301
|
+
super.initEvents();
|
302
|
+
this.evtHandlersHolder.addListener(this.getEditableDocument(), "compositionstart", this.onCompositionStart.bind(this));
|
303
|
+
this.evtHandlersHolder.addListener(this.getEditableDocument(), "compositionupdate", (evt) => Browser.IE || Browser.Edge ?
|
304
|
+
this.onCompositionUpdate(evt) : this.composUpdateTimerId = setTimeout(() => this.onCompositionUpdate(evt), 0));
|
305
|
+
this.evtHandlersHolder.addListener(this.getEditableDocument(), "compositionend", (evt) => !Browser.Safari ?
|
306
|
+
this.onCompositionEnd(evt) : this.composEndTimerId = setTimeout(() => this.onCompositionEnd(evt), 0));
|
307
|
+
}
|
292
308
|
onKeyDown(evt) {
|
293
309
|
var _a;
|
294
310
|
this.handled = false;
|
@@ -357,21 +373,15 @@ export class DivInputEditor extends InputEditorBase {
|
|
357
373
|
this.onTextReplace(text.substr(lastWordStartIndex), text);
|
358
374
|
else
|
359
375
|
super.onTextInput(data);
|
360
|
-
if (this.previousText && text.length < this.previousText.length || !text.length) {
|
361
|
-
let deletedCharacterCount = this.previousText ? this.previousText.length - text.length : 1;
|
362
|
-
for (let i = 0; i < deletedCharacterCount; i++)
|
363
|
-
this.eventManager.onShortcut(KeyCode.Backspace);
|
364
|
-
this.previousText = text;
|
365
|
-
}
|
366
376
|
this.cursorWasSetOnLastPosition = true;
|
367
377
|
}
|
368
378
|
this.handled = true;
|
369
|
-
if (
|
379
|
+
if (text[text.length - 1] == " ")
|
370
380
|
this.clearInputElement();
|
371
381
|
}
|
372
382
|
}
|
373
383
|
tryHandleShortcutByInputString(data) {
|
374
|
-
if (data &&
|
384
|
+
if (data && this.IMEState === IMEState.None) {
|
375
385
|
let enteredChar = data.charAt(data.length - 1);
|
376
386
|
const keyCode = this.tryObtainCodeFromChar(enteredChar);
|
377
387
|
if (keyCode != EMPTY_KEYCODE) {
|
@@ -462,6 +472,31 @@ export class DivInputEditor extends InputEditorBase {
|
|
462
472
|
selection.selectAllChildren(this.inputElement);
|
463
473
|
super.selectEditableDocumentContent();
|
464
474
|
}
|
475
|
+
onCompositionStart(_evt) {
|
476
|
+
this.IMEState = IMEState.Start;
|
477
|
+
this.needProcessShortcut = false;
|
478
|
+
this.clearInputElement();
|
479
|
+
}
|
480
|
+
onCompositionUpdate(_evt) {
|
481
|
+
const text = this.getEditableDocumentText();
|
482
|
+
if (text.length && this.previousText != text) {
|
483
|
+
if (this.IMEState === IMEState.Start)
|
484
|
+
this.onText(text, text, this.previousText.length > 0);
|
485
|
+
else if (this.IMEState === IMEState.Process)
|
486
|
+
this.onTextReplace(text, text);
|
487
|
+
}
|
488
|
+
this.IMEState = IMEState.Process;
|
489
|
+
}
|
490
|
+
onCompositionEnd(_evt) {
|
491
|
+
const text = this.getEditableDocumentText();
|
492
|
+
if (this.previousText != text) {
|
493
|
+
if (text.length > 0)
|
494
|
+
this.onTextReplace(text, text);
|
495
|
+
else
|
496
|
+
this.onShortcutCore(_evt, KeyCode.Backspace);
|
497
|
+
}
|
498
|
+
this.IMEState = IMEState.None;
|
499
|
+
}
|
465
500
|
}
|
466
501
|
export class IFrameInputEditor extends InputEditorBase {
|
467
502
|
constructor(control, eventManager, parent) {
|
@@ -565,7 +600,7 @@ export class IFrameInputEditor extends InputEditorBase {
|
|
565
600
|
}
|
566
601
|
setEditableDocumentContent(content) {
|
567
602
|
super.setEditableDocumentContent(content);
|
568
|
-
this.
|
603
|
+
this.IMEState = IMEState.None;
|
569
604
|
this.editableDocument.body.innerHTML = "";
|
570
605
|
if (typeof content === "string")
|
571
606
|
this.editableDocument.body.innerHTML = content;
|
@@ -613,7 +648,7 @@ export class IFrameInputEditor extends InputEditorBase {
|
|
613
648
|
}
|
614
649
|
onBlur(evt) {
|
615
650
|
super.onBlur(evt);
|
616
|
-
this.
|
651
|
+
this.IMEState = IMEState.None;
|
617
652
|
this.endInputIME();
|
618
653
|
}
|
619
654
|
onShortcutCore(evt, shortcutCode) {
|
@@ -642,7 +677,7 @@ export class IFrameInputEditor extends InputEditorBase {
|
|
642
677
|
}
|
643
678
|
}
|
644
679
|
onCompositionStart(_evt) {
|
645
|
-
this.
|
680
|
+
this.IMEState = IMEState.Start;
|
646
681
|
this.needProcessShortcut = false;
|
647
682
|
if (!Browser.IE && !Browser.Edge)
|
648
683
|
this.clearInputElement();
|
@@ -650,10 +685,11 @@ export class IFrameInputEditor extends InputEditorBase {
|
|
650
685
|
}
|
651
686
|
onCompositionUpdate(_evt) {
|
652
687
|
const text = this.getEditableDocumentText();
|
653
|
-
if (this.
|
688
|
+
if (this.IMEState !== IMEState.None && text.length && this.previousText != text) {
|
654
689
|
this.onTextReplace(text, text);
|
655
690
|
this.updateInputIME();
|
656
691
|
}
|
692
|
+
this.IMEState = IMEState.Process;
|
657
693
|
}
|
658
694
|
onCompositionEnd(_evt) {
|
659
695
|
const text = this.getEditableDocumentText();
|
@@ -663,7 +699,7 @@ export class IFrameInputEditor extends InputEditorBase {
|
|
663
699
|
this.clearInputElement();
|
664
700
|
if (text.charCodeAt(text.length - 1) == IDEOGRAPHIC_SPACE_CHARCODE)
|
665
701
|
this.clearInputElement();
|
666
|
-
this.
|
702
|
+
this.IMEState = IMEState.None;
|
667
703
|
this.endInputIME();
|
668
704
|
}
|
669
705
|
startInputIME() {
|
@@ -797,9 +833,8 @@ export class InputController {
|
|
797
833
|
if (typeof html === 'string')
|
798
834
|
el.innerHTML = html;
|
799
835
|
});
|
800
|
-
if (typeof html !== "string")
|
836
|
+
if (typeof html !== "string")
|
801
837
|
builder.assignFrom(html);
|
802
|
-
}
|
803
838
|
builder.endChild('b');
|
804
839
|
builder.endChild('span');
|
805
840
|
builder.endChild('a');
|
@@ -19,7 +19,7 @@ export class AnchorObjectsPositionInfo {
|
|
19
19
|
}
|
20
20
|
add(obj, modelPosition) {
|
21
21
|
this.delete(obj.objectId);
|
22
|
-
this.cache[obj.objectId] = new ModelPositionHolder(modelPosition, this.model.
|
22
|
+
this.cache[obj.objectId] = new ModelPositionHolder(modelPosition, this.model.subDocumentsCollection.collection[obj.belongsToSubDocId].positionManager);
|
23
23
|
}
|
24
24
|
delete(id) {
|
25
25
|
const info = this.cache[id];
|
@@ -22,7 +22,7 @@ export class LayoutSpaceBox extends LayoutBox {
|
|
22
22
|
return LayoutBoxType.Space;
|
23
23
|
}
|
24
24
|
pushInfoForMeasure(info, showHiddenSymbols) {
|
25
|
-
info.push(new MeasureInfoNonText(
|
25
|
+
info.push(new MeasureInfoNonText(RichUtils.specialCharacters.Space, this.characterProperties));
|
26
26
|
if (showHiddenSymbols)
|
27
27
|
info.push(new MeasureInfoNonText(RichUtils.specialCharacters.HiddenSpace, this.characterProperties));
|
28
28
|
}
|
package/lib/common/model/history/items/floating-objects/insert-anchored-picture-history-item.js
CHANGED
@@ -23,6 +23,7 @@ export class InsertAnchoredTextBoxHistoryItem extends PositionBasedHistoryItem {
|
|
23
23
|
}
|
24
24
|
redo() {
|
25
25
|
this.modelManipulator.textBox.insertAnchoredTextBox(this.subDocPos, this.charPropsBundle, this.textBoxInfo);
|
26
|
+
this.modelManipulator.model.subDocumentsCollection.restore(this.textBoxInfo.innerSubDocument.id);
|
26
27
|
}
|
27
28
|
undo() {
|
28
29
|
this.modelManipulator.range.removeIntervalWithoutHistory(this.boundSubDocument, new FixedInterval(this.position, 1), false);
|
@@ -7,7 +7,6 @@ export class SwitchTextBoxSubDocumentsStateHistoryItem extends HistoryItem {
|
|
7
7
|
this.position = position;
|
8
8
|
}
|
9
9
|
redo() {
|
10
|
-
this.oldSubDocument = this.oldSubDocument.getActualSubDocument();
|
11
10
|
const newRun = this.textBoxParentSubDocument.getRunAndIndexesByPosition(this.position).run;
|
12
11
|
this.newSubDocument = this.modelManipulator.model.subDocuments[newRun.subDocId];
|
13
12
|
this.modelManipulator.model.subDocumentsCollection.replace(this.oldSubDocument.id, this.newSubDocument.id);
|
@@ -54,8 +54,14 @@ export class RemoveIntervalOperation {
|
|
54
54
|
var accumulatedInterval = new FixedInterval(this.position, 0);
|
55
55
|
let removedTextList = [];
|
56
56
|
while (iterator.moveNext()) {
|
57
|
-
if (EnumUtils.isAnyOf(iterator.currentRun.getType(), RunType.AnchoredPictureRun, RunType.AnchoredTextBoxRun))
|
58
|
-
|
57
|
+
if (EnumUtils.isAnyOf(iterator.currentRun.getType(), RunType.AnchoredPictureRun, RunType.AnchoredTextBoxRun)) {
|
58
|
+
const currentRun = iterator.currentRun;
|
59
|
+
const position = iterator.currentInterval().start;
|
60
|
+
const change = new AnchorObjectRemovedSubDocumentChange(this.subDocument.id, currentRun.anchoredObjectID, position);
|
61
|
+
if (currentRun instanceof AnchoredTextBoxRun)
|
62
|
+
this.modelManipulator.model.subDocumentsCollection.replace(currentRun.subDocId, subDocument.id);
|
63
|
+
this.modelManipulator.notifyModelChanged(change);
|
64
|
+
}
|
59
65
|
if (iterator.currentChunk !== subDocument.chunks[this.currentChunkIndex]) {
|
60
66
|
this.removeAccumulatedInterval(accumulatedInterval, this.position, 0, removedTextList);
|
61
67
|
this.currentChunkIndex++;
|
@@ -17,6 +17,6 @@ export declare class BaseTextBoxInfo {
|
|
17
17
|
constructor(innerSubDocument: SubDocument, size: AnchorTextBoxSize, shape: Shape, anchorInfo: AnchorInfo, textBoxProperties: TextBoxProperties, containerProperties: NonVisualDrawingObjectInfo);
|
18
18
|
}
|
19
19
|
export declare class TextBoxManipulator extends RunsBaseManipulator {
|
20
|
-
|
20
|
+
insertAnchoredTextBoxViaHistory(subDocPos: SubDocumentPosition, charPropsBundle: MaskedCharacterPropertiesBundle, textBoxInfo: BaseTextBoxInfo): void;
|
21
21
|
insertAnchoredTextBox(subDocPos: SubDocumentPosition, charPropsBundle: MaskedCharacterPropertiesBundle, textBoxInfo: BaseTextBoxInfo): AnchoredTextBoxRun;
|
22
22
|
}
|
@@ -16,7 +16,7 @@ export class BaseTextBoxInfo {
|
|
16
16
|
}
|
17
17
|
}
|
18
18
|
export class TextBoxManipulator extends RunsBaseManipulator {
|
19
|
-
|
19
|
+
insertAnchoredTextBoxViaHistory(subDocPos, charPropsBundle, textBoxInfo) {
|
20
20
|
this.history.addAndRedo(new InsertAnchoredTextBoxHistoryItem(this.modelManipulator, subDocPos, charPropsBundle, textBoxInfo));
|
21
21
|
}
|
22
22
|
insertAnchoredTextBox(subDocPos, charPropsBundle, textBoxInfo) {
|
@@ -33,6 +33,7 @@ export class TextBoxManipulator extends RunsBaseManipulator {
|
|
33
33
|
let textBoxSubDoc = textBoxInfo.innerSubDocument ?
|
34
34
|
textBoxInfo.innerSubDocument :
|
35
35
|
this.model.createSubDocument(SubDocumentInfoType.TextBox, subDocument.id);
|
36
|
+
textBoxInfo.innerSubDocument = textBoxSubDoc;
|
36
37
|
textBoxRun.subDocId = textBoxSubDoc.id;
|
37
38
|
subDocument.chunks[insertedRun.chunkIndex].textRuns[insertedRun.runIndex].paragraph.length++;
|
38
39
|
this.modelManipulator.notifyModelChanged(new AnchoredTextBoxInsertedSubDocumentChange(subDocument.id, textBoxRun.anchoredObjectID, textBoxRun.subDocId, insertPositionAtStartDocument, textBoxInfo.anchorInfo, textBoxRun.containerProperties));
|
@@ -7,8 +7,8 @@ import { BookmarkBase } from './bookmarks';
|
|
7
7
|
export class RangePermission extends BookmarkBase {
|
8
8
|
constructor(positionManager, interval, userName, group) {
|
9
9
|
super(positionManager, interval);
|
10
|
-
this.userName = userName
|
11
|
-
this.group = group
|
10
|
+
this.userName = userName;
|
11
|
+
this.group = group;
|
12
12
|
}
|
13
13
|
isGranted(settings) {
|
14
14
|
return RangePermission.allow(this.group, RangePermission.Everyone_GROUP_NAME) ||
|
@@ -17,7 +17,7 @@ export class RangePermission extends BookmarkBase {
|
|
17
17
|
RangePermission.allow(this.group, settings.authenticationGroup);
|
18
18
|
}
|
19
19
|
static allow(permissionValue, settingsValue) {
|
20
|
-
return settingsValue != "" && permissionValue ==
|
20
|
+
return settingsValue != "" && Comparers.stringIgnoreCase(permissionValue, settingsValue) == 0;
|
21
21
|
}
|
22
22
|
get end() { return this._interval.end - 1; }
|
23
23
|
get length() { return this.end - this.start; }
|
@@ -42,7 +42,9 @@ export class RangePermission extends BookmarkBase {
|
|
42
42
|
return new RangePermission(positionManager, this.interval, this.userName, this.group);
|
43
43
|
}
|
44
44
|
equals(obj) {
|
45
|
-
return super.equals(obj) && (StringUtils.isNullOrEmpty(this.userName) ?
|
45
|
+
return super.equals(obj) && (StringUtils.isNullOrEmpty(this.userName) ?
|
46
|
+
Comparers.stringIgnoreCase(obj.group, this.group) == 0 :
|
47
|
+
Comparers.stringIgnoreCase(obj.userName, this.userName) == 0);
|
46
48
|
}
|
47
49
|
}
|
48
50
|
RangePermission.Everyone_GROUP_NAME = "Everyone".toLowerCase();
|
@@ -205,8 +205,9 @@ export class Selection extends BatchUpdatableObject {
|
|
205
205
|
this.resetInputPositionIfNeeded();
|
206
206
|
}
|
207
207
|
shouldResetInputPosition() {
|
208
|
+
var _a;
|
208
209
|
const currentState = this.getState();
|
209
|
-
return currentState.intervalsInfo.subDocument.id != this.prevState.intervalsInfo.subDocument.id ||
|
210
|
+
return currentState.intervalsInfo.subDocument.id != ((_a = this.prevState.intervalsInfo.subDocument) === null || _a === void 0 ? void 0 : _a.id) ||
|
210
211
|
!ListUtils.equals(currentState.intervalsInfo.intervals, this.prevState.intervalsInfo.intervals);
|
211
212
|
}
|
212
213
|
resetInputPositionIfNeeded() {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "devexpress-richedit",
|
3
|
-
"version": "24.1.8-build-
|
3
|
+
"version": "24.1.8-build-24340-0103",
|
4
4
|
"homepage": "https://www.devexpress.com/",
|
5
5
|
"bugs": "https://www.devexpress.com/support/",
|
6
6
|
"author": "Developer Express Inc.",
|
@@ -14,8 +14,8 @@
|
|
14
14
|
"build-nspell": "webpack --mode production --config=bin/nspell.webpack.config.js"
|
15
15
|
},
|
16
16
|
"peerDependencies": {
|
17
|
-
"devextreme": "24.1.8-build-
|
18
|
-
"devextreme-dist": "24.1.8-build-
|
17
|
+
"devextreme": "24.1.8-build-24338-1936",
|
18
|
+
"devextreme-dist": "24.1.8-build-24338-1936"
|
19
19
|
},
|
20
20
|
"dependencies": {
|
21
21
|
"jszip": "~3.10.1",
|