@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/README.md +0 -6
- package/build/ckbox.js +1 -1
- package/dist/index.js +282 -419
- package/dist/index.js.map +1 -1
- package/dist/types/ckboximageedit/ckboximageeditcommand.d.ts +0 -8
- package/dist/types/ckboxui.d.ts +2 -29
- package/package.json +2 -2
- package/src/ckboximageedit/ckboximageeditcommand.d.ts +0 -8
- package/src/ckboximageedit/ckboximageeditcommand.js +1 -11
- package/src/ckboxui.d.ts +2 -29
- package/src/ckboxui.js +36 -82
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,
|
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
|
-
|
25
|
-
|
15
|
+
* @inheritDoc
|
16
|
+
*/ static get pluginName() {
|
26
17
|
return 'CKBoxUI';
|
27
18
|
}
|
28
19
|
/**
|
29
|
-
|
30
|
-
|
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.
|
38
|
-
editor.ui.componentFactory
|
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')
|
37
|
+
const imageInsertUI = editor.plugins.get('ImageInsertUI');
|
38
|
+
imageInsertUI.registerIntegration({
|
41
39
|
name: 'assetManager',
|
42
40
|
observable: ()=>editor.commands.get('ckbox'),
|
43
|
-
buttonViewCreator: ()=>
|
44
|
-
|
45
|
-
|
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
|
-
|
51
|
-
|
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 =
|
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
|
-
|
330
|
-
|
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
|
-
|
342
|
-
|
255
|
+
* @inheritDoc
|
256
|
+
*/ execute() {
|
343
257
|
this.fire('ckbox:open');
|
344
258
|
}
|
345
259
|
/**
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
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
|
-
|
355
|
-
|
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
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
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
|
-
|
393
|
-
|
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
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
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
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
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
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
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
|
-
|
607
|
-
|
608
|
-
/**
|
609
|
-
* @inheritDoc
|
610
|
-
*/ static get pluginName() {
|
544
|
+
* @inheritDoc
|
545
|
+
*/ static get pluginName() {
|
611
546
|
return 'CKBoxUtils';
|
612
547
|
}
|
613
548
|
/**
|
614
|
-
|
615
|
-
|
549
|
+
* @inheritDoc
|
550
|
+
*/ static get requires() {
|
616
551
|
return [
|
617
552
|
'CloudServices'
|
618
553
|
];
|
619
554
|
}
|
620
555
|
/**
|
621
|
-
|
622
|
-
|
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
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
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
|
-
|
669
|
-
|
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
|
-
|
674
|
-
|
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
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
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
|
-
|
691
|
-
|
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
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
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
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
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
|
-
|
779
|
-
|
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
|
-
|
789
|
-
|
715
|
+
* @inheritDoc
|
716
|
+
*/ static get pluginName() {
|
790
717
|
return 'CKBoxUploadAdapter';
|
791
718
|
}
|
792
719
|
/**
|
793
|
-
|
794
|
-
|
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
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
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
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
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
|
-
|
909
|
-
|
811
|
+
* @inheritDoc
|
812
|
+
*/ static get pluginName() {
|
910
813
|
return 'CKBoxEditing';
|
911
814
|
}
|
912
815
|
/**
|
913
|
-
|
914
|
-
|
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
|
-
|
924
|
-
|
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
|
-
|
937
|
-
|
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
|
-
|
952
|
-
|
953
|
-
|
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
|
-
|
960
|
-
|
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
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
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
|
-
|
979
|
-
|
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
|
-
|
1010
|
-
|
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
|
-
|
1132
|
-
|
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
|
-
|
1260
|
-
|
1150
|
+
* @inheritDoc
|
1151
|
+
*/ static get pluginName() {
|
1261
1152
|
return 'CKBox';
|
1262
1153
|
}
|
1263
1154
|
/**
|
1264
|
-
|
1265
|
-
|
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
|
-
|
1344
|
-
|
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
|
-
|
1352
|
-
|
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
|
-
|
1380
|
-
|
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
|
-
|
1391
|
-
|
1248
|
+
* Indicates if the CKBox Image Editor dialog is already opened.
|
1249
|
+
*/ _getValue() {
|
1392
1250
|
return this._wrapper !== null;
|
1393
1251
|
}
|
1394
1252
|
/**
|
1395
|
-
|
1396
|
-
|
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
|
-
|
1432
|
-
|
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
|
-
|
1443
|
-
|
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
|
-
|
1462
|
-
|
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
|
-
|
1474
|
-
|
1475
|
-
|
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
|
-
|
1506
|
-
|
1507
|
-
|
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
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
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
|
-
|
1531
|
-
|
1532
|
-
|
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
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
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
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
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
|
-
|
1566
|
-
|
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
|
-
|
1602
|
-
|
1471
|
+
* @inheritDoc
|
1472
|
+
*/ static get pluginName() {
|
1603
1473
|
return 'CKBoxImageEditEditing';
|
1604
1474
|
}
|
1605
1475
|
/**
|
1606
|
-
|
1607
|
-
|
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
|
-
|
1619
|
-
|
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
|
-
|
1635
|
-
|
1499
|
+
* @inheritDoc
|
1500
|
+
*/ static get pluginName() {
|
1636
1501
|
return 'CKBoxImageEditUI';
|
1637
1502
|
}
|
1638
1503
|
/**
|
1639
|
-
|
1640
|
-
|
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
|
-
|
1668
|
-
|
1530
|
+
* @inheritDoc
|
1531
|
+
*/ static get pluginName() {
|
1669
1532
|
return 'CKBoxImageEdit';
|
1670
1533
|
}
|
1671
1534
|
/**
|
1672
|
-
|
1673
|
-
|
1535
|
+
* @inheritDoc
|
1536
|
+
*/ static get requires() {
|
1674
1537
|
return [
|
1675
1538
|
CKBoxImageEditEditing,
|
1676
1539
|
CKBoxImageEditUI
|