s) as handled by this converter.
conversionApi.consumable.consume( viewInfoBoxTitle, { name: true } );
conversionApi.consumable.consume( viewInfoBoxContent, { name: true } );
// Let the editor handle the children of
.
conversionApi.convertChildren( viewInfoBoxContent, modelElement );
// Finally, update the conversion's modelRange and modelCursor.
conversionApi.updateConversionResult( modelElement, data );
}
function editingDowncastConverter( event, data, conversionApi ) {
let { infoBox, infoBoxContent, infoBoxTitle } = createViewElements( data, conversionApi );
// Decorate view items as a widget and widget editable area.
infoBox = toWidget( infoBox, conversionApi.writer, { label: 'info box widget' } );
infoBoxContent = toWidgetEditable( infoBoxContent, conversionApi.writer );
insertViewElements( data, conversionApi, infoBox, infoBoxTitle, infoBoxContent );
}
function dataDowncastConverter( event, data, conversionApi ) {
const { infoBox, infoBoxContent, infoBoxTitle } = createViewElements( data, conversionApi );
insertViewElements( data, conversionApi, infoBox, infoBoxTitle, infoBoxContent );
}
function createViewElements( data, conversionApi ) {
const type = data.item.getAttribute( 'infoBoxType' );
const infoBox = conversionApi.writer.createContainerElement( 'div', {
class: `info-box info-box-${ type.toLowerCase() }`
} );
const infoBoxContent = conversionApi.writer.createEditableElement( 'div', {
class: 'info-box-content'
} );
const infoBoxTitle = conversionApi.writer.createUIElement( 'div',
{ class: 'info-box-title' },
function( domDocument ) {
const domElement = this.toDomElement( domDocument );
domElement.innerText = type;
return domElement;
} );
return { infoBox, infoBoxContent, infoBoxTitle };
}
function insertViewElements( data, conversionApi, infoBox, infoBoxTitle, infoBoxContent ) {
conversionApi.consumable.consume( data.item, 'insert' );
conversionApi.writer.insert(
conversionApi.writer.createPositionAt( infoBox, 0 ),
infoBoxTitle
);
conversionApi.writer.insert(
conversionApi.writer.createPositionAt( infoBox, 1 ),
infoBoxContent
);
// The default mapping between the model
and its view representation.
conversionApi.mapper.bindElements( data.item, infoBox );
// However, since the model content needs to end up in the inner
// , you need to bind one with another overriding
// a part of the default binding.
conversionApi.mapper.bindElements( data.item, infoBoxContent );
conversionApi.writer.insert(
conversionApi.mapper.toViewPosition( data.range.start ),
infoBox
);
}
ClassicEditor
.create( document.querySelector( '#editor-custom-element-converter' ), {
cloudServices: CS_CONFIG,
extraPlugins: [ InfoBox ],
image: {
toolbar: [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ]
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells'
]
},
toolbar: {
viewportTopOffset: window.getViewportTopOffsetConfig()
}
} )
.then( editor => {
window.editor = editor;
} )
.catch( err => {
console.error( err.stack );
} );
function getTypeFromViewElement( viewElement ) {
if ( viewElement.hasClass( 'info-box-info' ) ) {
return 'Info';
}
if ( viewElement.hasClass( 'info-box-warning' ) ) {
return 'Warning';
}
return 'None';
}