@deephaven/grid 0.4.1-modules.0 → 0.5.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CellInputField.js +88 -40
- package/dist/CellInputField.js.map +1 -1
- package/dist/Grid.js +1484 -1449
- package/dist/Grid.js.map +1 -1
- package/dist/GridColorUtils.js +51 -18
- package/dist/GridColorUtils.js.map +1 -1
- package/dist/GridMetricCalculator.js +994 -1017
- package/dist/GridMetricCalculator.js.map +1 -1
- package/dist/GridModel.js +286 -171
- package/dist/GridModel.js.map +1 -1
- package/dist/GridMouseHandler.js +59 -39
- package/dist/GridMouseHandler.js.map +1 -1
- package/dist/GridRange.js +630 -572
- package/dist/GridRange.js.map +1 -1
- package/dist/GridRenderer.d.ts.map +1 -1
- package/dist/GridRenderer.js +1564 -1650
- package/dist/GridRenderer.js.map +1 -1
- package/dist/GridTestUtils.js +29 -15
- package/dist/GridTestUtils.js.map +1 -1
- package/dist/GridUtils.js +717 -679
- package/dist/GridUtils.js.map +1 -1
- package/dist/KeyHandler.js +18 -6
- package/dist/KeyHandler.js.map +1 -1
- package/dist/MockGridModel.js +210 -105
- package/dist/MockGridModel.js.map +1 -1
- package/dist/MockTreeGridModel.js +183 -113
- package/dist/MockTreeGridModel.js.map +1 -1
- package/dist/errors/PasteError.js +44 -5
- package/dist/errors/PasteError.js.map +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/errors/index.js.map +1 -1
- package/dist/index.js +15 -15
- package/dist/index.js.map +1 -1
- package/dist/key-handlers/EditKeyHandler.js +75 -42
- package/dist/key-handlers/EditKeyHandler.js.map +1 -1
- package/dist/key-handlers/PasteKeyHandler.js +78 -42
- package/dist/key-handlers/PasteKeyHandler.js.map +1 -1
- package/dist/key-handlers/SelectionKeyHandler.js +234 -220
- package/dist/key-handlers/SelectionKeyHandler.js.map +1 -1
- package/dist/key-handlers/TreeKeyHandler.js +72 -42
- package/dist/key-handlers/TreeKeyHandler.js.map +1 -1
- package/dist/key-handlers/index.js +4 -4
- package/dist/key-handlers/index.js.map +1 -1
- package/dist/memoizeClear.js +1 -1
- package/dist/memoizeClear.js.map +1 -1
- package/dist/mouse-handlers/EditMouseHandler.js +50 -18
- package/dist/mouse-handlers/EditMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.js +163 -141
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js +86 -47
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.d.ts.map +1 -1
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js +171 -143
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowMoveMouseHandler.js +147 -125
- package/dist/mouse-handlers/GridRowMoveMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js +86 -47
- package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowTreeMouseHandler.js +76 -46
- package/dist/mouse-handlers/GridRowTreeMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.d.ts.map +1 -1
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js +62 -31
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridSelectionMouseHandler.js +222 -200
- package/dist/mouse-handlers/GridSelectionMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridSeparatorMouseHandler.js +253 -206
- package/dist/mouse-handlers/GridSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.d.ts.map +1 -1
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js +172 -144
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/index.js +10 -10
- package/dist/mouse-handlers/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -5
package/dist/GridRange.js
CHANGED
|
@@ -1,694 +1,752 @@
|
|
|
1
|
-
function
|
|
1
|
+
function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
static normalize(startColumn, startRow, endColumn, endRow) {
|
|
5
|
-
var left = startColumn;
|
|
6
|
-
var top = startRow;
|
|
7
|
-
var right = endColumn;
|
|
8
|
-
var bottom = endRow;
|
|
3
|
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
9
4
|
|
|
10
|
-
|
|
11
|
-
left = right;
|
|
12
|
-
right = startColumn;
|
|
13
|
-
}
|
|
5
|
+
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
14
6
|
|
|
15
|
-
|
|
16
|
-
top = bottom;
|
|
17
|
-
bottom = startRow;
|
|
18
|
-
}
|
|
7
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
19
8
|
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
/** Make a GridRange, but ensure startColumn <= endColumn, startRow <= endRow */
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
static makeNormalized() {
|
|
26
|
-
return new GridRange(...GridRange.normalize(...arguments));
|
|
27
|
-
}
|
|
9
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
28
10
|
|
|
29
|
-
|
|
30
|
-
return new GridRange(column, row, column, row);
|
|
31
|
-
}
|
|
11
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
32
12
|
|
|
33
|
-
|
|
34
|
-
return new GridRange(column, null, column, null);
|
|
35
|
-
}
|
|
13
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
|
|
36
14
|
|
|
37
|
-
|
|
38
|
-
return new GridRange(null, row, null, row);
|
|
39
|
-
}
|
|
15
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
40
16
|
|
|
41
|
-
|
|
42
|
-
if (value1 == null || value2 == null) {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
17
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
45
18
|
|
|
46
|
-
|
|
47
|
-
}
|
|
19
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
48
20
|
|
|
49
|
-
|
|
50
|
-
if (value1 == null || value2 == null) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
21
|
+
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); } }
|
|
53
22
|
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Consolidate the passed in ranges to the minimum set, merging overlapping ranges.
|
|
58
|
-
* @param {[GridRange]} ranges The ranges to consolidate
|
|
59
|
-
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
static consolidate(ranges) {
|
|
63
|
-
var result = ranges.slice();
|
|
64
|
-
var wasModified = true;
|
|
65
|
-
|
|
66
|
-
while (wasModified) {
|
|
67
|
-
wasModified = false;
|
|
68
|
-
|
|
69
|
-
for (var i = 0; i < result.length && !wasModified; i += 1) {
|
|
70
|
-
var range = result[i];
|
|
71
|
-
|
|
72
|
-
for (var j = result.length - 1; j > i; j -= 1) {
|
|
73
|
-
var other = result[j]; // If one contains the other, we can just keep the bigger one
|
|
74
|
-
|
|
75
|
-
if (range.contains(other)) {
|
|
76
|
-
result.splice(j, 1);
|
|
77
|
-
} else if (other.contains(range)) {
|
|
78
|
-
wasModified = true;
|
|
79
|
-
result[i] = other;
|
|
80
|
-
result.splice(j, 1);
|
|
81
|
-
break;
|
|
82
|
-
} else if (range.startRow === other.startRow && range.endRow === other.endRow) {
|
|
83
|
-
if (range.touches(other)) {
|
|
84
|
-
// If the start/end rows match, and columns touch, consolidate
|
|
85
|
-
var {
|
|
86
|
-
startRow,
|
|
87
|
-
endRow
|
|
88
|
-
} = range;
|
|
89
|
-
var startColumn = GridRange.minOrNull(range.startColumn, other.startColumn);
|
|
90
|
-
var endColumn = GridRange.maxOrNull(range.endColumn, other.endColumn);
|
|
91
|
-
wasModified = true;
|
|
92
|
-
result[i] = new GridRange(startColumn, startRow, endColumn, endRow);
|
|
93
|
-
result.splice(j, 1);
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
} else if (range.startColumn === other.startColumn && range.endColumn === other.endColumn) {
|
|
97
|
-
if (range.touches(other)) {
|
|
98
|
-
// If the start/end rows match, and columns touch, consolidate
|
|
99
|
-
var {
|
|
100
|
-
startColumn: _startColumn,
|
|
101
|
-
endColumn: _endColumn
|
|
102
|
-
} = range;
|
|
23
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
103
24
|
|
|
104
|
-
|
|
25
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
105
26
|
|
|
106
|
-
|
|
27
|
+
var GridRange = /*#__PURE__*/function () {
|
|
28
|
+
function GridRange(startColumn, startRow, endColumn, endRow) {
|
|
29
|
+
_classCallCheck(this, GridRange);
|
|
107
30
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return result;
|
|
31
|
+
this.startColumn = startColumn;
|
|
32
|
+
this.startRow = startRow;
|
|
33
|
+
this.endColumn = endColumn;
|
|
34
|
+
this.endRow = endRow;
|
|
119
35
|
}
|
|
120
36
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (otherStart == null) {
|
|
128
|
-
return true;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return otherStart <= end + 1;
|
|
37
|
+
_createClass(GridRange, [{
|
|
38
|
+
key: "equals",
|
|
39
|
+
value: function equals(other) {
|
|
40
|
+
return this.startColumn === other.startColumn && this.startRow === other.startRow && this.endColumn === other.endColumn && this.endRow === other.endRow;
|
|
132
41
|
}
|
|
42
|
+
/** @returns {boolean} true if this GridRange completely contains `other` */
|
|
133
43
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return otherEnd >= start - 1;
|
|
44
|
+
}, {
|
|
45
|
+
key: "contains",
|
|
46
|
+
value: function contains(other) {
|
|
47
|
+
return (this.startColumn == null || other.startColumn != null && this.startColumn <= other.startColumn) && (this.startRow == null || other.startRow != null && this.startRow <= other.startRow) && (this.endColumn == null || other.endColumn != null && this.endColumn >= other.endColumn) && (this.endRow == null || other.endRow != null && this.endRow >= other.endRow);
|
|
140
48
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Check if the provided cell is in this range
|
|
51
|
+
* @param {number} column The column to check
|
|
52
|
+
* @param {number} row The row to check
|
|
53
|
+
* @returns {boolean} True if this cell is within this range
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
}, {
|
|
57
|
+
key: "containsCell",
|
|
58
|
+
value: function containsCell(column, row) {
|
|
59
|
+
if (column == null || row == null) {
|
|
60
|
+
return false;
|
|
145
61
|
}
|
|
146
62
|
|
|
147
|
-
return
|
|
63
|
+
return (this.startColumn == null || this.startColumn <= column) && (this.endColumn == null || this.endColumn >= column) && (this.startRow == null || this.startRow <= row) && (this.endRow == null || this.endRow >= row);
|
|
148
64
|
}
|
|
65
|
+
/** @returns {boolean} true if this GridRange touches `other` */
|
|
149
66
|
|
|
150
|
-
|
|
151
|
-
|
|
67
|
+
}, {
|
|
68
|
+
key: "touches",
|
|
69
|
+
value: function touches(other) {
|
|
70
|
+
return GridRange.isAxisRangeTouching(this.startRow, this.endRow, other.startRow, other.endRow) && GridRange.isAxisRangeTouching(this.startColumn, this.endColumn, other.startColumn, other.endColumn);
|
|
152
71
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
72
|
+
/**
|
|
73
|
+
* @param {GridRange} other The range to deselect from within this range
|
|
74
|
+
* @returns {[GridRange]} The ranges needed to represent the remaining
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
}, {
|
|
78
|
+
key: "subtract",
|
|
79
|
+
value: function subtract(other) {
|
|
80
|
+
return GridRange.subtractFromRange(this, other);
|
|
156
81
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (!ranges1[i].equals(ranges2[i])) {
|
|
172
|
-
return false;
|
|
82
|
+
/**
|
|
83
|
+
* Get the first cell in this range. Throws if this range is unbounded.
|
|
84
|
+
*
|
|
85
|
+
* @param {GridRange.SELECTION_DIRECTION?} direction The direction to get the starting cell in. Defaults to DOWN
|
|
86
|
+
* @returns {{column: number, row: number}} The first cell in this range in the direction specified
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
}, {
|
|
90
|
+
key: "startCell",
|
|
91
|
+
value: function startCell() {
|
|
92
|
+
var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GridRange.SELECTION_DIRECTION.DOWN;
|
|
93
|
+
|
|
94
|
+
if (!GridRange.isBounded(this)) {
|
|
95
|
+
throw new Error('Cannot get the startCell of an unbounded range');
|
|
173
96
|
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Get the intersection (overlapping area) of two ranges
|
|
180
|
-
* @param {GridRange} range One range to check for the intersection
|
|
181
|
-
* @param {GridRange} otherRange The other range to check for the intersection
|
|
182
|
-
* @returns {GridRange|null} Intersection of the two ranges. If they do not intersect, returns `null`.
|
|
183
|
-
*/
|
|
184
97
|
|
|
98
|
+
switch (direction) {
|
|
99
|
+
case GridRange.SELECTION_DIRECTION.DOWN:
|
|
100
|
+
case GridRange.SELECTION_DIRECTION.RIGHT:
|
|
101
|
+
return {
|
|
102
|
+
column: this.startColumn,
|
|
103
|
+
row: this.startRow
|
|
104
|
+
};
|
|
185
105
|
|
|
186
|
-
|
|
187
|
-
|
|
106
|
+
case GridRange.SELECTION_DIRECTION.LEFT:
|
|
107
|
+
case GridRange.SELECTION_DIRECTION.UP:
|
|
108
|
+
{
|
|
109
|
+
return {
|
|
110
|
+
column: this.endColumn,
|
|
111
|
+
row: this.endRow
|
|
112
|
+
};
|
|
113
|
+
}
|
|
188
114
|
|
|
189
|
-
|
|
190
|
-
|
|
115
|
+
default:
|
|
116
|
+
throw new Error("Invalid direction: ".concat(direction));
|
|
117
|
+
}
|
|
191
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Get the next cell in the direction specified. Throws if this range is unbounded.
|
|
121
|
+
* If already at the bounds of the range in that direction, wrap to the next column or row
|
|
122
|
+
* If at the end of the entire range, return null
|
|
123
|
+
* If outside of the range, returns the next cell closest within this range.
|
|
124
|
+
*
|
|
125
|
+
* @param {number} column The cursor column
|
|
126
|
+
* @param {number} row The cursor row
|
|
127
|
+
* @param {SELECTION_DIRECTION} direction The direction to go in
|
|
128
|
+
* @returns {GridCell|null} The next cell in the direction specified, or `null` if at the end of the range
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
}, {
|
|
132
|
+
key: "nextCell",
|
|
133
|
+
value: function nextCell(column, row, direction) {
|
|
134
|
+
if (!GridRange.isBounded(this)) {
|
|
135
|
+
throw new Error('Bounded range required');
|
|
136
|
+
}
|
|
192
137
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
endColumn,
|
|
197
|
-
endRow
|
|
198
|
-
} = range;
|
|
199
|
-
startColumn = startColumn != null && otherRange.startColumn != null ? Math.max(startColumn, otherRange.startColumn) : (_startColumn2 = startColumn) !== null && _startColumn2 !== void 0 ? _startColumn2 : otherRange.startColumn;
|
|
200
|
-
endColumn = endColumn != null && otherRange.endColumn != null ? Math.min(endColumn, otherRange.endColumn) : (_endColumn2 = endColumn) !== null && _endColumn2 !== void 0 ? _endColumn2 : otherRange.endColumn;
|
|
201
|
-
startRow = startRow != null && otherRange.startRow != null ? Math.max(startRow, otherRange.startRow) : (_startRow2 = startRow) !== null && _startRow2 !== void 0 ? _startRow2 : otherRange.startRow;
|
|
202
|
-
endRow = endRow != null && otherRange.endRow != null ? Math.min(endRow, otherRange.endRow) : (_endRow2 = endRow) !== null && _endRow2 !== void 0 ? _endRow2 : otherRange.endRow;
|
|
138
|
+
if (column == null || row == null) {
|
|
139
|
+
throw new Error('Require a non-null cursor');
|
|
140
|
+
}
|
|
203
141
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
142
|
+
var startColumn = this.startColumn,
|
|
143
|
+
endColumn = this.endColumn,
|
|
144
|
+
startRow = this.startRow,
|
|
145
|
+
endRow = this.endRow;
|
|
146
|
+
|
|
147
|
+
switch (direction) {
|
|
148
|
+
case GridRange.SELECTION_DIRECTION.DOWN:
|
|
149
|
+
if (row < endRow) {
|
|
150
|
+
return {
|
|
151
|
+
column: column,
|
|
152
|
+
row: Math.max(row + 1, startRow)
|
|
153
|
+
};
|
|
154
|
+
}
|
|
207
155
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
*/
|
|
156
|
+
if (column < endColumn) {
|
|
157
|
+
return {
|
|
158
|
+
column: Math.max(column + 1, startColumn),
|
|
159
|
+
row: startRow
|
|
160
|
+
};
|
|
161
|
+
}
|
|
215
162
|
|
|
163
|
+
break;
|
|
216
164
|
|
|
217
|
-
|
|
218
|
-
|
|
165
|
+
case GridRange.SELECTION_DIRECTION.UP:
|
|
166
|
+
if (row > startRow) {
|
|
167
|
+
return {
|
|
168
|
+
column: column,
|
|
169
|
+
row: Math.min(row - 1, endRow)
|
|
170
|
+
};
|
|
171
|
+
}
|
|
219
172
|
|
|
220
|
-
|
|
173
|
+
if (column > startColumn) {
|
|
174
|
+
return {
|
|
175
|
+
column: Math.min(column - 1, endColumn),
|
|
176
|
+
row: endRow
|
|
177
|
+
};
|
|
178
|
+
}
|
|
221
179
|
|
|
222
|
-
|
|
223
|
-
return [range];
|
|
224
|
-
} // Go through each of the quadrants for deselection, there can be up to 4
|
|
225
|
-
// Top quadrant (above the subtracted area)
|
|
180
|
+
break;
|
|
226
181
|
|
|
182
|
+
case GridRange.SELECTION_DIRECTION.RIGHT:
|
|
183
|
+
if (column < endColumn) {
|
|
184
|
+
return {
|
|
185
|
+
column: Math.max(column + 1, startColumn),
|
|
186
|
+
row: row
|
|
187
|
+
};
|
|
188
|
+
}
|
|
227
189
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
190
|
+
if (row < endRow) {
|
|
191
|
+
return {
|
|
192
|
+
column: startColumn,
|
|
193
|
+
row: Math.max(row + 1, startRow)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
231
196
|
|
|
197
|
+
break;
|
|
232
198
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
199
|
+
case GridRange.SELECTION_DIRECTION.LEFT:
|
|
200
|
+
if (column > startColumn) {
|
|
201
|
+
return {
|
|
202
|
+
column: Math.min(column - 1, endColumn),
|
|
203
|
+
row: row
|
|
204
|
+
};
|
|
205
|
+
}
|
|
236
206
|
|
|
207
|
+
if (row > startRow) {
|
|
208
|
+
return {
|
|
209
|
+
column: endColumn,
|
|
210
|
+
row: Math.min(row - 1, endRow)
|
|
211
|
+
};
|
|
212
|
+
}
|
|
237
213
|
|
|
238
|
-
|
|
239
|
-
result.push(new GridRange(subtract.endColumn + 1, subtract.startRow, range.endColumn, subtract.endRow));
|
|
240
|
-
} // Bottom quadrant
|
|
214
|
+
break;
|
|
241
215
|
|
|
216
|
+
default:
|
|
217
|
+
throw new Error("Invalid direction: ".concat(direction));
|
|
218
|
+
}
|
|
242
219
|
|
|
243
|
-
|
|
244
|
-
result.push(new GridRange(range.startColumn, subtract.endRow + 1, range.endColumn, range.endRow));
|
|
220
|
+
return null;
|
|
245
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Iterate through each cell in the range
|
|
224
|
+
* @param {(column:number, row:number, index:number) => void} callback Callback to execute. `index` is the index within this range
|
|
225
|
+
* @param {GridRange.SELECTION_DIRECTION} direction The direction to iterate in
|
|
226
|
+
*/
|
|
246
227
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
* @param {GridRange} subtractRange The range to subtract from within these ranges
|
|
253
|
-
* @returns {GridRange[]} The ranges needed to represent the remaining
|
|
254
|
-
*/
|
|
228
|
+
}, {
|
|
229
|
+
key: "forEach",
|
|
230
|
+
value: function forEach(callback) {
|
|
231
|
+
var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : GridRange.SELECTION_DIRECTION.RIGHT;
|
|
232
|
+
var i = 0;
|
|
255
233
|
|
|
234
|
+
var _this$startCell = this.startCell(direction),
|
|
235
|
+
c = _this$startCell.column,
|
|
236
|
+
r = _this$startCell.row;
|
|
256
237
|
|
|
257
|
-
|
|
258
|
-
|
|
238
|
+
while (c != null && r != null) {
|
|
239
|
+
var _this$nextCell;
|
|
259
240
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
return result;
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Subtract multiple ranges from multiple ranges
|
|
268
|
-
* @param {GridRange[]} ranges The ranges to be subtracted from
|
|
269
|
-
* @param {GridRange[]} subtractRanges The ranges to subtract from within these ranges
|
|
270
|
-
* @returns {GridRange[]} The ranges needed to represent the remaining
|
|
271
|
-
*/
|
|
241
|
+
callback(c, r, i);
|
|
242
|
+
i += 1;
|
|
272
243
|
|
|
244
|
+
var _ref = (_this$nextCell = this.nextCell(c, r, direction)) !== null && _this$nextCell !== void 0 ? _this$nextCell : {};
|
|
273
245
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
246
|
+
c = _ref.column;
|
|
247
|
+
r = _ref.row;
|
|
248
|
+
}
|
|
277
249
|
}
|
|
250
|
+
}], [{
|
|
251
|
+
key: "normalize",
|
|
252
|
+
value: function normalize(startColumn, startRow, endColumn, endRow) {
|
|
253
|
+
var left = startColumn;
|
|
254
|
+
var top = startRow;
|
|
255
|
+
var right = endColumn;
|
|
256
|
+
var bottom = endRow;
|
|
257
|
+
|
|
258
|
+
if (left != null && right != null && right < left) {
|
|
259
|
+
left = right;
|
|
260
|
+
right = startColumn;
|
|
261
|
+
}
|
|
278
262
|
|
|
279
|
-
|
|
263
|
+
if (top != null && bottom != null && bottom < top) {
|
|
264
|
+
top = bottom;
|
|
265
|
+
bottom = startRow;
|
|
266
|
+
}
|
|
280
267
|
|
|
281
|
-
|
|
282
|
-
result = GridRange.subtractFromRanges(result, subtractRanges[i]);
|
|
268
|
+
return [left, top, right, bottom];
|
|
283
269
|
}
|
|
270
|
+
/** Make a GridRange, but ensure startColumn <= endColumn, startRow <= endRow */
|
|
284
271
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
272
|
+
}, {
|
|
273
|
+
key: "makeNormalized",
|
|
274
|
+
value: function makeNormalized() {
|
|
275
|
+
return _construct(GridRange, _toConsumableArray(GridRange.normalize.apply(GridRange, arguments)));
|
|
276
|
+
}
|
|
277
|
+
}, {
|
|
278
|
+
key: "makeCell",
|
|
279
|
+
value: function makeCell(column, row) {
|
|
280
|
+
return new GridRange(column, row, column, row);
|
|
281
|
+
}
|
|
282
|
+
}, {
|
|
283
|
+
key: "makeColumn",
|
|
284
|
+
value: function makeColumn(column) {
|
|
285
|
+
return new GridRange(column, null, column, null);
|
|
286
|
+
}
|
|
287
|
+
}, {
|
|
288
|
+
key: "makeRow",
|
|
289
|
+
value: function makeRow(row) {
|
|
290
|
+
return new GridRange(null, row, null, row);
|
|
291
|
+
}
|
|
292
|
+
}, {
|
|
293
|
+
key: "minOrNull",
|
|
294
|
+
value: function minOrNull(value1, value2) {
|
|
295
|
+
if (value1 == null || value2 == null) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
310
298
|
|
|
311
|
-
|
|
312
|
-
return range;
|
|
299
|
+
return Math.min(value1, value2);
|
|
313
300
|
}
|
|
301
|
+
}, {
|
|
302
|
+
key: "maxOrNull",
|
|
303
|
+
value: function maxOrNull(value1, value2) {
|
|
304
|
+
if (value1 == null || value2 == null) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
314
307
|
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Converts the GridRanges passed in to be bound to the `columnCount` and `rowCount` passed in
|
|
319
|
-
*
|
|
320
|
-
* @param {GridRange[]} ranges The ranges to get the bounded ranges of
|
|
321
|
-
* @param {number} columnCount The number of columns
|
|
322
|
-
* @param {number} rowCount The number of rows
|
|
323
|
-
* @returns {GridRange} The passed in GridRange with any null values filled in
|
|
324
|
-
*/
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
static boundedRanges(ranges, columnCount, rowCount) {
|
|
328
|
-
return ranges.map(r => GridRange.boundedRange(r, columnCount, rowCount));
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Offsets a GridRange by the specified amount in the x and y directions
|
|
332
|
-
*
|
|
333
|
-
* @param {GridRange} range The range to offset
|
|
334
|
-
* @param {number} columnOffset The number of columns to offset
|
|
335
|
-
* @param {number} rowOffset The number of rows to offset
|
|
336
|
-
* @returns {GridRange} The new grid range offset from the original
|
|
337
|
-
*/
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
static offset(range, columnOffset, rowOffset) {
|
|
341
|
-
return new GridRange(range.startColumn != null ? range.startColumn + columnOffset : null, range.startRow != null ? range.startRow + rowOffset : null, range.endColumn != null ? range.endColumn + columnOffset : null, range.endRow != null ? range.endRow + rowOffset : null);
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Get the next cell given the selected ranges and the current cell
|
|
345
|
-
* @param {GridRange[]} ranges The selected bounded ranges within the grid
|
|
346
|
-
* @param {number|null} column The cursor column, or null if none focused
|
|
347
|
-
* @param {number|null} row The cursor row, or null if none focused
|
|
348
|
-
* @param {SELECTION_DIRECTION} direction The direction in which to select next
|
|
349
|
-
* @returns {Cell} The next cell to focus, or null if there should be no more focus
|
|
350
|
-
*/
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
static nextCell(ranges) {
|
|
354
|
-
var column = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
355
|
-
var row = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
356
|
-
var direction = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : GridRange.SELECTION_DIRECTION.DOWN;
|
|
357
|
-
|
|
358
|
-
if (ranges.length === 0) {
|
|
359
|
-
return null;
|
|
308
|
+
return Math.max(value1, value2);
|
|
360
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* Consolidate the passed in ranges to the minimum set, merging overlapping ranges.
|
|
312
|
+
* @param {[GridRange]} ranges The ranges to consolidate
|
|
313
|
+
*/
|
|
314
|
+
|
|
315
|
+
}, {
|
|
316
|
+
key: "consolidate",
|
|
317
|
+
value: function consolidate(ranges) {
|
|
318
|
+
var result = ranges.slice();
|
|
319
|
+
var wasModified = true;
|
|
361
320
|
|
|
362
|
-
|
|
321
|
+
while (wasModified) {
|
|
322
|
+
wasModified = false;
|
|
363
323
|
|
|
364
|
-
|
|
365
|
-
|
|
324
|
+
for (var i = 0; i < result.length && !wasModified; i += 1) {
|
|
325
|
+
var range = result[i];
|
|
366
326
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
var nextCell = range.nextCell(column, row, direction);
|
|
327
|
+
for (var j = result.length - 1; j > i; j -= 1) {
|
|
328
|
+
var other = result[j]; // If one contains the other, we can just keep the bigger one
|
|
370
329
|
|
|
371
|
-
|
|
372
|
-
|
|
330
|
+
if (range.contains(other)) {
|
|
331
|
+
result.splice(j, 1);
|
|
332
|
+
} else if (other.contains(range)) {
|
|
333
|
+
wasModified = true;
|
|
334
|
+
result[i] = other;
|
|
335
|
+
result.splice(j, 1);
|
|
336
|
+
break;
|
|
337
|
+
} else if (range.startRow === other.startRow && range.endRow === other.endRow) {
|
|
338
|
+
if (range.touches(other)) {
|
|
339
|
+
// If the start/end rows match, and columns touch, consolidate
|
|
340
|
+
var startRow = range.startRow,
|
|
341
|
+
endRow = range.endRow;
|
|
342
|
+
var startColumn = GridRange.minOrNull(range.startColumn, other.startColumn);
|
|
343
|
+
var endColumn = GridRange.maxOrNull(range.endColumn, other.endColumn);
|
|
344
|
+
wasModified = true;
|
|
345
|
+
result[i] = new GridRange(startColumn, startRow, endColumn, endRow);
|
|
346
|
+
result.splice(j, 1);
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
} else if (range.startColumn === other.startColumn && range.endColumn === other.endColumn) {
|
|
350
|
+
if (range.touches(other)) {
|
|
351
|
+
// If the start/end rows match, and columns touch, consolidate
|
|
352
|
+
var _startColumn = range.startColumn,
|
|
353
|
+
_endColumn = range.endColumn;
|
|
354
|
+
|
|
355
|
+
var _startRow = GridRange.minOrNull(range.startRow, other.startRow);
|
|
356
|
+
|
|
357
|
+
var _endRow = GridRange.maxOrNull(range.endRow, other.endRow);
|
|
358
|
+
|
|
359
|
+
wasModified = true;
|
|
360
|
+
result[i] = new GridRange(_startColumn, _startRow, _endColumn, _endRow);
|
|
361
|
+
result.splice(j, 1);
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
373
366
|
}
|
|
374
367
|
}
|
|
375
|
-
} // Otherwise go to the start of the next range (could be same range if only one range)
|
|
376
|
-
|
|
377
368
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
369
|
+
return result;
|
|
370
|
+
}
|
|
371
|
+
}, {
|
|
372
|
+
key: "isAxisRangeTouching",
|
|
373
|
+
value: function isAxisRangeTouching(start, end, otherStart, otherEnd) {
|
|
374
|
+
if (start == null) {
|
|
375
|
+
if (end == null) {
|
|
376
|
+
return true;
|
|
385
377
|
}
|
|
386
378
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
{
|
|
390
|
-
var _nextRangeIndex = rangeIndex > 0 ? rangeIndex - 1 : ranges.length - 1;
|
|
391
|
-
|
|
392
|
-
var _nextRange = ranges[_nextRangeIndex];
|
|
393
|
-
return _nextRange.startCell(direction);
|
|
379
|
+
if (otherStart == null) {
|
|
380
|
+
return true;
|
|
394
381
|
}
|
|
395
382
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Count the number of cells in the provided grid ranges
|
|
402
|
-
* @param {GridRange[]} ranges The ranges to count the rows of
|
|
403
|
-
* @returns {number|NaN} The number of cells in the ranges, or `NaN` if any of the ranges were unbounded
|
|
404
|
-
*/
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
static cellCount(ranges) {
|
|
408
|
-
return ranges.reduce((cellCount, range) => {
|
|
409
|
-
var _range$endRow2, _range$startRow2, _range$endColumn2, _range$startColumn2;
|
|
410
|
-
|
|
411
|
-
return cellCount + (((_range$endRow2 = range.endRow) !== null && _range$endRow2 !== void 0 ? _range$endRow2 : NaN) - ((_range$startRow2 = range.startRow) !== null && _range$startRow2 !== void 0 ? _range$startRow2 : NaN) + 1) * (((_range$endColumn2 = range.endColumn) !== null && _range$endColumn2 !== void 0 ? _range$endColumn2 : NaN) - ((_range$startColumn2 = range.startColumn) !== null && _range$startColumn2 !== void 0 ? _range$startColumn2 : NaN) + 1);
|
|
412
|
-
}, 0);
|
|
413
|
-
}
|
|
414
|
-
/**
|
|
415
|
-
* Count the number of rows in the provided grid ranges
|
|
416
|
-
* @param {GridRange[]} ranges The ranges to count the rows of
|
|
417
|
-
* @returns {number|NaN} The number of rows in the ranges, or `NaN` if any of the ranges were unbounded
|
|
418
|
-
*/
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
static rowCount(ranges) {
|
|
422
|
-
return ranges.reduce((rowCount, range) => {
|
|
423
|
-
var _range$endRow3, _range$startRow3;
|
|
383
|
+
return otherStart <= end + 1;
|
|
384
|
+
}
|
|
424
385
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
* Count the number of columns in the provided grid ranges
|
|
430
|
-
* @param {GridRange[]} ranges The ranges to count the columns of
|
|
431
|
-
* @returns {number|NaN} The number of columns in the ranges, or `NaN` if any of the ranges were unbounded
|
|
432
|
-
*/
|
|
386
|
+
if (end == null) {
|
|
387
|
+
if (otherEnd == null) {
|
|
388
|
+
return true;
|
|
389
|
+
}
|
|
433
390
|
|
|
391
|
+
return otherEnd >= start - 1;
|
|
392
|
+
}
|
|
434
393
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
394
|
+
if (otherStart == null) {
|
|
395
|
+
if (otherEnd == null) {
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
438
398
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
/**
|
|
443
|
-
* Check if the provided ranges contain the provided cell
|
|
444
|
-
* @param {GridRange[]} ranges The ranges to check
|
|
445
|
-
* @param {number} column The column index
|
|
446
|
-
* @param {number} row The row index
|
|
447
|
-
* @returns {boolean} True if the cell is within the provided ranges, false otherwise.
|
|
448
|
-
*/
|
|
399
|
+
return start <= otherEnd + 1;
|
|
400
|
+
}
|
|
449
401
|
|
|
402
|
+
if (otherEnd == null) {
|
|
403
|
+
return end >= otherStart - 1;
|
|
404
|
+
}
|
|
450
405
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
406
|
+
if (otherStart >= start - 1) {
|
|
407
|
+
return otherStart <= end + 1;
|
|
408
|
+
}
|
|
454
409
|
|
|
455
|
-
|
|
410
|
+
return otherEnd >= start - 1;
|
|
411
|
+
}
|
|
412
|
+
}, {
|
|
413
|
+
key: "rangeArraysEqual",
|
|
414
|
+
value: function rangeArraysEqual(ranges1, ranges2) {
|
|
415
|
+
if (ranges1 === ranges2) {
|
|
456
416
|
return true;
|
|
457
417
|
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
return false;
|
|
461
|
-
}
|
|
462
|
-
/**
|
|
463
|
-
* Iterate through each cell in the provided ranges
|
|
464
|
-
* @param {GridRange[]} ranges The ranges to iterate through
|
|
465
|
-
* @param {(column: number, row: number, index: number) => void} callback The callback to execute. `index` is the index within that range
|
|
466
|
-
* @param {GridRange.SELECTION_DIRECTION} direction The direction to iterate in
|
|
467
|
-
*/
|
|
468
418
|
|
|
419
|
+
if (ranges1 == null || ranges2 == null || ranges1.length !== ranges2.length) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
469
422
|
|
|
470
|
-
|
|
471
|
-
|
|
423
|
+
for (var i = 0; i < ranges1.length; i += 1) {
|
|
424
|
+
if (!ranges1[i].equals(ranges2[i])) {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
472
428
|
|
|
473
|
-
|
|
474
|
-
ranges[i].forEach(callback, direction);
|
|
429
|
+
return true;
|
|
475
430
|
}
|
|
476
|
-
|
|
431
|
+
/**
|
|
432
|
+
* Get the intersection (overlapping area) of two ranges
|
|
433
|
+
* @param {GridRange} range One range to check for the intersection
|
|
434
|
+
* @param {GridRange} otherRange The other range to check for the intersection
|
|
435
|
+
* @returns {GridRange|null} Intersection of the two ranges. If they do not intersect, returns `null`.
|
|
436
|
+
*/
|
|
437
|
+
|
|
438
|
+
}, {
|
|
439
|
+
key: "intersection",
|
|
440
|
+
value: function intersection(range, otherRange) {
|
|
441
|
+
var _startColumn2, _endColumn2, _startRow2, _endRow2;
|
|
442
|
+
|
|
443
|
+
if (range.equals(otherRange)) {
|
|
444
|
+
return range;
|
|
445
|
+
}
|
|
477
446
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
447
|
+
var startColumn = range.startColumn,
|
|
448
|
+
startRow = range.startRow,
|
|
449
|
+
endColumn = range.endColumn,
|
|
450
|
+
endRow = range.endRow;
|
|
451
|
+
startColumn = startColumn != null && otherRange.startColumn != null ? Math.max(startColumn, otherRange.startColumn) : (_startColumn2 = startColumn) !== null && _startColumn2 !== void 0 ? _startColumn2 : otherRange.startColumn;
|
|
452
|
+
endColumn = endColumn != null && otherRange.endColumn != null ? Math.min(endColumn, otherRange.endColumn) : (_endColumn2 = endColumn) !== null && _endColumn2 !== void 0 ? _endColumn2 : otherRange.endColumn;
|
|
453
|
+
startRow = startRow != null && otherRange.startRow != null ? Math.max(startRow, otherRange.startRow) : (_startRow2 = startRow) !== null && _startRow2 !== void 0 ? _startRow2 : otherRange.startRow;
|
|
454
|
+
endRow = endRow != null && otherRange.endRow != null ? Math.min(endRow, otherRange.endRow) : (_endRow2 = endRow) !== null && _endRow2 !== void 0 ? _endRow2 : otherRange.endRow;
|
|
455
|
+
|
|
456
|
+
if (startColumn != null && startColumn > endColumn || startRow != null && startRow > endRow) {
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
484
459
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
460
|
+
return new GridRange(startColumn, startRow, endColumn, endRow);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* @param {GridRange} range The range to be subtracted from
|
|
464
|
+
* @param {GridRange} subtractRange The range to subtract from within this range
|
|
465
|
+
* @returns {GridRange[]} The ranges needed to represent the remaining
|
|
466
|
+
*/
|
|
489
467
|
|
|
468
|
+
}, {
|
|
469
|
+
key: "subtractFromRange",
|
|
470
|
+
value: function subtractFromRange(range, subtractRange) {
|
|
471
|
+
var result = []; // Make it a little easier by finding only the part the subtraction range intersects
|
|
490
472
|
|
|
491
|
-
|
|
492
|
-
return (this.startColumn == null || other.startColumn != null && this.startColumn <= other.startColumn) && (this.startRow == null || other.startRow != null && this.startRow <= other.startRow) && (this.endColumn == null || other.endColumn != null && this.endColumn >= other.endColumn) && (this.endRow == null || other.endRow != null && this.endRow >= other.endRow);
|
|
493
|
-
}
|
|
494
|
-
/**
|
|
495
|
-
* Check if the provided cell is in this range
|
|
496
|
-
* @param {number} column The column to check
|
|
497
|
-
* @param {number} row The row to check
|
|
498
|
-
* @returns {boolean} True if this cell is within this range
|
|
499
|
-
*/
|
|
473
|
+
var subtract = GridRange.intersection(range, subtractRange);
|
|
500
474
|
|
|
475
|
+
if (subtract == null) {
|
|
476
|
+
return [range];
|
|
477
|
+
} // Go through each of the quadrants for deselection, there can be up to 4
|
|
478
|
+
// Top quadrant (above the subtracted area)
|
|
501
479
|
|
|
502
|
-
containsCell(column, row) {
|
|
503
|
-
if (column == null || row == null) {
|
|
504
|
-
return false;
|
|
505
|
-
}
|
|
506
480
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
481
|
+
if (subtract.startRow != null && (range.startRow == null || range.startRow < subtract.startRow)) {
|
|
482
|
+
result.push(new GridRange(range.startColumn, range.startRow, range.endColumn, subtract.startRow - 1));
|
|
483
|
+
} // middle left
|
|
510
484
|
|
|
511
485
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
/**
|
|
516
|
-
* @param {GridRange} other The range to deselect from within this range
|
|
517
|
-
* @returns {[GridRange]} The ranges needed to represent the remaining
|
|
518
|
-
*/
|
|
486
|
+
if (subtract.startColumn != null && (range.startColumn == null || range.startColumn < subtract.startColumn)) {
|
|
487
|
+
result.push(new GridRange(range.startColumn, subtract.startRow, subtract.startColumn - 1, subtract.endRow));
|
|
488
|
+
} // middle right
|
|
519
489
|
|
|
520
490
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
/**
|
|
525
|
-
* Get the first cell in this range. Throws if this range is unbounded.
|
|
526
|
-
*
|
|
527
|
-
* @param {GridRange.SELECTION_DIRECTION?} direction The direction to get the starting cell in. Defaults to DOWN
|
|
528
|
-
* @returns {{column: number, row: number}} The first cell in this range in the direction specified
|
|
529
|
-
*/
|
|
491
|
+
if (subtract.endColumn != null && (range.endColumn == null || range.endColumn > subtract.endColumn)) {
|
|
492
|
+
result.push(new GridRange(subtract.endColumn + 1, subtract.startRow, range.endColumn, subtract.endRow));
|
|
493
|
+
} // Bottom quadrant
|
|
530
494
|
|
|
531
495
|
|
|
532
|
-
|
|
533
|
-
|
|
496
|
+
if (subtract.endRow != null && (range.endRow == null || range.endRow > subtract.endRow)) {
|
|
497
|
+
result.push(new GridRange(range.startColumn, subtract.endRow + 1, range.endColumn, range.endRow));
|
|
498
|
+
}
|
|
534
499
|
|
|
535
|
-
|
|
536
|
-
throw new Error('Cannot get the startCell of an unbounded range');
|
|
500
|
+
return result;
|
|
537
501
|
}
|
|
502
|
+
/**
|
|
503
|
+
* Subtract a range from multiple ranges
|
|
504
|
+
* @param {GridRange[]} ranges The ranges to be subtracted from
|
|
505
|
+
* @param {GridRange} subtractRange The range to subtract from within these ranges
|
|
506
|
+
* @returns {GridRange[]} The ranges needed to represent the remaining
|
|
507
|
+
*/
|
|
508
|
+
|
|
509
|
+
}, {
|
|
510
|
+
key: "subtractFromRanges",
|
|
511
|
+
value: function subtractFromRanges(ranges, subtractRange) {
|
|
512
|
+
var result = [];
|
|
513
|
+
|
|
514
|
+
for (var i = 0; i < ranges.length; i += 1) {
|
|
515
|
+
result.push.apply(result, _toConsumableArray(GridRange.subtractFromRange(ranges[i], subtractRange)));
|
|
516
|
+
}
|
|
538
517
|
|
|
539
|
-
|
|
540
|
-
case GridRange.SELECTION_DIRECTION.DOWN:
|
|
541
|
-
case GridRange.SELECTION_DIRECTION.RIGHT:
|
|
542
|
-
return {
|
|
543
|
-
column: this.startColumn,
|
|
544
|
-
row: this.startRow
|
|
545
|
-
};
|
|
546
|
-
|
|
547
|
-
case GridRange.SELECTION_DIRECTION.LEFT:
|
|
548
|
-
case GridRange.SELECTION_DIRECTION.UP:
|
|
549
|
-
{
|
|
550
|
-
return {
|
|
551
|
-
column: this.endColumn,
|
|
552
|
-
row: this.endRow
|
|
553
|
-
};
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
default:
|
|
557
|
-
throw new Error("Invalid direction: ".concat(direction));
|
|
518
|
+
return result;
|
|
558
519
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
nextCell(column, row, direction) {
|
|
574
|
-
if (!GridRange.isBounded(this)) {
|
|
575
|
-
throw new Error('Bounded range required');
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
if (column == null || row == null) {
|
|
579
|
-
throw new Error('Require a non-null cursor');
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
var {
|
|
583
|
-
startColumn,
|
|
584
|
-
endColumn,
|
|
585
|
-
startRow,
|
|
586
|
-
endRow
|
|
587
|
-
} = this;
|
|
588
|
-
|
|
589
|
-
switch (direction) {
|
|
590
|
-
case GridRange.SELECTION_DIRECTION.DOWN:
|
|
591
|
-
if (row < endRow) {
|
|
592
|
-
return {
|
|
593
|
-
column,
|
|
594
|
-
row: Math.max(row + 1, startRow)
|
|
595
|
-
};
|
|
596
|
-
}
|
|
520
|
+
/**
|
|
521
|
+
* Subtract multiple ranges from multiple ranges
|
|
522
|
+
* @param {GridRange[]} ranges The ranges to be subtracted from
|
|
523
|
+
* @param {GridRange[]} subtractRanges The ranges to subtract from within these ranges
|
|
524
|
+
* @returns {GridRange[]} The ranges needed to represent the remaining
|
|
525
|
+
*/
|
|
526
|
+
|
|
527
|
+
}, {
|
|
528
|
+
key: "subtractRangesFromRanges",
|
|
529
|
+
value: function subtractRangesFromRanges(ranges, subtractRanges) {
|
|
530
|
+
if (!subtractRanges || subtractRanges.length === 0) {
|
|
531
|
+
return ranges;
|
|
532
|
+
}
|
|
597
533
|
|
|
598
|
-
|
|
599
|
-
return {
|
|
600
|
-
column: Math.max(column + 1, startColumn),
|
|
601
|
-
row: startRow
|
|
602
|
-
};
|
|
603
|
-
}
|
|
534
|
+
var result = _toConsumableArray(ranges);
|
|
604
535
|
|
|
605
|
-
|
|
536
|
+
for (var i = 0; i < subtractRanges.length; i += 1) {
|
|
537
|
+
result = GridRange.subtractFromRanges(result, subtractRanges[i]);
|
|
538
|
+
}
|
|
606
539
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
540
|
+
return result;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Test if a given range is bounded (all values are non-null)
|
|
544
|
+
* @param {GridRange} range The range to test
|
|
545
|
+
* @returns {boolean} True if this range is bounded, false otherwise
|
|
546
|
+
*/
|
|
547
|
+
|
|
548
|
+
}, {
|
|
549
|
+
key: "isBounded",
|
|
550
|
+
value: function isBounded(range) {
|
|
551
|
+
return range.startRow != null && range.startColumn != null && range.endRow != null && range.endColumn != null;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Converts any GridRange passed in that is a full row or column selection to be bound
|
|
555
|
+
* to the `columnCount` and `rowCount` passed in
|
|
556
|
+
*
|
|
557
|
+
* @param {GridRange} range The range to get the bounded range of
|
|
558
|
+
* @param {number} columnCount The number of columns
|
|
559
|
+
* @param {number} rowCount The number of rows
|
|
560
|
+
* @returns {GridRange} The passed in GridRange with any null values filled in
|
|
561
|
+
*/
|
|
562
|
+
|
|
563
|
+
}, {
|
|
564
|
+
key: "boundedRange",
|
|
565
|
+
value: function boundedRange(range, columnCount, rowCount) {
|
|
566
|
+
var _range$startColumn, _range$startRow, _range$endColumn, _range$endRow;
|
|
567
|
+
|
|
568
|
+
if (GridRange.isBounded(range)) {
|
|
569
|
+
return range;
|
|
570
|
+
}
|
|
614
571
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
572
|
+
return new GridRange((_range$startColumn = range.startColumn) !== null && _range$startColumn !== void 0 ? _range$startColumn : 0, (_range$startRow = range.startRow) !== null && _range$startRow !== void 0 ? _range$startRow : 0, (_range$endColumn = range.endColumn) !== null && _range$endColumn !== void 0 ? _range$endColumn : columnCount - 1, (_range$endRow = range.endRow) !== null && _range$endRow !== void 0 ? _range$endRow : rowCount - 1);
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Converts the GridRanges passed in to be bound to the `columnCount` and `rowCount` passed in
|
|
576
|
+
*
|
|
577
|
+
* @param {GridRange[]} ranges The ranges to get the bounded ranges of
|
|
578
|
+
* @param {number} columnCount The number of columns
|
|
579
|
+
* @param {number} rowCount The number of rows
|
|
580
|
+
* @returns {GridRange} The passed in GridRange with any null values filled in
|
|
581
|
+
*/
|
|
582
|
+
|
|
583
|
+
}, {
|
|
584
|
+
key: "boundedRanges",
|
|
585
|
+
value: function boundedRanges(ranges, columnCount, rowCount) {
|
|
586
|
+
return ranges.map(function (r) {
|
|
587
|
+
return GridRange.boundedRange(r, columnCount, rowCount);
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Offsets a GridRange by the specified amount in the x and y directions
|
|
592
|
+
*
|
|
593
|
+
* @param {GridRange} range The range to offset
|
|
594
|
+
* @param {number} columnOffset The number of columns to offset
|
|
595
|
+
* @param {number} rowOffset The number of rows to offset
|
|
596
|
+
* @returns {GridRange} The new grid range offset from the original
|
|
597
|
+
*/
|
|
598
|
+
|
|
599
|
+
}, {
|
|
600
|
+
key: "offset",
|
|
601
|
+
value: function offset(range, columnOffset, rowOffset) {
|
|
602
|
+
return new GridRange(range.startColumn != null ? range.startColumn + columnOffset : null, range.startRow != null ? range.startRow + rowOffset : null, range.endColumn != null ? range.endColumn + columnOffset : null, range.endRow != null ? range.endRow + rowOffset : null);
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Get the next cell given the selected ranges and the current cell
|
|
606
|
+
* @param {GridRange[]} ranges The selected bounded ranges within the grid
|
|
607
|
+
* @param {number|null} column The cursor column, or null if none focused
|
|
608
|
+
* @param {number|null} row The cursor row, or null if none focused
|
|
609
|
+
* @param {SELECTION_DIRECTION} direction The direction in which to select next
|
|
610
|
+
* @returns {Cell} The next cell to focus, or null if there should be no more focus
|
|
611
|
+
*/
|
|
612
|
+
|
|
613
|
+
}, {
|
|
614
|
+
key: "nextCell",
|
|
615
|
+
value: function nextCell(ranges) {
|
|
616
|
+
var column = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
617
|
+
var row = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
618
|
+
var direction = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : GridRange.SELECTION_DIRECTION.DOWN;
|
|
619
|
+
|
|
620
|
+
if (ranges.length === 0) {
|
|
621
|
+
return null;
|
|
622
|
+
}
|
|
621
623
|
|
|
622
|
-
|
|
624
|
+
var rangeIndex = -1;
|
|
623
625
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
return
|
|
627
|
-
|
|
628
|
-
row
|
|
629
|
-
};
|
|
630
|
-
}
|
|
626
|
+
if (column != null && row != null) {
|
|
627
|
+
rangeIndex = ranges.findIndex(function (r) {
|
|
628
|
+
return r.containsCell(column, row);
|
|
629
|
+
});
|
|
631
630
|
|
|
632
|
-
if (
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
631
|
+
if (rangeIndex >= 0) {
|
|
632
|
+
var range = ranges[rangeIndex];
|
|
633
|
+
var nextCell = range.nextCell(column, row, direction);
|
|
634
|
+
|
|
635
|
+
if (nextCell != null) {
|
|
636
|
+
return nextCell;
|
|
637
|
+
}
|
|
637
638
|
}
|
|
639
|
+
} // Otherwise go to the start of the next range (could be same range if only one range)
|
|
638
640
|
|
|
639
|
-
break;
|
|
640
641
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
642
|
+
switch (direction) {
|
|
643
|
+
case GridRange.SELECTION_DIRECTION.DOWN:
|
|
644
|
+
case GridRange.SELECTION_DIRECTION.RIGHT:
|
|
645
|
+
{
|
|
646
|
+
var nextRangeIndex = rangeIndex < ranges.length - 1 ? rangeIndex + 1 : 0;
|
|
647
|
+
var nextRange = ranges[nextRangeIndex];
|
|
648
|
+
return nextRange.startCell(direction);
|
|
649
|
+
}
|
|
648
650
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
};
|
|
654
|
-
}
|
|
651
|
+
case GridRange.SELECTION_DIRECTION.LEFT:
|
|
652
|
+
case GridRange.SELECTION_DIRECTION.UP:
|
|
653
|
+
{
|
|
654
|
+
var _nextRangeIndex = rangeIndex > 0 ? rangeIndex - 1 : ranges.length - 1;
|
|
655
655
|
|
|
656
|
-
|
|
656
|
+
var _nextRange = ranges[_nextRangeIndex];
|
|
657
|
+
return _nextRange.startCell(direction);
|
|
658
|
+
}
|
|
657
659
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
+
default:
|
|
661
|
+
throw new Error("Invalid direction: ".concat(direction));
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Count the number of cells in the provided grid ranges
|
|
666
|
+
* @param {GridRange[]} ranges The ranges to count the rows of
|
|
667
|
+
* @returns {number|NaN} The number of cells in the ranges, or `NaN` if any of the ranges were unbounded
|
|
668
|
+
*/
|
|
669
|
+
|
|
670
|
+
}, {
|
|
671
|
+
key: "cellCount",
|
|
672
|
+
value: function cellCount(ranges) {
|
|
673
|
+
return ranges.reduce(function (cellCount, range) {
|
|
674
|
+
var _range$endRow2, _range$startRow2, _range$endColumn2, _range$startColumn2;
|
|
675
|
+
|
|
676
|
+
return cellCount + (((_range$endRow2 = range.endRow) !== null && _range$endRow2 !== void 0 ? _range$endRow2 : NaN) - ((_range$startRow2 = range.startRow) !== null && _range$startRow2 !== void 0 ? _range$startRow2 : NaN) + 1) * (((_range$endColumn2 = range.endColumn) !== null && _range$endColumn2 !== void 0 ? _range$endColumn2 : NaN) - ((_range$startColumn2 = range.startColumn) !== null && _range$startColumn2 !== void 0 ? _range$startColumn2 : NaN) + 1);
|
|
677
|
+
}, 0);
|
|
660
678
|
}
|
|
679
|
+
/**
|
|
680
|
+
* Count the number of rows in the provided grid ranges
|
|
681
|
+
* @param {GridRange[]} ranges The ranges to count the rows of
|
|
682
|
+
* @returns {number|NaN} The number of rows in the ranges, or `NaN` if any of the ranges were unbounded
|
|
683
|
+
*/
|
|
684
|
+
|
|
685
|
+
}, {
|
|
686
|
+
key: "rowCount",
|
|
687
|
+
value: function rowCount(ranges) {
|
|
688
|
+
return ranges.reduce(function (rowCount, range) {
|
|
689
|
+
var _range$endRow3, _range$startRow3;
|
|
690
|
+
|
|
691
|
+
return rowCount + ((_range$endRow3 = range.endRow) !== null && _range$endRow3 !== void 0 ? _range$endRow3 : NaN) - ((_range$startRow3 = range.startRow) !== null && _range$startRow3 !== void 0 ? _range$startRow3 : NaN) + 1;
|
|
692
|
+
}, 0);
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Count the number of columns in the provided grid ranges
|
|
696
|
+
* @param {GridRange[]} ranges The ranges to count the columns of
|
|
697
|
+
* @returns {number|NaN} The number of columns in the ranges, or `NaN` if any of the ranges were unbounded
|
|
698
|
+
*/
|
|
699
|
+
|
|
700
|
+
}, {
|
|
701
|
+
key: "columnCount",
|
|
702
|
+
value: function columnCount(ranges) {
|
|
703
|
+
return ranges.reduce(function (columnCount, range) {
|
|
704
|
+
var _range$endColumn3, _range$startColumn3;
|
|
705
|
+
|
|
706
|
+
return columnCount + ((_range$endColumn3 = range.endColumn) !== null && _range$endColumn3 !== void 0 ? _range$endColumn3 : NaN) - ((_range$startColumn3 = range.startColumn) !== null && _range$startColumn3 !== void 0 ? _range$startColumn3 : NaN) + 1;
|
|
707
|
+
}, 0);
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Check if the provided ranges contain the provided cell
|
|
711
|
+
* @param {GridRange[]} ranges The ranges to check
|
|
712
|
+
* @param {number} column The column index
|
|
713
|
+
* @param {number} row The row index
|
|
714
|
+
* @returns {boolean} True if the cell is within the provided ranges, false otherwise.
|
|
715
|
+
*/
|
|
716
|
+
|
|
717
|
+
}, {
|
|
718
|
+
key: "containsCell",
|
|
719
|
+
value: function containsCell(ranges, column, row) {
|
|
720
|
+
for (var i = 0; i < ranges.length; i += 1) {
|
|
721
|
+
var range = ranges[i];
|
|
722
|
+
|
|
723
|
+
if (range.containsCell(column, row)) {
|
|
724
|
+
return true;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
661
727
|
|
|
662
|
-
|
|
663
|
-
}
|
|
664
|
-
/**
|
|
665
|
-
* Iterate through each cell in the range
|
|
666
|
-
* @param {(column:number, row:number, index:number) => void} callback Callback to execute. `index` is the index within this range
|
|
667
|
-
* @param {GridRange.SELECTION_DIRECTION} direction The direction to iterate in
|
|
668
|
-
*/
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
forEach(callback) {
|
|
672
|
-
var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : GridRange.SELECTION_DIRECTION.RIGHT;
|
|
673
|
-
var i = 0;
|
|
674
|
-
var {
|
|
675
|
-
column: c,
|
|
676
|
-
row: r
|
|
677
|
-
} = this.startCell(direction);
|
|
678
|
-
|
|
679
|
-
while (c != null && r != null) {
|
|
680
|
-
var _this$nextCell;
|
|
681
|
-
|
|
682
|
-
callback(c, r, i);
|
|
683
|
-
i += 1;
|
|
684
|
-
({
|
|
685
|
-
column: c,
|
|
686
|
-
row: r
|
|
687
|
-
} = (_this$nextCell = this.nextCell(c, r, direction)) !== null && _this$nextCell !== void 0 ? _this$nextCell : {});
|
|
728
|
+
return false;
|
|
688
729
|
}
|
|
689
|
-
|
|
730
|
+
/**
|
|
731
|
+
* Iterate through each cell in the provided ranges
|
|
732
|
+
* @param {GridRange[]} ranges The ranges to iterate through
|
|
733
|
+
* @param {(column: number, row: number, index: number) => void} callback The callback to execute. `index` is the index within that range
|
|
734
|
+
* @param {GridRange.SELECTION_DIRECTION} direction The direction to iterate in
|
|
735
|
+
*/
|
|
736
|
+
|
|
737
|
+
}, {
|
|
738
|
+
key: "forEachCell",
|
|
739
|
+
value: function forEachCell(ranges, callback) {
|
|
740
|
+
var direction = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : GridRange.SELECTION_DIRECTION.RIGHT;
|
|
741
|
+
|
|
742
|
+
for (var i = 0; i < ranges.length; i += 1) {
|
|
743
|
+
ranges[i].forEach(callback, direction);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}]);
|
|
690
747
|
|
|
691
|
-
|
|
748
|
+
return GridRange;
|
|
749
|
+
}();
|
|
692
750
|
|
|
693
751
|
_defineProperty(GridRange, "SELECTION_DIRECTION", Object.freeze({
|
|
694
752
|
DOWN: 'DOWN',
|