@ckeditor/ckeditor5-typing 40.1.0 → 40.2.0
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/CHANGELOG.md +27 -27
- package/package.json +4 -4
- package/src/inserttextcommand.js +4 -1
- package/src/twostepcaretmovement.d.ts +33 -0
- package/src/twostepcaretmovement.js +191 -4
- package/src/typingconfig.d.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,12 +5,12 @@ All changes in the package are documented in the main repository. See: https://g
|
|
|
5
5
|
|
|
6
6
|
Changes for the past releases are available below.
|
|
7
7
|
|
|
8
|
-
## [19.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v18.0.0...v19.0.0) (2020
|
|
8
|
+
## [19.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v18.0.0...v19.0.0) (April 29, 2020)
|
|
9
9
|
|
|
10
10
|
Internal changes only (updated dependencies, documentation, etc.).
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
## [18.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v17.0.0...v18.0.0) (2020
|
|
13
|
+
## [18.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v17.0.0...v18.0.0) (March 19, 2020)
|
|
14
14
|
|
|
15
15
|
### Other changes
|
|
16
16
|
|
|
@@ -19,26 +19,26 @@ Internal changes only (updated dependencies, documentation, etc.).
|
|
|
19
19
|
* Run only one instance of the `TextWatcher` for all text transformations. Closes [ckeditor/ckeditor5#6020](https://github.com/ckeditor/ckeditor5/issues/6020). ([550426d](https://github.com/ckeditor/ckeditor5-typing/commit/550426d))
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
## [17.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v16.0.0...v17.0.0) (2020
|
|
22
|
+
## [17.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v16.0.0...v17.0.0) (February 19, 2020)
|
|
23
23
|
|
|
24
24
|
### Features
|
|
25
25
|
|
|
26
26
|
* Add `TextWatcher#isEnabled` property to allow toggling text watcher on and off. ([fa79d00](https://github.com/ckeditor/ckeditor5-typing/commit/fa79d00))
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
## [16.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v15.0.0...v16.0.0) (2019
|
|
29
|
+
## [16.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v15.0.0...v16.0.0) (December 4, 2019)
|
|
30
30
|
|
|
31
31
|
Internal changes only (updated dependencies, documentation, etc.).
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
## [15.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v12.2.0...v15.0.0) (2019
|
|
34
|
+
## [15.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v12.2.0...v15.0.0) (October 23, 2019)
|
|
35
35
|
|
|
36
36
|
### Bug fixes
|
|
37
37
|
|
|
38
38
|
* Autoformat transformations in blocks containing inline elements. See [ckeditor/ckeditor5#1955](https://github.com/ckeditor/ckeditor5/issues/1955). ([58abd23](https://github.com/ckeditor/ckeditor5-typing/commit/58abd23))
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
## [12.2.0](https://github.com/ckeditor/ckeditor5-typing/compare/v12.1.1...v12.2.0) (2019
|
|
41
|
+
## [12.2.0](https://github.com/ckeditor/ckeditor5-typing/compare/v12.1.1...v12.2.0) (August 26, 2019)
|
|
42
42
|
|
|
43
43
|
### Features
|
|
44
44
|
|
|
@@ -54,14 +54,14 @@ Internal changes only (updated dependencies, documentation, etc.).
|
|
|
54
54
|
* The issue tracker for this package was moved to https://github.com/ckeditor/ckeditor5/issues. See [ckeditor/ckeditor5#1988](https://github.com/ckeditor/ckeditor5/issues/1988). ([6491e8d](https://github.com/ckeditor/ckeditor5-typing/commit/6491e8d))
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
## [12.1.1](https://github.com/ckeditor/ckeditor5-typing/compare/v12.1.0...v12.1.1) (2019
|
|
57
|
+
## [12.1.1](https://github.com/ckeditor/ckeditor5-typing/compare/v12.1.0...v12.1.1) (July 10, 2019)
|
|
58
58
|
|
|
59
59
|
### Bug fixes
|
|
60
60
|
|
|
61
61
|
* Text transformations will not remove existing formatting. Closes [#203](https://github.com/ckeditor/ckeditor5-typing/issues/203). Closes [#196](https://github.com/ckeditor/ckeditor5-typing/issues/196). ([2279eee](https://github.com/ckeditor/ckeditor5-typing/commit/2279eee))
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
## [12.1.0](https://github.com/ckeditor/ckeditor5-typing/compare/v12.0.2...v12.1.0) (2019
|
|
64
|
+
## [12.1.0](https://github.com/ckeditor/ckeditor5-typing/compare/v12.0.2...v12.1.0) (July 4, 2019)
|
|
65
65
|
|
|
66
66
|
### Features
|
|
67
67
|
|
|
@@ -72,21 +72,21 @@ Internal changes only (updated dependencies, documentation, etc.).
|
|
|
72
72
|
* Improved typing on Android devices by handling `beforeinput` event instead of mutations. Introduced `options.selection` in the `DeleteCommand#execute()` params. Introduced `selectionToRemove` parameter in the `view.Document#event:delete` data. Closes [#167](https://github.com/ckeditor/ckeditor5-typing/issues/167). ([92ab3ff](https://github.com/ckeditor/ckeditor5-typing/commit/92ab3ff))
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
## [12.0.2](https://github.com/ckeditor/ckeditor5-typing/compare/v12.0.1...v12.0.2) (2019
|
|
75
|
+
## [12.0.2](https://github.com/ckeditor/ckeditor5-typing/compare/v12.0.1...v12.0.2) (June 6, 2019)
|
|
76
76
|
|
|
77
77
|
### Other changes
|
|
78
78
|
|
|
79
79
|
* Use `Model#insertContent()` instead of `model.Writer#insertText()`. Closes [#191](https://github.com/ckeditor/ckeditor5-typing/issues/191). ([0aeb384](https://github.com/ckeditor/ckeditor5-typing/commit/0aeb384))
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
## [12.0.1](https://github.com/ckeditor/ckeditor5-typing/compare/v12.0.0...v12.0.1) (2019
|
|
82
|
+
## [12.0.1](https://github.com/ckeditor/ckeditor5-typing/compare/v12.0.0...v12.0.1) (April 4, 2019)
|
|
83
83
|
|
|
84
84
|
### Bug fixes
|
|
85
85
|
|
|
86
86
|
* The `delete` event will now stop the `keydown` event if it was set with the highest priority. Closes [#186](https://github.com/ckeditor/ckeditor5-typing/issues/186). ([07cca83](https://github.com/ckeditor/ckeditor5-typing/commit/07cca83))
|
|
87
87
|
|
|
88
88
|
|
|
89
|
-
## [12.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v11.0.2...v12.0.0) (2019
|
|
89
|
+
## [12.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v11.0.2...v12.0.0) (February 28, 2019)
|
|
90
90
|
|
|
91
91
|
### Bug fixes
|
|
92
92
|
|
|
@@ -101,21 +101,21 @@ Internal changes only (updated dependencies, documentation, etc.).
|
|
|
101
101
|
* Upgraded minimal versions of Node to `8.0.0` and npm to `5.7.1`. See: [ckeditor/ckeditor5#1507](https://github.com/ckeditor/ckeditor5/issues/1507). ([612ea3c](https://github.com/ckeditor/ckeditor5-cloud-services/commit/612ea3c))
|
|
102
102
|
|
|
103
103
|
|
|
104
|
-
## [11.0.2](https://github.com/ckeditor/ckeditor5-typing/compare/v11.0.1...v11.0.2) (2018
|
|
104
|
+
## [11.0.2](https://github.com/ckeditor/ckeditor5-typing/compare/v11.0.1...v11.0.2) (December 5, 2018)
|
|
105
105
|
|
|
106
106
|
### Bug fixes
|
|
107
107
|
|
|
108
108
|
* Non-printable keys like volume up or the win key will not remove the content anymore. Closes [#136](https://github.com/ckeditor/ckeditor5-typing/issues/136). ([0ea9fbd](https://github.com/ckeditor/ckeditor5-typing/commit/0ea9fbd))
|
|
109
109
|
|
|
110
110
|
|
|
111
|
-
## [11.0.1](https://github.com/ckeditor/ckeditor5-typing/compare/v11.0.0...v11.0.1) (2018
|
|
111
|
+
## [11.0.1](https://github.com/ckeditor/ckeditor5-typing/compare/v11.0.0...v11.0.1) (October 8, 2018)
|
|
112
112
|
|
|
113
113
|
### Bug fixes
|
|
114
114
|
|
|
115
115
|
* ` ` is now correctly handled in mutations. Closes [#170](https://github.com/ckeditor/ckeditor5-typing/issues/170). ([9badb20](https://github.com/ckeditor/ckeditor5-typing/commit/9badb20))
|
|
116
116
|
|
|
117
117
|
|
|
118
|
-
## [11.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v10.0.1...v11.0.0) (2018
|
|
118
|
+
## [11.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v10.0.1...v11.0.0) (July 18, 2018)
|
|
119
119
|
|
|
120
120
|
### Bug fixes
|
|
121
121
|
|
|
@@ -127,14 +127,14 @@ Internal changes only (updated dependencies, documentation, etc.).
|
|
|
127
127
|
* `@ckeditor/ckeditor5-typing/src/changebuffer.js` was moved to `@ckeditor/ckeditor5-typing/src/utils/changebuffer.js`.
|
|
128
128
|
|
|
129
129
|
|
|
130
|
-
## [10.0.1](https://github.com/ckeditor/ckeditor5-typing/compare/v10.0.0...v10.0.1) (2018
|
|
130
|
+
## [10.0.1](https://github.com/ckeditor/ckeditor5-typing/compare/v10.0.0...v10.0.1) (June 21, 2018)
|
|
131
131
|
|
|
132
132
|
### Bug fixes
|
|
133
133
|
|
|
134
134
|
* Bogus `<br />` element inserted by a browser at the end of an element is now correctly handled. Closes [ckeditor/ckeditor5#1083](https://github.com/ckeditor/ckeditor5/issues/1083). ([22abdff](https://github.com/ckeditor/ckeditor5-typing/commit/22abdff))
|
|
135
135
|
|
|
136
136
|
|
|
137
|
-
## [10.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v1.0.0-beta.4...v10.0.0) (2018
|
|
137
|
+
## [10.0.0](https://github.com/ckeditor/ckeditor5-typing/compare/v1.0.0-beta.4...v10.0.0) (April 25, 2018)
|
|
138
138
|
|
|
139
139
|
### Other changes
|
|
140
140
|
|
|
@@ -145,17 +145,17 @@ Internal changes only (updated dependencies, documentation, etc.).
|
|
|
145
145
|
* The license under which CKEditor 5 is released has been changed from a triple GPL, LGPL and MPL license to a GPL2+ only. See [ckeditor/ckeditor5#991](https://github.com/ckeditor/ckeditor5/issues/991) for more information.
|
|
146
146
|
|
|
147
147
|
|
|
148
|
-
## [1.0.0-beta.4](https://github.com/ckeditor/ckeditor5-typing/compare/v1.0.0-beta.2...v1.0.0-beta.4) (2018
|
|
148
|
+
## [1.0.0-beta.4](https://github.com/ckeditor/ckeditor5-typing/compare/v1.0.0-beta.2...v1.0.0-beta.4) (April 19, 2018)
|
|
149
149
|
|
|
150
150
|
Internal changes only (updated dependencies, documentation, etc.).
|
|
151
151
|
|
|
152
152
|
|
|
153
|
-
## [1.0.0-beta.2](https://github.com/ckeditor/ckeditor5-typing/compare/v1.0.0-beta.1...v1.0.0-beta.2) (2018
|
|
153
|
+
## [1.0.0-beta.2](https://github.com/ckeditor/ckeditor5-typing/compare/v1.0.0-beta.1...v1.0.0-beta.2) (April 10, 2018)
|
|
154
154
|
|
|
155
155
|
Internal changes only (updated dependencies, documentation, etc.).
|
|
156
156
|
|
|
157
157
|
|
|
158
|
-
## [1.0.0-beta.1](https://github.com/ckeditor/ckeditor5-typing/compare/v1.0.0-alpha.2...v1.0.0-beta.1) (2018
|
|
158
|
+
## [1.0.0-beta.1](https://github.com/ckeditor/ckeditor5-typing/compare/v1.0.0-alpha.2...v1.0.0-beta.1) (March 15, 2018)
|
|
159
159
|
|
|
160
160
|
### Bug fixes
|
|
161
161
|
|
|
@@ -168,11 +168,11 @@ Internal changes only (updated dependencies, documentation, etc.).
|
|
|
168
168
|
* Aligned feature class naming to the new scheme. ([9c2cb9d](https://github.com/ckeditor/ckeditor5-typing/commit/9c2cb9d))
|
|
169
169
|
|
|
170
170
|
|
|
171
|
-
## [1.0.0-alpha.2](https://github.com/ckeditor/ckeditor5-typing/compare/v1.0.0-alpha.1...v1.0.0-alpha.2) (2017
|
|
171
|
+
## [1.0.0-alpha.2](https://github.com/ckeditor/ckeditor5-typing/compare/v1.0.0-alpha.1...v1.0.0-alpha.2) (November 14, 2017)
|
|
172
172
|
|
|
173
173
|
Internal changes only (updated dependencies, documentation, etc.).
|
|
174
174
|
|
|
175
|
-
## [1.0.0-alpha.1](https://github.com/ckeditor/ckeditor5-typing/compare/v0.10.0...v1.0.0-alpha.1) (2017
|
|
175
|
+
## [1.0.0-alpha.1](https://github.com/ckeditor/ckeditor5-typing/compare/v0.10.0...v1.0.0-alpha.1) (October 3, 2017)
|
|
176
176
|
|
|
177
177
|
### Bug fixes
|
|
178
178
|
|
|
@@ -180,7 +180,7 @@ Internal changes only (updated dependencies, documentation, etc.).
|
|
|
180
180
|
* Fixed an error where using spellchecker on a word with a style applied sometimes resulted in that word being removed. Closes [#117](https://github.com/ckeditor/ckeditor5-typing/issues/117). ([1e8d02b](https://github.com/ckeditor/ckeditor5-typing/commit/1e8d02b))
|
|
181
181
|
|
|
182
182
|
|
|
183
|
-
## [0.10.0](https://github.com/ckeditor/ckeditor5-typing/compare/v0.9.1...v0.10.0) (2017
|
|
183
|
+
## [0.10.0](https://github.com/ckeditor/ckeditor5-typing/compare/v0.9.1...v0.10.0) (September 3, 2017)
|
|
184
184
|
|
|
185
185
|
### Bug fixes
|
|
186
186
|
|
|
@@ -201,17 +201,17 @@ Internal changes only (updated dependencies, documentation, etc.).
|
|
|
201
201
|
* The command API has been changed.
|
|
202
202
|
|
|
203
203
|
|
|
204
|
-
## [0.9.1](https://github.com/ckeditor/ckeditor5-typing/compare/v0.9.0...v0.9.1) (2017
|
|
204
|
+
## [0.9.1](https://github.com/ckeditor/ckeditor5-typing/compare/v0.9.0...v0.9.1) (May 7, 2017)
|
|
205
205
|
|
|
206
206
|
Internal changes only (updated dependencies, documentation, etc.).
|
|
207
207
|
|
|
208
|
-
## [0.9.0](https://github.com/ckeditor/ckeditor5-typing/compare/v0.8.0...v0.9.0) (2017
|
|
208
|
+
## [0.9.0](https://github.com/ckeditor/ckeditor5-typing/compare/v0.8.0...v0.9.0) (April 5, 2017)
|
|
209
209
|
|
|
210
210
|
### Bug fixes
|
|
211
211
|
|
|
212
|
-
* [Safari] Fixed an issue when inserting a Spanish accent character on a non-collapsed selection
|
|
212
|
+
* [Safari] Fixed an issue when inserting a Spanish accent character on a non-collapsed selection would not work. Closes [#82](https://github.com/ckeditor/ckeditor5-typing/issues/82). ([49cfe9c](https://github.com/ckeditor/ckeditor5-typing/commit/49cfe9c))
|
|
213
213
|
* `InputCommand` now accepts `Range` instead of `Position` as a parameter. Closes [#86](https://github.com/ckeditor/ckeditor5-typing/issues/86). Closes [#54](https://github.com/ckeditor/ckeditor5-typing/issues/54). ([0766407](https://github.com/ckeditor/ckeditor5-typing/commit/0766407))
|
|
214
|
-
*
|
|
214
|
+
* A new undo step should be created on selection change or applying an attribute. Closes [#20](https://github.com/ckeditor/ckeditor5-typing/issues/20). Closes [#21](https://github.com/ckeditor/ckeditor5-typing/issues/21). ([011452b](https://github.com/ckeditor/ckeditor5-typing/commit/011452b))
|
|
215
215
|
* Use `typing.undoStep` in both `InputCommand` and `DeleteCommand`. Closes [#79](https://github.com/ckeditor/ckeditor5-typing/issues/79). ([c597467](https://github.com/ckeditor/ckeditor5-typing/commit/c597467))
|
|
216
216
|
|
|
217
217
|
### Features
|
|
@@ -224,7 +224,7 @@ Internal changes only (updated dependencies, documentation, etc.).
|
|
|
224
224
|
* The `undo.step` configuration option was replaced by `typing.undoStep` in `DeleteCommand`. See [#79](https://github.com/ckeditor/ckeditor5-typing/issues/79).
|
|
225
225
|
|
|
226
226
|
|
|
227
|
-
## [0.8.0](https://github.com/ckeditor/ckeditor5-typing/compare/v0.7.0...v0.8.0) (2017
|
|
227
|
+
## [0.8.0](https://github.com/ckeditor/ckeditor5-typing/compare/v0.7.0...v0.8.0) (March 6, 2017)
|
|
228
228
|
|
|
229
229
|
### Bug fixes
|
|
230
230
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-typing",
|
|
3
|
-
"version": "40.
|
|
3
|
+
"version": "40.2.0",
|
|
4
4
|
"description": "Typing feature for CKEditor 5.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ckeditor",
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
],
|
|
13
13
|
"main": "src/index.js",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@ckeditor/ckeditor5-core": "40.
|
|
16
|
-
"@ckeditor/ckeditor5-engine": "40.
|
|
17
|
-
"@ckeditor/ckeditor5-utils": "40.
|
|
15
|
+
"@ckeditor/ckeditor5-core": "40.2.0",
|
|
16
|
+
"@ckeditor/ckeditor5-engine": "40.2.0",
|
|
17
|
+
"@ckeditor/ckeditor5-utils": "40.2.0",
|
|
18
18
|
"lodash-es": "4.17.21"
|
|
19
19
|
},
|
|
20
20
|
"author": "CKSource (http://cksource.com/)",
|
package/src/inserttextcommand.js
CHANGED
|
@@ -63,9 +63,12 @@ export default class InsertTextCommand extends Command {
|
|
|
63
63
|
const resultRange = options.resultRange;
|
|
64
64
|
model.enqueueChange(this._buffer.batch, writer => {
|
|
65
65
|
this._buffer.lock();
|
|
66
|
+
// Store selection attributes before deleting old content to preserve formatting and link.
|
|
67
|
+
// This unifies the behavior between DocumentSelection and Selection provided as input option.
|
|
68
|
+
const selectionAttributes = Array.from(doc.selection.getAttributes());
|
|
66
69
|
model.deleteContent(selection);
|
|
67
70
|
if (text) {
|
|
68
|
-
model.insertContent(writer.createText(text,
|
|
71
|
+
model.insertContent(writer.createText(text, selectionAttributes), selection);
|
|
69
72
|
}
|
|
70
73
|
if (resultRange) {
|
|
71
74
|
writer.setSelection(resultRange);
|
|
@@ -179,6 +179,39 @@ export default class TwoStepCaretMovement extends Plugin {
|
|
|
179
179
|
* @returns `true` when the handler prevented caret movement
|
|
180
180
|
*/
|
|
181
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;
|
|
182
215
|
/**
|
|
183
216
|
* `true` when the gravity is overridden for the plugin.
|
|
184
217
|
*/
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
9
9
|
import { keyCodes } from '@ckeditor/ckeditor5-utils';
|
|
10
|
+
import { MouseObserver } from '@ckeditor/ckeditor5-engine';
|
|
10
11
|
/**
|
|
11
12
|
* This plugin enables the two-step caret (phantom) movement behavior for
|
|
12
13
|
* {@link module:typing/twostepcaretmovement~TwoStepCaretMovement#registerAttribute registered attributes}
|
|
@@ -142,6 +143,12 @@ export default class TwoStepCaretMovement extends Plugin {
|
|
|
142
143
|
*/
|
|
143
144
|
constructor(editor) {
|
|
144
145
|
super(editor);
|
|
146
|
+
/**
|
|
147
|
+
* A flag indicating that the automatic gravity restoration should not happen upon the next
|
|
148
|
+
* gravity restoration.
|
|
149
|
+
* {@link module:engine/model/selection~Selection#event:change:range} event.
|
|
150
|
+
*/
|
|
151
|
+
this._isNextGravityRestorationSkipped = false;
|
|
145
152
|
this.attributes = new Set();
|
|
146
153
|
this._overrideUid = null;
|
|
147
154
|
}
|
|
@@ -185,7 +192,6 @@ export default class TwoStepCaretMovement extends Plugin {
|
|
|
185
192
|
evt.stop();
|
|
186
193
|
}
|
|
187
194
|
}, { context: '$text', priority: 'highest' });
|
|
188
|
-
this._isNextGravityRestorationSkipped = false;
|
|
189
195
|
// The automatic gravity restoration logic.
|
|
190
196
|
this.listenTo(modelSelection, 'change:range', (evt, data) => {
|
|
191
197
|
// Skipping the automatic restoration is needed if the selection should change
|
|
@@ -208,6 +214,12 @@ export default class TwoStepCaretMovement extends Plugin {
|
|
|
208
214
|
}
|
|
209
215
|
this._restoreGravity();
|
|
210
216
|
});
|
|
217
|
+
// Handle a click at the beginning/end of a two-step element.
|
|
218
|
+
this._enableClickingAfterNode();
|
|
219
|
+
// Change the attributes of the selection in certain situations after the two-step node was inserted into the document.
|
|
220
|
+
this._enableInsertContentSelectionAttributesFixer();
|
|
221
|
+
// Handle removing the content after the two-step node.
|
|
222
|
+
this._handleDeleteContentAfterNode();
|
|
211
223
|
}
|
|
212
224
|
/**
|
|
213
225
|
* Registers a given attribute for the two-step caret movement.
|
|
@@ -260,7 +272,18 @@ export default class TwoStepCaretMovement extends Plugin {
|
|
|
260
272
|
//
|
|
261
273
|
if (isBetweenDifferentAttributes(position, attributes)) {
|
|
262
274
|
preventCaretMovement(data);
|
|
263
|
-
|
|
275
|
+
// CLEAR 2-SCM attributes if we are at the end of one 2-SCM and before
|
|
276
|
+
// the next one with a different value of the same attribute.
|
|
277
|
+
//
|
|
278
|
+
// <paragraph>foo<$text attribute=1>bar{}</$text><$text attribute=2>bar</$text>baz</paragraph>
|
|
279
|
+
//
|
|
280
|
+
if (hasAnyAttribute(selection, attributes) &&
|
|
281
|
+
isBetweenDifferentAttributes(position, attributes, true)) {
|
|
282
|
+
clearSelectionAttributes(model, attributes);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
this._overrideGravity();
|
|
286
|
+
}
|
|
264
287
|
return true;
|
|
265
288
|
}
|
|
266
289
|
return false;
|
|
@@ -288,7 +311,17 @@ export default class TwoStepCaretMovement extends Plugin {
|
|
|
288
311
|
if (this._isGravityOverridden) {
|
|
289
312
|
preventCaretMovement(data);
|
|
290
313
|
this._restoreGravity();
|
|
291
|
-
|
|
314
|
+
// CLEAR 2-SCM attributes if we are at the end of one 2-SCM and before
|
|
315
|
+
// the next one with a different value of the same attribute.
|
|
316
|
+
//
|
|
317
|
+
// <paragraph>foo<$text attribute=1>bar</$text><$text attribute=2>{}bar</$text>baz</paragraph>
|
|
318
|
+
//
|
|
319
|
+
if (isBetweenDifferentAttributes(position, attributes, true)) {
|
|
320
|
+
clearSelectionAttributes(model, attributes);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
setSelectionAttributesFromTheNodeBefore(model, attributes, position);
|
|
324
|
+
}
|
|
292
325
|
return true;
|
|
293
326
|
}
|
|
294
327
|
else {
|
|
@@ -305,6 +338,16 @@ export default class TwoStepCaretMovement extends Plugin {
|
|
|
305
338
|
}
|
|
306
339
|
return false;
|
|
307
340
|
}
|
|
341
|
+
// SET 2-SCM attributes if we are between nodes with the same attribute but with different values.
|
|
342
|
+
//
|
|
343
|
+
// <paragraph>foo<$text attribute=1>bar</$text>[]<$text attribute=2>bar</$text>baz</paragraph>
|
|
344
|
+
//
|
|
345
|
+
if (!hasAnyAttribute(selection, attributes) &&
|
|
346
|
+
isBetweenDifferentAttributes(position, attributes, true)) {
|
|
347
|
+
preventCaretMovement(data);
|
|
348
|
+
setSelectionAttributesFromTheNodeBefore(model, attributes, position);
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
308
351
|
// When we are moving from natural gravity, to the position of the 2SCM, we need to override the gravity,
|
|
309
352
|
// and make sure it won't be restored. Unless it's at the end of the block and an observed attribute.
|
|
310
353
|
// We need to check if the caret is a one position before the attribute boundary:
|
|
@@ -340,6 +383,139 @@ export default class TwoStepCaretMovement extends Plugin {
|
|
|
340
383
|
}
|
|
341
384
|
return false;
|
|
342
385
|
}
|
|
386
|
+
/**
|
|
387
|
+
* Starts listening to {@link module:engine/view/document~Document#event:mousedown} and
|
|
388
|
+
* {@link module:engine/view/document~Document#event:selectionChange} and puts the selection before/after a 2-step node
|
|
389
|
+
* if clicked at the beginning/ending of the 2-step node.
|
|
390
|
+
*
|
|
391
|
+
* The purpose of this action is to allow typing around the 2-step node directly after a click.
|
|
392
|
+
*
|
|
393
|
+
* See https://github.com/ckeditor/ckeditor5/issues/1016.
|
|
394
|
+
*/
|
|
395
|
+
_enableClickingAfterNode() {
|
|
396
|
+
const editor = this.editor;
|
|
397
|
+
const model = editor.model;
|
|
398
|
+
const selection = model.document.selection;
|
|
399
|
+
const document = editor.editing.view.document;
|
|
400
|
+
editor.editing.view.addObserver(MouseObserver);
|
|
401
|
+
let clicked = false;
|
|
402
|
+
// Detect the click.
|
|
403
|
+
this.listenTo(document, 'mousedown', () => {
|
|
404
|
+
clicked = true;
|
|
405
|
+
});
|
|
406
|
+
// When the selection has changed...
|
|
407
|
+
this.listenTo(document, 'selectionChange', () => {
|
|
408
|
+
const attributes = this.attributes;
|
|
409
|
+
if (!clicked) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
// ...and it was caused by the click...
|
|
413
|
+
clicked = false;
|
|
414
|
+
// ...and no text is selected...
|
|
415
|
+
if (!selection.isCollapsed) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
// ...and clicked text is the 2-step node...
|
|
419
|
+
if (!hasAnyAttribute(selection, attributes)) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const position = selection.getFirstPosition();
|
|
423
|
+
if (!isBetweenDifferentAttributes(position, attributes)) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
// The selection at the start of a block would use surrounding attributes
|
|
427
|
+
// from text after the selection so just clear 2-SCM attributes.
|
|
428
|
+
//
|
|
429
|
+
// Also, clear attributes for selection between same attribute with different values.
|
|
430
|
+
if (position.isAtStart ||
|
|
431
|
+
isBetweenDifferentAttributes(position, attributes, true)) {
|
|
432
|
+
clearSelectionAttributes(model, attributes);
|
|
433
|
+
}
|
|
434
|
+
else if (!this._isGravityOverridden) {
|
|
435
|
+
this._overrideGravity();
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Starts listening to {@link module:engine/model/model~Model#event:insertContent} and corrects the model
|
|
441
|
+
* selection attributes if the selection is at the end of a two-step node after inserting the content.
|
|
442
|
+
*
|
|
443
|
+
* The purpose of this action is to improve the overall UX because the user is no longer "trapped" by the
|
|
444
|
+
* two-step attribute of the selection, and they can type a "clean" (`linkHref`–less) text right away.
|
|
445
|
+
*
|
|
446
|
+
* See https://github.com/ckeditor/ckeditor5/issues/6053.
|
|
447
|
+
*/
|
|
448
|
+
_enableInsertContentSelectionAttributesFixer() {
|
|
449
|
+
const editor = this.editor;
|
|
450
|
+
const model = editor.model;
|
|
451
|
+
const selection = model.document.selection;
|
|
452
|
+
const attributes = this.attributes;
|
|
453
|
+
this.listenTo(model, 'insertContent', () => {
|
|
454
|
+
const position = selection.getFirstPosition();
|
|
455
|
+
if (hasAnyAttribute(selection, attributes) &&
|
|
456
|
+
isBetweenDifferentAttributes(position, attributes)) {
|
|
457
|
+
clearSelectionAttributes(model, attributes);
|
|
458
|
+
}
|
|
459
|
+
}, { priority: 'low' });
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Starts listening to {@link module:engine/model/model~Model#deleteContent} and checks whether
|
|
463
|
+
* removing a content right after the tow-step attribute.
|
|
464
|
+
*
|
|
465
|
+
* If so, the selection should not preserve the two-step attribute. However, if
|
|
466
|
+
* the {@link module:typing/twostepcaretmovement~TwoStepCaretMovement} plugin is active and
|
|
467
|
+
* the selection has the two-step attribute due to overridden gravity (at the end), the two-step attribute should stay untouched.
|
|
468
|
+
*
|
|
469
|
+
* The purpose of this action is to allow removing the link text and keep the selection outside the link.
|
|
470
|
+
*
|
|
471
|
+
* See https://github.com/ckeditor/ckeditor5/issues/7521.
|
|
472
|
+
*/
|
|
473
|
+
_handleDeleteContentAfterNode() {
|
|
474
|
+
const editor = this.editor;
|
|
475
|
+
const model = editor.model;
|
|
476
|
+
const selection = model.document.selection;
|
|
477
|
+
const view = editor.editing.view;
|
|
478
|
+
let isBackspace = false;
|
|
479
|
+
let shouldPreserveAttributes = false;
|
|
480
|
+
// Detect pressing `Backspace`.
|
|
481
|
+
this.listenTo(view.document, 'delete', (evt, data) => {
|
|
482
|
+
isBackspace = data.direction === 'backward';
|
|
483
|
+
}, { priority: 'high' });
|
|
484
|
+
// Before removing the content, check whether the selection is inside a two-step attribute.
|
|
485
|
+
// If so, we want to preserve those attributes.
|
|
486
|
+
this.listenTo(model, 'deleteContent', () => {
|
|
487
|
+
if (!isBackspace) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
const position = selection.getFirstPosition();
|
|
491
|
+
shouldPreserveAttributes = hasAnyAttribute(selection, this.attributes) &&
|
|
492
|
+
!isStepAfterAnyAttributeBoundary(position, this.attributes);
|
|
493
|
+
}, { priority: 'high' });
|
|
494
|
+
// After removing the content, check whether the current selection should preserve the `linkHref` attribute.
|
|
495
|
+
this.listenTo(model, 'deleteContent', () => {
|
|
496
|
+
if (!isBackspace) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
isBackspace = false;
|
|
500
|
+
// Do not escape two-step attribute if it was inside it before content deletion.
|
|
501
|
+
if (shouldPreserveAttributes) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
// Use `model.enqueueChange()` in order to execute the callback at the end of the changes process.
|
|
505
|
+
editor.model.enqueueChange(() => {
|
|
506
|
+
const position = selection.getFirstPosition();
|
|
507
|
+
if (hasAnyAttribute(selection, this.attributes) &&
|
|
508
|
+
isBetweenDifferentAttributes(position, this.attributes)) {
|
|
509
|
+
if (position.isAtStart || isBetweenDifferentAttributes(position, this.attributes, true)) {
|
|
510
|
+
clearSelectionAttributes(model, this.attributes);
|
|
511
|
+
}
|
|
512
|
+
else if (!this._isGravityOverridden) {
|
|
513
|
+
this._overrideGravity();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
}, { priority: 'low' });
|
|
518
|
+
}
|
|
343
519
|
/**
|
|
344
520
|
* `true` when the gravity is overridden for the plugin.
|
|
345
521
|
*/
|
|
@@ -404,6 +580,14 @@ function setSelectionAttributesFromTheNodeBefore(model, attributes, position) {
|
|
|
404
580
|
}
|
|
405
581
|
});
|
|
406
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* Removes 2-SCM attributes from the selection.
|
|
585
|
+
*/
|
|
586
|
+
function clearSelectionAttributes(model, attributes) {
|
|
587
|
+
model.change(writer => {
|
|
588
|
+
writer.removeSelectionAttribute(attributes);
|
|
589
|
+
});
|
|
590
|
+
}
|
|
407
591
|
/**
|
|
408
592
|
* Prevents the caret movement in the view by calling `preventDefault` on the event data.
|
|
409
593
|
*
|
|
@@ -422,11 +606,14 @@ function isStepAfterAnyAttributeBoundary(position, attributes) {
|
|
|
422
606
|
/**
|
|
423
607
|
* Checks whether the given position is between different values of given attributes.
|
|
424
608
|
*/
|
|
425
|
-
function isBetweenDifferentAttributes(position, attributes) {
|
|
609
|
+
function isBetweenDifferentAttributes(position, attributes, isStrict = false) {
|
|
426
610
|
const { nodeBefore, nodeAfter } = position;
|
|
427
611
|
for (const observedAttribute of attributes) {
|
|
428
612
|
const attrBefore = nodeBefore ? nodeBefore.getAttribute(observedAttribute) : undefined;
|
|
429
613
|
const attrAfter = nodeAfter ? nodeAfter.getAttribute(observedAttribute) : undefined;
|
|
614
|
+
if (isStrict && (attrBefore === undefined || attrAfter === undefined)) {
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
430
617
|
if (attrAfter !== attrBefore) {
|
|
431
618
|
return true;
|
|
432
619
|
}
|
package/src/typingconfig.d.ts
CHANGED
|
@@ -164,7 +164,7 @@ export interface TextTransformationConfig {
|
|
|
164
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
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
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 &
|
|
167
|
+
* * If a function is used, it should return an array as described above. The function is passed one parameter – an array with matches
|
|
168
168
|
* by the regular expression. See the examples below.
|
|
169
169
|
*
|
|
170
170
|
* A simple string-to-string replacement:
|