8
0

utils.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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/utils
  7. */
  8. import { isWidget, toWidget } from '@ckeditor/ckeditor5-widget/src/utils';
  9. import { findAncestor } from './commands/utils';
  10. /**
  11. * Converts a given {@link module:engine/view/element~Element} to a table widget:
  12. * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the table widget element.
  13. * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.
  14. *
  15. * @param {module:engine/view/element~Element} viewElement
  16. * @param {module:engine/view/downcastwriter~DowncastWriter} writer An instance of the view writer.
  17. * @param {String} label The element's label. It will be concatenated with the table `alt` attribute if one is present.
  18. * @returns {module:engine/view/element~Element}
  19. */
  20. export function toTableWidget( viewElement, writer ) {
  21. writer.setCustomProperty( 'table', true, viewElement );
  22. return toWidget( viewElement, writer, { hasSelectionHandle: true } );
  23. }
  24. /**
  25. * Checks if a given view element is a table widget.
  26. *
  27. * @param {module:engine/view/element~Element} viewElement
  28. * @returns {Boolean}
  29. */
  30. export function isTableWidget( viewElement ) {
  31. return !!viewElement.getCustomProperty( 'table' ) && isWidget( viewElement );
  32. }
  33. /**
  34. * Returns a table widget editing view element if one is selected.
  35. *
  36. * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection
  37. * @returns {module:engine/view/element~Element|null}
  38. */
  39. export function getSelectedTableWidget( selection ) {
  40. const viewElement = selection.getSelectedElement();
  41. if ( viewElement && isTableWidget( viewElement ) ) {
  42. return viewElement;
  43. }
  44. return null;
  45. }
  46. /**
  47. * Returns a table widget editing view element if one is among the selection's ancestors.
  48. *
  49. * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection
  50. * @returns {module:engine/view/element~Element|null}
  51. */
  52. export function getTableWidgetAncestor( selection ) {
  53. const parentTable = findAncestor( 'table', selection.getFirstPosition() );
  54. if ( parentTable && isTableWidget( parentTable.parent ) ) {
  55. return parentTable.parent;
  56. }
  57. return null;
  58. }
  59. /**
  60. * Returns all model table cells that are fully selected (from the outside)
  61. * within the provided model selection's ranges.
  62. *
  63. * To obtain the cells selected from the inside, use
  64. * {@link module:table/utils~getTableCellsContainingSelection}.
  65. *
  66. * @param {module:engine/model/selection~Selection} selection
  67. * @returns {Array.<module:engine/model/element~Element>}
  68. */
  69. export function getSelectedTableCells( selection ) {
  70. const cells = [];
  71. for ( const range of selection.getRanges() ) {
  72. const element = range.getContainedElement();
  73. if ( element && element.is( 'tableCell' ) ) {
  74. cells.push( element );
  75. }
  76. }
  77. return cells;
  78. }
  79. /**
  80. * Returns all model table cells the provided model selection's ranges
  81. * {@link module:engine/model/range~Range#start} inside.
  82. *
  83. * To obtain the cells selected from the outside, use
  84. * {@link module:table/utils~getSelectedTableCells}.
  85. *
  86. * @param {module:engine/model/selection~Selection} selection
  87. * @returns {Array.<module:engine/model/element~Element>}
  88. */
  89. export function getTableCellsContainingSelection( selection ) {
  90. const cells = [];
  91. for ( const range of selection.getRanges() ) {
  92. const cellWithSelection = findAncestor( 'tableCell', range.start );
  93. if ( cellWithSelection ) {
  94. cells.push( cellWithSelection );
  95. }
  96. }
  97. return cells;
  98. }
  99. /**
  100. * Returns all model table cells that are either completely selected
  101. * by selection ranges or host selection range
  102. * {@link module:engine/model/range~Range#start start positions} inside them.
  103. *
  104. * Combines {@link module:table/utils~getTableCellsContainingSelection} and
  105. * {@link module:table/utils~getSelectedTableCells}.
  106. *
  107. * @param {module:engine/model/selection~Selection} selection
  108. * @returns {Array.<module:engine/model/element~Element>}
  109. */
  110. export function getSelectionAffectedTableCells( selection ) {
  111. const selectedCells = getSelectedTableCells( selection );
  112. if ( selectedCells.length ) {
  113. return selectedCells;
  114. }
  115. return getTableCellsContainingSelection( selection );
  116. }