Explorar el Código

Merge pull request #8411 from ckeditor/cf/3602

Fix (undo): Fixed restoring selection on undo for some scenarios when some selection ranges are in the graveyard after restoring them.
Szymon Cofalik hace 5 años
padre
commit
772f45dd1c

+ 10 - 11
packages/ckeditor5-undo/src/basecommand.js

@@ -100,7 +100,14 @@ export default class BaseCommand extends Command {
 
 		for ( const rangeGroup of transformedRangeGroups ) {
 			// While transforming there could appear ranges that are contained by other ranges, we shall ignore them.
-			const transformed = rangeGroup.filter( range => !isRangeContainedByAnyOtherRange( range, allRanges ) );
+			const transformed = rangeGroup
+				.filter( range => range.root != document.graveyard )
+				.filter( range => !isRangeContainedByAnyOtherRange( range, allRanges ) );
+
+			// All the transformed ranges ended up in graveyard.
+			if ( !transformed.length ) {
+				continue;
+			}
 
 			// After the range got transformed, we have an array of ranges. Some of those
 			// ranges may be "touching" -- they can be next to each other and could be merged.
@@ -108,16 +115,8 @@ export default class BaseCommand extends Command {
 
 			// For each `range` from `ranges`, we take only one transformed range.
 			// This is because we want to prevent situation where single-range selection
-			// got transformed to multi-range selection. We will take the first range that
-			// is not in the graveyard.
-			const newRange = transformed.find(
-				range => range.root != document.graveyard
-			);
-
-			// `transformedRange` might be `undefined` if transformed range ended up in graveyard.
-			if ( newRange ) {
-				selectionRanges.push( newRange );
-			}
+			// got transformed to multi-range selection.
+			selectionRanges.push( transformed[ 0 ] );
 		}
 
 		// @if CK_DEBUG_ENGINE // console.log( `Restored selection by undo: ${ selectionRanges.join( ', ' ) }` );

+ 81 - 0
packages/ckeditor5-undo/tests/undoediting-integration.js

@@ -1100,6 +1100,87 @@ describe( 'UndoEditing integration', () => {
 				'</table>'
 			);
 		} );
+
+		it( 'undo table cells content wrapping', () => {
+			model.schema.register( 'tableCellContent', {
+				allowIn: 'tableCell',
+				allowContentOf: 'tableCell',
+				isLimit: true
+			} );
+
+			editor.conversion.elementToElement( { model: 'tableCellContent', view: 'td-content' } );
+
+			input(
+				'<table>' +
+					'<tableRow>' +
+						'<tableCell><paragraph>00</paragraph></tableCell>' +
+						'[<tableCell><paragraph>01</paragraph></tableCell>]' +
+						'[<tableCell><paragraph>02</paragraph></tableCell>]' +
+						'<tableCell><paragraph>03</paragraph></tableCell>' +
+					'</tableRow>' +
+					'<tableRow>' +
+						'<tableCell><paragraph>10</paragraph></tableCell>' +
+						'[<tableCell><paragraph>11</paragraph></tableCell>]' +
+						'[<tableCell><paragraph>12</paragraph></tableCell>]' +
+						'<tableCell><paragraph>13</paragraph></tableCell>' +
+					'</tableRow>' +
+				'</table>'
+			);
+
+			model.change( writer => {
+				const targetCell = root.getNodeByPath( [ 0, 0, 1 ] );
+				const insertionWrapper = writer.createElement( 'tableCellContent' );
+				const deletionWrapper = writer.createElement( 'tableCellContent' );
+				const paragraph = writer.createElement( 'paragraph' );
+
+				writer.wrap( writer.createRangeIn( targetCell ), deletionWrapper );
+				writer.insert( insertionWrapper, targetCell, 0 );
+
+				writer.insert( writer.createText( 'foobar' ), paragraph, 0 );
+				writer.insert( paragraph, insertionWrapper, 'end' );
+
+				writer.setSelection( writer.createRangeOn( targetCell ) );
+			} );
+
+			output(
+				'<table>' +
+					'<tableRow>' +
+						'<tableCell><paragraph>00</paragraph></tableCell>' +
+						'[<tableCell>' +
+							'<tableCellContent><paragraph>foobar</paragraph></tableCellContent>' +
+							'<tableCellContent><paragraph>01</paragraph></tableCellContent>' +
+						'</tableCell>]' +
+						'<tableCell><paragraph>02</paragraph></tableCell>' +
+						'<tableCell><paragraph>03</paragraph></tableCell>' +
+					'</tableRow>' +
+					'<tableRow>' +
+						'<tableCell><paragraph>10</paragraph></tableCell>' +
+						'<tableCell><paragraph>11</paragraph></tableCell>' +
+						'<tableCell><paragraph>12</paragraph></tableCell>' +
+						'<tableCell><paragraph>13</paragraph></tableCell>' +
+					'</tableRow>' +
+				'</table>'
+			);
+
+			editor.execute( 'undo' );
+
+			output(
+				'<table>' +
+					'<tableRow>' +
+						'<tableCell><paragraph>00</paragraph></tableCell>' +
+						'[<tableCell><paragraph>01</paragraph></tableCell>]' +
+						'[<tableCell><paragraph>02</paragraph></tableCell>]' +
+						'<tableCell><paragraph>03</paragraph></tableCell>' +
+					'</tableRow>' +
+					'<tableRow>' +
+						'<tableCell><paragraph>10</paragraph></tableCell>' +
+						'[<tableCell><paragraph>11</paragraph></tableCell>]' +
+						'[<tableCell><paragraph>12</paragraph></tableCell>]' +
+						'<tableCell><paragraph>13</paragraph></tableCell>' +
+					'</tableRow>' +
+				'</table>'
+			);
+		} );
 	} );
 
 	it( 'postfixers should not add another undo step when fixing undo changes', () => {