@ckeditor/ckeditor5-ckbox 0.0.0-nightly-20241219.0 → 0.0.0-nightly-20241219.2

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
@@ -21,18 +21,18 @@ import { isEqual } from 'lodash-es';
21
21
  * It also integrates with the `insertImage` toolbar component and `menuBar:insertImage` menu component.
22
22
  */ class CKBoxUI extends Plugin {
23
23
  /**
24
- * @inheritDoc
25
- */ static get pluginName() {
24
+ * @inheritDoc
25
+ */ static get pluginName() {
26
26
  return 'CKBoxUI';
27
27
  }
28
28
  /**
29
- * @inheritDoc
30
- */ static get isOfficialPlugin() {
29
+ * @inheritDoc
30
+ */ static get isOfficialPlugin() {
31
31
  return true;
32
32
  }
33
33
  /**
34
- * @inheritDoc
35
- */ afterInit() {
34
+ * @inheritDoc
35
+ */ afterInit() {
36
36
  const editor = this.editor;
37
37
  // Do not register the `ckbox` button if the command does not exist.
38
38
  // This might happen when CKBox library is not loaded on the page.
@@ -52,8 +52,8 @@ import { isEqual } from 'lodash-es';
52
52
  }
53
53
  }
54
54
  /**
55
- * Creates the base for various kinds of the button component provided by this feature.
56
- */ _createButton(ButtonClass) {
55
+ * Creates the base for various kinds of the button component provided by this feature.
56
+ */ _createButton(ButtonClass) {
57
57
  const editor = this.editor;
58
58
  const locale = editor.locale;
59
59
  const view = new ButtonClass(locale);
@@ -65,8 +65,8 @@ import { isEqual } from 'lodash-es';
65
65
  return view;
66
66
  }
67
67
  /**
68
- * Creates a simple toolbar button for files management, with an icon and a tooltip.
69
- */ _createFileToolbarButton() {
68
+ * Creates a simple toolbar button for files management, with an icon and a tooltip.
69
+ */ _createFileToolbarButton() {
70
70
  const t = this.editor.locale.t;
71
71
  const button = this._createButton(ButtonView);
72
72
  button.icon = icons.browseFiles;
@@ -75,8 +75,8 @@ import { isEqual } from 'lodash-es';
75
75
  return button;
76
76
  }
77
77
  /**
78
- * Creates a simple toolbar button for images management, with an icon and a tooltip.
79
- */ _createImageToolbarButton() {
78
+ * Creates a simple toolbar button for images management, with an icon and a tooltip.
79
+ */ _createImageToolbarButton() {
80
80
  const t = this.editor.locale.t;
81
81
  const imageInsertUI = this.editor.plugins.get('ImageInsertUI');
82
82
  const button = this._createButton(ButtonView);
@@ -86,8 +86,8 @@ import { isEqual } from 'lodash-es';
86
86
  return button;
87
87
  }
88
88
  /**
89
- * Creates a button for images management for the dropdown view, with an icon, text and no tooltip.
90
- */ _createImageDropdownButton() {
89
+ * Creates a button for images management for the dropdown view, with an icon, text and no tooltip.
90
+ */ _createImageDropdownButton() {
91
91
  const t = this.editor.locale.t;
92
92
  const imageInsertUI = this.editor.plugins.get('ImageInsertUI');
93
93
  const button = this._createButton(ButtonView);
@@ -100,8 +100,8 @@ import { isEqual } from 'lodash-es';
100
100
  return button;
101
101
  }
102
102
  /**
103
- * Creates a button for files management for the menu bar.
104
- */ _createFileMenuBarButton() {
103
+ * Creates a button for files management for the menu bar.
104
+ */ _createFileMenuBarButton() {
105
105
  const t = this.editor.locale.t;
106
106
  const button = this._createButton(MenuBarMenuListItemButtonView);
107
107
  button.icon = icons.browseFiles;
@@ -110,8 +110,8 @@ import { isEqual } from 'lodash-es';
110
110
  return button;
111
111
  }
112
112
  /**
113
- * Creates a button for images management for the menu bar.
114
- */ _createImageMenuBarButton(type) {
113
+ * Creates a button for images management for the menu bar.
114
+ */ _createImageMenuBarButton(type) {
115
115
  // Use t() stored in a variable with a different name to reuse existing translations from another package.
116
116
  const translateVariableKey = this.editor.locale.t;
117
117
  const t = this.editor.locale.t;
@@ -312,53 +312,53 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
312
312
  * {@link module:link/link~Link Link feature}.
313
313
  */ class CKBoxCommand extends Command {
314
314
  /**
315
- * @inheritDoc
316
- */ constructor(editor){
315
+ * A set of all chosen assets. They are stored temporarily and they are automatically removed 1 second after being chosen.
316
+ * Chosen assets have to be "remembered" for a while to be able to map the given asset with the element inserted into the model.
317
+ * This association map is then used to set the ID on the model element.
318
+ *
319
+ * All chosen assets are automatically removed after the timeout, because (theoretically) it may happen that they will never be
320
+ * inserted into the model, even if the {@link module:link/linkcommand~LinkCommand `'link'`} command or the
321
+ * {@link module:image/image/insertimagecommand~InsertImageCommand `'insertImage'`} command is enabled. Such a case may arise when
322
+ * another plugin blocks the command execution. Then, in order not to keep the chosen (but not inserted) assets forever, we delete
323
+ * them automatically to prevent memory leakage. The 1 second timeout is enough to insert the asset into the model and extract the
324
+ * ID from the chosen asset.
325
+ *
326
+ * The assets are stored only if
327
+ * the {@link module:ckbox/ckboxconfig~CKBoxConfig#ignoreDataId `config.ckbox.ignoreDataId`} option is set to `false` (by default).
328
+ *
329
+ * @internal
330
+ */ _chosenAssets = new Set();
331
+ /**
332
+ * The DOM element that acts as a mounting point for the CKBox dialog.
333
+ */ _wrapper = null;
334
+ /**
335
+ * @inheritDoc
336
+ */ constructor(editor){
317
337
  super(editor);
318
- /**
319
- * A set of all chosen assets. They are stored temporarily and they are automatically removed 1 second after being chosen.
320
- * Chosen assets have to be "remembered" for a while to be able to map the given asset with the element inserted into the model.
321
- * This association map is then used to set the ID on the model element.
322
- *
323
- * All chosen assets are automatically removed after the timeout, because (theoretically) it may happen that they will never be
324
- * inserted into the model, even if the {@link module:link/linkcommand~LinkCommand `'link'`} command or the
325
- * {@link module:image/image/insertimagecommand~InsertImageCommand `'insertImage'`} command is enabled. Such a case may arise when
326
- * another plugin blocks the command execution. Then, in order not to keep the chosen (but not inserted) assets forever, we delete
327
- * them automatically to prevent memory leakage. The 1 second timeout is enough to insert the asset into the model and extract the
328
- * ID from the chosen asset.
329
- *
330
- * The assets are stored only if
331
- * the {@link module:ckbox/ckboxconfig~CKBoxConfig#ignoreDataId `config.ckbox.ignoreDataId`} option is set to `false` (by default).
332
- *
333
- * @internal
334
- */ this._chosenAssets = new Set();
335
- /**
336
- * The DOM element that acts as a mounting point for the CKBox dialog.
337
- */ this._wrapper = null;
338
338
  this._initListeners();
339
339
  }
340
340
  /**
341
- * @inheritDoc
342
- */ refresh() {
341
+ * @inheritDoc
342
+ */ refresh() {
343
343
  this.value = this._getValue();
344
344
  this.isEnabled = this._checkEnabled();
345
345
  }
346
346
  /**
347
- * @inheritDoc
348
- */ execute() {
347
+ * @inheritDoc
348
+ */ execute() {
349
349
  this.fire('ckbox:open');
350
350
  }
351
351
  /**
352
- * Indicates if the CKBox dialog is already opened.
353
- *
354
- * @protected
355
- * @returns {Boolean}
356
- */ _getValue() {
352
+ * Indicates if the CKBox dialog is already opened.
353
+ *
354
+ * @protected
355
+ * @returns {Boolean}
356
+ */ _getValue() {
357
357
  return this._wrapper !== null;
358
358
  }
359
359
  /**
360
- * Checks whether the command can be enabled in the current context.
361
- */ _checkEnabled() {
360
+ * Checks whether the command can be enabled in the current context.
361
+ */ _checkEnabled() {
362
362
  const imageCommand = this.editor.commands.get('insertImage');
363
363
  const linkCommand = this.editor.commands.get('link');
364
364
  if (!imageCommand.isEnabled && !linkCommand.isEnabled) {
@@ -367,29 +367,29 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
367
367
  return true;
368
368
  }
369
369
  /**
370
- * Creates the options object for the CKBox dialog.
371
- *
372
- * @returns The object with properties:
373
- * - theme The theme for CKBox dialog.
374
- * - language The language for CKBox dialog.
375
- * - tokenUrl The token endpoint URL.
376
- * - serviceOrigin The base URL of the API service.
377
- * - forceDemoLabel Whether to force "Powered by CKBox" link.
378
- * - assets.onChoose The callback function invoked after choosing the assets.
379
- * - dialog.onClose The callback function invoked after closing the CKBox dialog.
380
- * - dialog.width The dialog width in pixels.
381
- * - dialog.height The dialog height in pixels.
382
- * - categories.icons Allows setting custom icons for categories.
383
- * - view.openLastView Sets if the last view visited by the user will be reopened
384
- * on the next startup.
385
- * - view.startupFolderId Sets the ID of the folder that will be opened on startup.
386
- * - view.startupCategoryId Sets the ID of the category that will be opened on startup.
387
- * - view.hideMaximizeButton Sets whether to hide the ‘Maximize’ button.
388
- * - view.componentsHideTimeout Sets timeout after which upload components are hidden
389
- * after completed upload.
390
- * - view.dialogMinimizeTimeout Sets timeout after which upload dialog is minimized
391
- * after completed upload.
392
- */ _prepareOptions() {
370
+ * Creates the options object for the CKBox dialog.
371
+ *
372
+ * @returns The object with properties:
373
+ * - theme The theme for CKBox dialog.
374
+ * - language The language for CKBox dialog.
375
+ * - tokenUrl The token endpoint URL.
376
+ * - serviceOrigin The base URL of the API service.
377
+ * - forceDemoLabel Whether to force "Powered by CKBox" link.
378
+ * - assets.onChoose The callback function invoked after choosing the assets.
379
+ * - dialog.onClose The callback function invoked after closing the CKBox dialog.
380
+ * - dialog.width The dialog width in pixels.
381
+ * - dialog.height The dialog height in pixels.
382
+ * - categories.icons Allows setting custom icons for categories.
383
+ * - view.openLastView Sets if the last view visited by the user will be reopened
384
+ * on the next startup.
385
+ * - view.startupFolderId Sets the ID of the folder that will be opened on startup.
386
+ * - view.startupCategoryId Sets the ID of the category that will be opened on startup.
387
+ * - view.hideMaximizeButton Sets whether to hide the ‘Maximize’ button.
388
+ * - view.componentsHideTimeout Sets timeout after which upload components are hidden
389
+ * after completed upload.
390
+ * - view.dialogMinimizeTimeout Sets timeout after which upload dialog is minimized
391
+ * after completed upload.
392
+ */ _prepareOptions() {
393
393
  const editor = this.editor;
394
394
  const ckboxConfig = editor.config.get('ckbox');
395
395
  const dialog = ckboxConfig.dialog;
@@ -427,8 +427,8 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
427
427
  };
428
428
  }
429
429
  /**
430
- * Initializes various event listeners for the `ckbox:*` events, because all functionality of the `ckbox` command is event-based.
431
- */ _initListeners() {
430
+ * Initializes various event listeners for the `ckbox:*` events, because all functionality of the `ckbox` command is event-based.
431
+ */ _initListeners() {
432
432
  const editor = this.editor;
433
433
  const model = editor.model;
434
434
  const shouldInsertDataId = !editor.config.get('ckbox.ignoreDataId');
@@ -497,13 +497,13 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
497
497
  });
498
498
  }
499
499
  /**
500
- * Inserts the asset into the model.
501
- *
502
- * @param asset The asset to be inserted.
503
- * @param isLastAsset Indicates if the current asset is the last one from the chosen set.
504
- * @param writer An instance of the model writer.
505
- * @param isSingleAsset It's true when only one asset is processed.
506
- */ _insertAsset(asset, isLastAsset, writer, isSingleAsset) {
500
+ * Inserts the asset into the model.
501
+ *
502
+ * @param asset The asset to be inserted.
503
+ * @param isLastAsset Indicates if the current asset is the last one from the chosen set.
504
+ * @param writer An instance of the model writer.
505
+ * @param isSingleAsset It's true when only one asset is processed.
506
+ */ _insertAsset(asset, isLastAsset, writer, isSingleAsset) {
507
507
  const editor = this.editor;
508
508
  const model = editor.model;
509
509
  const selection = model.document.selection;
@@ -521,10 +521,10 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
521
521
  }
522
522
  }
523
523
  /**
524
- * Inserts the image by calling the `insertImage` command.
525
- *
526
- * @param asset The asset to be inserted.
527
- */ _insertImage(asset) {
524
+ * Inserts the image by calling the `insertImage` command.
525
+ *
526
+ * @param asset The asset to be inserted.
527
+ */ _insertImage(asset) {
528
528
  const editor = this.editor;
529
529
  const { imageFallbackUrl, imageSources, imageTextAlternative, imageWidth, imageHeight, imagePlaceholder } = asset.attributes;
530
530
  editor.execute('insertImage', {
@@ -541,12 +541,12 @@ const ASSET_INSERTION_WAIT_TIMEOUT = 1000;
541
541
  });
542
542
  }
543
543
  /**
544
- * Inserts the link to the asset by calling the `link` command.
545
- *
546
- * @param asset The asset to be inserted.
547
- * @param writer An instance of the model writer.
548
- * @param isSingleAsset It's true when only one asset is processed.
549
- */ _insertLink(asset, writer, isSingleAsset) {
544
+ * Inserts the link to the asset by calling the `link` command.
545
+ *
546
+ * @param asset The asset to be inserted.
547
+ * @param writer An instance of the model writer.
548
+ * @param isSingleAsset It's true when only one asset is processed.
549
+ */ _insertLink(asset, writer, isSingleAsset) {
550
550
  const editor = this.editor;
551
551
  const model = editor.model;
552
552
  const selection = model.document.selection;
@@ -641,25 +641,28 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
641
641
  * The CKBox utilities plugin.
642
642
  */ class CKBoxUtils extends Plugin {
643
643
  /**
644
- * @inheritDoc
645
- */ static get pluginName() {
644
+ * CKEditor Cloud Services access token.
645
+ */ _token;
646
+ /**
647
+ * @inheritDoc
648
+ */ static get pluginName() {
646
649
  return 'CKBoxUtils';
647
650
  }
648
651
  /**
649
- * @inheritDoc
650
- */ static get isOfficialPlugin() {
652
+ * @inheritDoc
653
+ */ static get isOfficialPlugin() {
651
654
  return true;
652
655
  }
653
656
  /**
654
- * @inheritDoc
655
- */ static get requires() {
657
+ * @inheritDoc
658
+ */ static get requires() {
656
659
  return [
657
660
  'CloudServices'
658
661
  ];
659
662
  }
660
663
  /**
661
- * @inheritDoc
662
- */ init() {
664
+ * @inheritDoc
665
+ */ init() {
663
666
  const editor = this.editor;
664
667
  const hasConfiguration = !!editor.config.get('ckbox');
665
668
  const isLibraryLoaded = !!window.CKBox;
@@ -681,22 +684,22 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
681
684
  const ckboxTokenUrl = editor.config.get('ckbox.tokenUrl');
682
685
  if (!ckboxTokenUrl) {
683
686
  /**
684
- * The {@link module:ckbox/ckboxconfig~CKBoxConfig#tokenUrl `config.ckbox.tokenUrl`} or the
685
- * {@link module:cloud-services/cloudservicesconfig~CloudServicesConfig#tokenUrl `config.cloudServices.tokenUrl`}
686
- * configuration is required for the CKBox plugin.
687
- *
688
- * ```ts
689
- * ClassicEditor.create( document.createElement( 'div' ), {
690
- * ckbox: {
691
- * tokenUrl: "YOUR_TOKEN_URL"
692
- * // ...
693
- * }
694
- * // ...
695
- * } );
696
- * ```
697
- *
698
- * @error ckbox-plugin-missing-token-url
699
- */ throw new CKEditorError('ckbox-plugin-missing-token-url', this);
687
+ * The {@link module:ckbox/ckboxconfig~CKBoxConfig#tokenUrl `config.ckbox.tokenUrl`} or the
688
+ * {@link module:cloud-services/cloudservicesconfig~CloudServicesConfig#tokenUrl `config.cloudServices.tokenUrl`}
689
+ * configuration is required for the CKBox plugin.
690
+ *
691
+ * ```ts
692
+ * ClassicEditor.create( document.createElement( 'div' ), {
693
+ * ckbox: {
694
+ * tokenUrl: "YOUR_TOKEN_URL"
695
+ * // ...
696
+ * }
697
+ * // ...
698
+ * } );
699
+ * ```
700
+ *
701
+ * @error ckbox-plugin-missing-token-url
702
+ */ throw new CKEditorError('ckbox-plugin-missing-token-url', this);
700
703
  }
701
704
  if (ckboxTokenUrl == cloudServicesTokenUrl) {
702
705
  this._token = Promise.resolve(cloudServices.token);
@@ -705,30 +708,30 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
705
708
  }
706
709
  }
707
710
  /**
708
- * Returns a token used by the CKBox plugin for communication with the CKBox service.
709
- */ getToken() {
711
+ * Returns a token used by the CKBox plugin for communication with the CKBox service.
712
+ */ getToken() {
710
713
  return this._token;
711
714
  }
712
715
  /**
713
- * The ID of workspace to use when uploading an image.
714
- */ async getWorkspaceId() {
716
+ * The ID of workspace to use when uploading an image.
717
+ */ async getWorkspaceId() {
715
718
  const t = this.editor.t;
716
719
  const cannotAccessDefaultWorkspaceError = t('Cannot access default workspace.');
717
720
  const defaultWorkspaceId = this.editor.config.get('ckbox.defaultUploadWorkspaceId');
718
721
  const workspaceId = getWorkspaceId(await this._token, defaultWorkspaceId);
719
722
  if (workspaceId == null) {
720
723
  /**
721
- * The user is not authorized to access the workspace defined in the`ckbox.defaultUploadWorkspaceId` configuration.
722
- *
723
- * @error ckbox-access-default-workspace-error
724
- */ logError('ckbox-access-default-workspace-error');
724
+ * The user is not authorized to access the workspace defined in the`ckbox.defaultUploadWorkspaceId` configuration.
725
+ *
726
+ * @error ckbox-access-default-workspace-error
727
+ */ logError('ckbox-access-default-workspace-error');
725
728
  throw cannotAccessDefaultWorkspaceError;
726
729
  }
727
730
  return workspaceId;
728
731
  }
729
732
  /**
730
- * Resolves a promise with an object containing a category with which the uploaded file is associated or an error code.
731
- */ async getCategoryIdForFile(fileOrUrl, options) {
733
+ * Resolves a promise with an object containing a category with which the uploaded file is associated or an error code.
734
+ */ async getCategoryIdForFile(fileOrUrl, options) {
732
735
  const t = this.editor.t;
733
736
  const cannotFindCategoryError = t('Cannot determine a category for the uploaded file.');
734
737
  const defaultCategories = this.editor.config.get('ckbox.defaultUploadCategories');
@@ -761,10 +764,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
761
764
  return category.id;
762
765
  }
763
766
  /**
764
- * Resolves a promise with an array containing available categories with which the uploaded file can be associated.
765
- *
766
- * If the API returns limited results, the method will collect all items.
767
- */ async _getAvailableCategories(options) {
767
+ * Resolves a promise with an array containing available categories with which the uploaded file can be associated.
768
+ *
769
+ * If the API returns limited results, the method will collect all items.
770
+ */ async _getAvailableCategories(options) {
768
771
  const ITEMS_PER_REQUEST = 50;
769
772
  const editor = this.editor;
770
773
  const token = this._token;
@@ -785,10 +788,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
785
788
  } catch {
786
789
  signal.throwIfAborted();
787
790
  /**
788
- * Fetching a list of available categories with which an uploaded file can be associated failed.
789
- *
790
- * @error ckbox-fetch-category-http-error
791
- */ logError('ckbox-fetch-category-http-error');
791
+ * Fetching a list of available categories with which an uploaded file can be associated failed.
792
+ *
793
+ * @error ckbox-fetch-category-http-error
794
+ */ logError('ckbox-fetch-category-http-error');
792
795
  return undefined;
793
796
  }
794
797
  async function fetchCategories(offset) {
@@ -815,8 +818,8 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
815
818
  * other ways to upload images into CKEditor 5.
816
819
  */ class CKBoxUploadAdapter extends Plugin {
817
820
  /**
818
- * @inheritDoc
819
- */ static get requires() {
821
+ * @inheritDoc
822
+ */ static get requires() {
820
823
  return [
821
824
  'ImageUploadEditing',
822
825
  'ImageUploadProgress',
@@ -825,18 +828,18 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
825
828
  ];
826
829
  }
827
830
  /**
828
- * @inheritDoc
829
- */ static get pluginName() {
831
+ * @inheritDoc
832
+ */ static get pluginName() {
830
833
  return 'CKBoxUploadAdapter';
831
834
  }
832
835
  /**
833
- * @inheritDoc
834
- */ static get isOfficialPlugin() {
836
+ * @inheritDoc
837
+ */ static get isOfficialPlugin() {
835
838
  return true;
836
839
  }
837
840
  /**
838
- * @inheritDoc
839
- */ async afterInit() {
841
+ * @inheritDoc
842
+ */ async afterInit() {
840
843
  const editor = this.editor;
841
844
  const hasConfiguration = !!editor.config.get('ckbox');
842
845
  const isLibraryLoaded = !!window.CKBox;
@@ -865,8 +868,26 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
865
868
  * Upload adapter for CKBox.
866
869
  */ class Adapter {
867
870
  /**
868
- * Creates a new adapter instance.
869
- */ constructor(loader, editor, ckboxUtils){
871
+ * FileLoader instance to use during the upload.
872
+ */ loader;
873
+ /**
874
+ * CKEditor Cloud Services access token.
875
+ */ token;
876
+ /**
877
+ * The editor instance.
878
+ */ editor;
879
+ /**
880
+ * The abort controller for aborting asynchronous processes.
881
+ */ controller;
882
+ /**
883
+ * The base URL where all requests should be sent.
884
+ */ serviceOrigin;
885
+ /**
886
+ * The reference to CKBoxUtils plugin.
887
+ */ ckboxUtils;
888
+ /**
889
+ * Creates a new adapter instance.
890
+ */ constructor(loader, editor, ckboxUtils){
870
891
  this.loader = loader;
871
892
  this.token = ckboxUtils.getToken();
872
893
  this.ckboxUtils = ckboxUtils;
@@ -875,10 +896,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
875
896
  this.serviceOrigin = editor.config.get('ckbox.serviceOrigin');
876
897
  }
877
898
  /**
878
- * Starts the upload process.
879
- *
880
- * @see module:upload/filerepository~UploadAdapter#upload
881
- */ async upload() {
899
+ * Starts the upload process.
900
+ *
901
+ * @see module:upload/filerepository~UploadAdapter#upload
902
+ */ async upload() {
882
903
  const ckboxUtils = this.ckboxUtils;
883
904
  const t = this.editor.t;
884
905
  const file = await this.loader.file;
@@ -916,10 +937,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
916
937
  });
917
938
  }
918
939
  /**
919
- * Aborts the upload process.
920
- *
921
- * @see module:upload/filerepository~UploadAdapter#abort
922
- */ abort() {
940
+ * Aborts the upload process.
941
+ *
942
+ * @see module:upload/filerepository~UploadAdapter#abort
943
+ */ abort() {
923
944
  this.controller.abort();
924
945
  }
925
946
  }
@@ -930,18 +951,18 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
930
951
  * {@link module:ckbox/ckboxuploadadapter~CKBoxUploadAdapter CKBox upload adapter}.
931
952
  */ class CKBoxEditing extends Plugin {
932
953
  /**
933
- * @inheritDoc
934
- */ static get pluginName() {
954
+ * @inheritDoc
955
+ */ static get pluginName() {
935
956
  return 'CKBoxEditing';
936
957
  }
937
958
  /**
938
- * @inheritDoc
939
- */ static get isOfficialPlugin() {
959
+ * @inheritDoc
960
+ */ static get isOfficialPlugin() {
940
961
  return true;
941
962
  }
942
963
  /**
943
- * @inheritDoc
944
- */ static get requires() {
964
+ * @inheritDoc
965
+ */ static get requires() {
945
966
  return [
946
967
  'LinkEditing',
947
968
  'PictureEditing',
@@ -950,8 +971,8 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
950
971
  ];
951
972
  }
952
973
  /**
953
- * @inheritDoc
954
- */ init() {
974
+ * @inheritDoc
975
+ */ init() {
955
976
  const editor = this.editor;
956
977
  if (!this._shouldBeInitialised()) {
957
978
  return;
@@ -969,8 +990,8 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
969
990
  });
970
991
  }
971
992
  /**
972
- * @inheritDoc
973
- */ afterInit() {
993
+ * @inheritDoc
994
+ */ afterInit() {
974
995
  const editor = this.editor;
975
996
  if (!this._shouldBeInitialised()) {
976
997
  return;
@@ -984,16 +1005,16 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
984
1005
  }
985
1006
  }
986
1007
  /**
987
- * Returns true only when the integrator intentionally wants to use the plugin, i.e. when the `config.ckbox` exists or
988
- * the CKBox JavaScript library is loaded.
989
- */ _shouldBeInitialised() {
1008
+ * Returns true only when the integrator intentionally wants to use the plugin, i.e. when the `config.ckbox` exists or
1009
+ * the CKBox JavaScript library is loaded.
1010
+ */ _shouldBeInitialised() {
990
1011
  const editor = this.editor;
991
1012
  const hasConfiguration = !!editor.config.get('ckbox');
992
1013
  return hasConfiguration || isLibraryLoaded();
993
1014
  }
994
1015
  /**
995
- * Blocks `uploadImage` and `ckboxImageEdit` commands.
996
- */ _blockImageCommands() {
1016
+ * Blocks `uploadImage` and `ckboxImageEdit` commands.
1017
+ */ _blockImageCommands() {
997
1018
  const editor = this.editor;
998
1019
  const uploadImageCommand = editor.commands.get('uploadImage');
999
1020
  const imageEditingCommand = editor.commands.get('ckboxImageEdit');
@@ -1006,27 +1027,27 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
1006
1027
  }
1007
1028
  }
1008
1029
  /**
1009
- * Checks if at least one image plugin is loaded.
1010
- */ _checkImagePlugins() {
1030
+ * Checks if at least one image plugin is loaded.
1031
+ */ _checkImagePlugins() {
1011
1032
  const editor = this.editor;
1012
1033
  if (!editor.plugins.has('ImageBlockEditing') && !editor.plugins.has('ImageInlineEditing')) {
1013
1034
  /**
1014
- * The CKBox feature requires one of the following plugins to be loaded to work correctly:
1015
- *
1016
- * * {@link module:image/imageblock~ImageBlock},
1017
- * * {@link module:image/imageinline~ImageInline},
1018
- * * {@link module:image/image~Image} (loads both `ImageBlock` and `ImageInline`)
1019
- *
1020
- * Please make sure your editor configuration is correct.
1021
- *
1022
- * @error ckbox-plugin-image-feature-missing
1023
- * @param {module:core/editor/editor~Editor} editor
1024
- */ logError('ckbox-plugin-image-feature-missing', editor);
1035
+ * The CKBox feature requires one of the following plugins to be loaded to work correctly:
1036
+ *
1037
+ * * {@link module:image/imageblock~ImageBlock},
1038
+ * * {@link module:image/imageinline~ImageInline},
1039
+ * * {@link module:image/image~Image} (loads both `ImageBlock` and `ImageInline`)
1040
+ *
1041
+ * Please make sure your editor configuration is correct.
1042
+ *
1043
+ * @error ckbox-plugin-image-feature-missing
1044
+ * @param {module:core/editor/editor~Editor} editor
1045
+ */ logError('ckbox-plugin-image-feature-missing', editor);
1025
1046
  }
1026
1047
  }
1027
1048
  /**
1028
- * Extends the schema to allow the `ckboxImageId` and `ckboxLinkId` attributes for links and images.
1029
- */ _initSchema() {
1049
+ * Extends the schema to allow the `ckboxImageId` and `ckboxLinkId` attributes for links and images.
1050
+ */ _initSchema() {
1030
1051
  const editor = this.editor;
1031
1052
  const schema = editor.model.schema;
1032
1053
  schema.extend('$text', {
@@ -1056,8 +1077,8 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
1056
1077
  }, 'ckboxLinkId');
1057
1078
  }
1058
1079
  /**
1059
- * Configures the upcast and downcast conversions for the `ckboxImageId` and `ckboxLinkId` attributes.
1060
- */ _initConversion() {
1080
+ * Configures the upcast and downcast conversions for the `ckboxImageId` and `ckboxLinkId` attributes.
1081
+ */ _initConversion() {
1061
1082
  const editor = this.editor;
1062
1083
  // Convert `ckboxLinkId` => `data-ckbox-resource-id`.
1063
1084
  editor.conversion.for('downcast').add((dispatcher)=>{
@@ -1178,8 +1199,8 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
1178
1199
  }
1179
1200
  }
1180
1201
  /**
1181
- * Registers post-fixers that add or remove the `ckboxLinkId` and `ckboxImageId` attributes.
1182
- */ _initFixers() {
1202
+ * Registers post-fixers that add or remove the `ckboxLinkId` and `ckboxImageId` attributes.
1203
+ */ _initFixers() {
1183
1204
  const editor = this.editor;
1184
1205
  const model = editor.model;
1185
1206
  const selection = model.document.selection;
@@ -1320,18 +1341,18 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
1320
1341
  * images into CKEditor 5.
1321
1342
  */ class CKBox extends Plugin {
1322
1343
  /**
1323
- * @inheritDoc
1324
- */ static get pluginName() {
1344
+ * @inheritDoc
1345
+ */ static get pluginName() {
1325
1346
  return 'CKBox';
1326
1347
  }
1327
1348
  /**
1328
- * @inheritDoc
1329
- */ static get isOfficialPlugin() {
1349
+ * @inheritDoc
1350
+ */ static get isOfficialPlugin() {
1330
1351
  return true;
1331
1352
  }
1332
1353
  /**
1333
- * @inheritDoc
1334
- */ static get requires() {
1354
+ * @inheritDoc
1355
+ */ static get requires() {
1335
1356
  return [
1336
1357
  CKBoxEditing,
1337
1358
  CKBoxUI
@@ -1381,38 +1402,44 @@ function createUrlChecker(allowExternalImagesEditing) {
1381
1402
  * Opens the CKBox dialog for editing the image.
1382
1403
  */ class CKBoxImageEditCommand extends Command {
1383
1404
  /**
1384
- * @inheritDoc
1385
- */ constructor(editor){
1405
+ * The DOM element that acts as a mounting point for the CKBox Edit Image dialog.
1406
+ */ _wrapper = null;
1407
+ /**
1408
+ * The states of image processing in progress.
1409
+ */ _processInProgress = new Set();
1410
+ /**
1411
+ * Determines if the element can be edited.
1412
+ */ _canEdit;
1413
+ /**
1414
+ * A wrapper function to prepare mount options. Ensures that at most one preparation is in-flight.
1415
+ */ _prepareOptions;
1416
+ /**
1417
+ * CKBox's onClose function runs before the final cleanup, potentially causing
1418
+ * page layout changes after it finishes. To address this, we use a setTimeout hack
1419
+ * to ensure that floating elements on the page maintain their correct position.
1420
+ *
1421
+ * See: https://github.com/ckeditor/ckeditor5/issues/16153.
1422
+ */ _updateUiDelayed = delay(()=>this.editor.ui.update(), 0);
1423
+ /**
1424
+ * @inheritDoc
1425
+ */ constructor(editor){
1386
1426
  super(editor);
1387
- /**
1388
- * The DOM element that acts as a mounting point for the CKBox Edit Image dialog.
1389
- */ this._wrapper = null;
1390
- /**
1391
- * The states of image processing in progress.
1392
- */ this._processInProgress = new Set();
1393
- /**
1394
- * CKBox's onClose function runs before the final cleanup, potentially causing
1395
- * page layout changes after it finishes. To address this, we use a setTimeout hack
1396
- * to ensure that floating elements on the page maintain their correct position.
1397
- *
1398
- * See: https://github.com/ckeditor/ckeditor5/issues/16153.
1399
- */ this._updateUiDelayed = delay(()=>this.editor.ui.update(), 0);
1400
1427
  this.value = false;
1401
1428
  this._canEdit = createEditabilityChecker(editor.config.get('ckbox.allowExternalImagesEditing'));
1402
1429
  this._prepareOptions = abortableDebounce((signal, state)=>this._prepareOptionsAbortable(signal, state));
1403
1430
  this._prepareListeners();
1404
1431
  }
1405
1432
  /**
1406
- * @inheritDoc
1407
- */ refresh() {
1433
+ * @inheritDoc
1434
+ */ refresh() {
1408
1435
  const editor = this.editor;
1409
1436
  this.value = this._getValue();
1410
1437
  const selectedElement = editor.model.document.selection.getSelectedElement();
1411
1438
  this.isEnabled = !!selectedElement && this._canEdit(selectedElement) && !this._checkIfElementIsBeingProcessed(selectedElement);
1412
1439
  }
1413
1440
  /**
1414
- * Opens the CKBox Image Editor dialog for editing the image.
1415
- */ execute() {
1441
+ * Opens the CKBox Image Editor dialog for editing the image.
1442
+ */ execute() {
1416
1443
  if (this._getValue()) {
1417
1444
  return;
1418
1445
  }
@@ -1439,8 +1466,8 @@ function createUrlChecker(allowExternalImagesEditing) {
1439
1466
  });
1440
1467
  }
1441
1468
  /**
1442
- * @inheritDoc
1443
- */ destroy() {
1469
+ * @inheritDoc
1470
+ */ destroy() {
1444
1471
  this._handleImageEditorClose();
1445
1472
  this._prepareOptions.abort();
1446
1473
  this._updateUiDelayed.cancel();
@@ -1450,13 +1477,13 @@ function createUrlChecker(allowExternalImagesEditing) {
1450
1477
  super.destroy();
1451
1478
  }
1452
1479
  /**
1453
- * Indicates if the CKBox Image Editor dialog is already opened.
1454
- */ _getValue() {
1480
+ * Indicates if the CKBox Image Editor dialog is already opened.
1481
+ */ _getValue() {
1455
1482
  return this._wrapper !== null;
1456
1483
  }
1457
1484
  /**
1458
- * Creates the options object for the CKBox Image Editor dialog.
1459
- */ async _prepareOptionsAbortable(signal, state) {
1485
+ * Creates the options object for the CKBox Image Editor dialog.
1486
+ */ async _prepareOptionsAbortable(signal, state) {
1460
1487
  const editor = this.editor;
1461
1488
  const ckboxConfig = editor.config.get('ckbox');
1462
1489
  const ckboxUtils = editor.plugins.get(CKBoxUtils);
@@ -1491,8 +1518,8 @@ function createUrlChecker(allowExternalImagesEditing) {
1491
1518
  };
1492
1519
  }
1493
1520
  /**
1494
- * Initializes event lister for an event of removing an image.
1495
- */ _prepareListeners() {
1521
+ * Initializes event lister for an event of removing an image.
1522
+ */ _prepareListeners() {
1496
1523
  // Abort editing processing when the image has been removed.
1497
1524
  this.listenTo(this.editor.model.document, 'change:data', ()=>{
1498
1525
  const processingStates = this._getProcessingStatesOfDeletedImages();
@@ -1502,8 +1529,8 @@ function createUrlChecker(allowExternalImagesEditing) {
1502
1529
  });
1503
1530
  }
1504
1531
  /**
1505
- * Gets processing states of images that have been deleted in the mean time.
1506
- */ _getProcessingStatesOfDeletedImages() {
1532
+ * Gets processing states of images that have been deleted in the mean time.
1533
+ */ _getProcessingStatesOfDeletedImages() {
1507
1534
  const states = [];
1508
1535
  for (const state of this._processInProgress.values()){
1509
1536
  if (state.element.root.rootName == '$graveyard') {
@@ -1521,8 +1548,8 @@ function createUrlChecker(allowExternalImagesEditing) {
1521
1548
  return false;
1522
1549
  }
1523
1550
  /**
1524
- * Closes the CKBox Image Editor dialog.
1525
- */ _handleImageEditorClose() {
1551
+ * Closes the CKBox Image Editor dialog.
1552
+ */ _handleImageEditorClose() {
1526
1553
  if (!this._wrapper) {
1527
1554
  return;
1528
1555
  }
@@ -1533,9 +1560,9 @@ function createUrlChecker(allowExternalImagesEditing) {
1533
1560
  this.refresh();
1534
1561
  }
1535
1562
  /**
1536
- * Save edited image. In case server respond with "success" replace with edited image,
1537
- * otherwise show notification error.
1538
- */ _handleImageEditorSave(state, asset) {
1563
+ * Save edited image. In case server respond with "success" replace with edited image,
1564
+ * otherwise show notification error.
1565
+ */ _handleImageEditorSave(state, asset) {
1539
1566
  const t = this.editor.locale.t;
1540
1567
  const notification = this.editor.plugins.get(Notification);
1541
1568
  const pendingActions = this.editor.plugins.get(PendingActions);
@@ -1565,9 +1592,9 @@ function createUrlChecker(allowExternalImagesEditing) {
1565
1592
  });
1566
1593
  }
1567
1594
  /**
1568
- * Get asset's status on server. If server responds with "success" status then
1569
- * image is already proceeded and ready for saving.
1570
- */ async _getAssetStatusFromServer(id, signal) {
1595
+ * Get asset's status on server. If server responds with "success" status then
1596
+ * image is already proceeded and ready for saving.
1597
+ */ async _getAssetStatusFromServer(id, signal) {
1571
1598
  const ckboxUtils = this.editor.plugins.get(CKBoxUtils);
1572
1599
  const url = new URL('assets/' + id, this.editor.config.get('ckbox.serviceOrigin'));
1573
1600
  const response = await sendHttpRequest({
@@ -1578,10 +1605,10 @@ function createUrlChecker(allowExternalImagesEditing) {
1578
1605
  const status = response.metadata.metadataProcessingStatus;
1579
1606
  if (!status || status == 'queued') {
1580
1607
  /**
1581
- * Image has not been processed yet.
1582
- *
1583
- * @error ckbox-image-not-processed
1584
- */ throw new CKEditorError('ckbox-image-not-processed');
1608
+ * Image has not been processed yet.
1609
+ *
1610
+ * @error ckbox-image-not-processed
1611
+ */ throw new CKEditorError('ckbox-image-not-processed');
1585
1612
  }
1586
1613
  return {
1587
1614
  data: {
@@ -1590,27 +1617,27 @@ function createUrlChecker(allowExternalImagesEditing) {
1590
1617
  };
1591
1618
  }
1592
1619
  /**
1593
- * Waits for an asset to be processed.
1594
- * It retries retrieving asset status from the server in case of failure.
1595
- */ async _waitForAssetProcessed(id, signal) {
1620
+ * Waits for an asset to be processed.
1621
+ * It retries retrieving asset status from the server in case of failure.
1622
+ */ async _waitForAssetProcessed(id, signal) {
1596
1623
  const result = await retry(()=>this._getAssetStatusFromServer(id, signal), {
1597
1624
  signal,
1598
1625
  maxAttempts: 5
1599
1626
  });
1600
1627
  if (result.data.metadata.metadataProcessingStatus != 'success') {
1601
1628
  /**
1602
- * The image processing failed.
1603
- *
1604
- * @error ckbox-image-processing-failed
1605
- */ throw new CKEditorError('ckbox-image-processing-failed');
1629
+ * The image processing failed.
1630
+ *
1631
+ * @error ckbox-image-processing-failed
1632
+ */ throw new CKEditorError('ckbox-image-processing-failed');
1606
1633
  }
1607
1634
  return result;
1608
1635
  }
1609
1636
  /**
1610
- * Shows processing indicator while image is processing.
1611
- *
1612
- * @param asset Data about certain asset.
1613
- */ _showImageProcessingIndicator(element, asset) {
1637
+ * Shows processing indicator while image is processing.
1638
+ *
1639
+ * @param asset Data about certain asset.
1640
+ */ _showImageProcessingIndicator(element, asset) {
1614
1641
  const editor = this.editor;
1615
1642
  editor.editing.view.change((writer)=>{
1616
1643
  const imageElementView = editor.editing.mapper.toViewElement(element);
@@ -1625,8 +1652,8 @@ function createUrlChecker(allowExternalImagesEditing) {
1625
1652
  });
1626
1653
  }
1627
1654
  /**
1628
- * Replace the edited image with the new one.
1629
- */ _replaceImage(element, asset) {
1655
+ * Replace the edited image with the new one.
1656
+ */ _replaceImage(element, asset) {
1630
1657
  const editor = this.editor;
1631
1658
  const { imageFallbackUrl, imageSources, imageWidth, imageHeight, imagePlaceholder } = prepareImageAssetAttributes(asset);
1632
1659
  const previousSelectionRanges = Array.from(editor.model.document.selection.getRanges());
@@ -1662,18 +1689,18 @@ function createUrlChecker(allowExternalImagesEditing) {
1662
1689
  * The CKBox image edit editing plugin.
1663
1690
  */ class CKBoxImageEditEditing extends Plugin {
1664
1691
  /**
1665
- * @inheritDoc
1666
- */ static get pluginName() {
1692
+ * @inheritDoc
1693
+ */ static get pluginName() {
1667
1694
  return 'CKBoxImageEditEditing';
1668
1695
  }
1669
1696
  /**
1670
- * @inheritDoc
1671
- */ static get isOfficialPlugin() {
1697
+ * @inheritDoc
1698
+ */ static get isOfficialPlugin() {
1672
1699
  return true;
1673
1700
  }
1674
1701
  /**
1675
- * @inheritDoc
1676
- */ static get requires() {
1702
+ * @inheritDoc
1703
+ */ static get requires() {
1677
1704
  return [
1678
1705
  CKBoxEditing,
1679
1706
  CKBoxUtils,
@@ -1684,8 +1711,8 @@ function createUrlChecker(allowExternalImagesEditing) {
1684
1711
  ];
1685
1712
  }
1686
1713
  /**
1687
- * @inheritDoc
1688
- */ init() {
1714
+ * @inheritDoc
1715
+ */ init() {
1689
1716
  const { editor } = this;
1690
1717
  editor.commands.add('ckboxImageEdit', new CKBoxImageEditCommand(editor));
1691
1718
  }
@@ -1700,18 +1727,18 @@ var ckboxImageEditIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2
1700
1727
  * that allows you to open the CKBox dialog and edit the image.
1701
1728
  */ class CKBoxImageEditUI extends Plugin {
1702
1729
  /**
1703
- * @inheritDoc
1704
- */ static get pluginName() {
1730
+ * @inheritDoc
1731
+ */ static get pluginName() {
1705
1732
  return 'CKBoxImageEditUI';
1706
1733
  }
1707
1734
  /**
1708
- * @inheritDoc
1709
- */ static get isOfficialPlugin() {
1735
+ * @inheritDoc
1736
+ */ static get isOfficialPlugin() {
1710
1737
  return true;
1711
1738
  }
1712
1739
  /**
1713
- * @inheritDoc
1714
- */ init() {
1740
+ * @inheritDoc
1741
+ */ init() {
1715
1742
  const editor = this.editor;
1716
1743
  editor.ui.componentFactory.add('ckboxImageEdit', (locale)=>{
1717
1744
  const command = editor.commands.get('ckboxImageEdit');
@@ -1739,18 +1766,18 @@ var ckboxImageEditIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2
1739
1766
  * The CKBox image edit feature.
1740
1767
  */ class CKBoxImageEdit extends Plugin {
1741
1768
  /**
1742
- * @inheritDoc
1743
- */ static get pluginName() {
1769
+ * @inheritDoc
1770
+ */ static get pluginName() {
1744
1771
  return 'CKBoxImageEdit';
1745
1772
  }
1746
1773
  /**
1747
- * @inheritDoc
1748
- */ static get isOfficialPlugin() {
1774
+ * @inheritDoc
1775
+ */ static get isOfficialPlugin() {
1749
1776
  return true;
1750
1777
  }
1751
1778
  /**
1752
- * @inheritDoc
1753
- */ static get requires() {
1779
+ * @inheritDoc
1780
+ */ static get requires() {
1754
1781
  return [
1755
1782
  CKBoxImageEditEditing,
1756
1783
  CKBoxImageEditUI