qms-angular 1.0.30 → 1.0.34
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/bundles/qms-angular.umd.js +1099 -526
- package/bundles/qms-angular.umd.js.map +1 -1
- package/esm2015/lib/components/app-icon/app-icon.module.js +23 -0
- package/esm2015/lib/components/app-icon/icon-registry.service.js +47 -0
- package/esm2015/lib/components/breadcrumb/breadcrumb.js +47 -41
- package/esm2015/lib/components/breadcrumb/enum/dropdown-node-width.enum.js +6 -0
- package/esm2015/lib/components/button/button-toggle.js +1 -1
- package/esm2015/lib/components/dialog/constant.js +4 -2
- package/esm2015/lib/components/dialog/dialog.js +4 -4
- package/esm2015/lib/components/related/common/data-type.enum.js +2 -2
- package/esm2015/lib/components/related/common/qms-icon.const.js +21 -1
- package/esm2015/lib/components/related/common/tree.function.js +10 -5
- package/esm2015/lib/components/related/list-other-related/list-related.component.js +69 -8
- package/esm2015/lib/components/related/model/popup-data.model.js +2 -1
- package/esm2015/lib/components/related/model/related-data.model.js +1 -1
- package/esm2015/lib/components/related/model/selected-node.model.js +1 -1
- package/esm2015/lib/components/related/model/tree-config.model.js +1 -1
- package/esm2015/lib/components/related/model/tree-node.model.js +1 -1
- package/esm2015/lib/components/related/popup/related-popup.component.js +220 -27
- package/esm2015/lib/components/related/related.module.js +9 -5
- package/esm2015/lib/components/related/risk/analysis/analysis.component.js +1 -1
- package/esm2015/lib/components/related/service/related-global.service.js +5 -1
- package/esm2015/lib/components/related/tree/tree.component.js +38 -26
- package/esm2015/lib/components/table/table-action.js +2 -2
- package/esm2015/lib/directives/scrollbar/scrollbar.directive.js +8 -2
- package/esm2015/lib/model/en.js +7 -2
- package/esm2015/lib/model/no.js +7 -2
- package/esm2015/lib/qms-ckeditor-components/common/constants/ckeditorEvent.constant.js +3 -1
- package/esm2015/lib/qms-ckeditor-components/common/models/qms-ckeditor-data.model.js +1 -7
- package/esm2015/lib/qms-ckeditor-components/common/models/qms-ckeditor-input.model.js +3 -1
- package/esm2015/lib/qms-ckeditor-components/common/module/confirm/qms-ckeditor-confirm.component.js +1 -1
- package/esm2015/lib/qms-ckeditor-components/components/qms-ckeditor-link/attachments/link-attachment.component.js +1 -1
- package/esm2015/lib/qms-ckeditor-components/components/qms-ckeditor-link/qms-ckeditor-link.component.js +5 -5
- package/esm2015/lib/qms-ckeditor-components/components/qms-ckeditor-load-template/qms-ckeditor-load-template.component.js +1 -1
- package/esm2015/lib/qms-ckeditor-components/components/qms-ckeditor-relation/qmsckeditor-related.component.js +1 -1
- package/esm2015/lib/qms-ckeditor-components/components/qms-ckeditor-template/qms-ckeditor-template.component.js +1 -1
- package/esm2015/lib/qms-ckeditor-components/components/qms-ckeditor-tooltip/qms-ckeditor-tooltip.component.js +76 -0
- package/esm2015/lib/qms-ckeditor-components/models/qms-ckeditor-tooltip.model.js +7 -0
- package/esm2015/lib/qms-ckeditor-components/qms-ckeditor.component.js +72 -2
- package/esm2015/lib/qms-ckeditor-components/qms-ckeditor.module.js +4 -2
- package/esm2015/public-api.js +3 -1
- package/esm2015/qms-angular.js +3 -1
- package/fesm2015/qms-angular.js +1185 -640
- package/fesm2015/qms-angular.js.map +1 -1
- package/lib/components/app-icon/app-icon.module.d.ts +2 -0
- package/lib/components/app-icon/icon-registry.service.d.ts +11 -0
- package/lib/components/breadcrumb/breadcrumb.d.ts +2 -0
- package/lib/components/breadcrumb/enum/dropdown-node-width.enum.d.ts +4 -0
- package/lib/components/related/common/data-type.enum.d.ts +1 -1
- package/lib/components/related/common/qms-icon.const.d.ts +4 -0
- package/lib/components/related/list-other-related/list-related.component.d.ts +8 -3
- package/lib/components/related/model/popup-data.model.d.ts +2 -0
- package/lib/components/related/model/related-data.model.d.ts +7 -2
- package/lib/components/related/model/selected-node.model.d.ts +1 -0
- package/lib/components/related/model/tree-config.model.d.ts +1 -0
- package/lib/components/related/model/tree-node.model.d.ts +1 -0
- package/lib/components/related/popup/related-popup.component.d.ts +22 -1
- package/lib/components/related/service/related-global.service.d.ts +2 -0
- package/lib/components/related/tree/tree.component.d.ts +10 -2
- package/lib/directives/scrollbar/scrollbar.directive.d.ts +1 -0
- package/lib/model/en.d.ts +6 -1
- package/lib/model/no.d.ts +6 -1
- package/lib/qms-ckeditor-components/common/constants/ckeditorEvent.constant.d.ts +2 -0
- package/lib/qms-ckeditor-components/common/models/qms-ckeditor-data.model.d.ts +6 -5
- package/lib/qms-ckeditor-components/common/models/qms-ckeditor-input.model.d.ts +2 -0
- package/lib/qms-ckeditor-components/components/qms-ckeditor-tooltip/qms-ckeditor-tooltip.component.d.ts +36 -0
- package/lib/qms-ckeditor-components/models/qms-ckeditor-tooltip.model.d.ts +6 -0
- package/lib/qms-ckeditor-components/qms-ckeditor.component.d.ts +8 -0
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
- package/qms-angular.d.ts +2 -0
- package/qms-angular.metadata.json +1 -1
- package/src/assets/qms-ckeditor-plugin/build/ckeditor.js +2 -1
- package/src/assets/qms-ckeditor-plugin/build/ckeditor.js.map +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/az.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/cs.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/da.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/de.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/en-au.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/es.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/et.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/fa.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/fr.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/gl.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/hi.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/hr.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/hu.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/id.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/it.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/ko.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/ku.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/lv.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/nl.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/no.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/pl.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/pt-br.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/ru.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/sk.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/sr-latn.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/sr.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/th.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/tk.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/tr.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/uk.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/vi.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/zh-cn.js +1 -1
- package/src/assets/qms-ckeditor-plugin/build/translations/zh.js +1 -1
- package/src/assets/qms-ckeditor-plugin/package-lock.json +852 -2062
- package/src/assets/qms-ckeditor-plugin/package.json +26 -19
- package/src/assets/qms-ckeditor-plugin/src/ckeditor.js +17 -5
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/findandreplace.js +132 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/findandreplaceediting.js +315 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/findandreplaceui.js +223 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/findcommand.js +90 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/findnextcommand.js +62 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/findpreviouscommand.js +28 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/index.js +10 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/replaceallcommand.js +54 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/replacecommand.js +66 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/ui/checkboxview.js +212 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/ui/findandreplaceformview.js +546 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/src/utils.js +158 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/theme/findandreplace.css +13 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/theme/findandreplaceform.css +226 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-find-and-replace/theme/icons/find-replace.svg +1 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-special-characters/src/specialcharacters.js +4 -4
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-special-characters/src/specialcharactersarrows.js +1 -1
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-special-characters/src/specialcharacterscurrency.js +1 -1
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-special-characters/src/specialcharactersessentials.js +1 -1
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-special-characters/src/specialcharacterslatin.js +1 -1
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-special-characters/src/specialcharactersmathematical.js +1 -1
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-special-characters/src/specialcharacterstext.js +1 -1
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-special-characters/src/ui/charactergridview.js +1 -1
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-special-characters/src/ui/characterinfoview.js +1 -1
- package/src/assets/qms-ckeditor-plugin/src/plugins/ckeditor5-special-characters/src/ui/specialcharactersnavigationview.js +2 -2
- package/src/assets/qms-ckeditor-plugin/src/plugins/common/qmsCKEditorConstant.js +4 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/common/qmsCKEditorService.js +10 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/common/qmsCKEditorUtil.js +4 -3
- package/src/assets/qms-ckeditor-plugin/src/plugins/timestamp/timestamp.js +21 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/inserttooltipcommand.js +98 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/removetooltipcommand.js +41 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/tooltip.js +14 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/tooltipediting.js +280 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/tooltipui.js +203 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/ui/actionsview.js +95 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/utils.js +70 -0
- package/src/assets/qms-ckeditor-plugin/src/themes/icons/information.svg +50 -0
- package/src/assets/qms-ckeditor-plugin/src/themes/tyles/tooltip.css +74 -0
- package/src/lib/components/breadcrumb/breadcrumb.scss +10 -1
- package/src/lib/components/button/button-toggle.scss +25 -1
- package/src/lib/components/dialog/dialog.scss +9 -0
- package/src/lib/components/related/list-other-related/list-related.component.scss +41 -5
- package/src/lib/components/related/popup/related-popup.component.scss +69 -0
- package/src/lib/components/related/tree/tree.component.scss +3 -3
- package/src/lib/components/table/table.scss +5 -27
- package/src/lib/qms-ckeditor-components/components/qms-ckeditor-tooltip/qms-ckeditor-tooltip.component.scss +11 -0
- package/src/lib/qms-ckeditor-components/qms-ckeditor.component.scss +29 -1
- package/src/lib/qms-ckeditor-components/styles/_modules.scss +10 -0
- package/src/themes/core/_form.scss +4 -0
- package/src/themes/core/_input.scss +8 -0
- package/src/themes/core/_scrollbar.scss +9 -2
- package/src/themes/core/_styles.scss +5 -0
- package/src/themes/core/_tab.scss +272 -6
@@ -0,0 +1,546 @@
|
|
1
|
+
/**
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4
|
+
*/
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @module find-and-replace/ui/findandreplaceformview
|
8
|
+
*/
|
9
|
+
|
10
|
+
import { ButtonView, FocusCycler, LabeledFieldView, createLabeledInputText, View, submitHandler, ViewCollection } from '@ckeditor/ckeditor5-ui';
|
11
|
+
import { FocusTracker, KeystrokeHandler, uid } from '@ckeditor/ckeditor5-utils';
|
12
|
+
|
13
|
+
// See: #8833.
|
14
|
+
// eslint-disable-next-line ckeditor5-rules/ckeditor-imports
|
15
|
+
import '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';
|
16
|
+
import '../../theme/findandreplaceform.css';
|
17
|
+
// eslint-disable-next-line ckeditor5-rules/ckeditor-imports
|
18
|
+
import findArrowIcon from '@ckeditor/ckeditor5-ui/theme/icons/dropdown-arrow.svg';
|
19
|
+
import CheckboxView from '../ui/checkboxview';
|
20
|
+
|
21
|
+
/**
|
22
|
+
* The find and replace form view controller class.
|
23
|
+
*
|
24
|
+
* See {@link module:find-and-replace/ui/findandreplaceformview~FindAndReplaceFormView}.
|
25
|
+
*
|
26
|
+
* @extends module:ui/view~View
|
27
|
+
*/
|
28
|
+
export default class FindAndReplaceFormView extends View {
|
29
|
+
constructor( locale ) {
|
30
|
+
super( locale );
|
31
|
+
|
32
|
+
const t = locale.t;
|
33
|
+
|
34
|
+
/**
|
35
|
+
* Indicates that the form is in active searching state.
|
36
|
+
*
|
37
|
+
* @readonly
|
38
|
+
* @observable
|
39
|
+
* @member {Boolean} #isSearching
|
40
|
+
*/
|
41
|
+
this.set( 'isSearching' );
|
42
|
+
this.set( 'searchText', '' );
|
43
|
+
this.set( 'replaceText', '' );
|
44
|
+
|
45
|
+
/**
|
46
|
+
* Stores the number of matched search results.
|
47
|
+
*
|
48
|
+
* @readonly
|
49
|
+
* @observable
|
50
|
+
* @member {Number} #matchCount
|
51
|
+
*/
|
52
|
+
this.set( 'matchCount', null );
|
53
|
+
|
54
|
+
/**
|
55
|
+
* The offset of currently highlighted search result in {@link #matchCount matched results}.
|
56
|
+
*
|
57
|
+
* @readonly
|
58
|
+
* @observable
|
59
|
+
* @member {Number|null} #highlightOffset
|
60
|
+
*/
|
61
|
+
this.set( 'highlightOffset', null );
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Whether the search results counter should be visible.
|
65
|
+
*
|
66
|
+
* @private
|
67
|
+
* @readonly
|
68
|
+
* @observable
|
69
|
+
* @member {Boolean} #isCounterHidden
|
70
|
+
*/
|
71
|
+
this.set( 'isCounterHidden', true );
|
72
|
+
|
73
|
+
/**
|
74
|
+
* The find in text input view that stores the searched string.
|
75
|
+
*
|
76
|
+
* @member {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
|
77
|
+
*/
|
78
|
+
this.findInputView = this._createInputField( t( 'Find in text…' ) );
|
79
|
+
|
80
|
+
/**
|
81
|
+
* The find button view that initializes the search process.
|
82
|
+
*
|
83
|
+
* @member {module:ui/button/buttonview~ButtonView}
|
84
|
+
*/
|
85
|
+
this.findButtonView = this._createButton( t( 'Find' ), 'ck-button-find' );
|
86
|
+
this.findButtonView.on( 'execute', () => {
|
87
|
+
this.fire( 'findNext', {
|
88
|
+
searchText: this.searchText,
|
89
|
+
matchCase: this.matchCaseView.isChecked,
|
90
|
+
wholeWords: this.matchWholeWordsView.isChecked
|
91
|
+
} );
|
92
|
+
} );
|
93
|
+
|
94
|
+
/**
|
95
|
+
* The find previous button view.
|
96
|
+
*
|
97
|
+
* @member {module:ui/button/buttonview~ButtonView}
|
98
|
+
*/
|
99
|
+
this.findPrevButtonView = this._createButton( t( 'Previous result' ), 'ck-button-prev', findArrowIcon, false );
|
100
|
+
this.findPrevButtonView.on( 'execute', () => {
|
101
|
+
this.fire( 'findPrevious' );
|
102
|
+
} );
|
103
|
+
|
104
|
+
/**
|
105
|
+
* The find next button view.
|
106
|
+
*
|
107
|
+
* @member {module:ui/button/buttonview~ButtonView}
|
108
|
+
*/
|
109
|
+
this.findNextButtonView = this._createButton( t( 'Next result' ), 'ck-button-next', findArrowIcon, false );
|
110
|
+
this.findNextButtonView.on( 'execute', () => {
|
111
|
+
this.fire( 'findNext' );
|
112
|
+
} );
|
113
|
+
|
114
|
+
/**
|
115
|
+
* The replace button view.
|
116
|
+
*
|
117
|
+
* @member {module:ui/button/buttonview~ButtonView}
|
118
|
+
*/
|
119
|
+
this.replaceButtonView = this._createButton( t( 'Replace' ), 'ck-button-replace' );
|
120
|
+
this.replaceButtonView.on( 'execute', () => {
|
121
|
+
this.fire( 'replace', { searchText: this.searchText, replaceText: this.replaceText } );
|
122
|
+
} );
|
123
|
+
|
124
|
+
/**
|
125
|
+
* The replace all button view.
|
126
|
+
*
|
127
|
+
* @member {module:ui/button/buttonview~ButtonView}
|
128
|
+
*/
|
129
|
+
this.replaceAllButtonView = this._createButton( t( 'Replace all' ), 'ck-button-replaceall' );
|
130
|
+
this.replaceAllButtonView.on( 'execute', () => {
|
131
|
+
this.fire( 'replaceAll', { searchText: this.searchText, replaceText: this.replaceText } );
|
132
|
+
} );
|
133
|
+
|
134
|
+
/**
|
135
|
+
* The match case checkbox view.
|
136
|
+
*
|
137
|
+
* @member {module:find-and-replace/ui/checkboxview~CheckboxView}
|
138
|
+
*/
|
139
|
+
this.matchCaseView = this._createCheckbox( t( 'Match case' ) );
|
140
|
+
|
141
|
+
/**
|
142
|
+
* The whole words only checkbox view.
|
143
|
+
*
|
144
|
+
* @member {module:find-and-replace/ui/checkboxview~CheckboxView}
|
145
|
+
*/
|
146
|
+
this.matchWholeWordsView = this._createCheckbox( t( 'Whole words only' ) );
|
147
|
+
|
148
|
+
/**
|
149
|
+
* The replace input view.
|
150
|
+
*
|
151
|
+
* @member {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
|
152
|
+
*/
|
153
|
+
this.replaceInputView = this._createInputField( t( 'Replace with…' ) );
|
154
|
+
|
155
|
+
/**
|
156
|
+
* Stores gathered views related to find functionality of the feature.
|
157
|
+
*
|
158
|
+
* @member {module:ui/view~View}
|
159
|
+
*/
|
160
|
+
this.findView = this._createFindView();
|
161
|
+
|
162
|
+
/**
|
163
|
+
* Stores gathered views related to replace functionality of the feature.
|
164
|
+
*
|
165
|
+
* @member {module:ui/view~View}
|
166
|
+
*/
|
167
|
+
this.replaceView = this._createReplaceView();
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Tracks information about the DOM focus in the form.
|
171
|
+
*
|
172
|
+
* @readonly
|
173
|
+
* @member {module:utils/focustracker~FocusTracker}
|
174
|
+
*/
|
175
|
+
this.focusTracker = new FocusTracker();
|
176
|
+
|
177
|
+
/**
|
178
|
+
* An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
|
179
|
+
*
|
180
|
+
* @readonly
|
181
|
+
* @member {module:utils/keystrokehandler~KeystrokeHandler}
|
182
|
+
*/
|
183
|
+
this.keystrokes = new KeystrokeHandler();
|
184
|
+
|
185
|
+
/**
|
186
|
+
* A collection of views that can be focused in the form.
|
187
|
+
*
|
188
|
+
* @readonly
|
189
|
+
* @protected
|
190
|
+
* @member {module:ui/viewcollection~ViewCollection}
|
191
|
+
*/
|
192
|
+
this._focusables = new ViewCollection();
|
193
|
+
|
194
|
+
/**
|
195
|
+
* Helps cycling over {@link #_focusables} in the form.
|
196
|
+
*
|
197
|
+
* @readonly
|
198
|
+
* @protected
|
199
|
+
* @member {module:ui/focuscycler~FocusCycler}
|
200
|
+
*/
|
201
|
+
this._focusCycler = new FocusCycler( {
|
202
|
+
focusables: this._focusables,
|
203
|
+
focusTracker: this.focusTracker,
|
204
|
+
keystrokeHandler: this.keystrokes,
|
205
|
+
actions: {
|
206
|
+
// Navigate form fields backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.
|
207
|
+
focusPrevious: 'shift + tab',
|
208
|
+
|
209
|
+
// Navigate form fields forwards using the <kbd>Tab</kbd> key.
|
210
|
+
focusNext: 'tab'
|
211
|
+
}
|
212
|
+
} );
|
213
|
+
|
214
|
+
this.bind( 'searchText' ).to( this.findInputView.fieldView, 'value' );
|
215
|
+
this.findButtonView.bind( 'isEnabled' ).to( this.findInputView.fieldView, 'isEmpty', value => !value );
|
216
|
+
this.bind( 'replaceText' ).to( this.replaceInputView.fieldView, 'value' );
|
217
|
+
this.replaceButtonView.bind( 'isEnabled' ).to( this, 'isSearching' );
|
218
|
+
this.replaceAllButtonView.bind( 'isEnabled' ).to( this, 'isSearching' );
|
219
|
+
|
220
|
+
this.bind( 'isCounterHidden' ).to( this, 'matchCount', this, 'highlightOffset', ( matchCount, highlightOffset ) => {
|
221
|
+
return matchCount === null || matchCount === 0 ||
|
222
|
+
highlightOffset === null || highlightOffset === 0;
|
223
|
+
} );
|
224
|
+
|
225
|
+
this.setTemplate( {
|
226
|
+
tag: 'form',
|
227
|
+
|
228
|
+
attributes: {
|
229
|
+
class: [
|
230
|
+
'ck',
|
231
|
+
'ck-find-and-replace-form'
|
232
|
+
]
|
233
|
+
},
|
234
|
+
|
235
|
+
children: [
|
236
|
+
this.findView,
|
237
|
+
this.replaceView
|
238
|
+
]
|
239
|
+
} );
|
240
|
+
}
|
241
|
+
|
242
|
+
render() {
|
243
|
+
super.render();
|
244
|
+
|
245
|
+
submitHandler( {
|
246
|
+
view: this
|
247
|
+
} );
|
248
|
+
|
249
|
+
const childViews = [
|
250
|
+
this.findInputView,
|
251
|
+
this.matchCaseView,
|
252
|
+
this.matchWholeWordsView,
|
253
|
+
this.findButtonView,
|
254
|
+
this.findPrevButtonView,
|
255
|
+
this.findNextButtonView,
|
256
|
+
this.replaceInputView,
|
257
|
+
this.replaceAllButtonView,
|
258
|
+
this.replaceButtonView
|
259
|
+
];
|
260
|
+
|
261
|
+
childViews.forEach( v => {
|
262
|
+
// Register the view as focusable.
|
263
|
+
this._focusables.add( v );
|
264
|
+
|
265
|
+
// Register the view in the focus tracker.
|
266
|
+
this.focusTracker.add( v.element );
|
267
|
+
} );
|
268
|
+
|
269
|
+
// Start listening for the keystrokes coming from #element.
|
270
|
+
this.keystrokes.listenTo( this.element );
|
271
|
+
|
272
|
+
const stopPropagation = data => data.stopPropagation();
|
273
|
+
const stopPropagationAndPreventDefault = data => {
|
274
|
+
data.stopPropagation();
|
275
|
+
data.preventDefault();
|
276
|
+
};
|
277
|
+
|
278
|
+
this.keystrokes.set( 'f3', event => {
|
279
|
+
stopPropagationAndPreventDefault( event );
|
280
|
+
|
281
|
+
this.findNextButtonView.fire( 'execute' );
|
282
|
+
} );
|
283
|
+
|
284
|
+
this.keystrokes.set( 'shift+f3', event => {
|
285
|
+
stopPropagationAndPreventDefault( event );
|
286
|
+
|
287
|
+
this.findPrevButtonView.fire( 'execute' );
|
288
|
+
} );
|
289
|
+
|
290
|
+
this.keystrokes.set( 'enter', event => {
|
291
|
+
// @todo: this is a bit workaroundish way to handle enter, we should work on views rather than raw DOM elements.
|
292
|
+
const target = event.target;
|
293
|
+
|
294
|
+
if ( target.classList.contains( 'ck-input-text' ) ) {
|
295
|
+
if (
|
296
|
+
target.parentElement.parentElement.parentElement.classList.contains( 'ck-find-form__wrapper' ) &&
|
297
|
+
this.findButtonView.isEnabled
|
298
|
+
) {
|
299
|
+
this.findButtonView.fire( 'execute' );
|
300
|
+
stopPropagationAndPreventDefault( event );
|
301
|
+
} else if (
|
302
|
+
target.parentElement.parentElement.parentElement.classList.contains( 'ck-replace-form__wrapper' ) &&
|
303
|
+
this.replaceButtonView.isEnabled
|
304
|
+
) {
|
305
|
+
this.replaceButtonView.fire( 'execute' );
|
306
|
+
stopPropagationAndPreventDefault( event );
|
307
|
+
}
|
308
|
+
}
|
309
|
+
} );
|
310
|
+
|
311
|
+
// Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's
|
312
|
+
// keystroke handler would take over the key management in the URL input.
|
313
|
+
// We need to prevent this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.
|
314
|
+
this.keystrokes.set( 'arrowright', stopPropagation );
|
315
|
+
this.keystrokes.set( 'arrowleft', stopPropagation );
|
316
|
+
this.keystrokes.set( 'arrowup', stopPropagation );
|
317
|
+
this.keystrokes.set( 'arrowdown', stopPropagation );
|
318
|
+
|
319
|
+
// Intercept the `selectstart` event, which is blocked by default because of the default behavior
|
320
|
+
// of the DropdownView#panelView.
|
321
|
+
this.listenTo( this.findInputView.element, 'selectstart', ( evt, domEvt ) => {
|
322
|
+
domEvt.stopPropagation();
|
323
|
+
}, { priority: 'high' } );
|
324
|
+
this.listenTo( this.replaceInputView.element, 'selectstart', ( evt, domEvt ) => {
|
325
|
+
domEvt.stopPropagation();
|
326
|
+
}, { priority: 'high' } );
|
327
|
+
}
|
328
|
+
|
329
|
+
/**
|
330
|
+
* Focuses the fist {@link #_focusables} in the form.
|
331
|
+
*/
|
332
|
+
focus() {
|
333
|
+
this._focusCycler.focusFirst();
|
334
|
+
}
|
335
|
+
|
336
|
+
/**
|
337
|
+
* A collection of views for the 'find' functionality of the feature
|
338
|
+
*
|
339
|
+
* @private
|
340
|
+
* @return {module:ui/view~View} The find view instance.
|
341
|
+
*/
|
342
|
+
|
343
|
+
_createFindView() {
|
344
|
+
const findView = new View();
|
345
|
+
|
346
|
+
const bind = this.bindTemplate;
|
347
|
+
const t = this.locale.t;
|
348
|
+
|
349
|
+
findView.setTemplate( {
|
350
|
+
tag: 'div',
|
351
|
+
attributes: {
|
352
|
+
class: [
|
353
|
+
'ck',
|
354
|
+
'ck-find-form__wrapper',
|
355
|
+
'ck-responsive-form',
|
356
|
+
bind.if( 'isSearching', 'ck-is-searching' )
|
357
|
+
],
|
358
|
+
tabindex: '-1'
|
359
|
+
},
|
360
|
+
children: [
|
361
|
+
this.findInputView,
|
362
|
+
{ tag: 'span',
|
363
|
+
attributes: {
|
364
|
+
class: [
|
365
|
+
'ck-results-counter',
|
366
|
+
bind.if( 'isCounterHidden', 'ck-hidden' )
|
367
|
+
]
|
368
|
+
},
|
369
|
+
children: [
|
370
|
+
{
|
371
|
+
text: bind.to( 'highlightOffset' )
|
372
|
+
},
|
373
|
+
t( ' of ' ),
|
374
|
+
{
|
375
|
+
text: bind.to( 'matchCount' )
|
376
|
+
}
|
377
|
+
]
|
378
|
+
},
|
379
|
+
{
|
380
|
+
tag: 'div',
|
381
|
+
attributes: {
|
382
|
+
class: [ 'ck-find-checkboxes' ]
|
383
|
+
},
|
384
|
+
children: [
|
385
|
+
this.matchCaseView,
|
386
|
+
this.matchWholeWordsView
|
387
|
+
]
|
388
|
+
},
|
389
|
+
{
|
390
|
+
tag: 'div',
|
391
|
+
attributes: {
|
392
|
+
class: [
|
393
|
+
'ck-find-buttons'
|
394
|
+
]
|
395
|
+
},
|
396
|
+
children: [
|
397
|
+
this.findButtonView,
|
398
|
+
this.findPrevButtonView,
|
399
|
+
this.findNextButtonView
|
400
|
+
]
|
401
|
+
}
|
402
|
+
]
|
403
|
+
} );
|
404
|
+
|
405
|
+
return findView;
|
406
|
+
}
|
407
|
+
|
408
|
+
/**
|
409
|
+
* A collection of views for the 'replace' functionality of the feature
|
410
|
+
*
|
411
|
+
* @private
|
412
|
+
* @returns {module:ui/view~View} The replace view instance.
|
413
|
+
*/
|
414
|
+
_createReplaceView() {
|
415
|
+
const replaceView = new View();
|
416
|
+
const bind = this.bindTemplate;
|
417
|
+
|
418
|
+
replaceView.setTemplate( {
|
419
|
+
tag: 'div',
|
420
|
+
attributes: {
|
421
|
+
class: [
|
422
|
+
'ck',
|
423
|
+
'ck-replace-form__wrapper',
|
424
|
+
'ck-responsive-form',
|
425
|
+
bind.if( 'isSearching', 'ck-is-searching' )
|
426
|
+
],
|
427
|
+
tabindex: '-1'
|
428
|
+
},
|
429
|
+
children: [
|
430
|
+
this.replaceInputView,
|
431
|
+
{
|
432
|
+
tag: 'div',
|
433
|
+
attributes: {
|
434
|
+
class: [
|
435
|
+
'ck-replace-buttons'
|
436
|
+
]
|
437
|
+
},
|
438
|
+
children: [
|
439
|
+
this.replaceAllButtonView,
|
440
|
+
this.replaceButtonView
|
441
|
+
]
|
442
|
+
}
|
443
|
+
]
|
444
|
+
} );
|
445
|
+
return replaceView;
|
446
|
+
}
|
447
|
+
|
448
|
+
/**
|
449
|
+
* Creates a labeled input view.
|
450
|
+
*
|
451
|
+
* @private
|
452
|
+
* @param {String} infoText The input label.
|
453
|
+
* @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView} The labeled input view instance.
|
454
|
+
*/
|
455
|
+
_createInputField( infoText ) {
|
456
|
+
const labeledInput = new LabeledFieldView( this.locale, createLabeledInputText );
|
457
|
+
const inputField = labeledInput.fieldView;
|
458
|
+
|
459
|
+
// @todo: this looks like an upstream UI bug (the fact that InputTextView#value does not get updated).
|
460
|
+
inputField.on( 'input', () => {
|
461
|
+
inputField.value = inputField.element.value;
|
462
|
+
} );
|
463
|
+
|
464
|
+
labeledInput.label = infoText;
|
465
|
+
labeledInput.render();
|
466
|
+
|
467
|
+
return labeledInput;
|
468
|
+
}
|
469
|
+
|
470
|
+
/**
|
471
|
+
* Creates a button view.
|
472
|
+
*
|
473
|
+
* @private
|
474
|
+
* @param {String} label The button label.
|
475
|
+
* @param {String} className The individual button CSS class name.
|
476
|
+
* @param {String} icon An SVG image of icon to be used in button.
|
477
|
+
* @param {Boolean} withText Whether the text should be shown.
|
478
|
+
* @returns {module:ui/button/buttonview~ButtonView} The button view instance.
|
479
|
+
*/
|
480
|
+
_createButton( label, className, icon, withText = true ) {
|
481
|
+
const button = new ButtonView( this.locale );
|
482
|
+
|
483
|
+
button.set( {
|
484
|
+
label,
|
485
|
+
icon,
|
486
|
+
withText
|
487
|
+
} );
|
488
|
+
|
489
|
+
button.extendTemplate( {
|
490
|
+
attributes: {
|
491
|
+
class: className
|
492
|
+
}
|
493
|
+
} );
|
494
|
+
|
495
|
+
return button;
|
496
|
+
}
|
497
|
+
|
498
|
+
/**
|
499
|
+
* Creates a view for the checkboxes.
|
500
|
+
*
|
501
|
+
* @private
|
502
|
+
* @param {String} label The checkbox label.
|
503
|
+
* @returns {module:ui/view~View} The checkbox view instance.
|
504
|
+
*/
|
505
|
+
_createCheckbox( label ) {
|
506
|
+
const checkboxView = new CheckboxView( this.locale );
|
507
|
+
|
508
|
+
checkboxView.set( {
|
509
|
+
isVisible: true,
|
510
|
+
tooltip: true,
|
511
|
+
class: 'ck-find-checkboxes__box',
|
512
|
+
id: uid(),
|
513
|
+
label
|
514
|
+
} );
|
515
|
+
|
516
|
+
return checkboxView;
|
517
|
+
}
|
518
|
+
}
|
519
|
+
|
520
|
+
/**
|
521
|
+
* Fired when the find next button ({@link #findNextButtonView}) is triggered .
|
522
|
+
*
|
523
|
+
* @event findNext
|
524
|
+
* @param {String} searchText Search text.
|
525
|
+
*/
|
526
|
+
|
527
|
+
/**
|
528
|
+
* Fired when the find previous button ({@link #findPrevButtonView}) is triggered.
|
529
|
+
*
|
530
|
+
* @event findPrevious
|
531
|
+
* @param {String} searchText Search text.
|
532
|
+
*/
|
533
|
+
|
534
|
+
/**
|
535
|
+
* Fired when the replace button ({@link #replaceButtonView}) is triggered.
|
536
|
+
*
|
537
|
+
* @event replace
|
538
|
+
* @param {String} replaceText Replacement text.
|
539
|
+
*/
|
540
|
+
|
541
|
+
/**
|
542
|
+
* Fired when the replaceAll button ({@link #replaceAllButtonView}) is triggered.
|
543
|
+
*
|
544
|
+
* @event replaceAll
|
545
|
+
* @param {String} replaceText Replacement text.
|
546
|
+
*/
|
@@ -0,0 +1,158 @@
|
|
1
|
+
/**
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4
|
+
*/
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @module find-and-replace
|
8
|
+
*/
|
9
|
+
|
10
|
+
import { uid, Collection } from '@ckeditor/ckeditor5-utils';
|
11
|
+
import { escapeRegExp } from 'lodash-es';
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Executes findCallback and updates search results list.
|
15
|
+
*
|
16
|
+
* @param {module:engine/model/range~Range} range
|
17
|
+
* @param {module:engine/model/model~Model} model
|
18
|
+
* @param {Function} findCallback
|
19
|
+
* @param {module:utils/collection~Collection} [startResults] An optional collection of find matches that the function should
|
20
|
+
* starts with. This would be a collection returned by a previous `updateFindResultFromRange()` call.
|
21
|
+
* @returns {module:utils/collection~Collection} A collection of objects describing find match.
|
22
|
+
*
|
23
|
+
* An example structure:
|
24
|
+
*
|
25
|
+
* ```js
|
26
|
+
* {
|
27
|
+
* id: resultId,
|
28
|
+
* label: foundItem.label,
|
29
|
+
* marker
|
30
|
+
* }
|
31
|
+
* ```
|
32
|
+
*/
|
33
|
+
export function updateFindResultFromRange( range, model, findCallback, startResults ) {
|
34
|
+
const results = startResults || new Collection();
|
35
|
+
|
36
|
+
[ ...range ].forEach( ( { type, item } ) => {
|
37
|
+
if ( type === 'elementStart' ) {
|
38
|
+
if ( model.schema.checkChild( item, '$text' ) ) {
|
39
|
+
const foundItems = findCallback( {
|
40
|
+
item,
|
41
|
+
text: rangeToText( model.createRangeIn( item ) )
|
42
|
+
} );
|
43
|
+
|
44
|
+
if ( !foundItems ) {
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
|
48
|
+
foundItems.forEach( foundItem => {
|
49
|
+
model.change( writer => {
|
50
|
+
const resultId = `findResult:${ uid() }`;
|
51
|
+
const marker = writer.addMarker( resultId, {
|
52
|
+
usingOperation: false,
|
53
|
+
affectsData: false,
|
54
|
+
range: writer.createRange(
|
55
|
+
writer.createPositionAt( item, foundItem.start ),
|
56
|
+
writer.createPositionAt( item, foundItem.end )
|
57
|
+
)
|
58
|
+
} );
|
59
|
+
|
60
|
+
const index = findInsertIndex( results, marker );
|
61
|
+
|
62
|
+
results.add(
|
63
|
+
{
|
64
|
+
id: resultId,
|
65
|
+
label: foundItem.label,
|
66
|
+
marker
|
67
|
+
},
|
68
|
+
index
|
69
|
+
);
|
70
|
+
} );
|
71
|
+
} );
|
72
|
+
}
|
73
|
+
}
|
74
|
+
} );
|
75
|
+
|
76
|
+
return results;
|
77
|
+
}
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Returns text representation of a range. The returned text length should be the same as range length.
|
81
|
+
* In order to achieve this this function will:
|
82
|
+
* - replace inline elements (text-line) as new line character ("\n").
|
83
|
+
* - @todo: check unicode characters
|
84
|
+
*/
|
85
|
+
export function rangeToText( range ) {
|
86
|
+
return Array.from( range.getItems() ).reduce( ( rangeText, node ) => {
|
87
|
+
// Trim text to a last occurrence of an inline element and update range start.
|
88
|
+
if ( !( node.is( 'text' ) || node.is( 'textProxy' ) ) ) {
|
89
|
+
// Editor has only one inline element defined in schema: `<softBreak>` which is treated as new line character in blocks.
|
90
|
+
// Special handling might be needed for other inline elements (inline widgets).
|
91
|
+
return `${ rangeText }\n`;
|
92
|
+
}
|
93
|
+
|
94
|
+
return rangeText + node.data;
|
95
|
+
}, '' );
|
96
|
+
}
|
97
|
+
|
98
|
+
function findInsertIndex( resultsList, markerToInsert ) {
|
99
|
+
const result = resultsList.find( ( { marker } ) => {
|
100
|
+
return markerToInsert.getStart().isBefore( marker.getStart() );
|
101
|
+
} );
|
102
|
+
|
103
|
+
return result ? resultsList.getIndex( result ) : resultsList.length;
|
104
|
+
}
|
105
|
+
|
106
|
+
function regexpMatchToFindResult( matchResult ) {
|
107
|
+
// In case of match words option the matching results contain indices so that we work on
|
108
|
+
// offset where a subject match group was (as opposed to working on entire matched string).
|
109
|
+
if ( matchResult.indices ) {
|
110
|
+
return {
|
111
|
+
label: matchResult[ 1 ],
|
112
|
+
start: matchResult.indices[ 1 ][ 0 ],
|
113
|
+
end: matchResult.indices[ 1 ][ 1 ]
|
114
|
+
};
|
115
|
+
} else {
|
116
|
+
return {
|
117
|
+
label: matchResult[ 1 ],
|
118
|
+
start: matchResult.index,
|
119
|
+
end: matchResult.index + matchResult[ 1 ].length
|
120
|
+
};
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
/**
|
125
|
+
*
|
126
|
+
* @param {String} searchTerm
|
127
|
+
* @param {Object} [options]
|
128
|
+
* @param {Boolean} [options.matchCase=false] If set to `true` letter casing will be ignored.
|
129
|
+
* @param {Boolean} [options.wholeWords=false] If set to `true` only whole words that match `callbackOrText` will be matched.
|
130
|
+
* @returns {Function}
|
131
|
+
*/
|
132
|
+
export function findByTextCallback( searchTerm, options ) {
|
133
|
+
let flags = 'gu';
|
134
|
+
|
135
|
+
if ( !options.matchCase ) {
|
136
|
+
flags += 'i';
|
137
|
+
}
|
138
|
+
|
139
|
+
let regExpQuery = `(${ escapeRegExp( searchTerm ) })`;
|
140
|
+
|
141
|
+
if ( options.wholeWords ) {
|
142
|
+
flags += 'd'; // Special groups so that regexp indices are available.
|
143
|
+
|
144
|
+
const nonLetterGroup = '[^a-zA-Z\u00C0-\u024F\u1E00-\u1EFF]';
|
145
|
+
|
146
|
+
regExpQuery = `(?:^|${ nonLetterGroup }|_)` + regExpQuery + `(?:_|${ nonLetterGroup }|$)`;
|
147
|
+
}
|
148
|
+
|
149
|
+
const regExp = new RegExp( regExpQuery, flags );
|
150
|
+
|
151
|
+
function findCallback( { text } ) {
|
152
|
+
const matches = [ ...text.matchAll( regExp ) ];
|
153
|
+
|
154
|
+
return matches.map( regexpMatchToFindResult );
|
155
|
+
}
|
156
|
+
|
157
|
+
return findCallback;
|
158
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4
|
+
*/
|
5
|
+
|
6
|
+
.ck-find-result {
|
7
|
+
background: hsl(58, 100%, 50%);
|
8
|
+
color: var(--ck-color-text);
|
9
|
+
}
|
10
|
+
|
11
|
+
.ck-find-result_selected {
|
12
|
+
background: hsl(52, 100%, 50%);
|
13
|
+
}
|