Skip to content

Commit 17b169a

Browse files
committed
Improve performance of table editing cell selection by throttling it
1 parent 9e92a0a commit 17b169a

17 files changed

+22217
-295
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
.tern-port
33
/dist
44
/demo_bundle.js
5+
.idea

demo.base.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import {EditorView} from "prosemirror-view"
2+
import {EditorState} from "prosemirror-state"
3+
import {DOMParser, Schema} from "prosemirror-model"
4+
import {schema as baseSchema} from "prosemirror-schema-basic"
5+
import {baseKeymap} from "prosemirror-commands"
6+
import {keymap} from "prosemirror-keymap"
7+
import {exampleSetup, buildMenuItems} from "prosemirror-example-setup"
8+
import {MenuItem, Dropdown} from "prosemirror-menu"
9+
10+
import {addColumnAfter, addColumnBefore, deleteColumn, addRowAfter, addRowBefore, deleteRow,
11+
mergeCells, splitCell, setCellAttr, toggleHeaderRow, toggleHeaderColumn, toggleHeaderCell,
12+
goToNextCell, deleteTable} from "./src/commands"
13+
import {tableEditing, columnResizing, tableNodes, fixTables} from "./src"
14+
15+
let schema = new Schema({
16+
nodes: baseSchema.spec.nodes.append(tableNodes({
17+
tableGroup: "block",
18+
cellContent: "block+",
19+
cellAttributes: {
20+
background: {
21+
default: null,
22+
getFromDOM(dom) { return dom.style.backgroundColor || null },
23+
setDOMAttr(value, attrs) { if (value) attrs.style = (attrs.style || "") + `background-color: ${value};` }
24+
}
25+
}
26+
})),
27+
marks: baseSchema.spec.marks
28+
})
29+
30+
let menu = buildMenuItems(schema).fullMenu
31+
function item(label, cmd) { return new MenuItem({label, select: cmd, run: cmd}) }
32+
let tableMenu = [
33+
item("Insert column before", addColumnBefore),
34+
item("Insert column after", addColumnAfter),
35+
item("Delete column", deleteColumn),
36+
item("Insert row before", addRowBefore),
37+
item("Insert row after", addRowAfter),
38+
item("Delete row", deleteRow),
39+
item("Delete table", deleteTable),
40+
item("Merge cells", mergeCells),
41+
item("Split cell", splitCell),
42+
item("Toggle header column", toggleHeaderColumn),
43+
item("Toggle header row", toggleHeaderRow),
44+
item("Toggle header cells", toggleHeaderCell),
45+
item("Make cell green", setCellAttr("background", "#dfd")),
46+
item("Make cell not-green", setCellAttr("background", null))
47+
]
48+
menu.splice(2, 0, [new Dropdown(tableMenu, {label: "Table"})])
49+
50+
function initialize(doc, {plugins = [], tableEditingOptions = {}, columnResizingOptions = {}} = {}) {
51+
let state = EditorState.create({
52+
doc,
53+
plugins: [
54+
...plugins,
55+
columnResizing(columnResizingOptions),
56+
tableEditing(tableEditingOptions),
57+
keymap({
58+
"Tab": goToNextCell(1),
59+
"Shift-Tab": goToNextCell(-1)
60+
})
61+
].concat(exampleSetup({schema, menuContent: menu}))})
62+
let fix = fixTables(state)
63+
if (fix) state = state.apply(fix.setMeta("addToHistory", false))
64+
65+
window.view = new EditorView(document.querySelector("#editor"), {
66+
state,
67+
})
68+
69+
document.execCommand("enableObjectResizing", false, false)
70+
document.execCommand("enableInlineTableEditing", false, false)
71+
}
72+
73+
74+
export { initialize, schema }

demo.js

Lines changed: 3 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,6 @@
1-
import {EditorView} from "prosemirror-view"
2-
import {EditorState} from "prosemirror-state"
3-
import {DOMParser, Schema} from "prosemirror-model"
4-
import {schema as baseSchema} from "prosemirror-schema-basic"
5-
import {baseKeymap} from "prosemirror-commands"
6-
import {keymap} from "prosemirror-keymap"
7-
import {exampleSetup, buildMenuItems} from "prosemirror-example-setup"
8-
import {MenuItem, Dropdown} from "prosemirror-menu"
9-
10-
import {addColumnAfter, addColumnBefore, deleteColumn, addRowAfter, addRowBefore, deleteRow,
11-
mergeCells, splitCell, setCellAttr, toggleHeaderRow, toggleHeaderColumn, toggleHeaderCell,
12-
goToNextCell, deleteTable} from "./src/commands"
13-
import {tableEditing, columnResizing, tableNodes, fixTables} from "./src"
14-
15-
let schema = new Schema({
16-
nodes: baseSchema.spec.nodes.append(tableNodes({
17-
tableGroup: "block",
18-
cellContent: "block+",
19-
cellAttributes: {
20-
background: {
21-
default: null,
22-
getFromDOM(dom) { return dom.style.backgroundColor || null },
23-
setDOMAttr(value, attrs) { if (value) attrs.style = (attrs.style || "") + `background-color: ${value};` }
24-
}
25-
}
26-
})),
27-
marks: baseSchema.spec.marks
28-
})
29-
30-
let menu = buildMenuItems(schema).fullMenu
31-
function item(label, cmd) { return new MenuItem({label, select: cmd, run: cmd}) }
32-
let tableMenu = [
33-
item("Insert column before", addColumnBefore),
34-
item("Insert column after", addColumnAfter),
35-
item("Delete column", deleteColumn),
36-
item("Insert row before", addRowBefore),
37-
item("Insert row after", addRowAfter),
38-
item("Delete row", deleteRow),
39-
item("Delete table", deleteTable),
40-
item("Merge cells", mergeCells),
41-
item("Split cell", splitCell),
42-
item("Toggle header column", toggleHeaderColumn),
43-
item("Toggle header row", toggleHeaderRow),
44-
item("Toggle header cells", toggleHeaderCell),
45-
item("Make cell green", setCellAttr("background", "#dfd")),
46-
item("Make cell not-green", setCellAttr("background", null))
47-
]
48-
menu.splice(2, 0, [new Dropdown(tableMenu, {label: "Table"})])
1+
import {initialize, schema} from './demo.base'
2+
import {DOMParser} from "prosemirror-model";
493

504
let doc = DOMParser.fromSchema(schema).parse(document.querySelector("#content"))
51-
let state = EditorState.create({doc, plugins: [
52-
columnResizing(),
53-
tableEditing(),
54-
keymap({
55-
"Tab": goToNextCell(1),
56-
"Shift-Tab": goToNextCell(-1)
57-
})
58-
].concat(exampleSetup({schema, menuContent: menu}))})
59-
let fix = fixTables(state)
60-
if (fix) state = state.apply(fix.setMeta("addToHistory", false))
61-
62-
window.view = new EditorView(document.querySelector("#editor"), {state})
635

64-
document.execCommand("enableObjectResizing", false, false)
65-
document.execCommand("enableInlineTableEditing", false, false)
6+
initialize(doc)

demo.large.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const {initialize, schema} = require('./demo.base')
2+
const {decoPlugin} = require("./test/plugins/decorations");
3+
4+
const n = schema.nodes
5+
const rows = new Array(1000).fill(undefined).map((x, R) => {
6+
return n.table_row.createAndFill(
7+
{},
8+
new Array(20).fill(undefined).map((x, C) => {
9+
return n.table_cell.createAndFill(
10+
{}, n.paragraph.create({}, [schema.text(R + ' | ' + C)])
11+
)
12+
}
13+
)
14+
)
15+
}
16+
)
17+
18+
const largeTable = schema.nodes.table.createChecked({}, rows)
19+
const doc = schema.nodes.doc.create({}, largeTable)
20+
21+
initialize(doc, {
22+
plugins: [decoPlugin(['Test Decoration'])],
23+
tableEditingOptions: {
24+
mouseMoveThrottleOptOut: window.location.search.includes('throttle=false')
25+
},
26+
columnResizingOptions: {}
27+
})

0 commit comments

Comments
 (0)