Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editing images not in CKBox #15423

Merged
merged 10 commits into from
Dec 5, 2023
3 changes: 2 additions & 1 deletion packages/ckeditor5-ckbox/lang/contexts.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"Cannot access default workspace.": "A message is displayed when the user is not authorised to access the CKBox workspace configured as default one.",
"Edit image": "Image toolbar button tooltip for opening a dialog to manipulate the image.",
"Processing the edited image.": "A message stating that image editing is in progress.",
"Server failed to process the image.": "A message is displayed when the server fails to process an image or doesn't respond."
"Server failed to process the image.": "A message is displayed when the server fails to process an image or doesn't respond.",
"Failed to determine category of edited image.": "A message is displayed when category of the image user wants to edit can't be determined."
}
19 changes: 19 additions & 0 deletions packages/ckeditor5-ckbox/src/ckboxconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

import type { TokenUrl } from '@ckeditor/ckeditor5-cloud-services';
import type { ArrayOrItem } from 'ckeditor5/src/utils';

/**
* The configuration of the {@link module:ckbox/ckbox~CKBox CKBox feature}.
Expand Down Expand Up @@ -98,6 +99,24 @@ export interface CKBoxConfig {
*/
forceDemoLabel?: boolean;

/**
* Allows editing images that are not hosted in CKBox service.
*
* This configuration option should whitelist URL(s) of images that should be editable.
* Make sure that allowed image resources have CORS enabled.
*
* The image is editable if this option is:
* * a regular expression and it matches the image URL, or
* * a custom function that returns `true` for the image URL, or
* * `'origin'` literal and the image URL is from the same origin, or
* * an array of the above and the image URL matches one of the array elements.
*
* Images hosted in CKBox are always editable.
*
* @default []
*/
allowExternalImagesEditing?: ArrayOrItem<RegExp | 'origin' | ( ( src: string ) => boolean )>;

/**
* Inserts the unique asset ID as the `data-ckbox-resource-id` attribute. To disable this behavior, set it to `true`.
*
Expand Down
73 changes: 9 additions & 64 deletions packages/ckeditor5-ckbox/src/ckboxediting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* @module ckbox/ckboxediting
*/

import type { CloudServices, CloudServicesCore, InitializedToken } from '@ckeditor/ckeditor5-cloud-services';
import type { InitializedToken } from '@ckeditor/ckeditor5-cloud-services';
import { Plugin, type Editor } from 'ckeditor5/src/core';
import {
Range,
Expand All @@ -23,15 +23,15 @@ import {
type ViewElement,
type Writer
} from 'ckeditor5/src/engine';
import { CKEditorError, logError, type DecoratedMethodEvent } from 'ckeditor5/src/utils';
import { logError, type DecoratedMethodEvent } from 'ckeditor5/src/utils';

import type { CKBoxAssetDefinition } from './ckboxconfig';

import CKBoxCommand from './ckboxcommand';
import CKBoxUploadAdapter from './ckboxuploadadapter';
import type { ReplaceImageSourceCommand } from '@ckeditor/ckeditor5-image';
import CKBoxUtils from './ckboxutils';

const DEFAULT_CKBOX_THEME_NAME = 'lark';
import type { ReplaceImageSourceCommand } from '@ckeditor/ckeditor5-image';

/**
* The CKBox editing feature. It introduces the {@link module:ckbox/ckboxcommand~CKBoxCommand CKBox command} and
Expand All @@ -54,13 +54,13 @@ export default class CKBoxEditing extends Plugin {
* @inheritDoc
*/
public static get requires() {
return [ 'CloudServices', 'LinkEditing', 'PictureEditing', CKBoxUploadAdapter ] as const;
return [ 'LinkEditing', 'PictureEditing', CKBoxUploadAdapter, CKBoxUtils ] as const;
}

/**
* @inheritDoc
*/
public async init(): Promise<void> {
public init(): void {
const editor = this.editor;
const hasConfiguration = !!editor.config.get( 'ckbox' );
const isLibraryLoaded = !!window.CKBox;
Expand All @@ -71,23 +71,7 @@ export default class CKBoxEditing extends Plugin {
return;
}

this._initConfig();

const cloudServicesCore: CloudServicesCore = editor.plugins.get( 'CloudServicesCore' );
const ckboxTokenUrl = editor.config.get( 'ckbox.tokenUrl' )!;
const cloudServicesTokenUrl = editor.config.get( 'cloudServices.tokenUrl' );

// To avoid fetching the same token twice we need to compare the `ckbox.tokenUrl` and `cloudServices.tokenUrl` values.
// If they are equal, it's enough to take the token generated by the `CloudServices` plugin.
if ( ckboxTokenUrl === cloudServicesTokenUrl ) {
const cloudServices: CloudServices = editor.plugins.get( 'CloudServices' );

this._token = cloudServices.token!;
}
// Otherwise, create a new token manually.
else {
this._token = await cloudServicesCore.createToken( ckboxTokenUrl ).init();
}
this._checkImagePlugins();

// Extending the schema, registering converters and applying fixers only make sense if the configuration option to assign
// the assets ID with the model elements is enabled.
Expand All @@ -104,50 +88,11 @@ export default class CKBoxEditing extends Plugin {
}

/**
* Returns a token used by the CKBox plugin for communication with the CKBox service.
*/
public getToken(): InitializedToken {
return this._token;
}

/**
* Initializes the `ckbox` editor configuration.
* Checks if the at least one image plugin is loaded.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Checks if the at least one image plugin is loaded.
* Checks if at least one image plugin is loaded.

*/
private _initConfig() {
private _checkImagePlugins() {
const editor = this.editor;

editor.config.define( 'ckbox', {
serviceOrigin: 'https://api.ckbox.io',
defaultUploadCategories: null,
ignoreDataId: false,
language: editor.locale.uiLanguage,
theme: DEFAULT_CKBOX_THEME_NAME,
tokenUrl: editor.config.get( 'cloudServices.tokenUrl' )
} );

const tokenUrl = editor.config.get( 'ckbox.tokenUrl' );

if ( !tokenUrl ) {
/**
* The {@link module:ckbox/ckboxconfig~CKBoxConfig#tokenUrl `config.ckbox.tokenUrl`} or the
* {@link module:cloud-services/cloudservicesconfig~CloudServicesConfig#tokenUrl `config.cloudServices.tokenUrl`}
* configuration is required for the CKBox plugin.
*
* ```ts
* ClassicEditor.create( document.createElement( 'div' ), {
* ckbox: {
* tokenUrl: "YOUR_TOKEN_URL"
* // ...
* }
* // ...
* } );
* ```
*
* @error ckbox-plugin-missing-token-url
*/
throw new CKEditorError( 'ckbox-plugin-missing-token-url', this );
}

if ( !editor.plugins.has( 'ImageBlockEditing' ) && !editor.plugins.has( 'ImageInlineEditing' ) ) {
/**
* The CKBox feature requires one of the following plugins to be loaded to work correctly:
Expand Down
3 changes: 1 addition & 2 deletions packages/ckeditor5-ckbox/src/ckboximageedit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import { Plugin } from 'ckeditor5/src/core';

import CKBoxEditing from './ckboxediting';
import CKBoxImageEditEditing from './ckboximageedit/ckboximageeditediting';
import CKBoxImageEditUI from './ckboximageedit/ckboximageeditui';

Expand All @@ -30,6 +29,6 @@ export default class CKBoxImageEdit extends Plugin {
* @inheritDoc
*/
public static get requires() {
return [ CKBoxEditing, CKBoxImageEditEditing, CKBoxImageEditUI ] as const;
return [ CKBoxImageEditEditing, CKBoxImageEditUI ] as const;
}
}
Loading