8
0
Просмотр исходного кода

Added ImageUploadEngine and image placeholder image.

Szymon Kupś 8 лет назад
Родитель
Сommit
7cf8778f5e

+ 2 - 0
packages/ckeditor5-upload/package.json

@@ -6,6 +6,8 @@
   "dependencies": {
 	  "@ckeditor/ckeditor5-core": "^0.7.0",
 	  "@ckeditor/ckeditor5-engine": "^0.8.0",
+	  "@ckeditor/ckeditor5-notification": "^0.0.1",
+	  "@ckeditor/ckeditor5-ui": "^v0.7.1",
 	  "@ckeditor/ckeditor5-utils": "^0.8.0"
   },
   "devDependencies": {

+ 126 - 0
packages/ckeditor5-upload/src/imageuploadengine.js

@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2016, CKSource - Frederico Knabben. All rights reserved.
+ */
+
+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 Notification from '@ckeditor/ckeditor5-ui/src/notification/notification';
+import uploadingPlaceholder from '../theme/images/image_placeholder.svg';
+import { isImageType } from './utils';
+
+/**
+ * Image upload engine plugin.
+ *
+ * @extends module:core/plugin~Plugin
+ */
+export default class ImageUploadEngine extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	static get requires() {
+		return [ FileRepository, Notification ];
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		const editor = this.editor;
+		const doc = editor.document;
+		const schema = doc.schema;
+
+		// Setup schema to allow uploadId for images.
+		schema.allow( { name: 'image', attributes: [ 'uploadId' ], inside: '$root' } );
+		schema.requireAttributes( 'image', [ 'uploadId' ] );
+
+		// Register imageUpload command.
+		editor.commands.set( 'imageUpload', new ImageUploadCommand( editor ) );
+
+		// Execute imageUpload command when image is dropped or pasted.
+		editor.editing.view.on( 'input', ( evt, data ) => {
+			for ( const file of data.dataTransfer.files ) {
+				if ( isImageType( file ) ) {
+					editor.execute( 'imageUpload', { file: file } );
+					evt.stop();
+				}
+			}
+		} );
+
+		doc.on( 'change', ( evt, type, data, batch ) => {
+			if ( type === 'insert' ) {
+				for ( const value of data.range ) {
+					if ( value.type === 'elementStart' && value.item.name === 'image' ) {
+						const imageElement = value.item;
+						const uploadId = imageElement.getAttribute( 'uploadId' );
+						const fileRepository = editor.plugins.get( FileRepository );
+
+						if ( uploadId ) {
+							const loader = fileRepository.loaders.get( uploadId );
+
+							if ( loader && loader.status == 'idle' ) {
+								this.load( loader, batch, imageElement );
+							}
+						}
+					}
+				}
+			}
+		} );
+
+		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', uploadingPlaceholder );
+
+			// TODO: if there are data -> show data
+		} );
+	}
+
+	load( loader, batch, imageElement ) {
+		const editor = this.editor;
+		const doc = editor.document;
+		const fileRepository = editor.plugins.get( FileRepository );
+		const notification = editor.plugins.get( Notification );
+
+		loader.read()
+			.then( data => {
+				const viewFigure = editor.editing.mapper.toViewElement( imageElement );
+				const viewImg = viewFigure.getChild( 0 );
+				viewImg.setAttribute( 'src', data );
+				editor.editing.view.render();
+
+				return loader.upload();
+			} )
+			.then( data => {
+				doc.enqueueChanges( () => {
+					batch.setAttribute( imageElement, 'src', data.original );
+				} );
+
+				clean();
+			} )
+			.catch( msg => {
+				// Might be 'aborted'
+				if ( loader.status == 'error' ) {
+					notification.showWarning( msg, { namespace: 'upload' } );
+				}
+
+				clean();
+
+				// TODO: delete image
+			} );
+
+		function clean() {
+			doc.enqueueChanges( () => {
+				batch.removeAttribute( imageElement, 'uploadId' );
+			} );
+
+			fileRepository.destroyLoader( loader );
+		}
+	}
+}

+ 4 - 0
packages/ckeditor5-upload/tests/manual/imageupload.html

@@ -0,0 +1,4 @@
+<div id="editor">
+	<h2>Image upload</h2>
+	<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus consequat placerat. Vestibulum id tellus et mauris sagittis tincidunt quis id mauris. Curabitur consectetur lectus sit amet tellus mattis, non lobortis leo interdum.</p>
+</div>

+ 44 - 0
packages/ckeditor5-upload/tests/manual/imageupload.js

@@ -0,0 +1,44 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals document, window, console */
+
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic';
+import Enter from '@ckeditor/ckeditor5-enter/src/enter';
+import Typing from '@ckeditor/ckeditor5-typing/src/typing';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import Heading from '@ckeditor/ckeditor5-heading/src/heading';
+import Image from '@ckeditor/ckeditor5-image/src/image';
+import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
+import Undo from '@ckeditor/ckeditor5-undo/src/undo';
+import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';
+import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar';
+import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle';
+import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
+import List from '@ckeditor/ckeditor5-list/src/list';
+import ImageUpload from '../../src/imageuploadengine';
+import { AdapterMock } from '../_utils/mocks';
+
+ClassicEditor.create( document.querySelector( '#editor' ), {
+	plugins: [
+		Enter, Typing, Paragraph, Heading, Image, ImageToolbar, ImageUpload,
+		Undo, Clipboard, ImageCaption, ImageStyle, Bold, Italic, Heading, List
+	],
+	toolbar: [ 'headings', 'undo', 'redo', 'bold', 'italic', 'bulletedList', 'numberedList' ]
+} )
+.then( editor => {
+	window.editor = editor;
+
+	// Register fake adapter.
+	editor.plugins.get( 'fileRepository' ).createAdapter = loader => {
+		const adapterMock = new AdapterMock( loader );
+
+		return adapterMock;
+	};
+} )
+.catch( err => {
+	console.error( err.stack );
+} );

+ 1 - 0
packages/ckeditor5-upload/tests/manual/imageupload.md

@@ -0,0 +1 @@
+## Image upload

+ 15 - 0
packages/ckeditor5-upload/theme/images/image_placeholder.svg

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="350px" height="169px" viewBox="0 0 350 169" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 43 (38999) - http://www.bohemiancoding.com/sketch -->
+    <title>image_placeholder</title>
+    <desc>Created with Sketch.</desc>
+    <defs></defs>
+    <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="image_placeholder">
+            <rect id="Rectangle-10" fill="#EBF1F7" x="0" y="0" width="350" height="169" rx="4"></rect>
+            <text id="Uploading-image…" font-family="Georgia" font-size="14" font-weight="normal" fill="#A1B0C2">
+                <tspan x="117.100586" y="89">Uploading image…</tspan>
+            </text>
+        </g>
+    </g>
+</svg>