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

Easy image upload refactoring #1079

Merged
merged 15 commits into from
Oct 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 7 additions & 47 deletions plugins/easyimage/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,13 @@
}

function registerUploadWidget( editor ) {
var uploadUrl = CKEDITOR.fileTools.getUploadUrl( editor.config, 'easyimage' );

CKEDITOR.fileTools.addUploadWidget( editor, 'uploadeasyimage', {
supportedTypes: /image\/(jpeg|png|gif|bmp)/,

uploadUrl: uploadUrl,

loadMethod: 'loadAndUpload',
// Easy image uses only upload method, as is manually handled in onUploading function.
loadMethod: 'upload',

additionalRequestParameters: {
isEasyImage: true
},
loaderType: CKEDITOR.plugins.cloudservices.cloudServicesLoader,

fileToElement: function() {
var img = new CKEDITOR.dom.element( 'img' );
Expand All @@ -165,42 +160,6 @@
}
} );

editor.on( 'fileUploadRequest', function( evt ) {
var requestData = evt.data.requestData;

if ( !requestData.isEasyImage ) {
return;
}

evt.data.requestData.file = evt.data.requestData.upload;
delete evt.data.requestData.upload;

// This property is used by fileUploadResponse callback to identify EI requests.
evt.data.fileLoader.isEasyImage = true;

evt.data.fileLoader.xhr.setRequestHeader( 'Authorization', editor.config.easyimage_token );
} );

editor.on( 'fileUploadResponse', function( evt ) {
var fileLoader = evt.data.fileLoader,
xhr = fileLoader.xhr,
response;

if ( !fileLoader.isEasyImage ) {
return;
}

evt.stop();

try {
response = JSON.parse( xhr.responseText );

evt.data.response = response;
} catch ( e ) {
CKEDITOR.warn( 'filetools-response-error', { responseText: xhr.responseText } );
}
} );

// Handle images which are not available in the dataTransfer.
// This means that we need to read them from the <img src="data:..."> elements.
editor.on( 'paste', function( evt ) {
Expand All @@ -214,6 +173,7 @@
var data = evt.data,
// Prevent XSS attacks.
tempDoc = document.implementation.createHTMLDocument( '' ),
widgetDef = editor.widgets.registered.uploadeasyimage,
temp = new CKEDITOR.dom.element( tempDoc.body ),
imgs, img, i;

Expand All @@ -233,8 +193,8 @@

// We are not uploading images in non-editable blocs and fake objects (http://dev.ckeditor.com/ticket/13003).
if ( isDataInSrc && isRealObject && !img.data( 'cke-upload-id' ) && !img.isReadOnly( 1 ) ) {
var loader = editor.uploadRepository.create( img.getAttribute( 'src' ) );
loader.upload( uploadUrl );
var loader = editor.uploadRepository.create( img.getAttribute( 'src' ), undefined, widgetDef.loaderType );
loader.upload( widgetDef.uploadUrl, widgetDef.additionalRequestParameters );

fileTools.markElement( img, 'uploadeasyimage', loader.id );

Expand Down Expand Up @@ -290,7 +250,7 @@
};

CKEDITOR.plugins.add( 'easyimage', {
requires: 'image2,uploadwidget,contextmenu,dialog',
requires: 'image2,uploadwidget,contextmenu,dialog,cloudservices',
lang: 'en',

onLoad: function() {
Expand Down
4 changes: 2 additions & 2 deletions plugins/easyimage/samples/easyimage.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ <h1>Apollo 11</h1>
getToken( function( token ) {
CKEDITOR.replace( 'editor', {
extraPlugins: 'easyimage',
easyimageUploadUrl: 'https://files.cke-cs.com/upload/',
easyimage_token: token,
cloudServices_url: 'https://files.cke-cs.com/upload/',
cloudServices_token: token,
height: 500
} );
} );
Expand Down
115 changes: 83 additions & 32 deletions tests/plugins/easyimage/uploadwidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,34 @@
/* bender-include: %BASE_PATH%/plugins/uploadfile/_helpers/waitForImage.js */
/* global pasteFiles, waitForImage */

'use strict';

( function() {
var uploadCount, loadAndUploadCount, lastUploadUrl, resumeAfter, tests,
'use strict';

var uploadCount, loadAndUploadCount, resumeAfter, tests,
IMG_URL = '%BASE_PATH%_assets/logo.png',
DATA_IMG = 'data:',
BLOB_IMG = 'blob:';
BLOB_IMG = 'blob:',
commonConfig = {
cloudServices_url: 'http://foo/upload',
// Disable pasteFilter on Webkits (pasteFilter defaults semantic-text on Webkits).
pasteFilter: null
};

bender.editors = {
classic: {
name: 'classic',
config: {
easyimageUploadUrl: 'http://foo/upload',
// Disable pasteFilter on Webkits (pasteFilter defaults semantic-text on Webkits).
pasteFilter: null
}
config: commonConfig
},

divarea: {
name: 'divarea',
config: {
extraPlugins: 'divarea',
easyimageUploadUrl: 'http://foo/upload',
// Disable pasteFilter on Webkits (pasteFilter defaults semantic-text on Webkits).
pasteFilter: null
}
config: CKEDITOR.tools.extend( { extraPlugins: 'divarea' }, commonConfig )
},

inline: {
name: 'inline',
creator: 'inline',
config: {
easyimageUploadUrl: 'http://foo/upload',
// Disable pasteFilter on Webkits (pasteFilter defaults semantic-text on Webkits).
pasteFilter: null
}
config: commonConfig
}
};

Expand All @@ -65,24 +57,22 @@
}
};

responseData[ 'default' ] = IMG_URL;
responseData.response[ 'default' ] = IMG_URL;
resumeAfter = bender.tools.resumeAfter;

CKEDITOR.fileTools.fileLoader.prototype.loadAndUpload = function( url ) {
// Approach taken from tests/plugins/uploadwidget/uploadwidget.js test.
CKEDITOR.plugins.cloudservices.cloudServicesLoader.prototype.loadAndUpload = function() {
loadAndUploadCount++;
lastUploadUrl = url;

this.responseData = CKEDITOR.tools.clone( responseData );
};

CKEDITOR.fileTools.fileLoader.prototype.load = function() {};
CKEDITOR.plugins.cloudservices.cloudServicesLoader.prototype.load = function() {};

CKEDITOR.fileTools.fileLoader.prototype.upload = function( url ) {
sinon.stub( CKEDITOR.plugins.cloudservices.cloudServicesLoader.prototype, 'upload', function() {
uploadCount++;
lastUploadUrl = url;

this.responseData = CKEDITOR.tools.clone( responseData );
};
} );
},

setUp: function() {
Expand All @@ -103,6 +93,10 @@
if ( CKEDITOR.fileTools.bindNotifications.reset ) {
CKEDITOR.fileTools.bindNotifications.reset();
}

if ( CKEDITOR.plugins.cloudservices.cloudServicesLoader.prototype.upload.reset ) {
CKEDITOR.plugins.cloudservices.cloudServicesLoader.prototype.upload.reset();
}
},

'test classic with easyimage (integration test)': function( editor ) {
Expand All @@ -129,9 +123,8 @@
assert.sameData( '<p><img alt="" src="' + IMG_URL + '" /></p>', editor.getData() );
assert.areSame( 1, editor.editable().find( 'img[data-widget="image"]' ).count() );

assert.areSame( 1, loadAndUploadCount );
assert.areSame( 0, uploadCount );
assert.areSame( 'http://foo/upload', lastUploadUrl );
assert.areSame( 0, loadAndUploadCount );
assert.areSame( 1, uploadCount );
} );
},

Expand Down Expand Up @@ -161,7 +154,6 @@

assert.areSame( 0, loadAndUploadCount );
assert.areSame( 1, uploadCount );
assert.areSame( 'http://foo/upload', lastUploadUrl );
} );
} );
},
Expand Down Expand Up @@ -437,6 +429,65 @@
} );
} );

wait();
},

'test cloudservices URL/request params can be customized': function( editor ) {
var uploadEasyImageDef = editor.widgets.registered.uploadeasyimage,
originalUploadUrl = uploadEasyImageDef.uploadUrl,
originalAdditionalParams = uploadEasyImageDef.additionalRequestParameters,
loader;

// Upload widget might have an uploadUrl changed in definition, allowing for upload URL customization.
uploadEasyImageDef.uploadUrl = 'https://customDomain.localhost/endpoint';
uploadEasyImageDef.additionalRequestParameters = { a: 1 };

resumeAfter( editor, 'paste', function() {
// Restore original value.
uploadEasyImageDef.uploadUrl = originalUploadUrl;
uploadEasyImageDef.additionalRequestParameters = originalAdditionalParams;

loader = editor.uploadRepository.loaders[ 0 ];

sinon.assert.calledWith( loader.upload, 'https://customDomain.localhost/endpoint', { a: 1 } );
assert.isTrue( true );
} );

editor.fire( 'paste', {
dataValue: '<img src="' + bender.tools.pngBase64 + '">'
} );

wait();
},

'test loader type can be customized': function( editor ) {
var uploadEasyImageDef = editor.widgets.registered.uploadeasyimage,
originalType = uploadEasyImageDef.loaderType,
CloudServicesLoader = CKEDITOR.plugins.cloudservices.cloudServicesLoader,
loader;

function LoaderSubclass( editor, fileOrData, fileName, token ) {
CloudServicesLoader.call( this, editor, fileOrData, fileName, token );
}

LoaderSubclass.prototype = CKEDITOR.tools.extend( {}, CloudServicesLoader.prototype );

// Upload widget might have a loaderType changed in definition, allowing for loader type customization.
uploadEasyImageDef.loaderType = LoaderSubclass;

resumeAfter( editor, 'paste', function() {
// Restore original value.
uploadEasyImageDef.loaderType = originalType;

loader = editor.uploadRepository.loaders[ 0 ];

assert.isInstanceOf( LoaderSubclass, loader, 'Loader type' );
} );

editor.fire( 'paste', {
dataValue: '<img src="' + bender.tools.pngBase64 + '">'
} );

wait();
}
};
Expand Down
2 changes: 1 addition & 1 deletion tests/plugins/uploadfile/_helpers/waitForImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function waitForImage( image, callback ) {
if ( CKEDITOR.env.ie ) {
wait( callback, 100 );
} else {
image.on( 'load', function() {
image.once( 'load', function() {
resume( callback );
} );
wait();
Expand Down