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

Commit

Permalink
Merge pull request #1115 from ckeditor/t/1114
Browse files Browse the repository at this point in the history
Feature: Introduced `controller.DataController#hasContent`. Closes #1114.
  • Loading branch information
oskarwrobel authored Sep 1, 2017
2 parents e6c5bcf + 37be714 commit 712ccfc
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/controller/datacontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import ViewDocumentFragment from '../view/documentfragment';

import ModelRange from '../model/range';
import ModelPosition from '../model/position';
import ModelElement from '../model/element';

import insertContent from './insertcontent';
import deleteContent from './deletecontent';
Expand Down Expand Up @@ -297,6 +298,34 @@ export default class DataController {
getSelectedContent( selection ) {
return getSelectedContent( selection );
}

/**
* Checks whether given {@link module:engine/model/range~Range range} or {@link module:engine/model/element~Element element}
* has any content.
*
* Content is any text node or element which is registered in {@link module:engine/model/schema~Schema schema}.
*
* @param {module:engine/model/range~Range|module:engine/model/element~Element} rangeOrElement Range or element to check.
* @returns {Boolean}
*/
hasContent( rangeOrElement ) {
if ( rangeOrElement instanceof ModelElement ) {
rangeOrElement = ModelRange.createIn( rangeOrElement );
}

if ( rangeOrElement.isCollapsed ) {
return false;
}

for ( const item of rangeOrElement.getItems() ) {
// Remember, `TreeWalker` returns always `textProxy` nodes.
if ( item.is( 'textProxy' ) || this.model.schema.objects.has( item.name ) ) {
return true;
}
}

return false;
}
}

mix( DataController, ObservableMixin );
Expand Down
84 changes: 84 additions & 0 deletions tests/controller/datacontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import buildModelConverter from '../../src/conversion/buildmodelconverter';

import ModelDocumentFragment from '../../src/model/documentfragment';
import ModelText from '../../src/model/text';
import ModelRange from '../../src/model/range';
import ModelSelection from '../../src/model/selection';

import ViewDocumentFragment from '../../src/view/documentfragment';
Expand Down Expand Up @@ -439,4 +440,87 @@ describe( 'DataController', () => {
expect( stringify( content ) ).to.equal( 'ob' );
} );
} );

describe( 'hasContent', () => {
let root;

beforeEach( () => {
schema.registerItem( 'paragraph', '$block' );
schema.registerItem( 'div', '$block' );
schema.allow( { name: '$block', inside: 'div' } );
schema.registerItem( 'image' );
schema.allow( { name: 'image', inside: 'div' } );
schema.objects.add( 'image' );

setData(
modelDocument,

'<div>' +
'<paragraph></paragraph>' +
'</div>' +
'<paragraph>foo</paragraph>' +
'<div>' +
'<image></image>' +
'</div>'
);

root = modelDocument.getRoot();
} );

it( 'should return true if given element has text node', () => {
const pFoo = root.getChild( 1 );

expect( data.hasContent( pFoo ) ).to.be.true;
} );

it( 'should return true if given element has element that is an object', () => {
const divImg = root.getChild( 2 );

expect( data.hasContent( divImg ) ).to.be.true;
} );

it( 'should return false if given element has no elements', () => {
const pEmpty = root.getChild( 0 ).getChild( 0 );

expect( data.hasContent( pEmpty ) ).to.be.false;
} );

it( 'should return false if given element has only elements that are not objects', () => {
const divP = root.getChild( 0 );

expect( data.hasContent( divP ) ).to.be.false;
} );

it( 'should return true if there is a text node in given range', () => {
const range = ModelRange.createFromParentsAndOffsets( root, 1, root, 2 );

expect( data.hasContent( range ) ).to.be.true;
} );

it( 'should return true if there is a part of text node in given range', () => {
const pFoo = root.getChild( 1 );
const range = ModelRange.createFromParentsAndOffsets( pFoo, 1, pFoo, 2 );

expect( data.hasContent( range ) ).to.be.true;
} );

it( 'should return true if there is element that is an object in given range', () => {
const divImg = root.getChild( 2 );
const range = ModelRange.createFromParentsAndOffsets( divImg, 0, divImg, 1 );

expect( data.hasContent( range ) ).to.be.true;
} );

it( 'should return false if range is collapsed', () => {
const range = ModelRange.createFromParentsAndOffsets( root, 1, root, 1 );

expect( data.hasContent( range ) ).to.be.false;
} );

it( 'should return false if range has only elements that are not objects', () => {
const range = ModelRange.createFromParentsAndOffsets( root, 0, root, 1 );

expect( data.hasContent( range ) ).to.be.false;
} );
} );
} );

0 comments on commit 712ccfc

Please sign in to comment.