8
0
Просмотр исходного кода

Merge branch 'master' into t/1436

Piotrek Koszuliński 7 лет назад
Родитель
Сommit
85193a4777

+ 2 - 1
packages/ckeditor5-engine/src/model/utils/modifyselection.js

@@ -172,7 +172,8 @@ function getCorrectWordBreakPosition( walker, isForward ) {
 			// should expand to : 'foofoo [bar<$text bold="true">bar</$text>] bazbaz'.
 			// should expand to : 'foofoo [bar<$text bold="true">bar</$text>] bazbaz'.
 			const nextNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;
 			const nextNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;
 
 
-			if ( nextNode ) {
+			// Scan only text nodes. Ignore inline elements (like `<softBreak>`).
+			if ( nextNode && nextNode.is( 'text' ) ) {
 				// Check boundary char of an adjacent text node.
 				// Check boundary char of an adjacent text node.
 				const boundaryChar = nextNode.data.charAt( isForward ? 0 : nextNode.data.length - 1 );
 				const boundaryChar = nextNode.data.charAt( isForward ? 0 : nextNode.data.length - 1 );
 
 

+ 1 - 1
packages/ckeditor5-engine/src/view/renderer.js

@@ -256,7 +256,7 @@ export default class Renderer {
 
 
 		const actualDomChildren = this.domConverter.mapViewToDom( viewElement ).childNodes;
 		const actualDomChildren = this.domConverter.mapViewToDom( viewElement ).childNodes;
 		const expectedDomChildren = Array.from(
 		const expectedDomChildren = Array.from(
-			this.domConverter.viewChildrenToDom( viewElement, domElement.ownerDocument )
+			this.domConverter.viewChildrenToDom( viewElement, domElement.ownerDocument, { withChildren: false } )
 		);
 		);
 		const diff = this._diffNodeLists( actualDomChildren, expectedDomChildren );
 		const diff = this._diffNodeLists( actualDomChildren, expectedDomChildren );
 		const actions = this._findReplaceActions( diff, actualDomChildren, expectedDomChildren );
 		const actions = this._findReplaceActions( diff, actualDomChildren, expectedDomChildren );

+ 43 - 0
packages/ckeditor5-engine/tests/model/utils/modifyselection.js

@@ -18,6 +18,7 @@ describe( 'DataController utils', () => {
 		model.schema.register( 'p', { inheritAllFrom: '$block' } );
 		model.schema.register( 'p', { inheritAllFrom: '$block' } );
 		model.schema.register( 'x', { inheritAllFrom: '$block' } );
 		model.schema.register( 'x', { inheritAllFrom: '$block' } );
 		model.schema.extend( 'x', { allowIn: 'p' } );
 		model.schema.extend( 'x', { allowIn: 'p' } );
+		model.schema.register( 'br', { allowWhere: '$text' } );
 
 
 		doc.createRoot();
 		doc.createRoot();
 	} );
 	} );
@@ -554,6 +555,48 @@ describe( 'DataController utils', () => {
 					expect( doc.selection.isBackward ).to.true;
 					expect( doc.selection.isBackward ).to.true;
 				} );
 				} );
 
 
+				it( 'expands backward selection to the word begin in the paragraph with soft break', () => {
+					setData( model, '<p>Foo<br></br>Bar[]</p>' );
+
+					modifySelection( model, doc.selection, { unit: 'word', direction: 'backward' } );
+
+					expect( stringify( doc.getRoot(), doc.selection ) ).to.equal( '<p>Foo<br></br>[Bar]</p>' );
+				} );
+
+				it( 'expands backward selection to the whole paragraph in the paragraph with soft break', () => {
+					setData( model, '<p>Foo<br></br>Bar[]</p>' );
+
+					modifySelection( model, doc.selection, { unit: 'word', direction: 'backward' } );
+					modifySelection( model, doc.selection, { unit: 'word', direction: 'backward' } );
+
+					expect( stringify( doc.getRoot(), doc.selection ) ).to.equal( '<p>Foo[<br></br>Bar]</p>' );
+
+					modifySelection( model, doc.selection, { unit: 'word', direction: 'backward' } );
+
+					expect( stringify( doc.getRoot(), doc.selection ) ).to.equal( '<p>[Foo<br></br>Bar]</p>' );
+				} );
+
+				it( 'expands forward selection to the word end in the paragraph with soft break', () => {
+					setData( model, '<p>[]Foo<br></br>Bar</p>' );
+
+					modifySelection( model, doc.selection, { unit: 'word', direction: 'forward' } );
+
+					expect( stringify( doc.getRoot(), doc.selection ) ).to.equal( '<p>[Foo]<br></br>Bar</p>' );
+				} );
+
+				it( 'expands forward selection to the whole paragraph in the paragraph with soft break', () => {
+					setData( model, '<p>[]Foo<br></br>Bar</p>' );
+
+					modifySelection( model, doc.selection, { unit: 'word', direction: 'forward' } );
+					modifySelection( model, doc.selection, { unit: 'word', direction: 'forward' } );
+
+					expect( stringify( doc.getRoot(), doc.selection ) ).to.equal( '<p>[Foo<br></br>]Bar</p>' );
+
+					modifySelection( model, doc.selection, { unit: 'word', direction: 'forward' } );
+
+					expect( stringify( doc.getRoot(), doc.selection ) ).to.equal( '<p>[Foo<br></br>Bar]</p>' );
+				} );
+
 				function testStopCharacter( stopCharacter ) {
 				function testStopCharacter( stopCharacter ) {
 					describe( `stop character: "${ stopCharacter }"`, () => {
 					describe( `stop character: "${ stopCharacter }"`, () => {
 						test(
 						test(

+ 30 - 0
packages/ckeditor5-engine/tests/view/renderer.js

@@ -1683,6 +1683,36 @@ describe( 'Renderer', () => {
 			);
 			);
 		} );
 		} );
 
 
+		// #1451
+		it( 'should correctly render changed children even if direct parent is not marked to sync', () => {
+			const inputView =
+				'<container:ul>' +
+					'<container:li>Foo</container:li>' +
+					'<container:li><attribute:b>Bar</attribute:b></container:li>' +
+				'</container:ul>';
+
+			const view = parse( inputView );
+
+			viewRoot._appendChild( view );
+
+			renderer.markToSync( 'children', viewRoot );
+			renderer.render();
+
+			expect( domRoot.innerHTML ).to.equal( '<ul><li>Foo</li><li><b>Bar</b></li></ul>' );
+
+			const viewLi = view.getChild( 0 );
+			const viewLiIndented = view._removeChildren( 1, 1 ); // Array with one element.
+			viewLiIndented[ 0 ]._appendChild( parse( '<attribute:i>Baz</attribute:i>' ) );
+			const viewUl = new ViewContainerElement( 'ul', null, viewLiIndented );
+			viewLi._appendChild( viewUl );
+
+			renderer.markToSync( 'children', view );
+			renderer.markToSync( 'children', viewLi );
+			renderer.render();
+
+			expect( domRoot.innerHTML ).to.equal( '<ul><li>Foo<ul><li><b>Bar</b><i>Baz</i></li></ul></li></ul>' );
+		} );
+
 		describe( 'fake selection', () => {
 		describe( 'fake selection', () => {
 			beforeEach( () => {
 			beforeEach( () => {
 				const { view: viewP, selection: newSelection } = parse(
 				const { view: viewP, selection: newSelection } = parse(