You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
12 KiB

3 years ago
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core'), require('@tiptap/prosemirror-tables'), require('prosemirror-state')) :
typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core', '@tiptap/prosemirror-tables', 'prosemirror-state'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@tiptap/extension-table"] = {}, global.core, global.prosemirrorTables, global.prosemirrorState));
})(this, (function (exports, core, prosemirrorTables, prosemirrorState) { 'use strict';
function updateColumns(node, colgroup, table, cellMinWidth, overrideCol, overrideValue) {
let totalWidth = 0;
let fixedWidth = true;
let nextDOM = colgroup.firstChild;
const row = node.firstChild;
for (let i = 0, col = 0; i < row.childCount; i += 1) {
const { colspan, colwidth } = row.child(i).attrs;
for (let j = 0; j < colspan; j += 1, col += 1) {
const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j];
const cssWidth = hasWidth ? `${hasWidth}px` : '';
totalWidth += hasWidth || cellMinWidth;
if (!hasWidth) {
fixedWidth = false;
}
if (!nextDOM) {
colgroup.appendChild(document.createElement('col')).style.width = cssWidth;
}
else {
if (nextDOM.style.width !== cssWidth) {
nextDOM.style.width = cssWidth;
}
nextDOM = nextDOM.nextSibling;
}
}
}
while (nextDOM) {
const after = nextDOM.nextSibling;
nextDOM.parentNode.removeChild(nextDOM);
nextDOM = after;
}
if (fixedWidth) {
table.style.width = `${totalWidth}px`;
table.style.minWidth = '';
}
else {
table.style.width = '';
table.style.minWidth = `${totalWidth}px`;
}
}
class TableView {
constructor(node, cellMinWidth) {
this.node = node;
this.cellMinWidth = cellMinWidth;
this.dom = document.createElement('div');
this.dom.className = 'tableWrapper';
this.table = this.dom.appendChild(document.createElement('table'));
this.colgroup = this.table.appendChild(document.createElement('colgroup'));
updateColumns(node, this.colgroup, this.table, cellMinWidth);
this.contentDOM = this.table.appendChild(document.createElement('tbody'));
}
update(node) {
if (node.type !== this.node.type) {
return false;
}
this.node = node;
updateColumns(node, this.colgroup, this.table, this.cellMinWidth);
return true;
}
ignoreMutation(mutation) {
return mutation.type === 'attributes' && (mutation.target === this.table || this.colgroup.contains(mutation.target));
}
}
function createCell(cellType, cellContent) {
if (cellContent) {
return cellType.createChecked(null, cellContent);
}
return cellType.createAndFill();
}
function getTableNodeTypes(schema) {
if (schema.cached.tableNodeTypes) {
return schema.cached.tableNodeTypes;
}
const roles = {};
Object.keys(schema.nodes).forEach(type => {
const nodeType = schema.nodes[type];
if (nodeType.spec.tableRole) {
roles[nodeType.spec.tableRole] = nodeType;
}
});
schema.cached.tableNodeTypes = roles;
return roles;
}
function createTable(schema, rowsCount, colsCount, withHeaderRow, cellContent) {
const types = getTableNodeTypes(schema);
const headerCells = [];
const cells = [];
for (let index = 0; index < colsCount; index += 1) {
const cell = createCell(types.cell, cellContent);
if (cell) {
cells.push(cell);
}
if (withHeaderRow) {
const headerCell = createCell(types.header_cell, cellContent);
if (headerCell) {
headerCells.push(headerCell);
}
}
}
const rows = [];
for (let index = 0; index < rowsCount; index += 1) {
rows.push(types.row.createChecked(null, withHeaderRow && index === 0 ? headerCells : cells));
}
return types.table.createChecked(null, rows);
}
function isCellSelection(value) {
return value instanceof prosemirrorTables.CellSelection;
}
const deleteTableWhenAllCellsSelected = ({ editor }) => {
const { selection } = editor.state;
if (!isCellSelection(selection)) {
return false;
}
let cellCount = 0;
const table = core.findParentNodeClosestToPos(selection.ranges[0].$from, node => {
return node.type.name === 'table';
});
table === null || table === void 0 ? void 0 : table.node.descendants(node => {
if (node.type.name === 'table') {
return false;
}
if (['tableCell', 'tableHeader'].includes(node.type.name)) {
cellCount += 1;
}
});
const allCellsSelected = cellCount === selection.ranges.length;
if (!allCellsSelected) {
return false;
}
editor.commands.deleteTable();
return true;
};
const Table = core.Node.create({
name: 'table',
// @ts-ignore
addOptions() {
return {
HTMLAttributes: {},
resizable: false,
handleWidth: 5,
cellMinWidth: 25,
// TODO: fix
View: TableView,
lastColumnResizable: true,
allowTableNodeSelection: false,
};
},
content: 'tableRow+',
tableRole: 'table',
isolating: true,
group: 'block',
parseHTML() {
return [
{ tag: 'table' },
];
},
renderHTML({ HTMLAttributes }) {
return ['table', core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), ['tbody', 0]];
},
addCommands() {
return {
insertTable: ({ rows = 3, cols = 3, withHeaderRow = true } = {}) => ({ tr, dispatch, editor }) => {
const node = createTable(editor.schema, rows, cols, withHeaderRow);
if (dispatch) {
const offset = tr.selection.anchor + 1;
tr.replaceSelectionWith(node)
.scrollIntoView()
.setSelection(prosemirrorState.TextSelection.near(tr.doc.resolve(offset)));
}
return true;
},
addColumnBefore: () => ({ state, dispatch }) => {
return prosemirrorTables.addColumnBefore(state, dispatch);
},
addColumnAfter: () => ({ state, dispatch }) => {
return prosemirrorTables.addColumnAfter(state, dispatch);
},
deleteColumn: () => ({ state, dispatch }) => {
return prosemirrorTables.deleteColumn(state, dispatch);
},
addRowBefore: () => ({ state, dispatch }) => {
return prosemirrorTables.addRowBefore(state, dispatch);
},
addRowAfter: () => ({ state, dispatch }) => {
return prosemirrorTables.addRowAfter(state, dispatch);
},
deleteRow: () => ({ state, dispatch }) => {
return prosemirrorTables.deleteRow(state, dispatch);
},
deleteTable: () => ({ state, dispatch }) => {
return prosemirrorTables.deleteTable(state, dispatch);
},
mergeCells: () => ({ state, dispatch }) => {
return prosemirrorTables.mergeCells(state, dispatch);
},
splitCell: () => ({ state, dispatch }) => {
return prosemirrorTables.splitCell(state, dispatch);
},
toggleHeaderColumn: () => ({ state, dispatch }) => {
return prosemirrorTables.toggleHeader('column')(state, dispatch);
},
toggleHeaderRow: () => ({ state, dispatch }) => {
return prosemirrorTables.toggleHeader('row')(state, dispatch);
},
toggleHeaderCell: () => ({ state, dispatch }) => {
return prosemirrorTables.toggleHeaderCell(state, dispatch);
},
mergeOrSplit: () => ({ state, dispatch }) => {
if (prosemirrorTables.mergeCells(state, dispatch)) {
return true;
}
return prosemirrorTables.splitCell(state, dispatch);
},
setCellAttribute: (name, value) => ({ state, dispatch }) => {
return prosemirrorTables.setCellAttr(name, value)(state, dispatch);
},
goToNextCell: () => ({ state, dispatch }) => {
return prosemirrorTables.goToNextCell(1)(state, dispatch);
},
goToPreviousCell: () => ({ state, dispatch }) => {
return prosemirrorTables.goToNextCell(-1)(state, dispatch);
},
fixTables: () => ({ state, dispatch }) => {
if (dispatch) {
prosemirrorTables.fixTables(state);
}
return true;
},
setCellSelection: position => ({ tr, dispatch }) => {
if (dispatch) {
const selection = prosemirrorTables.CellSelection.create(tr.doc, position.anchorCell, position.headCell);
// @ts-ignore
tr.setSelection(selection);
}
return true;
},
};
},
addKeyboardShortcuts() {
return {
Tab: () => {
if (this.editor.commands.goToNextCell()) {
return true;
}
if (!this.editor.can().addRowAfter()) {
return false;
}
return this.editor
.chain()
.addRowAfter()
.goToNextCell()
.run();
},
'Shift-Tab': () => this.editor.commands.goToPreviousCell(),
Backspace: deleteTableWhenAllCellsSelected,
'Mod-Backspace': deleteTableWhenAllCellsSelected,
Delete: deleteTableWhenAllCellsSelected,
'Mod-Delete': deleteTableWhenAllCellsSelected,
};
},
addProseMirrorPlugins() {
const isResizable = this.options.resizable && this.editor.isEditable;
return [
...(isResizable ? [prosemirrorTables.columnResizing({
handleWidth: this.options.handleWidth,
cellMinWidth: this.options.cellMinWidth,
View: this.options.View,
// TODO: PR for @types/prosemirror-tables
// @ts-ignore (incorrect type)
lastColumnResizable: this.options.lastColumnResizable,
})] : []),
prosemirrorTables.tableEditing({
allowTableNodeSelection: this.options.allowTableNodeSelection,
}),
];
},
extendNodeSchema(extension) {
const context = {
name: extension.name,
options: extension.options,
storage: extension.storage,
};
return {
tableRole: core.callOrReturn(core.getExtensionField(extension, 'tableRole', context)),
};
},
});
exports.Table = Table;
exports.createTable = createTable;
exports["default"] = Table;
Object.defineProperty(exports, '__esModule', { value: true });
}));
//# sourceMappingURL=tiptap-extension-table.umd.js.map