| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- /**
- * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
- /* globals ClassicEditor, toWidget, toWidgetEditable, console, window, document */
- import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
- ClassicEditor
- .create( document.querySelector( '#editor-custom-element-converter' ), {
- cloudServices: CS_CONFIG,
- extraPlugins: [ function( editor ) {
- editor.model.schema.register( 'infoBox', {
- allowWhere: '$block',
- allowContentOf: '$root',
- isObject: true,
- allowAttributes: [ 'infoBoxType' ]
- } );
- editor.conversion.for( 'upcast' ).add( dispatcher => dispatcher.on( 'element:div', ( event, data, conversionApi ) => {
- const viewInfoBox = data.viewItem;
- // . Detect that converted div is the one we need to convert.
- // . Create model structure.
- const modelElement = conversionApi.writer.createElement( 'infoBox', {
- infoBoxType: getTypeFromViewElement( viewInfoBox )
- } );
- // . Try to safely insert element - if it returns false the element can't be safely inserted into
- // the content and the conversion process must stop.
- if ( !conversionApi.safeInsert( modelElement, data.modelCursor ) ) {
- return;
- }
- // . Mark info-box div as handled by this converter.
- if ( !conversionApi.consumable.consume( viewInfoBox, { name: true } ) ) {
- return; // If already handled by another converter.
- }
- // For the sake of simplicity we assume that HTML structure is always the same.
- // If you can't control the order of view elements a more sophisticated search might be needed.
- const viewInfoBoxTitle = viewInfoBox.getChild( 0 );
- const viewInfoBoxContent = viewInfoBox.getChild( 1 );
- conversionApi.consumable.consume( viewInfoBoxTitle, { name: true } );
- conversionApi.consumable.consume( viewInfoBoxContent, { name: true } );
- // . Make editor handle children conversion.
- conversionApi.convertChildren( viewInfoBoxContent, modelElement );
- // . Conversion requires updating data structure properly.
- conversionApi.updateConversionResult( modelElement, data );
- } ) );
- editor.conversion.for( 'downcast' ).add(
- dispatcher => dispatcher.on( 'insert:infoBox', ( event, data, conversionApi ) => {
- const modelElement = data.item;
- const viewWriter = conversionApi.writer;
- const type = modelElement.getAttribute( 'infoBoxType' );
- const infoBox = toWidget(
- viewWriter.createContainerElement( 'div', { class: `info-box info-box-${ type }` } ),
- viewWriter,
- { label: 'simple box widget' }
- );
- const infoBoxTitle = viewWriter.createUIElement( 'div', { class: 'info-box-title' }, function( domDocument ) {
- const domElement = this.toDomElement( domDocument );
- domElement.innerText = type;
- return domElement;
- } );
- const infoBoxContent = toWidgetEditable(
- viewWriter.createEditableElement( 'div', { class: 'info-box-content' } ),
- viewWriter
- );
- conversionApi.consumable.consume( modelElement, 'insert' );
- const viewPosition = conversionApi.mapper.toViewPosition( data.range.start );
- viewWriter.insert( viewWriter.createPositionAt( infoBox, 0 ), infoBoxTitle );
- viewWriter.insert( viewWriter.createPositionAt( infoBox, 1 ), infoBoxContent );
- // Bind both...
- conversionApi.mapper.bindElements( modelElement, infoBox );
- conversionApi.mapper.bindElements( modelElement, infoBoxContent );
- conversionApi.writer.insert( viewPosition, infoBox );
- } )
- );
- } ],
- toolbar: [
- 'heading',
- '|',
- 'bold',
- 'italic',
- 'link',
- 'bulletedList',
- 'numberedList',
- '|',
- 'outdent',
- 'indent',
- '|',
- 'blockQuote',
- 'insertTable',
- 'mediaEmbed',
- 'undo',
- 'redo'
- ],
- 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 ) {
- const classNames = [ ...viewElement.getClassNames() ];
- if ( classNames.includes( 'info-box-info' ) ) {
- return 'info';
- }
- if ( classNames.includes( 'info-box-warning' ) ) {
- return 'warning';
- }
- return 'none';
- }
|