devexpress-richedit 25.1.12 → 25.1.13

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 (53) hide show
  1. package/bin/gulpfile.js +6 -9
  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.d.ts +1 -1
  9. package/dist/dx.richedit.js +392 -185
  10. package/dist/dx.richedit.min.js +3 -3
  11. package/index.d.ts +1 -1
  12. package/index.js +1 -1
  13. package/lib/client/client-rich-edit.js +2 -2
  14. package/lib/client/document-processor/processor.d.ts +1 -0
  15. package/lib/client/document-processor/processor.js +11 -0
  16. package/lib/common/canvas/canvas-manager.d.ts +1 -1
  17. package/lib/common/canvas/canvas-manager.js +7 -3
  18. package/lib/common/canvas/double-tap-detector.d.ts +10 -0
  19. package/lib/common/canvas/double-tap-detector.js +28 -0
  20. package/lib/common/canvas/renderes/common/document-renderer.js +1 -1
  21. package/lib/common/commands/floating-objects/floating-object-drag-drop-change-position-command.js +5 -1
  22. package/lib/common/commands/text/clipboard-commands.d.ts +0 -1
  23. package/lib/common/commands/text/clipboard-commands.js +1 -5
  24. package/lib/common/commands/text/drag-drop-commands.js +2 -0
  25. package/lib/common/layout/main-structures/layout-row.d.ts +2 -1
  26. package/lib/common/layout/main-structures/layout-row.js +1 -0
  27. package/lib/common/layout-formatter/row/formatter.js +4 -1
  28. package/lib/common/layout-formatter/row/result.js +12 -4
  29. package/lib/common/layout-formatter/row/size-engine/row-height-calculator.js +20 -11
  30. package/lib/common/layout-formatter/row/size-engine/row-height-state.d.ts +2 -1
  31. package/lib/common/layout-formatter/row/size-engine/row-height-state.js +7 -2
  32. package/lib/common/layout-formatter/row/utils/line-spacing-calculator.d.ts +4 -3
  33. package/lib/common/layout-formatter/row/utils/line-spacing-calculator.js +16 -14
  34. package/lib/common/layout-formatter/table/borders/border-helper.js +4 -4
  35. package/lib/common/mouse-handler/mouse-handler/mouse-handler-default-state.d.ts +1 -0
  36. package/lib/common/mouse-handler/mouse-handler/mouse-handler-default-state.js +6 -4
  37. package/lib/common/ui/ruler/controls/divisions.d.ts +1 -0
  38. package/lib/common/ui/ruler/controls/divisions.js +4 -0
  39. package/lib/common/ui/ruler/controls/indent/first-line.d.ts +4 -2
  40. package/lib/common/ui/ruler/controls/indent/first-line.js +8 -0
  41. package/lib/common/ui/ruler/controls/indent/left.d.ts +4 -3
  42. package/lib/common/ui/ruler/controls/indent/left.js +10 -8
  43. package/lib/common/ui/ruler/controls/indent/right.d.ts +3 -1
  44. package/lib/common/ui/ruler/controls/indent/right.js +8 -0
  45. package/lib/common/ui/ruler/controls/tab/tab.d.ts +3 -0
  46. package/lib/common/ui/ruler/controls/tab/tab.js +12 -1
  47. package/lib/common/ui/ruler/controls/table.d.ts +4 -1
  48. package/lib/common/ui/ruler/controls/table.js +12 -0
  49. package/lib/common/ui/ruler/layout-recalculation-guard.d.ts +12 -0
  50. package/lib/common/ui/ruler/layout-recalculation-guard.js +23 -0
  51. package/lib/common/ui/ruler/manager.d.ts +3 -0
  52. package/lib/common/ui/ruler/manager.js +29 -0
  53. package/package.json +6 -4
package/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * DevExpress WebRichEdit (index.d.ts)
3
- * Version: 25.1.12
3
+ * Version: 25.1.13
4
4
  * Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
5
5
  * License: https://www.devexpress.com/Support/EULAs",
6
6
  */
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * DevExpress WebRichEdit (index.js)
3
- * Version: 25.1.12
3
+ * Version: 25.1.13
4
4
  * Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
5
5
  * License: https://www.devexpress.com/Support/EULAs",
6
6
  */
@@ -62,8 +62,8 @@ export class ClientRichEdit {
62
62
  this.rawDataSource = settings.rawDataSource;
63
63
  this.contextMenuSettings = settings.contextMenuSettings;
64
64
  this.fullScreenHelper = new FullScreenHelper(element);
65
- if ("eyJsaWNlbnNlS2V5IjoiZXdvZ0lDSm1iM0p0WVhRaU9pQXhMQW9nSUNKcGJuUmxjbTVoYkZWellXZGxTV1FpT2lBaWFFVTFORFkxU3pSUlpYaFNVWGxFWjIxTldtaHRVeUlLZlE9PS5hc1crYVJtdENhb2ZiRVJBTERDVkNmVTlCOGgxS3Y5SHBRRFhCQWphWUIxNHRmUEx6a09xdkhRbnlieFNVdEdKbmZ0dnkxNDQ5UE9QL1pmd1pzRThBTG4zWnpIaWEvWlVmTWNNUytOL2liNEM3VEhOS2tZYnZyL3AxaEVzTnVnRDgzZnhxdz09In0=")
66
- config(JSON.parse(atob("eyJsaWNlbnNlS2V5IjoiZXdvZ0lDSm1iM0p0WVhRaU9pQXhMQW9nSUNKcGJuUmxjbTVoYkZWellXZGxTV1FpT2lBaWFFVTFORFkxU3pSUlpYaFNVWGxFWjIxTldtaHRVeUlLZlE9PS5hc1crYVJtdENhb2ZiRVJBTERDVkNmVTlCOGgxS3Y5SHBRRFhCQWphWUIxNHRmUEx6a09xdkhRbnlieFNVdEdKbmZ0dnkxNDQ5UE9QL1pmd1pzRThBTG4zWnpIaWEvWlVmTWNNUytOL2liNEM3VEhOS2tZYnZyL3AxaEVzTnVnRDgzZnhxdz09In0=")));
65
+ if ("eyJsaWNlbnNlS2V5IjoiZXdvZ0lDSm1iM0p0WVhRaU9pQXhMQW9nSUNKcGJuUmxjbTVoYkZWellXZGxTV1FpT2lBaWRVSmhTVkoxT1hFNFoxTkpiemx6ZHpKd01GbElNQ0lLZlE9PS5NZW93UmpFY0N3YjVSZ0REdCtQRmNaTnZmUklyZERYRUp3Z3llYi9hd1BnTHVUWGxSMTRlTjdPNFVIelZDNzZxOEd0MDc4ZDJTYThRUktlVXVSVDh0TVVoVC9sV1VSOW52a1ZjcHhOWEN5V1BYV0dTWkM3SGhnVnlseTFacVUxeXAralhGUT09In0=")
66
+ config(JSON.parse(atob("eyJsaWNlbnNlS2V5IjoiZXdvZ0lDSm1iM0p0WVhRaU9pQXhMQW9nSUNKcGJuUmxjbTVoYkZWellXZGxTV1FpT2lBaWRVSmhTVkoxT1hFNFoxTkpiemx6ZHpKd01GbElNQ0lLZlE9PS5NZW93UmpFY0N3YjVSZ0REdCtQRmNaTnZmUklyZERYRUp3Z3llYi9hd1BnTHVUWGxSMTRlTjdPNFVIelZDNzZxOEd0MDc4ZDJTYThRUktlVXVSVDh0TVVoVC9sV1VSOW52a1ZjcHhOWEN5V1BYV0dTWkM3SGhnVnlseTFacVUxeXAralhGUT09In0=")));
67
67
  this.prepareElement(element, settings);
68
68
  this.initDefaultFontsAndStyles();
69
69
  this.initBars(settings.ribbon, settings.fonts);
@@ -39,5 +39,6 @@ export declare abstract class DocumentProcessorBase implements IProcessor {
39
39
  beginUpdate(): void;
40
40
  endUpdate(): void;
41
41
  invalidateLayoutAfterFontsLoaded(): void;
42
+ protected ensureDocumentIsFullyFormatted(): void;
42
43
  getExportModelOptions(initOptions?: Partial<IExportModelOptions>): IExportModelOptions;
43
44
  }
@@ -92,11 +92,22 @@ export class DocumentProcessorBase {
92
92
  this.layoutFormatterManager.invalidator.onChangedAllLayout();
93
93
  }
94
94
  }
95
+ ensureDocumentIsFullyFormatted() {
96
+ if (this.layoutFormatterManager.isDocumentOpened) {
97
+ while (!this.layoutFormatterManager.layout.isFullyFormatted)
98
+ this.layoutFormatterManager.forceFormatPage(this.layoutFormatterManager.layout.validPageCount + 1);
99
+ }
100
+ }
95
101
  getExportModelOptions(initOptions = {}) {
102
+ let grids;
96
103
  return {
97
104
  modelManager: isDefined(initOptions.modelManager) ? initOptions.modelManager : this.modelManager,
98
105
  pictureRenderer: this.documentRenderer,
99
106
  uiUnitConverter: this.uiUnitConverter,
107
+ getGrids: () => {
108
+ this.ensureDocumentIsFullyFormatted();
109
+ return grids !== null && grids !== void 0 ? grids : (grids = this.layoutFormatterManager.layout.grids);
110
+ },
100
111
  sessionGuid: this.sessionGuid,
101
112
  clientGuid: this.clientGuid,
102
113
  documentFormat: isDefined(initOptions.documentFormat) ? initOptions.documentFormat : DocumentFormat.OpenXml,
@@ -12,7 +12,7 @@ export declare class CanvasManager extends BatchUpdatableObject {
12
12
  private scrollIntervalID;
13
13
  private lastMousePosition;
14
14
  private canvasPosition;
15
- private doubleTapStartDate;
15
+ private doubleTapDetector;
16
16
  private pointer;
17
17
  private blockNotPointerEvents;
18
18
  private lastPointerPosition;
@@ -10,6 +10,7 @@ import { PopupUtils } from '@devexpress/utils/lib/utils/popup';
10
10
  import { RichMouseEvent } from '../event-manager';
11
11
  import { MouseEventSource } from '../mouse-handler/mouse-event-source';
12
12
  import { CursorPointer } from '../mouse-handler/mouse-handler/mouse-handler';
13
+ import { DoubleTapDetector } from './double-tap-detector';
13
14
  import { ResizeBoxListener } from './listeners/resize-box-listener';
14
15
  import { SimpleViewCanvasSizeManager } from './renderes/common/document-renderer';
15
16
  import { SizeUtils } from '../utils/size-utils';
@@ -19,6 +20,8 @@ const CSSCLASS_FOCUSED = "dxreInFocus";
19
20
  const AUTOSCROLL_AREA_SIZE = 10;
20
21
  const AUTOSCROLL_STEP = 10;
21
22
  const MSTOUCH_MOVE_SENSITIVITY = 5;
23
+ const DOUBLE_TAP_MAX_DISTANCE = 20;
24
+ const DOUBLE_TAP_MAX_INTERVAL = 600;
22
25
  export class CanvasManager extends BatchUpdatableObject {
23
26
  get sizes() { return this.viewManager.sizes; }
24
27
  get scroll() { return this.viewManager.scroll; }
@@ -27,6 +30,7 @@ export class CanvasManager extends BatchUpdatableObject {
27
30
  super();
28
31
  this.lastMousePosition = { x: -1, y: -1 };
29
32
  this.canvasPosition = { x: -1, y: -1 };
33
+ this.doubleTapDetector = new DoubleTapDetector(DOUBLE_TAP_MAX_DISTANCE, DOUBLE_TAP_MAX_INTERVAL);
30
34
  this.pointer = CursorPointer.Auto;
31
35
  this.blockNotPointerEvents = false;
32
36
  this.lastPointerPosition = { x: -1, y: -1 };
@@ -137,12 +141,12 @@ export class CanvasManager extends BatchUpdatableObject {
137
141
  onCanvasTouchStartInternal(evt) {
138
142
  this.saveMousePosition(evt);
139
143
  let richMouseEvent = new RichMouseEvent(evt, this.getLayoutPoint(evt, true), CanvasManager.getMouseEventSource(EvtUtils.getEventSource(evt)), this.scroll.lastScrollTop, this.scroll.lastScrollLeft);
140
- if (this.doubleTapStartDate && ((new Date()) - this.doubleTapStartDate) < 600) {
141
- this.doubleTapStartDate = null;
144
+ const evtX = EvtUtils.getEventX(evt);
145
+ const evtY = EvtUtils.getEventY(evt);
146
+ if (this.doubleTapDetector.isDoubleTap(evtX, evtY)) {
142
147
  this.onCanvasDoubleTap(richMouseEvent);
143
148
  }
144
149
  else {
145
- this.doubleTapStartDate = new Date();
146
150
  this.eventManager.onTouchStart(richMouseEvent);
147
151
  }
148
152
  }
@@ -0,0 +1,10 @@
1
+ export declare class DoubleTapDetector {
2
+ private readonly maxDistance;
3
+ private readonly maxInterval;
4
+ private lastTime;
5
+ private lastX;
6
+ private lastY;
7
+ constructor(maxDistance: number, maxInterval: number);
8
+ isDoubleTap(x: number, y: number): boolean;
9
+ reset(): void;
10
+ }
@@ -0,0 +1,28 @@
1
+ export class DoubleTapDetector {
2
+ constructor(maxDistance, maxInterval) {
3
+ this.maxDistance = maxDistance;
4
+ this.maxInterval = maxInterval;
5
+ this.lastTime = null;
6
+ this.lastX = -1;
7
+ this.lastY = -1;
8
+ }
9
+ isDoubleTap(x, y) {
10
+ const now = Date.now();
11
+ const result = this.lastTime !== null &&
12
+ (now - this.lastTime) < this.maxInterval &&
13
+ Math.abs(x - this.lastX) <= this.maxDistance &&
14
+ Math.abs(y - this.lastY) <= this.maxDistance;
15
+ if (result) {
16
+ this.reset();
17
+ }
18
+ else {
19
+ this.lastTime = now;
20
+ this.lastX = x;
21
+ this.lastY = y;
22
+ }
23
+ return result;
24
+ }
25
+ reset() {
26
+ this.lastTime = null;
27
+ }
28
+ }
@@ -869,7 +869,7 @@ export class DocumentRenderer {
869
869
  }
870
870
  if (isDefined(altText) && !StringUtils.isNullOrEmpty(altText))
871
871
  img.alt = altText;
872
- img.style.cssText = `height: ${MathUtils.round(size.height, 3)}px; width: ${MathUtils.round(size.width, 3)}px; vertical-align: baseline`;
872
+ img.style.cssText = `height: ${MathUtils.round(size.height, 3)}px; width: ${MathUtils.round(size.width, 3)}px`;
873
873
  img.setAttribute('class', RendererClassNames.PICTURE);
874
874
  return img;
875
875
  }
@@ -155,7 +155,11 @@ export class FloatingObjectDragDropChangePositionCommand extends CommandBase {
155
155
  moveOutsideTable(oldRun, oldRunPos, endPageIndex, pagePosition) {
156
156
  this.removeOldRun(oldRun, oldRunPos);
157
157
  this.control.layoutFormatterManager.forceFormatPage(endPageIndex);
158
- const layoutPoint = new LayoutPoint(Math.min(endPageIndex, this.control.layout.pages.length), pagePosition.x, pagePosition.y);
158
+ if (endPageIndex >= this.control.layout.pages.length) {
159
+ this.addRun(oldRun, oldRunPos, oldRun.anchorInfo);
160
+ return;
161
+ }
162
+ const layoutPoint = new LayoutPoint(endPageIndex, pagePosition.x, pagePosition.y);
159
163
  const htr = this.control.hitTestManager.calculate(layoutPoint, DocumentLayoutDetailsLevel.Row, this.activeSubDocument);
160
164
  const paragraphStartHTR = this.findParagraphStartOnThisPage(htr);
161
165
  const newLogPos = this.getNewLogPosition(this.activeSubDocument, paragraphStartHTR);
@@ -44,7 +44,6 @@ export declare class CutSelectionCommand extends ClipboardCommand {
44
44
  }
45
45
  export declare class PasteSelectionCommand extends ClipboardCommand {
46
46
  constructor(control: IRichEditControl);
47
- protected getTimeout(): number;
48
47
  pasteEventRaised(): void;
49
48
  changeModel(): void;
50
49
  isEnabled(): boolean;
@@ -138,8 +138,7 @@ export class ClipboardCommand extends CommandBase {
138
138
  }
139
139
  }
140
140
  ClipboardCommand.additionalWaitingTimeForMac = 10;
141
- ClipboardCommand.timeout = Browser.Firefox ? 10 :
142
- (Browser.MacOSPlatform && (Browser.WebKitFamily || Browser.Opera) ? 10 : 0);
141
+ ClipboardCommand.timeout = 0;
143
142
  export class CopySelectionCommand extends ClipboardCommand {
144
143
  constructor(control) {
145
144
  super(control, "copy");
@@ -207,9 +206,6 @@ export class PasteSelectionCommand extends ClipboardCommand {
207
206
  constructor(control) {
208
207
  super(control, "paste");
209
208
  }
210
- getTimeout() {
211
- return Browser.MacOSPlatform ? 300 : super.getTimeout();
212
- }
213
209
  pasteEventRaised() {
214
210
  if (Browser.MacOSPlatform && this.control.commandManager.clipboardTimerId !== null) {
215
211
  setTimeout(() => {
@@ -119,6 +119,8 @@ export class DragMoveContentCommand extends CommandBase {
119
119
  tryMoveIntervalInsideTable(intervalsInfo, positionTo) {
120
120
  if (!intervalsInfo.tableInfo.extendedData.numRows)
121
121
  return false;
122
+ if (ListUtils.unsafeAnyOf(intervalsInfo.intervals, (interval) => interval.start <= positionTo && interval.end >= positionTo))
123
+ return true;
122
124
  const subDocument = intervalsInfo.subDocument;
123
125
  const linkedIntervals = ListUtils.map(intervalsInfo.intervals, (curr) => new LinkedInterval(intervalsInfo.subDocument.positionManager, curr));
124
126
  this.history.addTransaction(() => {
@@ -13,7 +13,8 @@ export declare enum LayoutRowStateFlags {
13
13
  SectionEnd = 8,
14
14
  DocumentEnd = 16,
15
15
  CellTableEnd = 64,
16
- PageBreakBefore = 128
16
+ PageBreakBefore = 128,
17
+ ContainsText = 256
17
18
  }
18
19
  export declare class LayoutRow extends Rectangle {
19
20
  boxes: LayoutBox[];
@@ -12,6 +12,7 @@ export var LayoutRowStateFlags;
12
12
  LayoutRowStateFlags[LayoutRowStateFlags["DocumentEnd"] = 16] = "DocumentEnd";
13
13
  LayoutRowStateFlags[LayoutRowStateFlags["CellTableEnd"] = 64] = "CellTableEnd";
14
14
  LayoutRowStateFlags[LayoutRowStateFlags["PageBreakBefore"] = 128] = "PageBreakBefore";
15
+ LayoutRowStateFlags[LayoutRowStateFlags["ContainsText"] = 256] = "ContainsText";
15
16
  })(LayoutRowStateFlags || (LayoutRowStateFlags = {}));
16
17
  export class LayoutRow extends Rectangle {
17
18
  get hasEffectToPageHeight() { return this.boxes.length != 1 || !this.boxes[0].isSectionBreakBox; }
@@ -67,9 +67,12 @@ export class RowFormatter {
67
67
  const prevRow = this.manager.activeFormatter.lastRowInfo.row;
68
68
  const isFirstRowInParagraph = !prevRow || prevRow.flags.get(LayoutRowStateFlags.ParagraphEnd) ||
69
69
  this.manager.activeFormatter.lastRowInfo.paragraphIndex != this.currWrapInfo.paragraphIndex;
70
- const rowParagraphLeftIndent = isFirstRowInParagraph ?
70
+ let rowParagraphLeftIndent = isFirstRowInParagraph ?
71
71
  UnitConverter.twipsToPixelsF(this.paragraphProps.getLeftIndentForFirstRow()) :
72
72
  UnitConverter.twipsToPixelsF(this.paragraphProps.getLeftIndentForOtherRow());
73
+ if (this.manager.innerClientProperties.viewsSettings.isSimpleView) {
74
+ rowParagraphLeftIndent = Math.max(0, rowParagraphLeftIndent);
75
+ }
73
76
  const rowContentHorizontalBounds = FixedInterval.fromPositions(paragraphHorizontalBounds.start + rowParagraphLeftIndent, paragraphHorizontalBounds.end - UnitConverter.twipsToPixelsF(this.paragraphProps.rightIndent));
74
77
  this.rowSizesManager = new RowSizesManager(this, rowContentHorizontalBounds, minY, rowSpacingBeforeApplier, this.manager.activeFormatter.layoutRowBoundsCalculator.getRectangleBounds(this.manager), isFirstRowInParagraph);
75
78
  this.tabInfo = new RowTabInfo(this, paragraphHorizontalBounds.start);
@@ -82,18 +82,26 @@ export class RowFormatterResult {
82
82
  this.rowFormatter.manager.activeFormatter.layoutPosition.getLogPosition(DocumentLayoutDetailsLevel.Column);
83
83
  const firstBox = this.row.boxes[0];
84
84
  const lastVisibleBox = this.getLastVisibleBox();
85
- if (lastVisibleBox)
86
- this.row.width = Math.max(this.row.width, lastVisibleBox.right - firstBox.x);
85
+ if (lastVisibleBox) {
86
+ const actualContentWidth = Math.max(0, lastVisibleBox.right - firstBox.x);
87
+ this.row.width = this.rowFormatter.rowSizesManager.isInfinityWidth ?
88
+ actualContentWidth : Math.max(this.row.width, actualContentWidth);
89
+ }
87
90
  const currState = this.rowFormatter.rowSizesManager.heightCalculator.currState;
88
91
  this.row.increaseRowHeightFromSpacingBeforeAndAfter(currState.maxAscent, currState.maxDescent);
89
92
  }
90
93
  getLastVisibleBox() {
94
+ let lastVisibleWhitespaceBox = null;
91
95
  for (let i = this.row.boxes.length - 1; i >= 0; i--) {
92
96
  const box = this.row.boxes[i];
93
- if (box.isVisible() && !box.isWhitespace())
97
+ if (!box.isVisible())
98
+ continue;
99
+ if (!box.isWhitespace())
94
100
  return box;
101
+ if (!lastVisibleWhitespaceBox)
102
+ lastVisibleWhitespaceBox = box;
95
103
  }
96
- return null;
104
+ return lastVisibleWhitespaceBox;
97
105
  }
98
106
  addBracketBox(boxType, color, x, layoutBox) {
99
107
  const box = new BookmarkBox(boxType);
@@ -1,6 +1,7 @@
1
1
  import { ListUtils } from '@devexpress/utils/lib/utils/list';
2
2
  import { AnchoredObjectLevelType } from '../../../layout/main-structures/layout-boxes/layout-anchored-object-box';
3
3
  import { LayoutBoxType } from '../../../layout/main-structures/layout-boxes/layout-box';
4
+ import { LayoutRowStateFlags } from '../../../layout/main-structures/layout-row';
4
5
  import { ParagraphLineSpacingType } from '../../../model/paragraph/paragraph-properties';
5
6
  import { LineSpacingCalculator } from '../utils/line-spacing-calculator';
6
7
  import { RowHeightState } from './row-height-state';
@@ -12,7 +13,7 @@ export class RowHeightCalculator {
12
13
  this.rowFormatter = rowFormatter;
13
14
  this.rowSpacingBeforeApplier = rowSpacingBeforeApplier;
14
15
  this.lineSpacingCalculator = LineSpacingCalculator.create(this.rowFormatter.paragraphProps.lineSpacing, this.rowFormatter.paragraphProps.lineSpacingType);
15
- this.currState = new RowHeightState(0, 0, 0, 0);
16
+ this.currState = new RowHeightState(0, 0, 0, 0, false);
16
17
  this.currState.height = 0;
17
18
  this.currState.baseLine = 0;
18
19
  this.currState.spacingBefore = 0;
@@ -25,11 +26,11 @@ export class RowHeightCalculator {
25
26
  case LayoutBoxType.FieldCodeStart:
26
27
  case LayoutBoxType.FieldCodeEnd:
27
28
  case LayoutBoxType.Dash: {
28
- info = new RowHeightState(Math.max(box.height, this.currState.maxBoxHeight), Math.max(box.getAscent(), this.currState.maxAscent), Math.max(box.getDescent(), this.currState.maxDescent), this.currState.maxPictureBoxHeight);
29
+ info = new RowHeightState(Math.max(box.height, this.currState.maxBoxHeight), Math.max(box.getAscent(), this.currState.maxAscent), Math.max(box.getDescent(), this.currState.maxDescent), this.currState.maxPictureBoxHeight, this.currState.containsText || true);
29
30
  break;
30
31
  }
31
32
  case LayoutBoxType.Picture: {
32
- info = new RowHeightState(Math.max(box.height, this.currState.maxBoxHeight), this.currState.maxAscent, this.currState.maxDescent, Math.max(box.height, this.currState.maxPictureBoxHeight));
33
+ info = new RowHeightState(Math.max(box.height, this.currState.maxBoxHeight), this.currState.maxAscent, this.currState.maxDescent, Math.max(box.height, this.currState.maxPictureBoxHeight), this.currState.containsText || false);
33
34
  break;
34
35
  }
35
36
  default:
@@ -40,7 +41,7 @@ export class RowHeightCalculator {
40
41
  calcNewState(newInfo) {
41
42
  if (this.currState.equalHeights(newInfo) || newInfo.maxBoxHeight == 0)
42
43
  return this.currState;
43
- this.calcRowParams(newInfo.maxBoxHeight, newInfo.maxAscent, newInfo.maxDescent, newInfo.maxPictureBoxHeight);
44
+ this.calcRowParams(newInfo.maxBoxHeight, newInfo.maxAscent, newInfo.maxDescent, newInfo.maxPictureBoxHeight, newInfo.containsText);
44
45
  newInfo.initFromRow(this.row);
45
46
  return newInfo;
46
47
  }
@@ -71,7 +72,7 @@ export class RowHeightCalculator {
71
72
  }
72
73
  }
73
74
  applyT584234Height(b) {
74
- const info = new RowHeightState(Math.max(b.height, this.currState.maxBoxHeight), Math.max(b.getAscent(), this.currState.maxAscent), Math.max(b.getDescent(), this.currState.maxDescent), this.currState.maxPictureBoxHeight);
75
+ const info = new RowHeightState(Math.max(b.height, this.currState.maxBoxHeight), Math.max(b.getAscent(), this.currState.maxAscent), Math.max(b.getDescent(), this.currState.maxDescent), this.currState.maxPictureBoxHeight, this.currState.containsText);
75
76
  this.applyState(this.calcNewState(info));
76
77
  }
77
78
  setFinalRowParams() {
@@ -84,23 +85,31 @@ export class RowHeightCalculator {
84
85
  const lastBox = ListUtils.last(row.boxes);
85
86
  if (!lastBox && ListUtils.unsafeAnyOf(this.rowFormatter.result.newAnchoredObjects, (obj) => obj.levelType == AnchoredObjectLevelType.InText))
86
87
  return true;
87
- this.calcRowParams(lastBox.height, lastBox.getAscent(), lastBox.getDescent(), this.currState.maxPictureBoxHeight);
88
+ this.calcRowParams(lastBox.height, lastBox.getAscent(), lastBox.getDescent(), this.currState.maxPictureBoxHeight, this.currState.containsText);
88
89
  this.currState.initFromRow(this.row);
89
90
  return false;
90
91
  }
91
- calcRowParams(maxBoxHeight, maxAscent, maxDescent, maxPictureBoxHeight) {
92
+ calcRowParams(maxBoxHeight, maxAscent, maxDescent, maxPictureBoxHeight, containsText) {
92
93
  const row = this.row;
93
94
  row.rollbackSpacingBefore();
94
- row.height = this.lineSpacingCalculator.calculate(maxBoxHeight, maxAscent, maxDescent, maxPictureBoxHeight);
95
+ row.flags.set(LayoutRowStateFlags.ContainsText, containsText);
96
+ row.height = this.lineSpacingCalculator.calculate(maxBoxHeight, maxAscent, maxDescent, maxPictureBoxHeight, containsText);
97
+ const descent = this.lineSpacingCalculator.calculateDescent(maxAscent, maxDescent, maxPictureBoxHeight, containsText);
95
98
  switch (this.rowFormatter.paragraphProps.lineSpacingType) {
96
99
  case ParagraphLineSpacingType.AtLeast:
97
100
  case ParagraphLineSpacingType.Exactly:
98
- row.baseLine = Math.max(0, row.height - maxDescent);
101
+ row.baseLine = Math.max(0, row.height - descent);
99
102
  row.lineHeight = row.height;
100
103
  break;
101
104
  default:
102
- row.baseLine = Math.max(maxAscent, maxPictureBoxHeight);
103
- row.lineHeight = Math.max(maxAscent + maxDescent, maxPictureBoxHeight);
105
+ const textHeight = maxAscent + descent;
106
+ if (textHeight < maxPictureBoxHeight)
107
+ row.baseLine = maxPictureBoxHeight;
108
+ else if (!containsText && maxPictureBoxHeight > 0)
109
+ row.baseLine = textHeight;
110
+ else
111
+ row.baseLine = maxAscent;
112
+ row.lineHeight = Math.max(textHeight, maxPictureBoxHeight);
104
113
  }
105
114
  this.rowSpacingBeforeApplier.apply(this.row, this.rowFormatter.result.paragraphIndex);
106
115
  }
@@ -7,7 +7,8 @@ export declare class RowHeightState {
7
7
  height: number;
8
8
  baseLine: number;
9
9
  spacingBefore: number;
10
- constructor(maxBoxHeight: number, maxAscent: number, maxDescent: number, maxPictureBoxHeight: number);
10
+ containsText: boolean;
11
+ constructor(maxBoxHeight: number, maxAscent: number, maxDescent: number, maxPictureBoxHeight: number, containsText: boolean);
11
12
  initFromRow(row: LayoutRow): void;
12
13
  applyToRow(row: LayoutRow): void;
13
14
  getFullRowHeight(): number;
@@ -1,20 +1,24 @@
1
+ import { LayoutRowStateFlags } from '../../../layout/main-structures/layout-row';
1
2
  export class RowHeightState {
2
- constructor(maxBoxHeight, maxAscent, maxDescent, maxPictureBoxHeight) {
3
+ constructor(maxBoxHeight, maxAscent, maxDescent, maxPictureBoxHeight, containsText) {
3
4
  this.maxBoxHeight = maxBoxHeight;
4
5
  this.maxAscent = maxAscent;
5
6
  this.maxDescent = maxDescent;
6
7
  this.maxPictureBoxHeight = maxPictureBoxHeight;
8
+ this.containsText = containsText;
7
9
  }
8
10
  initFromRow(row) {
9
11
  this.height = row.height;
10
12
  this.baseLine = row.baseLine;
11
13
  this.spacingBefore = row.getSpacingBefore();
14
+ this.containsText = row.flags.get(LayoutRowStateFlags.ContainsText);
12
15
  }
13
16
  applyToRow(row) {
14
17
  row.rollbackSpacingBefore();
15
18
  row.applySpacingBefore(this.spacingBefore);
16
19
  row.height = this.height;
17
20
  row.baseLine = this.baseLine;
21
+ row.flags.set(LayoutRowStateFlags.ContainsText, this.containsText);
18
22
  }
19
23
  getFullRowHeight() {
20
24
  return this.height + this.spacingBefore;
@@ -23,6 +27,7 @@ export class RowHeightState {
23
27
  return this.maxBoxHeight == obj.maxBoxHeight &&
24
28
  this.maxAscent == obj.maxAscent &&
25
29
  this.maxDescent == obj.maxDescent &&
26
- this.maxPictureBoxHeight == obj.maxPictureBoxHeight;
30
+ this.maxPictureBoxHeight == obj.maxPictureBoxHeight &&
31
+ this.containsText == obj.containsText;
27
32
  }
28
33
  }
@@ -1,7 +1,8 @@
1
1
  import { ParagraphLineSpacingType } from '../../../model/paragraph/paragraph-properties';
2
2
  export declare abstract class LineSpacingCalculator {
3
3
  static create(lineSpacing: number, lineSpacingType: ParagraphLineSpacingType): LineSpacingCalculator;
4
- calculate(rowHeight: number, maxAscent: number, maxDescent: number, maxPictureHeight: number): number;
4
+ calculate(rowHeight: number, maxAscent: number, maxDescent: number, maxPictureHeight: number, containsText: boolean): number;
5
+ calculateDescent(maxAscent: number, maxDescent: number, maxPictureHeight: number, containsText: boolean): number;
5
6
  abstract calculateSpacing(maxTextHeight: number): number;
6
7
  abstract calculateSpacingInlineObjectCase(maxTextHeight: number, rowTextSpacing: number, maxPictureHeight: number, maxDescent: number): number;
7
8
  }
@@ -28,10 +29,10 @@ export declare class ExactlySpacingCalculator extends LineSpacingCalculator {
28
29
  constructor(lineSpacing: number);
29
30
  calculateSpacing(_maxTextHeight: number): number;
30
31
  calculateSpacingInlineObjectCase(_maxTextHeight: number, _rowTextSpacing: number, _maxPictureHeight: number, _maxDescent: number): number;
31
- calculate(_rowHeight: number, _maxAscent: number, _maxDescent: number, _maxPictureHeight: number): number;
32
+ calculate(_rowHeight: number, _maxAscent: number, _maxDescent: number, _maxPictureHeight: number, _containsText: boolean): number;
32
33
  }
33
34
  export declare class AtLeastSpacingCalculator extends SingleSpacingCalculator {
34
35
  lineSpacing: number;
35
36
  constructor(lineSpacing: number);
36
- calculate(rowHeight: number, maxAscent: number, maxDescent: number, maxPictureHeight: number): number;
37
+ calculate(rowHeight: number, maxAscent: number, maxDescent: number, maxPictureHeight: number, containsText: boolean): number;
37
38
  }
@@ -19,19 +19,21 @@ export class LineSpacingCalculator {
19
19
  return new SingleSpacingCalculator();
20
20
  }
21
21
  }
22
- calculate(rowHeight, maxAscent, maxDescent, maxPictureHeight) {
23
- const maxTextHeight = maxAscent + maxDescent;
24
- if (maxTextHeight == 0)
22
+ calculate(rowHeight, maxAscent, maxDescent, maxPictureHeight, containsText) {
23
+ if (maxAscent == 0 && maxDescent == 0)
25
24
  return rowHeight;
26
- const rowTextSpacing = this.calculateSpacing(maxTextHeight);
27
- if (!maxPictureHeight || maxAscent > maxPictureHeight)
25
+ const descent = this.calculateDescent(maxAscent, maxDescent, maxPictureHeight, containsText);
26
+ const textHeight = maxAscent + descent;
27
+ const rowTextSpacing = this.calculateSpacing(textHeight);
28
+ if (!maxPictureHeight || textHeight > maxPictureHeight)
28
29
  return rowTextSpacing;
29
- else {
30
- if (maxDescent == 0)
31
- return rowHeight;
32
- else
33
- return this.calculateSpacingInlineObjectCase(maxTextHeight, rowTextSpacing, maxPictureHeight, maxDescent);
34
- }
30
+ else
31
+ return this.calculateSpacingInlineObjectCase(textHeight, rowTextSpacing, maxPictureHeight, descent);
32
+ }
33
+ calculateDescent(maxAscent, maxDescent, maxPictureHeight, containsText) {
34
+ if (!containsText && maxPictureHeight !== 0)
35
+ return (maxPictureHeight >= maxAscent + maxDescent) ? 0 : maxDescent;
36
+ return maxDescent;
35
37
  }
36
38
  }
37
39
  export class MultipleSpacingCalculator extends LineSpacingCalculator {
@@ -83,7 +85,7 @@ export class ExactlySpacingCalculator extends LineSpacingCalculator {
83
85
  calculateSpacingInlineObjectCase(_maxTextHeight, _rowTextSpacing, _maxPictureHeight, _maxDescent) {
84
86
  throw new Error(Errors.NotImplemented);
85
87
  }
86
- calculate(_rowHeight, _maxAscent, _maxDescent, _maxPictureHeight) {
88
+ calculate(_rowHeight, _maxAscent, _maxDescent, _maxPictureHeight, _containsText) {
87
89
  return this.lineSpacing;
88
90
  }
89
91
  }
@@ -94,8 +96,8 @@ export class AtLeastSpacingCalculator extends SingleSpacingCalculator {
94
96
  throw new Error(argumentException("lineSpacing", lineSpacing));
95
97
  this.lineSpacing = lineSpacing;
96
98
  }
97
- calculate(rowHeight, maxAscent, maxDescent, maxPictureHeight) {
98
- var result = super.calculate(rowHeight, maxAscent, maxDescent, maxPictureHeight);
99
+ calculate(rowHeight, maxAscent, maxDescent, maxPictureHeight, containsText) {
100
+ var result = super.calculate(rowHeight, maxAscent, maxDescent, maxPictureHeight, containsText);
99
101
  return Math.max(result, this.lineSpacing);
100
102
  }
101
103
  }
@@ -46,7 +46,7 @@ export class BorderHelper {
46
46
  constructor(tableInfo, model) {
47
47
  this.colorProvider = model.colorProvider;
48
48
  this.tableInfo = tableInfo;
49
- this.tblbrdProvider = new TableBorderInfoProvider(model, tableInfo.table, UnitConverter.twipsToPixels);
49
+ this.tblbrdProvider = new TableBorderInfoProvider(model, tableInfo.table, UnitConverter.twipsToPixelsF);
50
50
  }
51
51
  getVerticalBorders() {
52
52
  const verticalBorders = [];
@@ -134,7 +134,7 @@ export class BorderHelper {
134
134
  return new LayoutCursorVerticalTableBorder(Math.floor(modelXPos - size / 2), 0, 0, new BorderInfo().getLayoutBorder(this.colorProvider));
135
135
  }
136
136
  mergeVerticalBorders(cellA, mergerCellA, cellB, mergerCellB, isOutsideCellBorders, tableBorderInfo, getX) {
137
- const brd = BorderHelper.mergeThreeBorders(this.colorProvider, cellA, mergerCellA, cellB, mergerCellB, isOutsideCellBorders, tableBorderInfo, this.tblStyle, UnitConverter.twipsToPixels);
137
+ const brd = BorderHelper.mergeThreeBorders(this.colorProvider, cellA, mergerCellA, cellB, mergerCellB, isOutsideCellBorders, tableBorderInfo, this.tblStyle, UnitConverter.twipsToPixelsF);
138
138
  const tableVerticalBorder = new LayoutTableBorder(0, 0, 0, brd ? brd.getLayoutBorder(this.colorProvider) : null);
139
139
  if (tableVerticalBorder.borderInfo)
140
140
  tableVerticalBorder.xPos = getX(tableVerticalBorder.borderInfo.width);
@@ -192,7 +192,7 @@ export class BorderHelper {
192
192
  const currCellEndGridColumn = Math.ceil(this.grid.columns.positions[currCellGridStartIndex + cell.columnSpan] - rowCellSpacing * (cellIndex == cells.length - 1 ? 2 : 1));
193
193
  const currCellBorder = getCurrCellBorderMerger ?
194
194
  TableBorderInfoProvider.borderConvertToPixels((new getCurrCellBorderMerger(cell.parentRow.tablePropertiesException, !isTableBorderRowIndexValid))
195
- .getProperty(cell.properties, this.tblStyle, cell.conditionalFormatting, null), UnitConverter.twipsToPixels) :
195
+ .getProperty(cell.properties, this.tblStyle, cell.conditionalFormatting, null), UnitConverter.twipsToPixelsF) :
196
196
  null;
197
197
  const horizBorder = new LayoutTableHorizontalBorder();
198
198
  horizBorder.xPosition = currCellXPosition;
@@ -223,7 +223,7 @@ export class BorderHelper {
223
223
  const horizBorder = new LayoutTableHorizontalBorder();
224
224
  horizBorder.xPosition = Math.floor(this.grid.columns.positions[cellGridIndex]);
225
225
  horizBorder.length = Math.ceil(this.grid.columns.width[cellGridIndex]);
226
- const brd = BorderHelper.mergeThreeBorders(this.colorProvider, currCell, getCurrCellBorderMerger, prevCell, getTopCellBorderMerger, false, tableBorderInfo, this.tblStyle, UnitConverter.twipsToPixels);
226
+ const brd = BorderHelper.mergeThreeBorders(this.colorProvider, currCell, getCurrCellBorderMerger, prevCell, getTopCellBorderMerger, false, tableBorderInfo, this.tblStyle, UnitConverter.twipsToPixelsF);
227
227
  horizBorder.borderInfo = brd ? brd.getLayoutBorder(this.colorProvider) : null;
228
228
  horizBordersInfo.updateWidth(horizBorder.borderInfo ? horizBorder.borderInfo.width : 0);
229
229
  horizBordersInfo.borders.push(horizBorder);
@@ -21,6 +21,7 @@ export declare class MouseHandlerDefaultState extends MouseHandlerStateBase {
21
21
  private beginCharacterMultiSelection;
22
22
  private isLeftArea;
23
23
  private isLeftAreaOffset;
24
+ private getLeftAreaOffset;
24
25
  private shouldProcessResizeBoxVisualizer;
25
26
  private beginResizeBoxMouseHandler;
26
27
  private beginRotate;
@@ -316,12 +316,9 @@ export class MouseHandlerDefaultState extends MouseHandlerStateBase {
316
316
  }
317
317
  isLeftAreaOffset(htr, evt) {
318
318
  if (htr) {
319
- const columnX = htr.pageArea.x + htr.column.x;
320
- const rowX = columnX + htr.row.x;
321
- const leftAreaX = Math.min(columnX - MouseHandler.LEFT_AREA_COMMANDS_OFFSET, rowX);
322
319
  if (htr.exactlyDetailLevel >= DocumentLayoutDetailsLevel.Page &&
323
320
  htr.deviations[DocumentLayoutDetailsLevel.Column] & HitTestDeviation.Left &&
324
- evt.layoutPoint.x <= leftAreaX)
321
+ evt.layoutPoint.x <= this.getLeftAreaOffset(htr))
325
322
  return true;
326
323
  if (htr.detailsLevel >= DocumentLayoutDetailsLevel.Box &&
327
324
  htr.exactlyDetailLevel >= DocumentLayoutDetailsLevel.Row &&
@@ -335,6 +332,11 @@ export class MouseHandlerDefaultState extends MouseHandlerStateBase {
335
332
  }
336
333
  return false;
337
334
  }
335
+ getLeftAreaOffset(htr) {
336
+ const columnX = htr.pageArea.x + htr.column.x;
337
+ const rowX = columnX + htr.row.x;
338
+ return Math.min(columnX - MouseHandler.LEFT_AREA_COMMANDS_OFFSET, rowX);
339
+ }
338
340
  shouldProcessResizeBoxVisualizer(evt) {
339
341
  return this.handler.boxVisualizerManager.resizeBoxVisualizer.shouldCapture(evt) &&
340
342
  this.handler.control.selection.activeSubDocument.isEditable([new FixedInterval(this.handler.control.selection.specialRunInfo.getPosition(), 1)]);
@@ -22,6 +22,7 @@ export declare class RulerDivisionsControl extends RulerBase {
22
22
  get height(): number;
23
23
  protected getRootClassName(): string;
24
24
  constructor(modelData: RulerModelData, controls: RulerControls, divisionInfo: DivisionInfo, maxPageWidth: number);
25
+ recalculateLayout(): void;
25
26
  render(): void;
26
27
  update(): void;
27
28
  updateModelState(): void;
@@ -28,6 +28,10 @@ export class RulerDivisionsControl extends RulerBase {
28
28
  this.rootElement.offsetParent;
29
29
  this.render();
30
30
  }
31
+ recalculateLayout() {
32
+ this._height = SizeUtils.getOffsetHeight(this.rootElement);
33
+ this.render();
34
+ }
31
35
  render() {
32
36
  const unitCount = Math.ceil(this.maxPageWidth / this.divisionInfo.unitSize);
33
37
  this.rootElement.style.width = this.divisionInfo.unitSize * (unitCount * 2 + 1) + "px";
@@ -3,11 +3,13 @@ import { RulerModelData } from '../../model-data';
3
3
  import { RulerModelState } from '../base';
4
4
  import { RulerBaseIndentControl } from './base';
5
5
  export declare class RulerFirstLineIndentDragHandle extends RulerBaseIndentControl {
6
- private readonly _heightOfProtrudingPart;
7
- private readonly leftCorrection;
6
+ private _heightOfProtrudingPart;
7
+ private leftCorrection;
8
8
  get heightOfProtrudingPart(): number;
9
9
  protected getRootClassName(): string;
10
10
  constructor(modelData: RulerModelData, controls: RulerControls);
11
+ recalculateLayout(): void;
12
+ private applyLayout;
11
13
  private adjustByTop;
12
14
  protected getModelState(): RulerModelState;
13
15
  updateView(): void;
@@ -19,6 +19,14 @@ export class RulerFirstLineIndentDragHandle extends RulerBaseIndentControl {
19
19
  this.rootElement.innerHTML = template;
20
20
  this.rootElement.title = this.modelData.titles.firstLineIndent;
21
21
  this.controls.ruler.rootElement.appendChild(this.rootElement);
22
+ this.applyLayout();
23
+ }
24
+ recalculateLayout() {
25
+ this.applyLayout();
26
+ if (this.modelData.showLeftIndent)
27
+ this.rootElement.style.left = this.viewState + RULLER_NUMBER_CORRECTION - this.leftCorrection + "px";
28
+ }
29
+ applyLayout() {
22
30
  this.adjustByTop();
23
31
  this.leftCorrection = Math.round(SizeUtils.getOffsetWidth(this.rootElement) / 2);
24
32
  this._heightOfProtrudingPart = SizeUtils.getOffsetHeight(this.rootElement) - this.controls.divisions.height / 2;