@ckeditor/ckeditor5-ckbox 0.0.0-nightly-20240602.0 → 0.0.0-nightly-20240604.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/dist/index.js CHANGED
@@ -5,123 +5,76 @@
5
5
  import { Plugin, icons, Command, PendingActions } from '@ckeditor/ckeditor5-core/dist/index.js';
6
6
  import { ButtonView, MenuBarMenuListItemButtonView, Notification } from '@ckeditor/ckeditor5-ui/dist/index.js';
7
7
  import { Range } from '@ckeditor/ckeditor5-engine/dist/index.js';
8
- import { createElement, toMap, CKEditorError, logError, global, delay, abortableDebounce, retry } from '@ckeditor/ckeditor5-utils/dist/index.js';
8
+ import { createElement, toMap, CKEditorError, logError, global, retry, abortableDebounce } from '@ckeditor/ckeditor5-utils/dist/index.js';
9
9
  import { decode } from 'blurhash';
10
10
  import { FileRepository } from '@ckeditor/ckeditor5-upload/dist/index.js';
11
11
  import { isEqual } from 'lodash-es';
12
12
 
13
- /**
14
- * Introduces UI components for the `CKBox` plugin.
15
- *
16
- * The plugin introduces two UI components to the {@link module:ui/componentfactory~ComponentFactory UI component factory}:
17
- *
18
- * * the `'ckbox'` toolbar button,
19
- * * the `'menuBar:ckbox'` menu bar component, which is by default added to the `'Insert'` menu.
20
- *
21
- * It also integrates with the `insertImage` toolbar component and `menuBar:insertImage` menu component.
22
- */ class CKBoxUI extends Plugin {
13
+ class CKBoxUI extends Plugin {
23
14
  /**
24
- * @inheritDoc
25
- */ static get pluginName() {
15
+ * @inheritDoc
16
+ */ static get pluginName() {
26
17
  return 'CKBoxUI';
27
18
  }
28
19
  /**
29
- * @inheritDoc
30
- */ afterInit() {
20
+ * @inheritDoc
21
+ */ afterInit() {
31
22
  const editor = this.editor;
32
23
  // Do not register the `ckbox` button if the command does not exist.
33
24
  // This might happen when CKBox library is not loaded on the page.
34
25
  if (!editor.commands.get('ckbox')) {
35
26
  return;
36
27
  }
37
- editor.ui.componentFactory.add('ckbox', ()=>this._createFileToolbarButton());
38
- editor.ui.componentFactory.add('menuBar:ckbox', ()=>this._createFileMenuBarButton());
28
+ const t = editor.t;
29
+ const componentFactory = editor.ui.componentFactory;
30
+ componentFactory.add('ckbox', ()=>{
31
+ const button = this._createButton(ButtonView);
32
+ button.tooltip = true;
33
+ return button;
34
+ });
35
+ componentFactory.add('menuBar:ckbox', ()=>this._createButton(MenuBarMenuListItemButtonView));
39
36
  if (editor.plugins.has('ImageInsertUI')) {
40
- editor.plugins.get('ImageInsertUI').registerIntegration({
37
+ const imageInsertUI = editor.plugins.get('ImageInsertUI');
38
+ imageInsertUI.registerIntegration({
41
39
  name: 'assetManager',
42
40
  observable: ()=>editor.commands.get('ckbox'),
43
- buttonViewCreator: ()=>this._createImageToolbarButton(),
44
- formViewCreator: ()=>this._createImageDropdownButton(),
45
- menuBarButtonViewCreator: (isOnly)=>this._createImageMenuBarButton(isOnly ? 'insertOnly' : 'insertNested')
41
+ buttonViewCreator: ()=>{
42
+ const button = this.editor.ui.componentFactory.create('ckbox');
43
+ button.icon = icons.imageAssetManager;
44
+ button.bind('label').to(imageInsertUI, 'isImageSelected', (isImageSelected)=>isImageSelected ? t('Replace image with file manager') : t('Insert image with file manager'));
45
+ return button;
46
+ },
47
+ formViewCreator: ()=>{
48
+ const button = this.editor.ui.componentFactory.create('ckbox');
49
+ button.icon = icons.imageAssetManager;
50
+ button.withText = true;
51
+ button.bind('label').to(imageInsertUI, 'isImageSelected', (isImageSelected)=>isImageSelected ? t('Replace with file manager') : t('Insert with file manager'));
52
+ button.on('execute', ()=>{
53
+ imageInsertUI.dropdownView.isOpen = false;
54
+ });
55
+ return button;
56
+ }
46
57
  });
47
58
  }
48
59
  }
49
60
  /**
50
- * Creates the base for various kinds of the button component provided by this feature.
51
- */ _createButton(ButtonClass) {
61
+ * Creates a button for CKBox command to use either in toolbar or in menu bar.
62
+ */ _createButton(ButtonClass) {
52
63
  const editor = this.editor;
53
64
  const locale = editor.locale;
54
65
  const view = new ButtonClass(locale);
55
66
  const command = editor.commands.get('ckbox');
56
- locale.t;
67
+ const t = locale.t;
68
+ view.set({
69
+ label: t('Open file manager'),
70
+ icon: icons.browseFiles
71
+ });
57
72
  view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');
58
73
  view.on('execute', ()=>{
59
74
  editor.execute('ckbox');
60
75
  });
61
76
  return view;
62
77
  }
63
- /**
64
- * Creates a simple toolbar button for files management, with an icon and a tooltip.
65
- */ _createFileToolbarButton() {
66
- const t = this.editor.locale.t;
67
- const button = this._createButton(ButtonView);
68
- button.icon = icons.browseFiles;
69
- button.label = t('Open file manager');
70
- button.tooltip = true;
71
- return button;
72
- }
73
- /**
74
- * Creates a simple toolbar button for images management, with an icon and a tooltip.
75
- */ _createImageToolbarButton() {
76
- const t = this.editor.locale.t;
77
- const imageInsertUI = this.editor.plugins.get('ImageInsertUI');
78
- const button = this._createButton(ButtonView);
79
- button.icon = icons.imageAssetManager;
80
- button.bind('label').to(imageInsertUI, 'isImageSelected', (isImageSelected)=>isImageSelected ? t('Replace image with file manager') : t('Insert image with file manager'));
81
- button.tooltip = true;
82
- return button;
83
- }
84
- /**
85
- * Creates a button for images management for the dropdown view, with an icon, text and no tooltip.
86
- */ _createImageDropdownButton() {
87
- const t = this.editor.locale.t;
88
- const imageInsertUI = this.editor.plugins.get('ImageInsertUI');
89
- const button = this._createButton(ButtonView);
90
- button.icon = icons.imageAssetManager;
91
- button.withText = true;
92
- button.bind('label').to(imageInsertUI, 'isImageSelected', (isImageSelected)=>isImageSelected ? t('Replace with file manager') : t('Insert with file manager'));
93
- button.on('execute', ()=>{
94
- imageInsertUI.dropdownView.isOpen = false;
95
- });
96
- return button;
97
- }
98
- /**
99
- * Creates a button for files management for the menu bar.
100
- */ _createFileMenuBarButton() {
101
- const t = this.editor.locale.t;
102
- const button = this._createButton(MenuBarMenuListItemButtonView);
103
- button.icon = icons.browseFiles;
104
- button.withText = true;
105
- button.label = t('File');
106
- return button;
107
- }
108
- /**
109
- * Creates a button for images management for the menu bar.
110
- */ _createImageMenuBarButton(type) {
111
- const t = this.editor.locale.t;
112
- const button = this._createButton(MenuBarMenuListItemButtonView);
113
- button.icon = icons.imageAssetManager;
114
- button.withText = true;
115
- switch(type){
116
- case 'insertOnly':
117
- button.label = t('Image');
118
- break;
119
- case 'insertNested':
120
- button.label = t('With file manager');
121
- break;
122
- }
123
- return button;
124
- }
125
78
  }
126
79
 
127
80
  /**
@@ -282,7 +235,7 @@ const MIME_TO_EXTENSION = {
282
235
  * Returns an extension from the given value.
283
236
  */ function getFileExtension(file) {
284
237
  const fileName = file.name;
285
- const extensionRegExp = /\.(?<ext>[^.]+)$/;
238
+ const extensionRegExp = RegExp("\\.(?<ext>[^.]+)$");
286
239
  const match = fileName.match(extensionRegExp);
287
240
  return match.groups.ext.toLowerCase();
288
241
  }
@@ -291,68 +244,29 @@ const MIME_TO_EXTENSION = {
291
244
  // `CKBoxCommand#_chosenAssets` and it is removed from there automatically after this time. See `CKBoxCommand#_chosenAssets` for more
292
245
  // details.
293
246
  const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
294
- /**
295
- * The CKBox command. It is used by the {@link module:ckbox/ckboxediting~CKBoxEditing CKBox editing feature} to open the CKBox file manager.
296
- * The file manager allows inserting an image or a link to a file into the editor content.
297
- *
298
- * ```ts
299
- * editor.execute( 'ckbox' );
300
- * ```
301
- *
302
- * **Note:** This command uses other features to perform the following tasks:
303
- * - To insert images it uses the {@link module:image/image/insertimagecommand~InsertImageCommand 'insertImage'} command from the
304
- * {@link module:image/image~Image Image feature}.
305
- * - To insert links to other files it uses the {@link module:link/linkcommand~LinkCommand 'link'} command from the
306
- * {@link module:link/link~Link Link feature}.
307
- */ class CKBoxCommand extends Command {
308
- /**
309
- * A set of all chosen assets. They are stored temporarily and they are automatically removed 1 second after being chosen.
310
- * Chosen assets have to be "remembered" for a while to be able to map the given asset with the element inserted into the model.
311
- * This association map is then used to set the ID on the model element.
312
- *
313
- * All chosen assets are automatically removed after the timeout, because (theoretically) it may happen that they will never be
314
- * inserted into the model, even if the {@link module:link/linkcommand~LinkCommand `'link'`} command or the
315
- * {@link module:image/image/insertimagecommand~InsertImageCommand `'insertImage'`} command is enabled. Such a case may arise when
316
- * another plugin blocks the command execution. Then, in order not to keep the chosen (but not inserted) assets forever, we delete
317
- * them automatically to prevent memory leakage. The 1 second timeout is enough to insert the asset into the model and extract the
318
- * ID from the chosen asset.
319
- *
320
- * The assets are stored only if
321
- * the {@link module:ckbox/ckboxconfig~CKBoxConfig#ignoreDataId `config.ckbox.ignoreDataId`} option is set to `false` (by default).
322
- *
323
- * @internal
324
- */ _chosenAssets = new Set();
325
- /**
326
- * The DOM element that acts as a mounting point for the CKBox dialog.
327
- */ _wrapper = null;
247
+ class CKBoxCommand extends Command {
328
248
  /**
329
- * @inheritDoc
330
- */ constructor(editor){
331
- super(editor);
332
- this._initListeners();
333
- }
334
- /**
335
- * @inheritDoc
336
- */ refresh() {
249
+ * @inheritDoc
250
+ */ refresh() {
337
251
  this.value = this._getValue();
338
252
  this.isEnabled = this._checkEnabled();
339
253
  }
340
254
  /**
341
- * @inheritDoc
342
- */ execute() {
255
+ * @inheritDoc
256
+ */ execute() {
343
257
  this.fire('ckbox:open');
344
258
  }
345
259
  /**
346
- * Indicates if the CKBox dialog is already opened.
347
- *
348
- * @protected
349
- * @returns {Boolean}
350
- */ _getValue() {
260
+ * Indicates if the CKBox dialog is already opened.
261
+ *
262
+ * @protected
263
+ * @returns {Boolean}
264
+ */ _getValue() {
351
265
  return this._wrapper !== null;
352
266
  }
353
267
  /**
354
- * Checks whether the command can be enabled in the current context.
355
- */ _checkEnabled() {
268
+ * Checks whether the command can be enabled in the current context.
269
+ */ _checkEnabled() {
356
270
  const imageCommand = this.editor.commands.get('insertImage');
357
271
  const linkCommand = this.editor.commands.get('link');
358
272
  if (!imageCommand.isEnabled && !linkCommand.isEnabled) {
@@ -361,17 +275,17 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
361
275
  return true;
362
276
  }
363
277
  /**
364
- * Creates the options object for the CKBox dialog.
365
- *
366
- * @returns The object with properties:
367
- * - theme The theme for CKBox dialog.
368
- * - language The language for CKBox dialog.
369
- * - tokenUrl The token endpoint URL.
370
- * - serviceOrigin The base URL of the API service.
371
- * - forceDemoLabel Whether to force "Powered by CKBox" link.
372
- * - dialog.onClose The callback function invoked after closing the CKBox dialog.
373
- * - assets.onChoose The callback function invoked after choosing the assets.
374
- */ _prepareOptions() {
278
+ * Creates the options object for the CKBox dialog.
279
+ *
280
+ * @returns The object with properties:
281
+ * - theme The theme for CKBox dialog.
282
+ * - language The language for CKBox dialog.
283
+ * - tokenUrl The token endpoint URL.
284
+ * - serviceOrigin The base URL of the API service.
285
+ * - forceDemoLabel Whether to force "Powered by CKBox" link.
286
+ * - dialog.onClose The callback function invoked after closing the CKBox dialog.
287
+ * - assets.onChoose The callback function invoked after choosing the assets.
288
+ */ _prepareOptions() {
375
289
  const editor = this.editor;
376
290
  const ckboxConfig = editor.config.get('ckbox');
377
291
  return {
@@ -389,8 +303,8 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
389
303
  };
390
304
  }
391
305
  /**
392
- * Initializes various event listeners for the `ckbox:*` events, because all functionality of the `ckbox` command is event-based.
393
- */ _initListeners() {
306
+ * Initializes various event listeners for the `ckbox:*` events, because all functionality of the `ckbox` command is event-based.
307
+ */ _initListeners() {
394
308
  const editor = this.editor;
395
309
  const model = editor.model;
396
310
  const shouldInsertDataId = !editor.config.get('ckbox.ignoreDataId');
@@ -459,13 +373,13 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
459
373
  });
460
374
  }
461
375
  /**
462
- * Inserts the asset into the model.
463
- *
464
- * @param asset The asset to be inserted.
465
- * @param isLastAsset Indicates if the current asset is the last one from the chosen set.
466
- * @param writer An instance of the model writer.
467
- * @param isSingleAsset It's true when only one asset is processed.
468
- */ _insertAsset(asset, isLastAsset, writer, isSingleAsset) {
376
+ * Inserts the asset into the model.
377
+ *
378
+ * @param asset The asset to be inserted.
379
+ * @param isLastAsset Indicates if the current asset is the last one from the chosen set.
380
+ * @param writer An instance of the model writer.
381
+ * @param isSingleAsset It's true when only one asset is processed.
382
+ */ _insertAsset(asset, isLastAsset, writer, isSingleAsset) {
469
383
  const editor = this.editor;
470
384
  const model = editor.model;
471
385
  const selection = model.document.selection;
@@ -483,10 +397,10 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
483
397
  }
484
398
  }
485
399
  /**
486
- * Inserts the image by calling the `insertImage` command.
487
- *
488
- * @param asset The asset to be inserted.
489
- */ _insertImage(asset) {
400
+ * Inserts the image by calling the `insertImage` command.
401
+ *
402
+ * @param asset The asset to be inserted.
403
+ */ _insertImage(asset) {
490
404
  const editor = this.editor;
491
405
  const { imageFallbackUrl, imageSources, imageTextAlternative, imageWidth, imageHeight, imagePlaceholder } = asset.attributes;
492
406
  editor.execute('insertImage', {
@@ -503,12 +417,12 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
503
417
  });
504
418
  }
505
419
  /**
506
- * Inserts the link to the asset by calling the `link` command.
507
- *
508
- * @param asset The asset to be inserted.
509
- * @param writer An instance of the model writer.
510
- * @param isSingleAsset It's true when only one asset is processed.
511
- */ _insertLink(asset, writer, isSingleAsset) {
420
+ * Inserts the link to the asset by calling the `link` command.
421
+ *
422
+ * @param asset The asset to be inserted.
423
+ * @param writer An instance of the model writer.
424
+ * @param isSingleAsset It's true when only one asset is processed.
425
+ */ _insertLink(asset, writer, isSingleAsset) {
512
426
  const editor = this.editor;
513
427
  const model = editor.model;
514
428
  const selection = model.document.selection;
@@ -536,6 +450,32 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
536
450
  }
537
451
  editor.execute('link', linkHref);
538
452
  }
453
+ /**
454
+ * @inheritDoc
455
+ */ constructor(editor){
456
+ super(editor);
457
+ /**
458
+ * A set of all chosen assets. They are stored temporarily and they are automatically removed 1 second after being chosen.
459
+ * Chosen assets have to be "remembered" for a while to be able to map the given asset with the element inserted into the model.
460
+ * This association map is then used to set the ID on the model element.
461
+ *
462
+ * All chosen assets are automatically removed after the timeout, because (theoretically) it may happen that they will never be
463
+ * inserted into the model, even if the {@link module:link/linkcommand~LinkCommand `'link'`} command or the
464
+ * {@link module:image/image/insertimagecommand~InsertImageCommand `'insertImage'`} command is enabled. Such a case may arise when
465
+ * another plugin blocks the command execution. Then, in order not to keep the chosen (but not inserted) assets forever, we delete
466
+ * them automatically to prevent memory leakage. The 1 second timeout is enough to insert the asset into the model and extract the
467
+ * ID from the chosen asset.
468
+ *
469
+ * The assets are stored only if
470
+ * the {@link module:ckbox/ckboxconfig~CKBoxConfig#ignoreDataId `config.ckbox.ignoreDataId`} option is set to `false` (by default).
471
+ *
472
+ * @internal
473
+ */ this._chosenAssets = new Set();
474
+ /**
475
+ * The DOM element that acts as a mounting point for the CKBox dialog.
476
+ */ this._wrapper = null;
477
+ this._initListeners();
478
+ }
539
479
  }
540
480
  /**
541
481
  * Parses the chosen assets into the internal data format. Filters out chosen assets that are not allowed.
@@ -599,27 +539,22 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
599
539
  }
600
540
 
601
541
  const DEFAULT_CKBOX_THEME_NAME = 'lark';
602
- /**
603
- * The CKBox utilities plugin.
604
- */ class CKBoxUtils extends Plugin {
542
+ class CKBoxUtils extends Plugin {
605
543
  /**
606
- * CKEditor Cloud Services access token.
607
- */ _token;
608
- /**
609
- * @inheritDoc
610
- */ static get pluginName() {
544
+ * @inheritDoc
545
+ */ static get pluginName() {
611
546
  return 'CKBoxUtils';
612
547
  }
613
548
  /**
614
- * @inheritDoc
615
- */ static get requires() {
549
+ * @inheritDoc
550
+ */ static get requires() {
616
551
  return [
617
552
  'CloudServices'
618
553
  ];
619
554
  }
620
555
  /**
621
- * @inheritDoc
622
- */ async init() {
556
+ * @inheritDoc
557
+ */ async init() {
623
558
  const editor = this.editor;
624
559
  const hasConfiguration = !!editor.config.get('ckbox');
625
560
  const isLibraryLoaded = !!window.CKBox;
@@ -641,22 +576,22 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
641
576
  const ckboxTokenUrl = editor.config.get('ckbox.tokenUrl');
642
577
  if (!ckboxTokenUrl) {
643
578
  /**
644
- * The {@link module:ckbox/ckboxconfig~CKBoxConfig#tokenUrl `config.ckbox.tokenUrl`} or the
645
- * {@link module:cloud-services/cloudservicesconfig~CloudServicesConfig#tokenUrl `config.cloudServices.tokenUrl`}
646
- * configuration is required for the CKBox plugin.
647
- *
648
- * ```ts
649
- * ClassicEditor.create( document.createElement( 'div' ), {
650
- * ckbox: {
651
- * tokenUrl: "YOUR_TOKEN_URL"
652
- * // ...
653
- * }
654
- * // ...
655
- * } );
656
- * ```
657
- *
658
- * @error ckbox-plugin-missing-token-url
659
- */ throw new CKEditorError('ckbox-plugin-missing-token-url', this);
579
+ * The {@link module:ckbox/ckboxconfig~CKBoxConfig#tokenUrl `config.ckbox.tokenUrl`} or the
580
+ * {@link module:cloud-services/cloudservicesconfig~CloudServicesConfig#tokenUrl `config.cloudServices.tokenUrl`}
581
+ * configuration is required for the CKBox plugin.
582
+ *
583
+ * ```ts
584
+ * ClassicEditor.create( document.createElement( 'div' ), {
585
+ * ckbox: {
586
+ * tokenUrl: "YOUR_TOKEN_URL"
587
+ * // ...
588
+ * }
589
+ * // ...
590
+ * } );
591
+ * ```
592
+ *
593
+ * @error ckbox-plugin-missing-token-url
594
+ */ throw new CKEditorError('ckbox-plugin-missing-token-url', this);
660
595
  }
661
596
  if (ckboxTokenUrl == cloudServicesTokenUrl) {
662
597
  this._token = cloudServices.token;
@@ -665,30 +600,30 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
665
600
  }
666
601
  }
667
602
  /**
668
- * Returns a token used by the CKBox plugin for communication with the CKBox service.
669
- */ getToken() {
603
+ * Returns a token used by the CKBox plugin for communication with the CKBox service.
604
+ */ getToken() {
670
605
  return this._token;
671
606
  }
672
607
  /**
673
- * The ID of workspace to use when uploading an image.
674
- */ getWorkspaceId() {
608
+ * The ID of workspace to use when uploading an image.
609
+ */ getWorkspaceId() {
675
610
  const t = this.editor.t;
676
611
  const cannotAccessDefaultWorkspaceError = t('Cannot access default workspace.');
677
612
  const defaultWorkspaceId = this.editor.config.get('ckbox.defaultUploadWorkspaceId');
678
613
  const workspaceId = getWorkspaceId(this._token, defaultWorkspaceId);
679
614
  if (workspaceId == null) {
680
615
  /**
681
- * The user is not authorized to access the workspace defined in the`ckbox.defaultUploadWorkspaceId` configuration.
682
- *
683
- * @error ckbox-access-default-workspace-error
684
- */ logError('ckbox-access-default-workspace-error');
616
+ * The user is not authorized to access the workspace defined in the`ckbox.defaultUploadWorkspaceId` configuration.
617
+ *
618
+ * @error ckbox-access-default-workspace-error
619
+ */ logError('ckbox-access-default-workspace-error');
685
620
  throw cannotAccessDefaultWorkspaceError;
686
621
  }
687
622
  return workspaceId;
688
623
  }
689
624
  /**
690
- * Resolves a promise with an object containing a category with which the uploaded file is associated or an error code.
691
- */ async getCategoryIdForFile(fileOrUrl, options) {
625
+ * Resolves a promise with an object containing a category with which the uploaded file is associated or an error code.
626
+ */ async getCategoryIdForFile(fileOrUrl, options) {
692
627
  const t = this.editor.t;
693
628
  const cannotFindCategoryError = t('Cannot determine a category for the uploaded file.');
694
629
  const defaultCategories = this.editor.config.get('ckbox.defaultUploadCategories');
@@ -721,10 +656,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
721
656
  return category.id;
722
657
  }
723
658
  /**
724
- * Resolves a promise with an array containing available categories with which the uploaded file can be associated.
725
- *
726
- * If the API returns limited results, the method will collect all items.
727
- */ async _getAvailableCategories(options) {
659
+ * Resolves a promise with an array containing available categories with which the uploaded file can be associated.
660
+ *
661
+ * If the API returns limited results, the method will collect all items.
662
+ */ async _getAvailableCategories(options) {
728
663
  const ITEMS_PER_REQUEST = 50;
729
664
  const editor = this.editor;
730
665
  const token = this._token;
@@ -745,10 +680,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
745
680
  } catch {
746
681
  signal.throwIfAborted();
747
682
  /**
748
- * Fetching a list of available categories with which an uploaded file can be associated failed.
749
- *
750
- * @error ckbox-fetch-category-http-error
751
- */ logError('ckbox-fetch-category-http-error');
683
+ * Fetching a list of available categories with which an uploaded file can be associated failed.
684
+ *
685
+ * @error ckbox-fetch-category-http-error
686
+ */ logError('ckbox-fetch-category-http-error');
752
687
  return undefined;
753
688
  }
754
689
  function fetchCategories(offset) {
@@ -765,18 +700,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
765
700
  }
766
701
  }
767
702
 
768
- /**
769
- * A plugin that enables file uploads in CKEditor 5 using the CKBox server–side connector.
770
- * See the {@glink features/file-management/ckbox CKBox file manager integration} guide to learn how to configure
771
- * and use this feature as well as find out more about the full integration with the file manager
772
- * provided by the {@link module:ckbox/ckbox~CKBox} plugin.
773
- *
774
- * Check out the {@glink features/images/image-upload/image-upload Image upload overview} guide to learn about
775
- * other ways to upload images into CKEditor 5.
776
- */ class CKBoxUploadAdapter extends Plugin {
703
+ class CKBoxUploadAdapter extends Plugin {
777
704
  /**
778
- * @inheritDoc
779
- */ static get requires() {
705
+ * @inheritDoc
706
+ */ static get requires() {
780
707
  return [
781
708
  'ImageUploadEditing',
782
709
  'ImageUploadProgress',
@@ -785,13 +712,13 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
785
712
  ];
786
713
  }
787
714
  /**
788
- * @inheritDoc
789
- */ static get pluginName() {
715
+ * @inheritDoc
716
+ */ static get pluginName() {
790
717
  return 'CKBoxUploadAdapter';
791
718
  }
792
719
  /**
793
- * @inheritDoc
794
- */ async afterInit() {
720
+ * @inheritDoc
721
+ */ async afterInit() {
795
722
  const editor = this.editor;
796
723
  const hasConfiguration = !!editor.config.get('ckbox');
797
724
  const isLibraryLoaded = !!window.CKBox;
@@ -820,38 +747,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
820
747
  * Upload adapter for CKBox.
821
748
  */ class Adapter {
822
749
  /**
823
- * FileLoader instance to use during the upload.
824
- */ loader;
825
- /**
826
- * CKEditor Cloud Services access token.
827
- */ token;
828
- /**
829
- * The editor instance.
830
- */ editor;
831
- /**
832
- * The abort controller for aborting asynchronous processes.
833
- */ controller;
834
- /**
835
- * The base URL where all requests should be sent.
836
- */ serviceOrigin;
837
- /**
838
- * The reference to CKBoxUtils plugin.
839
- */ ckboxUtils;
840
- /**
841
- * Creates a new adapter instance.
842
- */ constructor(loader, editor, ckboxUtils){
843
- this.loader = loader;
844
- this.token = ckboxUtils.getToken();
845
- this.ckboxUtils = ckboxUtils;
846
- this.editor = editor;
847
- this.controller = new AbortController();
848
- this.serviceOrigin = editor.config.get('ckbox.serviceOrigin');
849
- }
850
- /**
851
- * Starts the upload process.
852
- *
853
- * @see module:upload/filerepository~UploadAdapter#upload
854
- */ async upload() {
750
+ * Starts the upload process.
751
+ *
752
+ * @see module:upload/filerepository~UploadAdapter#upload
753
+ */ async upload() {
855
754
  const ckboxUtils = this.ckboxUtils;
856
755
  const t = this.editor.t;
857
756
  const file = await this.loader.file;
@@ -889,29 +788,33 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
889
788
  });
890
789
  }
891
790
  /**
892
- * Aborts the upload process.
893
- *
894
- * @see module:upload/filerepository~UploadAdapter#abort
895
- */ abort() {
791
+ * Aborts the upload process.
792
+ *
793
+ * @see module:upload/filerepository~UploadAdapter#abort
794
+ */ abort() {
896
795
  this.controller.abort();
897
796
  }
797
+ /**
798
+ * Creates a new adapter instance.
799
+ */ constructor(loader, editor, ckboxUtils){
800
+ this.loader = loader;
801
+ this.token = ckboxUtils.getToken();
802
+ this.ckboxUtils = ckboxUtils;
803
+ this.editor = editor;
804
+ this.controller = new AbortController();
805
+ this.serviceOrigin = editor.config.get('ckbox.serviceOrigin');
806
+ }
898
807
  }
899
808
 
900
- /**
901
- * The CKBox editing feature. It introduces the {@link module:ckbox/ckboxcommand~CKBoxCommand CKBox command} and
902
- * {@link module:ckbox/ckboxuploadadapter~CKBoxUploadAdapter CKBox upload adapter}.
903
- */ class CKBoxEditing extends Plugin {
904
- /**
905
- * CKEditor Cloud Services access token.
906
- */ _token;
809
+ class CKBoxEditing extends Plugin {
907
810
  /**
908
- * @inheritDoc
909
- */ static get pluginName() {
811
+ * @inheritDoc
812
+ */ static get pluginName() {
910
813
  return 'CKBoxEditing';
911
814
  }
912
815
  /**
913
- * @inheritDoc
914
- */ static get requires() {
816
+ * @inheritDoc
817
+ */ static get requires() {
915
818
  return [
916
819
  'LinkEditing',
917
820
  'PictureEditing',
@@ -920,8 +823,8 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
920
823
  ];
921
824
  }
922
825
  /**
923
- * @inheritDoc
924
- */ init() {
826
+ * @inheritDoc
827
+ */ init() {
925
828
  const editor = this.editor;
926
829
  if (!this._shouldBeInitialised()) {
927
830
  return;
@@ -933,8 +836,8 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
933
836
  }
934
837
  }
935
838
  /**
936
- * @inheritDoc
937
- */ afterInit() {
839
+ * @inheritDoc
840
+ */ afterInit() {
938
841
  const editor = this.editor;
939
842
  if (!this._shouldBeInitialised()) {
940
843
  return;
@@ -948,35 +851,35 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
948
851
  }
949
852
  }
950
853
  /**
951
- * Returns true only when the integrator intentionally wants to use the plugin, i.e. when the `config.ckbox` exists or
952
- * the CKBox JavaScript library is loaded.
953
- */ _shouldBeInitialised() {
854
+ * Returns true only when the integrator intentionally wants to use the plugin, i.e. when the `config.ckbox` exists or
855
+ * the CKBox JavaScript library is loaded.
856
+ */ _shouldBeInitialised() {
954
857
  const editor = this.editor;
955
858
  const hasConfiguration = !!editor.config.get('ckbox');
956
859
  return hasConfiguration || isLibraryLoaded();
957
860
  }
958
861
  /**
959
- * Checks if at least one image plugin is loaded.
960
- */ _checkImagePlugins() {
862
+ * Checks if at least one image plugin is loaded.
863
+ */ _checkImagePlugins() {
961
864
  const editor = this.editor;
962
865
  if (!editor.plugins.has('ImageBlockEditing') && !editor.plugins.has('ImageInlineEditing')) {
963
866
  /**
964
- * The CKBox feature requires one of the following plugins to be loaded to work correctly:
965
- *
966
- * * {@link module:image/imageblock~ImageBlock},
967
- * * {@link module:image/imageinline~ImageInline},
968
- * * {@link module:image/image~Image} (loads both `ImageBlock` and `ImageInline`)
969
- *
970
- * Please make sure your editor configuration is correct.
971
- *
972
- * @error ckbox-plugin-image-feature-missing
973
- * @param {module:core/editor/editor~Editor} editor
974
- */ logError('ckbox-plugin-image-feature-missing', editor);
867
+ * The CKBox feature requires one of the following plugins to be loaded to work correctly:
868
+ *
869
+ * * {@link module:image/imageblock~ImageBlock},
870
+ * * {@link module:image/imageinline~ImageInline},
871
+ * * {@link module:image/image~Image} (loads both `ImageBlock` and `ImageInline`)
872
+ *
873
+ * Please make sure your editor configuration is correct.
874
+ *
875
+ * @error ckbox-plugin-image-feature-missing
876
+ * @param {module:core/editor/editor~Editor} editor
877
+ */ logError('ckbox-plugin-image-feature-missing', editor);
975
878
  }
976
879
  }
977
880
  /**
978
- * Extends the schema to allow the `ckboxImageId` and `ckboxLinkId` attributes for links and images.
979
- */ _initSchema() {
881
+ * Extends the schema to allow the `ckboxImageId` and `ckboxLinkId` attributes for links and images.
882
+ */ _initSchema() {
980
883
  const editor = this.editor;
981
884
  const schema = editor.model.schema;
982
885
  schema.extend('$text', {
@@ -1006,8 +909,8 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
1006
909
  });
1007
910
  }
1008
911
  /**
1009
- * Configures the upcast and downcast conversions for the `ckboxImageId` and `ckboxLinkId` attributes.
1010
- */ _initConversion() {
912
+ * Configures the upcast and downcast conversions for the `ckboxImageId` and `ckboxLinkId` attributes.
913
+ */ _initConversion() {
1011
914
  const editor = this.editor;
1012
915
  // Convert `ckboxLinkId` => `data-ckbox-resource-id`.
1013
916
  editor.conversion.for('downcast').add((dispatcher)=>{
@@ -1128,8 +1031,8 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
1128
1031
  }
1129
1032
  }
1130
1033
  /**
1131
- * Registers post-fixers that add or remove the `ckboxLinkId` and `ckboxImageId` attributes.
1132
- */ _initFixers() {
1034
+ * Registers post-fixers that add or remove the `ckboxLinkId` and `ckboxImageId` attributes.
1035
+ */ _initFixers() {
1133
1036
  const editor = this.editor;
1134
1037
  const model = editor.model;
1135
1038
  const selection = model.document.selection;
@@ -1242,27 +1145,15 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
1242
1145
  return !!window.CKBox;
1243
1146
  }
1244
1147
 
1245
- /**
1246
- * The CKBox feature, a bridge between the CKEditor 5 WYSIWYG editor and the CKBox file manager and uploader.
1247
- *
1248
- * This is a "glue" plugin which enables:
1249
- *
1250
- * * {@link module:ckbox/ckboxediting~CKBoxEditing},
1251
- * * {@link module:ckbox/ckboxui~CKBoxUI},
1252
- *
1253
- * See the {@glink features/file-management/ckbox CKBox integration} guide to learn how to configure and use this feature.
1254
- *
1255
- * Check out the {@glink features/images/image-upload/image-upload Image upload} guide to learn about other ways to upload
1256
- * images into CKEditor 5.
1257
- */ class CKBox extends Plugin {
1148
+ class CKBox extends Plugin {
1258
1149
  /**
1259
- * @inheritDoc
1260
- */ static get pluginName() {
1150
+ * @inheritDoc
1151
+ */ static get pluginName() {
1261
1152
  return 'CKBox';
1262
1153
  }
1263
1154
  /**
1264
- * @inheritDoc
1265
- */ static get requires() {
1155
+ * @inheritDoc
1156
+ */ static get requires() {
1266
1157
  return [
1267
1158
  CKBoxEditing,
1268
1159
  CKBoxUI
@@ -1306,50 +1197,18 @@ function createUrlChecker(allowExternalImagesEditing) {
1306
1197
  return ()=>false;
1307
1198
  }
1308
1199
 
1309
- /**
1310
- * The CKBox edit image command.
1311
- *
1312
- * Opens the CKBox dialog for editing the image.
1313
- */ class CKBoxImageEditCommand extends Command {
1314
- /**
1315
- * The DOM element that acts as a mounting point for the CKBox Edit Image dialog.
1316
- */ _wrapper = null;
1317
- /**
1318
- * The states of image processing in progress.
1319
- */ _processInProgress = new Set();
1320
- /**
1321
- * Determines if the element can be edited.
1322
- */ _canEdit;
1323
- /**
1324
- * A wrapper function to prepare mount options. Ensures that at most one preparation is in-flight.
1325
- */ _prepareOptions;
1326
- /**
1327
- * CKBox's onClose function runs before the final cleanup, potentially causing
1328
- * page layout changes after it finishes. To address this, we use a setTimeout hack
1329
- * to ensure that floating elements on the page maintain their correct position.
1330
- *
1331
- * See: https://github.com/ckeditor/ckeditor5/issues/16153.
1332
- */ _updateUiDelayed = delay(()=>this.editor.ui.update(), 0);
1333
- /**
1334
- * @inheritDoc
1335
- */ constructor(editor){
1336
- super(editor);
1337
- this.value = false;
1338
- this._canEdit = createEditabilityChecker(editor.config.get('ckbox.allowExternalImagesEditing'));
1339
- this._prepareOptions = abortableDebounce((signal, state)=>this._prepareOptionsAbortable(signal, state));
1340
- this._prepareListeners();
1341
- }
1200
+ class CKBoxImageEditCommand extends Command {
1342
1201
  /**
1343
- * @inheritDoc
1344
- */ refresh() {
1202
+ * @inheritDoc
1203
+ */ refresh() {
1345
1204
  const editor = this.editor;
1346
1205
  this.value = this._getValue();
1347
1206
  const selectedElement = editor.model.document.selection.getSelectedElement();
1348
1207
  this.isEnabled = !!selectedElement && this._canEdit(selectedElement) && !this._checkIfElementIsBeingProcessed(selectedElement);
1349
1208
  }
1350
1209
  /**
1351
- * Opens the CKBox Image Editor dialog for editing the image.
1352
- */ execute() {
1210
+ * Opens the CKBox Image Editor dialog for editing the image.
1211
+ */ execute() {
1353
1212
  if (this._getValue()) {
1354
1213
  return;
1355
1214
  }
@@ -1376,24 +1235,23 @@ function createUrlChecker(allowExternalImagesEditing) {
1376
1235
  });
1377
1236
  }
1378
1237
  /**
1379
- * @inheritDoc
1380
- */ destroy() {
1238
+ * @inheritDoc
1239
+ */ destroy() {
1381
1240
  this._handleImageEditorClose();
1382
1241
  this._prepareOptions.abort();
1383
- this._updateUiDelayed.cancel();
1384
1242
  for (const state of this._processInProgress.values()){
1385
1243
  state.controller.abort();
1386
1244
  }
1387
1245
  super.destroy();
1388
1246
  }
1389
1247
  /**
1390
- * Indicates if the CKBox Image Editor dialog is already opened.
1391
- */ _getValue() {
1248
+ * Indicates if the CKBox Image Editor dialog is already opened.
1249
+ */ _getValue() {
1392
1250
  return this._wrapper !== null;
1393
1251
  }
1394
1252
  /**
1395
- * Creates the options object for the CKBox Image Editor dialog.
1396
- */ async _prepareOptionsAbortable(signal, state) {
1253
+ * Creates the options object for the CKBox Image Editor dialog.
1254
+ */ async _prepareOptionsAbortable(signal, state) {
1397
1255
  const editor = this.editor;
1398
1256
  const ckboxConfig = editor.config.get('ckbox');
1399
1257
  const ckboxUtils = editor.plugins.get(CKBoxUtils);
@@ -1428,8 +1286,8 @@ function createUrlChecker(allowExternalImagesEditing) {
1428
1286
  };
1429
1287
  }
1430
1288
  /**
1431
- * Initializes event lister for an event of removing an image.
1432
- */ _prepareListeners() {
1289
+ * Initializes event lister for an event of removing an image.
1290
+ */ _prepareListeners() {
1433
1291
  // Abort editing processing when the image has been removed.
1434
1292
  this.listenTo(this.editor.model.document, 'change:data', ()=>{
1435
1293
  const processingStates = this._getProcessingStatesOfDeletedImages();
@@ -1439,8 +1297,8 @@ function createUrlChecker(allowExternalImagesEditing) {
1439
1297
  });
1440
1298
  }
1441
1299
  /**
1442
- * Gets processing states of images that have been deleted in the mean time.
1443
- */ _getProcessingStatesOfDeletedImages() {
1300
+ * Gets processing states of images that have been deleted in the mean time.
1301
+ */ _getProcessingStatesOfDeletedImages() {
1444
1302
  const states = [];
1445
1303
  for (const state of this._processInProgress.values()){
1446
1304
  if (state.element.root.rootName == '$graveyard') {
@@ -1458,21 +1316,20 @@ function createUrlChecker(allowExternalImagesEditing) {
1458
1316
  return false;
1459
1317
  }
1460
1318
  /**
1461
- * Closes the CKBox Image Editor dialog.
1462
- */ _handleImageEditorClose() {
1319
+ * Closes the CKBox Image Editor dialog.
1320
+ */ _handleImageEditorClose() {
1463
1321
  if (!this._wrapper) {
1464
1322
  return;
1465
1323
  }
1466
1324
  this._wrapper.remove();
1467
1325
  this._wrapper = null;
1468
1326
  this.editor.editing.view.focus();
1469
- this._updateUiDelayed();
1470
1327
  this.refresh();
1471
1328
  }
1472
1329
  /**
1473
- * Save edited image. In case server respond with "success" replace with edited image,
1474
- * otherwise show notification error.
1475
- */ _handleImageEditorSave(state, asset) {
1330
+ * Save edited image. In case server respond with "success" replace with edited image,
1331
+ * otherwise show notification error.
1332
+ */ _handleImageEditorSave(state, asset) {
1476
1333
  const t = this.editor.locale.t;
1477
1334
  const notification = this.editor.plugins.get(Notification);
1478
1335
  const pendingActions = this.editor.plugins.get(PendingActions);
@@ -1502,9 +1359,9 @@ function createUrlChecker(allowExternalImagesEditing) {
1502
1359
  });
1503
1360
  }
1504
1361
  /**
1505
- * Get asset's status on server. If server responds with "success" status then
1506
- * image is already proceeded and ready for saving.
1507
- */ async _getAssetStatusFromServer(id, signal) {
1362
+ * Get asset's status on server. If server responds with "success" status then
1363
+ * image is already proceeded and ready for saving.
1364
+ */ async _getAssetStatusFromServer(id, signal) {
1508
1365
  const ckboxUtils = this.editor.plugins.get(CKBoxUtils);
1509
1366
  const url = new URL('assets/' + id, this.editor.config.get('ckbox.serviceOrigin'));
1510
1367
  const response = await sendHttpRequest({
@@ -1515,10 +1372,10 @@ function createUrlChecker(allowExternalImagesEditing) {
1515
1372
  const status = response.metadata.metadataProcessingStatus;
1516
1373
  if (!status || status == 'queued') {
1517
1374
  /**
1518
- * Image has not been processed yet.
1519
- *
1520
- * @error ckbox-image-not-processed
1521
- */ throw new CKEditorError('ckbox-image-not-processed');
1375
+ * Image has not been processed yet.
1376
+ *
1377
+ * @error ckbox-image-not-processed
1378
+ */ throw new CKEditorError('ckbox-image-not-processed');
1522
1379
  }
1523
1380
  return {
1524
1381
  data: {
@@ -1527,27 +1384,27 @@ function createUrlChecker(allowExternalImagesEditing) {
1527
1384
  };
1528
1385
  }
1529
1386
  /**
1530
- * Waits for an asset to be processed.
1531
- * It retries retrieving asset status from the server in case of failure.
1532
- */ async _waitForAssetProcessed(id, signal) {
1387
+ * Waits for an asset to be processed.
1388
+ * It retries retrieving asset status from the server in case of failure.
1389
+ */ async _waitForAssetProcessed(id, signal) {
1533
1390
  const result = await retry(()=>this._getAssetStatusFromServer(id, signal), {
1534
1391
  signal,
1535
1392
  maxAttempts: 5
1536
1393
  });
1537
1394
  if (result.data.metadata.metadataProcessingStatus != 'success') {
1538
1395
  /**
1539
- * The image processing failed.
1540
- *
1541
- * @error ckbox-image-processing-failed
1542
- */ throw new CKEditorError('ckbox-image-processing-failed');
1396
+ * The image processing failed.
1397
+ *
1398
+ * @error ckbox-image-processing-failed
1399
+ */ throw new CKEditorError('ckbox-image-processing-failed');
1543
1400
  }
1544
1401
  return result;
1545
1402
  }
1546
1403
  /**
1547
- * Shows processing indicator while image is processing.
1548
- *
1549
- * @param asset Data about certain asset.
1550
- */ _showImageProcessingIndicator(element, asset) {
1404
+ * Shows processing indicator while image is processing.
1405
+ *
1406
+ * @param asset Data about certain asset.
1407
+ */ _showImageProcessingIndicator(element, asset) {
1551
1408
  const editor = this.editor;
1552
1409
  editor.editing.view.change((writer)=>{
1553
1410
  const imageElementView = editor.editing.mapper.toViewElement(element);
@@ -1562,8 +1419,8 @@ function createUrlChecker(allowExternalImagesEditing) {
1562
1419
  });
1563
1420
  }
1564
1421
  /**
1565
- * Replace the edited image with the new one.
1566
- */ _replaceImage(element, asset) {
1422
+ * Replace the edited image with the new one.
1423
+ */ _replaceImage(element, asset) {
1567
1424
  const editor = this.editor;
1568
1425
  const { imageFallbackUrl, imageSources, imageWidth, imageHeight, imagePlaceholder } = prepareImageAssetAttributes(asset);
1569
1426
  const previousSelectionRanges = Array.from(editor.model.document.selection.getRanges());
@@ -1592,19 +1449,32 @@ function createUrlChecker(allowExternalImagesEditing) {
1592
1449
  writer.setSelection(previousSelectionRanges);
1593
1450
  });
1594
1451
  }
1452
+ /**
1453
+ * @inheritDoc
1454
+ */ constructor(editor){
1455
+ super(editor);
1456
+ /**
1457
+ * The DOM element that acts as a mounting point for the CKBox Edit Image dialog.
1458
+ */ this._wrapper = null;
1459
+ /**
1460
+ * The states of image processing in progress.
1461
+ */ this._processInProgress = new Set();
1462
+ this.value = false;
1463
+ this._canEdit = createEditabilityChecker(editor.config.get('ckbox.allowExternalImagesEditing'));
1464
+ this._prepareOptions = abortableDebounce((signal, state)=>this._prepareOptionsAbortable(signal, state));
1465
+ this._prepareListeners();
1466
+ }
1595
1467
  }
1596
1468
 
1597
- /**
1598
- * The CKBox image edit editing plugin.
1599
- */ class CKBoxImageEditEditing extends Plugin {
1469
+ class CKBoxImageEditEditing extends Plugin {
1600
1470
  /**
1601
- * @inheritDoc
1602
- */ static get pluginName() {
1471
+ * @inheritDoc
1472
+ */ static get pluginName() {
1603
1473
  return 'CKBoxImageEditEditing';
1604
1474
  }
1605
1475
  /**
1606
- * @inheritDoc
1607
- */ static get requires() {
1476
+ * @inheritDoc
1477
+ */ static get requires() {
1608
1478
  return [
1609
1479
  CKBoxEditing,
1610
1480
  CKBoxUtils,
@@ -1615,8 +1485,8 @@ function createUrlChecker(allowExternalImagesEditing) {
1615
1485
  ];
1616
1486
  }
1617
1487
  /**
1618
- * @inheritDoc
1619
- */ init() {
1488
+ * @inheritDoc
1489
+ */ init() {
1620
1490
  const { editor } = this;
1621
1491
  editor.commands.add('ckboxImageEdit', new CKBoxImageEditCommand(editor));
1622
1492
  }
@@ -1624,20 +1494,15 @@ function createUrlChecker(allowExternalImagesEditing) {
1624
1494
 
1625
1495
  var ckboxImageEditIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M1.201 1C.538 1 0 1.47 0 2.1v14.363c0 .64.534 1.037 1.186 1.037H5.06l5.058-5.078L6.617 9.15a.696.696 0 0 0-.957-.033L1.5 13.6V2.5h15v4.354a3.478 3.478 0 0 1 1.5.049V2.1c0-.63-.547-1.1-1.2-1.1H1.202Zm11.713 2.803a2.147 2.147 0 0 0-2.049 1.992 2.14 2.14 0 0 0 1.28 2.096 2.13 2.13 0 0 0 2.642-3.11 2.129 2.129 0 0 0-1.873-.978ZM8.089 17.635v2.388h2.389l7.046-7.046-2.39-2.39-7.045 7.048Zm11.282-6.507a.637.637 0 0 0 .139-.692.603.603 0 0 0-.139-.205l-1.49-1.488a.63.63 0 0 0-.899 0l-1.166 1.163 2.39 2.39 1.165-1.168Z\"/></svg>";
1626
1496
 
1627
- /**
1628
- * The UI plugin of the CKBox image edit feature.
1629
- *
1630
- * It registers the `'ckboxImageEdit'` UI button in the editor's {@link module:ui/componentfactory~ComponentFactory component factory}
1631
- * that allows you to open the CKBox dialog and edit the image.
1632
- */ class CKBoxImageEditUI extends Plugin {
1497
+ class CKBoxImageEditUI extends Plugin {
1633
1498
  /**
1634
- * @inheritDoc
1635
- */ static get pluginName() {
1499
+ * @inheritDoc
1500
+ */ static get pluginName() {
1636
1501
  return 'CKBoxImageEditUI';
1637
1502
  }
1638
1503
  /**
1639
- * @inheritDoc
1640
- */ init() {
1504
+ * @inheritDoc
1505
+ */ init() {
1641
1506
  const editor = this.editor;
1642
1507
  editor.ui.componentFactory.add('ckboxImageEdit', (locale)=>{
1643
1508
  const command = editor.commands.get('ckboxImageEdit');
@@ -1660,17 +1525,15 @@ var ckboxImageEditIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2
1660
1525
  }
1661
1526
  }
1662
1527
 
1663
- /**
1664
- * The CKBox image edit feature.
1665
- */ class CKBoxImageEdit extends Plugin {
1528
+ class CKBoxImageEdit extends Plugin {
1666
1529
  /**
1667
- * @inheritDoc
1668
- */ static get pluginName() {
1530
+ * @inheritDoc
1531
+ */ static get pluginName() {
1669
1532
  return 'CKBoxImageEdit';
1670
1533
  }
1671
1534
  /**
1672
- * @inheritDoc
1673
- */ static get requires() {
1535
+ * @inheritDoc
1536
+ */ static get requires() {
1674
1537
  return [
1675
1538
  CKBoxImageEditEditing,
1676
1539
  CKBoxImageEditUI