57bb38640cf42f266cb69b485850f4d7cbfa1605d7e26e63010e11bec5d3f3ffa865590179842f07f9fb18e2be8bb0ba299d0c669eb0b8a170bc792cf31646 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. 'use strict';
  2. describe('AutoRowSize', function () {
  3. var id = 'testContainer';
  4. beforeEach(function () {
  5. this.$container = $('<div id="' + id + '"></div>').appendTo('body');
  6. });
  7. afterEach(function () {
  8. if (this.$container) {
  9. destroy();
  10. this.$container.remove();
  11. }
  12. });
  13. function arrayOfObjects() {
  14. return [{ id: 'Short' }, { id: 'Somewhat\nlong' }, { id: 'The\nvery\nvery\nvery\nlongest one' }];
  15. }
  16. function arrayOfObjects2() {
  17. return [{ id: 'Short', name: 'Somewhat long' }, { id: 'Somewhat long', name: 'The very very longest one' }, { id: 'The very very very longest one', name: 'Short' }];
  18. }
  19. it('should apply auto size by default', function () {
  20. handsontable({
  21. data: arrayOfObjects()
  22. });
  23. var height0 = rowHeight(this.$container, 0);
  24. var height1 = rowHeight(this.$container, 1);
  25. var height2 = rowHeight(this.$container, 2);
  26. expect(height0).toBeLessThan(height1);
  27. expect(height1).toBeLessThan(height2);
  28. });
  29. it('should draw scrollbar correctly (proper height) after calculation when autoRowSize option is set (long text in row) #4000', function (done) {
  30. var row = ['This is very long text which will break this cell text into two lines'];
  31. var data = [];
  32. var nrOfRows = 200;
  33. var columnWidth = 100;
  34. for (var i = 0; i < nrOfRows; i += 1) {
  35. data.push(row);
  36. }
  37. handsontable({
  38. data: data,
  39. colWidths: function colWidths() {
  40. return columnWidth;
  41. },
  42. autoRowSize: true
  43. });
  44. var oldHeight = spec().$container[0].scrollHeight;
  45. setTimeout(function () {
  46. var newHeight = spec().$container[0].scrollHeight;
  47. expect(oldHeight).toBeLessThan(newHeight);
  48. done();
  49. }, 200);
  50. });
  51. describe('should draw scrollbar correctly (proper height) after calculation when autoRowSize option is set (`table td` element height set by CSS) #4000', function () {
  52. var cellHeightInPx = 100;
  53. var nrOfRows = null;
  54. var nrOfColumns = 200,
  55. style;
  56. var SYNC_CALCULATION_LIMIT = Handsontable.plugins.AutoRowSize.SYNC_CALCULATION_LIMIT;
  57. var CALCULATION_STEP = Handsontable.plugins.AutoRowSize.CALCULATION_STEP;
  58. beforeEach(function () {
  59. if (!this.$container) {
  60. this.$container = $('<div id="' + id + '"></div>').appendTo('body');
  61. }
  62. var css = '.handsontable table td { height: ' + cellHeightInPx + 'px !important }',
  63. head = document.head;
  64. style = document.createElement('style');
  65. style.type = 'text/css';
  66. if (style.styleSheet) {
  67. style.styleSheet.cssText = css;
  68. } else {
  69. style.appendChild(document.createTextNode(css));
  70. }
  71. $(head).append(style);
  72. });
  73. afterEach(function () {
  74. if (this.$container) {
  75. destroy();
  76. this.$container.remove();
  77. }
  78. if (style) {
  79. $(style).remove();
  80. }
  81. });
  82. it('(SYNC_CALCULATION_LIMIT - 1 rows)', function (done) {
  83. nrOfRows = SYNC_CALCULATION_LIMIT - 1;
  84. handsontable({
  85. data: Handsontable.helper.createSpreadsheetData(nrOfRows, nrOfColumns),
  86. autoRowSize: true
  87. });
  88. setTimeout(function () {
  89. var newHeight = spec().$container[0].scrollHeight;
  90. expect(newHeight).toEqual((cellHeightInPx + 1) * nrOfRows + 1);
  91. done();
  92. }, 200);
  93. });
  94. it('(SYNC_CALCULATION_LIMIT + 1 rows)', function (done) {
  95. nrOfRows = SYNC_CALCULATION_LIMIT + 1;
  96. handsontable({
  97. data: Handsontable.helper.createSpreadsheetData(nrOfRows, nrOfColumns),
  98. autoRowSize: true
  99. });
  100. setTimeout(function () {
  101. var newHeight = spec().$container[0].scrollHeight;
  102. expect(newHeight).toEqual((cellHeightInPx + 1) * nrOfRows + 1);
  103. done();
  104. }, 200);
  105. });
  106. it('(SYNC_CALCULATION_LIMIT + CALCULATION_STEP - 1 rows)', function (done) {
  107. nrOfRows = SYNC_CALCULATION_LIMIT + CALCULATION_STEP - 1;
  108. handsontable({
  109. data: Handsontable.helper.createSpreadsheetData(nrOfRows, nrOfColumns),
  110. autoRowSize: true
  111. });
  112. setTimeout(function () {
  113. var newHeight = spec().$container[0].scrollHeight;
  114. expect(newHeight).toEqual((cellHeightInPx + 1) * nrOfRows + 1);
  115. done();
  116. }, 200);
  117. });
  118. it('(SYNC_CALCULATION_LIMIT + CALCULATION_STEP + 1 rows)', function (done) {
  119. nrOfRows = SYNC_CALCULATION_LIMIT + CALCULATION_STEP + 1;
  120. handsontable({
  121. data: Handsontable.helper.createSpreadsheetData(nrOfRows, nrOfColumns),
  122. autoRowSize: true
  123. });
  124. setTimeout(function () {
  125. var newHeight = spec().$container[0].scrollHeight;
  126. expect(newHeight).toEqual((cellHeightInPx + 1) * nrOfRows + 1);
  127. done();
  128. }, 200);
  129. });
  130. });
  131. it('should correctly detect row height when table is hidden on init (display: none)', function (done) {
  132. this.$container.css('display', 'none');
  133. var hot = handsontable({
  134. data: arrayOfObjects(),
  135. rowHeaders: true,
  136. autoRowSize: true
  137. });
  138. setTimeout(function () {
  139. spec().$container.css('display', 'block');
  140. hot.render();
  141. expect(rowHeight(spec().$container, 0)).toBe(24);
  142. expect(rowHeight(spec().$container, 1)).toBe(43);
  143. expect([106, 127]).toEqual(jasmine.arrayContaining([rowHeight(spec().$container, 2)]));
  144. done();
  145. }, 200);
  146. });
  147. it('should be possible to disable plugin using updateSettings', function () {
  148. var hot = handsontable({
  149. data: arrayOfObjects()
  150. });
  151. var height0 = rowHeight(this.$container, 0);
  152. var height1 = rowHeight(this.$container, 1);
  153. var height2 = rowHeight(this.$container, 2);
  154. expect(height0).toBeLessThan(height1);
  155. expect(height1).toBeLessThan(height2);
  156. updateSettings({
  157. autoRowSize: false
  158. });
  159. hot.setDataAtCell(0, 0, 'A\nB\nC');
  160. var height4 = rowHeight(this.$container, 0);
  161. expect(height4).toBeGreaterThan(height0);
  162. });
  163. it('should be possible to enable plugin using updateSettings', function () {
  164. handsontable({
  165. data: arrayOfObjects(),
  166. autoRowSize: false
  167. });
  168. var height0 = parseInt(getCell(0, 0).style.height, 10);
  169. var height1 = parseInt(getCell(1, 0).style.height, 10);
  170. var height2 = parseInt(getCell(2, 0).style.height, 10);
  171. expect(height0).toEqual(height1);
  172. expect(height0).toEqual(height2);
  173. expect(height1).toEqual(height2);
  174. updateSettings({
  175. autoRowSize: true
  176. });
  177. height0 = parseInt(getCell(0, 0).style.height, 10);
  178. height1 = parseInt(getCell(1, 0).style.height, 10);
  179. height2 = parseInt(getCell(2, 0).style.height, 10);
  180. expect(height0).toBeLessThan(height1);
  181. expect(height1).toBeLessThan(height2);
  182. });
  183. it('should consider CSS style of each instance separately', function () {
  184. var $style = $('<style>.big .htCore td {font-size: 40px;line-height: 1.1}</style>').appendTo('head');
  185. var $container1 = $('<div id="hot1"></div>').appendTo('body').handsontable({
  186. data: arrayOfObjects(),
  187. autoRowSize: true
  188. });
  189. var $container2 = $('<div id="hot2"></div>').appendTo('body').handsontable({
  190. data: arrayOfObjects(),
  191. autoRowSize: true
  192. });
  193. var hot1 = $container1.handsontable('getInstance');
  194. var hot2 = $container2.handsontable('getInstance');
  195. expect(parseInt(hot1.getCell(0, 0).style.height, 10)).toEqual(parseInt(hot2.getCell(0, 0).style.height, 10));
  196. $container1.addClass('big');
  197. hot1.render();
  198. hot2.render();
  199. expect(parseInt(hot1.getCell(2, 0).style.height, 10)).toBeGreaterThan(parseInt(hot2.getCell(2, 0).style.height, 10));
  200. $container1.removeClass('big');
  201. hot1.render();
  202. $container2.addClass('big');
  203. hot2.render();
  204. expect(parseInt(hot1.getCell(2, 0).style.height, 10)).toBeLessThan(parseInt(hot2.getCell(2, 0).style.height, 10));
  205. $style.remove();
  206. $container1.handsontable('destroy');
  207. $container1.remove();
  208. $container2.handsontable('destroy');
  209. $container2.remove();
  210. });
  211. it('should consider CSS class of the <table> element (e.g. when used with Bootstrap)', function () {
  212. var $style = $('<style>.htCore.big-table td {font-size: 32px;line-height: 1.1}</style>').appendTo('head');
  213. var hot = handsontable({
  214. data: arrayOfObjects(),
  215. autoRowSize: true
  216. });
  217. var height = parseInt(hot.getCell(2, 0).style.height, 10);
  218. this.$container.find('table').addClass('big-table');
  219. hot.getPlugin('autoRowSize').clearCache();
  220. render();
  221. expect(parseInt(hot.getCell(2, 0).style.height, 10)).toBeGreaterThan(height);
  222. $style.remove();
  223. });
  224. it('should not trigger autoColumnSize when column width is defined (through colWidths)', function () {
  225. var hot = handsontable({
  226. data: arrayOfObjects(),
  227. autoRowSize: true,
  228. rowHeights: [70, 70, 70],
  229. width: 500,
  230. height: 100,
  231. rowHeaders: true
  232. });
  233. setDataAtCell(0, 0, 'LongLongLongLong');
  234. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(69); // -1px of cell border
  235. });
  236. // Currently columns.height is not supported
  237. xit('should not trigger autoRowSize when column height is defined (through columns.height)', function () {
  238. var hot = handsontable({
  239. data: arrayOfObjects(),
  240. autoRowSize: true,
  241. rowHeights: 77,
  242. columns: [{ height: 70 }, { height: 70 }, { height: 70 }],
  243. width: 500,
  244. height: 100,
  245. rowHeaders: true
  246. });
  247. setDataAtCell(0, 0, 'LongLongLongLong');
  248. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(69); // -1px of cell border
  249. });
  250. it('should consider renderer that uses conditional formatting for specific row & column index', function () {
  251. var data = arrayOfObjects();
  252. data.push({ id: '2', name: 'Rocket Man', lastName: 'In a tin can' });
  253. var hot = handsontable({
  254. data: data,
  255. columns: [{ data: 'id' }, { data: 'name' }],
  256. autoRowSize: true,
  257. renderer: function renderer(instance, td, row, col, prop, value, cellProperties) {
  258. // taken from demo/renderers.html
  259. Handsontable.renderers.TextRenderer.apply(this, arguments);
  260. if (row === 1 && col === 0) {
  261. td.style.padding = '100px';
  262. }
  263. }
  264. });
  265. expect(parseInt(hot.getCell(1, 0).style.height || 0, 10)).toBe(242);
  266. });
  267. it('should destroy temporary element', function () {
  268. handsontable({
  269. autoRowSize: true
  270. });
  271. expect(document.querySelector('.htAutoSize')).toBe(null);
  272. });
  273. it('should recalculate heights after column resize', function () {
  274. var hot = handsontable({
  275. data: arrayOfObjects2(),
  276. colWidths: 250,
  277. manualColumnResize: true,
  278. autoRowSize: true,
  279. rowHeaders: true,
  280. colHeaders: true
  281. });
  282. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(22); // -1px of cell border
  283. expect(parseInt(hot.getCell(1, -1).style.height, 10)).toBe(22); // -1px of cell border
  284. expect(parseInt(hot.getCell(2, -1).style.height, 10)).toBeInArray([22, 42]); // -1px of cell border
  285. resizeColumn.call(this, 1, 100);
  286. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(22);
  287. expect(parseInt(hot.getCell(1, -1).style.height, 10)).toBe(42);
  288. expect([63, 84]).toEqual(jasmine.arrayContaining([parseInt(hot.getCell(2, -1).style.height, 10)]));
  289. resizeColumn.call(this, 1, 50);
  290. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(22);
  291. expect(parseInt(hot.getCell(1, -1).style.height, 10)).toBe(42);
  292. expect(parseInt(hot.getCell(2, -1).style.height, 10)).toBe(126);
  293. resizeColumn.call(this, 1, 200);
  294. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(22);
  295. expect(parseInt(hot.getCell(1, -1).style.height, 10)).toBe(22);
  296. expect(parseInt(hot.getCell(2, -1).style.height, 10)).toBe(42);
  297. });
  298. it('should recalculate heights after column moved', function () {
  299. var hot = handsontable({
  300. data: arrayOfObjects2(),
  301. colWidths: [250, 50],
  302. manualColumnMove: true,
  303. autoRowSize: true,
  304. rowHeaders: true,
  305. colHeaders: true
  306. });
  307. var plugin = hot.getPlugin('manualColumnMove');
  308. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(42); // -1px of cell border
  309. expect(parseInt(hot.getCell(1, -1).style.height, 10)).toBe(105); // -1px of cell border
  310. expect(parseInt(hot.getCell(2, -1).style.height, 10)).toBeInArray([22, 42]); // -1px of cell border
  311. plugin.moveColumn(0, 2);
  312. hot.render();
  313. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(22);
  314. expect(parseInt(hot.getCell(1, -1).style.height, 10)).toBe(42);
  315. expect(parseInt(hot.getCell(2, -1).style.height, 10)).toBe(126);
  316. });
  317. it('should recalculate heights with manualRowResize when changing text to multiline', function () {
  318. var hot = handsontable({
  319. data: arrayOfObjects2(),
  320. colWidths: 250,
  321. manualRowResize: [23, 50],
  322. autoRowSize: true,
  323. rowHeaders: true,
  324. colHeaders: true
  325. });
  326. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(22); // -1px of cell border
  327. expect(parseInt(hot.getCell(1, -1).style.height, 10)).toBe(49); // -1px of cell border
  328. expect(parseInt(hot.getCell(2, -1).style.height, 10)).toBeInArray([22, 42]); // -1px of cell border
  329. hot.setDataAtCell(1, 0, 'A\nB\nC\nD\nE');
  330. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(22);
  331. expect(parseInt(hot.getCell(1, -1).style.height, 10)).toBe(105);
  332. expect(parseInt(hot.getCell(2, -1).style.height, 10)).toBeInArray([22, 42]);
  333. });
  334. it('should recalculate heights after moved row', function () {
  335. var hot = handsontable({
  336. data: arrayOfObjects2(),
  337. colWidths: 250,
  338. manualRowResize: [23, 50],
  339. manualRowMove: true,
  340. autoRowSize: true,
  341. rowHeaders: true,
  342. colHeaders: true
  343. });
  344. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(22); // -1px of cell border
  345. expect(parseInt(hot.getCell(1, -1).style.height, 10)).toBe(49); // -1px of cell border
  346. expect(parseInt(hot.getCell(2, -1).style.height, 10)).toBeInArray([22, 42]); // -1px of cell border
  347. var plugin = hot.getPlugin('manualRowMove');
  348. plugin.moveRow(1, 0);
  349. hot.render();
  350. expect(parseInt(hot.getCell(0, -1).style.height, 10)).toBe(49);
  351. expect(parseInt(hot.getCell(1, -1).style.height, 10)).toBe(22);
  352. expect(parseInt(hot.getCell(2, -1).style.height, 10)).toBeInArray([22, 42]); // -1px of cell border
  353. });
  354. it('should resize the column headers properly, according the their content sizes', function () {
  355. var hot = handsontable({
  356. data: Handsontable.helper.createSpreadsheetData(30, 30),
  357. colHeaders: function colHeaders(index) {
  358. if (index === 22) {
  359. return 'a<br>much<br>longer<br>label';
  360. }
  361. return 'test';
  362. },
  363. autoRowSize: true,
  364. rowHeaders: true,
  365. width: 300,
  366. height: 300
  367. });
  368. expect(rowHeight(spec().$container, -1)).toBe(89);
  369. });
  370. });