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

Commit

Permalink
Internal: Changed converters after engine/conversion refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
oskarwrobel committed Jan 25, 2018
1 parent e4ac704 commit c37f9fd
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 31 deletions.
51 changes: 22 additions & 29 deletions src/converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';
import ModelPosition from '@ckeditor/ckeditor5-engine/src/model/position';
import ModelRange from '@ckeditor/ckeditor5-engine/src/model/range';

import ViewContainerElement from '@ckeditor/ckeditor5-engine/src/view/containerelement';
import ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';
Expand Down Expand Up @@ -341,7 +342,7 @@ export function modelViewMergeAfter( evt, data, conversionApi ) {
*
* To set correct values of the `type` and `indent` attributes the converter:
* * checks `<li>`'s parent,
* * passes the `data.indent` value when `<li>`'s sub-items are converted.
* * stores and increases the `conversionApi.data.indent` value when `<li>`'s sub-items are converted.
*
* @see module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#event:element
* @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.
Expand All @@ -352,58 +353,44 @@ export function modelViewMergeAfter( evt, data, conversionApi ) {
export function viewModelConverter( evt, data, consumable, conversionApi ) {
if ( consumable.consume( data.input, { name: true } ) ) {
const writer = conversionApi.writer;
const conversionData = this.conversionApi.data;

// 1. Create `listItem` model element.
const listItem = writer.createElement( 'listItem' );

// 2. Handle `listItem` model element attributes.
data.indent = data.indent ? data.indent : 0;
writer.setAttribute( 'indent', data.indent, listItem );
conversionData.indent = conversionData.indent || 0;
writer.setAttribute( 'indent', conversionData.indent, listItem );

// Set 'bulleted' as default. If this item is pasted into a context,
const type = data.input.parent && data.input.parent.name == 'ol' ? 'numbered' : 'bulleted';
writer.setAttribute( 'type', type, listItem );

let alteredContext = false;

// See https://github.com/ckeditor/ckeditor5-list/issues/87
if ( data.context[ data.context.length - 1 ].name != 'listItem' ) {
// 3. Handle `<li>` children.
data.context.push( listItem );
alteredContext = true;
}

// `listItem`s created recursively should have bigger indent.
data.indent++;
conversionData.indent++;

// `listItem`s will be kept in flat structure.
const items = writer.createDocumentFragment();
writer.append( listItem, items );
writer.insert( listItem, data.position );

// Remember position after list item.
let nextPosition = ModelPosition.createAfter( listItem );

// Check all children of the converted `<li>`.
// At this point we assume there are no "whitespace" view text nodes in view list, between view list items.
// This should be handled by `<ul>` and `<ol>` converters.
for ( const child of data.input.getChildren() ) {
// Let's convert the child.
const converted = conversionApi.convertItem( child, consumable, data );

// If this is a view list element, we will convert it and concat the result (`listItem` model elements)
// with already gathered results (in `items` array). `converted` should be a `ModelDocumentFragment`.
// If this is a view list element, we will convert it after last `listItem` model element.
if ( child.name == 'ul' || child.name == 'ol' ) {
writer.append( converted, items );
nextPosition = conversionApi.convertItem( child, consumable, nextPosition ).end;
}
// If it was not a list it was a "regular" list item content. Just append it to `listItem`.
else {
writer.append( converted, listItem );
conversionApi.convertItem( child, consumable, ModelPosition.createAt( listItem, 'end' ) );
}
}

data.indent--;
if ( alteredContext ) {
data.context.pop();
}
conversionData.indent--;

data.output = items;
data.output = new ModelRange( data.position, nextPosition );
}
}

Expand Down Expand Up @@ -571,12 +558,18 @@ export function viewToModelPosition( evt, data ) {
/**
* Post-fixer that reacts to changes on document and fixes incorrect model states.
*
* Example:
* In an example below, there is a correct list structure.
* Then the middle element will be removed so the list structure will become incorrect:
*
* <listItem type="bulleted" indent=0>Item 1</listItem>
* <listItem type="bulleted" indent=1>Item 2</listItem> <--- this is removed.
* <listItem type="bulleted" indent=2>Item 3</listItem>
*
* List structure after the middle element removed:
*
* <listItem type="bulleted" indent=0>Item 1</listItem>
* <listItem type="bulleted" indent=2>Item 3</listItem>
*
* Should become:
*
* <listItem type="bulleted" indent=0>Item 1</listItem>
Expand Down
5 changes: 3 additions & 2 deletions tests/listengine.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ListCommand from '../src/listcommand';

import ModelDocumentFragment from '@ckeditor/ckeditor5-engine/src/model/documentfragment';
import ModelPosition from '@ckeditor/ckeditor5-engine/src/model/position';
import ModelRange from '@ckeditor/ckeditor5-engine/src/model/range';
import ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';
import ModelText from '@ckeditor/ckeditor5-engine/src/model/text';
import ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';
Expand Down Expand Up @@ -3374,9 +3375,9 @@ describe( 'ListEngine', () => {
expect( getModelData( model, { withoutSelection: true } ) ).to.equal( '<paragraph></paragraph>' );
} );

it( 'view converter should pass model document fragment in data.output', () => {
it( 'view converter should pass model range in data.output', () => {
editor.data.viewToModel.on( 'element:ul', ( evt, data ) => {
expect( data.output ).to.be.instanceof( ModelDocumentFragment );
expect( data.output ).to.be.instanceof( ModelRange );
}, { priority: 'lowest' } );

editor.setData( '<ul><li>Foo</li><li>Bar</li></ul>' );
Expand Down

0 comments on commit c37f9fd

Please sign in to comment.