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

Commit

Permalink
Merge 98f6831 into 968b193
Browse files Browse the repository at this point in the history
  • Loading branch information
oleq committed Mar 9, 2020
2 parents 968b193 + 98f6831 commit 1662787
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 6 deletions.
21 changes: 21 additions & 0 deletions src/model/range.js
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,27 @@ export default class Range {
return this.start.getCommonAncestor( this.end );
}

/**
* Returns an element contained by the range. The element will be returned when it is the **only** node
* within the range and **fully–contained** at the same time.
*
* @returns {module:engine/model/element~Element|null}
*/
getContainedElement() {
if ( this.isCollapsed ) {
return null;
}

const nodeAfterStart = this.start.nodeAfter;
const nodeBeforeEnd = this.end.nodeBefore;

if ( nodeAfterStart && nodeAfterStart.is( 'element' ) && nodeAfterStart === nodeBeforeEnd ) {
return nodeAfterStart;
}

return null;
}

/**
* Converts `Range` to plain object and returns it.
*
Expand Down
7 changes: 1 addition & 6 deletions src/model/selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
*/

import Position from './position';
import Element from './element';
import Node from './node';
import Range from './range';
import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
Expand Down Expand Up @@ -615,11 +614,7 @@ export default class Selection {
return null;
}

const range = this.getFirstRange();
const nodeAfterStart = range.start.nodeAfter;
const nodeBeforeEnd = range.end.nodeBefore;

return ( nodeAfterStart instanceof Element && nodeAfterStart == nodeBeforeEnd ) ? nodeAfterStart : null;
return this.getFirstRange().getContainedElement();
}

/**
Expand Down
41 changes: 41 additions & 0 deletions tests/model/range.js
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,47 @@ describe( 'Range', () => {
} );
} );

describe( 'getContainerElement()', () => {
beforeEach( () => {
prepareRichRoot( root );
} );

it( 'should return an element when it is fully contained by the range', () => {
// <div><h>first</h><p>lorem ipsum</p></div>[<p>foo</p>]<p>bar</p><div><h>second</h><p>lorem</p></div>
const range = new Range( new Position( root, [ 1 ] ), new Position( root, [ 2 ] ) );

expect( range.getContainedElement() ).to.equal( root.getNodeByPath( [ 1 ] ) );
} );

it( 'should return "null" if the range is collapsed', () => {
// <div><h>first</h><p>lorem ipsum</p></div>[]<p>foo</p><p>bar</p><div><h>second</h><p>lorem</p></div>
const range = new Range( new Position( root, [ 1 ] ) );

expect( range.getContainedElement() ).to.be.null;
} );

it( 'should return "null" if it contains 2+ elements', () => {
// <div><h>first</h><p>lorem ipsum</p></div>[<p>foo</p><p>bar</p>]<div><h>second</h><p>lorem</p></div>
const range = new Range( new Position( root, [ 1 ] ), new Position( root, [ 3 ] ) );

expect( range.getContainedElement() ).to.be.null;
} );

it( 'should return "null" if it contains an element and some other nodes', () => {
// <div><h>first</h><p>lorem ipsum</p></div>[<p>foo</p><p>ba]r</p><div><h>second</h><p>lorem</p></div>
const range = new Range( new Position( root, [ 1 ] ), new Position( root, [ 2, 2 ] ) );

expect( range.getContainedElement() ).to.be.null;
} );

it( 'should return "null" if it fully contains a node but the node is not an element', () => {
// <div><h>first</h><p>lorem ipsum</p></div><p>foo</p><p>[bar]</p><div><h>second</h><p>lorem</p></div>
const range = new Range( new Position( root, [ 2, 0 ] ), new Position( root, [ 2, 3 ] ) );

expect( range.getContainedElement() ).to.be.null;
} );
} );

function mapNodesToNames( nodes ) {
return nodes.map( node => {
return ( node instanceof Element ) ? 'E:' + node.name : 'T:' + node.data;
Expand Down

0 comments on commit 1662787

Please sign in to comment.