-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Expand file tree
/
Copy pathcolumnResizingSnapshot.ts
More file actions
98 lines (73 loc) · 2.39 KB
/
Copy pathcolumnResizingSnapshot.ts
File metadata and controls
98 lines (73 loc) · 2.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import { Plugin } from '@tiptap/pm/state'
import { columnResizingPluginKey, TableMap } from '@tiptap/pm/tables'
import type { EditorView } from '@tiptap/pm/view'
function findTableElement(view: EditorView, tableStart: number) {
let dom: Node | null = view.domAtPos(tableStart).node
while (dom && dom.nodeName !== 'TABLE') {
dom = dom.parentNode
}
return dom instanceof HTMLTableElement ? dom : null
}
function readRenderedColumnWidths(view: EditorView, tableStart: number, columnCount: number) {
const tableElement = findTableElement(view, tableStart)
if (!tableElement) {
return null
}
const columns = tableElement.querySelectorAll<HTMLTableColElement>(':scope > colgroup > col')
if (columns.length !== columnCount) {
return null
}
const widths = Array.from(columns, col => Math.round(col.getBoundingClientRect().width))
if (widths.some(width => width <= 0)) {
return null
}
return widths
}
function snapshotColumnWidths(view: EditorView, cellPos: number) {
const $cell = view.state.doc.resolve(cellPos)
const table = $cell.node(-1)
const tableStart = $cell.start(-1)
const map = TableMap.get(table)
const cellPositions = [...new Set(map.map)]
const needsSnapshot = cellPositions.some(pos => {
const cell = table.nodeAt(pos)
const colwidth = cell?.attrs.colwidth as number[] | null
return !colwidth || colwidth.length !== cell?.attrs.colspan || colwidth.some(width => !width)
})
if (!needsSnapshot) {
return
}
const widths = readRenderedColumnWidths(view, tableStart, map.width)
if (!widths) {
return
}
const tr = view.state.tr
cellPositions.forEach(pos => {
const cell = table.nodeAt(pos)
if (!cell) {
return
}
const column = map.colCount(pos)
const colwidth = widths.slice(column, column + cell.attrs.colspan)
tr.setNodeMarkup(tableStart + pos, null, { ...cell.attrs, colwidth })
})
if (tr.docChanged) {
tr.setMeta('addToHistory', false)
view.dispatch(tr)
}
}
export function columnResizingSnapshot() {
return new Plugin({
props: {
handleDOMEvents: {
mousedown(view) {
const resizeState = columnResizingPluginKey.getState(view.state)
if (resizeState && resizeState.activeHandle > -1 && !resizeState.dragging) {
snapshotColumnWidths(view, resizeState.activeHandle)
}
return false
},
},
},
})
}