UNPKG

@ckeditor/ckeditor5-merge-fields

Version:

Merge fields feature for CKEditor 5.

260 lines (259 loc) 9.79 kB
/** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ /** * @module merge-fields/mergefieldsconfig * @publicApi */ import type { Editor } from 'ckeditor5/src/core.js'; /** * The configuration of the merge fields feature. * * The properties defined in this config are set in the `config.mergeFields` namespace. * * ```ts * ClassicEditor * .create( editorElement, { * mergeFields: { * // Merge fields configuration. * } * } ) * .then( ... ) * .catch( ... ); * ``` * * See {@link module:core/editor/editorconfig~EditorConfig all editor options}. */ export interface MergeFieldsConfig { /** * The definitions of the merge fields that can be used in the editor. * It's allowed to define them in any combination of groups and individual merge fields. * The order of the definitions is respected when displaying the merge fields in the UI dropdown * except that merge fields that are not assigned to any group are displayed at the * very bottom of the list. */ definitions?: Array<GroupDefinition | MergeFieldDefinition>; /** * A prefix used to identify merge fields in the editor data. * * The list of allowed characters includes: ``'"`!#%:;=@{}~$()*+/?[\]^|``. * * @default '\{\{' */ prefix?: string; /** * A suffix used to identify merge fields in the editor data. * * The list of allowed characters includes: ``'"`!#%:;=@{}~$()*+/?[\]^|``. * * @default '\}\}' */ suffix?: string; /** * The data sets that can be displayed in place of the merge fields in the editor. * * @default [] */ dataSets?: Array<DataSetDefinition>; /** * Determines the available preview modes in the dropdown and menu bar. Possible values are: * * * `'$labels'` - adds the option to display the labels of the merge fields. * * `'$defaultValues'` - adds the option to display the default values. * * `'$dataSets'` - adds the options to display each of the configured data sets. * * At least one mode must be enabled. If more than one preview mode is configured, * you can add `previewMergeFields` button to the toolbar to switch between them, * and the menu bar button will be added automatically to the `View` category. * * @default [ '$labels', '$defaultValues', '$dataSets' ] */ previewModes?: Array<string>; /** * A name of the preview mode that should be active when the editor is initialized. Possible values are: * * * `'$labels'` - displays the labels of the merge fields, * * `'$defaultValues'` - displays the default values, * * one of the configured {@link module:merge-fields/mergefieldsconfig~MergeFieldsConfig#dataSets data sets} identifiers. * * If not set, it will default to the one of the {@link ~MergeFieldsConfig#previewModes available preview modes}, with the priority as * in the list above. */ initialPreviewMode?: string; /** * A flag indicating whether the feature preview mode should interpret merge fields * {@link ~DataSetDefinition#values data set values} and {@link ~MergeFieldDefinition#defaultValue default values} as HTML strings and * render them as HTML. * * When set to `true`, the merge field value will be interpreted and rendered as HTML. For example, `'<img src="image.jpg" />'` merge * field value will be previewed as the image located at given `src`. * * When set to `false`, the merge field value will be interpreted as a regular text. For example, `'<img src="image.jpg" />'` will be * displayed exactly as defined, meaning that text `<img src="image.jpg" />` will be displayed instead of an image. * * By default, it is set to `false`. * * Read more about the security of previewing merge fields HTML values in the * {@glink features/merge-fields#using-html-tags-in-merge-fields-values Merge fields feature} documentation. * * @default false */ previewHtmlValues?: boolean; /** * Callback used to sanitize the HTML used in merge fields values when they are previewed inside the editor. * * We strongly recommend overwriting the default function to avoid XSS vulnerabilities. * * Read more about the security aspect of this feature in {@glink features/merge-fields#using-html-tags-in-merge-fields-values Merge * fields feature} documentation. * * The function receives the input HTML (as a string), and should return an object * that matches the {@link module:merge-fields/mergefieldsconfig~MergeFieldsSanitizeOutput} interface. * * ```ts * ClassicEditor * .create( editorElement, { * mergeFields: { * previewHtmlValues: true, * sanitizeHtml( inputHtml ) { * // Strip unsafe elements and attributes, e.g.: * // the `<script>` elements and `on*` attributes. * const outputHtml = sanitize( inputHtml ); * * return { * html: outputHtml, * // true or false depending on whether the sanitizer stripped anything. * hasChanged: ... * }; * }, * } * } ) * .then( ... ) * .catch( ... ); * ``` * * **Note:** The function is used only when the feature * {@link module:merge-fields/mergefieldsconfig~MergeFieldsConfig#previewHtmlValues is configured to render previews}. */ sanitizeHtml?: (html: string) => MergeFieldsSanitizeOutput; } /** * An object returned by the {@link module:merge-fields/mergefieldsconfig~MergeFieldsConfig#sanitizeHtml} function. */ export interface MergeFieldsSanitizeOutput { /** * An output (safe) HTML that will be inserted into the {@glink framework/architecture/editing-engine editing view}. */ html: string; /** * A flag that indicates whether the output HTML is different than the input value. */ hasChanged: boolean; } export type GroupDefinition = { /** * The unique identifier of the group. * * If {@link ~GroupDefinition#groupLabel} is not specified, the ID will be used as a label in the UI. */ groupId: string; /** * The human-readable label of the group. * * It is displayed by the feature's UI. */ groupLabel?: string; /** * The array of merge fields definitions that belong to the group. */ definitions: Array<MergeFieldDefinition>; }; /** * The definition of a single merge field. * * Depending on the {@link ~MergeFieldDefinition#type type}, some of the properties may not be relevant: * * * For `text` merge fields, the `id`, `label`, and `defaultValue` properties are used. * * For `block` merge fields, the `id`, `label`, `height`, and `defaultValue` properties are used. * * For `image` merge fields, the `id`, `label`, `height`, `width`, and `defaultValue` properties are used. */ export interface MergeFieldDefinition { /** * The unique identifier of the merge field. * * If {@link ~MergeFieldDefinition#label label} is not specified, the ID will be used as a label. * * The list of allowed characters includes: `a-z`, `A-Z`, `0-9`, `_`, `.`, and `-`. */ id: string; /** * The human-readable label of the merge field. * * It is displayed by the feature's UI and inside the editing area. */ label?: string; /** * The type of the merge field. It determines how the merge field is rendered in the editor editing area. * * Possible options are `text` (meaning the merge field will be inline), `block` and `image`. * * @default 'text' */ type?: MergeFieldType; /** * The height of the non-text merge field in pixels. * * It is used only for merge fields of type `block` and `image`. If unset, the default height for block is 120 pixels * and for image - 400 pixels. * * @default 120 (for block)/ 400 (for image) */ height?: number; /** * The width of the image merge field in pixels. * * It is used only for merge fields of type `image`. If unset, the default width is 400 pixels. * * @default 400 */ width?: number; /** * Default value of the merge field. * * It is used if a value for given merge field has not been provided in a data set and in the default values preview mode. */ defaultValue?: MergeFieldDataSetValue; } export type DataSetDefinition = { /** * A unique identifier of the data set. It cannot start with `$`, as it is reserved for internal use. */ id: string; /** * A human-readable label of the data set. */ label?: string; /** * The data to be displayed in the editor in place of merge fields when the data set is previewed. * * The keys of this object are merge field IDs, while values are the merge field values, which can be strings or functions. * If the value is specified as a function, it should return a string. The function will be evaluated each time the data set values * are retrieved. * * ```ts * const mergeFieldsConfig = { * dataSets: [ * id: 'customDataSet', * values: { * companyName: 'CKSource', * productName: 'CKEditor 5' * } * ] * }; * ``` */ values: Record<string, MergeFieldDataSetValue>; }; export type MergeFieldDataSetValue = string | ((editor: Editor) => string); export type MergeFieldType = 'text' | 'block' | 'image';