inserttableview.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  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 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. * Collection of the table size box items.
  27. *
  28. * @readonly
  29. * @member {module:ui/viewcollection~ViewCollection}
  30. */
  31. this.items = this.createCollection();
  32. /**
  33. * Currently selected number of rows of a new table.
  34. *
  35. * @observable
  36. * @member {Number} #rows
  37. */
  38. this.set( 'rows', 0 );
  39. /**
  40. * Currently selected number of columns of a 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 } x ${ 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. children: this.items
  66. },
  67. {
  68. tag: 'div',
  69. attributes: {
  70. class: [ 'ck-insert-table-dropdown__label' ]
  71. },
  72. children: [
  73. {
  74. text: bind.to( 'label' )
  75. }
  76. ]
  77. }
  78. ],
  79. on: {
  80. mousedown: bind.to( evt => {
  81. evt.preventDefault();
  82. } ),
  83. click: bind.to( () => {
  84. this.fire( 'execute' );
  85. } )
  86. }
  87. } );
  88. // Add grid boxes to table selection view.
  89. for ( let index = 0; index < 100; index++ ) {
  90. const boxView = new TableSizeGridBoxView();
  91. // Listen to box view 'over' event which indicates that mouse is over this box.
  92. boxView.on( 'over', () => {
  93. // Translate box index to the row & column index.
  94. const row = Math.floor( index / 10 );
  95. const column = index % 10;
  96. // As row & column indexes are zero-based transform it to number of selected rows & columns.
  97. this.set( 'rows', row + 1 );
  98. this.set( 'columns', column + 1 );
  99. } );
  100. this.items.add( boxView );
  101. }
  102. this.on( 'change:columns', () => {
  103. this._highlightGridBoxes();
  104. } );
  105. this.on( 'change:rows', () => {
  106. this._highlightGridBoxes();
  107. } );
  108. }
  109. /**
  110. * @inheritDoc
  111. */
  112. focus() {
  113. // The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.
  114. // The method should be implemented while working on keyboard support for this view. See #22.
  115. }
  116. /**
  117. * @inheritDoc
  118. */
  119. focusLast() {
  120. // The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.
  121. // The method should be implemented while working on keyboard support for this view. See #22.
  122. }
  123. /**
  124. * Highlights grid boxes depending on rows & columns selected.
  125. *
  126. * @private
  127. */
  128. _highlightGridBoxes() {
  129. const rows = this.rows;
  130. const columns = this.columns;
  131. this.items.map( ( boxView, index ) => {
  132. // Translate box index to the row & column index.
  133. const itemRow = Math.floor( index / 10 );
  134. const itemColumn = index % 10;
  135. // Grid box is highlighted when its row & column index belongs to selected number of rows & columns.
  136. const isOn = itemRow < rows && itemColumn < columns;
  137. boxView.set( 'isOn', isOn );
  138. } );
  139. }
  140. }
  141. /**
  142. * A single grid box view element.
  143. *
  144. * This class is used to render table size selection grid in {@link module:table/ui/inserttableview~InsertTableView}
  145. *
  146. * @private
  147. */
  148. class TableSizeGridBoxView extends View {
  149. /**
  150. * @inheritDoc
  151. */
  152. constructor( locale ) {
  153. super( locale );
  154. const bind = this.bindTemplate;
  155. /**
  156. * Controls whether the grid box view is "on".
  157. *
  158. * @observable
  159. * @member {Boolean} #isOn
  160. */
  161. this.set( 'isOn', false );
  162. this.setTemplate( {
  163. tag: 'div',
  164. attributes: {
  165. class: [
  166. 'ck-insert-table-dropdown-grid-box',
  167. bind.if( 'isOn', 'ck-on' )
  168. ]
  169. },
  170. on: {
  171. mouseover: bind.to( 'over' )
  172. }
  173. } );
  174. }
  175. }