Ver código fonte

Improved docs and added one more test to match the docs.

Piotrek Koszuliński 7 anos atrás
pai
commit
524506069e

+ 18 - 8
packages/ckeditor5-engine/src/model/utils/selection-post-fixer.js

@@ -13,9 +13,21 @@ import Position from '../position';
 /**
 /**
  * Injects selection post-fixer to the model.
  * Injects selection post-fixer to the model.
  *
  *
- * The selection post-fixer checks if nodes with `isLimit` property in schema are properly selected.
+ * The role of the selection post-fixer is to ensure that the selection is in a correct place
+ * after a {@link module:engine/model/model~Model#change `change()`} block was executed.
  *
  *
- * See as an example selection that starts in P1 element and ends inside text of TD element
+ * The correct position means that:
+ *
+ * * all collapsed selection ranges are in a place where the {@link module:engine/model/schema~Schema}
+ * allows a `$text`,
+ * * none of selection's non-collapsed ranges crosses a {@link module:engine/model/schema~Schema#isLimit limit element}
+ * boundary (a range must be rooted within one limit element).
+ *
+ * If the position is not correct, the post-fixer will automatically correct it.
+ *
+ * ## Fixing a non-collapsed selection
+ *
+ * See as an example a selection that starts in a P1 element and ends inside a text of a TD element
  * (`[` and `]` are range boundaries and `(l)` denotes element defines as `isLimit=true`):
  * (`[` and `]` are range boundaries and `(l)` denotes element defines as `isLimit=true`):
  *
  *
  *		root
  *		root
@@ -36,16 +48,14 @@ import Position from '../position';
  *		                                                 TD      TD
  *		                                                 TD      TD
  *		                                               a a a    b b b
  *		                                               a a a    b b b
  *
  *
- * In above example, the TABLE, TR and TD are defined as `isLimit=true` in the schema. The range that is not contained withing
- * single limit element must be expanded to select outer most parent limit element. The range end is inside text node of TD element.
+ * In the above example, the TABLE, TR and TD are defined as `isLimit=true` in the schema. The range which is not contained within
+ * a single limit element must be expanded to select the outer most limit element. The range end is inside text node of TD element.
  * As TD element is a child of TR element and TABLE elements which both are defined as `isLimit=true` in schema the range must be expanded
  * As TD element is a child of TR element and TABLE elements which both are defined as `isLimit=true` in schema the range must be expanded
  * to select whole TABLE element.
  * to select whole TABLE element.
  *
  *
  * **Note** If selection contains multiple ranges the method returns minimal set of ranges that are not intersecting after expanding them
  * **Note** If selection contains multiple ranges the method returns minimal set of ranges that are not intersecting after expanding them
  * to select `isLimit=true` elements.
  * to select `isLimit=true` elements.
  *
  *
- * See {@link module:engine/model/schema~Schema#isLimit}.
- *
  * @param {module:engine/model/model~Model} model
  * @param {module:engine/model/model~Model} model
  */
  */
 export function injectSelectionPostFixer( model ) {
 export function injectSelectionPostFixer( model ) {
@@ -81,9 +91,9 @@ function selectionPostFixer( writer, model ) {
 	if ( wasFixed ) {
 	if ( wasFixed ) {
 		// The above algorithm might create ranges that intersects each other when selection contains more then one range.
 		// The above algorithm might create ranges that intersects each other when selection contains more then one range.
 		// This is case happens mostly on Firefox which creates multiple ranges for selected table.
 		// This is case happens mostly on Firefox which creates multiple ranges for selected table.
-		const safeRange = combineRangesOnLimitNodes( ranges );
+		const safeRanges = combineRangesOnLimitNodes( ranges );
 
 
-		writer.setSelection( safeRange, { backward: selection.isBackward } );
+		writer.setSelection( safeRanges, { backward: selection.isBackward } );
 	}
 	}
 }
 }
 
 

+ 20 - 0
packages/ckeditor5-engine/tests/model/utils/selection-post-fixer.js

@@ -319,6 +319,26 @@ describe( 'Selection post-fixer', () => {
 					'<paragraph>bar</paragraph>'
 					'<paragraph>bar</paragraph>'
 				);
 				);
 			} );
 			} );
+
+			it( 'should fix multiple ranges #1', () => {
+				// []<paragraph></paragraph>[]<table>...
+				model.change( writer => {
+					writer.setSelection(
+						[
+							ModelRange.createFromParentsAndOffsets( modelRoot, 0, modelRoot, 0 ),
+							ModelRange.createFromParentsAndOffsets( modelRoot, 1, modelRoot, 1 )
+						]
+					);
+				} );
+
+				expect( getModelData( model ) ).to.equal(
+					'<paragraph>[]foo[]</paragraph>' +
+					'<table>' +
+						'<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
+					'</table>' +
+					'<paragraph>bar</paragraph>'
+				);
+			} );
 		} );
 		} );
 	} );
 	} );
 } );
 } );