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

Implemented DC.toModel #718

Merged
merged 2 commits into from
Dec 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 33 additions & 13 deletions src/controller/datacontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,34 +138,38 @@ export default class DataController {
}

/**
* Returns the content of the given {@link module:engine/model/element~Element model's element} converted by the
* Returns the content of the given {@link module:engine/model/element~Element model's element} or
* {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the
* {@link #modelToView model to view converters} and formatted by the
* {@link #processor data processor}.
*
* @param {module:engine/model/element~Element} modelElement Element which content will be stringified.
* @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} modelElementOrFragment
* Element which content will be stringified.
* @returns {String} Output data.
*/
stringify( modelElement ) {
stringify( modelElementOrFragment ) {
// model -> view
const viewDocumentFragment = this.toView( modelElement );
const viewDocumentFragment = this.toView( modelElementOrFragment );

// view -> data
return this.processor.toData( viewDocumentFragment );
}

/**
* Returns the content of the given {@link module:engine/model/element~Element model's element} converted by the
* {@link #modelToView model to view converters} to the
* {@link module:engine/view/documentfragment~DocumentFragment view DocumentFragment}.
* Returns the content of the given {@link module:engine/model/element~Element model element} or
* {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the
* {@link #modelToView model to view converters} to a
* {@link module:engine/view/documentfragment~DocumentFragment view document fragment}.
*
* @param {module:engine/model/element~Element} modelElement Element which content will be stringified.
* @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} modelElementOrFragment
* Element or document fragment which content will be converted.
* @returns {module:engine/view/documentfragment~DocumentFragment} Output view DocumentFragment.
*/
toView( modelElement ) {
const modelRange = ModelRange.createIn( modelElement );
toView( modelElementOrFragment ) {
const modelRange = ModelRange.createIn( modelElementOrFragment );

const viewDocumentFragment = new ViewDocumentFragment();
this.mapper.bindElements( modelElement, viewDocumentFragment );
this.mapper.bindElements( modelElementOrFragment, viewDocumentFragment );

this.modelToView.convertInsertion( modelRange );

Expand Down Expand Up @@ -207,7 +211,7 @@ export default class DataController {
*
* @see #set
* @param {String} data Data to parse.
* @param {String} [context='$root'] Base context in which view will be converted to the model. See:
* @param {String} [context='$root'] Base context in which the view will be converted to the model. See:
* {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#convert}.
* @returns {module:engine/model/documentfragment~DocumentFragment} Parsed data.
*/
Expand All @@ -216,7 +220,23 @@ export default class DataController {
const viewDocumentFragment = this.processor.toView( data );

// view -> model
return this.viewToModel.convert( viewDocumentFragment, { context: [ context ] } );
return this.toModel( viewDocumentFragment, context );
}

/**
* Returns the content of the given {@link module:engine/view/element~Element view element} or
* {@link module:engine/view/documentfragment~DocumentFragment view document fragment} converted by the
* {@link #viewToModel view to model converters} to a
* {@link module:engine/model/documentfragment~DocumentFragment model document fragment}.
*
* @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} viewElementOrFragment
* Element or document fragment which content will be converted.
* @param {String} [context='$root'] Base context in which the view will be converted to the model. See:
* {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#convert}.
* @returns {module:engine/model/documentfragment~DocumentFragment} Output document fragment.
*/
toModel( viewElementOrFragment, context = '$root' ) {
return this.viewToModel.convert( viewElementOrFragment, { context: [ context ] } );
}

/**
Expand Down
87 changes: 81 additions & 6 deletions tests/controller/datacontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ import buildViewConverter from 'ckeditor5/engine/conversion/buildviewconverter.
import buildModelConverter from 'ckeditor5/engine/conversion/buildmodelconverter.js';

import ModelDocumentFragment from 'ckeditor5/engine/model/documentfragment.js';
import ModelElement from 'ckeditor5/engine/model/element.js';
import ModelText from 'ckeditor5/engine/model/text.js';
import ModelSelection from 'ckeditor5/engine/model/selection.js';

import { getData, setData, stringify, parse } from 'ckeditor5/engine/dev-utils/model.js';
import ViewDocumentFragment from 'ckeditor5/engine/view/documentfragment.js';

import { getData, setData, stringify, parse as parseModel } from 'ckeditor5/engine/dev-utils/model.js';
import { parse as parseView } from 'ckeditor5/engine/dev-utils/view.js';

import count from 'ckeditor5/utils/count.js';

Expand Down Expand Up @@ -170,6 +174,46 @@ describe( 'DataController', () => {
} );
} );

describe( 'toModel', () => {
beforeEach( () => {
schema.registerItem( 'paragraph', '$block' );

buildViewConverter().for( data.viewToModel ).fromElement( 'p' ).toElement( 'paragraph' );
} );

it( 'should convert content of an element', () => {
const viewElement = parseView( '<p>foo</p>' );
const modelElement = data.toModel( viewElement );

expect( modelElement ).to.be.instanceOf( ModelElement );
expect( stringify( modelElement ) ).to.equal( '<paragraph>foo</paragraph>' );
} );

it( 'should convert content of an element', () => {
const viewFragment = parseView( '<p>foo</p><p>bar</p>' );
const modelFragment = data.toModel( viewFragment );

expect( modelFragment ).to.be.instanceOf( ModelDocumentFragment );
expect( stringify( modelFragment ) ).to.equal( '<paragraph>foo</paragraph><paragraph>bar</paragraph>' );
} );

it( 'should accept parsing context', () => {
modelDocument.createRoot( 'inlineRoot', 'inlineRoot' );

schema.registerItem( 'inlineRoot' );
schema.allow( { name: '$text', inside: 'inlineRoot' } );

const viewFragment = new ViewDocumentFragment( [ parseView( 'foo' ) ] );
const modelFragmentInRoot = data.toModel( viewFragment );

expect( stringify( modelFragmentInRoot ) ).to.equal( '' );

const modelFragmentInInlineRoot = data.toModel( viewFragment, 'inlineRoot' );

expect( stringify( modelFragmentInInlineRoot ) ).to.equal( 'foo' );
} );
} );

describe( 'set', () => {
it( 'should set data to root', () => {
schema.allow( { name: '$text', inside: '$root' } );
Expand Down Expand Up @@ -293,26 +337,57 @@ describe( 'DataController', () => {
} );

describe( 'stringify', () => {
it( 'should get paragraph with text', () => {
beforeEach( () => {
modelDocument.schema.registerItem( 'paragraph', '$block' );
modelDocument.schema.registerItem( 'div', '$block' );
const modelElement = parse( '<div><paragraph>foo</paragraph></div>', modelDocument.schema );

buildModelConverter().for( data.modelToView ).fromElement( 'paragraph' ).toElement( 'p' );
} );

it( 'should stringify a content of an element', () => {
const modelElement = parseModel( '<div><paragraph>foo</paragraph></div>', modelDocument.schema );

expect( data.stringify( modelElement ) ).to.equal( '<p>foo</p>' );
} );

it( 'should stringify a content of a document fragment', () => {
const modelDocumentFragment = parseModel( '<paragraph>foo</paragraph><paragraph>bar</paragraph>', modelDocument.schema );

expect( data.stringify( modelDocumentFragment ) ).to.equal( '<p>foo</p><p>bar</p>' );
} );
} );

describe( 'toView', () => {
it( 'should get view element P with text', () => {
beforeEach( () => {
modelDocument.schema.registerItem( 'paragraph', '$block' );
modelDocument.schema.registerItem( 'div', '$block' );
const modelElement = parse( '<div><paragraph>foo</paragraph></div>', modelDocument.schema );

buildModelConverter().for( data.modelToView ).fromElement( 'paragraph' ).toElement( 'p' );
} );

it( 'should convert a content of an element', () => {
const modelElement = parseModel( '<div><paragraph>foo</paragraph></div>', modelDocument.schema );

const viewDocumentFragment = data.toView( modelElement );

expect( viewDocumentFragment ).to.be.instanceOf( ViewDocumentFragment );

const viewElement = viewDocumentFragment.getChild( 0 );

expect( viewElement.name ).to.equal( 'p' );
expect( viewElement.childCount ).to.equal( 1 );
expect( viewElement.getChild( 0 ).data ).to.equal( 'foo' );
} );

it( 'should convert a document fragment', () => {
const modelDocumentFragment = parseModel( '<paragraph>foo</paragraph><paragraph>bar</paragraph>', modelDocument.schema );

const viewDocumentFragment = data.toView( modelDocumentFragment );

expect( viewDocumentFragment ).to.be.instanceOf( ViewDocumentFragment );
expect( viewDocumentFragment ).to.have.property( 'childCount', 2 );

const viewElement = data.toView( modelElement ).getChild( 0 );
const viewElement = viewDocumentFragment.getChild( 0 );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more complete if you check both children.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. But this is not a test for conversion itself, but for methods utilising conversion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean – there are a lot more things which could be broken below, but it'd be unwise to try to test them so late. I'm checking the number of children and the first child to verify that enough elements were converted and that they make some sense.


expect( viewElement.name ).to.equal( 'p' );
expect( viewElement.childCount ).to.equal( 1 );
Expand Down