Skip to content

Commit

Permalink
Naive implementation of any child reconversion for table cell case.
Browse files Browse the repository at this point in the history
  • Loading branch information
jodator committed Oct 15, 2020
1 parent f6032d5 commit d3efbf0
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 47 deletions.
16 changes: 16 additions & 0 deletions packages/ckeditor5-engine/src/conversion/downcastdispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ export default class DowncastDispatcher {
);
// Do not move views that are already in converted element - those might be created by the main element converter
}
// convert attributes????
this._convertItemAttributes( walkerValueToEventData( value ) );
}
// ... or by converting newly inserted elements.
else {
Expand Down Expand Up @@ -597,6 +599,10 @@ export default class DowncastDispatcher {
// Fire a separate addAttribute event for each attribute that was set on inserted items.
// This is important because most attributes converters will listen only to add/change/removeAttribute events.
// If we would not add this part, attributes on inserted nodes would not be converted.
this._convertItemAttributes( data );
}

_convertItemAttributes( data ) {
for ( const key of data.item.getAttributeKeys() ) {
data.attributeKey = key;
data.attributeOldValue = null;
Expand Down Expand Up @@ -682,6 +688,16 @@ export default class DowncastDispatcher {

// Add special "reconvert" change.
updated.push( { type: 'reconvert', element } );
} else if ( element.parent && this._isReconvertTriggerEvent( eventName, element.parent.name ) ) {
if ( itemsToReconvert.has( element.parent ) ) {
// Element is already reconverted, so skip this change.
continue;
}

itemsToReconvert.add( element.parent );

// Add special "reconvert" change.
updated.push( { type: 'reconvert', element: element.parent } );
} else {
updated.push( entry );
}
Expand Down
80 changes: 38 additions & 42 deletions packages/ckeditor5-table/src/converters/downcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,65 +37,49 @@ export function downcastInsertTable( options = {} ) {
const tableElement = conversionApi.writer.createContainerElement( 'table' );
conversionApi.writer.insert( conversionApi.writer.createPositionAt( figureElement, 0 ), tableElement );

let tableWidget;

if ( asWidget ) {
toTableWidget( figureElement, conversionApi.writer );
tableWidget = toTableWidget( figureElement, conversionApi.writer );
}

const tableWalker = new TableWalker( table );

const tableAttributes = {
headingRows: table.getAttribute( 'headingRows' ) || 0,
headingColumns: table.getAttribute( 'headingColumns' ) || 0
};

// Insert empty TR elements if there are any rows without anchored cells. Since the model is always normalized
// this can happen only in the document fragment that only part of the table is down-casted.
for ( const tableRow of table.getChildren() ) {
createTr( tableElement, tableRow, tableRow.index, tableAttributes, conversionApi );
}

return figureElement;
};
}

/**
* Model table cell element to view `<td>` or `<th>` element conversion helper.
*
* This conversion helper will create proper `<th>` elements for table cells that are in the heading section (heading row or column)
* and `<td>` otherwise.
*
* @returns {Function} Conversion helper.
*/
export function downcastInsertCell( options ) {
return dispatcher => dispatcher.on( 'insert:tableCell', ( evt, data, conversionApi ) => {
const tableCell = data.item;
// Cache for created table rows.
const viewRows = new Map();

if ( !conversionApi.consumable.consume( tableCell, 'insert' ) ) {
return;
}
for ( const tableSlot of tableWalker ) {
const { row, cell } = tableSlot;

const tableRow = tableCell.parent;
const table = tableRow.parent;
const rowIndex = table.getChildIndex( tableRow );
const tableRow = table.getChild( row );
const trElement = viewRows.get( row ) || createTr( tableElement, tableRow, row, tableAttributes, conversionApi );
viewRows.set( row, trElement );

const tableWalker = new TableWalker( table, { row: rowIndex } );
// Consume table cell - it will be always consumed as we convert whole table at once.
conversionApi.consumable.consume( cell, 'insert' );

const tableAttributes = {
headingRows: table.getAttribute( 'headingRows' ) || 0,
headingColumns: table.getAttribute( 'headingColumns' ) || 0
};
const insertPosition = conversionApi.writer.createPositionAt( trElement, 'end' );

// We need to iterate over a table in order to get proper row & column values from a walker
for ( const tableSlot of tableWalker ) {
if ( tableSlot.cell === tableCell ) {
const trElement = conversionApi.mapper.toViewElement( tableRow );
const insertPosition = conversionApi.writer.createPositionAt( trElement, tableRow.getChildIndex( tableCell ) );
createViewTableCellElement( tableSlot, tableAttributes, insertPosition, conversionApi, options );
}

createViewTableCellElement( tableSlot, tableAttributes, insertPosition, conversionApi, options );
// Insert empty TR elements if there are any rows without anchored cells. Since the model is always normalized
// this can happen only in the document fragment that only part of the table is down-casted.
for ( const tableRow of table.getChildren() ) {
const rowIndex = tableRow.index;

// No need to iterate further.
return;
if ( !viewRows.has( rowIndex ) ) {
viewRows.set( rowIndex, createTr( tableElement, tableRow, rowIndex, tableAttributes, conversionApi ) );
}
}
} );

return asWidget ? tableWidget : figureElement;
};
}

/**
Expand Down Expand Up @@ -253,6 +237,18 @@ function createViewTableCellElement( tableSlot, tableAttributes, insertPosition,
toWidgetEditable( conversionApi.writer.createEditableElement( cellElementName ), conversionApi.writer ) :
conversionApi.writer.createContainerElement( cellElementName );

const colspan = tableSlot.cellWidth;

if ( colspan > 1 ) {
conversionApi.writer.setAttribute( 'colspan', colspan, cellElement );
}

const rowspan = tableSlot.cellHeight;

if ( rowspan > 1 ) {
conversionApi.writer.setAttribute( 'rowspan', rowspan, cellElement );
}

if ( asWidget ) {
setHighlightHandling(
cellElement,
Expand Down
7 changes: 3 additions & 4 deletions packages/ckeditor5-table/src/tableediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import upcastTable, { skipEmptyTableRow } from './converters/upcasttable';
import {
convertParagraphInTableCell,
downcastInsertCell,
downcastInsertTable,
downcastTableHeadingColumnsChange
} from './converters/downcast';
Expand Down Expand Up @@ -96,7 +95,7 @@ export default class TableEditing extends Plugin {
view: downcastInsertTable( { asWidget: true } ),
triggerBy: {
attributes: [ 'headingRows' ],
children: [ 'tableRow' ]
children: [ 'tableRow', 'tableCell' ]
}
} );
conversion.for( 'dataDowncast' ).elementToElement( {
Expand All @@ -115,8 +114,8 @@ export default class TableEditing extends Plugin {
conversion.for( 'upcast' ).elementToElement( { model: 'tableCell', view: 'td' } );
conversion.for( 'upcast' ).elementToElement( { model: 'tableCell', view: 'th' } );

conversion.for( 'dataDowncast' ).add( downcastInsertCell() );
conversion.for( 'editingDowncast' ).add( downcastInsertCell( { asWidget: true } ) );
// conversion.for( 'dataDowncast' ).add( downcastInsertCell() );
// conversion.for( 'editingDowncast' ).add( downcastInsertCell( { asWidget: true } ) );

// Duplicates code - needed to properly refresh paragraph inside table cell.
editor.conversion.for( 'editingDowncast' ).elementToElement( {
Expand Down
2 changes: 1 addition & 1 deletion packages/ckeditor5-table/tests/converters/downcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ describe( 'downcast converters', () => {
'<tbody>' +
'<tr><th rowspan="2">00</th><th>01</th><th rowspan="3">02</th><td>03</td></tr>' +
'<tr><th>11</th><td>13</td></tr>' +
'<tr><th rowspan="2" colspan="2">20</th><td>23</td></tr>' +
'<tr><th colspan="2" rowspan="2">20</th><td>23</td></tr>' +
'<tr><th>32</th><td>33</td></tr>' +
'</tbody>' +
'</table>' +
Expand Down

0 comments on commit d3efbf0

Please sign in to comment.