8
0
Pārlūkot izejas kodu

Add restricted editing marker upcast converter.

Maciej Gołaszewski 6 gadi atpakaļ
vecāks
revīzija
fb90dc1605

+ 51 - 0
packages/ckeditor5-restricted-editing/src/restrictedediting.js

@@ -8,6 +8,7 @@
  */
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import Matcher from '@ckeditor/ckeditor5-engine/src/view/matcher';
 
 /**
  * @extends module:core/plugin~Plugin
@@ -26,6 +27,20 @@ export default class RestrictedEditing extends Plugin {
 	init() {
 		const editor = this.editor;
 
+		let createdMarkers = 0;
+
+		editor.conversion.for( 'upcast' ).add( upcastHighlightToMarker( {
+			view: {
+				name: 'span',
+				classes: 'ck-restricted-editing-exception'
+			},
+			model: () => {
+				createdMarkers++;
+
+				return `restricted-editing-exception:${ createdMarkers }`;
+			}
+		} ) );
+
 		editor.conversion.for( 'downcast' ).markerToHighlight( {
 			model: 'restricted-editing-exception',
 			view: {
@@ -35,3 +50,39 @@ export default class RestrictedEditing extends Plugin {
 		} );
 	}
 }
+
+function upcastHighlightToMarker( config ) {
+	return dispatcher => dispatcher.on( 'element:span', ( evt, data, conversionApi ) => {
+		const { writer } = conversionApi;
+
+		const matcher = new Matcher( config.view );
+		const matcherResult = matcher.match( data.viewItem );
+
+		// If there is no match, this callback should not do anything.
+		if ( !matcherResult ) {
+			return;
+		}
+
+		const match = matcherResult.match;
+
+		// Force consuming element's name (taken from upcast helpers elementToElement converter).
+		match.name = true;
+
+		const { modelRange: convertedChildrenRange } = conversionApi.convertChildren( data.viewItem, data.modelCursor );
+		conversionApi.consumable.consume( data.viewItem, match );
+
+		const markerName = config.model( data.viewItem );
+		const fakeMarkerStart = writer.createElement( '$marker', { 'data-name': markerName } );
+		const fakeMarkerEnd = writer.createElement( '$marker', { 'data-name': markerName } );
+
+		// Insert in reverse order to use converter content positions directly (without recalculating).
+		writer.insert( fakeMarkerEnd, convertedChildrenRange.end );
+		writer.insert( fakeMarkerStart, convertedChildrenRange.start );
+
+		data.modelRange = writer.createRange(
+			writer.createPositionBefore( fakeMarkerStart ),
+			writer.createPositionAfter( fakeMarkerEnd )
+		);
+		data.modelCursor = data.modelRange.end;
+	} );
+}

+ 13 - 0
packages/ckeditor5-restricted-editing/tests/restrictedediting.js

@@ -54,6 +54,19 @@ describe( 'RestrictedEditing', () => {
 			return editor.destroy();
 		} );
 
+		describe( 'upcast', () => {
+			it( 'should convert <span class="ck-restricted-editing-exception"> to marker', () => {
+				editor.setData( '<p>foo <span class="ck-restricted-editing-exception">bar</span> baz</p>' );
+
+				expect( model.markers.has( 'restricted-editing-exception:1' ) ).to.be.true;
+
+				const marker = model.markers.get( 'restricted-editing-exception:1' );
+
+				expect( marker.getStart().path ).to.deep.equal( [ 0, 4 ] );
+				expect( marker.getEnd().path ).to.deep.equal( [ 0, 7 ] );
+			} );
+		} );
+
 		describe( 'downcast', () => {
 			it( 'should convert model marker to <span>', () => {
 				setModelData( model, '<paragraph>foo bar baz</paragraph>' );