383b85417cfd7248658d03cdc2bf9d73312112a063341c37165f6da000d3a0d8cc81a2ccdcc71bd9dd16126e20a31acc59b41db81b72345a7c852f2cb132d0 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829
  1. import {arrayEach} from './helpers/array';
  2. import {objectEach} from './helpers/object';
  3. /**
  4. * @description
  5. * Handsontable events are the common interface that function in 2 ways: as __callbacks__ and as __hooks__.
  6. *
  7. * @example
  8. *
  9. * ```js
  10. * // Using events as callbacks:
  11. * ...
  12. * var hot1 = new Handsontable(document.getElementById('example1'), {
  13. * afterChange: function(changes, source) {
  14. * $.ajax({
  15. * url: "save.php',
  16. * data: change
  17. * });
  18. * }
  19. * });
  20. * ...
  21. * ```
  22. *
  23. * ```js
  24. * // Using events as plugin hooks:
  25. * ...
  26. * var hot1 = new Handsontable(document.getElementById('example1'), {
  27. * myPlugin: true
  28. * });
  29. *
  30. * var hot2 = new Handsontable(document.getElementById('example2'), {
  31. * myPlugin: false
  32. * });
  33. *
  34. * // global hook
  35. * Handsontable.hooks.add('afterChange', function() {
  36. * // Fired twice - for hot1 and hot2
  37. * if (this.getSettings().myPlugin) {
  38. * // function body - will only run for hot1
  39. * }
  40. * });
  41. *
  42. * // local hook (has same effect as a callback)
  43. * hot2.addHook('afterChange', function() {
  44. * // function body - will only run in #example2
  45. * });
  46. * ```
  47. * ...
  48. */
  49. // @TODO: Move plugin description hooks to plugin?
  50. const REGISTERED_HOOKS = [
  51. /**
  52. * Callback fired after resetting a cell's meta.
  53. *
  54. * @event Hooks#afterCellMetaReset
  55. * @since 0.11
  56. */
  57. 'afterCellMetaReset',
  58. /**
  59. * @description
  60. * Callback fired after one or more cells has been changed. Its main use case is to save the input.
  61. *
  62. * __Note:__ For performance reasons, the `changes` array is null for `"loadData"` source.
  63. *
  64. * @event Hooks#afterChange
  65. * @param {Array} changes 2D array containing information about each of the edited cells `[[row, prop, oldVal, newVal], ...]`.
  66. * @param {String} [source] String that identifies source of hook call
  67. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  68. */
  69. 'afterChange',
  70. /**
  71. * @description
  72. * Fired after observing changes.
  73. *
  74. * @event Hooks#afterChangesObserved
  75. */
  76. 'afterChangesObserved',
  77. /**
  78. * @description
  79. * Fired after setting up the Context Menu's default options. These options are a collection which user can select by setting
  80. * an array of keys or an array of objects in `contextMenu` option.
  81. *
  82. * @event Hooks#afterContextMenuDefaultOptions
  83. * @param {Array} predefinedItems Array of objects containing information about the pre-defined Context Menu items.
  84. */
  85. 'afterContextMenuDefaultOptions',
  86. /**
  87. * @description
  88. * Fired before setting up the Context Menu's items but after filtering these options by user (`contextMenu` option). This hook
  89. * can by helpful to determine if user use specified menu item or to set up one of the menu item to by always visible.
  90. *
  91. * @event Hooks#beforeContextMenuSetItems
  92. * @param {Array} menuItems Array of objects containing information about to generated Context Menu items.
  93. */
  94. 'beforeContextMenuSetItems',
  95. /**
  96. * @description
  97. * Fired after setting up the Context Menu's default options. These options are a collection which user can select by setting
  98. * an array of keys or an array of objects in `contextMenu` option.
  99. *
  100. * @pro
  101. * @event Hooks#afterDropdownMenuDefaultOptions
  102. * @param {Array} predefinedItems Array of objects containing information about the pre-defined Context Menu items.
  103. */
  104. 'afterDropdownMenuDefaultOptions',
  105. /**
  106. * @description
  107. * Fired before setting up the Dropdown Menu's items but after filtering these options by user (`dropdownMenu` option). This hook
  108. * can by helpful to determine if user use specified menu item or to set up one of the menu item to by always visible.
  109. *
  110. * @pro
  111. * @event Hooks#beforeDropdownMenuSetItems
  112. * @param {Array} menuItems Array of objects containing information about to generated Dropdown Menu items.
  113. */
  114. 'beforeDropdownMenuSetItems',
  115. /**
  116. * @description
  117. * Fired after hiding the Context Menu.
  118. *
  119. * @event Hooks#afterContextMenuHide
  120. * @param {Object} context The Context menu instance.
  121. */
  122. 'afterContextMenuHide',
  123. /**
  124. * @description
  125. * Fired after opening the Context Menu.
  126. *
  127. * @event Hooks#afterContextMenuShow
  128. * @param {Object} context The Context Menu instance.
  129. */
  130. 'afterContextMenuShow',
  131. /**
  132. * @description
  133. * Fired after reaching the copy limit while copying data.
  134. *
  135. * @event Hooks#afterCopyLimit
  136. * @param {Number} selectedRows Count of selected copyable rows.
  137. * @param {Number} selectedColumns Count of selected copyable columns.
  138. * @param {Number} copyRowsLimit Current copy rows limit.
  139. * @param {Number} copyColumnsLimit Current copy columns limit.
  140. */
  141. 'afterCopyLimit',
  142. /**
  143. * Callback is fired before a new column was created.
  144. *
  145. * @since 0.28.0
  146. * @event Hooks#beforeCreateCol
  147. * @param {Number} index Represents the index of first newly created column in the data source array.
  148. * @param {Number} amount Number of newly created columns in the data source array.
  149. * @param {String} [source] String that identifies source of hook call
  150. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  151. */
  152. 'beforeCreateCol',
  153. /**
  154. * Callback is fired after a new column was created.
  155. *
  156. * @event Hooks#afterCreateCol
  157. * @param {Number} index Represents the index of first newly created column in the data source array.
  158. * @param {Number} amount Number of newly created columns in the data source array.
  159. * @param {String} [source] String that identifies source of hook call
  160. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  161. */
  162. 'afterCreateCol',
  163. /**
  164. * Callback is fired before a new row was created.
  165. *
  166. * @since 0.28.0
  167. * @event Hooks#beforeCreateRow
  168. * @param {Number} index Represents the index of first newly created row in the data source array.
  169. * @param {Number} amount Number of newly created rows in the data source array.
  170. * @param {String} [source] String that identifies source of hook call
  171. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  172. */
  173. 'beforeCreateRow',
  174. /**
  175. * Callback is fired after a new row was created.
  176. *
  177. * @event Hooks#afterCreateRow
  178. * @param {Number} index Represents the index of first newly created row in the data source array.
  179. * @param {Number} amount Number of newly created rows in the data source array.
  180. * @param {String} [source] String that identifies source of hook call
  181. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  182. */
  183. 'afterCreateRow',
  184. /**
  185. * Fired after the current cell is deselected.
  186. *
  187. * @event Hooks#afterDeselect
  188. */
  189. 'afterDeselect',
  190. /**
  191. * Fired after destroying the Handsontable instance.
  192. *
  193. * @event Hooks#afterDestroy
  194. */
  195. 'afterDestroy',
  196. /**
  197. * Fired on a `keydown` event on the document body.
  198. *
  199. * @event Hooks#afterDocumentKeyDown
  200. * @param {Event} event A `keydown` event.
  201. */
  202. 'afterDocumentKeyDown',
  203. /**
  204. * Callback fired after getting the cell settings.
  205. *
  206. * @event Hooks#afterGetCellMeta
  207. * @param {Number} row Row index.
  208. * @param {Number} col Column index.
  209. * @param {Object} cellProperties Object containing the cell properties.
  210. */
  211. 'afterGetCellMeta',
  212. /**
  213. * Callback fired after retrieving information about a column header and appending it to the table header.
  214. *
  215. * @event Hooks#afterGetColHeader
  216. * @param {Number} col Column index.
  217. * @param {Element} TH Header's TH element.
  218. */
  219. 'afterGetColHeader',
  220. /**
  221. * Callback fired after retrieving information about a column header and appending it to the table header.
  222. *
  223. * @event Hooks#afterGetRowHeader
  224. * @param {Number} row Row index.
  225. * @param {Element} TH Header's TH element.
  226. */
  227. 'afterGetRowHeader',
  228. /**
  229. * Callback fired after Handsontable instance is initiated.
  230. *
  231. * @event Hooks#afterInit
  232. */
  233. 'afterInit',
  234. /**
  235. * Callback fired after new data is loaded (by `loadData` method) into the data source array.
  236. *
  237. * @event Hooks#afterLoadData
  238. * @param {Boolean} firstTime flag that determines whether the data has been loaded during the initialization.
  239. */
  240. 'afterLoadData',
  241. /**
  242. * Fired after a scroll event, which is identified as a momentum scroll (e.g. on an iPad).
  243. *
  244. * @event Hooks#afterMomentumScroll
  245. */
  246. 'afterMomentumScroll',
  247. /**
  248. * Fired after a `mousedown` event is triggered on the cell corner (the drag handle).
  249. *
  250. * @event Hooks#afterOnCellCornerMouseDown
  251. * @since 0.11
  252. * @param {Object} event `mousedown` event object.
  253. */
  254. 'afterOnCellCornerMouseDown',
  255. /**
  256. * Fired after a `dblclick` event is triggered on the cell corner (the drag handle).
  257. *
  258. * @event Hooks#afterOnCellCornerDblClick
  259. * @since 0.30.0
  260. * @param {Object} event `dblclick` event object.
  261. */
  262. 'afterOnCellCornerDblClick',
  263. /**
  264. * Callback fired after clicking on a cell or row/column header.
  265. * In case the row/column header was clicked, the index is negative.
  266. * For example clicking on the row header of cell (0, 0) results with `afterOnCellMouseDown` called
  267. * with coords `{row: 0, col: -1}`.
  268. *
  269. * @event Hooks#afterOnCellMouseDown
  270. * @since 0.11
  271. * @param {Object} event `mousedown` event object.
  272. * @param {Object} coords Coordinates object containing the row and column indexes of the clicked cell.
  273. * @param {Element} TD Cell's TD (or TH) element.
  274. */
  275. 'afterOnCellMouseDown',
  276. /**
  277. * Callback fired after hovering a cell or row/column header with the mouse cursor.
  278. * In case the row/column header was hovered, the index is negative.
  279. * For example, hovering over the row header of cell (0, 0) results with `afterOnCellMouseOver` called
  280. * with coords `{row: 0, col: -1}`.
  281. *
  282. * @event Hooks#afterOnCellMouseOver
  283. * @since 0.11
  284. * @param {Object} event `mouseover` event object.
  285. * @param {Object} coords Hovered cell's coordinate object.
  286. * @param {Element} TD Cell's TD (or TH) element.
  287. */
  288. 'afterOnCellMouseOver',
  289. /**
  290. * Callback fired after leaving a cell or row/column header with the mouse cursor.
  291. *
  292. * @event Hooks#afterOnCellMouseOver
  293. * @since 0.31.1
  294. * @param {Object} event `mouseout` event object.
  295. * @param {Object} coords Leaved cell's coordinate object.
  296. * @param {Element} TD Cell's TD (or TH) element.
  297. */
  298. 'afterOnCellMouseOut',
  299. /**
  300. * Callback is fired when one or more columns are removed.
  301. *
  302. * @event Hooks#afterRemoveCol
  303. * @param {Number} index Is an index of starter column.
  304. * @param {Number} amount Is an amount of removed columns.
  305. */
  306. 'afterRemoveCol',
  307. /**
  308. * Callback is fired when one or more rows are removed.
  309. *
  310. * @event Hooks#afterRemoveRow
  311. * @param {Number} index Is an index of starter row.
  312. * @param {Number} amount Is an amount of removed rows.
  313. */
  314. 'afterRemoveRow',
  315. /**
  316. * Callback fired after the Handsontable table is rendered.
  317. *
  318. * @event Hooks#afterRender
  319. * @param {Boolean} isForced Is `true` if rendering was triggered by a change of settings or data; or `false` if
  320. * rendering was triggered by scrolling or moving selection.
  321. */
  322. 'afterRender',
  323. /**
  324. * Fired before starting rendering the cell.
  325. *
  326. * @event Hooks#beforeRenderer
  327. * @since 0.24.2
  328. * @param {Element} TD Currently rendered cell's TD element.
  329. * @param {Number} row Row index.
  330. * @param {Number} col Column index.
  331. * @param {String|Number} prop Column property name or a column index, if datasource is an array of arrays.
  332. * @param {String} value Value of the rendered cell.
  333. * @param {Object} cellProperties Object containing the cell's properties.
  334. */
  335. 'beforeRenderer',
  336. /**
  337. * Fired after finishing rendering the cell (after the renderer finishes).
  338. *
  339. * @event Hooks#afterRenderer
  340. * @since 0.11.0
  341. * @param {Element} TD Currently rendered cell's TD element.
  342. * @param {Number} row Row index.
  343. * @param {Number} col Column index.
  344. * @param {String|Number} prop Column property name or a column index, if datasource is an array of arrays.
  345. * @param {String} value Value of the rendered cell.
  346. * @param {Object} cellProperties Object containing the cell's properties.
  347. */
  348. 'afterRenderer',
  349. /**
  350. * Fired after the horizontal scroll event.
  351. *
  352. * @event Hooks#afterScrollHorizontally
  353. * @since 0.11
  354. */
  355. 'afterScrollHorizontally',
  356. /**
  357. * Fired after the vertical scroll event.
  358. *
  359. * @event Hooks#afterScrollVertically
  360. * @since 0.11
  361. */
  362. 'afterScrollVertically',
  363. /**
  364. * Callback fired after one or more cells are selected (e.g. during mouse move).
  365. *
  366. * @event Hooks#afterSelection
  367. * @param {Number} r Selection start row index.
  368. * @param {Number} c Selection start column index.
  369. * @param {Number} r2 Selection end row index.
  370. * @param {Number} c2 Selection end column index.
  371. * @param {Object} preventScrolling Object with `value` property where its value change will be observed.
  372. * * @example
  373. * ```js
  374. * handsontable({
  375. * afterSelection: function (r, c, r2, c2, preventScrolling) {
  376. * // setting if prevent scrolling after selection
  377. *
  378. * preventScrolling.value = true;
  379. * }
  380. * })
  381. * ```
  382. */
  383. 'afterSelection',
  384. /**
  385. * Callback fired after one or more cells are selected. The `p` argument represents the source object property name instead of the column number.
  386. *
  387. * @event Hooks#afterSelectionByProp
  388. * @param {Number} r Selection start row index.
  389. * @param {String} p Selection start data source object property name.
  390. * @param {Number} r2 Selection end row index.
  391. * @param {String} p2 Selection end data source object property name.
  392. * @param {Object} preventScrolling Object with `value` property where its value change will be observed.
  393. * * @example
  394. * ```js
  395. * handsontable({
  396. * afterSelectionByProp: function (r, c, r2, c2, preventScrolling) {
  397. * // setting if prevent scrolling after selection
  398. *
  399. * preventScrolling.value = true;
  400. * }
  401. * })
  402. * ```
  403. */
  404. 'afterSelectionByProp',
  405. /**
  406. * Callback fired after one or more cells are selected (e.g. on mouse up).
  407. *
  408. * @event Hooks#afterSelectionEnd
  409. * @param {Number} r Selection start row index.
  410. * @param {Number} c Selection start column index.
  411. * @param {Number} r2 Selection end row index.
  412. * @param {Number} c2 Selection end column index.
  413. */
  414. 'afterSelectionEnd',
  415. /**
  416. * Callback fired after one or more cells are selected (e.g. on mouse up). The `p` argument represents the data source object
  417. * property name instead of the column number.
  418. *
  419. * @event Hooks#afterSelectionEndByProp
  420. * @param {Number} r Selection start row index.
  421. * @param {String} p Selection start data source object property index.
  422. * @param {Number} r2 Selection end row index.
  423. * @param {String} p2 Selection end data source object property index.
  424. */
  425. 'afterSelectionEndByProp',
  426. /**
  427. * Called after cell meta is changed.
  428. *
  429. * @event Hooks#afterSetCellMeta
  430. * @since 0.11.0
  431. * @param {Number} row Row index.
  432. * @param {Number} col Column index.
  433. * @param {String} key The updated meta key.
  434. * @param {*} value The updated meta value.
  435. */
  436. 'afterSetCellMeta',
  437. /**
  438. * Called after cell data was changed.
  439. *
  440. * @event Hooks#afterSetDataAtCell
  441. * @since 0.28.0
  442. * @param {Array} changes An array of changes in format `[[row, col, oldValue, value], ...]`.
  443. * @param {String} [source] String that identifies source of hook call
  444. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  445. */
  446. 'afterSetDataAtCell',
  447. /**
  448. * Called after cell data was changed.
  449. *
  450. * @event Hooks#afterSetDataAtRowProp
  451. * @since 0.28.0
  452. * @param {Array} changes An array of changes in format `[[row, prop, oldValue, value], ...]`.
  453. * @param {String} [source] String that identifies source of hook call
  454. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  455. */
  456. 'afterSetDataAtRowProp',
  457. /**
  458. * Fired after calling the `updateSettings` method.
  459. *
  460. * @event Hooks#afterUpdateSettings
  461. */
  462. 'afterUpdateSettings',
  463. /**
  464. * @description
  465. * A plugin hook executed after validator function, only if validator function is defined.
  466. * Validation result is the first parameter. This can be used to determinate if validation passed successfully or not.
  467. *
  468. * __Returning false from the callback will mark the cell as invalid.__
  469. *
  470. * @event Hooks#afterValidate
  471. * @since 0.9.5
  472. * @param {Boolean} isValid `true` if valid, `false` if not.
  473. * @param {*} value The value in question.
  474. * @param {Number} row Row index.
  475. * @param {String|Number} prop Property name / column index.
  476. * @param {String} [source] String that identifies source of hook call
  477. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  478. */
  479. 'afterValidate',
  480. /**
  481. * Fired before populating the data in the autofill feature.
  482. *
  483. * @event Hooks#beforeAutofill
  484. * @param {Object} start Object containing information about first filled cell: `{row: 2, col: 0}`.
  485. * @param {Object} end Object containing information about last filled cell: `{row: 4, col: 1}`.
  486. * @param {Array} data 2D array containing information about fill pattern: `[["1', "Ted"], ["1', "John"]]`.
  487. */
  488. 'beforeAutofill',
  489. /**
  490. * Fired before aligning the cell contents.
  491. *
  492. * @event Hooks#beforeCellAlignment
  493. * @param stateBefore
  494. * @param range
  495. * @param {String} type Type of the alignment - either `horizontal` or `vertical`
  496. * @param {String} alignmentClass String defining the alignment class added to the cell.
  497. * Possible values:
  498. * * `htLeft`,
  499. * * `htCenter`,
  500. * * `htRight`,
  501. * * `htJustify`
  502. * for horizontal alignment,
  503. *
  504. *
  505. * * `htTop`,
  506. * * `htMiddle`,
  507. * * `htBottom`
  508. * for vertical alignment.
  509. */
  510. 'beforeCellAlignment',
  511. /**
  512. * Callback fired before one or more cells is changed. Its main purpose is to alter changes silently before input.
  513. *
  514. * @event Hooks#beforeChange
  515. * @param {Array} changes 2D array containing information about each of the edited cells.
  516. * @param {String} [source] String that identifies source of hook call
  517. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  518. * @example
  519. * ```js
  520. * // To disregard a single change, set changes[i] to null or remove it from array using changes.splice(i, 1).
  521. * ...
  522. * new Handsontable(document.getElementById('example'), {
  523. * beforeChange: function(changes, source) {
  524. * // [[row, prop, oldVal, newVal], ...]
  525. * changes[0] = null;
  526. * }
  527. * });
  528. * ...
  529. *
  530. * // To alter a single change, overwrite the desired value to changes[i][3].
  531. * ...
  532. * new Handsontable(document.getElementById('example'), {
  533. * beforeChange: function(changes, source) {
  534. * // [[row, prop, oldVal, newVal], ...]
  535. * changes[0][3] = 10;
  536. * }
  537. * });
  538. * ...
  539. *
  540. * // To cancel all edit, return false from the callback or set array length to 0 (changes.length = 0).
  541. * ...
  542. * new Handsontable(document.getElementById('example'), {
  543. * beforeChange: function(changes, source) {
  544. * // [[row, prop, oldVal, newVal], ...]
  545. * return false;
  546. * }
  547. * });
  548. * ...
  549. * ```
  550. */
  551. 'beforeChange',
  552. /**
  553. * Fired right before rendering the changes.
  554. *
  555. * @event Hooks#beforeChangeRender
  556. * @since 0.11
  557. * @param {Array} changes Array in form of [row, prop, oldValue, newValue].
  558. * @param {String} [source] String that identifies source of hook call
  559. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  560. */
  561. 'beforeChangeRender',
  562. /**
  563. * Fired before drawing the borders.
  564. *
  565. * @event Hooks#beforeDrawBorders
  566. * @param {Array} corners Array specifying the current selection borders.
  567. * @param {String} borderClassName Specifies the border class name.
  568. */
  569. 'beforeDrawBorders',
  570. /**
  571. * Callback fired before getting cell settings.
  572. *
  573. * @event Hooks#beforeGetCellMeta
  574. * @param {Number} row Row index.
  575. * @param {Number} col Column index.
  576. * @param {Object} cellProperties Object containing the cell's properties.
  577. */
  578. 'beforeGetCellMeta',
  579. /**
  580. * @description
  581. * Callback fired before Handsontable instance is initiated.
  582. *
  583. * @event Hooks#beforeInit
  584. */
  585. 'beforeInit',
  586. /**
  587. * Callback fired before Walkontable instance is initiated.
  588. *
  589. * @since 0.11
  590. * @event Hooks#beforeInitWalkontable
  591. * @param {Object} walkontableConfig Walkontable configuration object.
  592. */
  593. 'beforeInitWalkontable',
  594. /**
  595. * Callback fired before keydown event is handled. It can be used to overwrite default key bindings.
  596. * Caution - in your `beforeKeyDown` handler you need to call `event.stopImmediatePropagation()` to prevent default key behavior.
  597. *
  598. * @event Hooks#beforeKeyDown
  599. * @since 0.9.0
  600. * @param {Event} event Original DOM event.
  601. */
  602. 'beforeKeyDown',
  603. /**
  604. * Fired after the user clicked a cell, but before all the calculations related with it.
  605. *
  606. * @event Hooks#beforeOnCellMouseDown
  607. * @param {Event} event The `mousedown` event object.
  608. * @param {CellCoords} coords CellCoords object containing the coordinates of the clicked cell.
  609. * @param {Element} TD TD element.
  610. */
  611. 'beforeOnCellMouseDown',
  612. /**
  613. * Fired after the user moved cursor over a cell, but before all the calculations related with it.
  614. *
  615. * @event Hooks#beforeOnCellMouseOver
  616. * @param {Event} event The `mouseover` event object.
  617. * @param {CellCoords} coords CellCoords object containing the coordinates of the clicked cell.
  618. * @param {Element} TD TD element.
  619. * @param {Object} blockCalculations Contain keys 'row' and 'column' with boolean value.
  620. */
  621. 'beforeOnCellMouseOver',
  622. /**
  623. * Fired after the user moved cursor out from a cell, but before all the calculations related with it.
  624. *
  625. * @event Hooks#beforeOnCellMouseOut
  626. * @since 0.31.1
  627. * @param {Event} event The `mouseout` event object.
  628. * @param {WalkontableCellCoords} coords WalkontableCellCoords object containing the coordinates of the leaved cell.
  629. * @param {Element} TD TD element.
  630. */
  631. 'beforeOnCellMouseOut',
  632. /**
  633. * Callback is fired when one or more columns are about to be removed.
  634. *
  635. * @event Hooks#beforeRemoveCol
  636. * @param {Number} index Index of starter column.
  637. * @param {Number} amount Amount of columns to be removed.
  638. * @param {Array} [logicalCols] Consists of logical indexes of processed columns.
  639. */
  640. 'beforeRemoveCol',
  641. /**
  642. * Callback is fired when one or more rows are about to be removed.
  643. *
  644. * @event Hooks#beforeRemoveRow
  645. * @param {Number} index Index of starter column.
  646. * @param {Number} amount Amount of columns to be removed.
  647. * @param {Array} [logicalRows] Consists of logical indexes of processed rows.
  648. */
  649. 'beforeRemoveRow',
  650. /**
  651. * Callback fired before Handsontable table is rendered.
  652. *
  653. * @event Hooks#beforeRender
  654. * @param {Boolean} isForced If `true` rendering was triggered by a change of settings or data; or `false` if
  655. * rendering was triggered by scrolling or moving selection.
  656. */
  657. 'beforeRender',
  658. /**
  659. * Callback fired before setting range is started.
  660. *
  661. * @event Hooks#beforeSetRangeStart
  662. * @param {Array} coords CellCoords array.
  663. */
  664. 'beforeSetRangeStart',
  665. /**
  666. * Callback fired before setting range is ended.
  667. *
  668. * @event Hooks#beforeSetRangeEnd
  669. * @param {Array} coords CellCoords array.
  670. */
  671. 'beforeSetRangeEnd',
  672. /**
  673. * Fired before the logic of handling a touch scroll, when user started scrolling on a touch-enabled device.
  674. *
  675. * @event Hooks#beforeTouchScroll
  676. */
  677. 'beforeTouchScroll',
  678. /**
  679. * @description
  680. * A plugin hook executed before validator function, only if validator function is defined.
  681. * This can be used to manipulate the value of changed cell before it is applied to the validator function.
  682. *
  683. * __Notice:__ this will not affect values of changes. This will change value ONLY for validation!
  684. *
  685. * @event Hooks#beforeValidate
  686. * @since 0.9.5
  687. * @param {*} value Value of the cell.
  688. * @param {Number} row Row index.
  689. * @param {String|Number} prop Property name / column index.
  690. * @param {String} [source] String that identifies source of hook call
  691. * ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
  692. */
  693. 'beforeValidate',
  694. /**
  695. * Callback fired before cell value is rendered into the DOM (through renderer function).
  696. *
  697. * @event Hooks#beforeValueRender
  698. * @since 0.29.0
  699. * @param {*} value Cell value to render.
  700. */
  701. 'beforeValueRender',
  702. /**
  703. * Callback fired after Handsontable instance is constructed (via `new` operator).
  704. *
  705. * @event Hooks#construct
  706. * @since 0.16.1
  707. */
  708. 'construct',
  709. /**
  710. * Callback fired after Handsontable instance is initiated but before table is rendered.
  711. *
  712. * @event Hooks#init
  713. * @since 0.16.1
  714. */
  715. 'init',
  716. /**
  717. * Fired when a column index is about to be modified by a callback function.
  718. *
  719. * @event Hooks#modifyCol
  720. * @since 0.11
  721. * @param {Number} col Column index.
  722. */
  723. 'modifyCol',
  724. /**
  725. * Fired when a column index is about to be de-modified by a callback function.
  726. *
  727. * @event Hooks#unmodifyCol
  728. * @since 0.23.0
  729. * @param {Number} col Column index.
  730. */
  731. 'unmodifyCol',
  732. /**
  733. * Fired when a row index is about to be de-modified by a callback function.
  734. *
  735. * @event Hooks#unmodifyRow
  736. * @since 0.26.2
  737. * @param {Number} row Logical row index.
  738. */
  739. 'unmodifyRow',
  740. /**
  741. * Fired when a column header index is about to be modified by a callback function.
  742. *
  743. * @event Hooks#modifyColHeader
  744. * @since 0.20.0
  745. * @param {Number} column Column header index.
  746. */
  747. 'modifyColHeader',
  748. /**
  749. * Fired when a column width is about to be modified by a callback function.
  750. *
  751. * @event Hooks#modifyColWidth
  752. * @since 0.11
  753. * @param {Number} width Current column width.
  754. * @param {Number} col Column index.
  755. */
  756. 'modifyColWidth',
  757. /**
  758. * Fired when a row index is about to be modified by a callback function.
  759. *
  760. * @event Hooks#modifyRow
  761. * @since 0.11
  762. * @param {Number} row Row index.
  763. */
  764. 'modifyRow',
  765. /**
  766. * Fired when a row header index is about to be modified by a callback function.
  767. *
  768. * @event Hooks#modifyRowHeader
  769. * @since 0.20.0
  770. * @param {Number} row Row header index.
  771. */
  772. 'modifyRowHeader',
  773. /**
  774. * Fired when a row height is about to be modified by a callback function.
  775. *
  776. * @event Hooks#modifyRowHeight
  777. * @since 0.11.0
  778. * @param {Number} height Row height.
  779. * @param {Number} row Row index.
  780. */
  781. 'modifyRowHeight',
  782. /**
  783. * Fired when a data was retrieved or modified.
  784. *
  785. * @event Hooks#modifyData
  786. * @since 0.28.0
  787. * @param {Number} row Row height.
  788. * @param {Number} column Column index.
  789. * @param {Object} valueHolder Object which contains original value which can be modified by overwriting `.value` property.
  790. * @param {String} ioMode String which indicates for what operation hook is fired (`get` or `set`).
  791. */
  792. 'modifyData',
  793. /**
  794. * Fired when a data was retrieved or modified.
  795. *
  796. * @event Hooks#modifyRowSourceData
  797. * @since 0.28.0
  798. * @param {Number} row Row logical index.
  799. */
  800. 'modifyRowData',
  801. /**
  802. * Fired after loading data using the Persistent State plugin.
  803. *
  804. * @event Hooks#persistentStateLoad
  805. * @param {String} key Key string.
  806. * @param {Object} valuePlaceholder Object containing the loaded data.
  807. */
  808. 'persistentStateLoad',
  809. /**
  810. * Fired after resetting data using the Persistent State plugin.
  811. *
  812. * @event Hooks#persistentStateReset
  813. * @param {String} key Key string.
  814. */
  815. 'persistentStateReset',
  816. /**
  817. * Fired after resetting data using the Persistent State plugin.
  818. *
  819. * @event Hooks#persistentStateSave
  820. * @param {String} key Key string.
  821. * @param {Mixed} value Value to save.
  822. */
  823. 'persistentStateSave',
  824. /**
  825. * Fired before sorting the column. If you return `false` value then sorting will be not applied by
  826. * Handsontable (useful for server-side sorting).
  827. *
  828. * @event Hooks#beforeColumnSort
  829. * @param {Number} column Sorted column index.
  830. * @param {Boolean} order Soring order where:
  831. * * `true` means ascending order,
  832. * * `false` means descending order,
  833. * * `undefined` means original order.
  834. */
  835. 'beforeColumnSort',
  836. /**
  837. * Fired after sorting the column.
  838. *
  839. * @event Hooks#afterColumnSort
  840. * @param {Number} column Sorted column index.
  841. * @param {Boolean} order Soring order where:
  842. * * `true` means ascending order
  843. * * `false` means descending order
  844. * * `undefined` means original order
  845. */
  846. 'afterColumnSort',
  847. /**
  848. * @description
  849. * Fired after setting range of autofill.
  850. * Both arguments are provided in the following format:
  851. * ```js
  852. * [startRow, startColumn, endRow, endColumn]
  853. * ```
  854. *
  855. * @event Hooks#modifyAutofillRange
  856. * @param {Array} startArea Array of coordinates of the starting point for the drag-down operation.
  857. * @param {Array} entireArea Array of coordinates of the entire area of the drag-down operation.
  858. */
  859. 'modifyAutofillRange',
  860. /**
  861. * Fired to allow modifying the copyable range with a callback function.
  862. *
  863. * @since 0.19.0
  864. * @event Hooks#modifyCopyableRange
  865. * @param {Array} copyableRanges Array of objects defining copyable cells.
  866. */
  867. 'modifyCopyableRange',
  868. /**
  869. * Called before copying the values into clipboard and before clearing values of the selected cells.
  870. *
  871. * @event Hooks#beforeCut
  872. * @since 0.31.1
  873. * @param {Array} data An array of arrays which contains data to cut.
  874. * @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
  875. * which will be cut out.
  876. * @returns {*} If returns `false` then operation of the cutting out is cancelled.
  877. *
  878. * @example
  879. * ```js
  880. * // To disregard a single row, remove it from array using data.splice(i, 1).
  881. * ...
  882. * new Handsontable(document.getElementById('example'), {
  883. * beforeCut: function(data, coords) {
  884. * // data -> [[1, 2, 3], [4, 5, 6]]
  885. * data.splice(0, 1);
  886. * // data -> [[4, 5, 6]]
  887. * // coords -> [{startRow: 0, startCol: 0, endRow: 1, endCol: 2}]
  888. * }
  889. * });
  890. * ...
  891. *
  892. * // To cancel cutting out, return false from the callback.
  893. * ...
  894. * new Handsontable(document.getElementById('example'), {
  895. * beforeCut: function(data, coords) {
  896. * return false;
  897. * }
  898. * });
  899. * ...
  900. * ```
  901. */
  902. 'beforeCut',
  903. /**
  904. * Fired after data are cutted out from the table.
  905. *
  906. * @event Hooks#afterCut
  907. * @since 0.31.1
  908. * @param {Array} data An array of arrays which contains the cutted out data.
  909. * @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
  910. * which was cut out.
  911. */
  912. 'afterCut',
  913. /**
  914. * Fired before values are copied into clipboard.
  915. *
  916. * @event Hooks#beforeCopy
  917. * @since 0.31.1
  918. * @param {Array} data An array of arrays which contains data to copied.
  919. * @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
  920. * which will copied.
  921. * @returns {*} If returns `false` then copying is cancelled.
  922. *
  923. * @example
  924. * ```js
  925. * // To disregard a single row, remove it from array using data.splice(i, 1).
  926. * ...
  927. * new Handsontable(document.getElementById('example'), {
  928. * beforeCopy: function(data, coords) {
  929. * // data -> [[1, 2, 3], [4, 5, 6]]
  930. * data.splice(0, 1);
  931. * // data -> [[4, 5, 6]]
  932. * // coords -> [{startRow: 0, startCol: 0, endRow: 1, endCol: 2}]
  933. * }
  934. * });
  935. * ...
  936. *
  937. * // To cancel copying, return false from the callback.
  938. * ...
  939. * new Handsontable(document.getElementById('example'), {
  940. * beforeCopy: function(data, coords) {
  941. * return false;
  942. * }
  943. * });
  944. * ...
  945. * ```
  946. */
  947. 'beforeCopy',
  948. /**
  949. * Fired after data are pasted into table.
  950. *
  951. * @event Hooks#afterCopy
  952. * @since 0.31.1
  953. * @param {Array} data An array of arrays which contains the copied data.
  954. * @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
  955. * which was copied.
  956. */
  957. 'afterCopy',
  958. /**
  959. * Fired before values are pasted into table.
  960. *
  961. * @event Hooks#beforePaste
  962. * @since 0.31.1
  963. * @param {Array} data An array of arrays which contains data to paste.
  964. * @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
  965. * where changes will be inserted.
  966. * @returns {*} If returns `false` then pasting is cancelled.
  967. *
  968. * @example
  969. * ```js
  970. * // To disregard a single row, remove it from array using data.splice(i, 1).
  971. * ...
  972. * new Handsontable(document.getElementById('example'), {
  973. * beforePaste: function(data, coords) {
  974. * // data -> [[1, 2, 3], [4, 5, 6]]
  975. * data.splice(0, 1);
  976. * // data -> [[4, 5, 6]]
  977. * // coords -> [{startRow: 0, startCol: 0, endRow: 1, endCol: 2}]
  978. * }
  979. * });
  980. * ...
  981. *
  982. * // To cancel pasting, return false from the callback.
  983. * ...
  984. * new Handsontable(document.getElementById('example'), {
  985. * beforePaste: function(data, coords) {
  986. * return false;
  987. * }
  988. * });
  989. * ...
  990. * ```
  991. */
  992. 'beforePaste',
  993. /**
  994. * Fired after values are pasted into table.
  995. *
  996. * @event Hooks#afterePaste
  997. * @since 0.31.1
  998. * @param {Array} data An array of arrays which contains the pasted data.
  999. * @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
  1000. * where changes was inserted.
  1001. */
  1002. 'afterPaste',
  1003. /**
  1004. * Fired before change order of the logical indexes.
  1005. *
  1006. * @event Hooks#beforeColumnMove
  1007. * @param {Array} columns Array of visual column indexes to be moved.
  1008. * @param {Number} target Visual column index being a target for moved columns.
  1009. */
  1010. 'beforeColumnMove',
  1011. /**
  1012. * Fired after change order of the logical indexes.
  1013. *
  1014. * @event Hooks#afterColumnMove
  1015. * @param {Array} columns Array of visual column indexes that were moved.
  1016. * @param {Number} target Visual column index being a target for moved columns.
  1017. */
  1018. 'afterColumnMove',
  1019. /**
  1020. * Fired before change order of the logical indexes.
  1021. *
  1022. * @event Hooks#beforeRowMove
  1023. * @param {Array} rows Array of visual row indexes to be moved.
  1024. * @param {Number} target Visual row index being a target for moved rows.
  1025. */
  1026. 'beforeRowMove',
  1027. /**
  1028. * Fired after change order of the logical indexes.
  1029. *
  1030. * @event Hooks#afterRowMove
  1031. * @param {Array} rows Array of visual row indexes that were moved.
  1032. * @param {Number} target Visual row index being a target for moved rows.
  1033. */
  1034. 'afterRowMove',
  1035. /**
  1036. * Fired before rendering the table with modified column sizes.
  1037. *
  1038. * @event Hooks#beforeColumnResize
  1039. * @param {Number} currentColumn Index of the resized column.
  1040. * @param {Number} newSize Calculated new column width.
  1041. * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
  1042. * @returns {Number} Returns a new column size or `undefined`, if column size should be calculated automatically.
  1043. */
  1044. 'beforeColumnResize',
  1045. /**
  1046. * Fired after rendering the table with modified column sizes.
  1047. *
  1048. * @event Hooks#afterColumnResize
  1049. * @param {Number} currentColumn Index of the resized column.
  1050. * @param {Number} newSize Calculated new column width.
  1051. * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
  1052. */
  1053. 'afterColumnResize',
  1054. /**
  1055. * Fired before rendering the table with modified row sizes.
  1056. *
  1057. * @event Hooks#beforeRowResize
  1058. * @param {Number} currentRow Index of the resized row.
  1059. * @param {Number} newSize Calculated new row height.
  1060. * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
  1061. * @returns {Number} Returns the new row size or `undefined` if row size should be calculated automatically.
  1062. */
  1063. 'beforeRowResize',
  1064. /**
  1065. * Fired after rendering the table with modified row sizes.
  1066. *
  1067. * @event Hooks#afterRowResize
  1068. * @param {Number} currentRow Index of the resized row.
  1069. * @param {Number} newSize Calculated new row height.
  1070. * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
  1071. */
  1072. 'afterRowResize',
  1073. /**
  1074. * Fired after getting the column header renderers.
  1075. *
  1076. * @event Hooks#afterGetColumnHeaderRenderers
  1077. * @param {Array} array Array of the column header renderers.
  1078. */
  1079. 'afterGetColumnHeaderRenderers',
  1080. /**
  1081. * Fired after getting the row header renderers.
  1082. *
  1083. * @event Hooks#afterGetRowHeaderRenderers
  1084. * @param {Array} array Array of the row header renderers.
  1085. */
  1086. 'afterGetRowHeaderRenderers',
  1087. /**
  1088. * Fired before applying stretched column width to column.
  1089. *
  1090. * @event Hooks#beforeStretchingColumnWidth
  1091. * @param {Number} stretchedWidth Calculated width.
  1092. * @param {Number} column Column index.
  1093. * @returns {Number} Returns new width which will be applied to the column element.
  1094. */
  1095. 'beforeStretchingColumnWidth',
  1096. /**
  1097. * Fired before applying [filtering]{@link http://docs.handsontable.com/pro/demo-filtering.html}.
  1098. *
  1099. * @pro
  1100. * @event Hooks#beforeFilter
  1101. * @param {Array} formulasStack An array of objects with added formulas.
  1102. * @returns {Boolean} If hook returns `false` value then filtering won't be applied on the UI side (server-side filtering).
  1103. */
  1104. 'beforeFilter',
  1105. /**
  1106. * Fired after applying [filtering]{@link http://docs.handsontable.com/pro/demo-filtering.html}.
  1107. *
  1108. * @pro
  1109. * @event Hooks#afterFilter
  1110. * @param {Array} formulasStack An array of objects with added formulas.
  1111. */
  1112. 'afterFilter',
  1113. /**
  1114. * Used to modify the column header height.
  1115. *
  1116. * @event Hooks#modifyColumnHeaderHeight
  1117. * @since 0.25.0
  1118. * @param {Number} col Column index.
  1119. */
  1120. 'modifyColumnHeaderHeight',
  1121. /**
  1122. * Fired before the undo action. Contains information about the action that is being undone.
  1123. *
  1124. * @event Hooks#beforeUndo
  1125. * @since 0.26.2
  1126. * @param {Object} action The action object. Contains information about the action being undone. The `actionType`
  1127. * property of the object specifies the type of the action in a String format. (e.g. `'remove_row'`).
  1128. */
  1129. 'beforeUndo',
  1130. /**
  1131. * Fired after the undo action. Contains information about the action that is being undone.
  1132. *
  1133. * @event Hooks#afterUndo
  1134. * @since 0.26.2
  1135. * @param {Object} action The action object. Contains information about the action being undone. The `actionType`
  1136. * property of the object specifies the type of the action in a String format. (e.g. `'remove_row'`).
  1137. */
  1138. 'afterUndo',
  1139. /**
  1140. * Fired before the redo action. Contains information about the action that is being redone.
  1141. *
  1142. * @event Hooks#beforeRedo
  1143. * @since 0.26.2
  1144. * @param {Object} action The action object. Contains information about the action being redone. The `actionType`
  1145. * property of the object specifies the type of the action in a String format. (e.g. `'remove_row'`).
  1146. */
  1147. 'beforeRedo',
  1148. /**
  1149. * Fired after the redo action. Contains information about the action that is being redone.
  1150. *
  1151. * @event Hooks#afterRedo
  1152. * @since 0.26.2
  1153. * @param {Object} action The action object. Contains information about the action being redone. The `actionType`
  1154. * property of the object specifies the type of the action in a String format. (e.g. `'remove_row'`).
  1155. */
  1156. 'afterRedo',
  1157. /**
  1158. * Used to modify the row header width.
  1159. *
  1160. * @event Hooks#modifyRowHeaderWidth
  1161. * @param {Number} rowHeaderWidth Row header width.
  1162. */
  1163. 'modifyRowHeaderWidth',
  1164. /**
  1165. * Fired from the `populateFromArray` method during the `autofill` process. Fired for each "autofilled" cell individually.
  1166. *
  1167. * @event Hooks#beforeAutofillInsidePopulate
  1168. * @param {Object} index Object containing `row` and `col` properties, defining the number of rows/columns from the initial cell of the autofill.
  1169. * @param {String} direction Declares the direction of the autofill. Possible values: `up`, `down`, `left`, `right`.
  1170. * @param {Array} input Array of arrays. Contains an array of rows with data being used in the autofill.
  1171. * @param {Array} deltas The deltas array passed to the `populateFromArray` method.
  1172. */
  1173. 'beforeAutofillInsidePopulate',
  1174. /**
  1175. * Fired when the start of the selection is being modified. (e.g. moving the selection with the arrow keys).
  1176. *
  1177. * @event Hooks#modifyTransformStart
  1178. * @param {CellCoords} delta Cell coords object declaring the delta of the new selection relative to the previous one.
  1179. */
  1180. 'modifyTransformStart',
  1181. /**
  1182. * Fired when the end of the selection is being modified. (e.g. moving the selection with the arrow keys).
  1183. *
  1184. * @event Hooks#modifyTransformEnd
  1185. * @param {CellCoords} delta Cell coords object declaring the delta of the new selection relative to the previous one.
  1186. */
  1187. 'modifyTransformEnd',
  1188. /**
  1189. * Fired after the start of the selection is being modified. (e.g. moving the selection with the arrow keys).
  1190. *
  1191. * @event Hooks#afterModifyTransformStart
  1192. * @param {CellCoords} coords Coords of the freshly selected cell.
  1193. * @param {Number} rowTransformDir `-1` if trying to select a cell with a negative row index. `0` otherwise.
  1194. * @param {Number} colTransformDir `-1` if trying to select a cell with a negative column index. `0` otherwise.
  1195. */
  1196. 'afterModifyTransformStart',
  1197. /**
  1198. * Fired after the end of the selection is being modified. (e.g. moving the selection with the arrow keys).
  1199. *
  1200. * @event Hooks#afterModifyTransformEnd
  1201. * @param {CellCoords} coords Coords of the freshly selected cell.
  1202. * @param {Number} rowTransformDir `-1` if trying to select a cell with a negative row index. `0` otherwise.
  1203. * @param {Number} colTransformDir `-1` if trying to select a cell with a negative column index. `0` otherwise.
  1204. */
  1205. 'afterModifyTransformEnd',
  1206. /**
  1207. * Fired before rendering a cell value.
  1208. *
  1209. * @event Hooks#beforeValueRender
  1210. * @param {Mixed} value The rendered value.
  1211. */
  1212. 'beforeValueRender',
  1213. /**
  1214. * Fired inside the `viewportRowCalculatorOverride` method. Allows modifying the row calculator parameters.
  1215. *
  1216. * @event Hooks#afterViewportRowCalculatorOverride
  1217. * @param {Object} calc The row calculator.
  1218. */
  1219. 'afterViewportRowCalculatorOverride',
  1220. /**
  1221. * Fired inside the `viewportColumnCalculatorOverride` method. Allows modifying the row calculator parameters.
  1222. *
  1223. * @event Hooks#afterViewportColumnCalculatorOverride
  1224. * @param {Object} calc The row calculator.
  1225. */
  1226. 'afterViewportColumnCalculatorOverride',
  1227. /**
  1228. * Fired after initializing all the plugins.
  1229. *
  1230. * @event Hooks#afterPluginsInitialized
  1231. */
  1232. 'afterPluginsInitialized',
  1233. /**
  1234. * Used when saving/loading the manual row heights state.
  1235. *
  1236. * @event Hooks#manualRowHeights
  1237. * @param {Array} state The current manual row heights state.
  1238. */
  1239. 'manualRowHeights',
  1240. /**
  1241. * Used to skip the length cache calculation for a defined period of time.
  1242. *
  1243. * @event Hooks#skipLengthCache
  1244. * @param {Number} delay The delay in milliseconds.
  1245. */
  1246. 'skipLengthCache',
  1247. /**
  1248. * Fired after trimming rows in the TrimRows plugin.
  1249. *
  1250. * @pro
  1251. * @event Hooks#afterTrimRow
  1252. * @param {Array} rows Indexes of trimmed rows.
  1253. */
  1254. 'afterTrimRow',
  1255. /**
  1256. * Fired after untrimming rows in the TrimRows plugin.
  1257. *
  1258. * @pro
  1259. * @event Hooks#afterUntrimRow
  1260. * @param {Array} rows Indexes of untrimmed rows.
  1261. */
  1262. 'afterUntrimRow',
  1263. /**
  1264. * Fired after opening the dropdown menu.
  1265. *
  1266. * @pro
  1267. * @event Hooks#afterDropdownMenuShow
  1268. * @param {DropdownMenu} instance The DropdownMenu instance.
  1269. */
  1270. 'afterDropdownMenuShow',
  1271. /**
  1272. * Fired after hiding the dropdown menu.
  1273. *
  1274. * @pro
  1275. * @event Hooks#afterDropdownMenuHide
  1276. * @param {DropdownMenu} instance The DropdownMenu instance.
  1277. */
  1278. 'afterDropdownMenuHide',
  1279. /**
  1280. * Used to check whether the provided row index is hidden.
  1281. *
  1282. * @pro
  1283. * @event Hooks#hiddenRow
  1284. * @param {Number} row The row index in question.
  1285. */
  1286. 'hiddenRow',
  1287. /**
  1288. * Used to check whether the provided column index is hidden.
  1289. *
  1290. * @pro
  1291. * @event Hooks#hiddenColumn
  1292. * @param {Number} column The column index in question.
  1293. */
  1294. 'hiddenColumn',
  1295. /**
  1296. * Fired before adding a children to the NestedRows structure.
  1297. *
  1298. * @pro
  1299. * @event Hooks#beforeAddChild
  1300. * @param {Object} parent The parent object.
  1301. * @param {Object|undefined} element The element added as a child. If `undefined`, a blank child was added.
  1302. * @param {Number|undefined} index The index within the parent where the new child was added. If `undefined`, the element was added as the last child.
  1303. */
  1304. 'beforeAddChild',
  1305. /**
  1306. * Fired after adding a children to the NestedRows structure.
  1307. *
  1308. * @pro
  1309. * @event Hooks#afterAddChild
  1310. * @param {Object} parent The parent object.
  1311. * @param {Object|undefined} element The element added as a child. If `undefined`, a blank child was added.
  1312. * @param {Number|undefined} index The index within the parent where the new child was added. If `undefined`, the element was added as the last child.
  1313. */
  1314. 'afterAddChild',
  1315. /**
  1316. * Fired before detaching a child from its parent in the NestedRows plugin.
  1317. *
  1318. * @pro
  1319. * @event Hooks#beforeDetachChild
  1320. * @param {Object} parent An object representing the parent from which the element is to be detached.
  1321. * @param {Object} element The detached element.
  1322. */
  1323. 'beforeDetachChild',
  1324. /**
  1325. * Fired after detaching a child from its parent in the NestedRows plugin.
  1326. *
  1327. * @pro
  1328. * @event Hooks#afterDetachChild
  1329. * @param {Object} parent An object representing the parent from which the element was detached.
  1330. * @param {Object} element The detached element.
  1331. */
  1332. 'afterDetachChild',
  1333. /**
  1334. * Fired after the editor is opened and rendered.
  1335. *
  1336. * @event Hooks#afterBeginEditing
  1337. * @param {Number} row Row index of the edited cell.
  1338. * @param {Number} column Column index of the edited cell.
  1339. */
  1340. 'afterBeginEditing'
  1341. ];
  1342. class Hooks {
  1343. static getSingleton() {
  1344. return globalSingleton;
  1345. }
  1346. /**
  1347. *
  1348. */
  1349. constructor() {
  1350. this.globalBucket = this.createEmptyBucket();
  1351. }
  1352. /**
  1353. * Returns a new object with empty handlers related to every registered hook name.
  1354. *
  1355. * @returns {Object} The empty bucket object.
  1356. *
  1357. * @example
  1358. * ```js
  1359. * Handsontable.hooks.createEmptyBucket();
  1360. * // Results:
  1361. * {
  1362. * ...
  1363. * afterCreateCol: [],
  1364. * afterCreateRow: [],
  1365. * beforeInit: [],
  1366. * ...
  1367. * }
  1368. * ```
  1369. */
  1370. createEmptyBucket() {
  1371. const bucket = Object.create(null);
  1372. arrayEach(REGISTERED_HOOKS, (hook) => (bucket[hook] = []));
  1373. return bucket;
  1374. }
  1375. /**
  1376. * Get hook bucket based on the context of the object or if argument is `undefined`, get the global hook bucket.
  1377. *
  1378. * @param {Object} [context=null] A Handsontable instance.
  1379. * @returns {Object} Returns a global or Handsontable instance bucket.
  1380. */
  1381. getBucket(context = null) {
  1382. if (context) {
  1383. if (!context.pluginHookBucket) {
  1384. context.pluginHookBucket = this.createEmptyBucket();
  1385. }
  1386. return context.pluginHookBucket;
  1387. }
  1388. return this.globalBucket;
  1389. }
  1390. /**
  1391. * Adds a listener (globally or locally) to a specified hook name.
  1392. * If the `context` parameter is provided, the hook will be added only to the instance it references.
  1393. * Otherwise, the callback will be used everytime the hook fires on any Handsontable instance.
  1394. * You can provide an array of callback functions as the `callback` argument, this way they will all be fired
  1395. * once the hook is triggered.
  1396. *
  1397. * @see Core#addHook
  1398. * @param {String} key Hook name.
  1399. * @param {Function|Array} callback Callback function or an array of functions.
  1400. * @param {Object} [context=null] The context for the hook callback to be added - a Handsontable instance or leave empty.
  1401. * @returns {Hooks} Instance of Hooks.
  1402. *
  1403. * @example
  1404. * ```js
  1405. * // single callback, added locally
  1406. * Handsontable.hooks.add('beforeInit', myCallback, hotInstance);
  1407. *
  1408. * // single callback, added globally
  1409. * Handsontable.hooks.add('beforeInit', myCallback);
  1410. *
  1411. * // multiple callbacks, added locally
  1412. * Handsontable.hooks.add('beforeInit', [myCallback, anotherCallback], hotInstance);
  1413. *
  1414. * // multiple callbacks, added globally
  1415. * Handsontable.hooks.add('beforeInit', [myCallback, anotherCallback]);
  1416. * ```
  1417. */
  1418. add(key, callback, context = null) {
  1419. if (Array.isArray(callback)) {
  1420. arrayEach(callback, (c) => this.add(key, c, context));
  1421. } else {
  1422. const bucket = this.getBucket(context);
  1423. if (typeof bucket[key] === 'undefined') {
  1424. this.register(key);
  1425. bucket[key] = [];
  1426. }
  1427. callback.skip = false;
  1428. if (bucket[key].indexOf(callback) === -1) {
  1429. // only add a hook if it has not already been added (adding the same hook twice is now silently ignored)
  1430. let foundInitialHook = false;
  1431. if (callback.initialHook) {
  1432. arrayEach(bucket[key], (cb, i) => {
  1433. if (cb.initialHook) {
  1434. bucket[key][i] = callback;
  1435. foundInitialHook = true;
  1436. return false;
  1437. }
  1438. });
  1439. }
  1440. if (!foundInitialHook) {
  1441. bucket[key].push(callback);
  1442. }
  1443. }
  1444. }
  1445. return this;
  1446. }
  1447. /**
  1448. * Adds a listener to a specified hook. After the hook runs this listener will be automatically removed from the bucket.
  1449. *
  1450. * @see Core#addHookOnce
  1451. * @param {String} key Hook/Event name.
  1452. * @param {Function|Array} callback Callback function.
  1453. * @param {Object} [context=null] A Handsontable instance.
  1454. *
  1455. * @example
  1456. * ```js
  1457. * Handsontable.hooks.once('beforeInit', myCallback, hotInstance);
  1458. * ```
  1459. */
  1460. once(key, callback, context = null) {
  1461. if (Array.isArray(callback)) {
  1462. arrayEach(callback, (c) => this.once(key, c, context));
  1463. } else {
  1464. callback.runOnce = true;
  1465. this.add(key, callback, context);
  1466. }
  1467. }
  1468. /**
  1469. * Removes a listener from a hook with a given name. If the `context` argument is provided, it removes a listener from a local hook assigned to the given Handsontable instance.
  1470. *
  1471. * @see Core#removeHook
  1472. * @param {String} key Hook/Event name.
  1473. * @param {Function} callback Callback function (needs the be the function that was previously added to the hook).
  1474. * @param {Object} [context=null] Handsontable instance.
  1475. * @return {Boolean} Returns `true` if hook was removed, `false` otherwise.
  1476. *
  1477. * @example
  1478. * ```js
  1479. * Handsontable.hooks.remove('beforeInit', myCallback);
  1480. * ```
  1481. */
  1482. remove(key, callback, context = null) {
  1483. let bucket = this.getBucket(context);
  1484. if (typeof bucket[key] !== 'undefined') {
  1485. if (bucket[key].indexOf(callback) >= 0) {
  1486. callback.skip = true;
  1487. return true;
  1488. }
  1489. }
  1490. return false;
  1491. }
  1492. /**
  1493. * Checks whether there are any registered listeners for the provided hook name.
  1494. * If the `context` parameter is provided, it only checks for listeners assigned to the given Handsontable instance.
  1495. *
  1496. * @param {String} key Hook name.
  1497. * @param {Object} [context=null] A Handsontable instance.
  1498. * @returns {Boolean} `true` for success, `false` otherwise.
  1499. */
  1500. has(key, context = null) {
  1501. let bucket = this.getBucket(context);
  1502. return !!(bucket[key] !== void 0 && bucket[key].length);
  1503. }
  1504. /**
  1505. * Runs all local and global callbacks assigned to the hook identified by the `key` parameter.
  1506. * It returns either a return value from the last called callback or the first parameter (`p1`) passed to the `run` function.
  1507. *
  1508. * @see Core#runHooks
  1509. * @param {Object} context Handsontable instance.
  1510. * @param {String} key Hook/Event name.
  1511. * @param {*} [p1] Parameter to be passed as an argument to the callback function.
  1512. * @param {*} [p2] Parameter to be passed as an argument to the callback function.
  1513. * @param {*} [p3] Parameter to be passed as an argument to the callback function.
  1514. * @param {*} [p4] Parameter to be passed as an argument to the callback function.
  1515. * @param {*} [p5] Parameter to be passed as an argument to the callback function.
  1516. * @param {*} [p6] Parameter to be passed as an argument to the callback function.
  1517. * @returns {*} Either a return value from the last called callback or `p1`.
  1518. *
  1519. * @example
  1520. * ```js
  1521. * Handsontable.hooks.run(hot, 'beforeInit');
  1522. * ```
  1523. */
  1524. run(context, key, p1, p2, p3, p4, p5, p6) {
  1525. {
  1526. const globalHandlers = this.globalBucket[key];
  1527. let index = -1;
  1528. let length = globalHandlers ? globalHandlers.length : 0;
  1529. if (length) {
  1530. // Do not optimise this loop with arrayEach or arrow function! If you do You'll decrease perf because of GC.
  1531. while (++index < length) {
  1532. if (!globalHandlers[index] || globalHandlers[index].skip) {
  1533. /* eslint-disable no-continue */
  1534. continue;
  1535. }
  1536. // performance considerations - http://jsperf.com/call-vs-apply-for-a-plugin-architecture
  1537. let res = globalHandlers[index].call(context, p1, p2, p3, p4, p5, p6);
  1538. if (res !== void 0) {
  1539. p1 = res;
  1540. }
  1541. if (globalHandlers[index] && globalHandlers[index].runOnce) {
  1542. this.remove(key, globalHandlers[index]);
  1543. }
  1544. }
  1545. }
  1546. }
  1547. {
  1548. const localHandlers = this.getBucket(context)[key];
  1549. let index = -1;
  1550. let length = localHandlers ? localHandlers.length : 0;
  1551. if (length) {
  1552. // Do not optimise this loop with arrayEach or arrow function! If you do You'll decrease perf because of GC.
  1553. while (++index < length) {
  1554. if (!localHandlers[index] || localHandlers[index].skip) {
  1555. /* eslint-disable no-continue */
  1556. continue;
  1557. }
  1558. // performance considerations - http://jsperf.com/call-vs-apply-for-a-plugin-architecture
  1559. let res = localHandlers[index].call(context, p1, p2, p3, p4, p5, p6);
  1560. if (res !== void 0) {
  1561. p1 = res;
  1562. }
  1563. if (localHandlers[index] && localHandlers[index].runOnce) {
  1564. this.remove(key, localHandlers[index], context);
  1565. }
  1566. }
  1567. }
  1568. }
  1569. return p1;
  1570. }
  1571. /**
  1572. * Destroy all listeners connected to the context. If no context is provided, the global listeners will be destroyed.
  1573. *
  1574. * @param {Object} [context=null] A Handsontable instance.
  1575. * @example
  1576. * ```js
  1577. * // destroy the global listeners
  1578. * Handsontable.hooks.destroy();
  1579. *
  1580. * // destroy the local listeners
  1581. * Handsontable.hooks.destroy(hotInstance);
  1582. * ```
  1583. */
  1584. destroy(context = null) {
  1585. objectEach(this.getBucket(context), (value, key, bucket) => (bucket[key].length = 0));
  1586. }
  1587. /**
  1588. * Registers a hook name (adds it to the list of the known hook names). Used by plugins.
  1589. * It is not necessary to call register, but if you use it, your plugin hook will be used returned by
  1590. * the `getRegistered` method. (which itself is used in the demo http://docs.handsontable.com/tutorial-callbacks.html).
  1591. *
  1592. * @param key {String} The hook name.
  1593. *
  1594. * @example
  1595. * ```js
  1596. * Handsontable.hooks.register('myHook');
  1597. * ```
  1598. */
  1599. register(key) {
  1600. if (!this.isRegistered(key)) {
  1601. REGISTERED_HOOKS.push(key);
  1602. }
  1603. }
  1604. /**
  1605. * Deregisters a hook name (removes it from the list of known hook names).
  1606. *
  1607. * @param key {String} Hook name.
  1608. *
  1609. * @example
  1610. * ```js
  1611. * Handsontable.hooks.deregister('myHook');
  1612. * ```
  1613. */
  1614. deregister(key) {
  1615. if (this.isRegistered(key)) {
  1616. REGISTERED_HOOKS.splice(REGISTERED_HOOKS.indexOf(key), 1);
  1617. }
  1618. }
  1619. /**
  1620. * Returns a boolean depending on if a hook by such name has been registered.
  1621. *
  1622. * @param key {String} Hook name.
  1623. * @returns {Boolean} `true` for success, `false` otherwise.
  1624. *
  1625. * @example
  1626. * ```js
  1627. * Handsontable.hooks.isRegistered('beforeInit');
  1628. *
  1629. * // Results:
  1630. * true
  1631. * ```
  1632. */
  1633. isRegistered(key) {
  1634. return REGISTERED_HOOKS.indexOf(key) >= 0;
  1635. }
  1636. /**
  1637. * Returns an array of registered hooks.
  1638. *
  1639. * @returns {Array} An array of registered hooks.
  1640. *
  1641. * @example
  1642. * ```js
  1643. * Handsontable.hooks.getRegistered();
  1644. *
  1645. * // Results:
  1646. * [
  1647. * ...
  1648. * 'beforeInit',
  1649. * 'beforeRender',
  1650. * 'beforeSetRangeEnd',
  1651. * 'beforeDrawBorders',
  1652. * 'beforeChange',
  1653. * ...
  1654. * ]
  1655. * ```
  1656. */
  1657. getRegistered() {
  1658. return REGISTERED_HOOKS;
  1659. }
  1660. }
  1661. const globalSingleton = new Hooks();
  1662. export default Hooks;