ソースを参照

Other: Define highlight feature conversions.

Maciej Gołaszewski 8 年 前
コミット
64b6e86e2a

+ 43 - 0
packages/ckeditor5-highlight/src/highlightediting.js

@@ -10,6 +10,10 @@
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 
 import HighlightCommand from './highlightcommand';
+import buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';
+import buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';
+
+import AttributeElement from '@ckeditor/ckeditor5-engine/src/view/attributeelement';
 
 /**
  * @extends module:core/plugin~Plugin
@@ -20,6 +24,8 @@ export default class HighlightEditing extends Plugin {
 	 */
 	init() {
 		const editor = this.editor;
+		const data = editor.data;
+		const editing = editor.editing;
 
 		editor.config.define( 'highlight', [
 			{ class: 'marker', title: 'Marker', color: '#ffff66', type: 'marker' },
@@ -29,6 +35,43 @@ export default class HighlightEditing extends Plugin {
 			{ class: 'pen-blue', title: 'Blue Pen', color: '#0000ff', type: 'pen' }
 		] );
 
+		// Allow highlight attribute on all elements
+		editor.document.schema.allow( { name: '$inline', attributes: 'highlight', inside: '$block' } );
+
+		// Convert highlight attribute to a mark element with associated class.
+		buildModelConverter()
+			.for( data.modelToView, editing.modelToView )
+			.fromAttribute( 'highlight' )
+			.toElement( data => {
+				const attributeElement = new AttributeElement( 'mark' );
+
+				attributeElement.addClass( data );
+
+				return attributeElement;
+			} );
+
+		const configuredClasses = editor.config.get( 'highlight' ).map( config => config.class );
+
+		// Convert `mark` attribute with class name to model's highlight attribute.
+		buildViewConverter()
+			.for( data.viewToModel )
+			.fromElement( 'mark' )
+			.toAttribute( viewElement => {
+				const viewClassNames = [ ...viewElement.getClassNames() ];
+
+				if ( !viewClassNames.length ) {
+					return;
+				}
+
+				const highlightClassNames = viewClassNames.filter( className => configuredClasses.includes( className ) );
+
+				if ( !highlightClassNames.length ) {
+					return;
+				}
+
+				return { key: 'highlight', value: highlightClassNames[ 0 ] };
+			} );
+
 		editor.commands.add( 'highlight', new HighlightCommand( editor ) );
 	}
 }

+ 25 - 11
packages/ckeditor5-highlight/tests/highlightediting.js

@@ -56,28 +56,42 @@ describe( 'HighlightEditing', () => {
 		} );
 	} );
 
-	describe.skip( 'data pipeline conversions', () => {
+	describe( 'data pipeline conversions', () => {
 		it( 'should convert defined marker classes', () => {
 			const data = '<p>f<mark class="marker">o</mark>o</p>';
 
 			editor.setData( data );
 
-			expect( getModelData( doc ) ).to.equal( '<paragraph>f<$text highlight="">o</$text>o</paragraph>' );
-			expect( editor.getData() ).to.equal( '<p>x</p>' );
+			expect( getModelData( doc ) ).to.equal( '<paragraph>[]f<$text highlight="marker">o</$text>o</paragraph>' );
+			expect( editor.getData() ).to.equal( data );
+		} );
+		it( 'should convert only one defined marker classes', () => {
+			editor.setData( '<p>f<mark class="marker-green marker">o</mark>o</p>' );
+
+			expect( getModelData( doc ) ).to.equal( '<paragraph>[]f<$text highlight="marker-green">o</$text>o</paragraph>' );
+			expect( editor.getData() ).to.equal( '<p>f<mark class="marker-green">o</mark>o</p>' );
 		} );
-	} );
 
-	describe.skip( 'editing pipeline conversion', () => {
-		it( 'adds a converter to the view pipeline for removing attribute', () => {
-			setModelData( doc, '<paragraph>f<$text highlight="">o</$text>o</paragraph>' );
+		it( 'should not convert undefined marker classes', () => {
+			editor.setData( '<p>f<mark class="some-unknown-marker">o</mark>o</p>' );
 
-			expect( editor.getData() ).to.equal( '<p>f<mark>o</mark>o</p>' );
+			expect( getModelData( doc ) ).to.equal( '<paragraph>[]foo</paragraph>' );
+			expect( editor.getData() ).to.equal( '<p>foo</p>' );
+		} );
 
-			const command = editor.commands.get( 'highlight' );
+		it( 'should not convert marker without class', () => {
+			editor.setData( '<p>f<mark>o</mark>o</p>' );
+
+			expect( getModelData( doc ) ).to.equal( '<paragraph>[]foo</paragraph>' );
+			expect( editor.getData() ).to.equal( '<p>foo</p>' );
+		} );
+	} );
 
-			command.execute();
+	describe( 'editing pipeline conversion', () => {
+		it( 'should convert mark element with defined class', () => {
+			setModelData( doc, '<paragraph>f<$text highlight="marker">o</$text>o</paragraph>' );
 
-			expect( editor.getData() ).to.equal( '<p>x</p>' );
+			expect( editor.getData() ).to.equal( '<p>f<mark class="marker">o</mark>o</p>' );
 		} );
 	} );