8
0
Quellcode durchsuchen

Enhancement: Initial alignment feature implementation.

Maciej Gołaszewski vor 8 Jahren
Ursprung
Commit
6574bf163d

+ 10 - 1
packages/ckeditor5-alignment/package.json

@@ -9,9 +9,18 @@
   "dependencies": {
   "dependencies": {
     "@ckeditor/ckeditor5-core": "^1.0.0-alpha.1",
     "@ckeditor/ckeditor5-core": "^1.0.0-alpha.1",
     "@ckeditor/ckeditor5-engine": "^1.0.0-alpha.1",
     "@ckeditor/ckeditor5-engine": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-utils": "^1.0.0-alpha.1"
+    "@ckeditor/ckeditor5-ui": "^1.0.0-alpha.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
+    "@ckeditor/ckeditor5-basic-styles": "^1.0.0-alpha.1",
+    "@ckeditor/ckeditor5-clipboard": "^1.0.0-alpha.1",
+    "@ckeditor/ckeditor5-editor-classic": "^1.0.0-alpha.1",
+    "@ckeditor/ckeditor5-enter": "^1.0.0-alpha.1",
+    "@ckeditor/ckeditor5-heading": "^1.0.0-alpha.1",
+    "@ckeditor/ckeditor5-list": "^1.0.0-alpha.1",
+    "@ckeditor/ckeditor5-paragraph": "^1.0.0-alpha.1",
+    "@ckeditor/ckeditor5-typing": "^1.0.0-alpha.1",
+    "@ckeditor/ckeditor5-undo": "^1.0.0-alpha.1",
     "eslint": "^4.8.0",
     "eslint": "^4.8.0",
     "eslint-config-ckeditor5": "^1.0.6",
     "eslint-config-ckeditor5": "^1.0.6",
     "husky": "^0.14.3",
     "husky": "^0.14.3",

+ 85 - 0
packages/ckeditor5-alignment/src/alignment.js

@@ -0,0 +1,85 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module alignment/alignment
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+
+import AlignmentEngine from './alignmentengine';
+
+import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+
+import alignLeftIcon from '../theme/icons/alignleft.svg';
+import alignRightIcon from '../theme/icons/alignright.svg';
+import alignCenterIcon from '../theme/icons/aligncenter.svg';
+import alignJustifyIcon from '../theme/icons/alignjustify.svg';
+
+/**
+ * The alignment plugin.
+ *
+ * It introduces the `'alignLeft'`, `'alignRight'`, `'alignCenter'` and `'alignJustify'` buttons
+ * and requires the {@link module:alignment/alignmentengine~AlignmentEngine} plugin.
+ *
+ * @extends module:core/plugin~Plugin
+ */
+export default class Alignment extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	static get requires() {
+		return [ AlignmentEngine ];
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	static get pluginName() {
+		return 'Alignment';
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		const t = this.editor.t;
+		this._addButton( 'alignLeft', t( 'Left' ), alignLeftIcon );
+		this._addButton( 'alignRight', t( 'Right' ), alignRightIcon );
+		this._addButton( 'alignCenter', t( 'Center' ), alignCenterIcon );
+		this._addButton( 'alignJustify', t( 'Justify' ), alignJustifyIcon );
+	}
+
+	/**
+	 * Helper method for initializing a button and linking it with an appropriate command.
+	 *
+	 * @private
+	 * @param {String} commandName The name of the command.
+	 * @param {Object} label The button label.
+	 * @param {String} icon The source of the icon.
+	 */
+	_addButton( commandName, label, icon ) {
+		const editor = this.editor;
+		const command = editor.commands.get( commandName );
+
+		editor.ui.componentFactory.add( commandName, locale => {
+			const buttonView = new ButtonView( locale );
+
+			buttonView.set( {
+				label,
+				icon,
+				tooltip: true
+			} );
+
+			// Bind button model to command.
+			buttonView.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );
+
+			// Execute command.
+			this.listenTo( buttonView, 'execute', () => editor.execute( commandName ) );
+
+			return buttonView;
+		} );
+	}
+}

+ 73 - 0
packages/ckeditor5-alignment/src/alignmentcommand.js

@@ -0,0 +1,73 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module alignment/alignmentcommand
+ */
+
+import Command from '@ckeditor/ckeditor5-core/src/command';
+
+/**
+ * The alignment command plugin.
+ *
+ * @extends module:core/command~Command
+ */
+export default class AlignmentCommand extends Command {
+	/**
+	 * Creates an instance of the command.
+	 *
+	 * @param {module:core/editor/editor~Editor} editor The editor instance.
+	 * @param {'left'|'right'|'center'|'justify'} type Alignment type to be handled by this command.
+	 */
+	constructor( editor, type ) {
+		super( editor );
+
+		/**
+		 * The type of the list created by the command.
+		 *
+		 * @readonly
+		 * @member {'left'|'right'|'center'|'justify'}
+		 */
+		this.type = type;
+
+		/**
+		 * A flag indicating whether the command is active, which means that the selection starts in a list of the same type.
+		 *
+		 * @observable
+		 * @readonly
+		 * @member {Boolean} #value
+		 */
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	refresh() {
+		this.value = '';
+		this.isEnabled = true;
+	}
+
+	/**
+	 * Executes the command.
+	 *
+	 * @protected
+	 * @param {Object} [options] Options for the executed command.
+	 * @param {module:engine/model/batch~Batch} [options.batch] A batch to collect all the change steps.
+	 * A new batch will be created if this option is not set.
+	 */
+	execute( options = {} ) {
+		const editor = this.editor;
+		const document = editor.document;
+
+		document.enqueueChanges( () => {
+			const batch = options.batch || document.batch();
+			const blocks = Array.from( document.selection.getSelectedBlocks() );
+
+			for ( const block of blocks ) {
+				batch.setAttribute( block, 'alignment', this.type );
+			}
+		} );
+	}
+}

+ 65 - 0
packages/ckeditor5-alignment/src/alignmentengine.js

@@ -0,0 +1,65 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module alignment/alignmentengine
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+
+import AlignmentCommand from './alignmentcommand';
+
+import buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';
+import buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';
+
+/**
+ * @extends module:core/plugin~Plugin
+ */
+export default class AlignmentEngine extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	static get requires() {
+		return [];
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		const editor = this.editor;
+		const doc = editor.document;
+		const schema = doc.schema;
+		const data = editor.data;
+		const editing = editor.editing;
+
+		// Allow alignment on all blocks.
+		schema.allow( { name: '$block', attributes: 'alignment', inside: '$root' } );
+
+		buildModelConverter()
+			.for( data.modelToView, editing.modelToView )
+			.fromAttribute( 'alignment' )
+			.toAttribute( value => ( { key: 'style', value: `text-align:${ value }` } ) );
+
+		buildViewConverter()
+			.for( data.viewToModel )
+			.fromAttribute( 'style', /text-align/ )
+			.toAttribute( viewElement => {
+				const textAlign = viewElement.getStyle( 'text-align' );
+
+				if ( !textAlign ) {
+					return;
+				}
+
+				return { key: 'alignment', value: textAlign };
+			} );
+
+		// Register commands for text alignment.
+		editor.commands.add( 'alignLeft', new AlignmentCommand( editor, 'left' ) );
+		editor.commands.add( 'alignRight', new AlignmentCommand( editor, 'right' ) );
+		editor.commands.add( 'alignCenter', new AlignmentCommand( editor, 'center' ) );
+		editor.commands.add( 'alignJustify', new AlignmentCommand( editor, 'justify' ) );
+	}
+}

+ 9 - 0
packages/ckeditor5-alignment/tests/manual/alignment.html

@@ -0,0 +1,9 @@
+<div id="editor">
+	<p><strong>This should be aligned to the left</strong>This is a test for text alignment feature.</p>
+
+	<p style="text-align:right"><strong>This should be aligned to the right</strong>. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+
+	<p style="text-align:center"><strong>This should be centered</strong>. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+
+	<p style="text-align:justify"><strong>This should be justified</strong>. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+</div>

+ 31 - 0
packages/ckeditor5-alignment/tests/manual/alignment.js

@@ -0,0 +1,31 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals console, window, document */
+
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+import Enter from '@ckeditor/ckeditor5-enter/src/enter';
+import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Typing from '@ckeditor/ckeditor5-typing/src/typing';
+import Heading from '@ckeditor/ckeditor5-heading/src/heading';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import Undo from '@ckeditor/ckeditor5-undo/src/undo';
+import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';
+import List from '@ckeditor/ckeditor5-list/src/list';
+import Alignment from '../../src/alignment';
+
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ Enter, Typing, Bold, Heading, Paragraph, List, Undo, Clipboard, Alignment ],
+		toolbar: [
+			'headings', 'bold', 'alignLeft', 'alignRight', 'alignCenter', 'alignJustify', 'bulletedList', 'numberedList', 'undo', 'redo'
+		]
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 6 - 0
packages/ckeditor5-alignment/tests/manual/alignment.md

@@ -0,0 +1,6 @@
+### Loading
+
+TODO:
+
+### Testing
+

+ 17 - 0
packages/ckeditor5-alignment/theme/icons/aligncenter.svg

@@ -0,0 +1,17 @@
+<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg">
+ <!-- Created with Method Draw - http://github.com/duopixel/Method-Draw/ -->
+ <g>
+  <title>background</title>
+  <rect fill="none" id="canvas_background" height="22" width="22" y="-1" x="-1"/>
+  <g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" id="canvasGrid">
+   <rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" width="100%"/>
+  </g>
+ </g>
+ <g>
+  <title>Layer 1</title>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_5" y2="8.214292" x2="17.12117" y1="8.214292" x1="3.125025" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_6" y2="16.48807" x2="17.12117" y1="16.48807" x1="3.125025" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_8" y2="4.047642" x2="14.323562" y1="4.047642" x1="5.922633" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_9" y2="12.261896" x2="14.323562" y1="12.261896" x1="5.922633" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+ </g>
+</svg>

+ 17 - 0
packages/ckeditor5-alignment/theme/icons/alignjustify.svg

@@ -0,0 +1,17 @@
+<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg">
+ <!-- Created with Method Draw - http://github.com/duopixel/Method-Draw/ -->
+ <g>
+  <title>background</title>
+  <rect fill="none" id="canvas_background" height="22" width="22" y="-1" x="-1"/>
+  <g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" id="canvasGrid">
+   <rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" width="100%"/>
+  </g>
+ </g>
+ <g>
+  <title>Layer 1</title>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_5" y2="8.452387" x2="17.061646" y1="8.452387" x1="3.065501" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_6" y2="16.3095" x2="17.12117" y1="16.3095" x1="3.125025" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_10" y2="4.642877" x2="16.883075" y1="4.642877" x1="2.886931" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_11" y2="12.559514" x2="17.002123" y1="12.559514" x1="3.005978" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+ </g>
+</svg>

+ 17 - 0
packages/ckeditor5-alignment/theme/icons/alignleft.svg

@@ -0,0 +1,17 @@
+<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg">
+ <!-- Created with Method Draw - http://github.com/duopixel/Method-Draw/ -->
+ <g>
+  <title>background</title>
+  <rect fill="none" id="canvas_background" height="22" width="22" y="-1" x="-1"/>
+  <g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" id="canvasGrid">
+   <rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" width="100%"/>
+  </g>
+ </g>
+ <g>
+  <title>Layer 1</title>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_5" y2="8.214292" x2="15.930698" y1="8.214292" x1="1.934553" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_6" y2="16.48807" x2="15.930698" y1="16.48807" x1="1.934553" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_8" y2="4.047642" x2="10.335481" y1="4.047642" x1="1.934553" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_9" y2="12.261896" x2="10.335481" y1="12.261896" x1="1.934553" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+ </g>
+</svg>

+ 17 - 0
packages/ckeditor5-alignment/theme/icons/alignright.svg

@@ -0,0 +1,17 @@
+<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg">
+ <!-- Created with Method Draw - http://github.com/duopixel/Method-Draw/ -->
+ <g>
+  <title>background</title>
+  <rect fill="none" id="canvas_background" height="22" width="22" y="-1" x="-1"/>
+  <g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" id="canvasGrid">
+   <rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" width="100%"/>
+  </g>
+ </g>
+ <g>
+  <title>Layer 1</title>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_5" y2="8.214292" x2="18.133071" y1="8.214292" x1="4.136926" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_6" y2="16.48807" x2="18.133071" y1="16.48807" x1="4.136926" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_8" y2="4.047642" x2="18.133071" y1="4.047642" x1="9.732143" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+  <line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_9" y2="12.261896" x2="18.133071" y1="12.261896" x1="9.732143" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
+ </g>
+</svg>