8
0
فهرست منبع

Changed: treeModel.TextFragment constructor.

Szymon Cofalik 10 سال پیش
والد
کامیت
8777506739

+ 17 - 21
packages/ckeditor5-engine/src/treemodel/textfragment.js

@@ -5,19 +5,17 @@
 
 'use strict';
 
-import Position from './position.js';
-import Range from './range.js';
+import CharacterProxy from './characterproxy.js';
 
 /**
  * TextFragment is an aggregator for multiple CharacterProxy instances that are placed next to each other in
  * tree model, in the same parent, and all have same attributes set. Instances of this class are created and returned
  * in various algorithms that "merge characters" (see {@link treeModel.TreeWalker}, {@link treeModel.Range}).
  *
- * Difference between {@link treeModel.TextFragment} and {@link treeModel.Text} is that the former is bound to tree model,
- * while {@link treeModel.Text} is simply a string with attributes set.
+ * Difference between {@link treeModel.TextFragment} and {@link treeModel.Text} is that the former is a set of
+ * nodes taken from tree model, while {@link treeModel.Text} is simply a string with attributes set.
  *
- * You should never create an instance of this class by your own. When passing parameters to constructors,
- * use string literals or {@link treeModel.Text} instead.
+ * You should never create an instance of this class by your own. Instead, use string literals or {@link treeModel.Text}.
  *
  * @class treeModel.TextFragment
  */
@@ -25,19 +23,19 @@ export default class TextFragment {
 	/**
 	 * Creates a text fragment.
 	 *
-	 * @param {treeModel.Position} startPosition Position in the tree model where the {@link treeModel.TextFragment} starts.
-	 * @param {String} text Characters contained in {@link treeModel.TextFragment}.
+	 * @param {treeModel.CharacterProxy} firstCharacter First character node contained in {@link treeModel.TextFragment}.
+	 * @param {Number) length Whole text contained in {@link treeModel.TextFragment}.
 	 * @protected
 	 * @constructor
 	 */
-	constructor( startPosition, text ) {
+	constructor( firstCharacter, length ) {
 		/**
-		 * First {@link treeModel.CharacterProxy character node} contained in {@link treeModel.TextFragment}.
+		 * First character node contained in {@link treeModel.TextFragment}.
 		 *
 		 * @readonly
 		 * @property {treeModel.CharacterProxy} first
 		 */
-		this.first = startPosition.nodeAfter;
+		this.first = firstCharacter;
 
 		/**
 		 * Characters contained in {@link treeModel.TextFragment}.
@@ -45,7 +43,7 @@ export default class TextFragment {
 		 * @readonly
 		 * @property {String} text
 		 */
-		this.text = text;
+		this.text = firstCharacter._nodeListText.text.substr( this.first._index, length );
 
 		/**
 		 * Last {@link treeModel.CharacterProxy character node} contained in {@link treeModel.TextFragment}.
@@ -54,14 +52,6 @@ export default class TextFragment {
 		 * @property {treeModel.CharacterProxy} last
 		 */
 		this.last = this.getCharAt( this.text.length - 1 );
-
-		/**
-		 * List of attributes common for all characters in this {@link treeModel.TextFragment}.
-		 *
-		 * @readonly
-		 * @property {@link treeModel.AttributeList} attrs
-		 */
-		this.attrs = this.first.attrs;
 	}
 
 	/**
@@ -71,7 +61,13 @@ export default class TextFragment {
 	 * @returns {treeModel.CharacterProxy}
 	 */
 	getCharAt( index ) {
-		return this.first.parent.getChild( this.first._index + index );
+		if ( index < 0 || index >= this.text.length ) {
+			return null;
+		}
+
+		return new CharacterProxy( this.first._nodeListText, this.first._index + index );
+	}
+
 	/**
 	 * Checks if the text fragment has an attribute that is {@link treeModel.Attribute#isEqual equal} to given attribute or
 	 * attribute with given key if string was passed.

+ 2 - 5
packages/ckeditor5-engine/src/treemodel/treewalker.js

@@ -150,8 +150,7 @@ export default class TreeWalker {
 					charactersCount = offset - position.offset;
 				}
 
-				let text = node._nodeListText.text.substr( node._index, charactersCount );
-				let textFragment = new TextFragment( position, text );
+				let textFragment = new TextFragment( node, charactersCount );
 
 				position.offset = offset;
 				this.position = position;
@@ -216,13 +215,11 @@ export default class TreeWalker {
 					charactersCount = position.offset - offset;
 				}
 
-				let text = node._nodeListText.text.substr( node._index + 1 - charactersCount, charactersCount );
+				let textFragment = new TextFragment( parent.getChild( offset ), charactersCount );
 
 				position.offset = offset;
 				this.position = position;
 
-				let textFragment = new TextFragment( this.position, text );
-
 				return formatReturnValue( 'TEXT', textFragment );
 			} else {
 				position.offset--;

+ 27 - 12
packages/ckeditor5-engine/tests/treemodel/textfragment.js

@@ -11,22 +11,28 @@ import Element from '/ckeditor5/core/treemodel/element.js';
 import Text from '/ckeditor5/core/treemodel/text.js';
 import Attribute from '/ckeditor5/core/treemodel/attribute.js';
 import TextFragment from '/ckeditor5/core/treemodel/textfragment.js';
-import Position from '/ckeditor5/core/treemodel/position.js';
 import Document from '/ckeditor5/core/treemodel/document.js';
+import CharacterProxy from '/ckeditor5/core/treemodel/characterproxy.js';
 
 describe( 'TextFragment', () => {
-	let doc, text, element, textFragment, root;
+	let doc, attr, text, element, textFragment, root;
 
 	before( () => {
-		text = new Text( 'foobar', [ new Attribute( 'abc', 'xyz' ) ] );
-		element = new Element( 'div', [], [ text ] );
 		doc = new Document();
 		root = doc.createRoot( 'root' );
+		element = new Element( 'div' );
 		root.insertChildren( 0, element );
+		attr = new Attribute( 'foo', 'bar' );
 	} );
 
 	beforeEach( () => {
-		textFragment = new TextFragment( new Position( root, [ 0, 2 ] ), 'oba' );
+		text = new Text( 'foobar', [ attr ] );
+		element.insertChildren( 0, text );
+		textFragment = new TextFragment( element.getChild( 2 ), 3 );
+	} );
+
+	afterEach( () => {
+		element.removeChildren( 0, 1 );
 	} );
 
 	it( 'should have first property pointing to the first character node contained in TextFragment', () => {
@@ -43,17 +49,26 @@ describe( 'TextFragment', () => {
 		expect( char.character ).to.equal( 'a' );
 	} );
 
-	it( 'should have correct attributes property', () => {
-		expect( textFragment.attrs.size ).to.equal( 1 );
-		expect( textFragment.attrs.getValue( 'abc' ) ).to.equal( 'xyz' );
-	} );
-
 	it( 'should have text property', () => {
 		expect( textFragment ).to.have.property( 'text' ).that.equals( 'oba' );
 	} );
 
-	it( 'getRange should return range containing all characters from TextFragment', () => {
-		let range = textFragment.getRange();
+	describe( 'getCharAt', () => {
+		it( 'should return CharacterProxy element representing proper tree model character node', () => {
+			let char = textFragment.getCharAt( 1 );
+
+			expect( char ).to.be.instanceof( CharacterProxy );
+			expect( char.character ).to.equal( 'b' );
+			expect( char.getAttributeValue( 'foo' ) ).to.equal( 'bar' );
+			expect( char.parent ).to.equal( element );
+		} );
+
+		it( 'should return null for wrong index', () => {
+			expect( textFragment.getCharAt( -1 ) ).to.be.null;
+			expect( textFragment.getCharAt( 4 ) ).to.be.null;
+		} );
+	} );
+
 	describe( 'attributes interface', () => {
 		let attr2 = new Attribute( 'abc', 'xyz' );