devexpress-richedit 24.1.6-build-24246-0102 → 24.1.6
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 +45 -5
- package/dist/dx.richedit.min.js +1 -1
- package/lib/client/client-rich-edit.js +2 -2
- package/lib/client/i-rich-constructor-settings.d.ts +2 -0
- package/lib/client/public/options.d.ts +2 -0
- package/lib/client/settings.js +4 -0
- package/lib/common/commands/fields/open-hyperlink-command.js +6 -2
- package/lib/common/model/options/fields.d.ts +2 -0
- package/lib/common/model/options/fields.js +6 -2
- package/lib/common/utils/utils.d.ts +7 -0
- package/lib/common/utils/utils.js +26 -0
- package/package.json +3 -3
@@ -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 ("
|
57
|
-
config(JSON.parse(atob("
|
56
|
+
if ("eyJsaWNlbnNlS2V5IjoiZXdvZ0lDSm1iM0p0WVhRaU9pQXhMQW9nSUNKcGJuUmxjbTVoYkZWellXZGxTV1FpT2lBaWNIQktkR3hUTlRaeU1HRjZNV3R4VldwWFNuTXRaeUlLZlE9PS5GSzV0WCtSUkt0akY2Q2NwaExOa0R2V0RCTHVkb0ZrdTN3LzJEMGMxRVlWMXp4KzJEYURkYnA0MGtPbXpKTnBRMXB0TUpiT1NTUm1JVmJaSU5VejRINDE3ejZMTDF4cDRZdWpyL2hQU3RiZlNodkNJMGFmemN4TzhXL1ZaVUJUR2gyZUh6UT09In0=")
|
57
|
+
config(JSON.parse(atob("eyJsaWNlbnNlS2V5IjoiZXdvZ0lDSm1iM0p0WVhRaU9pQXhMQW9nSUNKcGJuUmxjbTVoYkZWellXZGxTV1FpT2lBaWNIQktkR3hUTlRaeU1HRjZNV3R4VldwWFNuTXRaeUlLZlE9PS5GSzV0WCtSUkt0akY2Q2NwaExOa0R2V0RCTHVkb0ZrdTN3LzJEMGMxRVlWMXp4KzJEYURkYnA0MGtPbXpKTnBRMXB0TUpiT1NTUm1JVmJaSU5VejRINDE3ejZMTDF4cDRZdWpyL2hQU3RiZlNodkNJMGFmemN4TzhXL1ZaVUJUR2gyZUh6UT09In0=")));
|
58
58
|
this.prepareElement(element, settings);
|
59
59
|
this.initDefaultFontsAndStyles();
|
60
60
|
this.initBars(settings.ribbon, settings.fonts);
|
@@ -80,6 +80,8 @@ export interface IRichEditFieldsSettings {
|
|
80
80
|
defaultDateFormat?: string;
|
81
81
|
openHyperlinkOnClick?: boolean;
|
82
82
|
keepHyperlinkResultForInvalidReference?: boolean;
|
83
|
+
disableRelativeHyperlinkUri?: boolean;
|
84
|
+
allowedHyperlinkUriProtocols?: string[];
|
83
85
|
createHyperlinkTooltip?: (hyperlinkTooltip: string, hint: string) => string;
|
84
86
|
}
|
85
87
|
export interface IRichEditRangePermissionsSettings {
|
@@ -93,6 +93,8 @@ export interface IFieldsSettings {
|
|
93
93
|
defaultDateFormat?: string;
|
94
94
|
openHyperlinkOnClick?: boolean;
|
95
95
|
keepHyperlinkResultForInvalidReference?: boolean;
|
96
|
+
disableRelativeHyperlinkUri?: boolean;
|
97
|
+
allowedHyperlinkUriProtocols?: string[];
|
96
98
|
createHyperlinkTooltip?: (hyperlinkTooltip: string, hint: string) => string;
|
97
99
|
}
|
98
100
|
export interface IBookmarkSettings {
|
package/lib/client/settings.js
CHANGED
@@ -146,6 +146,10 @@ export class Settings {
|
|
146
146
|
result.fields.createHyperlinkTooltip = this.parseEventHandler(settings.fields.createHyperlinkTooltip);
|
147
147
|
if (isDefined(settings.fields.keepHyperlinkResultForInvalidReference))
|
148
148
|
result.fields.keepHyperlinkResultForInvalidReference = settings.fields.keepHyperlinkResultForInvalidReference;
|
149
|
+
if (isDefined(settings.fields.disableRelativeHyperlinkUri))
|
150
|
+
result.fields.disableRelativeHyperlinkUri = settings.fields.disableRelativeHyperlinkUri;
|
151
|
+
if (isDefined(settings.fields.allowedHyperlinkUriProtocols))
|
152
|
+
result.fields.allowedHyperlinkUriProtocols = settings.fields.allowedHyperlinkUriProtocols;
|
149
153
|
}
|
150
154
|
}
|
151
155
|
static parsePrintingSettings(settings, result) {
|
@@ -4,6 +4,7 @@ import { ReadOnlyMode } from '../../interfaces/i-rich-edit-core';
|
|
4
4
|
import { RichEditClientCommand } from '../client-command';
|
5
5
|
import { CommandSimpleOptions } from '../command-base';
|
6
6
|
import { HyperlinkCommandBase } from './hyperlink-command-base';
|
7
|
+
import { createUrlValidationOptions, isUrlValid } from '../../../common/utils/utils';
|
7
8
|
export class OpenHyperlinkCommand extends HyperlinkCommandBase {
|
8
9
|
executeCore(state, options) {
|
9
10
|
let field;
|
@@ -27,8 +28,11 @@ export class OpenHyperlinkCommand extends HyperlinkCommandBase {
|
|
27
28
|
if (hyperlinkInfo.anchor)
|
28
29
|
this.control.commandManager.getCommand(RichEditClientCommand.GoToBookmark)
|
29
30
|
.execute(this.control.commandManager.isPublicApiCall, new CommandSimpleOptions(this.control, hyperlinkInfo.anchor));
|
30
|
-
else
|
31
|
-
|
31
|
+
else {
|
32
|
+
const options = createUrlValidationOptions(this.control);
|
33
|
+
if (isUrlValid(hyperlinkInfo.uri, options))
|
34
|
+
Url.navigate(hyperlinkInfo.uri, "_blank");
|
35
|
+
}
|
32
36
|
return true;
|
33
37
|
}
|
34
38
|
isEnabledInReadOnlyMode() {
|
@@ -6,6 +6,8 @@ export declare class FieldsSettings {
|
|
6
6
|
defaultTimeFormat: string;
|
7
7
|
defaultDateFormat: string;
|
8
8
|
openHyperlinkOnClick: boolean;
|
9
|
+
disableRelativeHyperlinkUri: boolean;
|
10
|
+
allowedHyperlinkUriProtocols: string[];
|
9
11
|
keepHyperlinkResultForInvalidReference: boolean;
|
10
12
|
createHyperlinkTooltip: (hyperlinkTooltip: string, hint: string) => string;
|
11
13
|
constructor();
|
@@ -3,6 +3,7 @@ import { isDefined, isNonNullString } from '@devexpress/utils/lib/utils/common';
|
|
3
3
|
export class FieldsSettings {
|
4
4
|
constructor() {
|
5
5
|
this.openHyperlinkOnClick = false;
|
6
|
+
this.disableRelativeHyperlinkUri = false;
|
6
7
|
this.updateFieldsBeforePrint = true;
|
7
8
|
this.updateFieldsOnPaste = true;
|
8
9
|
this.defaultTimeFormat = FieldsSettings.DEFAULT_TIME_FORMAT;
|
@@ -27,9 +28,12 @@ export class FieldsSettings {
|
|
27
28
|
this.openHyperlinkOnClick = obj.openHyperlinkOnClick;
|
28
29
|
if (isDefined(obj.keepHyperlinkResultForInvalidReference))
|
29
30
|
this.keepHyperlinkResultForInvalidReference = obj.keepHyperlinkResultForInvalidReference;
|
30
|
-
if (isDefined(obj.createHyperlinkTooltip) && obj.createHyperlinkTooltip !== '')
|
31
|
+
if (isDefined(obj.createHyperlinkTooltip) && obj.createHyperlinkTooltip !== '')
|
31
32
|
this.createHyperlinkTooltip = convertToFunction(obj.createHyperlinkTooltip);
|
32
|
-
|
33
|
+
if (isDefined(obj.disableRelativeHyperlinkUri))
|
34
|
+
this.disableRelativeHyperlinkUri = obj.disableRelativeHyperlinkUri;
|
35
|
+
if (isDefined(obj.allowedHyperlinkUriProtocols))
|
36
|
+
this.allowedHyperlinkUriProtocols = obj.allowedHyperlinkUriProtocols;
|
33
37
|
}
|
34
38
|
clone() {
|
35
39
|
const result = new FieldsSettings();
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { Point } from '@devexpress/utils/lib/geometry/point';
|
2
|
+
import { IRichEditControl } from '../interfaces/i-rich-edit-core';
|
2
3
|
export declare function rotatePoint(point: Point, angle: number, center: Point): Point;
|
3
4
|
export declare class SearchTreeItemResult<T> {
|
4
5
|
readonly parentList: T[];
|
@@ -11,3 +12,9 @@ export declare function searchTreeItem<T extends {
|
|
11
12
|
}>(items: T[], comparer: (item: T) => boolean): SearchTreeItemResult<T> | null;
|
12
13
|
export declare function convertToFunction(func: any): any | null;
|
13
14
|
export declare function splitByLines(text: string): string[];
|
15
|
+
export interface IUrlValidationOptions {
|
16
|
+
allowRelativeUrl?: boolean;
|
17
|
+
allowedProtocols?: string[];
|
18
|
+
}
|
19
|
+
export declare function createUrlValidationOptions(control: IRichEditControl): IUrlValidationOptions;
|
20
|
+
export declare function isUrlValid(url: string, options?: IUrlValidationOptions): boolean;
|
@@ -56,3 +56,29 @@ export function convertToFunction(func) {
|
|
56
56
|
export function splitByLines(text) {
|
57
57
|
return text ? text.split(/\r\n|\r|\n/) : [''];
|
58
58
|
}
|
59
|
+
export function createUrlValidationOptions(control) {
|
60
|
+
const fieldSettings = control.modelManager.richOptions.fields;
|
61
|
+
return {
|
62
|
+
allowRelativeUrl: !fieldSettings.disableRelativeHyperlinkUri,
|
63
|
+
allowedProtocols: fieldSettings.allowedHyperlinkUriProtocols
|
64
|
+
};
|
65
|
+
}
|
66
|
+
const disallowedProtocols = [
|
67
|
+
'data',
|
68
|
+
'javascript'
|
69
|
+
];
|
70
|
+
export function isUrlValid(url, options) {
|
71
|
+
let currentLocation;
|
72
|
+
if (options === null || options === void 0 ? void 0 : options.allowRelativeUrl)
|
73
|
+
currentLocation = window.location.href;
|
74
|
+
try {
|
75
|
+
const resultUrl = new URL(url, currentLocation);
|
76
|
+
const protocol = resultUrl.protocol.slice(0, -1);
|
77
|
+
const allowedProtocols = options === null || options === void 0 ? void 0 : options.allowedProtocols;
|
78
|
+
if (allowedProtocols)
|
79
|
+
return allowedProtocols.includes(protocol);
|
80
|
+
return !disallowedProtocols.includes(protocol);
|
81
|
+
}
|
82
|
+
catch (_a) { }
|
83
|
+
return false;
|
84
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "devexpress-richedit",
|
3
|
-
"version": "24.1.6
|
3
|
+
"version": "24.1.6",
|
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.6
|
18
|
-
"devextreme-dist": "24.1.6
|
17
|
+
"devextreme": "24.1.6",
|
18
|
+
"devextreme-dist": "24.1.6"
|
19
19
|
},
|
20
20
|
"dependencies": {
|
21
21
|
"jszip": "~3.10.1",
|