converters.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module table/converters
  7. */
  8. import Position from '@ckeditor/ckeditor5-engine/src/view/position';
  9. export function createTableCell( viewElement, modelWriter ) {
  10. const attributes = {};
  11. if ( viewElement.name === 'th' ) {
  12. attributes.isHeading = true;
  13. }
  14. return modelWriter.createElement( 'tableCell', attributes );
  15. }
  16. export function createTableRow( viewElement, modelWriter ) {
  17. const attributes = {};
  18. if ( viewElement.parent.name === 'tfoot' ) {
  19. attributes.isFooter = true;
  20. }
  21. if ( viewElement.parent.name === 'thead' ) {
  22. attributes.isHeading = true;
  23. }
  24. return modelWriter.createElement( 'tableRow', attributes );
  25. }
  26. export function downcastTableCell( dispatcher ) {
  27. dispatcher.on( 'insert:tableCell', ( evt, data, conversionApi ) => {
  28. const viewElementName = data.item.getAttribute( 'isHeading' ) ? 'th' : 'td';
  29. const tableCellElement = conversionApi.writer.createContainerElement( viewElementName, {} );
  30. if ( !tableCellElement ) {
  31. return;
  32. }
  33. if ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {
  34. return;
  35. }
  36. const viewPosition = conversionApi.mapper.toViewPosition( data.range.start );
  37. conversionApi.mapper.bindElements( data.item, tableCellElement );
  38. conversionApi.writer.insert( viewPosition, tableCellElement );
  39. }, { priority: 'normal' } );
  40. }
  41. export function downcastTable( dispatcher ) {
  42. dispatcher.on( 'insert:table', ( evt, data, conversionApi ) => {
  43. const tableElement = conversionApi.writer.createContainerElement( 'table' );
  44. if ( !tableElement ) {
  45. return;
  46. }
  47. if ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {
  48. return;
  49. }
  50. const { headings, footers, rows } = _extractSectionsRows( data.item );
  51. if ( headings.length ) {
  52. _createTableSection( 'thead', tableElement, headings, conversionApi );
  53. }
  54. if ( rows.length ) {
  55. _createTableSection( 'tbody', tableElement, rows, conversionApi );
  56. }
  57. if ( footers.length ) {
  58. _createTableSection( 'tfoot', tableElement, footers, conversionApi );
  59. }
  60. const viewPosition = conversionApi.mapper.toViewPosition( data.range.start );
  61. conversionApi.mapper.bindElements( data.item, tableElement );
  62. conversionApi.writer.insert( viewPosition, tableElement );
  63. }, { priority: 'normal' } );
  64. }
  65. function _extractSectionsRows( table ) {
  66. const tableRows = [ ...table.getChildren() ];
  67. const headings = [];
  68. const footers = [];
  69. const rows = [];
  70. for ( const tableRow of tableRows ) {
  71. if ( tableRow.getAttribute( 'isHeading' ) ) {
  72. headings.push( tableRow );
  73. } else if ( tableRow.getAttribute( 'isFooter' ) ) {
  74. footers.push( tableRow );
  75. } else {
  76. rows.push( tableRow );
  77. }
  78. }
  79. return { headings, footers, rows };
  80. }
  81. function _createTableSection( elementName, tableElement, rows, conversionApi ) {
  82. const tableBodyElement = conversionApi.writer.createContainerElement( elementName );
  83. conversionApi.writer.insert( Position.createAt( tableElement, 'end' ), tableBodyElement );
  84. rows.map( row => _downcastTableRow( row, conversionApi, tableBodyElement ) );
  85. }
  86. function _downcastTableRow( tableRow, conversionApi, parent ) {
  87. const tableRowElement = conversionApi.writer.createContainerElement( 'tr' );
  88. if ( !tableRowElement ) {
  89. return;
  90. }
  91. if ( !conversionApi.consumable.consume( tableRow, 'insert' ) ) {
  92. return;
  93. }
  94. conversionApi.mapper.bindElements( tableRow, tableRowElement );
  95. conversionApi.writer.insert( Position.createAt( parent, 'end' ), tableRowElement );
  96. }