Browse Source

Try to customize marker conversion.

Maciej Gołaszewski 6 years ago
parent
commit
c90989568e

+ 5 - 1
packages/ckeditor5-mention/src/mentioneditingmarker.js

@@ -10,6 +10,10 @@
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import Command from '@ckeditor/ckeditor5-core/src/command';
 
+export function createMentionMarkerId( someString ) {
+	return 'mention:' + someString.toLowerCase().replace( ' ', '-' ) + parseInt( Math.random() * 10000 );
+}
+
 class MentionCommand extends Command {
 	/**
 	 * @inheritDoc
@@ -47,7 +51,7 @@ class MentionCommand extends Command {
 			writer.insert( text, selection.focus );
 
 			// TODO dumb
-			const name = 'mention:' + label.toLowerCase().replace( ' ', '-' );
+			const name = createMentionMarkerId( label );
 
 			writer.addMarker( name, {
 				range: writer.createRange( selection.focus.getShiftedBy( -text.data.length ), selection.focus ),

+ 59 - 1
packages/ckeditor5-mention/tests/manual/mention-custom-view.js

@@ -23,6 +23,8 @@ import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
 import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import priorities from '@ckeditor/ckeditor5-utils/src/priorities';
+import ModelSelection from '@ckeditor/ckeditor5-engine/src/model/selection';
+import DocumentSelection from '@ckeditor/ckeditor5-engine/src/model/documentselection';
 
 import MentionUI from '../../src/mentionui';
 // eslint-disable-next-line no-unused-vars
@@ -30,7 +32,7 @@ import MentionEditing from '../../src/mentionediting';
 // eslint-disable-next-line no-unused-vars
 import MentionElementEditing from '../../src/mentioneditingelement';
 // eslint-disable-next-line no-unused-vars
-import MentionMarkerEditing from '../../src/mentioneditingmarker';
+import MentionMarkerEditing, { createMentionMarkerId } from '../../src/mentioneditingmarker';
 
 const HIGHER_THEN_HIGHEST = priorities.highest + 50;
 
@@ -129,6 +131,60 @@ class CustomMentionElementView extends Plugin {
 	}
 }
 
+// eslint-disable-next-line no-unused-vars
+class CustomMentionMarkerView extends Plugin {
+	init() {
+		const editor = this.editor;
+
+		// Convert marker v->m.
+		editor.conversion.for( 'upcast' ).elementToMarker( {
+			view: {
+				name: 'a',
+				attribute: {
+					'data-mention': /^\w/
+				}
+			},
+			model: viewElement => createMentionMarkerId( viewElement.getAttribute( 'data-mention' ) )
+		} );
+
+		editor.conversion.for( 'downcast' ).add( dispatcher => {
+			dispatcher.on( 'addMarker:mention', ( evt, data, conversionApi ) => {
+				const { id } = data.markerName.split( ':' )[ 1 ];
+
+				if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
+					return;
+				}
+
+				const viewWriter = conversionApi.writer;
+
+				// OMG I just wanted to change `<span>` to `<a>`...
+				const viewElement = viewWriter.createAttributeElement( 'a', {
+					class: [ 'mention' ],
+					'data-mention': id
+				} );
+				const viewSelection = viewWriter.document.selection;
+
+				if ( data.item instanceof ModelSelection || data.item instanceof DocumentSelection ) {
+					viewWriter.wrap( viewSelection.getFirstRange(), viewElement, viewSelection );
+				} else {
+					const viewRange = conversionApi.mapper.toViewRange( data.range );
+					const rangeAfterWrap = viewWriter.wrap( viewRange, viewElement );
+
+					for ( const element of rangeAfterWrap.getItems() ) {
+						if ( element.is( 'attributeElement' ) && element.isSimilar( viewElement ) ) {
+							conversionApi.mapper.bindElementToMarker( element, data.markerName );
+
+							// One attribute element is enough, because all of them are bound together by the view writer.
+							// Mapper uses this binding to get all the elements no matter how many of them are registered in the mapper.
+							break;
+						}
+					}
+				}
+			}, { priority: HIGHER_THEN_HIGHEST } );
+		} );
+	}
+}
+
 ClassicEditor
 	.create( global.document.querySelector( '#editor' ), {
 		plugins: [ Enter, Typing, Paragraph, Link, Heading, Bold, Italic, Underline, Undo, Clipboard, Widget, ShiftEnter, Table,
@@ -140,7 +196,9 @@ ClassicEditor
 			// MentionElementEditing,
 			// CustomMentionElementView,
 
+			// 3. Using marker - promising
 			MentionMarkerEditing,
+			CustomMentionMarkerView,
 
 			// Common: ui
 			MentionUI