8
0

inserttableview.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. 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. this.on( 'change:columns', () => {
  89. this._highlightGridBoxes();
  90. } );
  91. this.on( 'change:rows', () => {
  92. this._highlightGridBoxes();
  93. } );
  94. }
  95. /**
  96. * @inheritDoc
  97. */
  98. focus() {
  99. // The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.
  100. // The method should be implemented while working on keyboard support for this view. See #22.
  101. }
  102. /**
  103. * @inheritDoc
  104. */
  105. focusLast() {
  106. // The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.
  107. // The method should be implemented while working on keyboard support for this view. See #22.
  108. }
  109. /**
  110. * Highlights grid boxes depending on rows and columns selected.
  111. *
  112. * @private
  113. */
  114. _highlightGridBoxes() {
  115. const rows = this.rows;
  116. const columns = this.columns;
  117. this.items.map( ( boxView, index ) => {
  118. // Translate box index to the row & column index.
  119. const itemRow = Math.floor( index / 10 );
  120. const itemColumn = index % 10;
  121. // Grid box is highlighted when its row & column index belongs to selected number of rows & columns.
  122. const isOn = itemRow < rows && itemColumn < columns;
  123. boxView.set( 'isOn', isOn );
  124. } );
  125. }
  126. /**
  127. * @private
  128. * @returns {module:ui/viewcollection~ViewCollection} A view collection containing boxes to be placed in a table grid.
  129. */
  130. _createGridCollection() {
  131. const boxes = new Set();
  132. // Add grid boxes to table selection view.
  133. for ( let index = 0; index < 100; index++ ) {
  134. const boxView = new TableSizeGridBoxView();
  135. // Listen to box view 'over' event which indicates that mouse is over this box.
  136. boxView.on( 'over', () => {
  137. // Translate box index to the row & column index.
  138. const row = Math.floor( index / 10 );
  139. const column = index % 10;
  140. // As row & column indexes are zero-based transform it to number of selected rows & columns.
  141. this.set( {
  142. rows: row + 1,
  143. columns: column + 1
  144. } );
  145. } );
  146. boxes.add( boxView );
  147. }
  148. return this.createCollection( boxes );
  149. }
  150. }
  151. /**
  152. * A single grid box view element.
  153. *
  154. * This class is used to render the table size selection grid in {@link module:table/ui/inserttableview~InsertTableView}.
  155. *
  156. * @private
  157. */
  158. class TableSizeGridBoxView extends View {
  159. /**
  160. * @inheritDoc
  161. */
  162. constructor( locale ) {
  163. super( locale );
  164. const bind = this.bindTemplate;
  165. /**
  166. * Controls whether the grid box view is "on".
  167. *
  168. * @observable
  169. * @member {Boolean} #isOn
  170. */
  171. this.set( 'isOn', false );
  172. this.setTemplate( {
  173. tag: 'div',
  174. attributes: {
  175. class: [
  176. 'ck-insert-table-dropdown-grid-box',
  177. bind.if( 'isOn', 'ck-on' )
  178. ]
  179. },
  180. on: {
  181. mouseover: bind.to( 'over' )
  182. }
  183. } );
  184. }
  185. }