Procházet zdrojové kódy

Moved image upload progress to separate plugin.

Szymon Kupś před 8 roky
rodič
revize
4cb26a974c

+ 1 - 64
packages/ckeditor5-upload/src/imageupload.js

@@ -11,8 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import ImageUploadEngine from './imageuploadengine';
 import FileDialogButtonView from './ui/filedialogbuttonview';
 import imageIcon from '@ckeditor/ckeditor5-core/theme/icons/image.svg';
-import uploadingPlaceholder from '../theme/icons/image_placeholder.svg';
-import UIElement from '@ckeditor/ckeditor5-engine/src/view/uielement';
+
 import '../theme/theme.scss';
 
 /**
@@ -56,67 +55,5 @@ export default class ImageUpload extends Plugin {
 
 			return view;
 		} );
-
-		const uploadEngine = editor.plugins.get( ImageUploadEngine );
-
-		// TODO: to constructor?
-		this.placeholder = 'data:image/svg+xml;utf8,' + uploadingPlaceholder;
-
-		// Reading started.
-		uploadEngine.on( 'upload:reading', ( evt, modelImage ) => {
-			const viewFigure = editor.editing.mapper.toViewElement( modelImage );
-
-			// TODO: do it better since there might be more elements.
-			const viewImg = viewFigure.getChild( 0 );
-
-			viewFigure.addClass( 'ck-appear', 'ck-infinite-progress' );
-
-			viewImg.setAttribute( 'src', this.placeholder );
-			editor.editing.view.render();
-		} );
-
-		// Uploading started.
-		uploadEngine.on( 'upload:uploading', ( evt, modelImage, loader ) => {
-			const viewFigure = editor.editing.mapper.toViewElement( modelImage );
-			const progressBar = createProgressBar();
-			viewFigure.appendChildren( progressBar );
-
-			viewFigure.removeClass( 'ck-infinite-progress' );
-			editor.editing.view.render();
-
-			loader.on( 'change:uploadedPercent', ( evt, name, value ) => {
-				progressBar.setStyle( 'width', value + '%' );
-				editor.editing.view.render();
-			} );
-		} );
-
-		uploadEngine.on( 'upload:complete', ( evt, modelImage ) => {
-			const viewFigure = editor.editing.mapper.toViewElement( modelImage );
-			const progressBar = getProgressBar( viewFigure );
-
-			if ( progressBar ) {
-				progressBar.remove();
-				editor.editing.view.render();
-			}
-		} );
-	}
-}
-
-const progressBarSymbol = Symbol( 'progress-bar' );
-
-function createProgressBar() {
-	const progressBar = new UIElement( 'div', { class: 'ck-progress-bar' } );
-	progressBar.setCustomProperty( progressBarSymbol, true );
-
-	return progressBar;
-}
-
-function getProgressBar( imageFigure ) {
-	for ( const child of imageFigure.getChildren() ) {
-		if ( child.getCustomProperty( progressBarSymbol ) ) {
-			return child;
-		}
 	}
-
-	return null;
 }

+ 12 - 32
packages/ckeditor5-upload/src/imageuploadengine.js

@@ -8,11 +8,10 @@
  */
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
-import { eventNameToConsumableType } from '@ckeditor/ckeditor5-engine/src/conversion/model-to-view-converters';
 import FileRepository from './filerepository';
 import ImageUploadCommand from './imageuploadcommand';
+import ImageUploadProgress from './imageuploadprogress';
 import Notification from '@ckeditor/ckeditor5-ui/src/notification/notification';
-import uploadingPlaceholder from '../theme/icons/image_placeholder.svg';
 import { isImageType } from './utils';
 
 /**
@@ -21,23 +20,11 @@ import { isImageType } from './utils';
  * @extends module:core/plugin~Plugin
  */
 export default class ImageUploadEngine extends Plugin {
-	constructor( editor ) {
-		super( editor );
-
-		/**
-		 * Image's placeholder that is displayed before real image data can be accessed.
-		 *
-		 * @protected
-		 * @member {String} #placeholder
-		 */
-		this.placeholder = 'data:image/svg+xml;utf8,' + uploadingPlaceholder;
-	}
-
 	/**
 	 * @inheritDoc
 	 */
 	static get requires() {
-		return [ FileRepository, Notification ];
+		return [ FileRepository, Notification, ImageUploadProgress ];
 	}
 
 	/**
@@ -50,6 +37,7 @@ export default class ImageUploadEngine extends Plugin {
 
 		// Setup schema to allow uploadId for images.
 		schema.allow( { name: 'image', attributes: [ 'uploadId' ], inside: '$root' } );
+		schema.allow( { name: 'image', attributes: [ 'uploadId', 'uploadStatus' ], inside: '$root' } );
 		schema.requireAttributes( 'image', [ 'uploadId' ] );
 
 		// Register imageUpload command.
@@ -85,20 +73,6 @@ export default class ImageUploadEngine extends Plugin {
 				}
 			}
 		} );
-
-		// Model to view converter for image's `uploadId` attribute.
-		editor.editing.modelToView.on( 'addAttribute:uploadId:image', ( evt, data, consumable ) => {
-			if ( !consumable.consume( data.item, eventNameToConsumableType( evt.name ) ) ) {
-				return;
-			}
-
-			const modelImage = data.item;
-			const viewFigure = editor.editing.mapper.toViewElement( modelImage );
-			const viewImg = viewFigure.getChild( 0 );
-
-			viewImg.setAttribute( 'src', this.placeholder );
-			this.fire( 'upload:reading', modelImage );
-		} );
 	}
 
 	/**
@@ -116,6 +90,10 @@ export default class ImageUploadEngine extends Plugin {
 		const fileRepository = editor.plugins.get( FileRepository );
 		const notification = editor.plugins.get( Notification );
 
+		doc.enqueueChanges( () => {
+			batch.setAttribute( imageElement, 'uploadStatus', 'reading' );
+		} );
+
 		loader.read()
 			.then( data => {
 				const viewFigure = editor.editing.mapper.toViewElement( imageElement );
@@ -123,17 +101,18 @@ export default class ImageUploadEngine extends Plugin {
 				viewImg.setAttribute( 'src', data );
 				editor.editing.view.render();
 
-				this.fire( 'upload:uploading', imageElement, loader );
+				doc.enqueueChanges( () => {
+					batch.setAttribute( imageElement, 'uploadStatus', 'uploading' );
+				} );
 
 				return loader.upload();
 			} )
 			.then( data => {
 				doc.enqueueChanges( () => {
+					batch.setAttribute( imageElement, 'uploadStatus', 'complete' );
 					batch.setAttribute( imageElement, 'src', data.original );
 				} );
 
-				this.fire( 'upload:complete', imageElement, loader );
-
 				clean();
 			} )
 			.catch( msg => {
@@ -148,6 +127,7 @@ export default class ImageUploadEngine extends Plugin {
 		function clean() {
 			doc.enqueueChanges( () => {
 				batch.removeAttribute( imageElement, 'uploadId' );
+				batch.removeAttribute( imageElement, 'uploadStatus' );
 			} );
 
 			fileRepository.destroyLoader( loader );

+ 100 - 0
packages/ckeditor5-upload/src/imageuploadprogress.js

@@ -0,0 +1,100 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module upload/imageuploadprogress
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import { eventNameToConsumableType } from '@ckeditor/ckeditor5-engine/src/conversion/model-to-view-converters';
+import FileRepository from './filerepository';
+import uploadingPlaceholder from '../theme/icons/image_placeholder.svg';
+import UIElement from '@ckeditor/ckeditor5-engine/src/view/uielement';
+
+export default class ImageUploadProgress extends Plugin {
+	constructor( editor ) {
+		super( editor );
+
+		/**
+		 * Image's placeholder that is displayed before real image data can be accessed.
+		 *
+		 * @protected
+		 * @member {String} #placeholder
+		 */
+		this.placeholder = 'data:image/svg+xml;utf8,' + uploadingPlaceholder;
+	}
+
+	init() {
+		const editor = this.editor;
+		const fileRepository = editor.plugins.get( FileRepository );
+		const placeholder = this.placeholder;
+
+		// Upload status change - update image's view according to that status.
+		editor.editing.modelToView.on( 'addAttribute:uploadStatus:image', uploadStatusChange );
+		editor.editing.modelToView.on( 'changeAttribute:uploadStatus:image', uploadStatusChange );
+
+		function uploadStatusChange( evt, data, consumable ) {
+			if ( !consumable.consume( data.item, eventNameToConsumableType( evt.name ) ) ) {
+				return;
+			}
+
+			const status = data.attributeNewValue;
+			const modelImage = data.item;
+			const viewFigure = editor.editing.mapper.toViewElement( modelImage );
+			const uploadId = modelImage.getAttribute( 'uploadId' );
+
+			if ( !uploadId ) {
+				return;
+			}
+
+			if ( status == 'reading' ) {
+				viewFigure.addClass( 'ck-appear', 'ck-infinite-progress' );
+				const viewImg = viewFigure.getChild( 0 );
+				viewImg.setAttribute( 'src', placeholder );
+			}
+
+			if ( status == 'uploading' ) {
+				viewFigure.removeClass( 'ck-infinite-progress' );
+				const progressBar = createProgressBar();
+				viewFigure.appendChildren( progressBar );
+				const loader = fileRepository.loaders.get( uploadId );
+
+				loader.on( 'change:uploadedPercent', ( evt, name, value ) => {
+					progressBar.setStyle( 'width', value + '%' );
+					editor.editing.view.render();
+				} );
+			}
+
+			if ( status == 'complete' ) {
+				const viewFigure = editor.editing.mapper.toViewElement( modelImage );
+				const progressBar = getProgressBar( viewFigure );
+
+				if ( progressBar ) {
+					progressBar.remove();
+					editor.editing.view.render();
+				}
+			}
+		}
+	}
+}
+
+const progressBarSymbol = Symbol( 'progress-bar' );
+
+function createProgressBar() {
+	const progressBar = new UIElement( 'div', { class: 'ck-progress-bar' } );
+	progressBar.setCustomProperty( progressBarSymbol, true );
+
+	return progressBar;
+}
+
+function getProgressBar( imageFigure ) {
+	for ( const child of imageFigure.getChildren() ) {
+		if ( child.getCustomProperty( progressBarSymbol ) ) {
+			return child;
+		}
+	}
+
+	return null;
+}