|
|
@@ -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;
|
|
|
+ } );
|
|
|
+}
|