@milkdown/preset-gfm 6.1.4 → 6.3.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.
Files changed (85) hide show
  1. package/lib/auto-link.d.ts.map +1 -1
  2. package/lib/footnote/definition.d.ts +1 -5
  3. package/lib/footnote/definition.d.ts.map +1 -1
  4. package/lib/footnote/reference.d.ts +1 -5
  5. package/lib/footnote/reference.d.ts.map +1 -1
  6. package/lib/index.d.ts +1 -3
  7. package/lib/index.d.ts.map +1 -1
  8. package/lib/index.es.js +1979 -891
  9. package/lib/index.es.js.map +1 -1
  10. package/lib/strike-through.d.ts +1 -5
  11. package/lib/strike-through.d.ts.map +1 -1
  12. package/lib/supported-keys.d.ts +1 -0
  13. package/lib/supported-keys.d.ts.map +1 -1
  14. package/lib/table/command.d.ts +1 -1
  15. package/lib/table/command.d.ts.map +1 -1
  16. package/lib/table/nodes/index.d.ts +2 -23
  17. package/lib/table/nodes/index.d.ts.map +1 -1
  18. package/lib/table/operator-plugin/actions.d.ts +1 -1
  19. package/lib/table/operator-plugin/actions.d.ts.map +1 -1
  20. package/lib/table/operator-plugin/calc-pos.d.ts.map +1 -1
  21. package/lib/table/operator-plugin/helper.d.ts +1 -1
  22. package/lib/table/operator-plugin/helper.d.ts.map +1 -1
  23. package/lib/table/operator-plugin/index.d.ts +1 -1
  24. package/lib/table/operator-plugin/index.d.ts.map +1 -1
  25. package/lib/table/operator-plugin/widget.d.ts +4 -4
  26. package/lib/table/operator-plugin/widget.d.ts.map +1 -1
  27. package/lib/table/plugin/auto-insert-zero-space.d.ts +3 -0
  28. package/lib/table/plugin/auto-insert-zero-space.d.ts.map +1 -0
  29. package/lib/table/plugin/cell-selection.d.ts +38 -0
  30. package/lib/table/plugin/cell-selection.d.ts.map +1 -0
  31. package/lib/table/plugin/column-resizing.d.ts +17 -0
  32. package/lib/table/plugin/column-resizing.d.ts.map +1 -0
  33. package/lib/table/plugin/commands.d.ts +30 -0
  34. package/lib/table/plugin/commands.d.ts.map +1 -0
  35. package/lib/table/plugin/copy-paste.d.ts +13 -0
  36. package/lib/table/plugin/copy-paste.d.ts.map +1 -0
  37. package/lib/table/plugin/fix-tables.d.ts +6 -0
  38. package/lib/table/plugin/fix-tables.d.ts.map +1 -0
  39. package/lib/table/plugin/index.d.ts +4 -0
  40. package/lib/table/plugin/index.d.ts.map +1 -0
  41. package/lib/table/plugin/schema.d.ts +4 -0
  42. package/lib/table/plugin/schema.d.ts.map +1 -0
  43. package/lib/table/plugin/table-editing.d.ts +9 -0
  44. package/lib/table/plugin/table-editing.d.ts.map +1 -0
  45. package/lib/table/plugin/table-map.d.ts +44 -0
  46. package/lib/table/plugin/table-map.d.ts.map +1 -0
  47. package/lib/table/plugin/table-view.d.ts +15 -0
  48. package/lib/table/plugin/table-view.d.ts.map +1 -0
  49. package/lib/table/plugin/types.d.ts +15 -0
  50. package/lib/table/plugin/types.d.ts.map +1 -0
  51. package/lib/table/plugin/util.d.ts +16 -0
  52. package/lib/table/plugin/util.d.ts.map +1 -0
  53. package/lib/table/utils.d.ts +6 -6
  54. package/lib/table/utils.d.ts.map +1 -1
  55. package/lib/task-list-item.d.ts +1 -5
  56. package/lib/task-list-item.d.ts.map +1 -1
  57. package/package.json +8 -7
  58. package/src/auto-link.ts +4 -3
  59. package/src/footnote/definition.ts +3 -1
  60. package/src/footnote/reference.ts +2 -1
  61. package/src/table/command.ts +3 -3
  62. package/src/table/nodes/index.ts +7 -3
  63. package/src/table/operator-plugin/actions.ts +4 -4
  64. package/src/table/operator-plugin/calc-pos.ts +4 -2
  65. package/src/table/operator-plugin/helper.ts +2 -1
  66. package/src/table/operator-plugin/index.ts +1 -1
  67. package/src/table/operator-plugin/widget.ts +4 -14
  68. package/src/table/plugin/auto-insert-zero-space.ts +51 -0
  69. package/src/table/plugin/cell-selection.ts +352 -0
  70. package/src/table/plugin/column-resizing.ts +260 -0
  71. package/src/table/plugin/commands.ts +551 -0
  72. package/src/table/plugin/copy-paste.ts +306 -0
  73. package/src/table/plugin/fix-tables.ts +117 -0
  74. package/src/table/plugin/index.ts +4 -0
  75. package/src/table/plugin/schema.ts +114 -0
  76. package/src/table/plugin/table-editing.ts +275 -0
  77. package/src/table/plugin/table-map.ts +280 -0
  78. package/src/table/plugin/table-view.ts +76 -0
  79. package/src/table/plugin/types.ts +16 -0
  80. package/src/table/plugin/util.ts +107 -0
  81. package/src/table/utils.ts +31 -22
  82. package/src/task-list-item.ts +4 -2
  83. package/lib/table/nodes/schema.d.ts +0 -2
  84. package/lib/table/nodes/schema.d.ts.map +0 -1
  85. package/src/table/nodes/schema.ts +0 -16
@@ -0,0 +1,260 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+ import { Attrs, Node } from '@milkdown/prose/model';
3
+ import { EditorState, Plugin, PluginKey, Transaction } from '@milkdown/prose/state';
4
+ import { Decoration, DecorationSet, EditorView } from '@milkdown/prose/view';
5
+
6
+ import { tableNodeTypes } from './schema';
7
+ import { TableMap } from './table-map';
8
+ import { TableView, updateColumns } from './table-view';
9
+ import { cellAround, pointsAtCell, setAttr } from './util';
10
+
11
+ export const key = new PluginKey('tableColumnResizing');
12
+
13
+ export function columnResizing({
14
+ handleWidth = 5,
15
+ cellMinWidth = 25,
16
+ View = TableView,
17
+ lastColumnResizable = true,
18
+ } = {}) {
19
+ const plugin = new Plugin({
20
+ key,
21
+ state: {
22
+ init(this: Plugin, _, state) {
23
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
24
+ this.spec.props!.nodeViews![tableNodeTypes(state.schema).table.name] = (node) =>
25
+ new View(node, cellMinWidth);
26
+ return new ResizeState(-1, false);
27
+ },
28
+ apply(tr, prev) {
29
+ return prev.apply(tr);
30
+ },
31
+ },
32
+ props: {
33
+ attributes(state) {
34
+ const pluginState = key.getState(state);
35
+ return pluginState.activeHandle > -1 ? { class: 'resize-cursor' } : (undefined as unknown as Attrs);
36
+ },
37
+
38
+ handleDOMEvents: {
39
+ mousemove(view, event) {
40
+ handleMouseMove(view, event as MouseEvent, handleWidth, lastColumnResizable);
41
+ },
42
+ mouseleave(view) {
43
+ handleMouseLeave(view);
44
+ },
45
+ mousedown(view, event) {
46
+ handleMouseDown(view, event as MouseEvent, cellMinWidth);
47
+ },
48
+ },
49
+
50
+ decorations(state) {
51
+ const pluginState = key.getState(state);
52
+ if (pluginState.activeHandle > -1) return handleDecorations(state, pluginState.activeHandle);
53
+
54
+ return null;
55
+ },
56
+
57
+ nodeViews: {},
58
+ },
59
+ });
60
+ return plugin;
61
+ }
62
+
63
+ class ResizeState {
64
+ constructor(public activeHandle: number, public dragging: null | boolean) {
65
+ this.activeHandle = activeHandle;
66
+ this.dragging = dragging;
67
+ }
68
+
69
+ apply(this: ResizeState, tr: Transaction) {
70
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
71
+ let state = this;
72
+ const action = tr.getMeta(key);
73
+ if (action && action.setHandle != null) return new ResizeState(action.setHandle, null);
74
+ if (action && action.setDragging !== undefined) return new ResizeState(state.activeHandle, action.setDragging);
75
+ if (state.activeHandle > -1 && tr.docChanged) {
76
+ let handle = tr.mapping.map(state.activeHandle, -1);
77
+ if (!pointsAtCell(tr.doc.resolve(handle))) handle = 0;
78
+ state = new ResizeState(handle, state.dragging);
79
+ }
80
+ return state;
81
+ }
82
+ }
83
+
84
+ function handleMouseMove(view: EditorView, event: MouseEvent, handleWidth: number, lastColumnResizable: boolean) {
85
+ const pluginState = key.getState(view.state);
86
+
87
+ if (!pluginState.dragging) {
88
+ const target = domCellAround(event.target as Element);
89
+ let cell = -1;
90
+ if (target) {
91
+ const { left, right } = target.getBoundingClientRect();
92
+ if (event.clientX - left <= handleWidth) cell = edgeCell(view, event, 'left');
93
+ else if (right - event.clientX <= handleWidth) cell = edgeCell(view, event, 'right');
94
+ }
95
+
96
+ if (cell != pluginState.activeHandle) {
97
+ if (!lastColumnResizable && cell !== -1) {
98
+ const $cell = view.state.doc.resolve(cell);
99
+ const table = $cell.node(-1),
100
+ map = TableMap.get(table),
101
+ start = $cell.start(-1);
102
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
103
+ const col = map.colCount($cell.pos - start) + $cell.nodeAfter!.attrs['colspan'] - 1;
104
+
105
+ if (col == map.width - 1) {
106
+ return;
107
+ }
108
+ }
109
+
110
+ updateHandle(view, cell);
111
+ }
112
+ }
113
+ }
114
+
115
+ function handleMouseLeave(view: EditorView) {
116
+ const pluginState = key.getState(view.state);
117
+ if (pluginState.activeHandle > -1 && !pluginState.dragging) updateHandle(view, -1);
118
+ }
119
+
120
+ function handleMouseDown(view: EditorView, event: MouseEvent, cellMinWidth: number) {
121
+ const pluginState = key.getState(view.state);
122
+ if (pluginState.activeHandle == -1 || pluginState.dragging) return false;
123
+
124
+ const cell = view.state.doc.nodeAt(pluginState.activeHandle) as Node;
125
+ const width = currentColWidth(view, pluginState.activeHandle, cell.attrs);
126
+ view.dispatch(
127
+ view.state.tr.setMeta(key, {
128
+ setDragging: { startX: event.clientX, startWidth: width },
129
+ }),
130
+ );
131
+
132
+ function finish(event: MouseEvent) {
133
+ window.removeEventListener('mouseup', finish);
134
+ window.removeEventListener('mousemove', move);
135
+ const pluginState = key.getState(view.state);
136
+ if (pluginState.dragging) {
137
+ updateColumnWidth(view, pluginState.activeHandle, draggedWidth(pluginState.dragging, event, cellMinWidth));
138
+ view.dispatch(view.state.tr.setMeta(key, { setDragging: null }));
139
+ }
140
+ }
141
+ function move(event: MouseEvent) {
142
+ if (!event.which) return finish(event);
143
+ const pluginState = key.getState(view.state);
144
+ const dragged = draggedWidth(pluginState.dragging, event, cellMinWidth);
145
+ displayColumnWidth(view, pluginState.activeHandle, dragged, cellMinWidth);
146
+ }
147
+
148
+ window.addEventListener('mouseup', finish);
149
+ window.addEventListener('mousemove', move);
150
+ event.preventDefault();
151
+ return true;
152
+ }
153
+
154
+ function currentColWidth(view: EditorView, cellPos: number, { colspan, colwidth }: Attrs) {
155
+ const width = colwidth && colwidth[colwidth.length - 1];
156
+ if (width) return width;
157
+ const dom = view.domAtPos(cellPos);
158
+ const node = dom.node.childNodes[dom.offset] as HTMLElement;
159
+ let domWidth = node.offsetWidth,
160
+ parts = colspan;
161
+ if (colwidth)
162
+ for (let i = 0; i < colspan; i++)
163
+ if (colwidth[i]) {
164
+ domWidth -= colwidth[i];
165
+ parts--;
166
+ }
167
+ return domWidth / parts;
168
+ }
169
+
170
+ function domCellAround(target: Element | null) {
171
+ while (target && target.nodeName != 'TD' && target.nodeName != 'TH')
172
+ target = target.classList.contains('ProseMirror') ? null : (target.parentNode as Element);
173
+ return target;
174
+ }
175
+
176
+ function edgeCell(view: EditorView, event: MouseEvent, side: 'left' | 'right') {
177
+ const found = view.posAtCoords({ left: event.clientX, top: event.clientY });
178
+ if (!found) return -1;
179
+ const { pos } = found;
180
+ const $cell = cellAround(view.state.doc.resolve(pos));
181
+ if (!$cell) return -1;
182
+ if (side == 'right') return $cell.pos;
183
+ const map = TableMap.get($cell.node(-1)),
184
+ start = $cell.start(-1);
185
+ const index = map.map.indexOf($cell.pos - start);
186
+ return index % map.width == 0 ? -1 : start + (map.map[index - 1] as number);
187
+ }
188
+
189
+ function draggedWidth(dragging: { startX: number; startWidth: number }, event: MouseEvent, cellMinWidth: number) {
190
+ const offset = event.clientX - dragging.startX;
191
+ return Math.max(cellMinWidth, dragging.startWidth + offset);
192
+ }
193
+
194
+ function updateHandle(view: EditorView, value: number) {
195
+ view.dispatch(view.state.tr.setMeta(key, { setHandle: value }));
196
+ }
197
+
198
+ function updateColumnWidth(view: EditorView, cell: number, width: number) {
199
+ const $cell = view.state.doc.resolve(cell);
200
+ const table = $cell.node(-1),
201
+ map = TableMap.get(table),
202
+ start = $cell.start(-1);
203
+ const col = map.colCount($cell.pos - start) + ($cell.nodeAfter as Node).attrs['colspan'] - 1;
204
+ const tr = view.state.tr;
205
+ for (let row = 0; row < map.height; row++) {
206
+ const mapIndex = row * map.width + col;
207
+ // Rowspanning cell that has already been handled
208
+ if (row && map.map[mapIndex] == map.map[mapIndex - map.width]) continue;
209
+ const pos = map.map[mapIndex] as number,
210
+ { attrs } = table.nodeAt(pos) as Node;
211
+ const index = attrs['colspan'] == 1 ? 0 : col - map.colCount(pos);
212
+ if (attrs['colwidth'] && attrs['colwidth'][index] == width) continue;
213
+ const colwidth = attrs['colwidth'] ? attrs['colwidth'].slice() : zeroes(attrs['colspan']);
214
+ colwidth[index] = width;
215
+ tr.setNodeMarkup(start + pos, null, setAttr(attrs, 'colwidth', colwidth));
216
+ }
217
+ if (tr.docChanged) view.dispatch(tr);
218
+ }
219
+
220
+ function displayColumnWidth(view: EditorView, cell: number, width: number, cellMinWidth: number) {
221
+ const $cell = view.state.doc.resolve(cell);
222
+ const table = $cell.node(-1),
223
+ start = $cell.start(-1);
224
+ const col = TableMap.get(table).colCount($cell.pos - start) + ($cell.nodeAfter as Node).attrs['colspan'] - 1;
225
+ let dom = view.domAtPos($cell.start(-1)).node as HTMLElement;
226
+ while (dom.nodeName != 'TABLE') dom = dom.parentNode as HTMLElement;
227
+ updateColumns(table, dom.firstChild as HTMLTableColElement, dom as HTMLTableElement, cellMinWidth, col, width);
228
+ }
229
+
230
+ function zeroes(n: number) {
231
+ const result = [];
232
+ for (let i = 0; i < n; i++) result.push(0);
233
+ return result;
234
+ }
235
+
236
+ function handleDecorations(state: EditorState, cell: number) {
237
+ const decorations = [];
238
+ const $cell = state.doc.resolve(cell);
239
+ const table = $cell.node(-1),
240
+ map = TableMap.get(table),
241
+ start = $cell.start(-1);
242
+ const col = map.colCount($cell.pos - start) + ($cell.nodeAfter as Node).attrs['colspan'];
243
+ for (let row = 0; row < map.height; row++) {
244
+ const index = col + row * map.width - 1;
245
+ // For positions that are have either a different cell or the end
246
+ // of the table to their right, and either the top of the table or
247
+ // a different cell above them, add a decoration
248
+ if (
249
+ (col == map.width || map.map[index] != map.map[index + 1]) &&
250
+ (row == 0 || map.map[index - 1] != map.map[index - 1 - map.width])
251
+ ) {
252
+ const cellPos = map.map[index] as number;
253
+ const pos = start + cellPos + (table.nodeAt(cellPos) as Node).nodeSize - 1;
254
+ const dom = document.createElement('div');
255
+ dom.className = 'column-resize-handle';
256
+ decorations.push(Decoration.widget(pos, dom));
257
+ }
258
+ }
259
+ return DecorationSet.create(state.doc, decorations);
260
+ }