@ckeditor/ckeditor5-special-characters 0.0.0-nightly-20240610.0 → 0.0.0-nightly-20240612.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 (70) hide show
  1. package/build/special-characters.js +2 -2
  2. package/build/translations/ar.js +1 -1
  3. package/build/translations/az.js +1 -1
  4. package/build/translations/bg.js +1 -1
  5. package/build/translations/bn.js +1 -1
  6. package/build/translations/ca.js +1 -1
  7. package/build/translations/cs.js +1 -1
  8. package/build/translations/da.js +1 -1
  9. package/build/translations/de.js +1 -1
  10. package/build/translations/el.js +1 -1
  11. package/build/translations/en-au.js +1 -1
  12. package/build/translations/es.js +1 -1
  13. package/build/translations/et.js +1 -1
  14. package/build/translations/fa.js +1 -1
  15. package/build/translations/fi.js +1 -1
  16. package/build/translations/fr.js +1 -1
  17. package/build/translations/gl.js +1 -1
  18. package/build/translations/he.js +1 -1
  19. package/build/translations/hi.js +1 -1
  20. package/build/translations/hr.js +1 -1
  21. package/build/translations/hu.js +1 -1
  22. package/build/translations/id.js +1 -1
  23. package/build/translations/it.js +1 -1
  24. package/build/translations/ja.js +1 -1
  25. package/build/translations/ko.js +1 -1
  26. package/build/translations/lt.js +1 -1
  27. package/build/translations/lv.js +1 -1
  28. package/build/translations/ms.js +1 -1
  29. package/build/translations/nl.js +1 -1
  30. package/build/translations/no.js +1 -1
  31. package/build/translations/pl.js +1 -1
  32. package/build/translations/pt-br.js +1 -1
  33. package/build/translations/pt.js +1 -1
  34. package/build/translations/ro.js +1 -1
  35. package/build/translations/ru.js +1 -1
  36. package/build/translations/sk.js +1 -1
  37. package/build/translations/sq.js +1 -1
  38. package/build/translations/sr-latn.js +1 -1
  39. package/build/translations/sr.js +1 -1
  40. package/build/translations/sv.js +1 -1
  41. package/build/translations/th.js +1 -1
  42. package/build/translations/ti.js +1 -1
  43. package/build/translations/tk.js +1 -1
  44. package/build/translations/tr.js +1 -1
  45. package/build/translations/uk.js +1 -1
  46. package/build/translations/ur.js +1 -1
  47. package/build/translations/uz.js +1 -1
  48. package/build/translations/vi.js +1 -1
  49. package/build/translations/zh-cn.js +1 -1
  50. package/build/translations/zh.js +1 -1
  51. package/dist/index-editor.css +55 -0
  52. package/dist/index.css +96 -0
  53. package/dist/index.css.map +1 -1
  54. package/dist/index.js +154 -137
  55. package/dist/index.js.map +1 -1
  56. package/dist/types/specialcharacters.d.ts +8 -2
  57. package/dist/types/ui/specialcharacterscategoriesview.d.ts +45 -0
  58. package/dist/types/ui/specialcharactersview.d.ts +4 -4
  59. package/lang/contexts.json +2 -2
  60. package/package.json +3 -2
  61. package/src/specialcharacters.d.ts +8 -2
  62. package/src/specialcharacters.js +60 -38
  63. package/src/ui/specialcharacterscategoriesview.d.ts +41 -0
  64. package/src/ui/specialcharacterscategoriesview.js +93 -0
  65. package/src/ui/specialcharactersview.d.ts +4 -4
  66. package/src/ui/specialcharactersview.js +6 -6
  67. package/theme/specialcharacters.css +81 -0
  68. package/dist/types/ui/specialcharactersnavigationview.d.ts +0 -63
  69. package/src/ui/specialcharactersnavigationview.d.ts +0 -59
  70. package/src/ui/specialcharactersnavigationview.js +0 -95
package/dist/index.js CHANGED
@@ -4,97 +4,8 @@
4
4
  */
5
5
  import { Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
6
6
  import { Typing } from '@ckeditor/ckeditor5-typing/dist/index.js';
7
- import { FormHeaderView, createDropdown, addListToDropdown, ViewModel, View, addKeyboardHandlingForGrid, ButtonView, FocusCycler } from '@ckeditor/ckeditor5-ui/dist/index.js';
8
- import { Collection, FocusTracker, KeystrokeHandler, global, CKEditorError } from '@ckeditor/ckeditor5-utils/dist/index.js';
9
-
10
- /**
11
- * A class representing the navigation part of the special characters UI. It is responsible
12
- * for describing the feature and allowing the user to select a particular character group.
13
- */ class SpecialCharactersNavigationView extends FormHeaderView {
14
- /**
15
- * A dropdown that allows selecting a group of special characters to be displayed.
16
- */ groupDropdownView;
17
- /**
18
- * Creates an instance of the {@link module:special-characters/ui/specialcharactersnavigationview~SpecialCharactersNavigationView}
19
- * class.
20
- *
21
- * @param locale The localization services instance.
22
- * @param groupNames The names of the character groups and their displayed labels.
23
- */ constructor(locale, groupNames){
24
- super(locale);
25
- const t = locale.t;
26
- this.set('class', 'ck-special-characters-navigation');
27
- this.groupDropdownView = this._createGroupDropdown(groupNames);
28
- this.groupDropdownView.panelPosition = locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw';
29
- this.label = t('Special characters');
30
- this.children.add(this.groupDropdownView);
31
- }
32
- /**
33
- * Returns the name of the character group currently selected in the {@link #groupDropdownView}.
34
- */ get currentGroupName() {
35
- return this.groupDropdownView.value;
36
- }
37
- /**
38
- * Focuses the character categories dropdown.
39
- */ focus() {
40
- this.groupDropdownView.focus();
41
- }
42
- /**
43
- * Returns a dropdown that allows selecting character groups.
44
- *
45
- * @param groupNames The names of the character groups and their displayed labels.
46
- */ _createGroupDropdown(groupNames) {
47
- const locale = this.locale;
48
- const t = locale.t;
49
- const dropdown = createDropdown(locale);
50
- const groupDefinitions = this._getCharacterGroupListItemDefinitions(dropdown, groupNames);
51
- const accessibleLabel = t('Character categories');
52
- dropdown.set('value', groupDefinitions.first.model.name);
53
- dropdown.buttonView.bind('label').to(dropdown, 'value', (value)=>groupNames.get(value));
54
- dropdown.buttonView.set({
55
- isOn: false,
56
- withText: true,
57
- tooltip: accessibleLabel,
58
- class: [
59
- 'ck-dropdown__button_label-width_auto'
60
- ],
61
- ariaLabel: accessibleLabel,
62
- ariaLabelledBy: undefined
63
- });
64
- dropdown.on('execute', (evt)=>{
65
- dropdown.value = evt.source.name;
66
- });
67
- dropdown.delegate('execute').to(this);
68
- addListToDropdown(dropdown, groupDefinitions, {
69
- ariaLabel: accessibleLabel,
70
- role: 'menu'
71
- });
72
- return dropdown;
73
- }
74
- /**
75
- * Returns list item definitions to be used in the character group dropdown
76
- * representing specific character groups.
77
- *
78
- * @param dropdown Dropdown view element
79
- * @param groupNames The names of the character groups and their displayed labels.
80
- */ _getCharacterGroupListItemDefinitions(dropdown, groupNames) {
81
- const groupDefs = new Collection();
82
- for (const [name, label] of groupNames){
83
- const model = new ViewModel({
84
- name,
85
- label,
86
- withText: true,
87
- role: 'menuitemradio'
88
- });
89
- model.bind('isOn').to(dropdown, 'value', (value)=>value === model.name);
90
- groupDefs.add({
91
- type: 'button',
92
- model
93
- });
94
- }
95
- return groupDefs;
96
- }
97
- }
7
+ import { View, addKeyboardHandlingForGrid, ButtonView, FocusCycler, LabeledFieldView, createLabeledDropdown, ViewModel, addListToDropdown, Dialog, MenuBarMenuListItemButtonView, DialogViewPosition } from '@ckeditor/ckeditor5-ui/dist/index.js';
8
+ import { FocusTracker, KeystrokeHandler, global, Collection, CKEditorError } from '@ckeditor/ckeditor5-utils/dist/index.js';
98
9
 
99
10
  /**
100
11
  * A grid of character tiles. It allows browsing special characters and selecting the character to
@@ -309,8 +220,8 @@ import { Collection, FocusTracker, KeystrokeHandler, global, CKEditorError } fro
309
220
  * Helps cycling over focusable {@link #items} in the view.
310
221
  */ _focusCycler;
311
222
  /**
312
- * An instance of the `SpecialCharactersNavigationView`.
313
- */ navigationView;
223
+ * An instance of the `SpecialCharactersCategoriesView`.
224
+ */ categoriesView;
314
225
  /**
315
226
  * An instance of the `CharacterGridView`.
316
227
  */ gridView;
@@ -319,9 +230,9 @@ import { Collection, FocusTracker, KeystrokeHandler, global, CKEditorError } fro
319
230
  */ infoView;
320
231
  /**
321
232
  * Creates an instance of the `SpecialCharactersView`.
322
- */ constructor(locale, navigationView, gridView, infoView){
233
+ */ constructor(locale, categoriesView, gridView, infoView){
323
234
  super(locale);
324
- this.navigationView = navigationView;
235
+ this.categoriesView = categoriesView;
325
236
  this.gridView = gridView;
326
237
  this.infoView = infoView;
327
238
  this.items = this.createCollection();
@@ -339,7 +250,7 @@ import { Collection, FocusTracker, KeystrokeHandler, global, CKEditorError } fro
339
250
  this.setTemplate({
340
251
  tag: 'div',
341
252
  children: [
342
- this.navigationView,
253
+ this.categoriesView,
343
254
  this.gridView,
344
255
  this.infoView
345
256
  ],
@@ -349,14 +260,14 @@ import { Collection, FocusTracker, KeystrokeHandler, global, CKEditorError } fro
349
260
  tabindex: '-1'
350
261
  }
351
262
  });
352
- this.items.add(this.navigationView.groupDropdownView.buttonView);
263
+ this.items.add(this.categoriesView);
353
264
  this.items.add(this.gridView);
354
265
  }
355
266
  /**
356
267
  * @inheritDoc
357
268
  */ render() {
358
269
  super.render();
359
- this.focusTracker.add(this.navigationView.groupDropdownView.buttonView.element);
270
+ this.focusTracker.add(this.categoriesView.element);
360
271
  this.focusTracker.add(this.gridView.element);
361
272
  // Start listening for the keystrokes coming from #element.
362
273
  this.keystrokes.listenTo(this.element);
@@ -371,12 +282,96 @@ import { Collection, FocusTracker, KeystrokeHandler, global, CKEditorError } fro
371
282
  /**
372
283
  * Focuses the first focusable in {@link #items}.
373
284
  */ focus() {
374
- this.navigationView.focus();
285
+ this._focusCycler.focusFirst();
375
286
  }
376
287
  }
377
288
 
378
289
  var specialCharactersIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 2.5a7.47 7.47 0 0 1 4.231 1.31 7.268 7.268 0 0 1 2.703 3.454 7.128 7.128 0 0 1 .199 4.353c-.39 1.436-1.475 2.72-2.633 3.677h2.013c0-.226.092-.443.254-.603a.876.876 0 0 1 1.229 0c.163.16.254.377.254.603v.853c0 .209-.078.41-.22.567a.873.873 0 0 1-.547.28l-.101.006h-4.695a.517.517 0 0 1-.516-.518v-1.265c0-.21.128-.398.317-.489a5.601 5.601 0 0 0 2.492-2.371 5.459 5.459 0 0 0 .552-3.693 5.53 5.53 0 0 0-1.955-3.2A5.71 5.71 0 0 0 10 4.206 5.708 5.708 0 0 0 6.419 5.46 5.527 5.527 0 0 0 4.46 8.663a5.457 5.457 0 0 0 .554 3.695 5.6 5.6 0 0 0 2.497 2.37.55.55 0 0 1 .317.49v1.264c0 .286-.23.518-.516.518H2.618a.877.877 0 0 1-.614-.25.845.845 0 0 1-.254-.603v-.853c0-.226.091-.443.254-.603a.876.876 0 0 1 1.228 0c.163.16.255.377.255.603h1.925c-1.158-.958-2.155-2.241-2.545-3.678a7.128 7.128 0 0 1 .199-4.352 7.268 7.268 0 0 1 2.703-3.455A7.475 7.475 0 0 1 10 2.5z\"/></svg>";
379
290
 
291
+ /**
292
+ * A class representing the navigation part of the special characters UI. It is responsible
293
+ * for describing the feature and allowing the user to select a particular character group.
294
+ */ class SpecialCharactersCategoriesView extends View {
295
+ _groupNames;
296
+ _dropdownView;
297
+ /**
298
+ * Creates an instance of the {@link module:special-characters/ui/specialcharacterscategoriesview~SpecialCharactersCategoriesView}
299
+ * class.
300
+ *
301
+ * @param locale The localization services instance.
302
+ * @param groupNames The names of the character groups.
303
+ */ constructor(locale, groupNames){
304
+ super(locale);
305
+ this.set('currentGroupName', Array.from(groupNames.entries())[0][0]);
306
+ this._groupNames = groupNames;
307
+ this._dropdownView = new LabeledFieldView(locale, createLabeledDropdown);
308
+ this.setTemplate({
309
+ tag: 'div',
310
+ attributes: {
311
+ class: [
312
+ 'ck',
313
+ 'ck-character-categories'
314
+ ]
315
+ },
316
+ children: [
317
+ this._dropdownView
318
+ ]
319
+ });
320
+ }
321
+ /**
322
+ * @inheritDoc
323
+ */ render() {
324
+ super.render();
325
+ this._setupDropdown();
326
+ }
327
+ /**
328
+ * @inheritDoc
329
+ */ focus() {
330
+ this._dropdownView.focus();
331
+ }
332
+ /**
333
+ * Creates dropdown item list, sets up bindings and fills properties.
334
+ */ _setupDropdown() {
335
+ const items = new Collection();
336
+ for (const [name, label] of this._groupNames){
337
+ const item = {
338
+ type: 'button',
339
+ model: new ViewModel({
340
+ name,
341
+ label,
342
+ withText: true
343
+ })
344
+ };
345
+ item.model.bind('isOn').to(this, 'currentGroupName', (value)=>{
346
+ return value === name;
347
+ });
348
+ items.add(item);
349
+ }
350
+ const t = this.locale.t;
351
+ const accessibleLabel = t('Category');
352
+ this._dropdownView.set({
353
+ label: accessibleLabel,
354
+ isEmpty: false
355
+ });
356
+ this._dropdownView.fieldView.panelPosition = this.locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw';
357
+ this._dropdownView.fieldView.buttonView.set({
358
+ withText: true,
359
+ tooltip: accessibleLabel,
360
+ ariaLabel: accessibleLabel,
361
+ ariaLabelledBy: undefined,
362
+ isOn: false
363
+ });
364
+ this._dropdownView.fieldView.buttonView.bind('label').to(this, 'currentGroupName', (value)=>this._groupNames.get(value));
365
+ this._dropdownView.fieldView.on('execute', ({ source })=>{
366
+ this.currentGroupName = source.name;
367
+ });
368
+ addListToDropdown(this._dropdownView.fieldView, items, {
369
+ ariaLabel: accessibleLabel,
370
+ role: 'menu'
371
+ });
372
+ }
373
+ }
374
+
380
375
  const ALL_SPECIAL_CHARACTERS_GROUP = 'All';
381
376
  /**
382
377
  * The special characters feature.
@@ -396,7 +391,8 @@ const ALL_SPECIAL_CHARACTERS_GROUP = 'All';
396
391
  * @inheritDoc
397
392
  */ static get requires() {
398
393
  return [
399
- Typing
394
+ Typing,
395
+ Dialog
400
396
  ];
401
397
  }
402
398
  /**
@@ -417,37 +413,15 @@ const ALL_SPECIAL_CHARACTERS_GROUP = 'All';
417
413
  * @inheritDoc
418
414
  */ init() {
419
415
  const editor = this.editor;
420
- const t = editor.t;
421
- const inputCommand = editor.commands.get('insertText');
422
- // Add the `specialCharacters` dropdown button to feature components.
423
- editor.ui.componentFactory.add('specialCharacters', (locale)=>{
424
- const dropdownView = createDropdown(locale);
425
- let dropdownPanelContent;
426
- dropdownView.buttonView.set({
427
- label: t('Special characters'),
428
- icon: specialCharactersIcon,
416
+ editor.ui.componentFactory.add('specialCharacters', ()=>{
417
+ const button = this._createDialogButton(ButtonView);
418
+ button.set({
429
419
  tooltip: true
430
420
  });
431
- dropdownView.bind('isEnabled').to(inputCommand);
432
- // Insert a special character when a tile was clicked.
433
- dropdownView.on('execute', (evt, data)=>{
434
- editor.execute('insertText', {
435
- text: data.character
436
- });
437
- editor.editing.view.focus();
438
- });
439
- dropdownView.on('change:isOpen', ()=>{
440
- if (!dropdownPanelContent) {
441
- dropdownPanelContent = this._createDropdownPanelContent(locale, dropdownView);
442
- const specialCharactersView = new SpecialCharactersView(locale, dropdownPanelContent.navigationView, dropdownPanelContent.gridView, dropdownPanelContent.infoView);
443
- dropdownView.panelView.children.add(specialCharactersView);
444
- }
445
- dropdownPanelContent.infoView.set({
446
- character: null,
447
- name: null
448
- });
449
- });
450
- return dropdownView;
421
+ return button;
422
+ });
423
+ editor.ui.componentFactory.add('menuBar:specialCharacters', ()=>{
424
+ return this._createDialogButton(MenuBarMenuListItemButtonView);
451
425
  });
452
426
  }
453
427
  /**
@@ -539,8 +513,8 @@ const ALL_SPECIAL_CHARACTERS_GROUP = 'All';
539
513
  /**
540
514
  * Initializes the dropdown, used for lazy loading.
541
515
  *
542
- * @returns An object with `navigationView`, `gridView` and `infoView` properties, containing UI parts.
543
- */ _createDropdownPanelContent(locale, dropdownView) {
516
+ * @returns An object with `categoriesView`, `gridView` and `infoView` properties, containing UI parts.
517
+ */ _createDropdownPanelContent(locale) {
544
518
  const groupEntries = Array.from(this.getGroups()).map((name)=>[
545
519
  name,
546
520
  this._groups.get(name).label
@@ -554,10 +528,9 @@ const ALL_SPECIAL_CHARACTERS_GROUP = 'All';
554
528
  ],
555
529
  ...groupEntries
556
530
  ]);
557
- const navigationView = new SpecialCharactersNavigationView(locale, specialCharsGroups);
531
+ const categoriesView = new SpecialCharactersCategoriesView(locale, specialCharsGroups);
558
532
  const gridView = new CharacterGridView(locale);
559
533
  const infoView = new CharacterInfoView(locale);
560
- gridView.delegate('execute').to(dropdownView);
561
534
  gridView.on('tileHover', (evt, data)=>{
562
535
  infoView.set(data);
563
536
  });
@@ -565,17 +538,61 @@ const ALL_SPECIAL_CHARACTERS_GROUP = 'All';
565
538
  infoView.set(data);
566
539
  });
567
540
  // Update the grid of special characters when a user changed the character group.
568
- navigationView.on('execute', ()=>{
569
- this._updateGrid(navigationView.currentGroupName, gridView);
541
+ categoriesView.on('change:currentGroupName', (evt, propertyName, newValue)=>{
542
+ this._updateGrid(newValue, gridView);
570
543
  });
571
544
  // Set the initial content of the special characters grid.
572
- this._updateGrid(navigationView.currentGroupName, gridView);
545
+ this._updateGrid(categoriesView.currentGroupName, gridView);
573
546
  return {
574
- navigationView,
547
+ categoriesView,
575
548
  gridView,
576
549
  infoView
577
550
  };
578
551
  }
552
+ /**
553
+ * Creates a button for for menu bar that will show special characetrs dialog.
554
+ */ _createDialogButton(ButtonClass) {
555
+ const editor = this.editor;
556
+ const locale = editor.locale;
557
+ const buttonView = new ButtonClass(editor.locale);
558
+ const command = editor.commands.get('insertText');
559
+ const t = locale.t;
560
+ const dialogPlugin = this.editor.plugins.get('Dialog');
561
+ buttonView.set({
562
+ label: t('Special characters'),
563
+ icon: specialCharactersIcon
564
+ });
565
+ buttonView.bind('isOn').to(dialogPlugin, 'id', (id)=>id === 'specialCharacters');
566
+ buttonView.bind('isEnabled').to(command, 'isEnabled');
567
+ buttonView.on('execute', ()=>{
568
+ if (dialogPlugin.id === 'specialCharacters') {
569
+ dialogPlugin.hide();
570
+ return;
571
+ }
572
+ this._showDialog();
573
+ });
574
+ return buttonView;
575
+ }
576
+ _showDialog() {
577
+ const editor = this.editor;
578
+ const dialog = editor.plugins.get('Dialog');
579
+ const locale = editor.locale;
580
+ const t = locale.t;
581
+ const { categoriesView, gridView, infoView } = this._createDropdownPanelContent(locale);
582
+ const content = new SpecialCharactersView(locale, categoriesView, gridView, infoView);
583
+ gridView.on('execute', (evt, data)=>{
584
+ editor.execute('insertText', {
585
+ text: data.character
586
+ });
587
+ });
588
+ dialog.show({
589
+ id: 'specialCharacters',
590
+ title: t('Special characters'),
591
+ className: 'ck-special-characters',
592
+ content,
593
+ position: DialogViewPosition.EDITOR_TOP_SIDE
594
+ });
595
+ }
579
596
  }
580
597
 
581
598
  /**