@ckeditor/ckeditor5-typing 41.2.0 → 41.3.0-alpha.1

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.
@@ -0,0 +1,232 @@
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 typing/twostepcaretmovement
7
+ */
8
+ import { Plugin, type Editor } from '@ckeditor/ckeditor5-core';
9
+ /**
10
+ * This plugin enables the two-step caret (phantom) movement behavior for
11
+ * {@link module:typing/twostepcaretmovement~TwoStepCaretMovement#registerAttribute registered attributes}
12
+ * on arrow right (<kbd>→</kbd>) and left (<kbd>←</kbd>) key press.
13
+ *
14
+ * Thanks to this (phantom) caret movement the user is able to type before/after as well as at the
15
+ * beginning/end of an attribute.
16
+ *
17
+ * **Note:** This plugin support right–to–left (Arabic, Hebrew, etc.) content by mirroring its behavior
18
+ * but for the sake of simplicity examples showcase only left–to–right use–cases.
19
+ *
20
+ * # Forward movement
21
+ *
22
+ * ## "Entering" an attribute:
23
+ *
24
+ * When this plugin is enabled and registered for the `a` attribute and the selection is right before it
25
+ * (at the attribute boundary), pressing the right arrow key will not move the selection but update its
26
+ * attributes accordingly:
27
+ *
28
+ * * When enabled:
29
+ *
30
+ * ```xml
31
+ * foo{}<$text a="true">bar</$text>
32
+ * ```
33
+ *
34
+ * <kbd>→</kbd>
35
+ *
36
+ * ```xml
37
+ * foo<$text a="true">{}bar</$text>
38
+ * ```
39
+ *
40
+ * * When disabled:
41
+ *
42
+ * ```xml
43
+ * foo{}<$text a="true">bar</$text>
44
+ * ```
45
+ *
46
+ * <kbd>→</kbd>
47
+ *
48
+ * ```xml
49
+ * foo<$text a="true">b{}ar</$text>
50
+ * ```
51
+ *
52
+ *
53
+ * ## "Leaving" an attribute:
54
+ *
55
+ * * When enabled:
56
+ *
57
+ * ```xml
58
+ * <$text a="true">bar{}</$text>baz
59
+ * ```
60
+ *
61
+ * <kbd>→</kbd>
62
+ *
63
+ * ```xml
64
+ * <$text a="true">bar</$text>{}baz
65
+ * ```
66
+ *
67
+ * * When disabled:
68
+ *
69
+ * ```xml
70
+ * <$text a="true">bar{}</$text>baz
71
+ * ```
72
+ *
73
+ * <kbd>→</kbd>
74
+ *
75
+ * ```xml
76
+ * <$text a="true">bar</$text>b{}az
77
+ * ```
78
+ *
79
+ * # Backward movement
80
+ *
81
+ * * When enabled:
82
+ *
83
+ * ```xml
84
+ * <$text a="true">bar</$text>{}baz
85
+ * ```
86
+ *
87
+ * <kbd>←</kbd>
88
+ *
89
+ * ```xml
90
+ * <$text a="true">bar{}</$text>baz
91
+ * ```
92
+ *
93
+ * * When disabled:
94
+ *
95
+ * ```xml
96
+ * <$text a="true">bar</$text>{}baz
97
+ * ```
98
+ *
99
+ * <kbd>←</kbd>
100
+ *
101
+ * ```xml
102
+ * <$text a="true">ba{}r</$text>b{}az
103
+ * ```
104
+ *
105
+ * # Multiple attributes
106
+ *
107
+ * * When enabled and many attributes starts or ends at the same position:
108
+ *
109
+ * ```xml
110
+ * <$text a="true" b="true">bar</$text>{}baz
111
+ * ```
112
+ *
113
+ * <kbd>←</kbd>
114
+ *
115
+ * ```xml
116
+ * <$text a="true" b="true">bar{}</$text>baz
117
+ * ```
118
+ *
119
+ * * When enabled and one procedes another:
120
+ *
121
+ * ```xml
122
+ * <$text a="true">bar</$text><$text b="true">{}bar</$text>
123
+ * ```
124
+ *
125
+ * <kbd>←</kbd>
126
+ *
127
+ * ```xml
128
+ * <$text a="true">bar{}</$text><$text b="true">bar</$text>
129
+ * ```
130
+ *
131
+ */
132
+ export default class TwoStepCaretMovement extends Plugin {
133
+ /**
134
+ * A set of attributes to handle.
135
+ */
136
+ private attributes;
137
+ /**
138
+ * The current UID of the overridden gravity, as returned by
139
+ * {@link module:engine/model/writer~Writer#overrideSelectionGravity}.
140
+ */
141
+ private _overrideUid;
142
+ /**
143
+ * A flag indicating that the automatic gravity restoration should not happen upon the next
144
+ * gravity restoration.
145
+ * {@link module:engine/model/selection~Selection#event:change:range} event.
146
+ */
147
+ private _isNextGravityRestorationSkipped;
148
+ /**
149
+ * @inheritDoc
150
+ */
151
+ static get pluginName(): "TwoStepCaretMovement";
152
+ /**
153
+ * @inheritDoc
154
+ */
155
+ constructor(editor: Editor);
156
+ /**
157
+ * @inheritDoc
158
+ */
159
+ init(): void;
160
+ /**
161
+ * Registers a given attribute for the two-step caret movement.
162
+ *
163
+ * @param attribute Name of the attribute to handle.
164
+ */
165
+ registerAttribute(attribute: string): void;
166
+ /**
167
+ * Updates the document selection and the view according to the two–step caret movement state
168
+ * when moving **forwards**. Executed upon `keypress` in the {@link module:engine/view/view~View}.
169
+ *
170
+ * @param data Data of the key press.
171
+ * @returns `true` when the handler prevented caret movement.
172
+ */
173
+ private _handleForwardMovement;
174
+ /**
175
+ * Updates the document selection and the view according to the two–step caret movement state
176
+ * when moving **backwards**. Executed upon `keypress` in the {@link module:engine/view/view~View}.
177
+ *
178
+ * @param data Data of the key press.
179
+ * @returns `true` when the handler prevented caret movement
180
+ */
181
+ private _handleBackwardMovement;
182
+ /**
183
+ * Starts listening to {@link module:engine/view/document~Document#event:mousedown} and
184
+ * {@link module:engine/view/document~Document#event:selectionChange} and puts the selection before/after a 2-step node
185
+ * if clicked at the beginning/ending of the 2-step node.
186
+ *
187
+ * The purpose of this action is to allow typing around the 2-step node directly after a click.
188
+ *
189
+ * See https://github.com/ckeditor/ckeditor5/issues/1016.
190
+ */
191
+ private _enableClickingAfterNode;
192
+ /**
193
+ * Starts listening to {@link module:engine/model/model~Model#event:insertContent} and corrects the model
194
+ * selection attributes if the selection is at the end of a two-step node after inserting the content.
195
+ *
196
+ * The purpose of this action is to improve the overall UX because the user is no longer "trapped" by the
197
+ * two-step attribute of the selection, and they can type a "clean" (`linkHref`–less) text right away.
198
+ *
199
+ * See https://github.com/ckeditor/ckeditor5/issues/6053.
200
+ */
201
+ private _enableInsertContentSelectionAttributesFixer;
202
+ /**
203
+ * Starts listening to {@link module:engine/model/model~Model#deleteContent} and checks whether
204
+ * removing a content right after the tow-step attribute.
205
+ *
206
+ * If so, the selection should not preserve the two-step attribute. However, if
207
+ * the {@link module:typing/twostepcaretmovement~TwoStepCaretMovement} plugin is active and
208
+ * the selection has the two-step attribute due to overridden gravity (at the end), the two-step attribute should stay untouched.
209
+ *
210
+ * The purpose of this action is to allow removing the link text and keep the selection outside the link.
211
+ *
212
+ * See https://github.com/ckeditor/ckeditor5/issues/7521.
213
+ */
214
+ private _handleDeleteContentAfterNode;
215
+ /**
216
+ * `true` when the gravity is overridden for the plugin.
217
+ */
218
+ private get _isGravityOverridden();
219
+ /**
220
+ * Overrides the gravity using the {@link module:engine/model/writer~Writer model writer}
221
+ * and stores the information about this fact in the {@link #_overrideUid}.
222
+ *
223
+ * A shorthand for {@link module:engine/model/writer~Writer#overrideSelectionGravity}.
224
+ */
225
+ private _overrideGravity;
226
+ /**
227
+ * Restores the gravity using the {@link module:engine/model/writer~Writer model writer}.
228
+ *
229
+ * A shorthand for {@link module:engine/model/writer~Writer#restoreSelectionGravity}.
230
+ */
231
+ private _restoreGravity;
232
+ }
@@ -0,0 +1,23 @@
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 typing/typing
7
+ */
8
+ import { Plugin } from '@ckeditor/ckeditor5-core';
9
+ import Input from './input.js';
10
+ import Delete from './delete.js';
11
+ /**
12
+ * The typing feature. It handles typing.
13
+ *
14
+ * This is a "glue" plugin which loads the {@link module:typing/input~Input} and {@link module:typing/delete~Delete}
15
+ * plugins.
16
+ */
17
+ export default class Typing extends Plugin {
18
+ static get requires(): readonly [typeof Input, typeof Delete];
19
+ /**
20
+ * @inheritDoc
21
+ */
22
+ static get pluginName(): "Typing";
23
+ }
@@ -0,0 +1,204 @@
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 typing/typingconfig
7
+ */
8
+ /**
9
+ * The configuration of the typing features. Used by the typing features in `@ckeditor/ckeditor5-typing` package.
10
+ *
11
+ * ```ts
12
+ * ClassicEditor
13
+ * .create( editorElement, {
14
+ * typing: ... // Typing feature options.
15
+ * } )
16
+ * .then( ... )
17
+ * .catch( ... );
18
+ * ```
19
+ *
20
+ * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
21
+ */
22
+ export interface TypingConfig {
23
+ /**
24
+ * The granularity of undo/redo for typing and deleting. The value `20` means (more or less) that a new undo step
25
+ * is created every 20 characters are inserted or deleted.
26
+ *
27
+ * @default 20
28
+ */
29
+ undoStep?: number;
30
+ /**
31
+ * The configuration of the {@link module:typing/texttransformation~TextTransformation} feature.
32
+ *
33
+ * Read more in {@link module:typing/typingconfig~TextTransformationConfig}.
34
+ */
35
+ transformations: TextTransformationConfig;
36
+ }
37
+ /**
38
+ * The configuration of the text transformation feature.
39
+ *
40
+ * ```ts
41
+ * ClassicEditor
42
+ * .create( editorElement, {
43
+ * typing: {
44
+ * transformations: ... // Text transformation feature options.
45
+ * }
46
+ * } )
47
+ * .then( ... )
48
+ * .catch( ... );
49
+ * ```
50
+ *
51
+ * By default, the feature comes pre-configured
52
+ * (via {@link module:typing/typingconfig~TextTransformationConfig#include `config.typing.transformations.include`}) with the
53
+ * following groups of transformations:
54
+ *
55
+ * * Typography (group name: `typography`)
56
+ * - `ellipsis`: transforms `...` to `…`
57
+ * - `enDash`: transforms ` -- ` to ` – `
58
+ * - `emDash`: transforms ` --- ` to ` — `
59
+ * * Quotations (group name: `quotes`)
60
+ * - `quotesPrimary`: transforms `"Foo bar"` to `“Foo bar”`
61
+ * - `quotesSecondary`: transforms `'Foo bar'` to `‘Foo bar’`
62
+ * * Symbols (group name: `symbols`)
63
+ * - `trademark`: transforms `(tm)` to `™`
64
+ * - `registeredTrademark`: transforms `(r)` to `®`
65
+ * - `copyright`: transforms `(c)` to `©`
66
+ * * Mathematical (group name: `mathematical`)
67
+ * - `oneHalf`: transforms `1/2` to: `½`
68
+ * - `oneThird`: transforms `1/3` to: `⅓`
69
+ * - `twoThirds`: transforms `2/3` to: `⅔`
70
+ * - `oneForth`: transforms `1/4` to: `¼`
71
+ * - `threeQuarters`: transforms `3/4` to: `¾`
72
+ * - `lessThanOrEqual`: transforms `<=` to: `≤`
73
+ * - `greaterThanOrEqual`: transforms `>=` to: `≥`
74
+ * - `notEqual`: transforms `!=` to: `≠`
75
+ * - `arrowLeft`: transforms `<-` to: `←`
76
+ * - `arrowRight`: transforms `->` to: `→`
77
+ * * Misc:
78
+ * - `quotesPrimaryEnGb`: transforms `'Foo bar'` to `‘Foo bar’`
79
+ * - `quotesSecondaryEnGb`: transforms `"Foo bar"` to `“Foo bar”`
80
+ * - `quotesPrimaryPl`: transforms `"Foo bar"` to `„Foo bar”`
81
+ * - `quotesSecondaryPl`: transforms `'Foo bar'` to `‚Foo bar’`
82
+ *
83
+ * In order to load additional transformations, use the
84
+ * {@link module:typing/typingconfig~TextTransformationConfig#extra `transformations.extra` option}.
85
+ *
86
+ * In order to narrow down the list of transformations, use the
87
+ * {@link module:typing/typingconfig~TextTransformationConfig#remove `transformations.remove` option}.
88
+ *
89
+ * In order to completely override the supported transformations, use the
90
+ * {@link module:typing/typingconfig~TextTransformationConfig#include `transformations.include` option}.
91
+ *
92
+ * Examples:
93
+ *
94
+ * ```ts
95
+ * const transformationsConfig = {
96
+ * include: [
97
+ * // Use only the 'quotes' and 'typography' groups.
98
+ * 'quotes',
99
+ * 'typography',
100
+ *
101
+ * // Plus, some custom transformation.
102
+ * { from: 'CKE', to: 'CKEditor' }
103
+ * ]
104
+ * };
105
+ *
106
+ * const transformationsConfig = {
107
+ * // Remove the 'ellipsis' transformation loaded by the 'typography' group.
108
+ * remove: [ 'ellipsis' ]
109
+ * }
110
+ * ```
111
+ */
112
+ export interface TextTransformationConfig {
113
+ /**
114
+ * The standard list of text transformations supported by the editor. By default it comes pre-configured with a couple dozen of them
115
+ * (see {@link module:typing/typingconfig~TextTransformationConfig} for the full list). You can override this list completely
116
+ * by setting this option or use the other two options
117
+ * ({@link module:typing/typingconfig~TextTransformationConfig#extra `transformations.extra`},
118
+ * {@link module:typing/typingconfig~TextTransformationConfig#remove `transformations.remove`}) to fine-tune the default list.
119
+ */
120
+ include: Array<TextTransformationDescription | string>;
121
+ /**
122
+ * Additional text transformations that are added to the transformations defined in
123
+ * {@link module:typing/typingconfig~TextTransformationConfig#include `transformations.include`}.
124
+ *
125
+ * ```ts
126
+ * const transformationsConfig = {
127
+ * extra: [
128
+ * { from: 'CKE', to: 'CKEditor' }
129
+ * ]
130
+ * };
131
+ * ```
132
+ */
133
+ extra?: Array<TextTransformationDescription | string>;
134
+ /**
135
+ * The text transformation names that are removed from transformations defined in
136
+ * {@link module:typing/typingconfig~TextTransformationConfig#include `transformations.include`} or
137
+ * {@link module:typing/typingconfig~TextTransformationConfig#extra `transformations.extra`}.
138
+ *
139
+ * ```ts
140
+ * const transformationsConfig = {
141
+ * remove: [
142
+ * 'ellipsis', // Remove only 'ellipsis' from the 'typography' group.
143
+ * 'mathematical' // Remove all transformations from the 'mathematical' group.
144
+ * ]
145
+ * }
146
+ * ```
147
+ */
148
+ remove?: Array<TextTransformationDescription | string>;
149
+ }
150
+ /**
151
+ * The text transformation definition object. It describes what should be replaced with what.
152
+ *
153
+ * The input value (`from`) can be passed either as a string or as a regular expression.
154
+ *
155
+ * * If a string is passed, it will be simply checked if the end of the input matches it.
156
+ * * If a regular expression is passed, its entire length must be covered with capturing groups (e.g. `/(foo)(bar)$/`).
157
+ * Also, since it is compared against the end of the input, it has to end with `$` to be correctly matched.
158
+ * See examples below.
159
+ *
160
+ * The output value (`to`) can be passed as a string, as an array or as a function.
161
+ *
162
+ * * If a string is passed, it will be used as a replacement value as-is. Note that a string output value can be used only if
163
+ * the input value is a string, too.
164
+ * * If an array is passed, it has to have the same number of elements as there are capturing groups in the input value regular expression.
165
+ * Each capture group will be replaced with a corresponding string from the passed array. If a given capturing group should not be replaced,
166
+ * use `null` instead of passing a string.
167
+ * * If a function is used, it should return an array as described above. The function is passed one parameter &ndash; an array with matches
168
+ * by the regular expression. See the examples below.
169
+ *
170
+ * A simple string-to-string replacement:
171
+ *
172
+ * ```ts
173
+ * { from: '(c)', to: '©' }
174
+ * ```
175
+ *
176
+ * Change quote styles using a regular expression. Note how all the parts are in separate capturing groups and the space at the beginning
177
+ * and the text inside quotes are not replaced (`null` passed as the first and the third value in the `to` parameter):
178
+ *
179
+ * ```ts
180
+ * {
181
+ * from: /(^|\s)(")([^"]*)(")$/,
182
+ * to: [ null, '“', null, '”' ]
183
+ * }
184
+ * ```
185
+ *
186
+ * Automatic uppercase after a dot using a callback:
187
+ *
188
+ * ```ts
189
+ * {
190
+ * from: /(\. )([a-z])$/,
191
+ * to: matches => [ null, matches[ 1 ].toUpperCase() ]
192
+ * }
193
+ * ```
194
+ */
195
+ export interface TextTransformationDescription {
196
+ /**
197
+ * The string or regular expression to transform.
198
+ */
199
+ from: string | RegExp;
200
+ /**
201
+ * The text to transform compatible with `String.replace()`.
202
+ */
203
+ to: string | Array<string | null> | ((matches: Array<string>) => Array<string | null>);
204
+ }
@@ -0,0 +1,103 @@
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 typing/utils/changebuffer
7
+ */
8
+ import type { Model, Batch } from '@ckeditor/ckeditor5-engine';
9
+ /**
10
+ * Change buffer allows to group atomic changes (like characters that have been typed) into
11
+ * {@link module:engine/model/batch~Batch batches}.
12
+ *
13
+ * Batches represent single undo steps, hence changes added to one single batch are undone together.
14
+ *
15
+ * The buffer has a configurable limit of atomic changes that it can accommodate. After the limit was
16
+ * exceeded (see {@link ~ChangeBuffer#input}), a new batch is created in {@link ~ChangeBuffer#batch}.
17
+ *
18
+ * To use the change buffer you need to let it know about the number of changes that were added to the batch:
19
+ *
20
+ * ```ts
21
+ * const buffer = new ChangeBuffer( model, LIMIT );
22
+ *
23
+ * // Later on in your feature:
24
+ * buffer.batch.insert( pos, insertedCharacters );
25
+ * buffer.input( insertedCharacters.length );
26
+ * ```
27
+ */
28
+ export default class ChangeBuffer {
29
+ /**
30
+ * The model instance.
31
+ */
32
+ readonly model: Model;
33
+ /**
34
+ * The maximum number of atomic changes which can be contained in one batch.
35
+ */
36
+ readonly limit: number;
37
+ /**
38
+ * Whether the buffer is locked. A locked buffer cannot be reset unless it gets unlocked.
39
+ */
40
+ private _isLocked;
41
+ /**
42
+ * The number of atomic changes in the buffer. Once it exceeds the {@link #limit},
43
+ * the {@link #batch batch} is set to a new one.
44
+ */
45
+ private _size;
46
+ /**
47
+ * The current batch instance.
48
+ */
49
+ private _batch;
50
+ /**
51
+ * The callback to document the change event which later needs to be removed.
52
+ */
53
+ private readonly _changeCallback;
54
+ /**
55
+ * The callback to document selection `change:attribute` and `change:range` events which resets the buffer.
56
+ */
57
+ private readonly _selectionChangeCallback;
58
+ /**
59
+ * Creates a new instance of the change buffer.
60
+ *
61
+ * @param limit The maximum number of atomic changes which can be contained in one batch.
62
+ */
63
+ constructor(model: Model, limit?: number);
64
+ /**
65
+ * The current batch to which a feature should add its operations. Once the {@link #size}
66
+ * is reached or exceeds the {@link #limit}, the batch is set to a new instance and the size is reset.
67
+ */
68
+ get batch(): Batch;
69
+ /**
70
+ * The number of atomic changes in the buffer. Once it exceeds the {@link #limit},
71
+ * the {@link #batch batch} is set to a new one.
72
+ */
73
+ get size(): number;
74
+ /**
75
+ * The input number of changes into the buffer. Once the {@link #size} is
76
+ * reached or exceeds the {@link #limit}, the batch is set to a new instance and the size is reset.
77
+ *
78
+ * @param changeCount The number of atomic changes to input.
79
+ */
80
+ input(changeCount: number): void;
81
+ /**
82
+ * Whether the buffer is locked. A locked buffer cannot be reset unless it gets unlocked.
83
+ */
84
+ get isLocked(): boolean;
85
+ /**
86
+ * Locks the buffer.
87
+ */
88
+ lock(): void;
89
+ /**
90
+ * Unlocks the buffer.
91
+ */
92
+ unlock(): void;
93
+ /**
94
+ * Destroys the buffer.
95
+ */
96
+ destroy(): void;
97
+ /**
98
+ * Resets the change buffer.
99
+ *
100
+ * @param ignoreLock Whether internal lock {@link #isLocked} should be ignored.
101
+ */
102
+ private _reset;
103
+ }
@@ -0,0 +1,33 @@
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 typing/utils/findattributerange
7
+ */
8
+ import type { Position, Model, Range } from '@ckeditor/ckeditor5-engine';
9
+ /**
10
+ * Returns a model range that covers all consecutive nodes with the same `attributeName` and its `value`
11
+ * that intersect the given `position`.
12
+ *
13
+ * It can be used e.g. to get the entire range on which the `linkHref` attribute needs to be changed when having a
14
+ * selection inside a link.
15
+ *
16
+ * @param position The start position.
17
+ * @param attributeName The attribute name.
18
+ * @param value The attribute value.
19
+ * @param model The model instance.
20
+ * @returns The link range.
21
+ */
22
+ export default function findAttributeRange(position: Position, attributeName: string, value: unknown, model: Model): Range;
23
+ /**
24
+ * Walks forward or backward (depends on the `lookBack` flag), node by node, as long as they have the same attribute value
25
+ * and returns a position just before or after (depends on the `lookBack` flag) the last matched node.
26
+ *
27
+ * @param position The start position.
28
+ * @param attributeName The attribute name.
29
+ * @param value The attribute value.
30
+ * @param lookBack Whether the walk direction is forward (`false`) or backward (`true`).
31
+ * @returns The position just before the last matched node.
32
+ */
33
+ export declare function findAttributeRangeBound(position: Position, attributeName: string, value: unknown, lookBack: boolean, model: Model): Position;
@@ -0,0 +1,49 @@
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 typing/utils/getlasttextline
7
+ */
8
+ import type { Model, Range } from '@ckeditor/ckeditor5-engine';
9
+ /**
10
+ * Returns the last text line from the given range.
11
+ *
12
+ * "The last text line" is understood as text (from one or more text nodes) which is limited either by a parent block
13
+ * or by inline elements (e.g. `<softBreak>`).
14
+ *
15
+ * ```ts
16
+ * const rangeToCheck = model.createRange(
17
+ * model.createPositionAt( paragraph, 0 ),
18
+ * model.createPositionAt( paragraph, 'end' )
19
+ * );
20
+ *
21
+ * const { text, range } = getLastTextLine( rangeToCheck, model );
22
+ * ```
23
+ *
24
+ * For model below, the returned `text` will be "Foo bar baz" and `range` will be set on whole `<paragraph>` content:
25
+ *
26
+ * ```xml
27
+ * <paragraph>Foo bar baz<paragraph>
28
+ * ```
29
+ *
30
+ * However, in below case, `text` will be set to "baz" and `range` will be set only on "baz".
31
+ *
32
+ * ```xml
33
+ * <paragraph>Foo<softBreak></softBreak>bar<softBreak></softBreak>baz<paragraph>
34
+ * ```
35
+ */
36
+ export default function getLastTextLine(range: Range, model: Model): LastTextLineData;
37
+ /**
38
+ * The value returned by {@link module:typing/utils/getlasttextline~getLastTextLine}.
39
+ */
40
+ export type LastTextLineData = {
41
+ /**
42
+ * The text from the text nodes in the last text line.
43
+ */
44
+ text: string;
45
+ /**
46
+ * The range set on the text nodes in the last text line.
47
+ */
48
+ range: Range;
49
+ };
@@ -0,0 +1,33 @@
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
+ import type { Editor } from '@ckeditor/ckeditor5-core';
6
+ /**
7
+ * Adds a visual highlight style to an attribute element in which the selection is anchored.
8
+ * Together with two-step caret movement, they indicate that the user is typing inside the element.
9
+ *
10
+ * Highlight is turned on by adding the given class to the attribute element in the view:
11
+ *
12
+ * * The class is removed before the conversion has started, as callbacks added with the `'highest'` priority
13
+ * to {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} events.
14
+ * * The class is added in the view post fixer, after other changes in the model tree were converted to the view.
15
+ *
16
+ * This way, adding and removing the highlight does not interfere with conversion.
17
+ *
18
+ * Usage:
19
+ *
20
+ * ```ts
21
+ * import inlineHighlight from '@ckeditor/ckeditor5-typing/src/utils/inlinehighlight';
22
+ *
23
+ * // Make `ck-link_selected` class be applied on an `a` element
24
+ * // whenever the corresponding `linkHref` attribute element is selected.
25
+ * inlineHighlight( editor, 'linkHref', 'a', 'ck-link_selected' );
26
+ * ```
27
+ *
28
+ * @param editor The editor instance.
29
+ * @param attributeName The attribute name to check.
30
+ * @param tagName The tagName of a view item.
31
+ * @param className The class name to apply in the view.
32
+ */
33
+ export default function inlineHighlight(editor: Editor, attributeName: string, tagName: string, className: string): void;