Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
f1ames committed Nov 27, 2018
1 parent 996461b commit cd2a8fd
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 28 deletions.
29 changes: 12 additions & 17 deletions src/imageupload/imageuploadediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';
import Notification from '@ckeditor/ckeditor5-ui/src/notification/notification';
import UpcastWriter from '@ckeditor/ckeditor5-engine/src/view/upcastwriter';
import { upcastAttributeToAttribute } from '@ckeditor/ckeditor5-engine/src/conversion/upcast-converters';

import ImageUploadCommand from '../../src/imageupload/imageuploadcommand';
import { isImageType, isLocalImage, wrapImageToFetch } from '../../src/imageupload/utils';
import { isImageType, isLocalImage, fetchLocalImage } from '../../src/imageupload/utils';

/**
* The editing part of the image upload feature. It registers the `'imageUpload'` command.
Expand Down Expand Up @@ -98,11 +99,9 @@ export default class ImageUploadEditing extends Plugin {
// inserted into the content. Then, those images are uploaded once they appear in the model
// (see Document#change listener below).
this.listenTo( editor.plugins.get( 'Clipboard' ), 'inputTransformation', ( evt, data ) => {
const view = editor.editing.view;

const fetchableImages = Array.from( view.createRangeIn( data.content ) )
const fetchableImages = Array.from( editor.editing.view.createRangeIn( data.content ) )
.filter( value => isLocalImage( value.item ) && !value.item.getAttribute( 'uploadProcessed' ) )
.map( ( value, index ) => wrapImageToFetch( value.item, index ) );
.map( value => fetchLocalImage( value.item ) );

if ( !fetchableImages.length ) {
return;
Expand All @@ -111,25 +110,21 @@ export default class ImageUploadEditing extends Plugin {
evt.stop();

Promise.all( fetchableImages ).then( items => {
const writer = new UpcastWriter();

for ( const item of items ) {
if ( !item.file ) {
// Failed to fetch image or create a file instance, remove image element.
view.change( writer => {
writer.remove( item.image );
} );
writer.remove( item.image );
} else {
// Set attribute marking the image as processed.
writer.setAttribute( 'uploadProcessed', true, item.image );

const loader = fileRepository.createLoader( item.file );

if ( loader ) {
view.change( writer => {
writer.setAttribute( 'src', '', item.image );
writer.setAttribute( 'uploadId', loader.id, item.image );
} );
} else {
view.change( writer => {
// Set attribute so the image will not be processed 2nd time.
writer.setAttribute( 'uploadProcessed', true, item.image );
} );
writer.setAttribute( 'src', '', item.image );
writer.setAttribute( 'uploadId', loader.id, item.image );
}
}
}
Expand Down
19 changes: 8 additions & 11 deletions src/imageupload/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,19 @@ export function isImageType( file ) {
* Creates a promise which fetches the image local source (base64 or blob) and returns as a `File` object.
*
* @param {module:engine/view/element~Element} image Image which source to fetch.
* @param {Number} index Image index used as image name suffix.
* @returns {Promise} A promise which resolves when image source is fetched and converted to `File` instance.
* It resolves with object holding initial image element (as `image`) and its file source (as `file`). If
* the `file` attribute is null, it means fetching failed.
*/
export function wrapImageToFetch( image, index ) {
export function fetchLocalImage( image ) {
return new Promise( resolve => {
// Fetch works asynchronously and so does not block browser UI when processing data.
fetch( image.getAttribute( 'src' ) )
.then( resource => resource.blob() )
.then( blob => {
const mimeType = getImageMimeType( blob, image.getAttribute( 'src' ) );
const ext = mimeType.replace( 'image/', '' );
const filename = `${ Number( new Date() ) }-image${ index }.${ ext }`;
const filename = `image.${ ext }`;
const file = createFileFromBlob( blob, filename, mimeType );

resolve( { image, file } );
Expand All @@ -57,14 +56,12 @@ export function wrapImageToFetch( image, index ) {
* @returns {Boolean}
*/
export function isLocalImage( node ) {
return node.is( 'element', 'img' ) && node.getAttribute( 'src' ) &&
( node.getAttribute( 'src' ).match( /data:image\/\w+;base64,/g ) ||
if ( !node.is( 'element', 'img' ) || node.getAttribute( 'src' ) ) {
return false;
}

return ( node.getAttribute( 'src' ).match( /data:image\/\w+;base64,/g ) ||
node.getAttribute( 'src' ).match( /blob:/g ) );
if ( !node.is( 'element', 'img' ) || !node.getAttribute( 'src' ) ) {
return false;
}

return node.getAttribute( 'src' ).match( /^data:image\/\w+;base64,/g ) ||
node.getAttribute( 'src' ).match( /^blob:/g );
}

// Extracts image type based on its blob representation or its source.
Expand Down

0 comments on commit cd2a8fd

Please sign in to comment.