Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit 1902d7a

Browse files
authored
Merge pull request #1064 from ckeditor/t/1063
Feature: Introduced the `Selection#isEntireContentSelected( element )` method. Closes #1063.
2 parents 0e88c11 + e8e8b18 commit 1902d7a

File tree

3 files changed

+78
-6
lines changed

3 files changed

+78
-6
lines changed

src/controller/deletecontent.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,8 @@ function replaceEntireContentWithParagraph( batch, selection ) {
197197
// * whether the paragraph is allowed in schema in the common ancestor.
198198
function shouldEntireContentBeReplacedWithParagraph( schema, selection ) {
199199
const limitElement = schema.getLimitElement( selection );
200-
const limitStartPosition = Position.createAt( limitElement );
201-
const limitEndPosition = Position.createAt( limitElement, 'end' );
202200

203-
if (
204-
!limitStartPosition.isTouching( selection.getFirstPosition() ) ||
205-
!limitEndPosition.isTouching( selection.getLastPosition() )
206-
) {
201+
if ( !selection.isEntireContentSelected( limitElement ) ) {
207202
return false;
208203
}
209204

src/model/selection.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,25 @@ export default class Selection {
624624
}
625625
}
626626

627+
/**
628+
* Checks whether the selection contains the entire content of the given element. This means that selection must start
629+
* at a position {@link module:engine/model/position~Position#isTouching touching} the element's start and ends at position
630+
* touching the element's end.
631+
*
632+
* By default, this method will check whether the entire content of the selection's current root is selected.
633+
* Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.
634+
*
635+
* @param {module:engine/model/element~Element} [element=this.anchor.root]
636+
* @returns {Boolean}
637+
*/
638+
isEntireContentSelected( element = this.anchor.root ) {
639+
const limitStartPosition = Position.createAt( element );
640+
const limitEndPosition = Position.createAt( element, 'end' );
641+
642+
return limitStartPosition.isTouching( this.getFirstPosition() ) &&
643+
limitEndPosition.isTouching( this.getLastPosition() );
644+
}
645+
627646
/**
628647
* Creates and returns an instance of `Selection` that is a clone of given selection, meaning that it has same
629648
* ranges and same direction as this selection.

tests/model/selection.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,4 +1237,62 @@ describe( 'Selection', () => {
12371237
} );
12381238
} );
12391239
} );
1240+
1241+
describe( 'isEntireContentSelected()', () => {
1242+
beforeEach( () => {
1243+
doc.schema.registerItem( 'p', '$block' );
1244+
doc.schema.allow( { name: 'p', inside: '$root' } );
1245+
} );
1246+
1247+
it( 'returns true if the entire content in $root is selected', () => {
1248+
setData( doc, '<p>[Foo</p><p>Bom</p><p>Bar]</p>' );
1249+
1250+
expect( doc.selection.isEntireContentSelected() ).to.equal( true );
1251+
} );
1252+
1253+
it( 'returns false when only a fragment of the content in $root is selected', () => {
1254+
setData( doc, '<p>Fo[o</p><p>Bom</p><p>Bar]</p>' );
1255+
1256+
expect( doc.selection.isEntireContentSelected() ).to.equal( false );
1257+
} );
1258+
1259+
it( 'returns true if the entire content in specified element is selected', () => {
1260+
setData( doc, '<p>Foo</p><p>[Bom]</p><p>Bar</p>' );
1261+
1262+
const root = doc.getRoot();
1263+
const secondParagraph = root.getNodeByPath( [ 1 ] );
1264+
1265+
expect( doc.selection.isEntireContentSelected( secondParagraph ) ).to.equal( true );
1266+
} );
1267+
1268+
it( 'returns false if the entire content in specified element is not selected', () => {
1269+
setData( doc, '<p>Foo</p><p>[Bom</p><p>B]ar</p>' );
1270+
1271+
const root = doc.getRoot();
1272+
const secondParagraph = root.getNodeByPath( [ 1 ] );
1273+
1274+
expect( doc.selection.isEntireContentSelected( secondParagraph ) ).to.equal( false );
1275+
} );
1276+
1277+
it( 'returns false when the entire content except an empty element is selected', () => {
1278+
doc.schema.registerItem( 'img', '$inline' );
1279+
doc.schema.allow( { name: 'img', inside: 'p' } );
1280+
1281+
setData( doc, '<p><img></img>[Foo]</p>' );
1282+
1283+
expect( doc.selection.isEntireContentSelected() ).to.equal( false );
1284+
} );
1285+
1286+
it( 'returns true if the content is empty', () => {
1287+
setData( doc, '[]' );
1288+
1289+
expect( doc.selection.isEntireContentSelected() ).to.equal( true );
1290+
} );
1291+
1292+
it( 'returns false if empty selection is at the end of non-empty content', () => {
1293+
setData( doc, '<p>Foo bar bom.</p>[]' );
1294+
1295+
expect( doc.selection.isEntireContentSelected() ).to.equal( false );
1296+
} );
1297+
} );
12401298
} );

0 commit comments

Comments
 (0)