8
0

inserttableview.js 4.7 KB

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