devexpress-richedit 24.1.13-build-25156-0103 → 24.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.
@@ -53,8 +53,8 @@ export class ClientRichEdit {
53
53
  this.rawDataSource = settings.rawDataSource;
54
54
  this.contextMenuSettings = settings.contextMenuSettings;
55
55
  this.fullScreenHelper = new FullScreenHelper(element);
56
- if ("eyJsaWNlbnNlS2V5IjoiZXdvZ0lDSm1iM0p0WVhRaU9pQXhMQW9nSUNKcGJuUmxjbTVoYkZWellXZGxTV1FpT2lBaVREZzBkbWxZYUZOS1MyWnRRams0U0VOTVkxTTRNaUlLZlE9PS53SkN1UVJhY3dIaU9DMEdWZFBPVlNacDJsRThrcTdTbUZTTWpIMXgvamxEMnowbzQvYWFkVm9zK1g2ZzlwSDZaYjdUUXdOdlZvQkduRUNwblB2M0ZaOUV4eWlkK3pybUxITE8yZnIyVzFTOEJOWE1YaE1mSlNPdjJ3aCs5SDBSd2lMejJxUT09In0=")
57
- config(JSON.parse(atob("eyJsaWNlbnNlS2V5IjoiZXdvZ0lDSm1iM0p0WVhRaU9pQXhMQW9nSUNKcGJuUmxjbTVoYkZWellXZGxTV1FpT2lBaVREZzBkbWxZYUZOS1MyWnRRams0U0VOTVkxTTRNaUlLZlE9PS53SkN1UVJhY3dIaU9DMEdWZFBPVlNacDJsRThrcTdTbUZTTWpIMXgvamxEMnowbzQvYWFkVm9zK1g2ZzlwSDZaYjdUUXdOdlZvQkduRUNwblB2M0ZaOUV4eWlkK3pybUxITE8yZnIyVzFTOEJOWE1YaE1mSlNPdjJ3aCs5SDBSd2lMejJxUT09In0=")));
56
+ if ("eyJsaWNlbnNlS2V5IjoiZXdvZ0lDSm1iM0p0WVhRaU9pQXhMQW9nSUNKcGJuUmxjbTVoYkZWellXZGxTV1FpT2lBaVUyTnFlV05wY0hrM1ptcHpZMm8wV2xwdWVFUTVUaUlLZlE9PS5NQTY1NWlJNi9wMlJTZ2NnamlnVXFOTDVNUU15YjAzRGh3ZjdUeWlvcURSajIwL3Izbnl3S3dJOHdUVlM4aUR3eG1ZeWN4UmlIYWtiTTN3dS8ydUs2UTY2V3VXalFEeFlJbXhhajVBVFUrZDQzN2gwTGQvYXlqTHRiZWlhbFJBRkxWVWh6Zz09In0=")
57
+ config(JSON.parse(atob("eyJsaWNlbnNlS2V5IjoiZXdvZ0lDSm1iM0p0WVhRaU9pQXhMQW9nSUNKcGJuUmxjbTVoYkZWellXZGxTV1FpT2lBaVUyTnFlV05wY0hrM1ptcHpZMm8wV2xwdWVFUTVUaUlLZlE9PS5NQTY1NWlJNi9wMlJTZ2NnamlnVXFOTDVNUU15YjAzRGh3ZjdUeWlvcURSajIwL3Izbnl3S3dJOHdUVlM4aUR3eG1ZeWN4UmlIYWtiTTN3dS8ydUs2UTY2V3VXalFEeFlJbXhhajVBVFUrZDQzN2gwTGQvYXlqTHRiZWlhbFJBRkxWVWh6Zz09In0=")));
58
58
  this.prepareElement(element, settings);
59
59
  this.initDefaultFontsAndStyles();
60
60
  this.initBars(settings.ribbon, settings.fonts);
@@ -197,7 +197,7 @@ export class ImagesApi {
197
197
  applyVerticalPosition(verticalPosition, anchorInfo);
198
198
  const anchorPictureInfo = new AnchorPictureInfo(new PictureSize(true, 0, cacheInfo, new Size(100, 100)), shape, anchorInfo, new NonVisualDrawingObjectInfo(), new NonVisualDrawingObjectInfo());
199
199
  anchorPictureInfo.containerProperties.description = options.description;
200
- this._processor.modelManager.modelManipulator.picture.insertAnchoredPictureViaHistory(new SubDocumentPosition(this._subDocument, position), inputPos.charPropsBundle, anchorPictureInfo, new ImageLoadingOptions(false, size ? new Size(size.width, size.height) : undefined, (_picInterval, _cacheInfo) => setTimeout(() => {
200
+ this._processor.modelManager.modelManipulator.picture.insertAnchoredPictureViaHistory(new SubDocumentPosition(this._subDocument, position), inputPos.charPropsBundle, anchorPictureInfo, ImageLoadingOptions.initByActualSize(size ? new Size(size.width, size.height) : undefined, (_picInterval, _cacheInfo) => setTimeout(() => {
201
201
  callback(getFloatingImageApiFromRun(this._processor, this._subDocument, this._subDocument.getRunAndIndexesByPosition(position)));
202
202
  }, 0)));
203
203
  this._processor.endUpdate();
@@ -155,6 +155,7 @@ export interface IRichEditFontsSettings {
155
155
  export interface IFontSettings {
156
156
  name: string;
157
157
  fontFamily: string;
158
+ useGoogleFonts?: boolean;
158
159
  italicFontUri?: string;
159
160
  boldFontUri?: string;
160
161
  boldItalicFontUri?: string;
@@ -13,6 +13,8 @@ export declare class PrintDocumentOnClient extends CommandBase<SimpleCommandStat
13
13
  executeCore(_state: SimpleCommandState, options: CommandSimpleOptions<PrintMode | PrintingSettings | undefined>): boolean;
14
14
  private printCore;
15
15
  private generatePrintDocument;
16
+ private getGoogleFonts;
17
+ private createGoogleFontStyleLink;
16
18
  private generatePrintContent;
17
19
  private createZIndexStyles;
18
20
  }
@@ -80,8 +80,18 @@ export class PrintDocumentOnClient extends CommandBase {
80
80
  return true;
81
81
  }
82
82
  printCore(htmlPrinting, printWindow, closePrintDialogWithHtmlPreview, needSwitchViewType, needToggleHiddenSymbols) {
83
- if (htmlPrinting)
84
- this.generatePrintDocument(printWindow, closePrintDialogWithHtmlPreview);
83
+ if (htmlPrinting) {
84
+ this.generatePrintDocument(printWindow.document);
85
+ printWindow.focus();
86
+ const interval = setInterval(() => {
87
+ if (printWindow.document.readyState == 'complete') {
88
+ printWindow.print();
89
+ if (closePrintDialogWithHtmlPreview && !Browser.AndroidMobilePlatform)
90
+ printWindow.close();
91
+ clearInterval(interval);
92
+ }
93
+ }, 100);
94
+ }
85
95
  else {
86
96
  pdfExport(this.control, (blob, _stream) => {
87
97
  if (window.navigator.msSaveOrOpenBlob && !Browser.Edge)
@@ -96,12 +106,27 @@ export class PrintDocumentOnClient extends CommandBase {
96
106
  this.control.commandManager.getCommand(RichEditClientCommand.ToggleShowWhitespace).execute(this.control.commandManager.isPublicApiCall);
97
107
  this.control.commandManager.isPrintingProcessing = false;
98
108
  }
99
- generatePrintDocument(printWindow, closePrintDialogWithHtmlPreview) {
109
+ generatePrintDocument(document) {
100
110
  const height = this.control.layout.pages[0].height;
101
111
  const width = this.control.layout.pages[0].width;
102
- let printWindowContent = `<!DOCTYPE html>
103
- <html moznomarginboxes mozdisallowselectionprint>
112
+ let fontLink = "";
113
+ let divsToLoadFonts = "";
114
+ const googleFonts = this.getGoogleFonts();
115
+ if (googleFonts.length > 0) {
116
+ fontLink = this.createGoogleFontStyleLink(googleFonts);
117
+ divsToLoadFonts = googleFonts.reduce((prev, curr) => {
118
+ const fontStyles = [`font-family:${curr}`, 'font-weight:bold', 'font-style:italic'];
119
+ const result = [];
120
+ for (let i = 1; i <= fontStyles.length; i++)
121
+ result.push(`<div style="font-size:1pt;position:absolute;top:-1000px;${fontStyles.slice(0, i).join(';')}">${curr}</div>`);
122
+ return prev ? [prev, ...result].join('\n') : result.join('\n');
123
+ }, null);
124
+ }
125
+ document.documentElement.innerHTML =
126
+ `<!DOCTYPE html>
127
+ <html moznomarginboxes mozdisallowselectionprint>
104
128
  <head>
129
+ ${fontLink}
105
130
  <style ${this._nonce ? `nonce="${this._nonce}"` : ''}>
106
131
  html, body {
107
132
  margin: 0;
@@ -120,22 +145,25 @@ export class PrintDocumentOnClient extends CommandBase {
120
145
  </style>
121
146
  </head>
122
147
  <body>
148
+ ${divsToLoadFonts}
123
149
  </body>
124
- </html>`;
125
- printWindow.document.write(printWindowContent);
126
- printWindow.document.close();
150
+ </html>`;
127
151
  this.generatePrintContent().forEach((child) => {
128
- printWindow.document.body.appendChild(child);
152
+ document.body.appendChild(child);
129
153
  });
130
- printWindow.focus();
131
- const interval = setInterval(() => {
132
- if (printWindow.document.readyState == 'complete') {
133
- printWindow.print();
134
- if (closePrintDialogWithHtmlPreview && !Browser.AndroidMobilePlatform)
135
- printWindow.close();
136
- clearInterval(interval);
137
- }
138
- }, 100);
154
+ }
155
+ getGoogleFonts() {
156
+ return this.control.modelManager.richOptions.fonts.fonts.reduce((res, f) => {
157
+ if (f.useGoogleFonts)
158
+ res.push(f.fontFamily);
159
+ return res;
160
+ }, []);
161
+ }
162
+ createGoogleFontStyleLink(fontFamilies) {
163
+ const url = new URL('https://fonts.googleapis.com/css');
164
+ url.searchParams.append('family', fontFamilies.join('|'));
165
+ url.searchParams.append('display', 'auto');
166
+ return `<link href="${url.toString()}" rel="stylesheet" />`;
139
167
  }
140
168
  generatePrintContent() {
141
169
  const layout = this.control.layout;
@@ -25,7 +25,7 @@ export class WordHolderInfo {
25
25
  }
26
26
  if (res == null)
27
27
  return false;
28
- if (this.rowFormatter.row.isEmpty()) {
28
+ if (this.rowFormatter.row.isEmpty() || this.rowFormatter.row.containsSpacesOnly()) {
29
29
  if (this.rowFormatter.rowSizesManager.rowFormattingInfo.isFloatingIntersectRow) {
30
30
  this.rowFormatter.rowSizesManager.rowFormattingInfo.findNextYPosWhatHasNeededSpace(res.requiredWidth);
31
31
  return this.pushBoxes();
@@ -8,12 +8,15 @@ export declare class CacheImageInfo {
8
8
  private _convertedBase64?;
9
9
  private _size?;
10
10
  private _isLoaded;
11
+ private _isSizeDefined;
11
12
  tmpId?: number;
12
13
  actualId?: number;
13
14
  imageUrl?: string;
14
15
  file?: File;
15
16
  get isLoaded(): boolean;
16
17
  set isLoaded(val: boolean);
18
+ get isSizeDefined(): boolean;
19
+ set isSizeDefined(val: boolean);
17
20
  get size(): Size;
18
21
  set size(val: Size);
19
22
  get currId(): number;
@@ -22,7 +25,7 @@ export declare class CacheImageInfo {
22
25
  get pdfCompatibleBase64(): string | undefined;
23
26
  get referenceInfo(): CacheImageInfo | undefined;
24
27
  set referenceInfo(val: CacheImageInfo | undefined);
25
- constructor(base64?: string, actualId?: number, tmpId?: number, imageUrl?: string, file?: File, referenceInfo?: CacheImageInfo, size?: Size, isLoaded?: boolean);
28
+ constructor(base64?: string, actualId?: number, tmpId?: number, imageUrl?: string, file?: File, referenceInfo?: CacheImageInfo, size?: Size, isLoaded?: boolean, isActualSize?: boolean);
26
29
  equals(obj: CacheImageInfo): boolean;
27
30
  clone(): CacheImageInfo;
28
31
  shouldMakeImagePdfCompatible(): boolean;
@@ -4,19 +4,22 @@ import { Base64Utils } from '@devexpress/utils/lib/utils/base64';
4
4
  import { NumberMapUtils } from '@devexpress/utils/lib/utils/map/number';
5
5
  import { isDefined } from '@devexpress/utils/lib/utils/common';
6
6
  export class CacheImageInfo {
7
- constructor(base64, actualId, tmpId, imageUrl, file, referenceInfo, size, isLoaded) {
7
+ constructor(base64, actualId, tmpId, imageUrl, file, referenceInfo, size, isLoaded, isActualSize) {
8
8
  this._base64 = base64 !== undefined ? Base64Utils.normalizeToDataUrl(base64, "image/png") : undefined;
9
9
  this.actualId = actualId;
10
10
  this.tmpId = tmpId;
11
11
  this._referenceInfo = referenceInfo;
12
12
  this._size = size ? size : CacheImageInfo.emptyPictureSize;
13
13
  this._isLoaded = isLoaded !== undefined ? isLoaded : false;
14
+ this._isSizeDefined = isActualSize ? isActualSize : !!size;
14
15
  this.imageUrl = imageUrl;
15
16
  this.file = file;
16
17
  }
17
18
  static get emptyPictureSize() { return new Size(CacheImageInfo.emptyPicDimension, CacheImageInfo.emptyPicDimension); }
18
19
  get isLoaded() { return this._referenceInfo ? this._referenceInfo._isLoaded : this._isLoaded; }
19
20
  set isLoaded(val) { this._isLoaded = val; }
21
+ get isSizeDefined() { return this._referenceInfo ? this._referenceInfo._isSizeDefined : this._isSizeDefined; }
22
+ set isSizeDefined(val) { this._isSizeDefined = val; }
20
23
  get size() { return this._referenceInfo ? this._referenceInfo._size : this._size; }
21
24
  set size(val) { this._size = val; }
22
25
  get currId() { return this.actualId !== undefined ? this.actualId : this.tmpId; }
@@ -29,6 +32,7 @@ export class CacheImageInfo {
29
32
  this._base64 = undefined;
30
33
  this._size = undefined;
31
34
  this._isLoaded = undefined;
35
+ this._isSizeDefined = undefined;
32
36
  this.file = undefined;
33
37
  }
34
38
  equals(obj) {
@@ -41,7 +45,7 @@ export class CacheImageInfo {
41
45
  this.size.equals(obj.size);
42
46
  }
43
47
  clone() {
44
- return new CacheImageInfo(this._base64, this.actualId, this.tmpId, this.imageUrl, this.file, this._referenceInfo, this._size, this._isLoaded);
48
+ return new CacheImageInfo(this._base64, this.actualId, this.tmpId, this.imageUrl, this.file, this._referenceInfo, this._size, this._isLoaded, this._isSizeDefined);
45
49
  }
46
50
  shouldMakeImagePdfCompatible() {
47
51
  if (isDefined(this._convertedBase64))
@@ -88,7 +88,7 @@ export class PictureManipulator extends RunsBaseManipulator {
88
88
  this.history.addTransaction(() => {
89
89
  this.modelManipulator.range.removeInterval(new SubDocumentInterval(subDocument, interval), true, false);
90
90
  const newInfo = new InlinePictureInfo(pictureRun.size.clone(), new Shape(), -1, pictureRun.info.containerProperties, pictureRun.info.nonVisualDrawingProperties);
91
- this.modelManipulator.picture.insertInlinePictureViaHistory(new SubDocumentPosition(subDocument, interval.start), charPropsBundle, newInfo);
91
+ this.modelManipulator.picture.insertInlinePictureViaHistory(new SubDocumentPosition(subDocument, interval.start), charPropsBundle, newInfo, new ImageLoadingOptions(!pictureRun.cacheInfo.isSizeDefined));
92
92
  });
93
93
  }
94
94
  }
@@ -103,7 +103,7 @@ export class PictureManipulator extends RunsBaseManipulator {
103
103
  anchorInfo.zOrder = this.modelManipulator.floatingObject.zOrder.getNewZOrder(subDocument);
104
104
  this.modelManipulator.range.removeInterval(new SubDocumentInterval(subDocument, interval), true, false);
105
105
  const newInfo = new AnchorPictureInfo(pictureRun.size.clone(), new Shape(), anchorInfo, pictureRun.info.containerProperties, pictureRun.info.nonVisualDrawingProperties);
106
- this.modelManipulator.picture.insertAnchoredPictureViaHistory(new SubDocumentPosition(subDocument, interval.start), charPropsBundle, newInfo, new ImageLoadingOptions(false));
106
+ this.modelManipulator.picture.insertAnchoredPictureViaHistory(new SubDocumentPosition(subDocument, interval.start), charPropsBundle, newInfo, new ImageLoadingOptions(!pictureRun.cacheInfo.isSizeDefined));
107
107
  run = subDocument.getRunByPosition(interval.start);
108
108
  }
109
109
  let anchoredRun = run.getType() == RunType.AnchoredPictureRun ? run : run;
@@ -9,7 +9,7 @@ export interface IFontSettings {
9
9
  name: string;
10
10
  fontFamily: string;
11
11
  googleFontsResponse?: string;
12
- useGoogleFonts?: string;
12
+ useGoogleFonts?: boolean;
13
13
  italicFontUri?: string;
14
14
  boldFontUri?: string;
15
15
  boldItalicFontUri?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devexpress-richedit",
3
- "version": "24.1.13-build-25156-0103",
3
+ "version": "24.1.13",
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.13-build-25154-1937",
18
- "devextreme-dist": "24.1.13-build-25154-1937"
17
+ "devextreme": "24.1.13",
18
+ "devextreme-dist": "24.1.13"
19
19
  },
20
20
  "dependencies": {
21
21
  "jszip": "~3.10.1",