@deephaven/grid 0.5.2-beta.0 → 0.6.1-demo.8
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 +40 -88
- package/dist/CellInputField.js.map +1 -1
- package/dist/Grid.js +1449 -1484
- package/dist/Grid.js.map +1 -1
- package/dist/GridColorUtils.js +18 -51
- package/dist/GridColorUtils.js.map +1 -1
- package/dist/GridMetricCalculator.d.ts +8 -1
- package/dist/GridMetricCalculator.d.ts.map +1 -1
- package/dist/GridMetricCalculator.js +1031 -994
- package/dist/GridMetricCalculator.js.map +1 -1
- package/dist/GridModel.d.ts +4 -1
- package/dist/GridModel.d.ts.map +1 -1
- package/dist/GridModel.js +175 -286
- package/dist/GridModel.js.map +1 -1
- package/dist/GridMouseHandler.js +39 -59
- package/dist/GridMouseHandler.js.map +1 -1
- package/dist/GridRange.js +572 -630
- package/dist/GridRange.js.map +1 -1
- package/dist/GridRenderer.js +1650 -1564
- package/dist/GridRenderer.js.map +1 -1
- package/dist/GridTestUtils.js +15 -29
- package/dist/GridTestUtils.js.map +1 -1
- package/dist/GridUtils.js +679 -717
- package/dist/GridUtils.js.map +1 -1
- package/dist/KeyHandler.js +6 -18
- package/dist/KeyHandler.js.map +1 -1
- package/dist/MockGridModel.js +105 -210
- package/dist/MockGridModel.js.map +1 -1
- package/dist/MockTreeGridModel.js +113 -183
- package/dist/MockTreeGridModel.js.map +1 -1
- package/dist/errors/PasteError.js +5 -44
- 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 +42 -75
- package/dist/key-handlers/EditKeyHandler.js.map +1 -1
- package/dist/key-handlers/PasteKeyHandler.js +42 -78
- package/dist/key-handlers/PasteKeyHandler.js.map +1 -1
- package/dist/key-handlers/SelectionKeyHandler.d.ts.map +1 -1
- package/dist/key-handlers/SelectionKeyHandler.js +239 -229
- package/dist/key-handlers/SelectionKeyHandler.js.map +1 -1
- package/dist/key-handlers/TreeKeyHandler.js +42 -72
- 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 +18 -50
- package/dist/mouse-handlers/EditMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.d.ts.map +1 -1
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.js +141 -163
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js +47 -86
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js +145 -171
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowMoveMouseHandler.js +125 -147
- package/dist/mouse-handlers/GridRowMoveMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js +47 -86
- package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowTreeMouseHandler.js +46 -76
- package/dist/mouse-handlers/GridRowTreeMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js +31 -62
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridSelectionMouseHandler.js +200 -222
- package/dist/mouse-handlers/GridSelectionMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridSeparatorMouseHandler.js +206 -253
- package/dist/mouse-handlers/GridSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js +146 -172
- 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 +6 -10
package/dist/GridRange.js
CHANGED
|
@@ -1,752 +1,694 @@
|
|
|
1
|
-
function
|
|
1
|
+
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; }
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
class GridRange {
|
|
4
|
+
static normalize(startColumn, startRow, endColumn, endRow) {
|
|
5
|
+
var left = startColumn;
|
|
6
|
+
var top = startRow;
|
|
7
|
+
var right = endColumn;
|
|
8
|
+
var bottom = endRow;
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
if (left != null && right != null && right < left) {
|
|
11
|
+
left = right;
|
|
12
|
+
right = startColumn;
|
|
13
|
+
}
|
|
6
14
|
|
|
7
|
-
|
|
15
|
+
if (top != null && bottom != null && bottom < top) {
|
|
16
|
+
top = bottom;
|
|
17
|
+
bottom = startRow;
|
|
18
|
+
}
|
|
8
19
|
|
|
9
|
-
|
|
20
|
+
return [left, top, right, bottom];
|
|
21
|
+
}
|
|
22
|
+
/** Make a GridRange, but ensure startColumn <= endColumn, startRow <= endRow */
|
|
10
23
|
|
|
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); }
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
static makeNormalized() {
|
|
26
|
+
return new GridRange(...GridRange.normalize(...arguments));
|
|
27
|
+
}
|
|
14
28
|
|
|
15
|
-
|
|
29
|
+
static makeCell(column, row) {
|
|
30
|
+
return new GridRange(column, row, column, row);
|
|
31
|
+
}
|
|
16
32
|
|
|
17
|
-
|
|
33
|
+
static makeColumn(column) {
|
|
34
|
+
return new GridRange(column, null, column, null);
|
|
35
|
+
}
|
|
18
36
|
|
|
19
|
-
|
|
37
|
+
static makeRow(row) {
|
|
38
|
+
return new GridRange(null, row, null, row);
|
|
39
|
+
}
|
|
20
40
|
|
|
21
|
-
|
|
41
|
+
static minOrNull(value1, value2) {
|
|
42
|
+
if (value1 == null || value2 == null) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
22
45
|
|
|
23
|
-
|
|
46
|
+
return Math.min(value1, value2);
|
|
47
|
+
}
|
|
24
48
|
|
|
25
|
-
|
|
49
|
+
static maxOrNull(value1, value2) {
|
|
50
|
+
if (value1 == null || value2 == null) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
26
53
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
54
|
+
return Math.max(value1, value2);
|
|
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;
|
|
30
103
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
104
|
+
var _startRow = GridRange.minOrNull(range.startRow, other.startRow);
|
|
105
|
+
|
|
106
|
+
var _endRow = GridRange.maxOrNull(range.endRow, other.endRow);
|
|
107
|
+
|
|
108
|
+
wasModified = true;
|
|
109
|
+
result[i] = new GridRange(_startColumn, _startRow, _endColumn, _endRow);
|
|
110
|
+
result.splice(j, 1);
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return result;
|
|
35
119
|
}
|
|
36
120
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
121
|
+
static isAxisRangeTouching(start, end, otherStart, otherEnd) {
|
|
122
|
+
if (start == null) {
|
|
123
|
+
if (end == null) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (otherStart == null) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return otherStart <= end + 1;
|
|
41
132
|
}
|
|
42
|
-
/** @returns {boolean} true if this GridRange completely contains `other` */
|
|
43
133
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
134
|
+
if (end == null) {
|
|
135
|
+
if (otherEnd == null) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return otherEnd >= start - 1;
|
|
48
140
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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;
|
|
141
|
+
|
|
142
|
+
if (otherStart == null) {
|
|
143
|
+
if (otherEnd == null) {
|
|
144
|
+
return true;
|
|
61
145
|
}
|
|
62
146
|
|
|
63
|
-
return
|
|
147
|
+
return start <= otherEnd + 1;
|
|
64
148
|
}
|
|
65
|
-
/** @returns {boolean} true if this GridRange touches `other` */
|
|
66
149
|
|
|
67
|
-
|
|
68
|
-
|
|
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);
|
|
150
|
+
if (otherEnd == null) {
|
|
151
|
+
return end >= otherStart - 1;
|
|
71
152
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
*/
|
|
76
|
-
|
|
77
|
-
}, {
|
|
78
|
-
key: "subtract",
|
|
79
|
-
value: function subtract(other) {
|
|
80
|
-
return GridRange.subtractFromRange(this, other);
|
|
153
|
+
|
|
154
|
+
if (otherStart >= start - 1) {
|
|
155
|
+
return otherStart <= end + 1;
|
|
81
156
|
}
|
|
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');
|
|
96
|
-
}
|
|
97
157
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
case GridRange.SELECTION_DIRECTION.RIGHT:
|
|
101
|
-
return {
|
|
102
|
-
column: this.startColumn,
|
|
103
|
-
row: this.startRow
|
|
104
|
-
};
|
|
158
|
+
return otherEnd >= start - 1;
|
|
159
|
+
}
|
|
105
160
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
column: this.endColumn,
|
|
111
|
-
row: this.endRow
|
|
112
|
-
};
|
|
113
|
-
}
|
|
161
|
+
static rangeArraysEqual(ranges1, ranges2) {
|
|
162
|
+
if (ranges1 === ranges2) {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
114
165
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
166
|
+
if (ranges1 == null || ranges2 == null || ranges1.length !== ranges2.length) {
|
|
167
|
+
return false;
|
|
118
168
|
}
|
|
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
|
-
}
|
|
137
169
|
|
|
138
|
-
|
|
139
|
-
|
|
170
|
+
for (var i = 0; i < ranges1.length; i += 1) {
|
|
171
|
+
if (!ranges1[i].equals(ranges2[i])) {
|
|
172
|
+
return false;
|
|
140
173
|
}
|
|
174
|
+
}
|
|
141
175
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
return {
|
|
151
|
-
column: column,
|
|
152
|
-
row: Math.max(row + 1, startRow)
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (column < endColumn) {
|
|
157
|
-
return {
|
|
158
|
-
column: Math.max(column + 1, startColumn),
|
|
159
|
-
row: startRow
|
|
160
|
-
};
|
|
161
|
-
}
|
|
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
|
+
*/
|
|
162
184
|
|
|
163
|
-
break;
|
|
164
185
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
column: column,
|
|
169
|
-
row: Math.min(row - 1, endRow)
|
|
170
|
-
};
|
|
171
|
-
}
|
|
186
|
+
static intersection(range, otherRange) {
|
|
187
|
+
var _startColumn2, _endColumn2, _startRow2, _endRow2;
|
|
172
188
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
row: endRow
|
|
177
|
-
};
|
|
178
|
-
}
|
|
189
|
+
if (range.equals(otherRange)) {
|
|
190
|
+
return range;
|
|
191
|
+
}
|
|
179
192
|
|
|
180
|
-
|
|
193
|
+
var {
|
|
194
|
+
startColumn,
|
|
195
|
+
startRow,
|
|
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;
|
|
181
203
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
column: Math.max(column + 1, startColumn),
|
|
186
|
-
row: row
|
|
187
|
-
};
|
|
188
|
-
}
|
|
204
|
+
if (startColumn != null && startColumn > endColumn || startRow != null && startRow > endRow) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
189
207
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
208
|
+
return new GridRange(startColumn, startRow, endColumn, endRow);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* @param {GridRange} range The range to be subtracted from
|
|
212
|
+
* @param {GridRange} subtractRange The range to subtract from within this range
|
|
213
|
+
* @returns {GridRange[]} The ranges needed to represent the remaining
|
|
214
|
+
*/
|
|
196
215
|
|
|
197
|
-
break;
|
|
198
216
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
return {
|
|
202
|
-
column: Math.min(column - 1, endColumn),
|
|
203
|
-
row: row
|
|
204
|
-
};
|
|
205
|
-
}
|
|
217
|
+
static subtractFromRange(range, subtractRange) {
|
|
218
|
+
var result = []; // Make it a little easier by finding only the part the subtraction range intersects
|
|
206
219
|
|
|
207
|
-
|
|
208
|
-
return {
|
|
209
|
-
column: endColumn,
|
|
210
|
-
row: Math.min(row - 1, endRow)
|
|
211
|
-
};
|
|
212
|
-
}
|
|
220
|
+
var subtract = GridRange.intersection(range, subtractRange);
|
|
213
221
|
|
|
214
|
-
|
|
222
|
+
if (subtract == null) {
|
|
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)
|
|
215
226
|
|
|
216
|
-
default:
|
|
217
|
-
throw new Error("Invalid direction: ".concat(direction));
|
|
218
|
-
}
|
|
219
227
|
|
|
220
|
-
|
|
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
|
-
*/
|
|
228
|
+
if (subtract.startRow != null && (range.startRow == null || range.startRow < subtract.startRow)) {
|
|
229
|
+
result.push(new GridRange(range.startColumn, range.startRow, range.endColumn, subtract.startRow - 1));
|
|
230
|
+
} // middle left
|
|
227
231
|
|
|
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;
|
|
233
232
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
233
|
+
if (subtract.startColumn != null && (range.startColumn == null || range.startColumn < subtract.startColumn)) {
|
|
234
|
+
result.push(new GridRange(range.startColumn, subtract.startRow, subtract.startColumn - 1, subtract.endRow));
|
|
235
|
+
} // middle right
|
|
237
236
|
|
|
238
|
-
while (c != null && r != null) {
|
|
239
|
-
var _this$nextCell;
|
|
240
237
|
|
|
241
|
-
|
|
242
|
-
|
|
238
|
+
if (subtract.endColumn != null && (range.endColumn == null || range.endColumn > subtract.endColumn)) {
|
|
239
|
+
result.push(new GridRange(subtract.endColumn + 1, subtract.startRow, range.endColumn, subtract.endRow));
|
|
240
|
+
} // Bottom quadrant
|
|
243
241
|
|
|
244
|
-
var _ref = (_this$nextCell = this.nextCell(c, r, direction)) !== null && _this$nextCell !== void 0 ? _this$nextCell : {};
|
|
245
242
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
243
|
+
if (subtract.endRow != null && (range.endRow == null || range.endRow > subtract.endRow)) {
|
|
244
|
+
result.push(new GridRange(range.startColumn, subtract.endRow + 1, range.endColumn, range.endRow));
|
|
249
245
|
}
|
|
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
|
-
}
|
|
262
246
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Subtract a range from multiple ranges
|
|
251
|
+
* @param {GridRange[]} ranges The ranges to be subtracted from
|
|
252
|
+
* @param {GridRange} subtractRange The range to subtract from within these ranges
|
|
253
|
+
* @returns {GridRange[]} The ranges needed to represent the remaining
|
|
254
|
+
*/
|
|
267
255
|
|
|
268
|
-
return [left, top, right, bottom];
|
|
269
|
-
}
|
|
270
|
-
/** Make a GridRange, but ensure startColumn <= endColumn, startRow <= endRow */
|
|
271
256
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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);
|
|
257
|
+
static subtractFromRanges(ranges, subtractRange) {
|
|
258
|
+
var result = [];
|
|
259
|
+
|
|
260
|
+
for (var i = 0; i < ranges.length; i += 1) {
|
|
261
|
+
result.push(...GridRange.subtractFromRange(ranges[i], subtractRange));
|
|
286
262
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
+
*/
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
static subtractRangesFromRanges(ranges, subtractRanges) {
|
|
275
|
+
if (!subtractRanges || subtractRanges.length === 0) {
|
|
276
|
+
return ranges;
|
|
291
277
|
}
|
|
292
|
-
}, {
|
|
293
|
-
key: "minOrNull",
|
|
294
|
-
value: function minOrNull(value1, value2) {
|
|
295
|
-
if (value1 == null || value2 == null) {
|
|
296
|
-
return null;
|
|
297
|
-
}
|
|
298
278
|
|
|
299
|
-
|
|
279
|
+
var result = [...ranges];
|
|
280
|
+
|
|
281
|
+
for (var i = 0; i < subtractRanges.length; i += 1) {
|
|
282
|
+
result = GridRange.subtractFromRanges(result, subtractRanges[i]);
|
|
300
283
|
}
|
|
301
|
-
}, {
|
|
302
|
-
key: "maxOrNull",
|
|
303
|
-
value: function maxOrNull(value1, value2) {
|
|
304
|
-
if (value1 == null || value2 == null) {
|
|
305
|
-
return null;
|
|
306
|
-
}
|
|
307
284
|
|
|
308
|
-
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Test if a given range is bounded (all values are non-null)
|
|
289
|
+
* @param {GridRange} range The range to test
|
|
290
|
+
* @returns {boolean} True if this range is bounded, false otherwise
|
|
291
|
+
*/
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
static isBounded(range) {
|
|
295
|
+
return range.startRow != null && range.startColumn != null && range.endRow != null && range.endColumn != null;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Converts any GridRange passed in that is a full row or column selection to be bound
|
|
299
|
+
* to the `columnCount` and `rowCount` passed in
|
|
300
|
+
*
|
|
301
|
+
* @param {GridRange} range The range to get the bounded range of
|
|
302
|
+
* @param {number} columnCount The number of columns
|
|
303
|
+
* @param {number} rowCount The number of rows
|
|
304
|
+
* @returns {GridRange} The passed in GridRange with any null values filled in
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
static boundedRange(range, columnCount, rowCount) {
|
|
309
|
+
var _range$startColumn, _range$startRow, _range$endColumn, _range$endRow;
|
|
310
|
+
|
|
311
|
+
if (GridRange.isBounded(range)) {
|
|
312
|
+
return range;
|
|
309
313
|
}
|
|
310
|
-
/**
|
|
311
|
-
* Consolidate the passed in ranges to the minimum set, merging overlapping ranges.
|
|
312
|
-
* @param {[GridRange]} ranges The ranges to consolidate
|
|
313
|
-
*/
|
|
314
314
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
315
|
+
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);
|
|
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;
|
|
360
|
+
}
|
|
320
361
|
|
|
321
|
-
|
|
322
|
-
wasModified = false;
|
|
362
|
+
var rangeIndex = -1;
|
|
323
363
|
|
|
324
|
-
|
|
325
|
-
|
|
364
|
+
if (column != null && row != null) {
|
|
365
|
+
rangeIndex = ranges.findIndex(r => r.containsCell(column, row));
|
|
326
366
|
|
|
327
|
-
|
|
328
|
-
|
|
367
|
+
if (rangeIndex >= 0) {
|
|
368
|
+
var range = ranges[rangeIndex];
|
|
369
|
+
var nextCell = range.nextCell(column, row, direction);
|
|
329
370
|
|
|
330
|
-
|
|
331
|
-
|
|
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
|
-
}
|
|
371
|
+
if (nextCell != null) {
|
|
372
|
+
return nextCell;
|
|
366
373
|
}
|
|
367
374
|
}
|
|
375
|
+
} // Otherwise go to the start of the next range (could be same range if only one range)
|
|
368
376
|
|
|
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;
|
|
377
|
-
}
|
|
378
377
|
|
|
379
|
-
|
|
380
|
-
|
|
378
|
+
switch (direction) {
|
|
379
|
+
case GridRange.SELECTION_DIRECTION.DOWN:
|
|
380
|
+
case GridRange.SELECTION_DIRECTION.RIGHT:
|
|
381
|
+
{
|
|
382
|
+
var nextRangeIndex = rangeIndex < ranges.length - 1 ? rangeIndex + 1 : 0;
|
|
383
|
+
var nextRange = ranges[nextRangeIndex];
|
|
384
|
+
return nextRange.startCell(direction);
|
|
381
385
|
}
|
|
382
386
|
|
|
383
|
-
|
|
384
|
-
|
|
387
|
+
case GridRange.SELECTION_DIRECTION.LEFT:
|
|
388
|
+
case GridRange.SELECTION_DIRECTION.UP:
|
|
389
|
+
{
|
|
390
|
+
var _nextRangeIndex = rangeIndex > 0 ? rangeIndex - 1 : ranges.length - 1;
|
|
385
391
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
return true;
|
|
392
|
+
var _nextRange = ranges[_nextRangeIndex];
|
|
393
|
+
return _nextRange.startCell(direction);
|
|
389
394
|
}
|
|
390
395
|
|
|
391
|
-
|
|
392
|
-
|
|
396
|
+
default:
|
|
397
|
+
throw new Error("Invalid direction: ".concat(direction));
|
|
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
|
+
*/
|
|
393
405
|
|
|
394
|
-
if (otherStart == null) {
|
|
395
|
-
if (otherEnd == null) {
|
|
396
|
-
return true;
|
|
397
|
-
}
|
|
398
406
|
|
|
399
|
-
|
|
400
|
-
|
|
407
|
+
static cellCount(ranges) {
|
|
408
|
+
return ranges.reduce((cellCount, range) => {
|
|
409
|
+
var _range$endRow2, _range$startRow2, _range$endColumn2, _range$startColumn2;
|
|
401
410
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
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
|
+
*/
|
|
405
419
|
|
|
406
|
-
if (otherStart >= start - 1) {
|
|
407
|
-
return otherStart <= end + 1;
|
|
408
|
-
}
|
|
409
420
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
key: "rangeArraysEqual",
|
|
414
|
-
value: function rangeArraysEqual(ranges1, ranges2) {
|
|
415
|
-
if (ranges1 === ranges2) {
|
|
416
|
-
return true;
|
|
417
|
-
}
|
|
421
|
+
static rowCount(ranges) {
|
|
422
|
+
return ranges.reduce((rowCount, range) => {
|
|
423
|
+
var _range$endRow3, _range$startRow3;
|
|
418
424
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
425
|
+
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;
|
|
426
|
+
}, 0);
|
|
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
|
+
*/
|
|
422
433
|
|
|
423
|
-
for (var i = 0; i < ranges1.length; i += 1) {
|
|
424
|
-
if (!ranges1[i].equals(ranges2[i])) {
|
|
425
|
-
return false;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
434
|
|
|
429
|
-
|
|
430
|
-
|
|
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
|
-
}
|
|
435
|
+
static columnCount(ranges) {
|
|
436
|
+
return ranges.reduce((columnCount, range) => {
|
|
437
|
+
var _range$endColumn3, _range$startColumn3;
|
|
446
438
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
return null;
|
|
458
|
-
}
|
|
439
|
+
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;
|
|
440
|
+
}, 0);
|
|
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
|
+
*/
|
|
459
449
|
|
|
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
|
-
*/
|
|
467
450
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
var result = []; // Make it a little easier by finding only the part the subtraction range intersects
|
|
451
|
+
static containsCell(ranges, column, row) {
|
|
452
|
+
for (var i = 0; i < ranges.length; i += 1) {
|
|
453
|
+
var range = ranges[i];
|
|
472
454
|
|
|
473
|
-
|
|
455
|
+
if (range.containsCell(column, row)) {
|
|
456
|
+
return true;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
474
459
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
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
|
+
*/
|
|
479
468
|
|
|
480
469
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
} // middle left
|
|
470
|
+
static forEachCell(ranges, callback) {
|
|
471
|
+
var direction = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : GridRange.SELECTION_DIRECTION.RIGHT;
|
|
484
472
|
|
|
473
|
+
for (var i = 0; i < ranges.length; i += 1) {
|
|
474
|
+
ranges[i].forEach(callback, direction);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
485
477
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
478
|
+
constructor(startColumn, startRow, endColumn, endRow) {
|
|
479
|
+
this.startColumn = startColumn;
|
|
480
|
+
this.startRow = startRow;
|
|
481
|
+
this.endColumn = endColumn;
|
|
482
|
+
this.endRow = endRow;
|
|
483
|
+
}
|
|
489
484
|
|
|
485
|
+
equals(other) {
|
|
486
|
+
return this.startColumn === other.startColumn && this.startRow === other.startRow && this.endColumn === other.endColumn && this.endRow === other.endRow;
|
|
487
|
+
}
|
|
488
|
+
/** @returns {boolean} true if this GridRange completely contains `other` */
|
|
490
489
|
|
|
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
|
|
494
490
|
|
|
491
|
+
contains(other) {
|
|
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
|
+
*/
|
|
495
500
|
|
|
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
|
-
}
|
|
499
501
|
|
|
500
|
-
|
|
502
|
+
containsCell(column, row) {
|
|
503
|
+
if (column == null || row == null) {
|
|
504
|
+
return false;
|
|
501
505
|
}
|
|
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
|
-
}
|
|
517
506
|
|
|
518
|
-
|
|
519
|
-
|
|
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
|
-
}
|
|
507
|
+
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);
|
|
508
|
+
}
|
|
509
|
+
/** @returns {boolean} true if this GridRange touches `other` */
|
|
533
510
|
|
|
534
|
-
var result = _toConsumableArray(ranges);
|
|
535
511
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
512
|
+
touches(other) {
|
|
513
|
+
return GridRange.isAxisRangeTouching(this.startRow, this.endRow, other.startRow, other.endRow) && GridRange.isAxisRangeTouching(this.startColumn, this.endColumn, other.startColumn, other.endColumn);
|
|
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
|
+
*/
|
|
539
519
|
|
|
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
|
-
}
|
|
571
520
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
});
|
|
521
|
+
subtract(other) {
|
|
522
|
+
return GridRange.subtractFromRange(this, other);
|
|
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
|
+
*/
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
startCell() {
|
|
533
|
+
var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GridRange.SELECTION_DIRECTION.DOWN;
|
|
534
|
+
|
|
535
|
+
if (!GridRange.isBounded(this)) {
|
|
536
|
+
throw new Error('Cannot get the startCell of an unbounded range');
|
|
589
537
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
538
|
+
|
|
539
|
+
switch (direction) {
|
|
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));
|
|
603
558
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Get the next cell in the direction specified. Throws if this range is unbounded.
|
|
562
|
+
* If already at the bounds of the range in that direction, wrap to the next column or row
|
|
563
|
+
* If at the end of the entire range, return null
|
|
564
|
+
* If outside of the range, returns the next cell closest within this range.
|
|
565
|
+
*
|
|
566
|
+
* @param {number} column The cursor column
|
|
567
|
+
* @param {number} row The cursor row
|
|
568
|
+
* @param {SELECTION_DIRECTION} direction The direction to go in
|
|
569
|
+
* @returns {GridCell|null} The next cell in the direction specified, or `null` if at the end of the range
|
|
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
|
+
}
|
|
623
597
|
|
|
624
|
-
|
|
598
|
+
if (column < endColumn) {
|
|
599
|
+
return {
|
|
600
|
+
column: Math.max(column + 1, startColumn),
|
|
601
|
+
row: startRow
|
|
602
|
+
};
|
|
603
|
+
}
|
|
625
604
|
|
|
626
|
-
|
|
627
|
-
rangeIndex = ranges.findIndex(function (r) {
|
|
628
|
-
return r.containsCell(column, row);
|
|
629
|
-
});
|
|
605
|
+
break;
|
|
630
606
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
607
|
+
case GridRange.SELECTION_DIRECTION.UP:
|
|
608
|
+
if (row > startRow) {
|
|
609
|
+
return {
|
|
610
|
+
column,
|
|
611
|
+
row: Math.min(row - 1, endRow)
|
|
612
|
+
};
|
|
613
|
+
}
|
|
634
614
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
615
|
+
if (column > startColumn) {
|
|
616
|
+
return {
|
|
617
|
+
column: Math.min(column - 1, endColumn),
|
|
618
|
+
row: endRow
|
|
619
|
+
};
|
|
638
620
|
}
|
|
639
|
-
} // Otherwise go to the start of the next range (could be same range if only one range)
|
|
640
621
|
|
|
622
|
+
break;
|
|
641
623
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
624
|
+
case GridRange.SELECTION_DIRECTION.RIGHT:
|
|
625
|
+
if (column < endColumn) {
|
|
626
|
+
return {
|
|
627
|
+
column: Math.max(column + 1, startColumn),
|
|
628
|
+
row
|
|
629
|
+
};
|
|
630
|
+
}
|
|
650
631
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
632
|
+
if (row < endRow) {
|
|
633
|
+
return {
|
|
634
|
+
column: startColumn,
|
|
635
|
+
row: Math.max(row + 1, startRow)
|
|
636
|
+
};
|
|
637
|
+
}
|
|
655
638
|
|
|
656
|
-
|
|
657
|
-
return _nextRange.startCell(direction);
|
|
658
|
-
}
|
|
639
|
+
break;
|
|
659
640
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
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);
|
|
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;
|
|
641
|
+
case GridRange.SELECTION_DIRECTION.LEFT:
|
|
642
|
+
if (column > startColumn) {
|
|
643
|
+
return {
|
|
644
|
+
column: Math.min(column - 1, endColumn),
|
|
645
|
+
row
|
|
646
|
+
};
|
|
725
647
|
}
|
|
726
|
-
}
|
|
727
648
|
|
|
728
|
-
|
|
649
|
+
if (row > startRow) {
|
|
650
|
+
return {
|
|
651
|
+
column: endColumn,
|
|
652
|
+
row: Math.min(row - 1, endRow)
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
break;
|
|
657
|
+
|
|
658
|
+
default:
|
|
659
|
+
throw new Error("Invalid direction: ".concat(direction));
|
|
729
660
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
661
|
+
|
|
662
|
+
return null;
|
|
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 : {});
|
|
745
688
|
}
|
|
746
|
-
}
|
|
689
|
+
}
|
|
747
690
|
|
|
748
|
-
|
|
749
|
-
}();
|
|
691
|
+
}
|
|
750
692
|
|
|
751
693
|
_defineProperty(GridRange, "SELECTION_DIRECTION", Object.freeze({
|
|
752
694
|
DOWN: 'DOWN',
|