table-heading-rows-refresh-post-fixer.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module table/converters/table-heading-rows-refresh-post-fixer
  7. */
  8. /**
  9. * Injects a table post-fixer into the model which marks the table in the differ to have it re-rendered.
  10. *
  11. * Table heading rows are represented in the model by a `headingRows` attribute. However, in the view, it's represented as separate
  12. * sections of the table (`<thead>` or `<tbody>`) and changing `headingRows` attribute requires moving table rows between two sections.
  13. * This causes problems with structural changes in a table (like adding and removing rows) thus atomic converters cannot be used.
  14. *
  15. * When table `headingRows` attribute changes, the entire table is re-rendered.
  16. *
  17. * @param {module:engine/model/model~Model} model
  18. */
  19. export default function injectTableHeadingRowsRefreshPostFixer( model ) {
  20. model.document.registerPostFixer( () => tableHeadingRowsRefreshPostFixer( model ) );
  21. }
  22. function tableHeadingRowsRefreshPostFixer( model ) {
  23. const differ = model.document.differ;
  24. // Stores tables to be refreshed so the table will be refreshed once for multiple changes.
  25. const tablesToRefresh = new Set();
  26. for ( const change of differ.getChanges() ) {
  27. if ( change.type != 'attribute' ) {
  28. continue;
  29. }
  30. const element = change.range.start.nodeAfter;
  31. if ( element && element.is( 'element', 'table' ) && change.attributeKey == 'headingRows' ) {
  32. tablesToRefresh.add( element );
  33. }
  34. }
  35. if ( tablesToRefresh.size ) {
  36. // @if CK_DEBUG_TABLE // console.log( `Post-fixing table: refreshing heading rows (${ tablesToRefresh.size }).` );
  37. for ( const table of tablesToRefresh.values() ) {
  38. // Should be handled by a `triggerBy` configuration. See: https://github.com/ckeditor/ckeditor5/issues/8138.
  39. differ.refreshItem( table );
  40. }
  41. return true;
  42. }
  43. return false;
  44. }