element-reconversion-demo.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* globals ClassicEditor, console, window, document */
  6. import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
  7. const getTypeFromViewElement = viewElement => {
  8. for ( const type of [ 'info', 'warning' ] ) {
  9. if ( viewElement.hasClass( `info-box-${ type }` ) ) {
  10. return type;
  11. }
  12. }
  13. return 'info';
  14. };
  15. const upcastInfoBox = ( viewElement, { writer } ) => {
  16. const complexInfoBox = writer.createElement( 'complexInfoBox' );
  17. const type = getTypeFromViewElement( viewElement );
  18. writer.setAttribute( 'infoBoxType', type, complexInfoBox );
  19. writer.setAttribute( 'infoBoxURL', 'https://ckeditor.com', complexInfoBox );
  20. return complexInfoBox;
  21. };
  22. const downcastInfoBox = ( modelElement, { writer, consumable, mapper } ) => {
  23. const complexInfoBoxView = writer.createContainerElement( 'div', { class: 'info-box' } );
  24. const type = modelElement.getAttribute( 'infoBoxType' ) || 'info';
  25. writer.addClass( `info-box-${ type }`, complexInfoBoxView );
  26. for ( const child of modelElement.getChildren() ) {
  27. const childView = writer.createContainerElement( 'div' );
  28. if ( child.is( 'element', 'complexInfoBoxTitle' ) ) {
  29. writer.addClass( 'info-box-title', childView );
  30. } else {
  31. writer.addClass( 'info-box-content', childView );
  32. }
  33. consumable.consume( child, 'insert' );
  34. mapper.bindElements( child, childView );
  35. writer.insert( writer.createPositionAt( complexInfoBoxView, 'end' ), childView );
  36. }
  37. return complexInfoBoxView;
  38. };
  39. class ComplexInfoBox {
  40. constructor( editor ) {
  41. this._defineSchema( editor );
  42. this._defineConversion( editor );
  43. }
  44. _defineConversion( editor ) {
  45. editor.conversion.for( 'upcast' )
  46. .elementToElement( {
  47. view: { name: 'div', classes: [ 'info-box' ] },
  48. model: upcastInfoBox
  49. } )
  50. .elementToElement( {
  51. view: { name: 'div', classes: [ 'info-box-title' ] },
  52. model: 'complexInfoBoxTitle'
  53. } )
  54. .elementToElement( {
  55. view: { name: 'div', classes: [ 'info-box-content' ] },
  56. model: 'complexInfoBoxContent'
  57. } );
  58. // The downcast conversion must be split as you need a widget in the editing pipeline.
  59. editor.conversion.for( 'downcast' ).elementToElement( {
  60. model: 'complexInfoBox',
  61. view: downcastInfoBox
  62. } );
  63. }
  64. _defineSchema( editor ) {
  65. editor.model.schema.register( 'complexInfoBox', {
  66. allowWhere: '$block',
  67. allowContentOf: '$root',
  68. isObject: true,
  69. allowAttributes: [ 'infoBoxType', 'infoBoxURL' ]
  70. } );
  71. editor.model.schema.register( 'complexInfoBoxTitle', {
  72. isLimit: true,
  73. allowIn: 'complexInfoBox',
  74. allowContentOf: '$block'
  75. } );
  76. editor.model.schema.register( 'complexInfoBoxContent', {
  77. isLimit: true,
  78. allowIn: 'complexInfoBox',
  79. allowContentOf: '$root'
  80. } );
  81. }
  82. }
  83. ClassicEditor
  84. .create( document.querySelector( '#editor-element-reconversion' ), {
  85. cloudServices: CS_CONFIG,
  86. extraPlugins: [ ComplexInfoBox ],
  87. image: {
  88. toolbar: [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ]
  89. },
  90. table: {
  91. contentToolbar: [
  92. 'tableColumn',
  93. 'tableRow',
  94. 'mergeTableCells'
  95. ]
  96. },
  97. toolbar: {
  98. items: [ 'heading', '|', 'bold', 'italic' ],
  99. viewportTopOffset: window.getViewportTopOffsetConfig()
  100. }
  101. } )
  102. .then( editor => {
  103. window.editor = editor;
  104. } )
  105. .catch( err => {
  106. console.error( err );
  107. } );