UNPKG

react-microspreadsheet

Version:

A pluggable spreadsheet component.

764 lines (684 loc) 23.1 kB
// Generated by CoffeeScript 1.8.0 var Mori, RawStore, Store, expandPattern, recalc, selix, store, utils, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; Store = require('./base-store'); Mori = require('mori'); utils = require('./utils'); selix = require('selix'); RawStore = (function(_super) { __extends(RawStore, _super); function RawStore() { return RawStore.__super__.constructor.apply(this, arguments); } RawStore.prototype.cells = Mori.js_to_clj([ [ { raw: '', calc: '' }, { raw: '', calc: '' }, { raw: '', calc: '' } ], [ { raw: '', calc: '' }, { raw: '', calc: '' }, { raw: '', calc: '' } ], [ { raw: '', calc: '' }, { raw: '', calc: '' }, { raw: '', calc: '' } ] ]); RawStore.prototype.selectedCoord = [0, 0]; RawStore.prototype.multi = [[0, 0], [0, 0]]; RawStore.prototype.selectingMulti = false; RawStore.prototype.strapping = false; RawStore.prototype.strapVector = [null, null, null]; RawStore.prototype.editingCoord = null; RawStore.prototype.volatileEdit = false; RawStore.prototype.refEdit = false; RawStore.prototype.caretPosition = null; RawStore.prototype.select = function(coord) { this.selectedCoord = coord; return this.multi = [coord, coord]; }; RawStore.prototype.edit = function(coord) { this.editingCoord = coord; this.selectingMulti = false; this.caretPosition = null; this.volatileEdit = false; return this.refEdit = false; }; RawStore.prototype.getCells = function() { var cells, highlight, i, j, _i, _j, _ref, _ref1, _ref2, _ref3; cells = Mori.assoc_in(this.cells, this.selectedCoord.concat('selected'), true); if (this.editingCoord) { cells = Mori.assoc_in(cells, this.editingCoord.concat('editing'), true); } if (this.strapVector[1] !== null) { highlight = [utils.firstCellFromMulti(this.multi), utils.lastCellFromMulti(this.multi)]; highlight[this.strapVector[1]][this.strapVector[0]] += this.strapVector[2]; } else { highlight = this.multi; } for (i = _i = _ref = highlight[0][0], _ref1 = highlight[1][0]; _ref <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = _ref <= _ref1 ? ++_i : --_i) { for (j = _j = _ref2 = highlight[0][1], _ref3 = highlight[1][1]; _ref2 <= _ref3 ? _j <= _ref3 : _j >= _ref3; j = _ref2 <= _ref3 ? ++_j : --_j) { cells = Mori.assoc_in(cells, [i, j, 'multi'], true); } } cells = Mori.assoc_in(cells, utils.lastCellFromMulti(store.multi).concat('last-multi'), true); return cells; }; RawStore.prototype.undoStates = Mori.list(); RawStore.prototype.redoStates = Mori.list(); RawStore.prototype.canUndo = false; RawStore.prototype.canRedo = false; RawStore.prototype.redo = function() { if (store.canRedo) { store.undoStates = Mori.conj(store.undoStates, Mori.first(store.redoStates)); store.cells = Mori.first(store.redoStates); store.redoStates = Mori.drop(1, store.redoStates); store.canRedo = !Mori.is_empty(store.redoStates); return store.canUndo = true; } }; RawStore.prototype.undo = function() { if (store.canUndo) { store.redoStates = Mori.conj(store.redoStates, Mori.first(this.undoStates)); store.undoStates = Mori.drop(1, store.undoStates); store.cells = Mori.first(store.undoStates); store.canUndo = !Mori.is_empty(store.undoStates); return store.canRedo = true; } }; RawStore.prototype.clipboard = false; RawStore.prototype.rawClipboard = {}; return RawStore; })(Store); store = new RawStore; store.registerCallback('replace-cells', function(cellsArray) { var newCells, rawValue, row; newCells = Mori.js_to_clj((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = cellsArray.length; _i < _len; _i++) { row = cellsArray[_i]; _results.push((function() { var _j, _len1, _results1; _results1 = []; for (_j = 0, _len1 = row.length; _j < _len1; _j++) { rawValue = row[_j]; _results1.push({ raw: rawValue, calc: '' }); } return _results1; })()); } return _results; })()); store.cells = newCells; store.edit(null); store.select([0, 0]); recalc(); return store.changed(); }); store.registerCallback('new-cell-value', function(value) { store.cells = Mori.assoc_in(store.cells, store.editingCoord.concat('raw'), value); store.caretPosition = null; store.refEdit = true; store.changed(); return store.rawClipboard = {}; }); store.registerCallback('input-clicked', function(element) { var caret; caret = selix.getCaret(element); if (caret.end === caret.start) { store.caretPosition = caret.end; } store.volatileEdit = false; return store.refEdit = true; }); store.registerCallback('input-selecttext', function(element) { if (selix.getText(element)) { return store.refEdit = true; } }); store.registerCallback('input-doubleclicked', function(element) { return store.refEdit = true; }); store.registerCallback('left-keyup', function(e) { if (store.editingCoord && e.target.tagName === 'INPUT') { return store.caretPosition = selix.getCaret(e.target).start; } }); store.registerCallback('right-keyup', function(e) { if (store.editingCoord && e.target.tagName === 'INPUT') { return store.caretPosition = selix.getCaret(e.target).end; } }); store.registerCallback('cell-clicked', function(coord) { var addr, valueBeingEdited; if (store.editingCoord) { valueBeingEdited = Mori.get_in(store.cells, store.editingCoord.concat('raw')); if (valueBeingEdited[0] === '=' && store.refEdit || store.volatileEdit) { addr = utils.getAddressFromCoord(coord); store.cells = Mori.update_in(store.cells, store.editingCoord.concat('raw'), function(val) { var caretPosition, left, leftMatch, right, rightMatch; caretPosition = store.caretPosition === null ? val.length : store.caretPosition; left = val.substr(0, caretPosition); right = val.substr(caretPosition); leftMatch = /[+-\/:;.*(=^><!]([A-Za-z]?\d{0,2})$/.exec(left); rightMatch = /^([A-Za-z]?\d{0,2})([+-\/:;.*)=^><!]|$)/.exec(right); if (!leftMatch || !rightMatch) { return val; } if ((leftMatch[1] || rightMatch[1]) && (!/[A-Za-z]\d{1,2}/.exec(leftMatch[1] + rightMatch[1]))) { return val; } left = left.replace(/([+-/:;.*(=^><!])[^+-/:;.*(=^><!]*$/, '$1'); right = right.replace(/^[^+-/:;.*^><!)]*([+-/:;.*)^><!]|$)/, '$1'); store.caretPosition = (left + addr).length; return left + addr + right; }); } else { store.select(coord); store.edit(null); recalc(); } return store.changed(); } }); store.registerCallback('cell-mousedown', function(coord) { if (!store.editingCoord) { store.select(coord); store.changed(); return store.selectingMulti = true; } }); store.registerCallback('cell-mouseenter', function(coord) { var x, y, _i, _j, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _results, _results1; if (store.selectingMulti) { store.multi = [store.selectedCoord, coord]; return store.changed(); } else if (store.strapping) { /* check if coord is at the same vertical or horizontal lines of the multi-selection example: store.multi = [[3,1], [4,2]] coord[0] must be within the range 3-4 -> same horizontal line coord[1] must be within the range 1-2 -> same vertical line the strapping zone will be described by a tuple of [ direction -> either 0 for 'vertical' or 1 for 'horizontal' (this is because the first element (0) of any coord array describes the number of rows, the second (1) describes the number of columns) sense -> either 0 for 'left' or 'top' or 1 for 'right' or 'bottom' ( this is because in the normalized store.multi, the first cell (0) will describe the leftmost and uppermost point, the second cell (1) will describe the rightmost and bottommost point, which we will modify accordingly) magnitude -> an integer describing how many columns/rows ocuppy the strapping zone beggining where the multi-selection ends and extending to where the mouse is. ] */ if (_ref = coord[0], __indexOf.call((function() { _results = []; for (var _i = _ref1 = store.multi[0][0], _ref2 = store.multi[1][0]; _ref1 <= _ref2 ? _i <= _ref2 : _i >= _ref2; _ref1 <= _ref2 ? _i++ : _i--){ _results.push(_i); } return _results; }).apply(this), _ref) >= 0) { /* horizontal in this case, we must check if the zone will be to the left of the current selection or to the right, and the magnitude of the vector example: store.multi = [[5,2], [3,3]] we get the minimum of (coord[1] - 3), (coord[1] - 2) if they are positive and the maximum, if they are negative. the result will be the magnitude, the sense will be 0 if the result is negative, 1 if it is positive. */ x = coord[1] - store.multi[0][1]; y = coord[1] - store.multi[1][1]; if (x > 0) { store.strapVector = [1, 1, Math.min(x, y)]; } else if (x < 0) { store.strapVector = [1, 0, Math.max(x, y)]; } } else if (_ref3 = coord[1], __indexOf.call((function() { _results1 = []; for (var _j = _ref4 = store.multi[0][1], _ref5 = store.multi[1][1]; _ref4 <= _ref5 ? _j <= _ref5 : _j >= _ref5; _ref4 <= _ref5 ? _j++ : _j--){ _results1.push(_j); } return _results1; }).apply(this), _ref3) >= 0) { /* vertical the procedure is analogal with the horizontal. but instead we use coord[0] */ x = coord[0] - store.multi[0][0]; y = coord[0] - store.multi[1][0]; if (x > 0) { store.strapVector = [0, 1, Math.min(x, y)]; } else if (x < 0) { store.strapVector = [0, 0, Math.max(x, y)]; } } return store.changed(); } }); store.registerCallback('cell-mouseup', function(coord) { if (!store.editingCoord) { store.selectingMulti = false; if (store.strapping && store.strapVector[1] !== null) { expandPattern(); store.multi = [utils.firstCellFromMulti(store.multi), utils.lastCellFromMulti(store.multi)]; store.multi[store.strapVector[1]][store.strapVector[0]] += store.strapVector[2]; store.strapping = false; store.strapVector = [null, null, null]; recalc(); return store.changed(); } } }); store.registerCallback('strap-mousedown', function(coord) { if (!store.editingCoord) { store.strapping = true; return store.changed(); } }); store.registerCallback('cell-doubleclicked', function(coord) { store.select(coord); store.edit(coord); if (!Mori.get_in(store.cells, coord.concat('raw'))) { store.volatileEdit = true; } return store.changed(); }); store.registerCallback('down', function(e) { e.preventDefault(); if (store.editingCoord) { store.edit(null); recalc(); } if (store.selectedCoord[0] < (Mori.count(store.cells) - 1)) { store.select([store.selectedCoord[0] + 1, store.selectedCoord[1]]); } return store.changed(); }); store.registerCallback('up', function(e) { e.preventDefault(); if (store.editingCoord) { store.edit(null); recalc(); } if (store.selectedCoord[0] > 0) { store.select([store.selectedCoord[0] - 1, store.selectedCoord[1]]); } return store.changed(); }); store.registerCallback('tab', function(e) { e.preventDefault(); if (store.editingCoord) { store.edit(null); recalc(); } if (store.selectedCoord[1] === (Mori.count(Mori.get(store.cells, 0)) - 1)) { if (store.selectedCoord[0] + 1 <= (Mori.count(store.cells) - 1)) { store.select([store.selectedCoord[0] + 1, 0]); return store.changed(); } } else { return store.triggerCallback('right', e); } }); store.registerCallback('left', function(e) { if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { if (store.selectedCoord[1] > 0) { store.select([store.selectedCoord[0], store.selectedCoord[1] - 1]); } return store.changed(); } }); store.registerCallback('right', function(e) { if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { if (store.selectedCoord[1] < (Mori.count(Mori.get(store.cells, 0)) - 1)) { store.select([store.selectedCoord[0], store.selectedCoord[1] + 1]); } return store.changed(); } }); store.registerCallback('all-right', function() { if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { store.select([store.selectedCoord[0], Mori.count(Mori.get(store.cells, 0)) - 1]); } return store.changed(); }); store.registerCallback('all-down', function() { if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { store.select([Mori.count(store.cells) - 1, store.selectedCoord[1]]); } return store.changed(); }); store.registerCallback('all-up', function() { if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { store.select([0, store.selectedCoord[1]]); } return store.changed(); }); store.registerCallback('all-left', function() { if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { store.select([store.selectedCoord[0], 0]); } return store.changed(); }); store.registerCallback('select-down', function(e) { var edge; if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { e.preventDefault(); edge = store.multi[1]; if (edge[0] < (Mori.count(store.cells) - 1)) { store.multi = [store.selectedCoord, [edge[0] + 1, edge[1]]]; } return store.changed(); } }); store.registerCallback('select-up', function(e) { var edge; if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { e.preventDefault(); edge = store.multi[1]; if (edge[0] > 0) { store.multi = [store.selectedCoord, [edge[0] - 1, edge[1]]]; } return store.changed(); } }); store.registerCallback('select-left', function(e) { var edge; if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { e.preventDefault(); edge = store.multi[1]; if (edge[1] > 0) { store.multi = [store.selectedCoord, [edge[0], edge[1] - 1]]; } return store.changed(); } }); store.registerCallback('select-right', function(e) { var edge; if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { e.preventDefault(); edge = store.multi[1]; if (edge[1] < (Mori.count(Mori.get(store.cells, 0)) - 1)) { store.multi = [store.selectedCoord, [edge[0], edge[1] + 1]]; } return store.changed(); } }); store.registerCallback('select-all-right', function(e) { var edge; if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { e.preventDefault(); edge = store.multi[1]; store.multi = [store.selectedCoord, [edge[0], Mori.count(Mori.get(store.cells, 0)) - 1]]; } return store.changed(); }); store.registerCallback('select-all-down', function(e) { var edge; if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { e.preventDefault(); edge = store.multi[1]; store.multi = [store.selectedCoord, [Mori.count(store.cells) - 1, edge[1]]]; } return store.changed(); }); store.registerCallback('select-all-up', function(e) { var edge; if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { e.preventDefault(); edge = store.multi[1]; store.multi = [store.selectedCoord, [0, edge[1]]]; } return store.changed(); }); store.registerCallback('select-all-left', function(e) { var edge; if (store.volatileEdit) { store.edit(null); recalc(); } if (!store.editingCoord) { e.preventDefault(); edge = store.multi[1]; store.multi = [store.selectedCoord, [edge[0], 0]]; } return store.changed(); }); store.registerCallback('del', function() { var i, j, _i, _j, _ref, _ref1, _ref2, _ref3; if (!store.editingCoord) { store.cells = Mori.assoc_in(store.cells, store.selectedCoord.concat('raw'), ''); for (i = _i = _ref = store.multi[0][0], _ref1 = store.multi[1][0]; _ref <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = _ref <= _ref1 ? ++_i : --_i) { for (j = _j = _ref2 = store.multi[0][1], _ref3 = store.multi[1][1]; _ref2 <= _ref3 ? _j <= _ref3 : _j >= _ref3; j = _ref2 <= _ref3 ? ++_j : --_j) { store.cells = Mori.assoc_in(store.cells, [i, j, 'raw'], ''); } } recalc(); return store.changed(); } }); store.registerCallback('letter', function(e) { if (!store.editingCoord) { if (e.ctrlKey || e.metaKey || e.altKey) { return; } store.cells = Mori.assoc_in(store.cells, store.selectedCoord.concat('raw'), String.fromCharCode(e.keyCode || e.charCode)); e.preventDefault(); e.stopPropagation(); store.edit(store.selectedCoord); store.volatileEdit = true; return store.changed(); } }); store.registerCallback('esc', function() { if (store.editingCoord) { store.edit(null); store.undo(); return store.changed(); } }); store.registerCallback('sheet-clicked-out', function() { store.selectingMulti = false; store.multi = [store.selectedCoord, store.selectedCoord]; store.strapping = false; store.strapVector = [null, null, null]; return store.changed(); }); store.registerCallback('sheet-mouseup-out', function() { return store.selectingMulti = false; }); store.registerCallback('undo', function(e) { store.undo(); return store.changed(); }); store.registerCallback('redo', function() { store.redo(); return store.changed(); }); store.registerCallback('before-copypaste', function(e) { var clipCells, clipRows, i, j, multiRearranged, _i, _j, _ref, _ref1, _ref2, _ref3; e.preventDefault(); if (window.getSelection && window.getSelection().toString()) { return; } if (document.selection && document.selection.createRange()) { return; } clipRows = []; multiRearranged = [utils.firstCellFromMulti(store.multi), utils.lastCellFromMulti(store.multi)]; for (i = _i = _ref = multiRearranged[0][0], _ref1 = multiRearranged[1][0]; _ref <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = _ref <= _ref1 ? ++_i : --_i) { clipCells = []; for (j = _j = _ref2 = multiRearranged[0][1], _ref3 = multiRearranged[1][1]; _ref2 <= _ref3 ? _j <= _ref3 : _j >= _ref3; j = _ref2 <= _ref3 ? ++_j : --_j) { clipCells.push(Mori.get_in(store.cells, [i, j, 'calc'])); } clipRows.push(clipCells.join('\t')); } store.clipboard = clipRows.join('\n'); return store.changed(); }); store.registerCallback('cutcopy', function(e) { var clipboard, copied, copiedRows, i, j; clipboard = document.querySelector('.clipboard-container .clipboard'); if (clipboard) { copied = [utils.firstCellFromMulti(store.multi), utils.lastCellFromMulti(store.multi)]; copiedRows = (function() { var _i, _ref, _ref1, _results; _results = []; for (i = _i = _ref = copied[0][0], _ref1 = copied[1][0]; _ref <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = _ref <= _ref1 ? ++_i : --_i) { _results.push((function() { var _j, _ref2, _ref3, _results1; _results1 = []; for (j = _j = _ref2 = copied[0][1], _ref3 = copied[1][1]; _ref2 <= _ref3 ? _j <= _ref3 : _j >= _ref3; j = _ref2 <= _ref3 ? ++_j : --_j) { _results1.push(Mori.get_in(store.cells, [i, j, 'raw'])); } return _results1; })()); } return _results; })(); store.rawClipboard = {}; return store.rawClipboard[selix.getText(clipboard)] = copiedRows; } }); store.registerCallback('clipboardchanged', function(what) { var cell, firstSelected, i, j, pastedCell, pastedRow, pastedRows, qi, qj, row, _i, _j, _k, _l, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; if (what === '') { for (i = _i = _ref = store.multi[0][0], _ref1 = store.multi[1][0]; _ref <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = _ref <= _ref1 ? ++_i : --_i) { for (j = _j = _ref2 = store.multi[0][1], _ref3 = store.multi[1][1]; _ref2 <= _ref3 ? _j <= _ref3 : _j >= _ref3; j = _ref2 <= _ref3 ? ++_j : --_j) { store.cells = Mori.assoc_in(store.cells, [i, j, 'raw'], ''); } } } else { if (what in store.rawClipboard) { pastedRows = store.rawClipboard[what]; } else { pastedRows = (function() { var _k, _len, _ref4, _results; _ref4 = what.split('\n'); _results = []; for (_k = 0, _len = _ref4.length; _k < _len; _k++) { row = _ref4[_k]; _results.push((function() { var _l, _len1, _ref5, _results1; _ref5 = row.split('\t'); _results1 = []; for (_l = 0, _len1 = _ref5.length; _l < _len1; _l++) { cell = _ref5[_l]; _results1.push(cell); } return _results1; })()); } return _results; })(); } firstSelected = utils.firstCellFromMulti(store.multi); for (i = _k = 0, _ref4 = pastedRows.length - 1; 0 <= _ref4 ? _k <= _ref4 : _k >= _ref4; i = 0 <= _ref4 ? ++_k : --_k) { pastedRow = pastedRows[i]; qi = i + firstSelected[0]; if (qi >= Mori.count(store.cells)) { continue; } for (j = _l = 0, _ref5 = pastedRow.length - 1; 0 <= _ref5 ? _l <= _ref5 : _l >= _ref5; j = 0 <= _ref5 ? ++_l : --_l) { pastedCell = pastedRow[j]; qj = j + firstSelected[1]; if (qj >= Mori.count(Mori.get(store.cells, 0))) { continue; } store.cells = Mori.assoc_in(store.cells, [qi, qj, 'raw'], pastedCell); } } } recalc(); return store.changed(); }); store.registerCallback('after-copypaste', function() { store.clipboard = null; return store.changed(); }); module.exports = store; recalc = require('./recalc').recalc; expandPattern = require('./expand-pattern');