inserttableview.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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/ui/inserttableview
  7. */
  8. import View from '@ckeditor/ckeditor5-ui/src/view';
  9. import './../../theme/inserttable.css';
  10. /**
  11. * The table size view.
  12. *
  13. * It renders a 10x10 grid to choose the inserted table size.
  14. *
  15. * @extends module:ui/view~View
  16. * @implements module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable
  17. */
  18. export default class InsertTableView extends View {
  19. /**
  20. * @inheritDoc
  21. */
  22. constructor( locale ) {
  23. super( locale );
  24. const bind = this.bindTemplate;
  25. /**
  26. * A collection of table size box items.
  27. *
  28. * @readonly
  29. * @member {module:ui/viewcollection~ViewCollection}
  30. */
  31. this.items = this._createGridCollection();
  32. /**
  33. * The currently selected number of rows of the new table.
  34. *
  35. * @observable
  36. * @member {Number} #rows
  37. */
  38. this.set( 'rows', 0 );
  39. /**
  40. * The currently selected number of columns of the new table.
  41. *
  42. * @observable
  43. * @member {Number} #columns
  44. */
  45. this.set( 'columns', 0 );
  46. /**
  47. * The label text displayed under the boxes.
  48. *
  49. * @observable
  50. * @member {String} #label
  51. */
  52. this.bind( 'label' )
  53. .to( this, 'columns', this, 'rows', ( columns, rows ) => `${ rows } × ${ columns }` );
  54. this.setTemplate( {
  55. tag: 'div',
  56. attributes: {
  57. class: [ 'ck' ]
  58. },
  59. children: [
  60. {
  61. tag: 'div',
  62. attributes: {
  63. class: [ 'ck-insert-table-dropdown__grid' ]
  64. },
  65. on: {
  66. 'mouseover@.ck-insert-table-dropdown-grid-box': bind.to( 'boxover' )
  67. },
  68. children: this.items
  69. },
  70. {
  71. tag: 'div',
  72. attributes: {
  73. class: [ 'ck-insert-table-dropdown__label' ]
  74. },
  75. children: [
  76. {
  77. text: bind.to( 'label' )
  78. }
  79. ]
  80. }
  81. ],
  82. on: {
  83. mousedown: bind.to( evt => {
  84. evt.preventDefault();
  85. } ),
  86. click: bind.to( () => {
  87. this.fire( 'execute' );
  88. } )
  89. }
  90. } );
  91. this.on( 'boxover', ( evt, domEvt ) => {
  92. const { row, column } = domEvt.target.dataset;
  93. // As row & column indexes are zero-based transform it to number of selected rows & columns.
  94. this.set( {
  95. rows: parseInt( row ),
  96. columns: parseInt( column )
  97. } );
  98. } );
  99. this.on( 'change:columns', () => {
  100. this._highlightGridBoxes();
  101. } );
  102. this.on( 'change:rows', () => {
  103. this._highlightGridBoxes();
  104. } );
  105. }
  106. /**
  107. * @inheritDoc
  108. */
  109. focus() {
  110. // The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.
  111. // The method should be implemented while working on keyboard support for this view. See #22.
  112. }
  113. /**
  114. * @inheritDoc
  115. */
  116. focusLast() {
  117. // The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.
  118. // The method should be implemented while working on keyboard support for this view. See #22.
  119. }
  120. /**
  121. * Highlights grid boxes depending on rows and columns selected.
  122. *
  123. * @private
  124. */
  125. _highlightGridBoxes() {
  126. const rows = this.rows;
  127. const columns = this.columns;
  128. this.items.map( ( boxView, index ) => {
  129. // Translate box index to the row & column index.
  130. const itemRow = Math.floor( index / 10 );
  131. const itemColumn = index % 10;
  132. // Grid box is highlighted when its row & column index belongs to selected number of rows & columns.
  133. const isOn = itemRow < rows && itemColumn < columns;
  134. boxView.set( 'isOn', isOn );
  135. } );
  136. }
  137. /**
  138. * @private
  139. * @returns {module:ui/viewcollection~ViewCollection} A view collection containing boxes to be placed in a table grid.
  140. */
  141. _createGridCollection() {
  142. const boxes = [];
  143. // Add grid boxes to table selection view.
  144. for ( let index = 0; index < 100; index++ ) {
  145. const row = Math.floor( index / 10 );
  146. const column = index % 10;
  147. boxes.push( new TableSizeGridBoxView( this.locale, row + 1, column + 1 ) );
  148. }
  149. return this.createCollection( boxes );
  150. }
  151. /**
  152. * Fired when the mouse hover over one of the {@link #items child grid boxes}.
  153. *
  154. * @event boxover
  155. */
  156. }
  157. /**
  158. * A single grid box view element.
  159. *
  160. * This class is used to render the table size selection grid in {@link module:table/ui/inserttableview~InsertTableView}.
  161. *
  162. * @private
  163. */
  164. class TableSizeGridBoxView extends View {
  165. /**
  166. * @inheritDoc
  167. */
  168. constructor( locale, row, column ) {
  169. super( locale );
  170. const bind = this.bindTemplate;
  171. /**
  172. * Controls whether the grid box view is "on".
  173. *
  174. * @observable
  175. * @member {Boolean} #isOn
  176. */
  177. this.set( 'isOn', false );
  178. this.setTemplate( {
  179. tag: 'div',
  180. attributes: {
  181. class: [
  182. 'ck-insert-table-dropdown-grid-box',
  183. bind.if( 'isOn', 'ck-on' )
  184. ],
  185. 'data-row': row,
  186. 'data-column': column
  187. }
  188. } );
  189. }
  190. }