118 lines
3.4 KiB
TypeScript
118 lines
3.4 KiB
TypeScript
import Token from "markdown-it/lib/token";
|
|
import { NodeSpec } from "prosemirror-model";
|
|
import { Plugin } from "prosemirror-state";
|
|
import { DecorationSet, Decoration } from "prosemirror-view";
|
|
import { selectRow, selectTable } from "../commands/table";
|
|
import {
|
|
getCellsInColumn,
|
|
isRowSelected,
|
|
isTableSelected,
|
|
} from "../queries/table";
|
|
import Node from "./Node";
|
|
|
|
export default class TableCell extends Node {
|
|
get name() {
|
|
return "td";
|
|
}
|
|
|
|
get schema(): NodeSpec {
|
|
return {
|
|
content: "(paragraph | embed)+",
|
|
tableRole: "cell",
|
|
isolating: true,
|
|
parseDOM: [{ tag: "td" }],
|
|
toDOM(node) {
|
|
return [
|
|
"td",
|
|
node.attrs.alignment
|
|
? { style: `text-align: ${node.attrs.alignment}` }
|
|
: {},
|
|
0,
|
|
];
|
|
},
|
|
attrs: {
|
|
colspan: { default: 1 },
|
|
rowspan: { default: 1 },
|
|
alignment: { default: null },
|
|
},
|
|
};
|
|
}
|
|
|
|
toMarkdown() {
|
|
// see: renderTable
|
|
}
|
|
|
|
parseMarkdown() {
|
|
return {
|
|
block: "td",
|
|
getAttrs: (tok: Token) => ({ alignment: tok.info }),
|
|
};
|
|
}
|
|
|
|
get plugins() {
|
|
return [
|
|
new Plugin({
|
|
props: {
|
|
decorations: (state) => {
|
|
const { doc } = state;
|
|
const decorations: Decoration[] = [];
|
|
const cells = getCellsInColumn(0)(state);
|
|
|
|
if (cells) {
|
|
cells.forEach((pos, index) => {
|
|
if (index === 0) {
|
|
decorations.push(
|
|
Decoration.widget(pos + 1, () => {
|
|
let className = "grip-table";
|
|
const selected = isTableSelected(state);
|
|
if (selected) {
|
|
className += " selected";
|
|
}
|
|
const grip = document.createElement("a");
|
|
grip.className = className;
|
|
grip.addEventListener("mousedown", (event) => {
|
|
event.preventDefault();
|
|
event.stopImmediatePropagation();
|
|
this.editor.view.dispatch(selectTable(state));
|
|
});
|
|
return grip;
|
|
})
|
|
);
|
|
}
|
|
decorations.push(
|
|
Decoration.widget(pos + 1, () => {
|
|
const rowSelected = isRowSelected(index)(state);
|
|
|
|
let className = "grip-row";
|
|
if (rowSelected) {
|
|
className += " selected";
|
|
}
|
|
if (index === 0) {
|
|
className += " first";
|
|
}
|
|
if (index === cells.length - 1) {
|
|
className += " last";
|
|
}
|
|
const grip = document.createElement("a");
|
|
grip.className = className;
|
|
grip.addEventListener("mousedown", (event) => {
|
|
event.preventDefault();
|
|
event.stopImmediatePropagation();
|
|
this.editor.view.dispatch(
|
|
selectRow(index, event.metaKey || event.shiftKey)(state)
|
|
);
|
|
});
|
|
return grip;
|
|
})
|
|
);
|
|
});
|
|
}
|
|
|
|
return DecorationSet.create(doc, decorations);
|
|
},
|
|
},
|
|
}),
|
|
];
|
|
}
|
|
}
|