Explorar o código

Introduce getText() protected util.

Maciej Gołaszewski %!s(int64=6) %!d(string=hai) anos
pai
achega
197564c76d

+ 2 - 22
packages/ckeditor5-typing/src/textwatcher.js

@@ -9,6 +9,7 @@
 
 import mix from '@ckeditor/ckeditor5-utils/src/mix';
 import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
+import getText from './utils/gettext';
 
 /**
  * The text watcher feature.
@@ -132,30 +133,9 @@ export default class TextWatcher {
 
 		const rangeBeforeSelection = model.createRange( model.createPositionAt( selection.focus.parent, 0 ), selection.focus );
 
-		return _getText( rangeBeforeSelection, model );
+		return getText( rangeBeforeSelection, model );
 	}
 }
 
-// Returns the whole text from a given range by adding all data from the text nodes together.
-//
-// @param {module:engine/model/range~Range} range
-// @returns {Object}
-function _getText( range, model ) {
-	let start = range.start;
-
-	const text = Array.from( range.getItems() ).reduce( ( rangeText, node ) => {
-		if ( node.is( 'softBreak' ) ) {
-			// Trim text to a <softBreak> and update range start.
-			start = model.createPositionAfter( node );
-
-			return '';
-		}
-
-		return rangeText + node.data;
-	}, '' );
-
-	return { text, range: model.createRange( start, range.end ) };
-}
-
 mix( TextWatcher, EmitterMixin );
 

+ 36 - 0
packages/ckeditor5-typing/src/utils/gettext.js

@@ -0,0 +1,36 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/**
+ * @module typing/utils/gettext
+ */
+
+/**
+ * Returns the whole text from a given range by adding all data from the text nodes together.
+ *
+ * **Note** The text is trimmed to the last occurrence of any inline element (e.g. `<softBreak>`).
+ *
+ * @protected
+ * @param {module:engine/model/range~Range} range
+ * @param {module:engine/model/model~Model} model
+ * @returns {Object}
+ */
+export default function getText( range, model ) {
+	let start = range.start;
+
+	const text = Array.from( range.getItems() ).reduce( ( rangeText, node ) => {
+		// Trim text to a last occurrence of an inline element and update range start.
+		if ( !( node.is( 'text' ) || node.is( 'textProxy' ) ) ) {
+			start = model.createPositionAfter( node );
+
+			return '';
+		}
+
+		return rangeText + node.data;
+	}, '' );
+
+	return { text, range: model.createRange( start, range.end ) };
+}
+

+ 88 - 0
packages/ckeditor5-typing/tests/utils/gettext.js

@@ -0,0 +1,88 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+import Model from '@ckeditor/ckeditor5-engine/src/model/model';
+import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+import getText from '../../src/utils/gettext';
+
+describe( 'utils', () => {
+	let model, doc, root;
+
+	beforeEach( () => {
+		model = new Model();
+		doc = model.document;
+		root = doc.createRoot();
+
+		model.schema.register( 'paragraph', { inheritAllFrom: '$block' } );
+		model.schema.register( 'softBreak', { allowWhere: '$text', isInline: true } );
+		model.schema.extend( '$text', { allowAttributes: [ 'bold', 'italic' ] } );
+	} );
+
+	describe( 'getText()', () => {
+		it( 'should return all text from passed range', () => {
+			setModelData( model, '<paragraph>foobar[]baz</paragraph>' );
+
+			testOutput(
+				model.createRangeIn( root.getChild( 0 ) ),
+				'foobarbaz',
+				[ 0, 0 ],
+				[ 0, 9 ] );
+		} );
+
+		it( 'should limit the output text to the given range', () => {
+			setModelData( model, '<paragraph>foobar[]baz</paragraph>' );
+
+			const testRange = model.createRange(
+				model.createPositionAt( root.getChild( 0 ), 1 ),
+				model.document.selection.focus
+			);
+
+			testOutput(
+				testRange,
+				'oobar',
+				[ 0, 1 ],
+				[ 0, 6 ] );
+		} );
+
+		it( 'should limit the output to the last inline element text constrain in given range', () => {
+			setModelData( model, '<paragraph>foo<softBreak></softBreak>bar<softBreak></softBreak>baz[]</paragraph>' );
+
+			const testRange = model.createRange(
+				model.createPositionAt( root.getChild( 0 ), 0 ),
+				model.document.selection.focus
+			);
+
+			testOutput(
+				testRange,
+				'baz',
+				[ 0, 8 ],
+				[ 0, 11 ] );
+		} );
+
+		it( 'should return text from text nodes with attributes', () => {
+			setModelData( model,
+				'<paragraph>' +
+				'<$text bold="true">foo</$text>' +
+				'<$text bold="true" italic="true">bar</$text>' +
+				'<$text italic="true">baz</$text>[]' +
+				'</paragraph>'
+			);
+
+			testOutput(
+				model.createRangeIn( root.getChild( 0 ) ),
+				'foobarbaz',
+				[ 0, 0 ],
+				[ 0, 9 ] );
+		} );
+	} );
+
+	function testOutput( range1, expectedText, startPath, endPath ) {
+		const { text, range } = getText( range1, model );
+
+		expect( text ).to.equal( expectedText );
+		expect( range.start.path ).to.deep.equal( startPath );
+		expect( range.end.path ).to.deep.equal( endPath );
+	}
+} );