Przeglądaj źródła

Added configuration for range inside text representation.

Oskar Wrobel 9 lat temu
rodzic
commit
c0dd13db03

+ 13 - 0
packages/ckeditor5-engine/tests/_utils-tests/view.js

@@ -186,6 +186,19 @@ describe( 'view test utils', () => {
 			expect( stringify( p, selection ) ).to.equal( '<p><b>f{ooba}r</b><b>bazqux</b></p>' );
 		} );
 
+		it( 'should write selection ranges inside text represented by custom characters', () => {
+			const text1 = new Text( 'foobar' );
+			const text2 = new Text( 'bazqux' );
+			const b1 = new Element( 'b', null, text1 );
+			const b2 = new Element( 'b', null, text2 );
+			const p = new Element( 'p', null, [ b1, b2 ] );
+			const range = Range.createFromParentsAndOffsets( text1, 1, text1, 5 );
+			const selection = new Selection();
+			selection.addRange( range );
+			expect( stringify( p, selection, { characterForSelectionInText: [ '_SELECTION-START_', '_SELECTION-END_' ] } ) )
+				.to.equal( '<p><b>f_SELECTION-START_ooba_SELECTION-END_r</b><b>bazqux</b></p>' );
+		} );
+
 		it( 'should write collapsed selection ranges inside texts', () => {
 			const text = new Text( 'foobar' );
 			const p = new Element( 'p', null, text );

+ 2 - 5
packages/ckeditor5-engine/tests/_utils/model.js

@@ -23,10 +23,7 @@ import ViewText from '/ckeditor5/engine/view/text.js';
 import viewWriter from '/ckeditor5/engine/view/writer.js';
 
 import { parse as viewParse, stringify as viewStringify } from '/tests/engine/_utils/view.js';
-import {
-	convertRangeSelection,
-	convertCollapsedSelection
-} from '/ckeditor5/engine/conversion/model-selection-to-view-converters.js';
+import { convertRangeSelection, convertCollapsedSelection } from '/ckeditor5/engine/conversion/model-selection-to-view-converters.js';
 import { convertText, convertToModelFragment } from '/ckeditor5/engine/conversion/view-to-model-converters.js';
 
 // Test utils uses `<$text foo="bar">Lorem ipsum</$text>` notation to create text with attributes, but `$text` is not
@@ -194,7 +191,7 @@ export function stringify( node, selectionOrPositionOrRange = null ) {
 	mapper.clearBindings();
 
 	// Parse view to data string.
-	let data = viewStringify( viewDocumentFragment, viewSelection );
+	let data = viewStringify( viewDocumentFragment, viewSelection, { characterForSelectionInText: [ '[', ']' ] } );
 
 	// Replace valid XML text element name to `$text`.
 	return data.replace( new RegExp( VIEW_TEXT_WITH_ATTRIBUTES_ELEMENT, 'g' ), DATA_STRING_TEXT_WITH_ATTRIBUTES_ELEMENT );

+ 17 - 3
packages/ckeditor5-engine/tests/_utils/view.js

@@ -125,6 +125,11 @@ setData._parse = parse;
  *
  *		stringify( p, selection ); // '<p><b>f{ooba}r</b></p>'
  *
+ * NOTE:
+ * Characters representing range placed inside text are customizable by `characterForSelectionInText` option.
+ * It is mainly needed when view stringify function is used by model stringify util, then range
+ * is represented with `[` and `]`.
+ *
  * Multiple ranges are supported:
  *
  *		const text = new Text( 'foobar' );
@@ -175,6 +180,9 @@ setData._parse = parse;
  * (`<span:12>`, `<b:10>`).
  * @param {Boolean} [options.ignoreRoot=false] When set to `true` root's element opening and closing will not be printed.
  * Mainly used by `getData` function to ignore {@link engine.view.Document Document's} root element.
+ * @param {Array<String>} [options.characterForSelectionInText=['{','}']] At default range placed inside text is
+ * represented with `{` and `}` characters, but when stringify function is used by model stringify util then characters
+ * are changed to `[` and `]`.
  * @returns {String} HTML-like string representing the view.
  */
 export function stringify( node, selectionOrPositionOrRange = null, options = {} ) {
@@ -190,6 +198,10 @@ export function stringify( node, selectionOrPositionOrRange = null, options = {}
 		selection = selectionOrPositionOrRange;
 	}
 
+	if ( !options.characterForSelectionInText ) {
+		options.characterForSelectionInText = [ TEXT_RANGE_START_TOKEN, TEXT_RANGE_END_TOKEN ];
+	}
+
 	const viewStringify = new ViewStringify( node, selection, options );
 
 	return viewStringify.stringify();
@@ -520,6 +532,7 @@ class ViewStringify {
 	 * @param {Boolean} [options.showPriority=false] When set to `true` AttributeElement's priority will be printed.
 	 * @param {Boolean} [options.ignoreRoot=false] When set to `true` root's element opening and closing tag will not
 	 * be outputted.
+	 * @param {Array<String>} [options.characterForSelectionInText = [ '{', '}' ]
 	 */
 	constructor( root, selection = null, options = {} ) {
 		this.root = root;
@@ -533,6 +546,7 @@ class ViewStringify {
 		this.showType = !!options.showType;
 		this.showPriority = !!options.showPriority;
 		this.ignoreRoot = !!options.ignoreRoot;
+		this.characterForSelectionInText = options.characterForSelectionInText;
 	}
 
 	/**
@@ -646,14 +660,14 @@ class ViewStringify {
 
 			if ( start.parent == node && start.offset >= 0 && start.offset <= length ) {
 				if ( range.isCollapsed ) {
-					result[ end.offset ].collapsed += TEXT_RANGE_START_TOKEN + TEXT_RANGE_END_TOKEN;
+					result[ end.offset ].collapsed += this.characterForSelectionInText.join( '' );
 				} else {
-					result[ start.offset ].start += TEXT_RANGE_START_TOKEN;
+					result[ start.offset ].start += this.characterForSelectionInText[ 0 ];
 				}
 			}
 
 			if ( end.parent == node && end.offset >= 0 && end.offset <= length && !range.isCollapsed  ) {
-				result[ end.offset ].end += TEXT_RANGE_END_TOKEN;
+				result[ end.offset ].end += this.characterForSelectionInText[ 1 ];
 			}
 		}