5b6a296f5b0015504b00ea200c2dea9a2bd193bb8dcbc2da77c93cd4dbcc03a71a780bdd7168b378c9bc1be5594aacd4752c83bea669db1beeb4941746fc95 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. 'use strict';
  2. exports.__esModule = true;
  3. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  4. var _element = require('./../helpers/dom/element');
  5. var _array = require('./../helpers/array');
  6. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7. /**
  8. * @class GhostTable
  9. * @util
  10. */
  11. var GhostTable = function () {
  12. function GhostTable(hotInstance) {
  13. _classCallCheck(this, GhostTable);
  14. /**
  15. * Handsontable instance.
  16. *
  17. * @type {Core}
  18. */
  19. this.hot = hotInstance;
  20. /**
  21. * Container element where every table will be injected.
  22. *
  23. * @type {HTMLElement|null}
  24. */
  25. this.container = null;
  26. /**
  27. * Flag which determine is table was injected to DOM.
  28. *
  29. * @type {Boolean}
  30. */
  31. this.injected = false;
  32. /**
  33. * Added rows collection.
  34. *
  35. * @type {Array}
  36. */
  37. this.rows = [];
  38. /**
  39. * Added columns collection.
  40. *
  41. * @type {Array}
  42. */
  43. this.columns = [];
  44. /**
  45. * Samples prepared for calculations.
  46. *
  47. * @type {Map}
  48. * @default {null}
  49. */
  50. this.samples = null;
  51. /**
  52. * Ghost table settings.
  53. *
  54. * @type {Object}
  55. * @default {Object}
  56. */
  57. this.settings = {
  58. useHeaders: true
  59. };
  60. }
  61. /**
  62. * Add row.
  63. *
  64. * @param {Number} row Row index.
  65. * @param {Map} samples Samples Map object.
  66. */
  67. _createClass(GhostTable, [{
  68. key: 'addRow',
  69. value: function addRow(row, samples) {
  70. if (this.columns.length) {
  71. throw new Error('Doesn\'t support multi-dimensional table');
  72. }
  73. if (!this.rows.length) {
  74. this.container = this.createContainer(this.hot.rootElement.className);
  75. }
  76. var rowObject = { row: row };
  77. this.rows.push(rowObject);
  78. this.samples = samples;
  79. this.table = this.createTable(this.hot.table.className);
  80. this.table.colGroup.appendChild(this.createColGroupsCol());
  81. this.table.tr.appendChild(this.createRow(row));
  82. this.container.container.appendChild(this.table.fragment);
  83. rowObject.table = this.table.table;
  84. }
  85. /**
  86. * Add a row consisting of the column headers.
  87. */
  88. }, {
  89. key: 'addColumnHeadersRow',
  90. value: function addColumnHeadersRow(samples) {
  91. if (this.hot.getColHeader(0) != null) {
  92. var rowObject = { row: -1 };
  93. this.rows.push(rowObject);
  94. this.container = this.createContainer(this.hot.rootElement.className);
  95. this.samples = samples;
  96. this.table = this.createTable(this.hot.table.className);
  97. this.table.colGroup.appendChild(this.createColGroupsCol());
  98. this.table.tHead.appendChild(this.createColumnHeadersRow());
  99. this.container.container.appendChild(this.table.fragment);
  100. rowObject.table = this.table.table;
  101. }
  102. }
  103. /**
  104. * Add column.
  105. *
  106. * @param {Number} column Column index.
  107. * @param {Map} samples Samples Map object.
  108. */
  109. }, {
  110. key: 'addColumn',
  111. value: function addColumn(column, samples) {
  112. if (this.rows.length) {
  113. throw new Error('Doesn\'t support multi-dimensional table');
  114. }
  115. if (!this.columns.length) {
  116. this.container = this.createContainer(this.hot.rootElement.className);
  117. }
  118. var columnObject = { col: column };
  119. this.columns.push(columnObject);
  120. this.samples = samples;
  121. this.table = this.createTable(this.hot.table.className);
  122. if (this.getSetting('useHeaders') && this.hot.getColHeader(column) !== null) {
  123. this.hot.view.appendColHeader(column, this.table.th);
  124. }
  125. this.table.tBody.appendChild(this.createCol(column));
  126. this.container.container.appendChild(this.table.fragment);
  127. columnObject.table = this.table.table;
  128. }
  129. /**
  130. * Get calculated heights.
  131. *
  132. * @param {Function} callback Callback which will be fired for each calculated row.
  133. */
  134. }, {
  135. key: 'getHeights',
  136. value: function getHeights(callback) {
  137. if (!this.injected) {
  138. this.injectTable();
  139. }
  140. (0, _array.arrayEach)(this.rows, function (row) {
  141. // -1 <- reduce border-top from table
  142. callback(row.row, (0, _element.outerHeight)(row.table) - 1);
  143. });
  144. }
  145. /**
  146. * Get calculated widths.
  147. *
  148. * @param {Function} callback Callback which will be fired for each calculated column.
  149. */
  150. }, {
  151. key: 'getWidths',
  152. value: function getWidths(callback) {
  153. if (!this.injected) {
  154. this.injectTable();
  155. }
  156. (0, _array.arrayEach)(this.columns, function (column) {
  157. callback(column.col, (0, _element.outerWidth)(column.table));
  158. });
  159. }
  160. /**
  161. * Set the Ghost Table settings to the provided object.
  162. *
  163. * @param {Object} settings New Ghost Table Settings
  164. */
  165. }, {
  166. key: 'setSettings',
  167. value: function setSettings(settings) {
  168. this.settings = settings;
  169. }
  170. /**
  171. * Set a single setting of the Ghost Table.
  172. *
  173. * @param {String} name Setting name.
  174. * @param {*} value Setting value.
  175. */
  176. }, {
  177. key: 'setSetting',
  178. value: function setSetting(name, value) {
  179. if (!this.settings) {
  180. this.settings = {};
  181. }
  182. this.settings[name] = value;
  183. }
  184. /**
  185. * Get the Ghost Table settings.
  186. *
  187. * @returns {Object|null}
  188. */
  189. }, {
  190. key: 'getSettings',
  191. value: function getSettings() {
  192. return this.settings;
  193. }
  194. /**
  195. * Get a single Ghost Table setting.
  196. *
  197. * @param {String} name
  198. * @returns {Boolean|null}
  199. */
  200. }, {
  201. key: 'getSetting',
  202. value: function getSetting(name) {
  203. if (this.settings) {
  204. return this.settings[name];
  205. }
  206. return null;
  207. }
  208. /**
  209. * Create colgroup col elements.
  210. *
  211. * @returns {DocumentFragment}
  212. */
  213. }, {
  214. key: 'createColGroupsCol',
  215. value: function createColGroupsCol() {
  216. var _this = this;
  217. var d = document;
  218. var fragment = d.createDocumentFragment();
  219. if (this.hot.hasRowHeaders()) {
  220. fragment.appendChild(this.createColElement(-1));
  221. }
  222. this.samples.forEach(function (sample) {
  223. (0, _array.arrayEach)(sample.strings, function (string) {
  224. fragment.appendChild(_this.createColElement(string.col));
  225. });
  226. });
  227. return fragment;
  228. }
  229. /**
  230. * Create table row element.
  231. *
  232. * @param {Number} row Row index.
  233. * @returns {DocumentFragment} Returns created table row elements.
  234. */
  235. }, {
  236. key: 'createRow',
  237. value: function createRow(row) {
  238. var _this2 = this;
  239. var d = document;
  240. var fragment = d.createDocumentFragment();
  241. var th = d.createElement('th');
  242. if (this.hot.hasRowHeaders()) {
  243. this.hot.view.appendRowHeader(row, th);
  244. fragment.appendChild(th);
  245. }
  246. this.samples.forEach(function (sample) {
  247. (0, _array.arrayEach)(sample.strings, function (string) {
  248. var column = string.col;
  249. var cellProperties = _this2.hot.getCellMeta(row, column);
  250. cellProperties.col = column;
  251. cellProperties.row = row;
  252. var renderer = _this2.hot.getCellRenderer(cellProperties);
  253. var td = d.createElement('td');
  254. renderer(_this2.hot, td, row, column, _this2.hot.colToProp(column), string.value, cellProperties);
  255. fragment.appendChild(td);
  256. });
  257. });
  258. return fragment;
  259. }
  260. }, {
  261. key: 'createColumnHeadersRow',
  262. value: function createColumnHeadersRow() {
  263. var _this3 = this;
  264. var d = document;
  265. var fragment = d.createDocumentFragment();
  266. if (this.hot.hasRowHeaders()) {
  267. var th = d.createElement('th');
  268. this.hot.view.appendColHeader(-1, th);
  269. fragment.appendChild(th);
  270. }
  271. this.samples.forEach(function (sample) {
  272. (0, _array.arrayEach)(sample.strings, function (string) {
  273. var column = string.col;
  274. var th = d.createElement('th');
  275. _this3.hot.view.appendColHeader(column, th);
  276. fragment.appendChild(th);
  277. });
  278. });
  279. return fragment;
  280. }
  281. /**
  282. * Create table column elements.
  283. *
  284. * @param {Number} column Column index.
  285. * @returns {DocumentFragment} Returns created column table column elements.
  286. */
  287. }, {
  288. key: 'createCol',
  289. value: function createCol(column) {
  290. var _this4 = this;
  291. var d = document;
  292. var fragment = d.createDocumentFragment();
  293. this.samples.forEach(function (sample) {
  294. (0, _array.arrayEach)(sample.strings, function (string) {
  295. var row = string.row;
  296. var cellProperties = _this4.hot.getCellMeta(row, column);
  297. cellProperties.col = column;
  298. cellProperties.row = row;
  299. var renderer = _this4.hot.getCellRenderer(cellProperties);
  300. var td = d.createElement('td');
  301. var tr = d.createElement('tr');
  302. renderer(_this4.hot, td, row, column, _this4.hot.colToProp(column), string.value, cellProperties);
  303. tr.appendChild(td);
  304. fragment.appendChild(tr);
  305. });
  306. });
  307. return fragment;
  308. }
  309. /**
  310. * Remove table from document and reset internal state.
  311. */
  312. }, {
  313. key: 'clean',
  314. value: function clean() {
  315. this.rows.length = 0;
  316. this.rows[-1] = void 0;
  317. this.columns.length = 0;
  318. if (this.samples) {
  319. this.samples.clear();
  320. }
  321. this.samples = null;
  322. this.removeTable();
  323. }
  324. /**
  325. * Inject generated table into document.
  326. *
  327. * @param {HTMLElement} [parent=null]
  328. */
  329. }, {
  330. key: 'injectTable',
  331. value: function injectTable() {
  332. var parent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
  333. if (!this.injected) {
  334. (parent || this.hot.rootElement).appendChild(this.container.fragment);
  335. this.injected = true;
  336. }
  337. }
  338. /**
  339. * Remove table from document.
  340. */
  341. }, {
  342. key: 'removeTable',
  343. value: function removeTable() {
  344. if (this.injected && this.container.container.parentNode) {
  345. this.container.container.parentNode.removeChild(this.container.container);
  346. this.container = null;
  347. this.injected = false;
  348. }
  349. }
  350. /**
  351. * Create col element.
  352. *
  353. * @param {Number} column Column index.
  354. * @returns {HTMLElement}
  355. */
  356. }, {
  357. key: 'createColElement',
  358. value: function createColElement(column) {
  359. var d = document;
  360. var col = d.createElement('col');
  361. col.style.width = this.hot.view.wt.wtTable.getStretchedColumnWidth(column) + 'px';
  362. return col;
  363. }
  364. /**
  365. * Create table element.
  366. *
  367. * @param {String} className
  368. * @returns {Object}
  369. */
  370. }, {
  371. key: 'createTable',
  372. value: function createTable() {
  373. var className = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  374. var d = document;
  375. var fragment = d.createDocumentFragment();
  376. var table = d.createElement('table');
  377. var tHead = d.createElement('thead');
  378. var tBody = d.createElement('tbody');
  379. var colGroup = d.createElement('colgroup');
  380. var tr = d.createElement('tr');
  381. var th = d.createElement('th');
  382. if (this.isVertical()) {
  383. table.appendChild(colGroup);
  384. }
  385. if (this.isHorizontal()) {
  386. tr.appendChild(th);
  387. tHead.appendChild(tr);
  388. table.style.tableLayout = 'auto';
  389. table.style.width = 'auto';
  390. }
  391. table.appendChild(tHead);
  392. if (this.isVertical()) {
  393. tBody.appendChild(tr);
  394. }
  395. table.appendChild(tBody);
  396. (0, _element.addClass)(table, className);
  397. fragment.appendChild(table);
  398. return { fragment: fragment, table: table, tHead: tHead, tBody: tBody, colGroup: colGroup, tr: tr, th: th };
  399. }
  400. /**
  401. * Create container for tables.
  402. *
  403. * @param {String} className
  404. * @returns {Object}
  405. */
  406. }, {
  407. key: 'createContainer',
  408. value: function createContainer() {
  409. var className = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  410. var d = document;
  411. var fragment = d.createDocumentFragment();
  412. var container = d.createElement('div');
  413. className = 'htGhostTable htAutoSize ' + className.trim();
  414. (0, _element.addClass)(container, className);
  415. fragment.appendChild(container);
  416. return { fragment: fragment, container: container };
  417. }
  418. /**
  419. * Checks if table is raised vertically (checking rows).
  420. *
  421. * @returns {Boolean}
  422. */
  423. }, {
  424. key: 'isVertical',
  425. value: function isVertical() {
  426. return !!(this.rows.length && !this.columns.length);
  427. }
  428. /**
  429. * Checks if table is raised horizontally (checking columns).
  430. *
  431. * @returns {Boolean}
  432. */
  433. }, {
  434. key: 'isHorizontal',
  435. value: function isHorizontal() {
  436. return !!(this.columns.length && !this.rows.length);
  437. }
  438. }]);
  439. return GhostTable;
  440. }();
  441. exports.default = GhostTable;