b3ebc1674c24a3b21ba3017fd0bfea6d8e5a95ee10b96311543d1cabbf3d68c4e6840f9c4a6c8cddbc04c7ba2336421487ebd38c5c53108a43a0067072d042 14 KB

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