瀏覽代碼

Add getTopMostBlocks() method to Selection.

Maciej Gołaszewski 7 年之前
父節點
當前提交
0a2e32d795

+ 4 - 0
packages/ckeditor5-engine/src/model/documentselection.js

@@ -253,6 +253,10 @@ export default class DocumentSelection {
 		return this._selection.getSelectedBlocks();
 	}
 
+	getTopMostBlocks( schema ) {
+		return this._selection.getTopMostBlocks( schema );
+	}
+
 	/**
 	 * Returns the selected element. {@link module:engine/model/element~Element Element} is considered as selected if there is only
 	 * one range in the selection, and that range contains exactly one element.

+ 43 - 0
packages/ckeditor5-engine/src/model/selection.js

@@ -673,6 +673,31 @@ export default class Selection {
 	}
 
 	/**
+	 * Returns blocks that aren't nested in other selected blocks.
+	 *
+	 * In this case the method will return blocks A, B and C:
+	 *
+	 *		[<blockA></blockA>
+	 *		<blockB>
+	 *			<blockC></blockC>
+	 *			<blockD></blockD>
+	 *		</blockB>
+	 *		<blockE></blockE>]
+	 *
+	 * @returns {Iterator.<module:engine/model/element~Element>}
+	 */
+	* getTopMostBlocks() {
+		for ( const block of this.getSelectedBlocks() ) {
+			const parentBlock = findAncestorBlock( block );
+
+			// Filter out blocks that are nested in other selected blocks (like paragraphs in tables).
+			if ( !parentBlock || !this.containsEntireContent( parentBlock ) ) {
+				yield block;
+			}
+		}
+	}
+
+	/**
 	 * Checks whether the selection contains the entire content of the given element. This means that selection must start
 	 * at a position {@link module:engine/model/position~Position#isTouching touching} the element's start and ends at position
 	 * touching the element's end.
@@ -802,3 +827,21 @@ function getParentBlock( position, visited ) {
 
 	return block;
 }
+
+// Returns first ancestor block of a node.
+//
+// @param {module:engine/model/node~Node} node
+// @returns {module:engine/model/node~Node|undefined}
+function findAncestorBlock( node ) {
+	const schema = node.document.model.schema;
+
+	let parent = node.parent;
+
+	while ( parent ) {
+		if ( schema.isBlock( parent ) ) {
+			return parent;
+		}
+
+		parent = parent.parent;
+	}
+}