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
						
					
					
				
			
		
		
	
	
							308 lines
						
					
					
						
							12 KiB
						
					
					
				| (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
 |