@ckeditor/ckeditor5-find-and-replace 29.2.0 → 32.0.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.
Files changed (53) hide show
  1. package/LICENSE.md +2 -2
  2. package/build/find-and-replace.js +3 -3
  3. package/build/translations/bs.js +1 -0
  4. package/build/translations/cs.js +1 -0
  5. package/build/translations/da.js +1 -0
  6. package/build/translations/de.js +1 -1
  7. package/build/translations/es.js +1 -0
  8. package/build/translations/hu.js +1 -1
  9. package/build/translations/id.js +1 -0
  10. package/build/translations/it.js +1 -1
  11. package/build/translations/nl.js +1 -0
  12. package/build/translations/no.js +1 -0
  13. package/build/translations/pl.js +1 -0
  14. package/build/translations/pt-br.js +1 -0
  15. package/build/translations/sr-latn.js +1 -0
  16. package/build/translations/sr.js +1 -0
  17. package/build/translations/zh-cn.js +1 -0
  18. package/build/translations/zh.js +1 -0
  19. package/lang/translations/bs.po +69 -0
  20. package/lang/translations/cs.po +69 -0
  21. package/lang/translations/da.po +69 -0
  22. package/lang/translations/de.po +4 -4
  23. package/lang/translations/en.po +1 -1
  24. package/lang/translations/es.po +69 -0
  25. package/lang/translations/gl.po +1 -1
  26. package/lang/translations/hu.po +4 -4
  27. package/lang/translations/id.po +69 -0
  28. package/lang/translations/it.po +4 -4
  29. package/lang/translations/nl.po +69 -0
  30. package/lang/translations/no.po +69 -0
  31. package/lang/translations/pl.po +69 -0
  32. package/lang/translations/pt-br.po +69 -0
  33. package/lang/translations/ru.po +1 -1
  34. package/lang/translations/sr-latn.po +69 -0
  35. package/lang/translations/sr.po +69 -0
  36. package/lang/translations/zh-cn.po +69 -0
  37. package/lang/translations/zh.po +69 -0
  38. package/package.json +23 -22
  39. package/src/findandreplace.js +1 -1
  40. package/src/findandreplaceediting.js +18 -7
  41. package/src/findandreplacestate.js +14 -2
  42. package/src/findandreplaceui.js +15 -8
  43. package/src/findcommand.js +19 -15
  44. package/src/findnextcommand.js +12 -9
  45. package/src/findpreviouscommand.js +5 -2
  46. package/src/index.js +1 -1
  47. package/src/replaceallcommand.js +4 -2
  48. package/src/replacecommand.js +12 -2
  49. package/src/ui/findandreplaceformview.js +15 -4
  50. package/src/utils.js +29 -23
  51. package/theme/findandreplace.css +1 -1
  52. package/theme/findandreplaceform.css +1 -1
  53. package/CHANGELOG.md +0 -4
@@ -0,0 +1,69 @@
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ #
3
+ # !!! IMPORTANT !!!
4
+ #
5
+ # Before you edit this file, please keep in mind that contributing to the project
6
+ # translations is possible ONLY via the Transifex online service.
7
+ #
8
+ # To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
9
+ #
10
+ # To learn more, check out the official contributor's guide:
11
+ # https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
12
+ #
13
+ msgid ""
14
+ msgstr ""
15
+ "Language-Team: Chinese (Taiwan) (https://www.transifex.com/ckeditor/teams/11143/zh_TW/)\n"
16
+ "Language: zh_TW\n"
17
+ "Plural-Forms: nplurals=1; plural=0;\n"
18
+
19
+ msgctxt "The tooltip of a find and replace button in the toolbar. Also, the title of the find and replace form."
20
+ msgid "Find and replace"
21
+ msgstr "尋找和取代"
22
+
23
+ msgctxt "The label for the searched text in the find and replace dropdown."
24
+ msgid "Find in text…"
25
+ msgstr "在文本中尋找"
26
+
27
+ msgctxt "The label for the find action button in the find and replace dropdown."
28
+ msgid "Find"
29
+ msgstr "尋找"
30
+
31
+ msgctxt "The label for the previous result button in the find and replace dropdown."
32
+ msgid "Previous result"
33
+ msgstr "前一個結果"
34
+
35
+ msgctxt "The label for the previous result button in the find and replace dropdown."
36
+ msgid "Next result"
37
+ msgstr "後一個結果"
38
+
39
+ msgctxt "The label for the (single) replace action button in the find and replace dropdown."
40
+ msgid "Replace"
41
+ msgstr "取代"
42
+
43
+ msgctxt "The label for the replace all action button in the find and replace dropdown."
44
+ msgid "Replace all"
45
+ msgstr "全部取代"
46
+
47
+ msgctxt "The label for the match case checkbox in the find and replace dropdown."
48
+ msgid "Match case"
49
+ msgstr "大小寫需相符"
50
+
51
+ msgctxt "The label for the whole words only checkbox in the find and replace dropdown."
52
+ msgid "Whole words only"
53
+ msgstr ""
54
+
55
+ msgctxt "The label for the text replacement in the find and replace dropdown."
56
+ msgid "Replace with…"
57
+ msgstr "以…替代"
58
+
59
+ msgctxt "An error text displayed when user attempted to find an empty text."
60
+ msgid "Text to find must not be empty."
61
+ msgstr "不能查找空字串"
62
+
63
+ msgctxt "A message displayed next to the replace field when disabled but user tries to use it."
64
+ msgid "Tip: Find some text first in order to replace it."
65
+ msgstr "提示:先查找字串再取代"
66
+
67
+ msgctxt "The label and a tooltip of the options dropdown button in the find and replace form."
68
+ msgid "Show options"
69
+ msgstr "顯示設定"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-find-and-replace",
3
- "version": "29.2.0",
3
+ "version": "32.0.0",
4
4
  "description": "Find and replace feature for CKEditor 5.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -12,32 +12,33 @@
12
12
  ],
13
13
  "main": "src/index.js",
14
14
  "dependencies": {
15
- "@ckeditor/ckeditor5-ui": "^29.2.0",
16
- "@ckeditor/ckeditor5-utils": "^29.2.0",
17
- "ckeditor5": "^29.2.0",
15
+ "@ckeditor/ckeditor5-ui": "^32.0.0",
16
+ "@ckeditor/ckeditor5-utils": "^32.0.0",
17
+ "ckeditor5": "^32.0.0",
18
18
  "lodash-es": "^4.17.15"
19
19
  },
20
20
  "devDependencies": {
21
- "@ckeditor/ckeditor5-dev-utils": "^25.4.0",
22
- "@ckeditor/ckeditor5-basic-styles": "^29.2.0",
23
- "@ckeditor/ckeditor5-core": "^29.2.0",
24
- "@ckeditor/ckeditor5-editor-classic": "^29.2.0",
25
- "@ckeditor/ckeditor5-editor-decoupled": "^29.2.0",
26
- "@ckeditor/ckeditor5-engine": "^29.2.0",
27
- "@ckeditor/ckeditor5-essentials": "^29.2.0",
28
- "@ckeditor/ckeditor5-heading": "^29.2.0",
29
- "@ckeditor/ckeditor5-font": "^29.2.0",
30
- "@ckeditor/ckeditor5-highlight": "^29.2.0",
31
- "@ckeditor/ckeditor5-link": "^29.2.0",
32
- "@ckeditor/ckeditor5-list": "^29.2.0",
33
- "@ckeditor/ckeditor5-paragraph": "^29.2.0",
34
- "@ckeditor/ckeditor5-source-editing": "^29.2.0",
35
- "@ckeditor/ckeditor5-theme-lark": "^29.2.0",
36
- "webpack": "^4.43.0",
37
- "webpack-cli": "^3.3.11"
21
+ "@ckeditor/ckeditor5-dev-utils": "^27.1.0",
22
+ "@ckeditor/ckeditor5-basic-styles": "^32.0.0",
23
+ "@ckeditor/ckeditor5-core": "^32.0.0",
24
+ "@ckeditor/ckeditor5-editor-classic": "^32.0.0",
25
+ "@ckeditor/ckeditor5-editor-decoupled": "^32.0.0",
26
+ "@ckeditor/ckeditor5-engine": "^32.0.0",
27
+ "@ckeditor/ckeditor5-essentials": "^32.0.0",
28
+ "@ckeditor/ckeditor5-heading": "^32.0.0",
29
+ "@ckeditor/ckeditor5-font": "^32.0.0",
30
+ "@ckeditor/ckeditor5-highlight": "^32.0.0",
31
+ "@ckeditor/ckeditor5-link": "^32.0.0",
32
+ "@ckeditor/ckeditor5-list": "^32.0.0",
33
+ "@ckeditor/ckeditor5-paragraph": "^32.0.0",
34
+ "@ckeditor/ckeditor5-source-editing": "^32.0.0",
35
+ "@ckeditor/ckeditor5-theme-lark": "^32.0.0",
36
+ "@ckeditor/ckeditor5-undo": "^32.0.0",
37
+ "webpack": "^5.58.1",
38
+ "webpack-cli": "^4.9.0"
38
39
  },
39
40
  "engines": {
40
- "node": ">=12.0.0",
41
+ "node": ">=14.0.0",
41
42
  "npm": ">=5.7.1"
42
43
  },
43
44
  "author": "CKSource (http://cksource.com/)",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -94,7 +94,13 @@ export default class FindAndReplaceEditing extends Plugin {
94
94
  * @inheritDoc
95
95
  */
96
96
  init() {
97
- this.activeResults = null;
97
+ /**
98
+ * The collection of currently highlighted search results.
99
+ *
100
+ * @private
101
+ * @member {module:utils/collection~Collection} #_activeResults
102
+ */
103
+ this._activeResults = null;
98
104
 
99
105
  /**
100
106
  * An object storing the find and replace state within a given editor instance.
@@ -138,6 +144,7 @@ export default class FindAndReplaceEditing extends Plugin {
138
144
  // This would result with accessing a view three that is no longer in DOM.
139
145
  this.listenTo( this.editor, 'destroy', debouncedScrollListener.cancel );
140
146
 
147
+ /* istanbul ignore next */
141
148
  function scrollToHighlightedResult( eventInfo, name, newValue ) {
142
149
  if ( newValue ) {
143
150
  const domConverter = this.editor.editing.view.domConverter;
@@ -163,19 +170,19 @@ export default class FindAndReplaceEditing extends Plugin {
163
170
 
164
171
  const { findCallback, results } = editor.execute( 'find', callbackOrText );
165
172
 
166
- this.activeResults = results;
173
+ this._activeResults = results;
167
174
 
168
175
  // @todo: handle this listener, another copy is in findcommand.js file.
169
- this.listenTo( model.document, 'change:data', () => onDocumentChange( this.activeResults, model, findCallback ) );
176
+ this.listenTo( model.document, 'change:data', () => onDocumentChange( this._activeResults, model, findCallback ) );
170
177
 
171
- return this.activeResults;
178
+ return this._activeResults;
172
179
  }
173
180
 
174
181
  /**
175
182
  * Stops active results from updating, and clears out the results.
176
183
  */
177
184
  stop() {
178
- if ( !this.activeResults ) {
185
+ if ( !this._activeResults ) {
179
186
  return;
180
187
  }
181
188
 
@@ -183,10 +190,12 @@ export default class FindAndReplaceEditing extends Plugin {
183
190
 
184
191
  this.state.clear( this.editor.model );
185
192
 
186
- this.activeResults = null;
193
+ this._activeResults = null;
187
194
  }
188
195
 
189
196
  /**
197
+ * Sets up the commands.
198
+ *
190
199
  * @private
191
200
  */
192
201
  _defineCommands() {
@@ -198,6 +207,8 @@ export default class FindAndReplaceEditing extends Plugin {
198
207
  }
199
208
 
200
209
  /**
210
+ * Sets up the marker downcast converters for search results highlighting.
211
+ *
201
212
  * @private
202
213
  */
203
214
  _defineConverters() {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -12,13 +12,20 @@ import { ObservableMixin, mix, Collection } from 'ckeditor5/src/utils';
12
12
  /**
13
13
  * The object storing find and replace plugin state for a given editor instance.
14
14
  *
15
+ * @mixes module:utils/observablemixin~ObservableMixin
15
16
  */
16
17
  export default class FindAndReplaceState {
18
+ /**
19
+ * Creates an instance of the state.
20
+ *
21
+ * @param {module:engine/model/model~Model} model
22
+ */
17
23
  constructor( model ) {
18
24
  /**
19
25
  * A collection of find matches.
20
26
  *
21
- * @private
27
+ * @protected
28
+ * @observable
22
29
  * @member {module:utils/collection~Collection} #results
23
30
  */
24
31
  this.set( 'results', new Collection() );
@@ -94,6 +101,11 @@ export default class FindAndReplaceState {
94
101
  } );
95
102
  }
96
103
 
104
+ /**
105
+ * Cleans the state up and removes markers from the model.
106
+ *
107
+ * @param {module:engine/model/model~Model} model
108
+ */
97
109
  clear( model ) {
98
110
  this.searchText = '';
99
111
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -29,6 +29,9 @@ export default class FindAndReplaceUI extends Plugin {
29
29
  return 'FindAndReplaceUI';
30
30
  }
31
31
 
32
+ /**
33
+ * @inheritDoc
34
+ */
32
35
  constructor( editor ) {
33
36
  super( editor );
34
37
 
@@ -55,12 +58,12 @@ export default class FindAndReplaceUI extends Plugin {
55
58
  dropdown.bind( 'isEnabled' ).to( editor.commands.get( 'find' ) );
56
59
  dropdown.panelView.children.add( formView );
57
60
 
58
- // Each time a dropdown is opened, the search text field should get focused and selected for better UX.
59
- // Note: Using the low priority here to make sure the following listener starts working after the
60
- // default action of the drop-down is executed (i.e. the panel showed up). Otherwise, the
61
- // invisible form/input cannot be focused/selected.
61
+ // Every time a dropdown is opened, the search text field should get focused and selected for better UX.
62
+ // Note: Using the low priority here to make sure the following listener starts working after
63
+ // the default action of the drop-down is executed (i.e. the panel showed up). Otherwise,
64
+ // the invisible form/input cannot be focused/selected.
62
65
  //
63
- // Each time a dropdown is closed, move the focus back to the editing root (to preserve it)
66
+ // Each time a dropdown is closed, move the focus back to the find and replace toolbar button
64
67
  // and let the find and replace editing feature know that all search results can be invalidated
65
68
  // and no longer should be marked in the content.
66
69
  dropdown.on( 'change:isOpen', ( event, name, isOpen ) => {
@@ -73,7 +76,7 @@ export default class FindAndReplaceUI extends Plugin {
73
76
 
74
77
  formView.enableCssTransitions();
75
78
  } else {
76
- editor.editing.view.focus();
79
+ formView.focus();
77
80
 
78
81
  this.fire( 'searchReseted' );
79
82
  }
@@ -87,8 +90,10 @@ export default class FindAndReplaceUI extends Plugin {
87
90
  }
88
91
 
89
92
  /**
93
+ * Sets up the find and replace button.
94
+ *
90
95
  * @private
91
- * @param {module:ui/dropdown/dropdownview~DropdownView} buttonView
96
+ * @param {module:ui/dropdown/dropdownview~DropdownView} dropdown
92
97
  */
93
98
  _setupDropdownButton( dropdown ) {
94
99
  const editor = this.editor;
@@ -108,6 +113,8 @@ export default class FindAndReplaceUI extends Plugin {
108
113
  }
109
114
 
110
115
  /**
116
+ * Sets up the form view for the find and replace.
117
+ *
111
118
  * @private
112
119
  * @param {module:find-and-replace/ui/findandreplaceformview~FindAndReplaceFormView} formView A related form view.
113
120
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -20,6 +20,7 @@ export default class FindCommand extends Command {
20
20
  * Creates a new `FindCommand` instance.
21
21
  *
22
22
  * @param {module:core/editor/editor~Editor} editor The editor on which this command will be used.
23
+ * @param {module:find-and-replace/findandreplacestate~FindAndReplaceState} state An object to hold plugin state.
23
24
  */
24
25
  constructor( editor, state ) {
25
26
  super( editor );
@@ -27,14 +28,16 @@ export default class FindCommand extends Command {
27
28
  // The find command is always enabled.
28
29
  this.isEnabled = true;
29
30
 
30
- this.state = state;
31
+ // It does not affect data so should be enabled in read-only mode.
32
+ this.affectsData = false;
31
33
 
32
- // Do not block the command if the editor goes into the read-only mode as it does not impact the data. See #9975.
33
- this.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {
34
- if ( value ) {
35
- this.clearForceDisabled( 'readOnlyMode' );
36
- }
37
- } );
34
+ /**
35
+ * The find and replace state object used for command operations.
36
+ *
37
+ * @private
38
+ * @member {module:find-and-replace/findandreplacestate~FindAndReplaceState} #_state
39
+ */
40
+ this._state = state;
38
41
  }
39
42
 
40
43
  /**
@@ -44,6 +47,7 @@ export default class FindCommand extends Command {
44
47
  * @param {Object} [options]
45
48
  * @param {Boolean} [options.matchCase=false] If set to `true`, the letter case will be matched.
46
49
  * @param {Boolean} [options.wholeWords=false] If set to `true`, only whole words that match `callbackOrText` will be matched.
50
+ *
47
51
  * @fires execute
48
52
  */
49
53
  execute( callbackOrText, { matchCase, wholeWords } = {} ) {
@@ -56,7 +60,7 @@ export default class FindCommand extends Command {
56
60
  if ( typeof callbackOrText === 'string' ) {
57
61
  findCallback = findByTextCallback( callbackOrText, { matchCase, wholeWords } );
58
62
 
59
- this.state.searchText = callbackOrText;
63
+ this._state.searchText = callbackOrText;
60
64
  } else {
61
65
  findCallback = callbackOrText;
62
66
  }
@@ -70,16 +74,16 @@ export default class FindCommand extends Command {
70
74
  currentResults
71
75
  ) ), null );
72
76
 
73
- this.state.clear( model );
74
- this.state.results.addMany( Array.from( results ) );
75
- this.state.highlightedResult = results.get( 0 );
77
+ this._state.clear( model );
78
+ this._state.results.addMany( Array.from( results ) );
79
+ this._state.highlightedResult = results.get( 0 );
76
80
 
77
81
  if ( typeof callbackOrText === 'string' ) {
78
- this.state.searchText = callbackOrText;
82
+ this._state.searchText = callbackOrText;
79
83
  }
80
84
 
81
- this.state.matchCase = !!matchCase;
82
- this.state.matchWholeWords = !!wholeWords;
85
+ this._state.matchCase = !!matchCase;
86
+ this._state.matchWholeWords = !!wholeWords;
83
87
 
84
88
  return {
85
89
  results,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -21,14 +21,18 @@ export default class FindNextCommand extends Command {
21
21
  * Creates a new `FindNextCommand` instance.
22
22
  *
23
23
  * @param {module:core/editor/editor~Editor} editor The editor on which this command will be used.
24
+ * @param {module:find-and-replace/findandreplacestate~FindAndReplaceState} state An object to hold plugin state.
24
25
  */
25
26
  constructor( editor, state ) {
26
27
  super( editor );
27
28
 
29
+ // It does not affect data so should be enabled in read-only mode.
30
+ this.affectsData = false;
31
+
28
32
  /**
29
33
  * The find and replace state object used for command operations.
30
34
  *
31
- * @private
35
+ * @protected
32
36
  * @member {module:find-and-replace/findandreplacestate~FindAndReplaceState} #_state
33
37
  */
34
38
  this._state = state;
@@ -38,19 +42,18 @@ export default class FindNextCommand extends Command {
38
42
  this.listenTo( this._state.results, 'change', () => {
39
43
  this.isEnabled = this._state.results.length > 1;
40
44
  } );
41
-
42
- // Do not block the command if the editor goes into the read-only mode as it does not impact the data. See #9975.
43
- this.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {
44
- if ( value ) {
45
- this.clearForceDisabled( 'readOnlyMode' );
46
- }
47
- } );
48
45
  }
49
46
 
47
+ /**
48
+ * @inheritDoc
49
+ */
50
50
  refresh() {
51
51
  this.isEnabled = this._state.results.length > 1;
52
52
  }
53
53
 
54
+ /**
55
+ * @inheritDoc
56
+ */
54
57
  execute() {
55
58
  const results = this._state.results;
56
59
  const currentIndex = results.getIndex( this._state.highlightedResult );
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -10,13 +10,16 @@
10
10
  import FindNextCommand from './findnextcommand';
11
11
 
12
12
  /**
13
- * The find next command. Moves the highlight to the next search result.
13
+ * The find previous command. Moves the highlight to the previous search result.
14
14
  *
15
15
  * It is used by the {@link module:find-and-replace/findandreplace~FindAndReplace find and replace feature}.
16
16
  *
17
17
  * @extends module:find-and-replace/findnextcommand~FindNextCommand
18
18
  */
19
19
  export default class FindPreviousCommand extends FindNextCommand {
20
+ /**
21
+ * @inheritDoc
22
+ */
20
23
  execute() {
21
24
  const results = this._state.results;
22
25
  const currentIndex = results.getIndex( this._state.highlightedResult );
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -14,7 +14,7 @@ import ReplaceCommand from './replacecommand';
14
14
  /**
15
15
  * The replace all command. It is used by the {@link module:find-and-replace/findandreplace~FindAndReplace find and replace feature}.
16
16
  *
17
- * @extends module:core/command~Command
17
+ * @extends module:find-and-replace/replacecommand~ReplaceCommand
18
18
  */
19
19
  export default class ReplaceAllCommand extends ReplaceCommand {
20
20
  /**
@@ -33,6 +33,8 @@ export default class ReplaceAllCommand extends ReplaceCommand {
33
33
  * @param {String} newText Text that will be inserted to the editor for each match.
34
34
  * @param {String|module:utils/collection~Collection} textToReplace Text to be replaced or a collection of matches
35
35
  * as returned by the find command.
36
+ *
37
+ * @fires module:core/command~Command#event:execute
36
38
  */
37
39
  execute( newText, textToReplace ) {
38
40
  const { editor } = this;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -19,6 +19,7 @@ export default class ReplaceCommand extends Command {
19
19
  * Creates a new `ReplaceCommand` instance.
20
20
  *
21
21
  * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.
22
+ * @param {module:find-and-replace/findandreplacestate~FindAndReplaceState} state An object to hold plugin state.
22
23
  */
23
24
  constructor( editor, state ) {
24
25
  super( editor );
@@ -29,7 +30,7 @@ export default class ReplaceCommand extends Command {
29
30
  /**
30
31
  * The find and replace state object used for command operations.
31
32
  *
32
- * @private
33
+ * @protected
33
34
  * @member {module:find-and-replace/findandreplacestate~FindAndReplaceState} #_state
34
35
  */
35
36
  this._state = state;
@@ -40,6 +41,8 @@ export default class ReplaceCommand extends Command {
40
41
  *
41
42
  * @param {String} replacementText
42
43
  * @param {Object} result A single result from the find command.
44
+ *
45
+ * @fires module:core/command~Command#event:execute
43
46
  */
44
47
  execute( replacementText, result ) {
45
48
  const { model } = this.editor;
@@ -47,6 +50,13 @@ export default class ReplaceCommand extends Command {
47
50
  model.change( writer => {
48
51
  const range = result.marker.getRange();
49
52
 
53
+ // Don't replace a result (marker) that found its way into the $graveyard (e.g. removed by collaborators).
54
+ if ( range.root.rootName === '$graveyard' ) {
55
+ this._state.results.remove( result );
56
+
57
+ return;
58
+ }
59
+
50
60
  let textAttributes = {};
51
61
 
52
62
  for ( const item of range.getItems() ) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -28,7 +28,8 @@ import {
28
28
  FocusTracker,
29
29
  KeystrokeHandler,
30
30
  Collection,
31
- Rect
31
+ Rect,
32
+ isVisible
32
33
  } from 'ckeditor5/src/utils';
33
34
 
34
35
  // See: #8833.
@@ -353,6 +354,16 @@ export default class FindAndReplaceFormView extends View {
353
354
  this._initKeystrokeHandling();
354
355
  }
355
356
 
357
+ /**
358
+ * @inheritDoc
359
+ */
360
+ destroy() {
361
+ super.destroy();
362
+
363
+ this._focusTracker.destroy();
364
+ this._keystrokes.destroy();
365
+ }
366
+
356
367
  /**
357
368
  * Focuses the fist {@link #_focusables} in the form.
358
369
  */
@@ -503,7 +514,7 @@ export default class FindAndReplaceFormView extends View {
503
514
  const inputElement = this._findInputView.fieldView.element;
504
515
 
505
516
  // Don't adjust the padding if the input (also: counter) were not rendered or not inserted into DOM yet.
506
- if ( !inputElement || !inputElement.offsetParent ) {
517
+ if ( !inputElement || !isVisible( inputElement ) ) {
507
518
  return;
508
519
  }
509
520
 
@@ -725,7 +736,7 @@ export default class FindAndReplaceFormView extends View {
725
736
  this._findButtonView.fire( 'execute' );
726
737
  }
727
738
  stopPropagationAndPreventDefault( event );
728
- } else if ( target === this._replaceInputView.fieldView.element ) {
739
+ } else if ( target === this._replaceInputView.fieldView.element && !this.isDirty ) {
729
740
  this._replaceButtonView.fire( 'execute' );
730
741
  stopPropagationAndPreventDefault( event );
731
742
  }