Sfoglia il codice sorgente

Small adjustments for Edge browser.

Krzysztof Krztoń 7 anni fa
parent
commit
37845457bb

+ 5 - 5
packages/ckeditor5-image/src/imageupload/imageuploadediting.js

@@ -325,13 +325,13 @@ export function isHtmlIncluded( dataTransfer ) {
 // @param {String} filename Filename used during file creation.
 // @returns {File|null} The `File` instance created from the given blob or `null` if `File API` is not available.
 function createFileFromBlob( blob, filename ) {
-	if ( typeof File === 'function' ) {
+	try {
 		return new File( [ blob ], filename );
-	} else {
+	} catch ( err ) {
 		// Edge does not support `File` constructor ATM, see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9551546/.
-		// The `Blob` object could be used, however it causes the issue with upload itself where filename is read directly
-		// from a `File` instance. Since `Blob` instance does not provide one, the default "blob" filename is used which
-		// doesn't work well with most upload adapters (same name for every file + checking file type by extension fails).
+		// However, the `File` function is present (so cannot be checked with `!window.File` or `typeof File === 'function'`), but
+		// calling it with `new File( ... )` throws an error. This try-catch prevents that. Also when the function will
+		// be implemented correctly in Edge the code will start working without any changes (see #247).
 		return null;
 	}
 }

+ 43 - 18
packages/ckeditor5-image/tests/imageupload/imageuploadediting.js

@@ -32,12 +32,6 @@ describe( 'ImageUploadEditing', () => {
 	const base64Sample = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=';
 	let editor, model, view, doc, fileRepository, viewDocument, nativeReaderMock, loader, adapterMock, uploadStartedCallback;
 
-	const windowFilePolyfill = function( parts, filename, properties ) {
-		this.name = filename;
-		this.parts = parts;
-		this.properties = properties;
-	};
-
 	testUtils.createSinonSandbox();
 
 	class UploadAdapterPluginMock extends Plugin {
@@ -57,6 +51,12 @@ describe( 'ImageUploadEditing', () => {
 	}
 
 	beforeEach( () => {
+		if ( env.isEdge ) {
+			testUtils.sinon.stub( window, 'File' ).callsFake( () => {
+				return { name: 'file.jpg' };
+			} );
+		}
+
 		// Most tests assume non-edge environment but we do not set `contenteditable=false` on Edge so stub `env.isEdge`.
 		testUtils.sinon.stub( env, 'isEdge' ).get( () => false );
 
@@ -66,11 +66,6 @@ describe( 'ImageUploadEditing', () => {
 			return nativeReaderMock;
 		} );
 
-		// Use `File` polyfill so test can be run on Edge too (which lacks `File` constructor).
-		if ( !window.File ) {
-			window.File = windowFilePolyfill;
-		}
-
 		return VirtualTestEditor
 			.create( {
 				plugins: [ ImageEditing, ImageUploadEditing, Paragraph, UndoEditing, UploadAdapterPluginMock ]
@@ -88,10 +83,6 @@ describe( 'ImageUploadEditing', () => {
 		adapterMock = null;
 		uploadStartedCallback = null;
 
-		if ( window.File === windowFilePolyfill ) {
-			window.File = null;
-		}
-
 		return editor.destroy();
 	} );
 
@@ -641,7 +632,10 @@ describe( 'ImageUploadEditing', () => {
 		} );
 	} );
 
-	it( 'should not upload nor change image data when `File` constructor is not supported', done => {
+	it( 'should not upload nor change image data when `File` constructor is not present', done => {
+		// Restore `File` stub.
+		testUtils.sinon.restore();
+
 		const fileFn = window.File;
 
 		window.File = undefined;
@@ -667,11 +661,42 @@ describe( 'ImageUploadEditing', () => {
 		} );
 	} );
 
+	it( 'should not upload nor change image data when `File` constructor is not supported', done => {
+		// Restore `File` stub.
+		testUtils.sinon.restore();
+
+		const fileFn = window.File;
+
+		window.File = function() {
+			throw new Error( 'Function expected.' ); // Simulating Edge browser behaviour here.
+		};
+
+		setModelData( model, '<paragraph>[]foo</paragraph>' );
+
+		model.document.once( 'change', () => {
+			setTimeout( () => {
+				window.File = fileFn;
+
+				expect( adapterMock ).to.null;
+				expectModel( done, model, `<paragraph><image src="${ base64Sample }"></image>[]foo</paragraph>` );
+
+				done();
+			}, 50 );
+		} );
+
+		model.change( writer => {
+			const image = writer.createElement( 'image' );
+
+			writer.setAttribute( 'src', base64Sample, image );
+			writer.insert( image, model.document.selection.getFirstPosition() );
+		} );
+	} );
+
 	it( 'should not initialize upload if inserted image have uploadId', () => {
 		setModelData( model, '<paragraph>[]foo</paragraph>' );
 
 		const imageUploadEditing = editor.plugins.get( ImageUploadEditing );
-		const uploadSpy = sinon.spy( imageUploadEditing, '_uploadBase64Images' );
+		const uploadSpy = testUtils.sinon.spy( imageUploadEditing, '_uploadBase64Images' );
 
 		model.document.once( 'change', () => {
 			expect( uploadSpy.callCount ).to.equal( 0 );
@@ -692,7 +717,7 @@ describe( 'ImageUploadEditing', () => {
 		setModelData( model, '<paragraph src="foo">[]bar</paragraph>' );
 
 		const imageUploadEditing = editor.plugins.get( ImageUploadEditing );
-		const uploadSpy = sinon.spy( imageUploadEditing, '_uploadBase64Images' );
+		const uploadSpy = testUtils.sinon.spy( imageUploadEditing, '_uploadBase64Images' );
 
 		model.document.once( 'change', () => {
 			expect( uploadSpy.callCount ).to.equal( 0 );