@atlaskit/editor-tables 2.2.4 → 2.2.6
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/CHANGELOG.md +12 -0
- package/dist/cjs/cell-bookmark.js +0 -10
- package/dist/cjs/cell-selection.js +37 -102
- package/dist/cjs/index.js +0 -4
- package/dist/cjs/pm-plugins/input.js +17 -83
- package/dist/cjs/pm-plugins/plugin-key.js +0 -2
- package/dist/cjs/pm-plugins/table-editing.js +17 -18
- package/dist/cjs/pm-plugins.js +0 -2
- package/dist/cjs/table-map.js +67 -138
- package/dist/cjs/utils/add-column-at.js +0 -9
- package/dist/cjs/utils/add-column.js +8 -24
- package/dist/cjs/utils/add-row-at.js +8 -37
- package/dist/cjs/utils/add-row.js +2 -23
- package/dist/cjs/utils/analytics-helpers.js +4 -15
- package/dist/cjs/utils/cells.js +0 -12
- package/dist/cjs/utils/clone-tr.js +0 -2
- package/dist/cjs/utils/colspan.js +2 -18
- package/dist/cjs/utils/copy-paste.js +51 -139
- package/dist/cjs/utils/create-table.js +14 -28
- package/dist/cjs/utils/draw-cell-selection.js +0 -4
- package/dist/cjs/utils/empty-cells.js +0 -6
- package/dist/cjs/utils/find.js +6 -18
- package/dist/cjs/utils/fix-tables.js +13 -56
- package/dist/cjs/utils/for-each-cell.js +3 -17
- package/dist/cjs/utils/get-cell-selection-ranges.js +2 -9
- package/dist/cjs/utils/get-cells-in-column.js +0 -7
- package/dist/cjs/utils/get-cells-in-row.js +0 -7
- package/dist/cjs/utils/get-cells-in-table.js +0 -8
- package/dist/cjs/utils/get-selection-range-in-column.js +6 -27
- package/dist/cjs/utils/get-selection-range-in-row.js +6 -27
- package/dist/cjs/utils/get-selection-rect.js +0 -7
- package/dist/cjs/utils/go-to-next-cell.js +3 -22
- package/dist/cjs/utils/handle-paste.js +5 -34
- package/dist/cjs/utils/is-selected.js +6 -23
- package/dist/cjs/utils/is-selection-type.js +0 -2
- package/dist/cjs/utils/move-column.js +0 -12
- package/dist/cjs/utils/move-row.js +0 -11
- package/dist/cjs/utils/normalize-selection.js +3 -27
- package/dist/cjs/utils/remove-column.js +10 -46
- package/dist/cjs/utils/remove-row.js +8 -49
- package/dist/cjs/utils/remove-table.js +0 -6
- package/dist/cjs/utils/reorder-utils.js +13 -37
- package/dist/cjs/utils/replace-table.js +0 -8
- package/dist/cjs/utils/select-nodes.js +11 -31
- package/dist/cjs/utils/selection-cell.js +0 -5
- package/dist/cjs/utils/selection-rect.js +0 -10
- package/dist/cjs/utils/set-cell-attrs.js +0 -4
- package/dist/cjs/utils/split-cell-with-type.js +2 -35
- package/dist/cjs/utils/split-cell.js +0 -4
- package/dist/cjs/utils/table-node-types.js +4 -8
- package/dist/cjs/utils/tables.js +0 -4
- package/dist/cjs/utils/test-utils.js +9 -26
- package/dist/cjs/utils/toggle-header.js +3 -16
- package/dist/cjs/utils/uuid.js +0 -3
- package/dist/cjs/utils.js +0 -42
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/cell-bookmark.js +0 -5
- package/dist/es2019/cell-selection.js +37 -81
- package/dist/es2019/index.js +1 -0
- package/dist/es2019/pm-plugins/input.js +15 -67
- package/dist/es2019/pm-plugins/table-editing.js +3 -12
- package/dist/es2019/table-map.js +57 -127
- package/dist/es2019/utils/add-column-at.js +2 -4
- package/dist/es2019/utils/add-column.js +6 -16
- package/dist/es2019/utils/add-row-at.js +8 -22
- package/dist/es2019/utils/add-row.js +2 -17
- package/dist/es2019/utils/analytics-helpers.js +0 -5
- package/dist/es2019/utils/cells.js +4 -9
- package/dist/es2019/utils/colspan.js +6 -11
- package/dist/es2019/utils/copy-paste.js +41 -115
- package/dist/es2019/utils/create-table.js +3 -12
- package/dist/es2019/utils/draw-cell-selection.js +0 -1
- package/dist/es2019/utils/empty-cells.js +2 -3
- package/dist/es2019/utils/find.js +8 -8
- package/dist/es2019/utils/fix-tables.js +17 -47
- package/dist/es2019/utils/for-each-cell.js +6 -11
- package/dist/es2019/utils/get-cell-selection-ranges.js +2 -4
- package/dist/es2019/utils/get-cells-in-column.js +2 -3
- package/dist/es2019/utils/get-cells-in-row.js +2 -3
- package/dist/es2019/utils/get-cells-in-table.js +2 -4
- package/dist/es2019/utils/get-selection-range-in-column.js +8 -22
- package/dist/es2019/utils/get-selection-range-in-row.js +8 -22
- package/dist/es2019/utils/get-selection-rect.js +2 -2
- package/dist/es2019/utils/go-to-next-cell.js +3 -19
- package/dist/es2019/utils/handle-paste.js +3 -14
- package/dist/es2019/utils/is-selected.js +8 -10
- package/dist/es2019/utils/is-selection-type.js +0 -1
- package/dist/es2019/utils/move-column.js +3 -8
- package/dist/es2019/utils/move-row.js +3 -7
- package/dist/es2019/utils/normalize-selection.js +0 -16
- package/dist/es2019/utils/remove-column.js +10 -27
- package/dist/es2019/utils/remove-row.js +12 -32
- package/dist/es2019/utils/remove-table.js +2 -4
- package/dist/es2019/utils/reorder-utils.js +11 -26
- package/dist/es2019/utils/replace-table.js +0 -2
- package/dist/es2019/utils/select-nodes.js +9 -20
- package/dist/es2019/utils/selection-cell.js +0 -2
- package/dist/es2019/utils/selection-rect.js +0 -4
- package/dist/es2019/utils/set-cell-attrs.js +2 -2
- package/dist/es2019/utils/split-cell-with-type.js +8 -28
- package/dist/es2019/utils/split-cell.js +3 -2
- package/dist/es2019/utils/table-node-types.js +4 -7
- package/dist/es2019/utils/tables.js +0 -2
- package/dist/es2019/utils/test-utils.js +12 -16
- package/dist/es2019/utils/toggle-header.js +3 -10
- package/dist/es2019/utils/uuid.js +0 -2
- package/dist/es2019/version.json +1 -1
- package/dist/esm/cell-bookmark.js +0 -5
- package/dist/esm/cell-selection.js +37 -79
- package/dist/esm/index.js +1 -0
- package/dist/esm/pm-plugins/input.js +17 -71
- package/dist/esm/pm-plugins/table-editing.js +8 -13
- package/dist/esm/table-map.js +68 -133
- package/dist/esm/utils/add-column-at.js +2 -4
- package/dist/esm/utils/add-column.js +8 -20
- package/dist/esm/utils/add-row-at.js +8 -23
- package/dist/esm/utils/add-row.js +2 -21
- package/dist/esm/utils/analytics-helpers.js +4 -10
- package/dist/esm/utils/cells.js +0 -5
- package/dist/esm/utils/colspan.js +2 -14
- package/dist/esm/utils/copy-paste.js +44 -125
- package/dist/esm/utils/create-table.js +14 -25
- package/dist/esm/utils/draw-cell-selection.js +0 -1
- package/dist/esm/utils/empty-cells.js +2 -3
- package/dist/esm/utils/find.js +8 -8
- package/dist/esm/utils/fix-tables.js +13 -49
- package/dist/esm/utils/for-each-cell.js +6 -11
- package/dist/esm/utils/get-cell-selection-ranges.js +2 -4
- package/dist/esm/utils/get-cells-in-column.js +2 -3
- package/dist/esm/utils/get-cells-in-row.js +2 -3
- package/dist/esm/utils/get-cells-in-table.js +2 -4
- package/dist/esm/utils/get-selection-range-in-column.js +8 -24
- package/dist/esm/utils/get-selection-range-in-row.js +8 -24
- package/dist/esm/utils/get-selection-rect.js +2 -2
- package/dist/esm/utils/go-to-next-cell.js +3 -19
- package/dist/esm/utils/handle-paste.js +5 -23
- package/dist/esm/utils/is-selected.js +8 -10
- package/dist/esm/utils/is-selection-type.js +0 -1
- package/dist/esm/utils/move-column.js +3 -8
- package/dist/esm/utils/move-row.js +3 -7
- package/dist/esm/utils/normalize-selection.js +3 -22
- package/dist/esm/utils/remove-column.js +10 -31
- package/dist/esm/utils/remove-row.js +8 -35
- package/dist/esm/utils/remove-table.js +2 -4
- package/dist/esm/utils/reorder-utils.js +11 -26
- package/dist/esm/utils/replace-table.js +0 -2
- package/dist/esm/utils/select-nodes.js +11 -22
- package/dist/esm/utils/selection-cell.js +0 -2
- package/dist/esm/utils/selection-rect.js +0 -4
- package/dist/esm/utils/set-cell-attrs.js +2 -2
- package/dist/esm/utils/split-cell-with-type.js +2 -28
- package/dist/esm/utils/split-cell.js +3 -2
- package/dist/esm/utils/table-node-types.js +4 -7
- package/dist/esm/utils/tables.js +0 -2
- package/dist/esm/utils/test-utils.js +12 -16
- package/dist/esm/utils/toggle-header.js +3 -10
- package/dist/esm/version.json +1 -1
- package/package.json +6 -4
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
// Was copied from https://github.com/ProseMirror/prosemirror-tables/blob/master/src/cellselection.js
|
|
2
|
+
|
|
2
3
|
// This file defines a ProseMirror selection subclass that models
|
|
3
4
|
// table cell selections. The table plugin needs to be active to wire
|
|
4
5
|
// in the user interaction part of table selections (so that you
|
|
5
6
|
// actually get such selections when you select across cells).
|
|
7
|
+
|
|
6
8
|
import { Fragment, Slice } from 'prosemirror-model';
|
|
7
9
|
import { Selection, TextSelection } from 'prosemirror-state';
|
|
8
10
|
import { CellBookmark } from './cell-bookmark';
|
|
@@ -10,56 +12,52 @@ import { TableMap } from './table-map';
|
|
|
10
12
|
import { pointsAtCell } from './utils/cells';
|
|
11
13
|
import { removeColSpan } from './utils/colspan';
|
|
12
14
|
import { getCellSelectionRanges } from './utils/get-cell-selection-ranges';
|
|
13
|
-
import { inSameTable } from './utils/tables';
|
|
15
|
+
import { inSameTable } from './utils/tables';
|
|
16
|
+
|
|
17
|
+
// ::- A [`Selection`](http://prosemirror.net/docs/ref/#state.Selection)
|
|
14
18
|
// subclass that represents a cell selection spanning part of a table.
|
|
15
19
|
// With the plugin enabled, these will be created when the user
|
|
16
20
|
// selects across cells, and will be drawn by giving selected cells a
|
|
17
21
|
// `selectedCell` CSS class.
|
|
18
|
-
|
|
19
22
|
export class CellSelection extends Selection {
|
|
20
23
|
// :: (ResolvedPos, ?ResolvedPos)
|
|
21
24
|
// A table selection is identified by its anchor and head cells. The
|
|
22
25
|
// positions given to this constructor should point _before_ two
|
|
23
26
|
// cells in the same table. They may be the same, to select a single
|
|
24
27
|
// cell.
|
|
28
|
+
|
|
25
29
|
constructor($anchorCell, $headCell = $anchorCell) {
|
|
26
30
|
const ranges = getCellSelectionRanges($anchorCell, $headCell);
|
|
27
|
-
super(ranges[0].$from, ranges[0].$to, ranges);
|
|
31
|
+
super(ranges[0].$from, ranges[0].$to, ranges);
|
|
32
|
+
// :: ResolvedPos
|
|
28
33
|
// A resolved position pointing _in front of_ the anchor cell (the one
|
|
29
34
|
// that doesn't move when extending the selection).
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
this.$anchorCell = $anchorCell;
|
|
36
|
+
// :: ResolvedPos
|
|
32
37
|
// A resolved position pointing in front of the head cell (the one
|
|
33
38
|
// moves when extending the selection).
|
|
34
|
-
|
|
35
39
|
this.$headCell = $headCell;
|
|
36
40
|
this.visible = false;
|
|
37
41
|
}
|
|
38
|
-
|
|
39
42
|
map(doc, mapping) {
|
|
40
43
|
const $anchorCell = doc.resolve(mapping.map(this.$anchorCell.pos));
|
|
41
44
|
const $headCell = doc.resolve(mapping.map(this.$headCell.pos));
|
|
42
|
-
|
|
43
45
|
if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) {
|
|
44
46
|
const tableChanged = this.$anchorCell.node(-1) !== $anchorCell.node(-1);
|
|
45
|
-
|
|
46
47
|
if (tableChanged && this.isRowSelection()) {
|
|
47
48
|
return CellSelection.rowSelection($anchorCell, $headCell);
|
|
48
49
|
}
|
|
49
|
-
|
|
50
50
|
if (tableChanged && this.isColSelection()) {
|
|
51
51
|
return CellSelection.colSelection($anchorCell, $headCell);
|
|
52
52
|
}
|
|
53
|
-
|
|
54
53
|
return new CellSelection($anchorCell, $headCell);
|
|
55
54
|
}
|
|
56
|
-
|
|
57
55
|
return TextSelection.between($anchorCell, $headCell);
|
|
58
|
-
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// :: () → Slice
|
|
59
59
|
// Returns a rectangular slice of table rows containing the selected
|
|
60
60
|
// cells.
|
|
61
|
-
|
|
62
|
-
|
|
63
61
|
content() {
|
|
64
62
|
const table = this.$anchorCell.node(-1);
|
|
65
63
|
const map = TableMap.get(table);
|
|
@@ -67,86 +65,68 @@ export class CellSelection extends Selection {
|
|
|
67
65
|
const rect = map.rectBetween(this.$anchorCell.pos - start, this.$headCell.pos - start);
|
|
68
66
|
const seen = {};
|
|
69
67
|
const rows = [];
|
|
70
|
-
|
|
71
68
|
for (let row = rect.top; row < rect.bottom; row++) {
|
|
72
69
|
const rowContent = [];
|
|
73
|
-
|
|
74
70
|
for (let index = row * map.width + rect.left, col = rect.left; col < rect.right; col++, index++) {
|
|
75
71
|
const pos = map.map[index];
|
|
76
|
-
|
|
77
72
|
if (!seen[pos]) {
|
|
78
73
|
seen[pos] = true;
|
|
79
74
|
const cellRect = map.findCell(pos);
|
|
80
75
|
let cell = table.nodeAt(pos);
|
|
81
|
-
|
|
82
76
|
if (cell === null || cell === undefined) {
|
|
83
77
|
throw new Error(`No cell at position ${pos}`);
|
|
84
78
|
}
|
|
85
|
-
|
|
86
79
|
const extraLeft = rect.left - cellRect.left;
|
|
87
80
|
const extraRight = cellRect.right - rect.right;
|
|
88
|
-
|
|
89
81
|
if (extraLeft > 0 || extraRight > 0) {
|
|
90
82
|
let {
|
|
91
83
|
attrs
|
|
92
84
|
} = cell;
|
|
93
|
-
|
|
94
85
|
if (!attrs) {
|
|
95
86
|
throw new Error(`No cell at position ${pos}`);
|
|
96
87
|
}
|
|
97
|
-
|
|
98
88
|
if (extraLeft > 0) {
|
|
99
89
|
attrs = removeColSpan(attrs, 0, extraLeft);
|
|
100
90
|
}
|
|
101
|
-
|
|
102
91
|
if (extraRight > 0) {
|
|
103
92
|
attrs = removeColSpan(attrs, attrs.colspan - extraRight, extraRight);
|
|
104
93
|
}
|
|
105
|
-
|
|
106
94
|
if (cellRect.left < rect.left) {
|
|
107
95
|
cell = cell.type.createAndFill(attrs);
|
|
108
96
|
} else {
|
|
109
97
|
cell = cell.type.create(attrs, cell.content);
|
|
110
98
|
}
|
|
111
99
|
}
|
|
112
|
-
|
|
113
100
|
if (cell === null || cell === undefined) {
|
|
114
101
|
throw new Error(`No cell at position after create/createAndFill`);
|
|
115
102
|
}
|
|
116
|
-
|
|
117
103
|
if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) {
|
|
118
|
-
const attrs = {
|
|
104
|
+
const attrs = {
|
|
105
|
+
...cell.attrs,
|
|
119
106
|
rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top)
|
|
120
107
|
};
|
|
121
|
-
|
|
122
108
|
if (cellRect.top < rect.top) {
|
|
123
109
|
cell = cell.type.createAndFill(attrs);
|
|
124
110
|
} else {
|
|
125
111
|
cell = cell.type.create(attrs, cell.content);
|
|
126
112
|
}
|
|
127
113
|
}
|
|
128
|
-
|
|
129
114
|
if (cell === null || cell === undefined) {
|
|
130
115
|
throw new Error(`No cell at position before rowContent.push`);
|
|
131
116
|
}
|
|
132
|
-
|
|
133
117
|
rowContent.push(cell);
|
|
134
118
|
}
|
|
135
119
|
}
|
|
136
|
-
|
|
137
120
|
rows.push(table.child(row).copy(Fragment.from(rowContent)));
|
|
138
121
|
}
|
|
139
|
-
|
|
140
122
|
const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
|
|
141
123
|
return new Slice(Fragment.from(fragment), 1, 1);
|
|
142
124
|
}
|
|
143
|
-
|
|
144
125
|
replace(tr, content = Slice.empty) {
|
|
145
126
|
const mapFrom = tr.steps.length;
|
|
146
127
|
const {
|
|
147
128
|
ranges
|
|
148
129
|
} = this;
|
|
149
|
-
|
|
150
130
|
for (let i = 0; i < ranges.length; i++) {
|
|
151
131
|
const {
|
|
152
132
|
$from,
|
|
@@ -155,58 +135,48 @@ export class CellSelection extends Selection {
|
|
|
155
135
|
const mapping = tr.mapping.slice(mapFrom);
|
|
156
136
|
tr.replace(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content);
|
|
157
137
|
}
|
|
158
|
-
|
|
159
138
|
const sel = Selection.findFrom(tr.doc.resolve(tr.mapping.slice(mapFrom).map(this.to)), -1);
|
|
160
|
-
|
|
161
139
|
if (sel) {
|
|
162
140
|
tr.setSelection(sel);
|
|
163
141
|
}
|
|
164
142
|
}
|
|
165
|
-
|
|
166
143
|
replaceWith(tr, node) {
|
|
167
144
|
this.replace(tr, new Slice(Fragment.from(node), 0, 0));
|
|
168
145
|
}
|
|
169
|
-
|
|
170
146
|
forEachCell(f) {
|
|
171
147
|
const table = this.$anchorCell.node(-1);
|
|
172
148
|
const map = TableMap.get(table);
|
|
173
149
|
const start = this.$anchorCell.start(-1);
|
|
174
150
|
const cells = map.cellsInRect(map.rectBetween(this.$anchorCell.pos - start, this.$headCell.pos - start));
|
|
175
|
-
|
|
176
151
|
for (let i = 0; i < cells.length; i++) {
|
|
177
152
|
const cell = table.nodeAt(cells[i]);
|
|
178
|
-
|
|
179
153
|
if (cell === null || cell === undefined) {
|
|
180
154
|
throw new Error(`undefined cell at pos ${cells[i]}`);
|
|
181
155
|
}
|
|
182
|
-
|
|
183
156
|
f(cell, start + cells[i]);
|
|
184
157
|
}
|
|
185
|
-
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// :: () → bool
|
|
186
161
|
// True if this selection goes all the way from the top to the
|
|
187
162
|
// bottom of the table.
|
|
188
|
-
|
|
189
|
-
|
|
190
163
|
isColSelection() {
|
|
191
164
|
if (!this.$anchorCell || !this.$headCell) {
|
|
192
165
|
throw new Error('invalid $anchorCell or $headCell');
|
|
193
166
|
}
|
|
194
|
-
|
|
195
167
|
const anchorTop = this.$anchorCell.index(-1);
|
|
196
168
|
const headTop = this.$headCell.index(-1);
|
|
197
|
-
|
|
198
169
|
if (Math.min(anchorTop, headTop) > 0) {
|
|
199
170
|
return false;
|
|
200
171
|
}
|
|
201
|
-
|
|
202
172
|
const anchorBot = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan;
|
|
203
173
|
const headBot = headTop + this.$headCell.nodeAfter.attrs.rowspan;
|
|
204
174
|
return Math.max(anchorBot, headBot) === this.$headCell.node(-1).childCount;
|
|
205
|
-
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// :: (ResolvedPos, ?ResolvedPos) → CellSelection
|
|
206
178
|
// Returns the smallest column selection that covers the given anchor
|
|
207
179
|
// and head cell.
|
|
208
|
-
|
|
209
|
-
|
|
210
180
|
static colSelection($anchorCell, $headCell = $anchorCell) {
|
|
211
181
|
let $calculatedAnchorCell = $anchorCell;
|
|
212
182
|
let $calculatedHeadCell = $headCell;
|
|
@@ -215,12 +185,10 @@ export class CellSelection extends Selection {
|
|
|
215
185
|
const anchorRect = map.findCell($calculatedAnchorCell.pos - start);
|
|
216
186
|
const headRect = map.findCell($calculatedHeadCell.pos - start);
|
|
217
187
|
const doc = $calculatedAnchorCell.node(0);
|
|
218
|
-
|
|
219
188
|
if (anchorRect.top <= headRect.top) {
|
|
220
189
|
if (anchorRect.top > 0) {
|
|
221
190
|
$calculatedAnchorCell = doc.resolve(start + map.map[anchorRect.left]);
|
|
222
191
|
}
|
|
223
|
-
|
|
224
192
|
if (headRect.bottom < map.height) {
|
|
225
193
|
$calculatedHeadCell = doc.resolve(start + map.map[map.width * (map.height - 1) + headRect.right - 1]);
|
|
226
194
|
}
|
|
@@ -228,59 +196,55 @@ export class CellSelection extends Selection {
|
|
|
228
196
|
if (headRect.top > 0) {
|
|
229
197
|
$calculatedHeadCell = doc.resolve(start + map.map[headRect.left]);
|
|
230
198
|
}
|
|
231
|
-
|
|
232
199
|
if (anchorRect.bottom < map.height) {
|
|
233
200
|
$calculatedAnchorCell = doc.resolve(start + map.map[map.width * (map.height - 1) + anchorRect.right - 1]);
|
|
234
201
|
}
|
|
235
202
|
}
|
|
236
|
-
|
|
237
203
|
return new CellSelection($calculatedAnchorCell, $calculatedHeadCell);
|
|
238
|
-
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// :: () → bool
|
|
239
207
|
// True if this selection goes all the way from the left to the
|
|
240
208
|
// right of the table.
|
|
241
|
-
|
|
242
|
-
|
|
243
209
|
isRowSelection() {
|
|
244
210
|
if (!this.$anchorCell || !this.$headCell) {
|
|
245
211
|
return false;
|
|
246
212
|
}
|
|
247
|
-
|
|
248
213
|
const start = this.$anchorCell.start(-1);
|
|
249
214
|
const map = TableMap.get(this.$anchorCell.node(-1));
|
|
250
215
|
const rowAtAnchorCell = map.rowCount(this.$anchorCell.pos - start);
|
|
251
216
|
const rowAtHeadCell = map.rowCount(this.$headCell.pos - start);
|
|
252
|
-
const isSelectionSameRow = rowAtAnchorCell === rowAtHeadCell;
|
|
217
|
+
const isSelectionSameRow = rowAtAnchorCell === rowAtHeadCell;
|
|
218
|
+
|
|
219
|
+
// if anchor and head in the same line, counting how many cells
|
|
253
220
|
// should be in the row except merged cell
|
|
221
|
+
let maxColumnInSelectedRow = map.getMaxColInRow(this.$anchorCell);
|
|
254
222
|
|
|
255
|
-
|
|
223
|
+
// if selected cells less than table max column amount, and
|
|
256
224
|
// the anchor/head not in a merged cell
|
|
257
225
|
// it should be select maxColumnInSelectedRow to be TRUE
|
|
258
|
-
|
|
259
226
|
if (isSelectionSameRow && this.ranges.length <= map.width && !map.isPosMerged(this.$anchorCell.pos - start) && !map.isPosMerged(this.$headCell.pos - start)) {
|
|
260
227
|
return this.ranges.length === maxColumnInSelectedRow;
|
|
261
|
-
}
|
|
262
|
-
// last column to select the whole row.
|
|
263
|
-
|
|
228
|
+
}
|
|
264
229
|
|
|
230
|
+
// If anchor and head in different row, it should be always in first and
|
|
231
|
+
// last column to select the whole row.
|
|
265
232
|
const anchorLeft = map.colCount(this.$anchorCell.pos - start);
|
|
266
233
|
const headLeft = map.colCount(this.$headCell.pos - start);
|
|
267
|
-
|
|
268
234
|
if (Math.min(anchorLeft, headLeft) > 0) {
|
|
269
235
|
return false;
|
|
270
236
|
}
|
|
271
|
-
|
|
272
237
|
const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan;
|
|
273
238
|
const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan;
|
|
274
239
|
return Math.max(anchorRight, headRight) === map.width;
|
|
275
240
|
}
|
|
276
|
-
|
|
277
241
|
eq(other) {
|
|
278
242
|
return other instanceof CellSelection && other.$anchorCell.pos === this.$anchorCell.pos && other.$headCell.pos === this.$headCell.pos;
|
|
279
|
-
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// :: (ResolvedPos, ?ResolvedPos) → CellSelection
|
|
280
246
|
// Returns the smallest row selection that covers the given anchor
|
|
281
247
|
// and head cell.
|
|
282
|
-
|
|
283
|
-
|
|
284
248
|
static rowSelection($anchorCell, $headCell = $anchorCell) {
|
|
285
249
|
let $calculatedAnchorCell = $anchorCell;
|
|
286
250
|
let $calculatedHeadCell = $headCell;
|
|
@@ -289,12 +253,10 @@ export class CellSelection extends Selection {
|
|
|
289
253
|
const anchorRect = map.findCell($calculatedAnchorCell.pos - start);
|
|
290
254
|
const headRect = map.findCell($calculatedHeadCell.pos - start);
|
|
291
255
|
const doc = $calculatedAnchorCell.node(0);
|
|
292
|
-
|
|
293
256
|
if (anchorRect.left <= headRect.left) {
|
|
294
257
|
if (anchorRect.left > 0) {
|
|
295
258
|
$calculatedAnchorCell = doc.resolve(start + map.map[anchorRect.top * map.width]);
|
|
296
259
|
}
|
|
297
|
-
|
|
298
260
|
if (headRect.right < map.width) {
|
|
299
261
|
$calculatedHeadCell = doc.resolve(start + map.map[map.width * (headRect.top + 1) - 1]);
|
|
300
262
|
}
|
|
@@ -302,15 +264,12 @@ export class CellSelection extends Selection {
|
|
|
302
264
|
if (headRect.left > 0) {
|
|
303
265
|
$calculatedHeadCell = doc.resolve(start + map.map[headRect.top * map.width]);
|
|
304
266
|
}
|
|
305
|
-
|
|
306
267
|
if (anchorRect.right < map.width) {
|
|
307
268
|
$calculatedAnchorCell = doc.resolve(start + map.map[map.width * (anchorRect.top + 1) - 1]);
|
|
308
269
|
}
|
|
309
270
|
}
|
|
310
|
-
|
|
311
271
|
return new CellSelection($calculatedAnchorCell, $calculatedHeadCell);
|
|
312
272
|
}
|
|
313
|
-
|
|
314
273
|
toJSON() {
|
|
315
274
|
return {
|
|
316
275
|
type: 'cell',
|
|
@@ -318,19 +277,16 @@ export class CellSelection extends Selection {
|
|
|
318
277
|
head: this.$headCell.pos
|
|
319
278
|
};
|
|
320
279
|
}
|
|
321
|
-
|
|
322
280
|
static fromJSON(doc, json) {
|
|
323
281
|
return new CellSelection(doc.resolve(json.anchor), doc.resolve(json.head));
|
|
324
|
-
}
|
|
325
|
-
|
|
282
|
+
}
|
|
326
283
|
|
|
284
|
+
// :: (Node, number, ?number) → CellSelection
|
|
327
285
|
static create(doc, anchorCell, headCell = anchorCell) {
|
|
328
286
|
return new CellSelection(doc.resolve(anchorCell), doc.resolve(headCell));
|
|
329
287
|
}
|
|
330
|
-
|
|
331
288
|
getBookmark() {
|
|
332
289
|
return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos);
|
|
333
290
|
}
|
|
334
|
-
|
|
335
291
|
}
|
|
336
292
|
Selection.jsonID('cell', CellSelection);
|
package/dist/es2019/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// This file defines a number of helpers for wiring up user input to
|
|
2
2
|
// table-related functionality.
|
|
3
|
+
|
|
3
4
|
import { keydownHandler } from 'prosemirror-keymap';
|
|
4
5
|
import { Slice } from 'prosemirror-model';
|
|
5
6
|
import { Selection, TextSelection } from 'prosemirror-state';
|
|
@@ -22,46 +23,35 @@ export const handleKeyDown = keydownHandler({
|
|
|
22
23
|
Delete: deleteCellSelection,
|
|
23
24
|
'Mod-Delete': deleteCellSelection
|
|
24
25
|
});
|
|
25
|
-
|
|
26
26
|
function maybeSetSelection(state, dispatch, selection) {
|
|
27
27
|
if (selection.eq(state.selection)) {
|
|
28
28
|
return false;
|
|
29
29
|
}
|
|
30
|
-
|
|
31
30
|
if (dispatch) {
|
|
32
31
|
dispatch(state.tr.setSelection(selection).scrollIntoView());
|
|
33
32
|
}
|
|
34
|
-
|
|
35
33
|
return true;
|
|
36
34
|
}
|
|
37
|
-
|
|
38
35
|
function arrow(axis, dir) {
|
|
39
36
|
return (state, dispatch, view) => {
|
|
40
37
|
if (dispatch) {
|
|
41
38
|
const sel = state.selection;
|
|
42
|
-
|
|
43
39
|
if (sel instanceof CellSelection) {
|
|
44
40
|
return maybeSetSelection(state, dispatch, Selection.near(sel.$headCell, dir));
|
|
45
41
|
}
|
|
46
|
-
|
|
47
42
|
if (axis !== 'horiz' && !sel.empty) {
|
|
48
43
|
return false;
|
|
49
44
|
}
|
|
50
|
-
|
|
51
45
|
const end = view ? atEndOfCell(view, axis, dir) : null;
|
|
52
|
-
|
|
53
46
|
if (end === null) {
|
|
54
47
|
return false;
|
|
55
48
|
}
|
|
56
|
-
|
|
57
49
|
if (axis === 'horiz') {
|
|
58
50
|
return maybeSetSelection(state, dispatch, Selection.near(state.doc.resolve(sel.head + dir), dir));
|
|
59
51
|
}
|
|
60
|
-
|
|
61
52
|
const $cell = state.doc.resolve(end);
|
|
62
53
|
const $next = nextCell($cell, axis, dir);
|
|
63
54
|
let newSel;
|
|
64
|
-
|
|
65
55
|
if ($next) {
|
|
66
56
|
newSel = Selection.near($next, 1);
|
|
67
57
|
} else if (dir < 0) {
|
|
@@ -69,65 +59,50 @@ function arrow(axis, dir) {
|
|
|
69
59
|
} else {
|
|
70
60
|
newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1);
|
|
71
61
|
}
|
|
72
|
-
|
|
73
62
|
return maybeSetSelection(state, dispatch, newSel);
|
|
74
63
|
}
|
|
75
|
-
|
|
76
64
|
return true;
|
|
77
65
|
};
|
|
78
66
|
}
|
|
79
|
-
|
|
80
67
|
function shiftArrow(axis, dir) {
|
|
81
68
|
return (state, dispatch, view) => {
|
|
82
69
|
let sel = state.selection;
|
|
83
|
-
|
|
84
70
|
if (!(sel instanceof CellSelection)) {
|
|
85
71
|
var _maybeTableCell$paren;
|
|
86
|
-
|
|
87
72
|
const end = view ? atEndOfCell(view, axis, dir) : null;
|
|
88
|
-
|
|
89
73
|
if (end === null) {
|
|
90
74
|
return false;
|
|
91
75
|
}
|
|
92
|
-
|
|
93
76
|
const {
|
|
94
77
|
selection: {
|
|
95
78
|
$head,
|
|
96
79
|
$anchor
|
|
97
80
|
}
|
|
98
81
|
} = state;
|
|
99
|
-
const maybeTableCell = $head.blockRange($anchor);
|
|
82
|
+
const maybeTableCell = $head.blockRange($anchor);
|
|
100
83
|
|
|
84
|
+
// Make sure the selection is coming from the same cell
|
|
101
85
|
const sameCell = ['tableCell', 'tableHeader'].includes((maybeTableCell === null || maybeTableCell === void 0 ? void 0 : (_maybeTableCell$paren = maybeTableCell.parent) === null || _maybeTableCell$paren === void 0 ? void 0 : _maybeTableCell$paren.type.name) || '');
|
|
102
|
-
|
|
103
86
|
if (!sameCell) {
|
|
104
87
|
return false;
|
|
105
88
|
}
|
|
106
|
-
|
|
107
89
|
sel = new CellSelection(state.doc.resolve(end));
|
|
108
90
|
}
|
|
109
|
-
|
|
110
91
|
const $head = nextCell(sel.$headCell, axis, dir);
|
|
111
|
-
|
|
112
92
|
if (!$head) {
|
|
113
93
|
return false;
|
|
114
94
|
}
|
|
115
|
-
|
|
116
95
|
if (dispatch) {
|
|
117
96
|
return maybeSetSelection(state, dispatch, new CellSelection(sel.$anchorCell, $head));
|
|
118
97
|
}
|
|
119
|
-
|
|
120
98
|
return true;
|
|
121
99
|
};
|
|
122
100
|
}
|
|
123
|
-
|
|
124
101
|
function deleteCellSelection(state, dispatch) {
|
|
125
102
|
const sel = state.selection;
|
|
126
|
-
|
|
127
103
|
if (!(sel instanceof CellSelection)) {
|
|
128
104
|
return false;
|
|
129
105
|
}
|
|
130
|
-
|
|
131
106
|
if (dispatch) {
|
|
132
107
|
const {
|
|
133
108
|
tr
|
|
@@ -138,39 +113,32 @@ function deleteCellSelection(state, dispatch) {
|
|
|
138
113
|
tr.replace(tr.mapping.map(pos + 1), tr.mapping.map(pos + cell.nodeSize - 1), new Slice(baseContent, 0, 0));
|
|
139
114
|
}
|
|
140
115
|
});
|
|
141
|
-
|
|
142
116
|
if (tr.docChanged) {
|
|
143
117
|
dispatch(tr);
|
|
144
118
|
}
|
|
145
119
|
}
|
|
146
|
-
|
|
147
120
|
return true;
|
|
148
121
|
}
|
|
149
|
-
|
|
150
122
|
export function handleTripleClick(view, pos) {
|
|
151
123
|
const {
|
|
152
124
|
doc
|
|
153
125
|
} = view.state;
|
|
154
126
|
const $cell = cellAround(doc.resolve(pos));
|
|
155
|
-
|
|
156
127
|
if (!$cell) {
|
|
157
128
|
return false;
|
|
158
129
|
}
|
|
159
|
-
|
|
160
130
|
view.dispatch(view.state.tr.setSelection(new CellSelection($cell)));
|
|
161
131
|
return true;
|
|
162
132
|
}
|
|
163
133
|
export function handleMouseDown(view, event) {
|
|
164
|
-
const startEvent = event;
|
|
165
|
-
|
|
134
|
+
const startEvent = event;
|
|
135
|
+
// Prevent right clicks from making a cell selection https://product-fabric.atlassian.net/browse/ED-12527
|
|
166
136
|
if (startEvent.ctrlKey || startEvent.metaKey || startEvent.button === 2 // right mouse click
|
|
167
137
|
) {
|
|
168
138
|
return false;
|
|
169
139
|
}
|
|
170
|
-
|
|
171
140
|
const startDOMCell = domInCell(view, startEvent.target);
|
|
172
141
|
const $anchor = cellAround(view.state.selection.$anchor);
|
|
173
|
-
|
|
174
142
|
if (startEvent.shiftKey && view.state.selection instanceof CellSelection) {
|
|
175
143
|
// Adding to an existing cell selection
|
|
176
144
|
setCellSelection(view.state.selection.$anchorCell, startEvent);
|
|
@@ -183,14 +151,13 @@ export function handleMouseDown(view, event) {
|
|
|
183
151
|
} else if (!startDOMCell) {
|
|
184
152
|
// Not in a cell, let the default behavior happen.
|
|
185
153
|
return false;
|
|
186
|
-
}
|
|
187
|
-
// the position under the mouse.
|
|
188
|
-
|
|
154
|
+
}
|
|
189
155
|
|
|
156
|
+
// Create and dispatch a cell selection between the given anchor and
|
|
157
|
+
// the position under the mouse.
|
|
190
158
|
function setCellSelection($selectionAnchor, event) {
|
|
191
159
|
let $head = cellUnderMouse(view, event);
|
|
192
160
|
const starting = tableEditingKey.getState(view.state) == null;
|
|
193
|
-
|
|
194
161
|
if (!$head || !inSameTable($selectionAnchor, $head)) {
|
|
195
162
|
if (starting) {
|
|
196
163
|
$head = $selectionAnchor;
|
|
@@ -198,109 +165,90 @@ export function handleMouseDown(view, event) {
|
|
|
198
165
|
return false;
|
|
199
166
|
}
|
|
200
167
|
}
|
|
201
|
-
|
|
202
168
|
const selection = new CellSelection($selectionAnchor, $head);
|
|
203
|
-
|
|
204
169
|
if (starting || !view.state.selection.eq(selection)) {
|
|
205
170
|
const tr = view.state.tr.setSelection(selection);
|
|
206
|
-
|
|
207
171
|
if (starting) {
|
|
208
172
|
tr.setMeta(tableEditingKey, $selectionAnchor.pos);
|
|
209
173
|
}
|
|
210
|
-
|
|
211
174
|
view.dispatch(tr);
|
|
212
175
|
}
|
|
213
|
-
}
|
|
214
|
-
|
|
176
|
+
}
|
|
215
177
|
|
|
178
|
+
// Stop listening to mouse motion events.
|
|
216
179
|
function stop() {
|
|
217
180
|
view.root.removeEventListener('mouseup', stop);
|
|
218
181
|
view.root.removeEventListener('dragstart', stop);
|
|
219
182
|
view.root.removeEventListener('mousemove', move);
|
|
220
|
-
|
|
221
183
|
if (tableEditingKey.getState(view.state) != null) {
|
|
222
184
|
view.dispatch(view.state.tr.setMeta(tableEditingKey, -1));
|
|
223
185
|
}
|
|
224
186
|
}
|
|
225
|
-
|
|
226
187
|
function move(event) {
|
|
227
188
|
const anchor = tableEditingKey.getState(view.state);
|
|
228
189
|
let $moveAnchor;
|
|
229
|
-
|
|
230
190
|
if (anchor != null) {
|
|
231
191
|
// Continuing an existing cross-cell selection
|
|
232
192
|
$moveAnchor = view.state.doc.resolve(anchor);
|
|
233
193
|
} else if (domInCell(view, event.target) !== startDOMCell) {
|
|
234
194
|
// Moving out of the initial cell -- start a new cell selection
|
|
235
195
|
$moveAnchor = cellUnderMouse(view, startEvent);
|
|
236
|
-
|
|
237
196
|
if (!$moveAnchor) {
|
|
238
197
|
stop();
|
|
239
198
|
return;
|
|
240
199
|
}
|
|
241
200
|
}
|
|
242
|
-
|
|
243
201
|
if ($moveAnchor) {
|
|
244
202
|
setCellSelection($moveAnchor, event);
|
|
245
203
|
}
|
|
246
204
|
}
|
|
247
|
-
|
|
248
205
|
view.root.addEventListener('mouseup', stop);
|
|
249
206
|
view.root.addEventListener('dragstart', stop);
|
|
250
207
|
view.root.addEventListener('mousemove', move);
|
|
251
208
|
return false;
|
|
252
|
-
}
|
|
253
|
-
// motion would move out of the cell)
|
|
209
|
+
}
|
|
254
210
|
|
|
211
|
+
// Check whether the cursor is at the end of a cell (so that further
|
|
212
|
+
// motion would move out of the cell)
|
|
255
213
|
function atEndOfCell(view, axis, dir) {
|
|
256
214
|
if (!(view.state.selection instanceof TextSelection)) {
|
|
257
215
|
return null;
|
|
258
216
|
}
|
|
259
|
-
|
|
260
217
|
const {
|
|
261
218
|
$head
|
|
262
219
|
} = view.state.selection;
|
|
263
|
-
|
|
264
220
|
for (let d = $head.depth - 1; d >= 0; d--) {
|
|
265
221
|
const parent = $head.node(d);
|
|
266
222
|
const index = dir < 0 ? $head.index(d) : $head.indexAfter(d);
|
|
267
|
-
|
|
268
223
|
if (index !== (dir < 0 ? 0 : parent.childCount)) {
|
|
269
224
|
return null;
|
|
270
225
|
}
|
|
271
|
-
|
|
272
226
|
if (parent.type.spec.tableRole === 'cell' || parent.type.spec.tableRole === 'header_cell') {
|
|
273
227
|
const cellPos = $head.before(d);
|
|
274
|
-
const dirStr =
|
|
228
|
+
const dirStr =
|
|
229
|
+
// eslint-disable-next-line no-nested-ternary
|
|
275
230
|
axis === 'vert' ? dir > 0 ? 'down' : 'up' : dir > 0 ? 'right' : 'left';
|
|
276
231
|
return view.endOfTextblock(dirStr) ? cellPos : null;
|
|
277
232
|
}
|
|
278
233
|
}
|
|
279
|
-
|
|
280
234
|
return null;
|
|
281
235
|
}
|
|
282
|
-
|
|
283
236
|
function domInCell(view, inputDom) {
|
|
284
237
|
let dom = inputDom;
|
|
285
|
-
|
|
286
238
|
for (; dom && dom !== view.dom; dom = dom.parentNode) {
|
|
287
239
|
if (dom.nodeName === 'TD' || dom.nodeName === 'TH') {
|
|
288
240
|
return dom;
|
|
289
241
|
}
|
|
290
242
|
}
|
|
291
|
-
|
|
292
243
|
return null;
|
|
293
244
|
}
|
|
294
|
-
|
|
295
245
|
function cellUnderMouse(view, event) {
|
|
296
246
|
const mousePos = view.posAtCoords({
|
|
297
247
|
left: event.clientX,
|
|
298
248
|
top: event.clientY
|
|
299
249
|
});
|
|
300
|
-
|
|
301
250
|
if (!mousePos) {
|
|
302
251
|
return null;
|
|
303
252
|
}
|
|
304
|
-
|
|
305
253
|
return cellAround(view.state.doc.resolve(mousePos.pos));
|
|
306
254
|
}
|