@ckeditor/ckeditor5-ckbox 0.0.0-nightly-20241216.0 → 0.0.0-nightly-20241218.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 +267 -294
- package/dist/index.js.map +1 -1
- package/package.json +27 -8
- package/dist/augmentation.d.ts +0 -36
- package/dist/ckbox.d.ts +0 -41
- package/dist/ckboxcommand.d.ts +0 -130
- package/dist/ckboxconfig.d.ts +0 -434
- package/dist/ckboxediting.d.ts +0 -65
- package/dist/ckboximageedit/ckboximageeditcommand.d.ts +0 -109
- package/dist/ckboximageedit/ckboximageeditediting.d.ts +0 -36
- package/dist/ckboximageedit/ckboximageeditui.d.ts +0 -32
- package/dist/ckboximageedit/utils.d.ts +0 -14
- package/dist/ckboximageedit.d.ts +0 -32
- package/dist/ckboxui.d.ts +0 -60
- package/dist/ckboxuploadadapter.d.ts +0 -41
- package/dist/ckboxutils.d.ts +0 -58
- package/dist/index.d.ts +0 -21
- package/dist/utils.d.ts +0 -67
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
|
-
|
25
|
-
|
24
|
+
* @inheritDoc
|
25
|
+
*/ static get pluginName() {
|
26
26
|
return 'CKBoxUI';
|
27
27
|
}
|
28
28
|
/**
|
29
|
-
|
30
|
-
|
29
|
+
* @inheritDoc
|
30
|
+
*/ static get isOfficialPlugin() {
|
31
31
|
return true;
|
32
32
|
}
|
33
33
|
/**
|
34
|
-
|
35
|
-
|
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
|
-
|
56
|
-
|
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
|
-
|
69
|
-
|
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
|
-
|
79
|
-
|
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
|
-
|
90
|
-
|
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
|
-
|
104
|
-
|
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
|
-
|
114
|
-
|
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
|
-
|
316
|
-
|
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){
|
315
|
+
* @inheritDoc
|
316
|
+
*/ constructor(editor){
|
337
317
|
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
|
-
|
342
|
-
|
341
|
+
* @inheritDoc
|
342
|
+
*/ refresh() {
|
343
343
|
this.value = this._getValue();
|
344
344
|
this.isEnabled = this._checkEnabled();
|
345
345
|
}
|
346
346
|
/**
|
347
|
-
|
348
|
-
|
347
|
+
* @inheritDoc
|
348
|
+
*/ execute() {
|
349
349
|
this.fire('ckbox:open');
|
350
350
|
}
|
351
351
|
/**
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
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
|
-
|
361
|
-
|
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
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
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
|
-
|
431
|
-
|
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
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
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
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
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
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
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,28 +641,25 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
|
|
641
641
|
* The CKBox utilities plugin.
|
642
642
|
*/ class CKBoxUtils extends Plugin {
|
643
643
|
/**
|
644
|
-
|
645
|
-
|
646
|
-
/**
|
647
|
-
* @inheritDoc
|
648
|
-
*/ static get pluginName() {
|
644
|
+
* @inheritDoc
|
645
|
+
*/ static get pluginName() {
|
649
646
|
return 'CKBoxUtils';
|
650
647
|
}
|
651
648
|
/**
|
652
|
-
|
653
|
-
|
649
|
+
* @inheritDoc
|
650
|
+
*/ static get isOfficialPlugin() {
|
654
651
|
return true;
|
655
652
|
}
|
656
653
|
/**
|
657
|
-
|
658
|
-
|
654
|
+
* @inheritDoc
|
655
|
+
*/ static get requires() {
|
659
656
|
return [
|
660
657
|
'CloudServices'
|
661
658
|
];
|
662
659
|
}
|
663
660
|
/**
|
664
|
-
|
665
|
-
|
661
|
+
* @inheritDoc
|
662
|
+
*/ init() {
|
666
663
|
const editor = this.editor;
|
667
664
|
const hasConfiguration = !!editor.config.get('ckbox');
|
668
665
|
const isLibraryLoaded = !!window.CKBox;
|
@@ -684,22 +681,22 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
|
|
684
681
|
const ckboxTokenUrl = editor.config.get('ckbox.tokenUrl');
|
685
682
|
if (!ckboxTokenUrl) {
|
686
683
|
/**
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
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);
|
703
700
|
}
|
704
701
|
if (ckboxTokenUrl == cloudServicesTokenUrl) {
|
705
702
|
this._token = Promise.resolve(cloudServices.token);
|
@@ -708,30 +705,30 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
|
|
708
705
|
}
|
709
706
|
}
|
710
707
|
/**
|
711
|
-
|
712
|
-
|
708
|
+
* Returns a token used by the CKBox plugin for communication with the CKBox service.
|
709
|
+
*/ getToken() {
|
713
710
|
return this._token;
|
714
711
|
}
|
715
712
|
/**
|
716
|
-
|
717
|
-
|
713
|
+
* The ID of workspace to use when uploading an image.
|
714
|
+
*/ async getWorkspaceId() {
|
718
715
|
const t = this.editor.t;
|
719
716
|
const cannotAccessDefaultWorkspaceError = t('Cannot access default workspace.');
|
720
717
|
const defaultWorkspaceId = this.editor.config.get('ckbox.defaultUploadWorkspaceId');
|
721
718
|
const workspaceId = getWorkspaceId(await this._token, defaultWorkspaceId);
|
722
719
|
if (workspaceId == null) {
|
723
720
|
/**
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
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');
|
728
725
|
throw cannotAccessDefaultWorkspaceError;
|
729
726
|
}
|
730
727
|
return workspaceId;
|
731
728
|
}
|
732
729
|
/**
|
733
|
-
|
734
|
-
|
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) {
|
735
732
|
const t = this.editor.t;
|
736
733
|
const cannotFindCategoryError = t('Cannot determine a category for the uploaded file.');
|
737
734
|
const defaultCategories = this.editor.config.get('ckbox.defaultUploadCategories');
|
@@ -764,10 +761,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
|
|
764
761
|
return category.id;
|
765
762
|
}
|
766
763
|
/**
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
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) {
|
771
768
|
const ITEMS_PER_REQUEST = 50;
|
772
769
|
const editor = this.editor;
|
773
770
|
const token = this._token;
|
@@ -788,10 +785,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
|
|
788
785
|
} catch {
|
789
786
|
signal.throwIfAborted();
|
790
787
|
/**
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
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');
|
795
792
|
return undefined;
|
796
793
|
}
|
797
794
|
async function fetchCategories(offset) {
|
@@ -818,8 +815,8 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
|
|
818
815
|
* other ways to upload images into CKEditor 5.
|
819
816
|
*/ class CKBoxUploadAdapter extends Plugin {
|
820
817
|
/**
|
821
|
-
|
822
|
-
|
818
|
+
* @inheritDoc
|
819
|
+
*/ static get requires() {
|
823
820
|
return [
|
824
821
|
'ImageUploadEditing',
|
825
822
|
'ImageUploadProgress',
|
@@ -828,18 +825,18 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
|
|
828
825
|
];
|
829
826
|
}
|
830
827
|
/**
|
831
|
-
|
832
|
-
|
828
|
+
* @inheritDoc
|
829
|
+
*/ static get pluginName() {
|
833
830
|
return 'CKBoxUploadAdapter';
|
834
831
|
}
|
835
832
|
/**
|
836
|
-
|
837
|
-
|
833
|
+
* @inheritDoc
|
834
|
+
*/ static get isOfficialPlugin() {
|
838
835
|
return true;
|
839
836
|
}
|
840
837
|
/**
|
841
|
-
|
842
|
-
|
838
|
+
* @inheritDoc
|
839
|
+
*/ async afterInit() {
|
843
840
|
const editor = this.editor;
|
844
841
|
const hasConfiguration = !!editor.config.get('ckbox');
|
845
842
|
const isLibraryLoaded = !!window.CKBox;
|
@@ -868,26 +865,8 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
|
|
868
865
|
* Upload adapter for CKBox.
|
869
866
|
*/ class Adapter {
|
870
867
|
/**
|
871
|
-
|
872
|
-
|
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){
|
868
|
+
* Creates a new adapter instance.
|
869
|
+
*/ constructor(loader, editor, ckboxUtils){
|
891
870
|
this.loader = loader;
|
892
871
|
this.token = ckboxUtils.getToken();
|
893
872
|
this.ckboxUtils = ckboxUtils;
|
@@ -896,10 +875,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
|
|
896
875
|
this.serviceOrigin = editor.config.get('ckbox.serviceOrigin');
|
897
876
|
}
|
898
877
|
/**
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
878
|
+
* Starts the upload process.
|
879
|
+
*
|
880
|
+
* @see module:upload/filerepository~UploadAdapter#upload
|
881
|
+
*/ async upload() {
|
903
882
|
const ckboxUtils = this.ckboxUtils;
|
904
883
|
const t = this.editor.t;
|
905
884
|
const file = await this.loader.file;
|
@@ -937,10 +916,10 @@ const DEFAULT_CKBOX_THEME_NAME = 'lark';
|
|
937
916
|
});
|
938
917
|
}
|
939
918
|
/**
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
919
|
+
* Aborts the upload process.
|
920
|
+
*
|
921
|
+
* @see module:upload/filerepository~UploadAdapter#abort
|
922
|
+
*/ abort() {
|
944
923
|
this.controller.abort();
|
945
924
|
}
|
946
925
|
}
|
@@ -951,18 +930,18 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
|
|
951
930
|
* {@link module:ckbox/ckboxuploadadapter~CKBoxUploadAdapter CKBox upload adapter}.
|
952
931
|
*/ class CKBoxEditing extends Plugin {
|
953
932
|
/**
|
954
|
-
|
955
|
-
|
933
|
+
* @inheritDoc
|
934
|
+
*/ static get pluginName() {
|
956
935
|
return 'CKBoxEditing';
|
957
936
|
}
|
958
937
|
/**
|
959
|
-
|
960
|
-
|
938
|
+
* @inheritDoc
|
939
|
+
*/ static get isOfficialPlugin() {
|
961
940
|
return true;
|
962
941
|
}
|
963
942
|
/**
|
964
|
-
|
965
|
-
|
943
|
+
* @inheritDoc
|
944
|
+
*/ static get requires() {
|
966
945
|
return [
|
967
946
|
'LinkEditing',
|
968
947
|
'PictureEditing',
|
@@ -971,8 +950,8 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
|
|
971
950
|
];
|
972
951
|
}
|
973
952
|
/**
|
974
|
-
|
975
|
-
|
953
|
+
* @inheritDoc
|
954
|
+
*/ init() {
|
976
955
|
const editor = this.editor;
|
977
956
|
if (!this._shouldBeInitialised()) {
|
978
957
|
return;
|
@@ -990,8 +969,8 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
|
|
990
969
|
});
|
991
970
|
}
|
992
971
|
/**
|
993
|
-
|
994
|
-
|
972
|
+
* @inheritDoc
|
973
|
+
*/ afterInit() {
|
995
974
|
const editor = this.editor;
|
996
975
|
if (!this._shouldBeInitialised()) {
|
997
976
|
return;
|
@@ -1005,16 +984,16 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
|
|
1005
984
|
}
|
1006
985
|
}
|
1007
986
|
/**
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
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() {
|
1011
990
|
const editor = this.editor;
|
1012
991
|
const hasConfiguration = !!editor.config.get('ckbox');
|
1013
992
|
return hasConfiguration || isLibraryLoaded();
|
1014
993
|
}
|
1015
994
|
/**
|
1016
|
-
|
1017
|
-
|
995
|
+
* Blocks `uploadImage` and `ckboxImageEdit` commands.
|
996
|
+
*/ _blockImageCommands() {
|
1018
997
|
const editor = this.editor;
|
1019
998
|
const uploadImageCommand = editor.commands.get('uploadImage');
|
1020
999
|
const imageEditingCommand = editor.commands.get('ckboxImageEdit');
|
@@ -1027,27 +1006,27 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
|
|
1027
1006
|
}
|
1028
1007
|
}
|
1029
1008
|
/**
|
1030
|
-
|
1031
|
-
|
1009
|
+
* Checks if at least one image plugin is loaded.
|
1010
|
+
*/ _checkImagePlugins() {
|
1032
1011
|
const editor = this.editor;
|
1033
1012
|
if (!editor.plugins.has('ImageBlockEditing') && !editor.plugins.has('ImageInlineEditing')) {
|
1034
1013
|
/**
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
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);
|
1046
1025
|
}
|
1047
1026
|
}
|
1048
1027
|
/**
|
1049
|
-
|
1050
|
-
|
1028
|
+
* Extends the schema to allow the `ckboxImageId` and `ckboxLinkId` attributes for links and images.
|
1029
|
+
*/ _initSchema() {
|
1051
1030
|
const editor = this.editor;
|
1052
1031
|
const schema = editor.model.schema;
|
1053
1032
|
schema.extend('$text', {
|
@@ -1077,8 +1056,8 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
|
|
1077
1056
|
}, 'ckboxLinkId');
|
1078
1057
|
}
|
1079
1058
|
/**
|
1080
|
-
|
1081
|
-
|
1059
|
+
* Configures the upcast and downcast conversions for the `ckboxImageId` and `ckboxLinkId` attributes.
|
1060
|
+
*/ _initConversion() {
|
1082
1061
|
const editor = this.editor;
|
1083
1062
|
// Convert `ckboxLinkId` => `data-ckbox-resource-id`.
|
1084
1063
|
editor.conversion.for('downcast').add((dispatcher)=>{
|
@@ -1199,8 +1178,8 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
|
|
1199
1178
|
}
|
1200
1179
|
}
|
1201
1180
|
/**
|
1202
|
-
|
1203
|
-
|
1181
|
+
* Registers post-fixers that add or remove the `ckboxLinkId` and `ckboxImageId` attributes.
|
1182
|
+
*/ _initFixers() {
|
1204
1183
|
const editor = this.editor;
|
1205
1184
|
const model = editor.model;
|
1206
1185
|
const selection = model.document.selection;
|
@@ -1341,18 +1320,18 @@ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
|
|
1341
1320
|
* images into CKEditor 5.
|
1342
1321
|
*/ class CKBox extends Plugin {
|
1343
1322
|
/**
|
1344
|
-
|
1345
|
-
|
1323
|
+
* @inheritDoc
|
1324
|
+
*/ static get pluginName() {
|
1346
1325
|
return 'CKBox';
|
1347
1326
|
}
|
1348
1327
|
/**
|
1349
|
-
|
1350
|
-
|
1328
|
+
* @inheritDoc
|
1329
|
+
*/ static get isOfficialPlugin() {
|
1351
1330
|
return true;
|
1352
1331
|
}
|
1353
1332
|
/**
|
1354
|
-
|
1355
|
-
|
1333
|
+
* @inheritDoc
|
1334
|
+
*/ static get requires() {
|
1356
1335
|
return [
|
1357
1336
|
CKBoxEditing,
|
1358
1337
|
CKBoxUI
|
@@ -1402,44 +1381,38 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1402
1381
|
* Opens the CKBox dialog for editing the image.
|
1403
1382
|
*/ class CKBoxImageEditCommand extends Command {
|
1404
1383
|
/**
|
1405
|
-
|
1406
|
-
|
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){
|
1384
|
+
* @inheritDoc
|
1385
|
+
*/ constructor(editor){
|
1426
1386
|
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);
|
1427
1400
|
this.value = false;
|
1428
1401
|
this._canEdit = createEditabilityChecker(editor.config.get('ckbox.allowExternalImagesEditing'));
|
1429
1402
|
this._prepareOptions = abortableDebounce((signal, state)=>this._prepareOptionsAbortable(signal, state));
|
1430
1403
|
this._prepareListeners();
|
1431
1404
|
}
|
1432
1405
|
/**
|
1433
|
-
|
1434
|
-
|
1406
|
+
* @inheritDoc
|
1407
|
+
*/ refresh() {
|
1435
1408
|
const editor = this.editor;
|
1436
1409
|
this.value = this._getValue();
|
1437
1410
|
const selectedElement = editor.model.document.selection.getSelectedElement();
|
1438
1411
|
this.isEnabled = !!selectedElement && this._canEdit(selectedElement) && !this._checkIfElementIsBeingProcessed(selectedElement);
|
1439
1412
|
}
|
1440
1413
|
/**
|
1441
|
-
|
1442
|
-
|
1414
|
+
* Opens the CKBox Image Editor dialog for editing the image.
|
1415
|
+
*/ execute() {
|
1443
1416
|
if (this._getValue()) {
|
1444
1417
|
return;
|
1445
1418
|
}
|
@@ -1466,8 +1439,8 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1466
1439
|
});
|
1467
1440
|
}
|
1468
1441
|
/**
|
1469
|
-
|
1470
|
-
|
1442
|
+
* @inheritDoc
|
1443
|
+
*/ destroy() {
|
1471
1444
|
this._handleImageEditorClose();
|
1472
1445
|
this._prepareOptions.abort();
|
1473
1446
|
this._updateUiDelayed.cancel();
|
@@ -1477,13 +1450,13 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1477
1450
|
super.destroy();
|
1478
1451
|
}
|
1479
1452
|
/**
|
1480
|
-
|
1481
|
-
|
1453
|
+
* Indicates if the CKBox Image Editor dialog is already opened.
|
1454
|
+
*/ _getValue() {
|
1482
1455
|
return this._wrapper !== null;
|
1483
1456
|
}
|
1484
1457
|
/**
|
1485
|
-
|
1486
|
-
|
1458
|
+
* Creates the options object for the CKBox Image Editor dialog.
|
1459
|
+
*/ async _prepareOptionsAbortable(signal, state) {
|
1487
1460
|
const editor = this.editor;
|
1488
1461
|
const ckboxConfig = editor.config.get('ckbox');
|
1489
1462
|
const ckboxUtils = editor.plugins.get(CKBoxUtils);
|
@@ -1518,8 +1491,8 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1518
1491
|
};
|
1519
1492
|
}
|
1520
1493
|
/**
|
1521
|
-
|
1522
|
-
|
1494
|
+
* Initializes event lister for an event of removing an image.
|
1495
|
+
*/ _prepareListeners() {
|
1523
1496
|
// Abort editing processing when the image has been removed.
|
1524
1497
|
this.listenTo(this.editor.model.document, 'change:data', ()=>{
|
1525
1498
|
const processingStates = this._getProcessingStatesOfDeletedImages();
|
@@ -1529,8 +1502,8 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1529
1502
|
});
|
1530
1503
|
}
|
1531
1504
|
/**
|
1532
|
-
|
1533
|
-
|
1505
|
+
* Gets processing states of images that have been deleted in the mean time.
|
1506
|
+
*/ _getProcessingStatesOfDeletedImages() {
|
1534
1507
|
const states = [];
|
1535
1508
|
for (const state of this._processInProgress.values()){
|
1536
1509
|
if (state.element.root.rootName == '$graveyard') {
|
@@ -1548,8 +1521,8 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1548
1521
|
return false;
|
1549
1522
|
}
|
1550
1523
|
/**
|
1551
|
-
|
1552
|
-
|
1524
|
+
* Closes the CKBox Image Editor dialog.
|
1525
|
+
*/ _handleImageEditorClose() {
|
1553
1526
|
if (!this._wrapper) {
|
1554
1527
|
return;
|
1555
1528
|
}
|
@@ -1560,9 +1533,9 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1560
1533
|
this.refresh();
|
1561
1534
|
}
|
1562
1535
|
/**
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1536
|
+
* Save edited image. In case server respond with "success" replace with edited image,
|
1537
|
+
* otherwise show notification error.
|
1538
|
+
*/ _handleImageEditorSave(state, asset) {
|
1566
1539
|
const t = this.editor.locale.t;
|
1567
1540
|
const notification = this.editor.plugins.get(Notification);
|
1568
1541
|
const pendingActions = this.editor.plugins.get(PendingActions);
|
@@ -1592,9 +1565,9 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1592
1565
|
});
|
1593
1566
|
}
|
1594
1567
|
/**
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
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) {
|
1598
1571
|
const ckboxUtils = this.editor.plugins.get(CKBoxUtils);
|
1599
1572
|
const url = new URL('assets/' + id, this.editor.config.get('ckbox.serviceOrigin'));
|
1600
1573
|
const response = await sendHttpRequest({
|
@@ -1605,10 +1578,10 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1605
1578
|
const status = response.metadata.metadataProcessingStatus;
|
1606
1579
|
if (!status || status == 'queued') {
|
1607
1580
|
/**
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1581
|
+
* Image has not been processed yet.
|
1582
|
+
*
|
1583
|
+
* @error ckbox-image-not-processed
|
1584
|
+
*/ throw new CKEditorError('ckbox-image-not-processed');
|
1612
1585
|
}
|
1613
1586
|
return {
|
1614
1587
|
data: {
|
@@ -1617,27 +1590,27 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1617
1590
|
};
|
1618
1591
|
}
|
1619
1592
|
/**
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
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) {
|
1623
1596
|
const result = await retry(()=>this._getAssetStatusFromServer(id, signal), {
|
1624
1597
|
signal,
|
1625
1598
|
maxAttempts: 5
|
1626
1599
|
});
|
1627
1600
|
if (result.data.metadata.metadataProcessingStatus != 'success') {
|
1628
1601
|
/**
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1602
|
+
* The image processing failed.
|
1603
|
+
*
|
1604
|
+
* @error ckbox-image-processing-failed
|
1605
|
+
*/ throw new CKEditorError('ckbox-image-processing-failed');
|
1633
1606
|
}
|
1634
1607
|
return result;
|
1635
1608
|
}
|
1636
1609
|
/**
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1610
|
+
* Shows processing indicator while image is processing.
|
1611
|
+
*
|
1612
|
+
* @param asset Data about certain asset.
|
1613
|
+
*/ _showImageProcessingIndicator(element, asset) {
|
1641
1614
|
const editor = this.editor;
|
1642
1615
|
editor.editing.view.change((writer)=>{
|
1643
1616
|
const imageElementView = editor.editing.mapper.toViewElement(element);
|
@@ -1652,8 +1625,8 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1652
1625
|
});
|
1653
1626
|
}
|
1654
1627
|
/**
|
1655
|
-
|
1656
|
-
|
1628
|
+
* Replace the edited image with the new one.
|
1629
|
+
*/ _replaceImage(element, asset) {
|
1657
1630
|
const editor = this.editor;
|
1658
1631
|
const { imageFallbackUrl, imageSources, imageWidth, imageHeight, imagePlaceholder } = prepareImageAssetAttributes(asset);
|
1659
1632
|
const previousSelectionRanges = Array.from(editor.model.document.selection.getRanges());
|
@@ -1689,18 +1662,18 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1689
1662
|
* The CKBox image edit editing plugin.
|
1690
1663
|
*/ class CKBoxImageEditEditing extends Plugin {
|
1691
1664
|
/**
|
1692
|
-
|
1693
|
-
|
1665
|
+
* @inheritDoc
|
1666
|
+
*/ static get pluginName() {
|
1694
1667
|
return 'CKBoxImageEditEditing';
|
1695
1668
|
}
|
1696
1669
|
/**
|
1697
|
-
|
1698
|
-
|
1670
|
+
* @inheritDoc
|
1671
|
+
*/ static get isOfficialPlugin() {
|
1699
1672
|
return true;
|
1700
1673
|
}
|
1701
1674
|
/**
|
1702
|
-
|
1703
|
-
|
1675
|
+
* @inheritDoc
|
1676
|
+
*/ static get requires() {
|
1704
1677
|
return [
|
1705
1678
|
CKBoxEditing,
|
1706
1679
|
CKBoxUtils,
|
@@ -1711,8 +1684,8 @@ function createUrlChecker(allowExternalImagesEditing) {
|
|
1711
1684
|
];
|
1712
1685
|
}
|
1713
1686
|
/**
|
1714
|
-
|
1715
|
-
|
1687
|
+
* @inheritDoc
|
1688
|
+
*/ init() {
|
1716
1689
|
const { editor } = this;
|
1717
1690
|
editor.commands.add('ckboxImageEdit', new CKBoxImageEditCommand(editor));
|
1718
1691
|
}
|
@@ -1727,18 +1700,18 @@ var ckboxImageEditIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2
|
|
1727
1700
|
* that allows you to open the CKBox dialog and edit the image.
|
1728
1701
|
*/ class CKBoxImageEditUI extends Plugin {
|
1729
1702
|
/**
|
1730
|
-
|
1731
|
-
|
1703
|
+
* @inheritDoc
|
1704
|
+
*/ static get pluginName() {
|
1732
1705
|
return 'CKBoxImageEditUI';
|
1733
1706
|
}
|
1734
1707
|
/**
|
1735
|
-
|
1736
|
-
|
1708
|
+
* @inheritDoc
|
1709
|
+
*/ static get isOfficialPlugin() {
|
1737
1710
|
return true;
|
1738
1711
|
}
|
1739
1712
|
/**
|
1740
|
-
|
1741
|
-
|
1713
|
+
* @inheritDoc
|
1714
|
+
*/ init() {
|
1742
1715
|
const editor = this.editor;
|
1743
1716
|
editor.ui.componentFactory.add('ckboxImageEdit', (locale)=>{
|
1744
1717
|
const command = editor.commands.get('ckboxImageEdit');
|
@@ -1766,18 +1739,18 @@ var ckboxImageEditIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2
|
|
1766
1739
|
* The CKBox image edit feature.
|
1767
1740
|
*/ class CKBoxImageEdit extends Plugin {
|
1768
1741
|
/**
|
1769
|
-
|
1770
|
-
|
1742
|
+
* @inheritDoc
|
1743
|
+
*/ static get pluginName() {
|
1771
1744
|
return 'CKBoxImageEdit';
|
1772
1745
|
}
|
1773
1746
|
/**
|
1774
|
-
|
1775
|
-
|
1747
|
+
* @inheritDoc
|
1748
|
+
*/ static get isOfficialPlugin() {
|
1776
1749
|
return true;
|
1777
1750
|
}
|
1778
1751
|
/**
|
1779
|
-
|
1780
|
-
|
1752
|
+
* @inheritDoc
|
1753
|
+
*/ static get requires() {
|
1781
1754
|
return [
|
1782
1755
|
CKBoxImageEditEditing,
|
1783
1756
|
CKBoxImageEditUI
|