UNPKG

12.2 kBTypeScriptView Raw
1/**
2 * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4 */
5/**
6 * @module link/linkconfig
7 */
8import type { ArrayOrItem } from 'ckeditor5/src/utils.js';
9/**
10 * The configuration of the {@link module:link/link~Link link feature}.
11 *
12 * ```ts
13 * ClassicEditor
14 * .create( editorElement, {
15 * link: ... // Link feature configuration.
16 * } )
17 * .then( ... )
18 * .catch( ... );
19 * ```
20 *
21 * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
22 */
23export interface LinkConfig {
24 /**
25 * When set, the editor will add the given protocol to the link when the user creates a link without one.
26 * For example, when the user is creating a link and types `ckeditor.com` in the link form input, during link submission
27 * the editor will automatically add the `http://` protocol, so the link will look as follows: `http://ckeditor.com`.
28 *
29 * The feature also provides email address auto-detection. When you submit `hello@example.com`,
30 * the plugin will automatically change it to `mailto:hello@example.com`.
31 *
32 * ```ts
33 * ClassicEditor
34 * .create( editorElement, {
35 * link: {
36 * defaultProtocol: 'http://'
37 * }
38 * } )
39 * .then( ... )
40 * .catch( ... );
41 * ```
42 *
43 * **NOTE:** If no configuration is provided, the editor will not auto-fix the links.
44 */
45 defaultProtocol?: string;
46 /**
47 * This is a protocols whitelist that can be used in links, defined as an array of strings.
48 * When not set, the editor will use a default list of allowed protocols.
49 *
50 * **Note:** Use this with caution and at your own risk - adding unsafe protocols like `javascript:`
51 * can result in serious security vulnerabilities!
52 *
53 * ```ts
54 * ClassicEditor
55 * .create( editorElement, {
56 * link: {
57 * allowedProtocols: [ 'http', 'https', 'ftp', 'tel', 'mailto', 'ssh' ]
58 * }
59 * } )
60 * .then( ... )
61 * .catch( ... );
62 * ```
63 *
64 */
65 allowedProtocols?: Array<string>;
66 /**
67 * When set to `true`, the form will accept an empty value in the URL field, creating a link with an empty `href` (`<a href="">`).
68 *
69 * ```ts
70 * ClassicEditor
71 * .create( editorElement, {
72 * link: {
73 * allowCreatingEmptyLinks: true
74 * }
75 * } )
76 * .then( ... )
77 * .catch( ... );
78 * ```
79 *
80 * **NOTE:** This option only adds form validation. If a link with an empty `href` is loaded into the editor, it will be left as-is.
81 *
82 * @default false
83 */
84 allowCreatingEmptyLinks?: boolean;
85 /**
86 * When set to `true`, the `target="blank"` and `rel="noopener noreferrer"` attributes are automatically added to all external links
87 * in the editor. "External links" are all links in the editor content starting with `http`, `https`, or `//`.
88 *
89 * ```ts
90 * ClassicEditor
91 * .create( editorElement, {
92 * link: {
93 * addTargetToExternalLinks: true
94 * }
95 * } )
96 * .then( ... )
97 * .catch( ... );
98 * ```
99 *
100 * Internally, this option activates a predefined {@link module:link/linkconfig~LinkConfig#decorators automatic link decorator}
101 * that extends all external links with the `target` and `rel` attributes.
102 *
103 * **Note**: To control the `target` and `rel` attributes of specific links in the edited content, a dedicated
104 * {@link module:link/linkconfig~LinkDecoratorManualDefinition manual} decorator must be defined in the
105 * {@link module:link/linkconfig~LinkConfig#decorators `config.link.decorators`} array. In such scenario,
106 * the `config.link.addTargetToExternalLinks` option should remain `undefined` or `false` to not interfere with the manual decorator.
107 *
108 * It is possible to add other {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition automatic}
109 * or {@link module:link/linkconfig~LinkDecoratorManualDefinition manual} link decorators when this option is active.
110 *
111 * More information about decorators can be found in the {@link module:link/linkconfig~LinkConfig#decorators decorators configuration}
112 * reference.
113 *
114 * @default false
115 */
116 addTargetToExternalLinks?: boolean;
117 /**
118 * Decorators provide an easy way to configure and manage additional link attributes in the editor content. There are
119 * two types of link decorators:
120 *
121 * * {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition Automatic} &ndash; They match links against pre–defined rules and
122 * manage their attributes based on the results.
123 * * {@link module:link/linkconfig~LinkDecoratorManualDefinition Manual} &ndash; They allow users to control link attributes
124 * individually, using the editor UI.
125 *
126 * Link decorators are defined as objects with key-value pairs, where the key is the name provided for a given decorator and the
127 * value is the decorator definition.
128 *
129 * The name of the decorator also corresponds to the {@glink framework/architecture/editing-engine#text-attributes text
130 * attribute} in the model. For instance, the `isExternal` decorator below is represented as a `linkIsExternal` attribute in the model.
131 *
132 * ```ts
133 * ClassicEditor
134 * .create( editorElement, {
135 * link: {
136 * decorators: {
137 * isExternal: {
138 * mode: 'automatic',
139 * callback: url => url.startsWith( 'http://' ),
140 * attributes: {
141 * target: '_blank',
142 * rel: 'noopener noreferrer'
143 * }
144 * },
145 * isDownloadable: {
146 * mode: 'manual',
147 * label: 'Downloadable',
148 * attributes: {
149 * download: 'file.png',
150 * }
151 * },
152 * // ...
153 * }
154 * }
155 * } )
156 * .then( ... )
157 * .catch( ... );
158 * ```
159 *
160 * To learn more about the configuration syntax, check out the {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition automatic}
161 * and {@link module:link/linkconfig~LinkDecoratorManualDefinition manual} decorator option reference.
162 *
163 * **Warning:** Currently, link decorators work independently of one another and no conflict resolution mechanism exists.
164 * For example, configuring the `target` attribute using both an automatic and a manual decorator at the same time could end up with
165 * quirky results. The same applies if multiple manual or automatic decorators were defined for the same attribute.
166 *
167 * **Note**: Since the `target` attribute management for external links is a common use case, there is a predefined automatic decorator
168 * dedicated for that purpose which can be enabled by turning a single option on. Check out the
169 * {@link module:link/linkconfig~LinkConfig#addTargetToExternalLinks `config.link.addTargetToExternalLinks`}
170 * configuration description to learn more.
171 *
172 * See also the {@glink features/link#custom-link-attributes-decorators link feature guide} for more information.
173 */
174 decorators?: Record<string, LinkDecoratorDefinition>;
175}
176/**
177 * A link decorator definition. Two types implement this definition:
178 *
179 * * {@link module:link/linkconfig~LinkDecoratorManualDefinition}
180 * * {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition}
181 *
182 * Refer to their document for more information about available options or to the
183 * {@glink features/link#custom-link-attributes-decorators link feature guide} for general information.
184 */
185export type LinkDecoratorDefinition = LinkDecoratorAutomaticDefinition | LinkDecoratorManualDefinition;
186/**
187 * Describes an automatic {@link module:link/linkconfig~LinkConfig#decorators link decorator}. This decorator type matches
188 * all links in the editor content against a function that decides whether the link should receive a pre–defined set of attributes.
189 *
190 * It takes an object with key-value pairs of attributes and a callback function that must return a Boolean value based on the link's
191 * `href` (URL). When the callback returns `true`, attributes are applied to the link.
192 *
193 * For example, to add the `target="_blank"` attribute to all links in the editor starting with `http://`, the
194 * configuration could look like this:
195 *
196 * ```ts
197 * {
198 * mode: 'automatic',
199 * callback: url => url.startsWith( 'http://' ),
200 * attributes: {
201 * target: '_blank'
202 * }
203 * }
204 * ```
205 *
206 * **Note**: Since the `target` attribute management for external links is a common use case, there is a predefined automatic decorator
207 * dedicated for that purpose that can be enabled by turning a single option on. Check out the
208 * {@link module:link/linkconfig~LinkConfig#addTargetToExternalLinks `config.link.addTargetToExternalLinks`}
209 * configuration description to learn more.
210 */
211export interface LinkDecoratorAutomaticDefinition {
212 /**
213 * Link decorator type. It is `'automatic'` for all automatic decorators.
214 */
215 mode: 'automatic';
216 /**
217 * Takes a `url` as a parameter and returns `true` if the `attributes` should be applied to the link.
218 */
219 callback: (url: string | null) => boolean;
220 /**
221 * Key-value pairs used as link attributes added to the output during the
222 * {@glink framework/architecture/editing-engine#conversion downcasting}.
223 * Attributes should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
224 */
225 attributes?: Record<string, string>;
226 /**
227 * Key-value pairs used as link styles added to the output during the
228 * {@glink framework/architecture/editing-engine#conversion downcasting}.
229 * Styles should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
230 */
231 styles?: Record<string, string>;
232 /**
233 * Class names used as link classes added to the output during the
234 * {@glink framework/architecture/editing-engine#conversion downcasting}.
235 * Classes should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
236 */
237 classes?: ArrayOrItem<string>;
238}
239/**
240 * Describes a manual {@link module:link/linkconfig~LinkConfig#decorators link decorator}. This decorator type is represented in
241 * the link feature's {@link module:link/linkui user interface} as a switch that the user can use to control the presence
242 * of a predefined set of attributes.
243 *
244 * For instance, to allow the users to manually control the presence of the `target="_blank"` and
245 * `rel="noopener noreferrer"` attributes on specific links, the decorator could look as follows:
246 *
247 * ```ts
248 * {
249 * mode: 'manual',
250 * label: 'Open in a new tab',
251 * defaultValue: true,
252 * attributes: {
253 * target: '_blank',
254 * rel: 'noopener noreferrer'
255 * }
256 * }
257 * ```
258 */
259export interface LinkDecoratorManualDefinition {
260 /**
261 * Link decorator type. It is `'manual'` for all manual decorators.
262 */
263 mode: 'manual';
264 /**
265 * The label of the UI button that the user can use to control the presence of link attributes.
266 */
267 label: string;
268 /**
269 * Key-value pairs used as link attributes added to the output during the
270 * {@glink framework/architecture/editing-engine#conversion downcasting}.
271 * Attributes should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
272 */
273 attributes?: Record<string, string>;
274 /**
275 * Key-value pairs used as link styles added to the output during the
276 * {@glink framework/architecture/editing-engine#conversion downcasting}.
277 * Styles should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
278 */
279 styles?: Record<string, string>;
280 /**
281 * Class names used as link classes added to the output during the
282 * {@glink framework/architecture/editing-engine#conversion downcasting}.
283 * Classes should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
284 */
285 classes?: ArrayOrItem<string>;
286 /**
287 * Controls whether the decorator is "on" by default.
288 */
289 defaultValue?: boolean;
290}