Built files from Bizgaze WebServer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

autofill.js 52KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. var Unibase;
  2. (function (Unibase) {
  3. let Apps;
  4. (function (Apps) {
  5. let Collaboration;
  6. (function (Collaboration) {
  7. let Components;
  8. (function (Components) {
  9. let Sheets;
  10. (function (Sheets) {
  11. class Autofill {
  12. constructor() {
  13. this.hederText = {};
  14. this.colType = { String: "string", Number: "number", Custom: "custom", Formula: "formula", Time: "time", LongDate: "longdate", ShortDate: "shortdate", Scientific: "scientific", Fraction: "fraction", Text: "text", General: "general", Accounting: "accounting", Currency: "currency", Percentage: "percentage", Date: "date", DateTime: "datetime" };
  15. this.customList = [
  16. ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
  17. ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
  18. ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
  19. ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
  20. ];
  21. this.UC = {
  22. uniqueOBracket: String.fromCharCode(129),
  23. uniqueCBracket: String.fromCharCode(130),
  24. uniqueCSeparator: String.fromCharCode(131),
  25. uniqueCOperator: String.fromCharCode(132),
  26. uniquePOperator: String.fromCharCode(133),
  27. uniqueSOperator: String.fromCharCode(134),
  28. uniqueMOperator: String.fromCharCode(135),
  29. uniqueDOperator: String.fromCharCode(136),
  30. uniqueModOperator: String.fromCharCode(137),
  31. uniqueConcateOperator: String.fromCharCode(138),
  32. uniqueEqualOperator: String.fromCharCode(139),
  33. uniqueExpOperator: String.fromCharCode(140),
  34. uniqueGTOperator: String.fromCharCode(141),
  35. uniqueLTOperator: String.fromCharCode(142)
  36. };
  37. }
  38. init(base) {
  39. this.base = base;
  40. this.ssObj = base.ssObj;
  41. this.initProp();
  42. }
  43. initProp() {
  44. this.beforeSelectFn = this.beforeSelect.bind(this);
  45. this.base.ssObj.addEventListener("beforeSelect", this.beforeSelectFn);
  46. this.selectFn = this.selected.bind(this);
  47. this.base.ssObj.addEventListener("select", this.selectFn);
  48. this.actionCompleteFn = this.updateAutofill.bind(this);
  49. this.base.ssObj.addEventListener("actionComplete", this.actionCompleteFn);
  50. this.createdFn = this.created.bind(this);
  51. this.base.ssObj.addEventListener("created", this.createdFn);
  52. this.dataBoundFn = this.dataBound.bind(this);
  53. this.base.ssObj.addEventListener("dataBound", this.dataBoundFn);
  54. this.cellEditFn = this.cellEdit.bind(this);
  55. this.base.ssObj.addEventListener("cellEditing", this.cellEditFn);
  56. this.cellSaveFn = this.cellSave.bind(this);
  57. this.base.ssObj.addEventListener("cellSave", this.cellSaveFn);
  58. this.base.ssObj.on("activeSheetChanged", this.updateAutofill, this);
  59. this.base.ssObj.on("mouseDown", this.mouseDown, this);
  60. }
  61. destroy() {
  62. this.base.ssObj.removeEventListener("beforeSelect", this.beforeSelectFn);
  63. this.base.ssObj.removeEventListener("select", this.selectFn);
  64. this.base.ssObj.removeEventListener("actionComplete", this.actionCompleteFn);
  65. this.base.ssObj.removeEventListener("created", this.createdFn);
  66. this.base.ssObj.removeEventListener("dataBound", this.dataBoundFn);
  67. this.base.ssObj.removeEventListener("cellEditing", this.cellEditFn);
  68. this.base.ssObj.removeEventListener("cellSave", this.cellSaveFn);
  69. this.base.ssObj.off("activeSheetChanged", this.updateAutofill);
  70. this.base.ssObj.on("mouseDown", this.mouseDown, this);
  71. ej.base.EventHandler.remove(this.base.ssObj.element, 'mouseup', this.mouseUp);
  72. ej.base.EventHandler.remove(this.base.ssObj.element, 'keydown', this.keypress);
  73. ej.base.EventHandler.remove(this.base.ssObj.element, 'dblclick', this.dblClick);
  74. }
  75. cellEdit() {
  76. this.hideAutofill();
  77. }
  78. cellSave() {
  79. this.updateAutofill();
  80. }
  81. dataBound() {
  82. this.updateAutofill();
  83. }
  84. createBorders() {
  85. if (!this.base.ssObj.element.getElementsByClassName('biz-af-bdr')[0]) {
  86. let content = this.base.ssObj.element.getElementsByClassName('e-sheet-content')[0];
  87. this.bdrAF = content.appendChild(ej.base.createElement('div', { className: 'biz-af-bdr' }));
  88. }
  89. }
  90. hideBorders() {
  91. if (this.bdrAF) {
  92. this.bdrAF.style.display = 'none';
  93. }
  94. }
  95. showBorders() {
  96. if (this.bdrAF) {
  97. this.bdrAF.style.display = '';
  98. }
  99. }
  100. updateBorderDirection(hideDirecton) {
  101. this.bdrAF.style.borderRightWidth = '1px';
  102. this.bdrAF.style.borderLeftWidth = '1px';
  103. this.bdrAF.style.borderTopWidth = '1px';
  104. this.bdrAF.style.borderBottomWidth = '1px';
  105. this.bdrAF.style["border" + hideDirecton + "Width"] = '0px';
  106. }
  107. mouseDown(e) {
  108. if (e.target.classList.contains('biz-autofill')) {
  109. this.isDrag = true;
  110. ej.base.EventHandler.add(this.base.ssObj.element, 'mousemove', this.mouseMoveHandler, this);
  111. this.x = e.clientX;
  112. this.y = e.clientY;
  113. this.indexes = this.base.ssObj.biz.getIndexes();
  114. this.createBorders();
  115. let sel = this.base.ssObj.element.getElementsByClassName('e-selection')[0];
  116. let activecell = this.base.ssObj.element.getElementsByClassName('e-active-cell')[0];
  117. this.selection = sel.classList.contains('e-hide') ? activecell : sel;
  118. this.selOffset = this.selection.getBoundingClientRect();
  119. this.parentOffset = this.selection.offsetParent.getBoundingClientRect();
  120. this.left = parseInt(this.selection.style.left);
  121. this.top = parseInt(this.selection.style.top);
  122. }
  123. }
  124. mouseUp(e) {
  125. this.isDrag = false;
  126. ej.base.EventHandler.remove(this.base.ssObj.element, 'mousemove', this.mouseMoveHandler);
  127. if (this.direction != undefined) {
  128. this.autoFill();
  129. }
  130. this.direction = undefined;
  131. this.hideBorders();
  132. this.isDragged = false;
  133. this.prevTarget = undefined;
  134. }
  135. createAutofill() {
  136. if (!this.base.ssObj.element.getElementsByClassName('biz-autofill')[0]) {
  137. this.element = document.createElement('div');
  138. this.element.classList.add('biz-autofill');
  139. let content = this.base.ssObj.element.getElementsByClassName('e-sheet-content')[0];
  140. content && content.appendChild(this.element);
  141. }
  142. this.element.classList.remove('biz-hide');
  143. }
  144. updateAutofill() {
  145. if (!this.base.ssObj.isEdit) {
  146. this.positionAutofill();
  147. }
  148. else {
  149. this.hideAutofill();
  150. }
  151. }
  152. dblClick() {
  153. setTimeout(() => {
  154. this.hideAutofill();
  155. }, 1);
  156. }
  157. positionAutofill() {
  158. setTimeout(() => {
  159. this.createAutofill();
  160. let selection = this.base.ssObj.element.getElementsByClassName('e-selection')[0];
  161. let activecell = this.base.ssObj.element.getElementsByClassName('e-active-cell')[0];
  162. if (selection && !selection.classList.contains('e-hide')) {
  163. activecell = selection;
  164. }
  165. (this.element && activecell) && (this.element.style.top = parseInt(activecell.style.top) + parseInt(activecell.style.height) - 6 + 'px');
  166. (this.element && activecell) && (this.element.style.left = parseInt(activecell.style.left) + parseInt(activecell.style.width) + -5 + 'px');
  167. }, 10);
  168. }
  169. hideAutofill() {
  170. let ele = this.base.ssObj.element.getElementsByClassName('biz-autofill')[0];
  171. if (ele) {
  172. ele.classList.add('biz-hide');
  173. }
  174. }
  175. mouseMoveHandler(e) {
  176. e.preventDefault();
  177. let x = e.clientX;
  178. let y = e.clientY;
  179. if (e.target === this.prevTarget) {
  180. return;
  181. }
  182. let tr = ej.base.closest(e.target, 'tr');
  183. let td = ej.base.closest(e.target, '.e-cell');
  184. if (!this.isDragged) {
  185. this.showBorders();
  186. }
  187. this.isDragged = true;
  188. if (!tr || !td) {
  189. return;
  190. }
  191. let colIdx = parseInt(td.getAttribute('aria-colindex')) - 1;
  192. let rowIdx = parseInt(tr.getAttribute('aria-rowindex')) - 1;
  193. if (this.indexes[0] <= rowIdx && this.indexes[2] >= rowIdx && this.indexes[1] <= colIdx && this.indexes[3] >= colIdx) {
  194. this.hideBorders();
  195. return;
  196. }
  197. let tdOffset = td.getBoundingClientRect();
  198. let px = 'px';
  199. this.showBorders();
  200. let sheet = this.base.ssObj.biz.getActiveSheet();
  201. let freezeRow = this.base.ssObj.frozenRowCount(sheet);
  202. let freezeCol = this.base.ssObj.frozenColCount(sheet);
  203. let left;
  204. let width;
  205. let top;
  206. let height;
  207. switch (true) {
  208. case this.indexes[3] < colIdx && this.indexes[0] - rowIdx < colIdx - this.indexes[3] && rowIdx - this.indexes[2] < colIdx - this.indexes[3]:
  209. this.direction = "right";
  210. left = this.left + this.selOffset.width;
  211. width = ej.spreadsheet.getCellPosition(sheet, [rowIdx - 1, colIdx + 1], freezeRow, freezeCol).left - (this.left + this.selOffset.width);
  212. this.updateBorderDirection('Left');
  213. this.bdrAF.style.top = this.top + px;
  214. this.bdrAF.style.left = left + px;
  215. this.bdrAF.style.height = this.selOffset.height + px;
  216. this.bdrAF.style.width = width + px;
  217. this.fIndexes = [this.indexes[0], this.indexes[3] + 1, this.indexes[2], colIdx];
  218. this.startCell = { rowIndex: this.indexes[0], colIndex: this.indexes[1] };
  219. this.endCell = { rowIndex: this.indexes[2], colIndex: colIdx };
  220. break;
  221. case this.indexes[1] > colIdx && this.indexes[0] - rowIdx <= this.indexes[1] - colIdx && rowIdx - this.indexes[2] < this.indexes[1] - colIdx:
  222. this.direction = "left";
  223. left = ej.spreadsheet.getCellPosition(sheet, [rowIdx - 1, colIdx], freezeRow, freezeCol).left;
  224. width = this.left - left;
  225. this.updateBorderDirection('Right');
  226. this.bdrAF.style.top = this.top + px;
  227. this.bdrAF.style.left = left + px;
  228. this.bdrAF.style.height = this.selOffset.height + px;
  229. this.bdrAF.style.width = width + px;
  230. this.fIndexes = [this.indexes[0], colIdx, this.indexes[2], this.indexes[3] - 1];
  231. this.startCell = { rowIndex: this.indexes[0], colIndex: colIdx };
  232. this.endCell = { rowIndex: this.indexes[2], colIndex: this.indexes[3] };
  233. break;
  234. case this.indexes[0] > rowIdx:
  235. this.direction = "up";
  236. top = ej.spreadsheet.getCellPosition(sheet, [rowIdx, colIdx - 1], freezeRow, freezeCol).top;
  237. height = this.top - top;
  238. this.updateBorderDirection('Bottom');
  239. this.bdrAF.style.top = top + px;
  240. this.bdrAF.style.left = this.left + px;
  241. this.bdrAF.style.height = height + px;
  242. this.bdrAF.style.width = this.selOffset.width + px;
  243. this.fIndexes = [rowIdx, this.indexes[1], this.indexes[0] - 1, this.indexes[3]];
  244. this.startCell = { rowIndex: rowIdx, colIndex: this.indexes[1] };
  245. this.endCell = { rowIndex: this.indexes[2], colIndex: this.indexes[3] };
  246. break;
  247. case this.indexes[2] < rowIdx:
  248. this.direction = "down";
  249. top = this.top + this.selOffset.height;
  250. height = ej.spreadsheet.getCellPosition(sheet, [rowIdx + 1, colIdx - 1], freezeRow, freezeCol).top - (this.top + this.selOffset.height);
  251. this.updateBorderDirection('Top');
  252. this.bdrAF.style.top = top + px;
  253. this.bdrAF.style.left = this.left + px;
  254. this.bdrAF.style.height = height + px;
  255. this.bdrAF.style.width = this.selOffset.width + px;
  256. this.fIndexes = [this.indexes[2] + 1, this.indexes[1], rowIdx, this.indexes[3]];
  257. this.startCell = { rowIndex: this.indexes[0], colIndex: this.indexes[1] };
  258. this.endCell = { rowIndex: rowIdx, colIndex: this.indexes[3] };
  259. break;
  260. default:
  261. this.direction = undefined;
  262. break;
  263. }
  264. this.prevTarget = e.target;
  265. this.drawAutoFill(e);
  266. }
  267. drawAutoFill(e) {
  268. }
  269. selected(e) {
  270. this.range = e.range;
  271. this.updateAutofill();
  272. }
  273. beforeSelect(e) {
  274. if (this.isDrag) {
  275. e.cancel = true;
  276. }
  277. this.hideAutofill();
  278. }
  279. created() {
  280. ej.base.EventHandler.add(this.base.ssObj.element, 'mouseup', this.mouseUp, this);
  281. ej.base.EventHandler.add(this.base.ssObj.element, 'keydown', this.keypress, this);
  282. ej.base.EventHandler.add(this.base.ssObj.element, 'dblclick', this.dblClick, this);
  283. }
  284. keypress() {
  285. this.updateAutofill();
  286. }
  287. autoFill() {
  288. let options = {};
  289. let sheetIdx = this.base.getSheetIndex();
  290. options.sheetIdx = sheetIdx;
  291. options.dataRange = this.indexes;
  292. options.fillRange = this.fIndexes;
  293. this.base.ssObj.updateUndoRedoCollection({ name: 'bizAction', args: { action: 'autofill', options: options, direction: this.direction, oldCells: this.base.getCellsFromIndexes(options.fillRange) } });
  294. this.applyValues(options);
  295. this.base.ssObj.selectRange(this.base.generateHeaderText(this.startCell.colIndex + 1) + (this.startCell.rowIndex + 1) + ':' + this.base.generateHeaderText(this.endCell.colIndex + 1) + (this.endCell.rowIndex + 1));
  296. let args = { action: "autofill" };
  297. Unibase.Apps.Collaboration.Components.Common.Download.Instance().ssAutoSave(args, this.base, true);
  298. this.updateAutofill();
  299. }
  300. applyAutofill(options, direction) {
  301. this.direction = direction;
  302. this.applyValues(options);
  303. this.direction = undefined;
  304. }
  305. applyValues(options) {
  306. let pos = { Down: 'down', Up: 'up', Left: 'left', Right: 'right' };
  307. let val, plen, patterns, patrn, pRanges, patrnRange, fillRange, cellObjs, data, temp, dlen, j, k, l, tlen, tot, hasRef, format, formats, cells, clen, cellIdx, cellProps, i = 0, dataObj = {};
  308. let drSR = options.dataRange[0];
  309. let drSC = options.dataRange[1];
  310. let drER = options.dataRange[2];
  311. let drEC = options.dataRange[3];
  312. let frSR = options.fillRange[0];
  313. let frSC = options.fillRange[1];
  314. let frER = options.fillRange[2];
  315. let frEC = options.fillRange[3];
  316. let isVFill = [pos.Down, pos.Up].indexOf(this.direction) > -1;
  317. let isRFill = [pos.Up, pos.Left].indexOf(this.direction) > -1;
  318. let sheet = this.base.ssObj.biz.getActiveSheet();
  319. let len = isVFill ? drEC - drSC : drER - drSR;
  320. while (i <= len) {
  321. pRanges = this.updateFillValues(isVFill, drSR, drSC, drER, drEC, frSR, frSC, frER, frEC, i);
  322. patrnRange = pRanges.patrnRange;
  323. fillRange = pRanges.fillRange;
  324. patterns = this.createPattern(patrnRange, { isRFill: isRFill, isVFill: isVFill });
  325. cellObjs = this.getData(patrnRange);
  326. data = this.getRawData(cellObjs);
  327. dlen = data.length;
  328. if (!patterns)
  329. return;
  330. plen = patterns.length;
  331. cells = this.getSelectedRange({ rowIndex: fillRange[0], colIndex: fillRange[1] }, { rowIndex: fillRange[2], colIndex: fillRange[3] });
  332. clen = cells.length;
  333. if (isRFill) {
  334. cells = cells.reverse();
  335. patterns = patterns.reverse();
  336. patterns = this.ensurePattern(patterns);
  337. cellObjs = cellObjs.reverse();
  338. data = data.reverse();
  339. }
  340. j = 0;
  341. while (j < clen) {
  342. dataObj = {};
  343. cellIdx = cells[j];
  344. patrn = patterns[j % plen];
  345. if (this.isNumber(patrn))
  346. patrn = patterns[patrn];
  347. switch (patrn.type) {
  348. case this.colType.Number:
  349. val = this.round(patrn.regVal.a + (patrn.regVal.b * patrn.i), 5);
  350. if (isRFill)
  351. patrn.i--;
  352. else
  353. patrn.i++;
  354. break;
  355. case this.colType.String:
  356. val = patrn.val[patrn.i % patrn.val.length];
  357. patrn.i++;
  358. break;
  359. case this.colType.Formula:
  360. hasRef = false;
  361. val = "=";
  362. k = 0;
  363. tlen = patrn.val.length;
  364. while (k < tlen) {
  365. temp = patrn.val[k];
  366. if (this.isObject(temp)) {
  367. hasRef = true;
  368. tot = this.round(temp.a + (temp.b * patrn.i), 0);
  369. if (tot < 1)
  370. val += "#REF!";
  371. else
  372. val += isVFill ? temp.c + (temp.b ? tot : '$' + tot) : (temp.b ? this.base.generateHeaderText(tot) : '$' + this.base.generateHeaderText(tot)) + temp.c;
  373. }
  374. else
  375. val += temp;
  376. k++;
  377. }
  378. if (hasRef && isRFill)
  379. patrn.i--;
  380. else
  381. patrn.i++;
  382. break;
  383. case this.colType.Custom:
  384. val = this.round(patrn.regVal.a + (patrn.regVal.b * patrn.i), 0);
  385. if (val < 0)
  386. val = (val % patrn.len) + patrn.len;
  387. if (val >= patrn.len)
  388. val = val % patrn.len;
  389. val = patrn.val[val];
  390. if (isRFill)
  391. patrn.i--;
  392. else
  393. patrn.i++;
  394. break;
  395. }
  396. l = j % dlen;
  397. let cell = ej.spreadsheet.getCell(cellIdx.rowIndex, cellIdx.colIndex, sheet);
  398. if (cellObjs[l]) {
  399. cell = this.formObjFromValues(cellObjs[l], ['style', 'format', 'wrap', 'isLocked', 'validation', 'hyperlink',]);
  400. cell['value'] = val;
  401. }
  402. else {
  403. cell = {};
  404. }
  405. this.base.ssObj.biz.setCell(cellIdx.rowIndex, cellIdx.colIndex, sheet, cell);
  406. if (cell.validation && cell.validation.isHighlighted) {
  407. this.base.ssObj.addInvalidHighlight(this.base.generateHeaderText(cellIdx.colIndex + 1) + (cellIdx.rowIndex + 1));
  408. }
  409. j++;
  410. }
  411. i++;
  412. }
  413. let args = { options: options, direction: this.direction, action: 'autofill', origin: 'biz', sheetIndex: this.base.getSheetIndex() };
  414. Unibase.Apps.Collaboration.Components.Sheets.Base.Instance().bizSignalr(args);
  415. }
  416. formObjFromValues(cellObj, props) {
  417. let obj = {};
  418. for (let i = 0; i < props.length; i++) {
  419. if (cellObj[props[i]]) {
  420. obj[props[i]] = cellObj[props[i]];
  421. }
  422. }
  423. return obj;
  424. }
  425. updateFillValues(isVFill, drSR, drSC, drER, drEC, frSR, frSC, frER, frEC, i) {
  426. let pStart, pEnd, fStart, fEnd, patrnRange, fillRange;
  427. if (isVFill) {
  428. pStart = { rowIndex: drSR, colIndex: drSC + i };
  429. pEnd = { rowIndex: drER, colIndex: drSC + i };
  430. fStart = { rowIndex: frSR, colIndex: frSC + i };
  431. fEnd = { rowIndex: frER, colIndex: frSC + i };
  432. }
  433. else {
  434. pStart = { rowIndex: drSR + i, colIndex: drSC };
  435. pEnd = { rowIndex: drSR + i, colIndex: drEC };
  436. fStart = { rowIndex: frSR + i, colIndex: frSC };
  437. fEnd = { rowIndex: frSR + i, colIndex: frEC };
  438. }
  439. patrnRange = [pStart.rowIndex, pStart.colIndex, pEnd.rowIndex, pEnd.colIndex];
  440. fillRange = [fStart.rowIndex, fStart.colIndex, fEnd.rowIndex, fEnd.colIndex];
  441. return { patrnRange: patrnRange, fillRange: fillRange };
  442. }
  443. createPattern(range, options) {
  444. let j, idx, temp, regVal, custColl, lCaseColl, lCaseVal, isLCase, diff, len, i = 0, pattern = [];
  445. let patrns = this.createDataPattern(range);
  446. let plen = patrns.length;
  447. let patrn;
  448. if (patrns) {
  449. while (i < plen) {
  450. patrn = patrns[i];
  451. switch (patrn.type) {
  452. case this.colType.Number:
  453. idx = pattern.length;
  454. len = patrn.val.length;
  455. diff = options.isRFill ? -1 : len;
  456. if (len === 1)
  457. patrn.val.push(patrn.val[0] + 1);
  458. regVal = this.getPredictionValue(patrn.val);
  459. temp = { regVal: regVal, type: patrn.type, i: diff };
  460. pattern.push(temp);
  461. j = 1;
  462. while (j < len) {
  463. pattern.push(idx);
  464. j++;
  465. }
  466. break;
  467. case this.colType.String:
  468. idx = pattern.length;
  469. temp = { val: patrn.val, type: patrn.type, i: 0 };
  470. pattern.push(temp);
  471. j = 1;
  472. len = patrn.val.length;
  473. while (j < len) {
  474. pattern.push(idx);
  475. j++;
  476. }
  477. break;
  478. case this.colType.Formula:
  479. len = patrn.val.length;
  480. patrn = this.createFormulaPattern(patrn.val, options);
  481. diff = options.isRFill ? -1 : len;
  482. if (patrn.isInPattern) {
  483. idx = pattern.length;
  484. temp = { val: patrn.val, type: this.colType.Formula, i: diff };
  485. pattern.push(temp);
  486. j = 1;
  487. while (j < len) {
  488. pattern.push(idx);
  489. j++;
  490. }
  491. }
  492. else {
  493. j = 0;
  494. diff = options.isRFill ? -1 : 1;
  495. while (j < len) {
  496. pattern.push({ val: patrn.val[j], type: this.colType.Formula, i: diff });
  497. j++;
  498. }
  499. }
  500. break;
  501. }
  502. i++;
  503. }
  504. return pattern;
  505. }
  506. }
  507. createDataPattern(range) {
  508. let val, type, i = 0;
  509. let obj = {};
  510. let patrn = [];
  511. let cellObjs;
  512. cellObjs = this.getData(range);
  513. let data = this.getRawData(cellObjs);
  514. let dlen = data.length;
  515. if (dlen) {
  516. while (i < dlen) {
  517. val = data[i];
  518. type = this.getType(val);
  519. if (i === 0)
  520. obj = { val: [val], type: type };
  521. else if (type === obj.type)
  522. obj.val.push(val);
  523. else {
  524. patrn.push(obj);
  525. obj = { val: [val], type: type };
  526. }
  527. i++;
  528. }
  529. patrn.push(obj);
  530. return patrn;
  531. }
  532. }
  533. createFormulaPattern(data, options) {
  534. let patrn, j, temp, isInPatrn, patrns = [], i = 0, len = data.length, cRfrType;
  535. while (i < len) {
  536. patrns.push(this.parseFormula(data[i]));
  537. i++;
  538. }
  539. isInPatrn = this.isInPattern(patrns, options.isVFill);
  540. if (isInPatrn) {
  541. patrn = patrns[0];
  542. i = patrn.length;
  543. while (i--) {
  544. temp = patrn[i];
  545. cRfrType = this.isCellReference(temp);
  546. if (cRfrType && (cRfrType !== "absolute"))
  547. patrn[i] = this.getCellRefPrediction(temp, options, null, cRfrType);
  548. }
  549. return { isInPattern: isInPatrn, val: patrn };
  550. }
  551. else {
  552. i = 0;
  553. while (i < len) {
  554. patrn = patrns[i];
  555. j = patrn.length;
  556. while (j--) {
  557. temp = patrn[j];
  558. cRfrType = this.isCellReference(temp);
  559. if (cRfrType && (cRfrType !== "absolute"))
  560. patrns[i][j] = this.getCellRefPrediction(temp, options, len, cRfrType);
  561. }
  562. i++;
  563. }
  564. return { isInPattern: isInPatrn, val: patrns };
  565. }
  566. }
  567. parseFormula(formula) {
  568. var temp, str, len, i = 0, arr = [];
  569. formula = this.markSpecialChar(formula.replace("=", ""));
  570. formula = formula.split(/\(|\)|=|\^|>|<|,|:|\+|-|\*|\/|%|&/g);
  571. len = formula.length;
  572. while (i < len) {
  573. temp = formula[i];
  574. if (!temp) {
  575. i++;
  576. continue;
  577. }
  578. if (temp.length === 1)
  579. arr.push(this.isUniqueChar(temp) ? this.getUniqueCharVal(temp) : temp);
  580. else {
  581. str = temp[0];
  582. if (temp.indexOf('!') > 0) {
  583. if (this.isUniqueChar(str)) {
  584. arr.push(this.getUniqueCharVal(str));
  585. temp = temp.substr(1);
  586. }
  587. str = temp.indexOf('!') + 1;
  588. arr.push(temp.substr(0, str));
  589. arr.push(temp.substr(str));
  590. }
  591. else if (this.isUniqueChar(str)) {
  592. arr.push(this.getUniqueCharVal(str));
  593. arr.push(temp.substr(1));
  594. }
  595. else
  596. arr.push(temp);
  597. }
  598. i++;
  599. }
  600. return arr;
  601. }
  602. getUniqueCharVal(str) {
  603. switch (str) {
  604. case this.UC.uniqueOBracket:
  605. return "(";
  606. case this.UC.uniqueCBracket:
  607. return ")";
  608. case this.UC.uniqueCSeparator:
  609. return ",";
  610. case this.UC.uniqueCOperator:
  611. return ':';
  612. case this.UC.uniquePOperator:
  613. return "+";
  614. case this.UC.uniqueSOperator:
  615. return "-";
  616. case this.UC.uniqueMOperator:
  617. return "*";
  618. case this.UC.uniqueDOperator:
  619. return "/";
  620. case this.UC.uniqueModOperator:
  621. return "%";
  622. case this.UC.uniqueConcateOperator:
  623. return "&";
  624. case this.UC.uniqueEqualOperator:
  625. return "=";
  626. case this.UC.uniqueExpOperator:
  627. return "^";
  628. case this.UC.uniqueGTOperator:
  629. return ">";
  630. case this.UC.uniqueLTOperator:
  631. return "<";
  632. }
  633. return "";
  634. }
  635. isUniqueChar(str) {
  636. var code = str.charCodeAt(str);
  637. return code >= 129 && code <= 142;
  638. }
  639. markSpecialChar(formula) {
  640. formula = formula.replace(/\(/g, "(" + this.UC.uniqueOBracket).replace(/\)/g, ")" + this.UC.uniqueCBracket);
  641. formula = formula.replace(/,/g, "," + this.UC.uniqueCSeparator).replace(/:/g, ":" + this.UC.uniqueCOperator);
  642. formula = formula.replace(/\+/g, "+" + this.UC.uniquePOperator).replace(/-/g, "-" + this.UC.uniqueSOperator);
  643. formula = formula.replace(/\*/g, "*" + this.UC.uniqueMOperator).replace(/\//g, "/" + this.UC.uniqueDOperator);
  644. formula = formula.replace(/&/g, "&" + this.UC.uniqueConcateOperator);
  645. formula = formula.replace(/=/g, "=" + this.UC.uniqueEqualOperator);
  646. formula = formula.replace(/\^/g, "^" + this.UC.uniqueExpOperator);
  647. formula = formula.replace(/>/g, ">" + this.UC.uniqueGTOperator).replace(/</g, "<" + this.UC.uniqueLTOperator);
  648. return formula.replace(/%/g, "%" + this.UC.uniqueModOperator);
  649. }
  650. isInPattern(patrn, isVFill) {
  651. var oldPatrn, olen, newPatrn, nlen, oldStr, newStr, oldInt, newInt, eStr = "", i = 0, j = 1, plen = patrn.length, nregx = new RegExp("[0-9$]", "g"), aregx = new RegExp("[a-z$]", "gi");
  652. if (plen === 1)
  653. return false;
  654. while (j < plen) {
  655. oldPatrn = patrn[i];
  656. newPatrn = patrn[j];
  657. olen = oldPatrn.length;
  658. nlen = newPatrn.length;
  659. if (olen !== nlen)
  660. return false;
  661. else {
  662. while (olen--) {
  663. oldStr = oldPatrn[olen];
  664. newStr = newPatrn[olen];
  665. if (this.isCellReference(oldStr) === this.isCellReference(newStr)) {
  666. if (isVFill) {
  667. oldInt = Number(oldStr.replace(aregx, eStr));
  668. newInt = Number(newStr.replace(aregx, eStr));
  669. }
  670. else {
  671. oldInt = this.generateColCount(oldStr.replace(nregx, eStr));
  672. newInt = this.generateColCount(newStr.replace(nregx, eStr));
  673. }
  674. if (oldInt !== newInt - 1)
  675. return false;
  676. }
  677. else if (oldStr !== newStr)
  678. return false;
  679. }
  680. }
  681. i++;
  682. j++;
  683. }
  684. return true;
  685. }
  686. generateColCount(text) {
  687. var colCount = 0;
  688. text = text.split('').reverse().join('');
  689. for (var i = text.length - 1; i >= 0; i--) {
  690. colCount += (text[i].charCodeAt(text[i]) - 64) * (Math.pow(26, i));
  691. }
  692. return colCount;
  693. }
  694. getData(range) {
  695. let sheet = this.base.ssObj.biz.getActiveSheet();
  696. let data = [];
  697. let obj;
  698. let newRange = this.base.swapRange(range);
  699. for (let i = newRange[0]; i <= newRange[2]; i++) {
  700. for (let j = newRange[1]; j <= newRange[3]; j++) {
  701. obj = sheet.rows[i] ? sheet.rows[i].cells[j] : undefined;
  702. data.push(obj);
  703. }
  704. }
  705. return data;
  706. }
  707. getRawData(arr) {
  708. let len = arr.length;
  709. let newArr = [];
  710. for (let i = 0; i < len; i++) {
  711. if (!arr[i] || !arr[i].value || arr[i].value.length === 0) {
  712. newArr.push('');
  713. }
  714. else if (arr[i].formula) {
  715. newArr.push(arr[i].formula);
  716. }
  717. else if (arr[i].value) {
  718. newArr.push(arr[i].value);
  719. }
  720. }
  721. return newArr;
  722. }
  723. isCellReference(text) {
  724. return /^[a-z]{1,3}\d{1,7}$/gi.test(text) ? "relative" : (/^\$[a-z]{1,3}\$\d{1,7}$/gi.test(text) ? "absolute" : (/^((\$[a-z]{1,3})\d{1,7}|[a-z]{1,3}(\$\d{1,7}))$/gi.test(text) ? "mixed" : false));
  725. }
  726. getCellRefPrediction(text, options, length, rfrType) {
  727. text = text.toUpperCase();
  728. var eStr = "", aRegx = new RegExp("[a-z$]", "gi"), nRegx = new RegExp("[0-9$]", "g"), str = options.isVFill ? text.replace(nRegx, eStr) : text.replace(aRegx, eStr);
  729. let temp = options.isVFill ? Number(text.replace(aRegx, eStr)) : this.generateColCount(text.replace(nRegx, eStr)), arr = [temp], isColAbslt = text[0] === '$';
  730. if (length && length !== 1)
  731. arr.push(temp + length);
  732. else
  733. arr.push(temp + 1);
  734. temp = this.getPredictionValue(arr);
  735. if (rfrType && (rfrType === "mixed")) {
  736. if (isColAbslt === options.isVFill)
  737. str = '$' + str;
  738. else
  739. temp.b = 0;
  740. }
  741. temp.c = str;
  742. return temp;
  743. }
  744. getType(val) {
  745. let type1;
  746. let type = this.isCustomType(val);
  747. if (type)
  748. type1 = type;
  749. else if (this.isFormula(val))
  750. type1 = this.colType.Formula;
  751. else if (this.isNumber(val))
  752. type1 = this.colType.Number;
  753. return type1 || this.colType.String;
  754. }
  755. isCustomType(val) {
  756. val = val + "";
  757. val = val.toLowerCase();
  758. let i = this.customList.length;
  759. while (i--) {
  760. if (this.toArrayLowerCase(this.customList[i].slice(0)).indexOf(val) > -1)
  761. return this.colType.Custom + i;
  762. }
  763. return false;
  764. }
  765. toArrayLowerCase(args) {
  766. for (let i = 0; i < args.length; i++)
  767. args[i] = args[i].toString().toLowerCase();
  768. return args;
  769. }
  770. isFormula(formula) {
  771. let obrackets, cbrackets;
  772. if (formula) {
  773. if (!formula.toString().indexOf("=") && formula.length > 1) {
  774. obrackets = formula.split("(").length - 1;
  775. cbrackets = formula.split(")").length - 1;
  776. return obrackets === cbrackets;
  777. }
  778. }
  779. return false;
  780. }
  781. isNumber(val) {
  782. return val - parseFloat(val) >= 0;
  783. }
  784. round(val, digits) {
  785. let str = val + 'e' + digits;
  786. let str1 = 'e-' + digits;
  787. return Number(Math.round(str) + str1);
  788. }
  789. getPredictionValue(args) {
  790. let i = 0, sumx = 0, sumy = 0, sumxy = 0, sumxx = 0, n = args.length;
  791. while (i < n) {
  792. sumx = sumx + i;
  793. sumy = sumy + Number(args[i]);
  794. sumxy = sumxy + (i * Number(args[i]));
  795. sumxx = sumxx + (i * i);
  796. i++;
  797. }
  798. let a = this.round(((sumy * sumxx) - (sumx * sumxy)) / ((n * sumxx) - (sumx * sumx)), 5), b = this.round(((n * sumxy) - (sumx * sumy)) / ((n * sumxx) - (sumx * sumx)), 5);
  799. return { a: a, b: b };
  800. }
  801. ensurePattern(patterns) {
  802. let patrn, idx = -1, i = patterns.length;
  803. while (i--) {
  804. patrn = patterns[i];
  805. if (this.isObject(patrn)) {
  806. idx = i;
  807. if (patrn.type === this.colType.String)
  808. patrn.val = patrn.val.reverse();
  809. }
  810. else
  811. patterns[i] = idx;
  812. }
  813. return patterns;
  814. }
  815. isObject(obj) {
  816. if (typeof obj !== "object")
  817. return false;
  818. return Object.prototype.toString.call(obj) === "[object Object]";
  819. }
  820. getSelectedRange(startcell, endcell) {
  821. let i, j, k, l, arr = [], range = this.base.swapRange([startcell.rowIndex, startcell.colIndex, endcell.rowIndex, endcell.colIndex]);
  822. i = range[0], j = range[2];
  823. while (i <= j) {
  824. k = range[1];
  825. l = range[3];
  826. while (k <= l) {
  827. arr.push({ rowIndex: i, colIndex: k });
  828. k++;
  829. }
  830. i++;
  831. }
  832. return arr;
  833. }
  834. static Instance() {
  835. if (this.instance === undefined) {
  836. this.instance = new Autofill();
  837. }
  838. return this.instance;
  839. }
  840. }
  841. Sheets.Autofill = Autofill;
  842. })(Sheets = Components.Sheets || (Components.Sheets = {}));
  843. })(Components = Collaboration.Components || (Collaboration.Components = {}));
  844. })(Collaboration = Apps.Collaboration || (Apps.Collaboration = {}));
  845. })(Apps = Unibase.Apps || (Unibase.Apps = {}));
  846. })(Unibase || (Unibase = {}));