@ckeditor/ckeditor5-bookmark 0.0.0-nightly-next-20250302.0 → 0.0.0-nightly-20250303.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/build/bookmark.js +2 -2
- package/build/translations/af.js +1 -1
- package/build/translations/ar.js +1 -1
- package/build/translations/ast.js +1 -1
- package/build/translations/az.js +1 -1
- package/build/translations/bg.js +1 -1
- package/build/translations/bn.js +1 -1
- package/build/translations/bs.js +1 -1
- package/build/translations/ca.js +1 -1
- package/build/translations/cs.js +1 -1
- package/build/translations/da.js +1 -1
- package/build/translations/de-ch.js +1 -1
- package/build/translations/de.js +1 -1
- package/build/translations/el.js +1 -1
- package/build/translations/en-au.js +1 -1
- package/build/translations/en-gb.js +1 -1
- package/build/translations/eo.js +1 -1
- package/build/translations/es-co.js +1 -1
- package/build/translations/es.js +1 -1
- package/build/translations/et.js +1 -1
- package/build/translations/eu.js +1 -1
- package/build/translations/fa.js +1 -1
- package/build/translations/fi.js +1 -1
- package/build/translations/fr.js +1 -1
- package/build/translations/gl.js +1 -1
- package/build/translations/gu.js +1 -1
- package/build/translations/he.js +1 -1
- package/build/translations/hi.js +1 -1
- package/build/translations/hr.js +1 -1
- package/build/translations/hu.js +1 -1
- package/build/translations/hy.js +1 -1
- package/build/translations/id.js +1 -1
- package/build/translations/it.js +1 -1
- package/build/translations/ja.js +1 -1
- package/build/translations/jv.js +1 -1
- package/build/translations/kk.js +1 -1
- package/build/translations/km.js +1 -1
- package/build/translations/kn.js +1 -1
- package/build/translations/ko.js +1 -1
- package/build/translations/ku.js +1 -1
- package/build/translations/lt.js +1 -1
- package/build/translations/lv.js +1 -1
- package/build/translations/ms.js +1 -1
- package/build/translations/nb.js +1 -1
- package/build/translations/ne.js +1 -1
- package/build/translations/nl.js +1 -1
- package/build/translations/no.js +1 -1
- package/build/translations/oc.js +1 -1
- package/build/translations/pl.js +1 -1
- package/build/translations/pt-br.js +1 -1
- package/build/translations/pt.js +1 -1
- package/build/translations/ro.js +1 -1
- package/build/translations/ru.js +1 -1
- package/build/translations/si.js +1 -1
- package/build/translations/sk.js +1 -1
- package/build/translations/sl.js +1 -1
- package/build/translations/sq.js +1 -1
- package/build/translations/sr-latn.js +1 -1
- package/build/translations/sr.js +1 -1
- package/build/translations/sv.js +1 -1
- package/build/translations/th.js +1 -1
- package/build/translations/ti.js +1 -1
- package/build/translations/tk.js +1 -1
- package/build/translations/tr.js +1 -1
- package/build/translations/tt.js +1 -1
- package/build/translations/ug.js +1 -1
- package/build/translations/uk.js +1 -1
- package/build/translations/ur.js +1 -1
- package/build/translations/uz.js +1 -1
- package/build/translations/vi.js +1 -1
- package/build/translations/zh-cn.js +1 -1
- package/build/translations/zh.js +1 -1
- package/ckeditor5-metadata.json +1 -1
- package/dist/index-editor.css +101 -56
- package/dist/index.css +119 -59
- package/dist/index.css.map +1 -1
- package/dist/index.js +389 -282
- package/dist/index.js.map +1 -1
- package/lang/contexts.json +3 -5
- package/package.json +7 -8
- package/src/bookmarkconfig.d.ts +0 -24
- package/src/bookmarkediting.d.ts +1 -9
- package/src/bookmarkediting.js +9 -23
- package/src/bookmarkui.d.ts +57 -24
- package/src/bookmarkui.js +212 -207
- package/src/ui/bookmarkactionsview.d.ts +102 -0
- package/src/ui/bookmarkactionsview.js +154 -0
- package/src/ui/bookmarkformview.d.ts +14 -24
- package/src/ui/bookmarkformview.js +62 -103
- package/theme/bookmark.css +46 -0
- package/theme/bookmarkactions.css +44 -0
- package/theme/bookmarkform.css +38 -0
- package/theme/bookmarktoolbar.css +0 -4
package/dist/index.js
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
4
|
*/
|
|
5
|
-
import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
|
|
6
|
-
import { toWidget,
|
|
7
|
-
import { View, ViewCollection,
|
|
8
|
-
import {
|
|
5
|
+
import { icons, Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
|
|
6
|
+
import { toWidget, Widget } from '@ckeditor/ckeditor5-widget/dist/index.js';
|
|
7
|
+
import { View, ViewCollection, FocusCycler, submitHandler, FormHeaderView, LabeledFieldView, createLabeledInputText, ButtonView, LabelView, IconView, ContextualBalloon, CssTransitionDisablerMixin, MenuBarMenuListItemButtonView, clickOutsideHandler } from '@ckeditor/ckeditor5-ui/dist/index.js';
|
|
8
|
+
import { ClickObserver } from '@ckeditor/ckeditor5-engine/dist/index.js';
|
|
9
9
|
import { FocusTracker, KeystrokeHandler, logWarning } from '@ckeditor/ckeditor5-utils/dist/index.js';
|
|
10
|
-
import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* The bookmark form view controller class.
|
|
@@ -24,11 +23,8 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
24
23
|
* The ID input view.
|
|
25
24
|
*/ idInputView;
|
|
26
25
|
/**
|
|
27
|
-
* The
|
|
28
|
-
*/
|
|
29
|
-
/**
|
|
30
|
-
* A button used to submit the form.
|
|
31
|
-
*/ saveButtonView;
|
|
26
|
+
* The Submit button view.
|
|
27
|
+
*/ buttonView;
|
|
32
28
|
/**
|
|
33
29
|
* A collection of form child views in the form.
|
|
34
30
|
*/ children;
|
|
@@ -50,30 +46,12 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
50
46
|
* @param validators Form validators used by {@link #isValid}.
|
|
51
47
|
*/ constructor(locale, validators){
|
|
52
48
|
super(locale);
|
|
49
|
+
const t = locale.t;
|
|
53
50
|
this._validators = validators;
|
|
54
|
-
// Create buttons.
|
|
55
|
-
this.backButtonView = this._createBackButton();
|
|
56
|
-
this.saveButtonView = this._createSaveButton();
|
|
57
|
-
// Create input fields.
|
|
58
51
|
this.idInputView = this._createIdInput();
|
|
59
|
-
this.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.children.add(new FormRowView(locale, {
|
|
63
|
-
children: [
|
|
64
|
-
this.idInputView,
|
|
65
|
-
this.saveButtonView
|
|
66
|
-
],
|
|
67
|
-
class: [
|
|
68
|
-
'ck-form__row_with-submit',
|
|
69
|
-
'ck-form__row_large-top-padding'
|
|
70
|
-
]
|
|
71
|
-
}));
|
|
72
|
-
// Close the panel on esc key press when the **form has focus**.
|
|
73
|
-
this.keystrokes.set('Esc', (data, cancel)=>{
|
|
74
|
-
this.fire('cancel');
|
|
75
|
-
cancel();
|
|
76
|
-
});
|
|
52
|
+
this.buttonView = this._createButton(t('Insert'), 'ck-button-action ck-button-bold');
|
|
53
|
+
this.buttonView.type = 'submit';
|
|
54
|
+
this.children = this._createViewChildren();
|
|
77
55
|
this._focusCycler = new FocusCycler({
|
|
78
56
|
focusables: this._focusables,
|
|
79
57
|
focusTracker: this.focusTracker,
|
|
@@ -85,15 +63,14 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
85
63
|
focusNext: 'tab'
|
|
86
64
|
}
|
|
87
65
|
});
|
|
66
|
+
const classList = [
|
|
67
|
+
'ck',
|
|
68
|
+
'ck-bookmark-view'
|
|
69
|
+
];
|
|
88
70
|
this.setTemplate({
|
|
89
71
|
tag: 'form',
|
|
90
72
|
attributes: {
|
|
91
|
-
class:
|
|
92
|
-
'ck',
|
|
93
|
-
'ck-form',
|
|
94
|
-
'ck-bookmark-form',
|
|
95
|
-
'ck-responsive-form'
|
|
96
|
-
],
|
|
73
|
+
class: classList,
|
|
97
74
|
// https://github.com/ckeditor/ckeditor5-link/issues/90
|
|
98
75
|
tabindex: '-1'
|
|
99
76
|
},
|
|
@@ -108,9 +85,8 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
108
85
|
view: this
|
|
109
86
|
});
|
|
110
87
|
const childViews = [
|
|
111
|
-
this.backButtonView,
|
|
112
88
|
this.idInputView,
|
|
113
|
-
this.
|
|
89
|
+
this.buttonView
|
|
114
90
|
];
|
|
115
91
|
childViews.forEach((v)=>{
|
|
116
92
|
// Register the view as focusable.
|
|
@@ -131,7 +107,7 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
131
107
|
/**
|
|
132
108
|
* Focuses the fist {@link #_focusables} in the form.
|
|
133
109
|
*/ focus() {
|
|
134
|
-
this.
|
|
110
|
+
this._focusCycler.focusFirst();
|
|
135
111
|
}
|
|
136
112
|
/**
|
|
137
113
|
* Validates the form and returns `false` when some fields are invalid.
|
|
@@ -157,41 +133,36 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
157
133
|
this.idInputView.errorText = null;
|
|
158
134
|
}
|
|
159
135
|
/**
|
|
160
|
-
* Creates
|
|
161
|
-
*/
|
|
162
|
-
const
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
});
|
|
170
|
-
backButton.delegate('execute').to(this, 'cancel');
|
|
171
|
-
return backButton;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Creates a save button view that saves the bookmark.
|
|
175
|
-
*/ _createSaveButton() {
|
|
176
|
-
const t = this.locale.t;
|
|
177
|
-
const saveButton = new ButtonView(this.locale);
|
|
178
|
-
saveButton.set({
|
|
179
|
-
label: t('Save'),
|
|
180
|
-
withText: true,
|
|
181
|
-
type: 'submit',
|
|
182
|
-
class: 'ck-button-action ck-button-bold'
|
|
183
|
-
});
|
|
184
|
-
return saveButton;
|
|
136
|
+
* Creates header and form view.
|
|
137
|
+
*/ _createViewChildren() {
|
|
138
|
+
const children = this.createCollection();
|
|
139
|
+
const t = this.t;
|
|
140
|
+
children.add(new FormHeaderView(this.locale, {
|
|
141
|
+
label: t('Bookmark')
|
|
142
|
+
}));
|
|
143
|
+
children.add(this._createFormContentView());
|
|
144
|
+
return children;
|
|
185
145
|
}
|
|
186
146
|
/**
|
|
187
|
-
* Creates
|
|
188
|
-
*/
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
|
|
147
|
+
* Creates form content view with input and button.
|
|
148
|
+
*/ _createFormContentView() {
|
|
149
|
+
const view = new View(this.locale);
|
|
150
|
+
const children = this.createCollection();
|
|
151
|
+
const classList = [
|
|
152
|
+
'ck',
|
|
153
|
+
'ck-bookmark-form',
|
|
154
|
+
'ck-responsive-form'
|
|
155
|
+
];
|
|
156
|
+
children.add(this.idInputView);
|
|
157
|
+
children.add(this.buttonView);
|
|
158
|
+
view.setTemplate({
|
|
159
|
+
tag: 'div',
|
|
160
|
+
attributes: {
|
|
161
|
+
class: classList
|
|
162
|
+
},
|
|
163
|
+
children
|
|
192
164
|
});
|
|
193
|
-
|
|
194
|
-
return header;
|
|
165
|
+
return view;
|
|
195
166
|
}
|
|
196
167
|
/**
|
|
197
168
|
* Creates a labeled input view.
|
|
@@ -202,9 +173,27 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
202
173
|
const labeledInput = new LabeledFieldView(this.locale, createLabeledInputText);
|
|
203
174
|
labeledInput.label = t('Bookmark name');
|
|
204
175
|
labeledInput.infoText = t('Enter the bookmark name without spaces.');
|
|
205
|
-
labeledInput.class = 'ck-labeled-field-view_full-width';
|
|
206
176
|
return labeledInput;
|
|
207
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Creates a button view.
|
|
180
|
+
*
|
|
181
|
+
* @param label The button label.
|
|
182
|
+
* @param className The additional button CSS class name.
|
|
183
|
+
* @returns The button view instance.
|
|
184
|
+
*/ _createButton(label, className) {
|
|
185
|
+
const button = new ButtonView(this.locale);
|
|
186
|
+
button.set({
|
|
187
|
+
label,
|
|
188
|
+
withText: true
|
|
189
|
+
});
|
|
190
|
+
button.extendTemplate({
|
|
191
|
+
attributes: {
|
|
192
|
+
class: className
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
return button;
|
|
196
|
+
}
|
|
208
197
|
/**
|
|
209
198
|
* The native DOM `value` of the {@link #idInputView} element.
|
|
210
199
|
*
|
|
@@ -219,6 +208,149 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
219
208
|
}
|
|
220
209
|
}
|
|
221
210
|
|
|
211
|
+
/**
|
|
212
|
+
* The bookmark actions view class. This view displays the bookmark preview, allows
|
|
213
|
+
* removing or editing the bookmark.
|
|
214
|
+
*/ class BookmarkActionsView extends View {
|
|
215
|
+
/**
|
|
216
|
+
* Tracks information about DOM focus in the actions.
|
|
217
|
+
*/ focusTracker = new FocusTracker();
|
|
218
|
+
/**
|
|
219
|
+
* An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
|
|
220
|
+
*/ keystrokes = new KeystrokeHandler();
|
|
221
|
+
/**
|
|
222
|
+
* The bookmark preview view.
|
|
223
|
+
*/ bookmarkPreviewView;
|
|
224
|
+
/**
|
|
225
|
+
* The remove button view.
|
|
226
|
+
*/ removeButtonView;
|
|
227
|
+
/**
|
|
228
|
+
* The edit bookmark button view.
|
|
229
|
+
*/ editButtonView;
|
|
230
|
+
/**
|
|
231
|
+
* A collection of views that can be focused in the view.
|
|
232
|
+
*/ _focusables = new ViewCollection();
|
|
233
|
+
/**
|
|
234
|
+
* Helps cycling over {@link #_focusables} in the view.
|
|
235
|
+
*/ _focusCycler;
|
|
236
|
+
/**
|
|
237
|
+
* @inheritDoc
|
|
238
|
+
*/ constructor(locale){
|
|
239
|
+
super(locale);
|
|
240
|
+
const t = locale.t;
|
|
241
|
+
this.bookmarkPreviewView = this._createBookmarkPreviewView();
|
|
242
|
+
this.removeButtonView = this._createButton(t('Remove bookmark'), icons.remove, 'remove', this.bookmarkPreviewView);
|
|
243
|
+
this.editButtonView = this._createButton(t('Edit bookmark'), icons.pencil, 'edit', this.bookmarkPreviewView);
|
|
244
|
+
this.set('id', undefined);
|
|
245
|
+
this._focusCycler = new FocusCycler({
|
|
246
|
+
focusables: this._focusables,
|
|
247
|
+
focusTracker: this.focusTracker,
|
|
248
|
+
keystrokeHandler: this.keystrokes,
|
|
249
|
+
actions: {
|
|
250
|
+
// Navigate fields backwards using the Shift + Tab keystroke.
|
|
251
|
+
focusPrevious: 'shift + tab',
|
|
252
|
+
// Navigate fields forwards using the Tab key.
|
|
253
|
+
focusNext: 'tab'
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
this.setTemplate({
|
|
257
|
+
tag: 'div',
|
|
258
|
+
attributes: {
|
|
259
|
+
class: [
|
|
260
|
+
'ck',
|
|
261
|
+
'ck-bookmark-actions',
|
|
262
|
+
'ck-responsive-form'
|
|
263
|
+
],
|
|
264
|
+
// https://github.com/ckeditor/ckeditor5-link/issues/90
|
|
265
|
+
tabindex: '-1'
|
|
266
|
+
},
|
|
267
|
+
children: [
|
|
268
|
+
this.bookmarkPreviewView,
|
|
269
|
+
this.editButtonView,
|
|
270
|
+
this.removeButtonView
|
|
271
|
+
]
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* @inheritDoc
|
|
276
|
+
*/ render() {
|
|
277
|
+
super.render();
|
|
278
|
+
const childViews = [
|
|
279
|
+
this.editButtonView,
|
|
280
|
+
this.removeButtonView
|
|
281
|
+
];
|
|
282
|
+
childViews.forEach((v)=>{
|
|
283
|
+
// Register the view as focusable.
|
|
284
|
+
this._focusables.add(v);
|
|
285
|
+
// Register the view in the focus tracker.
|
|
286
|
+
this.focusTracker.add(v.element);
|
|
287
|
+
});
|
|
288
|
+
// Start listening for the keystrokes coming from #element.
|
|
289
|
+
this.keystrokes.listenTo(this.element);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* @inheritDoc
|
|
293
|
+
*/ destroy() {
|
|
294
|
+
super.destroy();
|
|
295
|
+
this.focusTracker.destroy();
|
|
296
|
+
this.keystrokes.destroy();
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Focuses the fist {@link #_focusables} in the actions.
|
|
300
|
+
*/ focus() {
|
|
301
|
+
this._focusCycler.focusFirst();
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Creates a button view.
|
|
305
|
+
*
|
|
306
|
+
* @param label The button label.
|
|
307
|
+
* @param icon The button icon.
|
|
308
|
+
* @param eventName An event name that the `ButtonView#execute` event will be delegated to.
|
|
309
|
+
* @param additionalLabel An additional label outside the button.
|
|
310
|
+
* @returns The button view instance.
|
|
311
|
+
*/ _createButton(label, icon, eventName, additionalLabel) {
|
|
312
|
+
const button = new ButtonView(this.locale);
|
|
313
|
+
button.set({
|
|
314
|
+
label,
|
|
315
|
+
icon,
|
|
316
|
+
tooltip: true
|
|
317
|
+
});
|
|
318
|
+
button.delegate('execute').to(this, eventName);
|
|
319
|
+
// Since button label `id` is bound to the `ariaLabelledBy` property
|
|
320
|
+
// we need to modify this binding to include only the first ID token
|
|
321
|
+
// as this button will be labeled by multiple labels.
|
|
322
|
+
button.labelView.unbind('id');
|
|
323
|
+
button.labelView.bind('id').to(button, 'ariaLabelledBy', (ariaLabelledBy)=>{
|
|
324
|
+
return getFirstToken(ariaLabelledBy);
|
|
325
|
+
});
|
|
326
|
+
button.ariaLabelledBy = `${button.ariaLabelledBy} ${additionalLabel.id}`;
|
|
327
|
+
return button;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Creates a bookmark name preview label.
|
|
331
|
+
*
|
|
332
|
+
* @returns The label view instance.
|
|
333
|
+
*/ _createBookmarkPreviewView() {
|
|
334
|
+
const label = new LabelView(this.locale);
|
|
335
|
+
label.extendTemplate({
|
|
336
|
+
attributes: {
|
|
337
|
+
class: [
|
|
338
|
+
'ck',
|
|
339
|
+
'ck-bookmark-actions__preview'
|
|
340
|
+
]
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
// Bind label text with the bookmark ID.
|
|
344
|
+
label.bind('text').to(this, 'id');
|
|
345
|
+
return label;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Returns the first token from space separated token list.
|
|
350
|
+
*/ function getFirstToken(tokenList) {
|
|
351
|
+
return tokenList.split(' ')[0];
|
|
352
|
+
}
|
|
353
|
+
|
|
222
354
|
/**
|
|
223
355
|
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
224
356
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
@@ -416,19 +548,6 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
416
548
|
*/ static get isOfficialPlugin() {
|
|
417
549
|
return true;
|
|
418
550
|
}
|
|
419
|
-
/**
|
|
420
|
-
* @inheritDoc
|
|
421
|
-
*/ constructor(editor){
|
|
422
|
-
super(editor);
|
|
423
|
-
editor.config.define('bookmark', {
|
|
424
|
-
toolbar: [
|
|
425
|
-
'bookmarkPreview',
|
|
426
|
-
'|',
|
|
427
|
-
'editBookmark',
|
|
428
|
-
'removeBookmark'
|
|
429
|
-
]
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
551
|
/**
|
|
433
552
|
* @inheritDoc
|
|
434
553
|
*/ init() {
|
|
@@ -451,11 +570,6 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
451
570
|
}
|
|
452
571
|
return null;
|
|
453
572
|
}
|
|
454
|
-
/**
|
|
455
|
-
* Returns all unique bookmark names existing in the content.
|
|
456
|
-
*/ getAllBookmarkNames() {
|
|
457
|
-
return new Set(this._bookmarkElements.values());
|
|
458
|
-
}
|
|
459
573
|
/**
|
|
460
574
|
* Defines the schema for the bookmark feature.
|
|
461
575
|
*/ _defineSchema() {
|
|
@@ -508,7 +622,6 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
508
622
|
}, [
|
|
509
623
|
this._createBookmarkUIElement(writer)
|
|
510
624
|
]);
|
|
511
|
-
writer.setCustomProperty('bookmark', true, containerElement);
|
|
512
625
|
this._bookmarkElements.set(modelElement, id);
|
|
513
626
|
// `getFillerOffset` is not needed to set here, because `toWidget` has already covered it.
|
|
514
627
|
const labelCreator = ()=>`${id} ${t('bookmark widget')}`;
|
|
@@ -528,7 +641,7 @@ import { IconPreviousArrow } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
|
528
641
|
const domElement = this.toDomElement(domDocument);
|
|
529
642
|
const icon = new IconView();
|
|
530
643
|
icon.set({
|
|
531
|
-
content:
|
|
644
|
+
content: icons.bookmarkInline,
|
|
532
645
|
isColorInherited: false
|
|
533
646
|
});
|
|
534
647
|
icon.render();
|
|
@@ -638,6 +751,9 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
638
751
|
* It registers the `'bookmark'` UI button in the editor's {@link module:ui/componentfactory~ComponentFactory component factory}
|
|
639
752
|
* which inserts the `bookmark` element upon selection.
|
|
640
753
|
*/ class BookmarkUI extends Plugin {
|
|
754
|
+
/**
|
|
755
|
+
* The actions view displayed inside of the balloon.
|
|
756
|
+
*/ actionsView = null;
|
|
641
757
|
/**
|
|
642
758
|
* The form view displayed inside the balloon.
|
|
643
759
|
*/ formView = null;
|
|
@@ -649,8 +765,7 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
649
765
|
*/ static get requires() {
|
|
650
766
|
return [
|
|
651
767
|
BookmarkEditing,
|
|
652
|
-
ContextualBalloon
|
|
653
|
-
WidgetToolbarRepository
|
|
768
|
+
ContextualBalloon
|
|
654
769
|
];
|
|
655
770
|
}
|
|
656
771
|
/**
|
|
@@ -667,13 +782,11 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
667
782
|
* @inheritDoc
|
|
668
783
|
*/ init() {
|
|
669
784
|
const editor = this.editor;
|
|
785
|
+
editor.editing.view.addObserver(ClickObserver);
|
|
670
786
|
this._balloon = editor.plugins.get(ContextualBalloon);
|
|
671
|
-
// Register the link provider in link plugin to display the link form.
|
|
672
|
-
if (editor.plugins.has('LinkUI')) {
|
|
673
|
-
this._registerLinkProvider();
|
|
674
|
-
}
|
|
675
787
|
// Create toolbar buttons.
|
|
676
|
-
this.
|
|
788
|
+
this._createToolbarBookmarkButton();
|
|
789
|
+
this._enableBalloonActivators();
|
|
677
790
|
// Renders a fake visual selection marker on an expanded selection.
|
|
678
791
|
editor.conversion.for('editingDowncast').markerToHighlight({
|
|
679
792
|
model: VISUAL_SELECTION_MARKER_NAME,
|
|
@@ -699,34 +812,6 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
699
812
|
}
|
|
700
813
|
});
|
|
701
814
|
}
|
|
702
|
-
/**
|
|
703
|
-
* @inheritDoc
|
|
704
|
-
*/ afterInit() {
|
|
705
|
-
const editor = this.editor;
|
|
706
|
-
const t = editor.locale.t;
|
|
707
|
-
const widgetToolbarRepository = this.editor.plugins.get(WidgetToolbarRepository);
|
|
708
|
-
const defaultPositions = BalloonPanelView.defaultPositions;
|
|
709
|
-
widgetToolbarRepository.register('bookmark', {
|
|
710
|
-
ariaLabel: t('Bookmark toolbar'),
|
|
711
|
-
items: editor.config.get('bookmark.toolbar'),
|
|
712
|
-
getRelatedElement: getSelectedBookmarkWidget,
|
|
713
|
-
// Override positions to the same list as for balloon panel default
|
|
714
|
-
// so widget toolbar will try to use same position as form view.
|
|
715
|
-
positions: [
|
|
716
|
-
defaultPositions.southArrowNorth,
|
|
717
|
-
defaultPositions.southArrowNorthMiddleWest,
|
|
718
|
-
defaultPositions.southArrowNorthMiddleEast,
|
|
719
|
-
defaultPositions.southArrowNorthWest,
|
|
720
|
-
defaultPositions.southArrowNorthEast,
|
|
721
|
-
defaultPositions.northArrowSouth,
|
|
722
|
-
defaultPositions.northArrowSouthMiddleWest,
|
|
723
|
-
defaultPositions.northArrowSouthMiddleEast,
|
|
724
|
-
defaultPositions.northArrowSouthWest,
|
|
725
|
-
defaultPositions.northArrowSouthEast,
|
|
726
|
-
defaultPositions.viewportStickyNorth
|
|
727
|
-
]
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
815
|
/**
|
|
731
816
|
* @inheritDoc
|
|
732
817
|
*/ destroy() {
|
|
@@ -735,20 +820,49 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
735
820
|
if (this.formView) {
|
|
736
821
|
this.formView.destroy();
|
|
737
822
|
}
|
|
823
|
+
if (this.actionsView) {
|
|
824
|
+
this.actionsView.destroy();
|
|
825
|
+
}
|
|
738
826
|
}
|
|
739
827
|
/**
|
|
740
828
|
* Creates views.
|
|
741
829
|
*/ _createViews() {
|
|
830
|
+
this.actionsView = this._createActionsView();
|
|
742
831
|
this.formView = this._createFormView();
|
|
743
832
|
// Attach lifecycle actions to the the balloon.
|
|
744
833
|
this._enableUserBalloonInteractions();
|
|
745
834
|
}
|
|
835
|
+
/**
|
|
836
|
+
* Creates the {@link module:bookmark/ui/bookmarkactionsview~BookmarkActionsView} instance.
|
|
837
|
+
*/ _createActionsView() {
|
|
838
|
+
const editor = this.editor;
|
|
839
|
+
const actionsView = new BookmarkActionsView(editor.locale);
|
|
840
|
+
const updateBookmarkCommand = editor.commands.get('updateBookmark');
|
|
841
|
+
const deleteCommand = editor.commands.get('delete');
|
|
842
|
+
actionsView.bind('id').to(updateBookmarkCommand, 'value');
|
|
843
|
+
actionsView.editButtonView.bind('isEnabled').to(updateBookmarkCommand);
|
|
844
|
+
actionsView.removeButtonView.bind('isEnabled').to(deleteCommand);
|
|
845
|
+
// Display edit form view after clicking on the "Edit" button.
|
|
846
|
+
this.listenTo(actionsView, 'edit', ()=>{
|
|
847
|
+
this._addFormView();
|
|
848
|
+
});
|
|
849
|
+
// Execute remove command after clicking on the "Remove" button.
|
|
850
|
+
this.listenTo(actionsView, 'remove', ()=>{
|
|
851
|
+
this._hideUI();
|
|
852
|
+
editor.execute('delete');
|
|
853
|
+
});
|
|
854
|
+
// Close the panel on esc key press when the **actions have focus**.
|
|
855
|
+
actionsView.keystrokes.set('Esc', (data, cancel)=>{
|
|
856
|
+
this._hideUI();
|
|
857
|
+
cancel();
|
|
858
|
+
});
|
|
859
|
+
return actionsView;
|
|
860
|
+
}
|
|
746
861
|
/**
|
|
747
862
|
* Creates the {@link module:bookmark/ui/bookmarkformview~BookmarkFormView} instance.
|
|
748
863
|
*/ _createFormView() {
|
|
749
864
|
const editor = this.editor;
|
|
750
865
|
const locale = editor.locale;
|
|
751
|
-
const t = locale.t;
|
|
752
866
|
const insertBookmarkCommand = editor.commands.get('insertBookmark');
|
|
753
867
|
const updateBookmarkCommand = editor.commands.get('updateBookmark');
|
|
754
868
|
const commands = [
|
|
@@ -757,15 +871,10 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
757
871
|
];
|
|
758
872
|
const formView = new (CssTransitionDisablerMixin(BookmarkFormView))(locale, getFormValidators(editor));
|
|
759
873
|
formView.idInputView.fieldView.bind('value').to(updateBookmarkCommand, 'value');
|
|
760
|
-
formView.saveButtonView.bind('label').to(updateBookmarkCommand, 'value', (value)=>value ? t('Save') : t('Insert'));
|
|
761
874
|
// Form elements should be read-only when corresponding commands are disabled.
|
|
762
875
|
formView.idInputView.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isEnabled)=>isEnabled));
|
|
763
876
|
// Disable the "save" button if the command is disabled.
|
|
764
|
-
formView.
|
|
765
|
-
// Close the panel on form after clicking back button.
|
|
766
|
-
this.listenTo(formView, 'cancel', ()=>{
|
|
767
|
-
this._hideFormView();
|
|
768
|
-
});
|
|
877
|
+
formView.buttonView.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isEnabled)=>isEnabled));
|
|
769
878
|
// Execute link command after clicking the "Save" button.
|
|
770
879
|
this.listenTo(formView, 'submit', ()=>{
|
|
771
880
|
if (formView.isValid()) {
|
|
@@ -779,131 +888,39 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
779
888
|
bookmarkId: value
|
|
780
889
|
});
|
|
781
890
|
}
|
|
782
|
-
this.
|
|
891
|
+
this._closeFormView();
|
|
783
892
|
}
|
|
784
893
|
});
|
|
785
894
|
// Update balloon position when form error changes.
|
|
786
895
|
this.listenTo(formView.idInputView, 'change:errorText', ()=>{
|
|
787
896
|
editor.ui.update();
|
|
788
897
|
});
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
* the list of the bookmarks from the link form.
|
|
794
|
-
*/ _registerLinkProvider() {
|
|
795
|
-
const t = this.editor.locale.t;
|
|
796
|
-
const linksUI = this.editor.plugins.get('LinkUI');
|
|
797
|
-
const bookmarkEditing = this.editor.plugins.get(BookmarkEditing);
|
|
798
|
-
const getListItems = ()=>Array.from(bookmarkEditing.getAllBookmarkNames()).sort((a, b)=>a.localeCompare(b)).map((bookmarkId)=>({
|
|
799
|
-
id: bookmarkId,
|
|
800
|
-
href: `#${bookmarkId}`,
|
|
801
|
-
label: bookmarkId,
|
|
802
|
-
icon: IconBookmarkMedium
|
|
803
|
-
}));
|
|
804
|
-
const getItem = (href)=>{
|
|
805
|
-
const bookmark = [
|
|
806
|
-
...bookmarkEditing.getAllBookmarkNames()
|
|
807
|
-
].find((item)=>`#${item}` === href);
|
|
808
|
-
if (!bookmark) {
|
|
809
|
-
return null;
|
|
810
|
-
}
|
|
811
|
-
return {
|
|
812
|
-
href,
|
|
813
|
-
label: bookmark,
|
|
814
|
-
icon: IconBookmarkSmall,
|
|
815
|
-
tooltip: t('Scroll to bookmark')
|
|
816
|
-
};
|
|
817
|
-
};
|
|
818
|
-
linksUI.registerLinksListProvider({
|
|
819
|
-
label: t('Bookmarks'),
|
|
820
|
-
emptyListPlaceholder: t('No bookmarks available.'),
|
|
821
|
-
navigate: ({ href })=>this._scrollToBookmark(href),
|
|
822
|
-
getListItems,
|
|
823
|
-
getItem
|
|
824
|
-
});
|
|
825
|
-
}
|
|
826
|
-
/**
|
|
827
|
-
* Scrolls the editor to the bookmark with the given id.
|
|
828
|
-
*/ _scrollToBookmark(href) {
|
|
829
|
-
const bookmarkEditing = this.editor.plugins.get(BookmarkEditing);
|
|
830
|
-
const bookmarkElement = bookmarkEditing.getElementForBookmarkId(href.slice(1));
|
|
831
|
-
if (!bookmarkElement) {
|
|
832
|
-
return false;
|
|
833
|
-
}
|
|
834
|
-
this.editor.model.change((writer)=>{
|
|
835
|
-
writer.setSelection(bookmarkElement, 'on');
|
|
836
|
-
});
|
|
837
|
-
this.editor.editing.view.scrollToTheSelection({
|
|
838
|
-
alignToTop: true,
|
|
839
|
-
forceScroll: true
|
|
898
|
+
// Close the panel on esc key press when the **form has focus**.
|
|
899
|
+
formView.keystrokes.set('Esc', (data, cancel)=>{
|
|
900
|
+
this._closeFormView();
|
|
901
|
+
cancel();
|
|
840
902
|
});
|
|
841
|
-
return
|
|
903
|
+
return formView;
|
|
842
904
|
}
|
|
843
905
|
/**
|
|
844
906
|
* Creates a toolbar Bookmark button. Clicking this button will show
|
|
845
907
|
* a {@link #_balloon} attached to the selection.
|
|
846
|
-
*/
|
|
908
|
+
*/ _createToolbarBookmarkButton() {
|
|
847
909
|
const editor = this.editor;
|
|
848
910
|
editor.ui.componentFactory.add('bookmark', ()=>{
|
|
849
|
-
const buttonView = this.
|
|
911
|
+
const buttonView = this._createButton(ButtonView);
|
|
850
912
|
buttonView.set({
|
|
851
913
|
tooltip: true
|
|
852
914
|
});
|
|
853
915
|
return buttonView;
|
|
854
916
|
});
|
|
855
917
|
editor.ui.componentFactory.add('menuBar:bookmark', ()=>{
|
|
856
|
-
return this.
|
|
857
|
-
});
|
|
858
|
-
// Bookmark toolbar buttons.
|
|
859
|
-
editor.ui.componentFactory.add('bookmarkPreview', (locale)=>{
|
|
860
|
-
const updateBookmarkCommand = editor.commands.get('updateBookmark');
|
|
861
|
-
const label = new LabelView(locale);
|
|
862
|
-
label.extendTemplate({
|
|
863
|
-
attributes: {
|
|
864
|
-
class: [
|
|
865
|
-
'ck-bookmark-toolbar__preview'
|
|
866
|
-
]
|
|
867
|
-
}
|
|
868
|
-
});
|
|
869
|
-
label.bind('text').to(updateBookmarkCommand, 'value');
|
|
870
|
-
return label;
|
|
871
|
-
});
|
|
872
|
-
editor.ui.componentFactory.add('editBookmark', (locale)=>{
|
|
873
|
-
const updateBookmarkCommand = editor.commands.get('updateBookmark');
|
|
874
|
-
const button = new ButtonView(locale);
|
|
875
|
-
const t = locale.t;
|
|
876
|
-
button.set({
|
|
877
|
-
label: t('Edit bookmark'),
|
|
878
|
-
icon: IconPencil,
|
|
879
|
-
tooltip: true
|
|
880
|
-
});
|
|
881
|
-
button.bind('isEnabled').to(updateBookmarkCommand);
|
|
882
|
-
this.listenTo(button, 'execute', ()=>{
|
|
883
|
-
this._showFormView();
|
|
884
|
-
});
|
|
885
|
-
return button;
|
|
886
|
-
});
|
|
887
|
-
editor.ui.componentFactory.add('removeBookmark', (locale)=>{
|
|
888
|
-
const deleteCommand = editor.commands.get('delete');
|
|
889
|
-
const button = new ButtonView(locale);
|
|
890
|
-
const t = locale.t;
|
|
891
|
-
button.set({
|
|
892
|
-
label: t('Remove bookmark'),
|
|
893
|
-
icon: IconRemove,
|
|
894
|
-
tooltip: true
|
|
895
|
-
});
|
|
896
|
-
button.bind('isEnabled').to(deleteCommand);
|
|
897
|
-
this.listenTo(button, 'execute', ()=>{
|
|
898
|
-
editor.execute('delete');
|
|
899
|
-
editor.editing.view.focus();
|
|
900
|
-
});
|
|
901
|
-
return button;
|
|
918
|
+
return this._createButton(MenuBarMenuListItemButtonView);
|
|
902
919
|
});
|
|
903
920
|
}
|
|
904
921
|
/**
|
|
905
922
|
* Creates a button for `bookmark` command to use either in toolbar or in menu bar.
|
|
906
|
-
*/
|
|
923
|
+
*/ _createButton(ButtonClass) {
|
|
907
924
|
const editor = this.editor;
|
|
908
925
|
const locale = editor.locale;
|
|
909
926
|
const view = new ButtonClass(locale);
|
|
@@ -912,10 +929,10 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
912
929
|
const t = locale.t;
|
|
913
930
|
view.set({
|
|
914
931
|
label: t('Bookmark'),
|
|
915
|
-
icon:
|
|
932
|
+
icon: icons.bookmark
|
|
916
933
|
});
|
|
917
934
|
// Execute the command.
|
|
918
|
-
this.listenTo(view, 'execute', ()=>this.
|
|
935
|
+
this.listenTo(view, 'execute', ()=>this._showUI(true));
|
|
919
936
|
view.bind('isEnabled').toMany([
|
|
920
937
|
insertCommand,
|
|
921
938
|
updateCommand
|
|
@@ -923,25 +940,75 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
923
940
|
view.bind('isOn').to(updateCommand, 'value', (value)=>!!value);
|
|
924
941
|
return view;
|
|
925
942
|
}
|
|
943
|
+
/**
|
|
944
|
+
* Attaches actions that control whether the balloon panel containing the
|
|
945
|
+
* {@link #formView} should be displayed.
|
|
946
|
+
*/ _enableBalloonActivators() {
|
|
947
|
+
const editor = this.editor;
|
|
948
|
+
const viewDocument = editor.editing.view.document;
|
|
949
|
+
// Handle click on view document and show panel when selection is placed inside the bookmark element.
|
|
950
|
+
// Keep panel open until selection will be inside the same bookmark element.
|
|
951
|
+
this.listenTo(viewDocument, 'click', ()=>{
|
|
952
|
+
const bookmark = this._getSelectedBookmarkElement();
|
|
953
|
+
if (bookmark) {
|
|
954
|
+
// Then show panel but keep focus inside editor editable.
|
|
955
|
+
this._showUI();
|
|
956
|
+
}
|
|
957
|
+
});
|
|
958
|
+
}
|
|
926
959
|
/**
|
|
927
960
|
* Attaches actions that control whether the balloon panel containing the
|
|
928
961
|
* {@link #formView} is visible or not.
|
|
929
962
|
*/ _enableUserBalloonInteractions() {
|
|
963
|
+
// Focus the form if the balloon is visible and the Tab key has been pressed.
|
|
964
|
+
this.editor.keystrokes.set('Tab', (data, cancel)=>{
|
|
965
|
+
if (this._areActionsVisible && !this.actionsView.focusTracker.isFocused) {
|
|
966
|
+
this.actionsView.focus();
|
|
967
|
+
cancel();
|
|
968
|
+
}
|
|
969
|
+
}, {
|
|
970
|
+
// Use the high priority because the bookmark UI navigation is more important
|
|
971
|
+
// than other feature's actions, e.g. list indentation.
|
|
972
|
+
priority: 'high'
|
|
973
|
+
});
|
|
930
974
|
// Close the panel on the Esc key press when the editable has focus and the balloon is visible.
|
|
931
975
|
this.editor.keystrokes.set('Esc', (data, cancel)=>{
|
|
932
|
-
if (this.
|
|
933
|
-
this.
|
|
976
|
+
if (this._isUIVisible) {
|
|
977
|
+
this._hideUI();
|
|
934
978
|
cancel();
|
|
935
979
|
}
|
|
936
980
|
});
|
|
937
981
|
// Close on click outside of balloon panel element.
|
|
938
982
|
clickOutsideHandler({
|
|
939
983
|
emitter: this.formView,
|
|
940
|
-
activator: ()=>this.
|
|
984
|
+
activator: ()=>this._isUIInPanel,
|
|
941
985
|
contextElements: ()=>[
|
|
942
986
|
this._balloon.view.element
|
|
943
987
|
],
|
|
944
|
-
callback: ()=>this.
|
|
988
|
+
callback: ()=>this._hideUI()
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* Updates the button label. If bookmark is selected label is set to 'Update' otherwise
|
|
993
|
+
* it is 'Insert'.
|
|
994
|
+
*/ _updateFormButtonLabel(isBookmarkSelected) {
|
|
995
|
+
const t = this.editor.locale.t;
|
|
996
|
+
this.formView.buttonView.label = isBookmarkSelected ? t('Update') : t('Insert');
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Adds the {@link #actionsView} to the {@link #_balloon}.
|
|
1000
|
+
*
|
|
1001
|
+
* @internal
|
|
1002
|
+
*/ _addActionsView() {
|
|
1003
|
+
if (!this.actionsView) {
|
|
1004
|
+
this._createViews();
|
|
1005
|
+
}
|
|
1006
|
+
if (this._areActionsInPanel) {
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
this._balloon.add({
|
|
1010
|
+
view: this.actionsView,
|
|
1011
|
+
position: this._getBalloonPositionData()
|
|
945
1012
|
});
|
|
946
1013
|
}
|
|
947
1014
|
/**
|
|
@@ -953,14 +1020,14 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
953
1020
|
if (this._isFormInPanel) {
|
|
954
1021
|
return;
|
|
955
1022
|
}
|
|
956
|
-
const
|
|
1023
|
+
const editor = this.editor;
|
|
1024
|
+
const updateBookmarkCommand = editor.commands.get('updateBookmark');
|
|
957
1025
|
this.formView.disableCssTransitions();
|
|
958
1026
|
this.formView.resetFormStatus();
|
|
959
1027
|
this._balloon.add({
|
|
960
1028
|
view: this.formView,
|
|
961
1029
|
position: this._getBalloonPositionData()
|
|
962
1030
|
});
|
|
963
|
-
this.formView.backButtonView.isVisible = updateBookmarkCommand.isEnabled;
|
|
964
1031
|
this.formView.idInputView.fieldView.value = updateBookmarkCommand.value || '';
|
|
965
1032
|
// Select input when form view is currently visible.
|
|
966
1033
|
if (this._balloon.visibleView === this.formView) {
|
|
@@ -968,39 +1035,69 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
968
1035
|
}
|
|
969
1036
|
this.formView.enableCssTransitions();
|
|
970
1037
|
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Closes the form view. Decides whether the balloon should be hidden completely.
|
|
1040
|
+
*/ _closeFormView() {
|
|
1041
|
+
const updateBookmarkCommand = this.editor.commands.get('updateBookmark');
|
|
1042
|
+
if (updateBookmarkCommand.value !== undefined) {
|
|
1043
|
+
this._removeFormView();
|
|
1044
|
+
} else {
|
|
1045
|
+
this._hideUI();
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
971
1048
|
/**
|
|
972
1049
|
* Removes the {@link #formView} from the {@link #_balloon}.
|
|
973
1050
|
*/ _removeFormView() {
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1051
|
+
if (this._isFormInPanel) {
|
|
1052
|
+
// Blur the input element before removing it from DOM to prevent issues in some browsers.
|
|
1053
|
+
// See https://github.com/ckeditor/ckeditor5/issues/1501.
|
|
1054
|
+
this.formView.buttonView.focus();
|
|
1055
|
+
// Reset the ID field to update the state of the submit button.
|
|
1056
|
+
this.formView.idInputView.fieldView.reset();
|
|
1057
|
+
this._balloon.remove(this.formView);
|
|
1058
|
+
// Because the form has an input which has focus, the focus must be brought back
|
|
1059
|
+
// to the editor. Otherwise, it would be lost.
|
|
1060
|
+
this.editor.editing.view.focus();
|
|
1061
|
+
this._hideFakeVisualSelection();
|
|
1062
|
+
}
|
|
984
1063
|
}
|
|
985
1064
|
/**
|
|
986
|
-
* Shows the {@link #formView}.
|
|
987
|
-
*/
|
|
1065
|
+
* Shows the correct UI type. It is either {@link #formView} or {@link #actionsView}.
|
|
1066
|
+
*/ _showUI(forceVisible = false) {
|
|
988
1067
|
if (!this.formView) {
|
|
989
1068
|
this._createViews();
|
|
990
1069
|
}
|
|
1070
|
+
// When there's no bookmark under the selection, go straight to the editing UI.
|
|
991
1071
|
if (!this._getSelectedBookmarkElement()) {
|
|
1072
|
+
// Show visual selection on a text without a bookmark when the contextual balloon is displayed.
|
|
992
1073
|
this._showFakeVisualSelection();
|
|
1074
|
+
this._addActionsView();
|
|
1075
|
+
// Be sure panel with bookmark is visible.
|
|
1076
|
+
if (forceVisible) {
|
|
1077
|
+
this._balloon.showStack('main');
|
|
1078
|
+
}
|
|
1079
|
+
this._addFormView();
|
|
1080
|
+
} else {
|
|
1081
|
+
// Go to the editing UI if actions are already visible.
|
|
1082
|
+
if (this._areActionsVisible) {
|
|
1083
|
+
this._addFormView();
|
|
1084
|
+
} else {
|
|
1085
|
+
this._addActionsView();
|
|
1086
|
+
}
|
|
1087
|
+
// Be sure panel with bookmark is visible.
|
|
1088
|
+
if (forceVisible) {
|
|
1089
|
+
this._balloon.showStack('main');
|
|
1090
|
+
}
|
|
993
1091
|
}
|
|
994
|
-
this._addFormView();
|
|
995
|
-
// Be sure panel with bookmark is visible.
|
|
996
|
-
this._balloon.showStack('main');
|
|
997
1092
|
// Begin responding to ui#update once the UI is added.
|
|
998
1093
|
this._startUpdatingUI();
|
|
999
1094
|
}
|
|
1000
1095
|
/**
|
|
1001
1096
|
* Removes the {@link #formView} from the {@link #_balloon}.
|
|
1002
|
-
|
|
1003
|
-
|
|
1097
|
+
*
|
|
1098
|
+
* See {@link #_addFormView}, {@link #_addActionsView}.
|
|
1099
|
+
*/ _hideUI() {
|
|
1100
|
+
if (!this._isUIInPanel) {
|
|
1004
1101
|
return;
|
|
1005
1102
|
}
|
|
1006
1103
|
const editor = this.editor;
|
|
@@ -1011,18 +1108,21 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
1011
1108
|
editor.editing.view.focus();
|
|
1012
1109
|
// Remove form first because it's on top of the stack.
|
|
1013
1110
|
this._removeFormView();
|
|
1111
|
+
// Then remove the actions view because it's beneath the form.
|
|
1112
|
+
this._balloon.remove(this.actionsView);
|
|
1014
1113
|
this._hideFakeVisualSelection();
|
|
1015
1114
|
}
|
|
1016
1115
|
/**
|
|
1017
1116
|
* Makes the UI react to the {@link module:ui/editorui/editorui~EditorUI#event:update} event to
|
|
1018
1117
|
* reposition itself when the editor UI should be refreshed.
|
|
1019
1118
|
*
|
|
1020
|
-
* See: {@link #
|
|
1119
|
+
* See: {@link #_hideUI} to learn when the UI stops reacting to the `update` event.
|
|
1021
1120
|
*/ _startUpdatingUI() {
|
|
1022
1121
|
const editor = this.editor;
|
|
1023
1122
|
const viewDocument = editor.editing.view.document;
|
|
1024
1123
|
let prevSelectedBookmark = this._getSelectedBookmarkElement();
|
|
1025
1124
|
let prevSelectionParent = getSelectionParent();
|
|
1125
|
+
this._updateFormButtonLabel(!!prevSelectedBookmark);
|
|
1026
1126
|
const update = ()=>{
|
|
1027
1127
|
const selectedBookmark = this._getSelectedBookmarkElement();
|
|
1028
1128
|
const selectionParent = getSelectionParent();
|
|
@@ -1035,13 +1135,14 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
1035
1135
|
// * the selection has expanded (e.g. displaying bookmark actions then pressing SHIFT+Right arrow).
|
|
1036
1136
|
//
|
|
1037
1137
|
if (prevSelectedBookmark && !selectedBookmark || !prevSelectedBookmark && selectionParent !== prevSelectionParent) {
|
|
1038
|
-
this.
|
|
1039
|
-
} else if (this.
|
|
1138
|
+
this._hideUI();
|
|
1139
|
+
} else if (this._isUIVisible) {
|
|
1040
1140
|
// If still in a bookmark element, simply update the position of the balloon.
|
|
1041
1141
|
// If there was no bookmark (e.g. inserting one), the balloon must be moved
|
|
1042
1142
|
// to the new position in the editing view (a new native DOM range).
|
|
1043
1143
|
this._balloon.updatePosition(this._getBalloonPositionData());
|
|
1044
1144
|
}
|
|
1145
|
+
this._updateFormButtonLabel(!!prevSelectedBookmark);
|
|
1045
1146
|
prevSelectedBookmark = selectedBookmark;
|
|
1046
1147
|
prevSelectionParent = selectionParent;
|
|
1047
1148
|
};
|
|
@@ -1057,9 +1158,27 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
1057
1158
|
return !!this.formView && this._balloon.hasView(this.formView);
|
|
1058
1159
|
}
|
|
1059
1160
|
/**
|
|
1060
|
-
* Returns `true` when {@link #
|
|
1061
|
-
*/ get
|
|
1062
|
-
return !!this.
|
|
1161
|
+
* Returns `true` when {@link #actionsView} is in the {@link #_balloon}.
|
|
1162
|
+
*/ get _areActionsInPanel() {
|
|
1163
|
+
return !!this.actionsView && this._balloon.hasView(this.actionsView);
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Returns `true` when {@link #actionsView} is in the {@link #_balloon} and it is
|
|
1167
|
+
* currently visible.
|
|
1168
|
+
*/ get _areActionsVisible() {
|
|
1169
|
+
return !!this.actionsView && this._balloon.visibleView === this.actionsView;
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* Returns `true` when {@link #actionsView} or {@link #formView} is in the {@link #_balloon}.
|
|
1173
|
+
*/ get _isUIInPanel() {
|
|
1174
|
+
return this._isFormInPanel || this._areActionsInPanel;
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Returns `true` when {@link #actionsView} or {@link #formView} is in the {@link #_balloon} and it is
|
|
1178
|
+
* currently visible.
|
|
1179
|
+
*/ get _isUIVisible() {
|
|
1180
|
+
const visibleView = this._balloon.visibleView;
|
|
1181
|
+
return !!this.formView && visibleView == this.formView || this._areActionsVisible;
|
|
1063
1182
|
}
|
|
1064
1183
|
/**
|
|
1065
1184
|
* Returns positioning options for the {@link #_balloon}. They control the way the balloon is attached
|
|
@@ -1082,10 +1201,7 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
1082
1201
|
return domConverter.mapViewToDom(viewElement);
|
|
1083
1202
|
};
|
|
1084
1203
|
}
|
|
1085
|
-
|
|
1086
|
-
return;
|
|
1087
|
-
}
|
|
1088
|
-
return {
|
|
1204
|
+
return target && {
|
|
1089
1205
|
target
|
|
1090
1206
|
};
|
|
1091
1207
|
}
|
|
@@ -1173,15 +1289,6 @@ const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
|
1173
1289
|
}
|
|
1174
1290
|
];
|
|
1175
1291
|
}
|
|
1176
|
-
/**
|
|
1177
|
-
* Returns the currently selected bookmark view element.
|
|
1178
|
-
*/ function getSelectedBookmarkWidget(selection) {
|
|
1179
|
-
const element = selection.getSelectedElement();
|
|
1180
|
-
if (!element || !isWidget(element) || !element.getCustomProperty('bookmark')) {
|
|
1181
|
-
return null;
|
|
1182
|
-
}
|
|
1183
|
-
return element;
|
|
1184
|
-
}
|
|
1185
1292
|
|
|
1186
1293
|
/**
|
|
1187
1294
|
* The bookmark feature.
|