Skip to content

Commit

Permalink
Merge pull request #15153 from ckeditor/ck/15090
Browse files Browse the repository at this point in the history
Feature (image, ckbox): Images inserted by CKBox should set the provided dimensions and use the blurhash to indicate image loading. Closes #15090.
  • Loading branch information
niegowski authored Oct 23, 2023
2 parents b441bee + fd8e959 commit 6ee2867
Show file tree
Hide file tree
Showing 18 changed files with 850 additions and 31 deletions.
1 change: 1 addition & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The following libraries are included in CKEditor under the [MIT license](https:/
* turndown - turndown is copyright © Dom Christie and released under the MIT license.
* turndown-plugin-gfm - turndown-plugin-gfm is copyright © Dom Christie and released under the MIT license.
* vanilla-colorful - Copyright (c) 2020 Serhii Kulykov <iamkulykov@gmail.com> (MIT license).
* blurhash - Copyright (c) 2018 Wolt Enterprises (MIT license).

Trademarks
----------
Expand Down
4 changes: 4 additions & 0 deletions packages/ckeditor5-ckbox/LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Sources of Intellectual Property Included in CKEditor

Where not otherwise indicated, all CKEditor content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, CKEditor will incorporate work done by developers outside of CKSource with their express permission.

The following libraries are included in CKEditor under the [MIT license](https://opensource.org/licenses/MIT):

* blurhash - Copyright (c) 2018 Wolt Enterprises (MIT license).

Trademarks
----------

Expand Down
3 changes: 2 additions & 1 deletion packages/ckeditor5-ckbox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
],
"main": "src/index.ts",
"dependencies": {
"ckeditor5": "40.0.0"
"ckeditor5": "40.0.0",
"blurhash": "^2.0.5"
},
"devDependencies": {
"@ckeditor/ckeditor5-basic-styles": "40.0.0",
Expand Down
25 changes: 19 additions & 6 deletions packages/ckeditor5-ckbox/src/ckboxcommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type {
CKBoxRawAssetDefinition
} from './ckboxconfig';

import { getImageUrls } from './utils';
import { blurHashToDataUrl, getImageUrls } from './utils';

declare global {
// eslint-disable-next-line no-var
Expand Down Expand Up @@ -281,13 +281,23 @@ export default class CKBoxCommand extends Command {
*/
private _insertImage( asset: CKBoxAssetImageDefinition ) {
const editor = this.editor;
const { imageFallbackUrl, imageSources, imageTextAlternative } = asset.attributes;
const {
imageFallbackUrl,
imageSources,
imageTextAlternative,
imageWidth,
imageHeight,
imagePlaceholder
} = asset.attributes;

editor.execute( 'insertImage', {
source: {
src: imageFallbackUrl,
sources: imageSources,
alt: imageTextAlternative
alt: imageTextAlternative,
width: imageWidth,
height: imageHeight,
...( imagePlaceholder ? { placeholder: imagePlaceholder } : null )
}
} );
}
Expand Down Expand Up @@ -365,16 +375,19 @@ function prepareAssets(

/**
* Parses the assets attributes into the internal data format.
*
* @param origin The base URL for assets inserted into the editor.
*/
function prepareImageAssetAttributes( asset: CKBoxRawAssetDefinition ): CKBoxAssetImageAttributesDefinition {
const { imageFallbackUrl, imageSources } = getImageUrls( asset.data.imageUrls! );
const { description, width, height, blurHash } = asset.data.metadata!;
const imagePlaceholder = blurHashToDataUrl( blurHash );

return {
imageFallbackUrl,
imageSources,
imageTextAlternative: asset.data.metadata!.description || ''
imageTextAlternative: description || '',
imageWidth: width,
imageHeight: height,
...( imagePlaceholder ? { imagePlaceholder } : null )
};
}

Expand Down
20 changes: 20 additions & 0 deletions packages/ckeditor5-ckbox/src/ckboxconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,21 @@ export interface CKBoxAssetImageAttributesDefinition {
* An alternative text for an image.
*/
imageTextAlternative: string;

/**
* Image width.
*/
imageWidth?: number;

/**
* Image height.
*/
imageHeight?: number;

/**
* Image placeholder image.
*/
imagePlaceholder?: string;
}

/**
Expand Down Expand Up @@ -320,4 +335,9 @@ export interface CKBoxRawAssetMetadataDefinition {
* Image height.
*/
height?: number;

/**
* The blurhash placeholder value.
*/
blurHash?: string;
}
42 changes: 42 additions & 0 deletions packages/ckeditor5-ckbox/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import type { InitializedToken } from '@ckeditor/ckeditor5-cloud-services';
import type { CKBoxImageUrls } from './ckboxconfig';

import { decode } from 'blurhash';

/**
* Converts image source set provided by the CKBox into an object containing:
* - responsive URLs for the "webp" image format,
Expand Down Expand Up @@ -74,3 +76,43 @@ export function getWorkspaceId( token: InitializedToken, defaultWorkspaceId?: st

return null;
}

/**
* Default resolution for decoding blurhash values.
* Relatively small values must be used in order to ensure acceptable performance.
*/
const BLUR_RESOLUTION = 32;

/**
* Generates an image data URL from its `blurhash` representation.
*/
export function blurHashToDataUrl( hash?: string ): string | undefined {
if ( !hash ) {
return;
}

try {
const resolutionInPx = `${ BLUR_RESOLUTION }px`;
const canvas = document.createElement( 'canvas' );

canvas.setAttribute( 'width', resolutionInPx );
canvas.setAttribute( 'height', resolutionInPx );

const ctx = canvas.getContext( '2d' );

/* istanbul ignore next -- @preserve */
if ( !ctx ) {
return;
}

const imageData = ctx.createImageData( BLUR_RESOLUTION, BLUR_RESOLUTION );
const decoded = decode( hash, BLUR_RESOLUTION, BLUR_RESOLUTION );

imageData.data.set( decoded );
ctx.putImageData( imageData, 0, 0 );

return canvas.toDataURL();
} catch ( e ) {
return undefined;
}
}
Loading

0 comments on commit 6ee2867

Please sign in to comment.