-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Writing an event-based elementToElement upcast converter should be simpler #7336
Comments
BTW, the best proof that this needs to be simplified is https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-code-block/src/converters.js#L197-L239. |
@Reinmar I'm reading this issue backwards so I'll touch the copy-paste example. When I was starting with table I was convinced that this is the proper way of doing it. Lately we was proposing "additive" converters - ie such that adds something to a previously converted element. Compare my proposal (not yet issued) for changing the table cell upcast conversion: https://github.com/ckeditor/ckeditor5/compare/i/6XXX-simplify-table-cell-upcast?expand=1 This is much simpler example than code block. The table cell converter would only ensure that upcasted table has The side question (or a thing to consider) is maybe some of the converters can be written differently? Other than that I think that such converters could be simplified and better utils for those tasks are welcome :) |
TODO:
|
🚧 WiP 🚧 Right this post will act as a placeholder for longer notes - ATM I've only checked where the custom element-to-element conversion happens and what's happening there. Upcast
|
I've added two new methods:
The usage is: const wasInserted = conversionApi.safeInsert( modelElement, data.modelCursor ) );
if ( !wasInserted ) {
return;
}
conversionApi.consumable.consume( modelElement, { name: true } ); // might be anywhere...
conversionApi.convertChildren( modelElement );
conversionApi.updateConversionResult( modelElement, data ); I've used it in conversion of:
I've failed with list feature conversion but from bird's eye it might be because the list converters doesn't use As for editor.conversion.for( 'upcast' ).add( dispatcher => {
dispatcher.on( 'element:raw-html', ( evt, data, conversionApi ) => {
const viewItem = data.viewItem;
const viewItemContent = stringifyViewItem( viewItem );
const modelElement = conversionApi.writer.createElement(
'rawHtml',
{ rawHtmlContent: viewItemContent }
);
conversionApi.safeInsert( modelElement, data.modelCursor );
conversionApi.consumable.consume( viewItem, { name: true } );
conversionApi.updateConversionResult( modelElement, data );
} );
} ); But it could also look like this: editor.conversion.for( 'upcast' ).elementToElement( {
view: 'raw-html',
model: ( viewItem, writer, conversionApi ) => {
const viewItemContent = stringifyViewItem( viewItem );
const modelElement = conversionApi.writer.createElement(
'rawHtml',
{ rawHtmlContent: viewItemContent }
);
for ( const child of viewItem.getChildren() ) {
conversionApi.consumable.consume( child, { name: true } );
}
return modelElement;
}
} ); ps.: To my surprise this also works: editor.conversion.for( 'upcast' ).elementToElement( {
view: 'raw-html',
model: ( viewItem, writer ) => {
const viewItemContent = stringifyViewItem( viewItem );
return writer.createElement( 'rawHtml', { rawHtmlContent: viewItemContent } );
}
} ); Because the POC uses |
Maybe then we could merge |
Okay, it seems that |
AFAICS - Not doable because of |
Okay. I don't have any other remarks. |
conversionApi.safeInsert( modelElement, data.modelCursor ) );
conversionApi.convertChildren( modelElement );
conversionApi.updateConversionResult( modelElement, data ); But... cannot this be moved into one function? Assuming that we already checked that the element can be inserted. |
conversionApi.safelyInsertAndConvertChildrenIfPossible( modelElement, data ); Looks weird - or I don't have a better name for that. |
I was trying to understand the code in ckeditor5-image and I hate how hard to read this is ;/ It's doing some smart things, but I highly doubt I'd write it the same way myself. In fact, #2780 proves that it's non-obvious how to write such a converter. But I guess it's beyond the scope of this ticket.
I also can't think of a reasonable API. Second, if you write a custom converter, there's usually something custom that you'll want to do at one of the stages or drop one of the stages. In fact, ACAICS, none of the cases that @jodator improved would benefit from this method. |
So, anyway, it looks good to me so far. I think the direction makes sense. The missing piece for me will be of course APi docs but also a chapter about writing an event based converters in https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/conversion/conversion-introduction.html. It's a broader topic than just e2e converters, so we'd need some short general intro. I can write that part. But then we need an example of switching from e2e to a custom converter. If you could prepare something, that'd speed up the rest. Also, do we want to review other helpers in the same way? a2e, a2a? If so, perhaps it'd be good to do the research before actually committing changes done in this ticket. IDK if that'll be possible, but the APIs should be consistent. |
To not forget - some API might be removed. For instance the |
Feature (engine): Introduced new upcast `ConversionApi` helper methods - `conversionApi.safeInsert()` and `conversionApi.updateConversionResult()`. New methods are intended to simplify writing event based element-to-element converters. Closes #7336. MAJOR BREAKING CHANGE (engine): The `config.view` parameter for upcast element-to-element conversion helpers configurations is again mandatory. You can retain previous "catch-all" behavior for upcast converter using `config.view = /[\s\S]+/`.
📝 Provide a description of the improvement
Right now, if you need to do something at least slightly custom (so
elementToElement()
is not an option to you), you need to copy 90% of this code:https://github.com/ckeditor/ckeditor5/blob/79221ae/packages/ckeditor5-engine/src/conversion/upcasthelpers.js#L544-L618
We should clean up and split this algorithm into set of function that one could pick from.
https://github.com/ckeditor/ckeditor5/blob/79221ae/packages/ckeditor5-engine/src/conversion/upcasthelpers.js#L572 – why do we check whether we can consume it after calling(edit: yep, already refactored)getModelElement()
? Can't the order be changed?conversionApi.safeInsert()
?modelElement
to make it shorterIf you'd like to see this improvement implemented, add a 👍 reaction to this post.
The text was updated successfully, but these errors were encountered: