1779 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			1779 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | ||
| THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
 | ||
| if you want to view the source, please visit the github repository of this plugin
 | ||
| */
 | ||
| 
 | ||
| var __defProp = Object.defineProperty;
 | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
 | ||
| var __getOwnPropNames = Object.getOwnPropertyNames;
 | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty;
 | ||
| var __export = (target, all) => {
 | ||
|   for (var name in all)
 | ||
|     __defProp(target, name, { get: all[name], enumerable: true });
 | ||
| };
 | ||
| var __copyProps = (to, from, except, desc) => {
 | ||
|   if (from && typeof from === "object" || typeof from === "function") {
 | ||
|     for (let key of __getOwnPropNames(from))
 | ||
|       if (!__hasOwnProp.call(to, key) && key !== except)
 | ||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
 | ||
|   }
 | ||
|   return to;
 | ||
| };
 | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
 | ||
| 
 | ||
| // main.ts
 | ||
| var main_exports = {};
 | ||
| __export(main_exports, {
 | ||
|   default: () => TableEnhancer2
 | ||
| });
 | ||
| module.exports = __toCommonJS(main_exports);
 | ||
| var import_obsidian9 = require("obsidian");
 | ||
| 
 | ||
| // src/global.ts
 | ||
| var import_obsidian = require("obsidian");
 | ||
| var editingCellClassName = "editing-cell";
 | ||
| var hoveredCellClassName = "hovered-cell";
 | ||
| function getCaretPosition(editableElem) {
 | ||
|   let caretPos = 0, sel, range;
 | ||
|   sel = activeWindow.getSelection();
 | ||
|   if (sel && sel.rangeCount) {
 | ||
|     range = sel.getRangeAt(0);
 | ||
|     if (range.commonAncestorContainer.parentNode == editableElem) {
 | ||
|       caretPos = range.endOffset;
 | ||
|     }
 | ||
|   }
 | ||
|   return caretPos;
 | ||
| }
 | ||
| function setCaretPosition(editableElem, newPos) {
 | ||
|   let caretPos = 0, sel, range = activeDocument.createRange();
 | ||
|   sel = activeWindow.getSelection();
 | ||
|   if (sel && sel.rangeCount) {
 | ||
|     range.setStart(editableElem.childNodes[0], newPos);
 | ||
|     range.collapse(true);
 | ||
|     sel.removeAllRanges();
 | ||
|     sel.addRange(range);
 | ||
|   }
 | ||
|   return caretPos;
 | ||
| }
 | ||
| function getCellText(table, i, j) {
 | ||
|   let result = null;
 | ||
|   try {
 | ||
|     result = table.cells[i][j];
 | ||
|   } catch (err) {
 | ||
|     result = null;
 | ||
|     console.error("Cannot get cell i=", i, ", j=", j, " from table=", table);
 | ||
|   }
 | ||
|   return result;
 | ||
| }
 | ||
| function getCellInfo(cellEl, plugin, tableEl, editorView) {
 | ||
|   if (!tableEl)
 | ||
|     tableEl = getTableOfCell(cellEl);
 | ||
|   if (!tableEl) {
 | ||
|     console.error("Cannot get table element of cell ", cellEl);
 | ||
|     return;
 | ||
|   }
 | ||
|   if (!editorView) {
 | ||
|     const markdownView = plugin.app.workspace.getActiveViewOfType(import_obsidian.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     editorView = editor == null ? void 0 : editor.cm;
 | ||
|   }
 | ||
|   const tablePos = editorView.posAtDOM(tableEl);
 | ||
|   const tableLine = editorView.state.doc.lineAt(tablePos).number - 1;
 | ||
|   const trEl = cellEl.closest("tr");
 | ||
|   const i = trEl.rowIndex;
 | ||
|   const j = cellEl.cellIndex;
 | ||
|   return { tableLine, i, j };
 | ||
| }
 | ||
| function getTableOfCell(cellEl) {
 | ||
|   if (!cellEl)
 | ||
|     return;
 | ||
|   let parent = cellEl.parentNode;
 | ||
|   while (parent) {
 | ||
|     if (parent instanceof HTMLTableElement)
 | ||
|       break;
 | ||
|     parent = parent.parentNode;
 | ||
|   }
 | ||
|   if (parent)
 | ||
|     return parent;
 | ||
| }
 | ||
| function getCellEl(tablePos, i, j, plugin) {
 | ||
|   var _a;
 | ||
|   const markdownView = plugin.app.workspace.getActiveViewOfType(import_obsidian.MarkdownView);
 | ||
|   const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|   const editorView = editor == null ? void 0 : editor.cm;
 | ||
|   const { node, offset } = editorView.domAtPos(tablePos);
 | ||
|   const el = node.childNodes[offset];
 | ||
|   if (!(el instanceof HTMLElement))
 | ||
|     return null;
 | ||
|   const tables = el.getElementsByTagName("table");
 | ||
|   if (tables.length > 1) {
 | ||
|     console.error("More than 1 tables were found");
 | ||
|     return null;
 | ||
|   }
 | ||
|   const table = tables[0];
 | ||
|   return (_a = table == null ? void 0 : table.rows[i]) == null ? void 0 : _a.cells[j];
 | ||
| }
 | ||
| function withEditingCell(callback) {
 | ||
|   const cellEl = activeDocument.querySelector("." + editingCellClassName);
 | ||
|   if (!(cellEl instanceof HTMLTableCellElement))
 | ||
|     return null;
 | ||
|   return callback(cellEl);
 | ||
| }
 | ||
| 
 | ||
| // src/tableEditor.ts
 | ||
| var import_obsidian2 = require("obsidian");
 | ||
| 
 | ||
| // src/editorUtils.ts
 | ||
| var getLineStartPos = (line) => ({
 | ||
|   line,
 | ||
|   ch: 0
 | ||
| });
 | ||
| var getLineEndPos = (line, editor) => ({
 | ||
|   line,
 | ||
|   ch: editor.getLine(line).length
 | ||
| });
 | ||
| var deleteLines = (editor, from, to) => {
 | ||
|   if (to === editor.lastLine() + 1) {
 | ||
|     return replaceRangeWithoutScroll(editor, "", getLineEndPos(from - 1, editor), getLineEndPos(to, editor));
 | ||
|   } else {
 | ||
|     return replaceRangeWithoutScroll(editor, "", getLineStartPos(from), getLineStartPos(to));
 | ||
|   }
 | ||
| };
 | ||
| var deleteLine = (editor, line) => {
 | ||
|   return deleteLines(editor, line, line + 1);
 | ||
| };
 | ||
| var getLeadingWhitespace = (lineContent) => {
 | ||
|   const indentation = lineContent.match(/^\s+/);
 | ||
|   return indentation ? indentation[0] : "";
 | ||
| };
 | ||
| var insertLineBelow = (editor, line) => {
 | ||
|   const endOfCurrentLine = getLineEndPos(line, editor);
 | ||
|   const indentation = getLeadingWhitespace(editor.getLine(line));
 | ||
|   return replaceRangeWithoutScroll(editor, "\n" + indentation, endOfCurrentLine);
 | ||
| };
 | ||
| var zf = (e, t) => {
 | ||
|   if (t.line < 0)
 | ||
|     return 0;
 | ||
|   const n = t.line + 1;
 | ||
|   if (n > e.lines)
 | ||
|     return e.length;
 | ||
|   const i = e.line(n);
 | ||
|   return isFinite(t.ch) ? t.ch < 0 ? i.from + Math.max(0, i.length + t.ch) : i.from + t.ch : i.to;
 | ||
| };
 | ||
| var replaceRangeWithoutScroll = (editor, replacement, from, to) => {
 | ||
|   const cm = editor.cm;
 | ||
|   const state = cm.state.doc;
 | ||
|   const from2 = zf(state, from);
 | ||
|   const to2 = to ? zf(state, to) : from2;
 | ||
|   return {
 | ||
|     changes: {
 | ||
|       from: from2,
 | ||
|       to: to2,
 | ||
|       insert: replacement
 | ||
|     },
 | ||
|     scrollIntoView: false,
 | ||
|     sequential: false
 | ||
|   };
 | ||
| };
 | ||
| var setLineWithoutScroll = (editor, n, text) => {
 | ||
|   const cm = editor.cm;
 | ||
|   const state = cm.state.doc;
 | ||
|   const from = zf(state, { line: n, ch: 0 });
 | ||
|   const to = zf(state, { line: n, ch: editor.getLine(n).length });
 | ||
|   return {
 | ||
|     changes: {
 | ||
|       from,
 | ||
|       to,
 | ||
|       insert: text
 | ||
|     },
 | ||
|     scrollIntoView: false,
 | ||
|     sequential: false
 | ||
|   };
 | ||
| };
 | ||
| function withoutScrollAndFocus(editorView, callback) {
 | ||
|   const contentDom = editorView.contentDOM;
 | ||
|   const scrollDom = editorView.scrollDOM;
 | ||
|   const x = scrollDom.scrollLeft;
 | ||
|   const y = scrollDom.scrollTop;
 | ||
|   scrollDom.addEventListener("scroll", (e) => {
 | ||
|     e.stopImmediatePropagation();
 | ||
|     e.preventDefault();
 | ||
|     scrollDom.scrollTo(x, y);
 | ||
|   }, { once: true, capture: true });
 | ||
|   callback();
 | ||
|   contentDom.blur();
 | ||
| }
 | ||
| 
 | ||
| // src/tableEditor.ts
 | ||
| var TableEditor = class {
 | ||
|   constructor(plugin) {
 | ||
|     this.plugin = plugin;
 | ||
|   }
 | ||
|   getTable(tableLine) {
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     if (markdownView instanceof import_obsidian2.MarkdownView && markdownView.editor) {
 | ||
|       const editor = markdownView.editor;
 | ||
|       const lineCount = editor.lineCount();
 | ||
|       const cells = [];
 | ||
|       let match;
 | ||
|       let notStandard = false;
 | ||
|       let formatLine = editor.getLine(tableLine + 1);
 | ||
|       const formatRowRegex = /^\s*(\|)?(?:\s*:?\s*?-+\s*:?\s*\|?){2,}/;
 | ||
|       match = formatRowRegex.exec(formatLine);
 | ||
|       if (!match) {
 | ||
|         for (let i2 = 1; ; i2++) {
 | ||
|           const down = tableLine + 1 + i2;
 | ||
|           const up = tableLine + 1 - i2;
 | ||
|           if (up >= lineCount && down < 0)
 | ||
|             break;
 | ||
|           if (down >= 0) {
 | ||
|             match = formatRowRegex.exec(editor.getLine(down));
 | ||
|             if (match) {
 | ||
|               tableLine = down - 1;
 | ||
|               break;
 | ||
|             }
 | ||
|           }
 | ||
|           if (up < lineCount) {
 | ||
|             match = formatRowRegex.exec(editor.getLine(up));
 | ||
|             if (match) {
 | ||
|               tableLine = down - 1;
 | ||
|               break;
 | ||
|             }
 | ||
|           }
 | ||
|         }
 | ||
|         if (!match)
 | ||
|           return null;
 | ||
|       }
 | ||
|       formatLine = editor.getLine(tableLine + 1);
 | ||
|       if (!match[1]) {
 | ||
|         formatLine = `| ${formatLine} |`;
 | ||
|         editor.setLine(tableLine + 1, formatLine);
 | ||
|         notStandard = true;
 | ||
|       }
 | ||
|       const parsedFormatLine = formatLine.split(/(?<!\\)\|/).slice(1, -1);
 | ||
|       let headerLine = editor.getLine(tableLine);
 | ||
|       if (notStandard) {
 | ||
|         headerLine = `| ${headerLine} |`;
 | ||
|         editor.setLine(tableLine, headerLine);
 | ||
|       }
 | ||
|       const parsedHeaderLine = headerLine.split(/(?<!\\)\|/).slice(1, -1);
 | ||
|       cells.push(parsedHeaderLine);
 | ||
|       let i = tableLine + 1;
 | ||
|       const notStandardRegex = /^\s*[^|]*\|/;
 | ||
|       while (++i < lineCount) {
 | ||
|         let bodyLine = editor.getLine(i);
 | ||
|         if (notStandard) {
 | ||
|           if (notStandardRegex.exec(bodyLine)) {
 | ||
|             bodyLine = `| ${bodyLine} |`;
 | ||
|             editor.setLine(i, bodyLine);
 | ||
|             const parsedBodyLine = bodyLine.split(/(?<!\\)\|/).slice(1, -1);
 | ||
|             cells.push(parsedBodyLine);
 | ||
|           } else
 | ||
|             break;
 | ||
|         } else {
 | ||
|           if (bodyLine.trimStart().startsWith("|")) {
 | ||
|             const parsedBodyLine = bodyLine.split(/(?<!\\)\|/).slice(1, -1);
 | ||
|             cells.push(parsedBodyLine);
 | ||
|           } else
 | ||
|             break;
 | ||
|         }
 | ||
|       }
 | ||
|       return {
 | ||
|         fromLine: tableLine,
 | ||
|         toLine: i,
 | ||
|         formatLine: parsedFormatLine,
 | ||
|         cells
 | ||
|       };
 | ||
|     }
 | ||
|     return null;
 | ||
|   }
 | ||
|   static getLineNumber(table, line) {
 | ||
|     return table.fromLine + (line == 0 ? 0 : line + 1);
 | ||
|   }
 | ||
|   async updateCell(table, i, j, newContent) {
 | ||
|     if (!table)
 | ||
|       return;
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor || !editorView) {
 | ||
|       console.error("Cannot get editor");
 | ||
|       return;
 | ||
|     }
 | ||
|     if (newContent == table.cells[i][j])
 | ||
|       newContent += " ";
 | ||
|     table.cells[i][j] = newContent;
 | ||
|     const rowLineNumber = TableEditor.getLineNumber(table, i);
 | ||
|     const newLine = TableEditor.rowCells2rowString(table.cells[i]);
 | ||
|     withoutScrollAndFocus(editorView, () => {
 | ||
|       editorView.dispatch(setLineWithoutScroll(editor, rowLineNumber, newLine));
 | ||
|     });
 | ||
|   }
 | ||
|   async insertColRight(table, colIndex, col) {
 | ||
|     if (!table)
 | ||
|       return;
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor || !editorView) {
 | ||
|       console.error("Cannot get editor");
 | ||
|       return;
 | ||
|     }
 | ||
|     const textAlignment = this.plugin.settings.defaultAlignmentWhenInsertNewCol == "left" ? ":--" : this.plugin.settings.defaultAlignmentWhenInsertNewCol == "center" ? ":-:" : this.plugin.settings.defaultAlignmentWhenInsertNewCol == "right" ? "--:" : this.plugin.settings.defaultAlignmentWhenInsertNewCol == "follow" ? table.formatLine[colIndex] : null;
 | ||
|     table.formatLine.splice(colIndex + 1, 0, textAlignment);
 | ||
|     table.cells.forEach((row, idx) => {
 | ||
|       const newCell = col ? col[idx] : "   ";
 | ||
|       row.splice(colIndex + 1, 0, newCell);
 | ||
|     });
 | ||
|     const transactionSpecs = [];
 | ||
|     transactionSpecs.push(setLineWithoutScroll(editor, table.fromLine + 1, TableEditor.rowCells2rowString(table.formatLine)));
 | ||
|     for (let i = 0; i < table.cells.length; i++) {
 | ||
|       const lineNumber = TableEditor.getLineNumber(table, i);
 | ||
|       transactionSpecs.push(setLineWithoutScroll(editor, lineNumber, TableEditor.rowCells2rowString(table.cells[i])));
 | ||
|     }
 | ||
|     withoutScrollAndFocus(editorView, () => {
 | ||
|       editorView.dispatch(...transactionSpecs);
 | ||
|     });
 | ||
|   }
 | ||
|   async insertRowBelow(table, rowIndex, row) {
 | ||
|     if (!table)
 | ||
|       return;
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor || !editorView) {
 | ||
|       console.error("Cannot get editor");
 | ||
|       return;
 | ||
|     }
 | ||
|     if (!row) {
 | ||
|       row = [];
 | ||
|       let i = table.formatLine.length;
 | ||
|       while (i--) {
 | ||
|         row.push("  ");
 | ||
|       }
 | ||
|     }
 | ||
|     if (rowIndex == 0) {
 | ||
|       const rowLineNumber = table.fromLine + 1;
 | ||
|       withoutScrollAndFocus(editorView, () => {
 | ||
|         editorView.dispatch(insertLineBelow(editor, rowLineNumber));
 | ||
|         editorView.dispatch(setLineWithoutScroll(editor, rowLineNumber + 1, TableEditor.rowCells2rowString(row)));
 | ||
|       });
 | ||
|     } else {
 | ||
|       const rowLineNumber = TableEditor.getLineNumber(table, rowIndex);
 | ||
|       withoutScrollAndFocus(editorView, () => {
 | ||
|         editorView.dispatch(insertLineBelow(editor, rowLineNumber));
 | ||
|         editorView.dispatch(setLineWithoutScroll(editor, rowLineNumber + 1, TableEditor.rowCells2rowString(row)));
 | ||
|       });
 | ||
|     }
 | ||
|   }
 | ||
|   async setColAligned(table, colIndex, aligned) {
 | ||
|     if (!table)
 | ||
|       return;
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor || !editorView) {
 | ||
|       console.error("Cannot get editor");
 | ||
|       return;
 | ||
|     }
 | ||
|     table.formatLine[colIndex] = aligned == "left" ? ":--" : aligned == "right" ? "--:" : aligned == "center" ? ":-:" : null;
 | ||
|     withoutScrollAndFocus(editorView, () => {
 | ||
|       editorView.dispatch(setLineWithoutScroll(editor, table.fromLine + 1, TableEditor.rowCells2rowString(table.formatLine)));
 | ||
|     });
 | ||
|   }
 | ||
|   async swapCols(table, colIndex1, colIndex2) {
 | ||
|     if (!table)
 | ||
|       return;
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor || !editorView) {
 | ||
|       console.error("Cannot get editor");
 | ||
|       return;
 | ||
|     }
 | ||
|     const colNum = table.cells[0].length;
 | ||
|     if (colIndex1 < 0 || colIndex2 < 0 || colIndex1 >= colNum || colIndex2 >= colNum) {
 | ||
|       console.error("Move out of range");
 | ||
|       return;
 | ||
|     }
 | ||
|     const transactionSpecs = [];
 | ||
|     [table.formatLine[colIndex1], table.formatLine[colIndex2]] = [table.formatLine[colIndex2], table.formatLine[colIndex1]];
 | ||
|     transactionSpecs.push(setLineWithoutScroll(editor, table.fromLine + 1, TableEditor.rowCells2rowString(table.formatLine)));
 | ||
|     for (let i = 0; i < table.cells.length; i++) {
 | ||
|       const lineNumber = TableEditor.getLineNumber(table, i);
 | ||
|       [table.cells[i][colIndex1], table.cells[i][colIndex2]] = [table.cells[i][colIndex2], table.cells[i][colIndex1]];
 | ||
|       transactionSpecs.push(setLineWithoutScroll(editor, lineNumber, TableEditor.rowCells2rowString(table.cells[i])));
 | ||
|     }
 | ||
|     withoutScrollAndFocus(editorView, () => {
 | ||
|       editorView.dispatch(...transactionSpecs);
 | ||
|     });
 | ||
|   }
 | ||
|   async swapRows(table, rowIndex1, rowIndex2) {
 | ||
|     if (!table)
 | ||
|       return;
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor || !editorView) {
 | ||
|       console.error("Cannot get editor");
 | ||
|       return;
 | ||
|     }
 | ||
|     const rowNum = table.cells.length;
 | ||
|     if (rowIndex1 < 1 || rowIndex2 < 1 || rowIndex1 >= rowNum || rowIndex2 >= rowNum) {
 | ||
|       console.error("Move out of range");
 | ||
|       return;
 | ||
|     }
 | ||
|     const transactionSpecs = [];
 | ||
|     [table.cells[rowIndex1], table.cells[rowIndex2]] = [table.cells[rowIndex2], table.cells[rowIndex1]];
 | ||
|     const lineNumber1 = TableEditor.getLineNumber(table, rowIndex1);
 | ||
|     const row1String = TableEditor.rowCells2rowString(table.cells[rowIndex1]);
 | ||
|     transactionSpecs.push(setLineWithoutScroll(editor, lineNumber1, row1String));
 | ||
|     const lineNumber2 = TableEditor.getLineNumber(table, rowIndex2);
 | ||
|     const row2String = TableEditor.rowCells2rowString(table.cells[rowIndex2]);
 | ||
|     transactionSpecs.push(setLineWithoutScroll(editor, lineNumber2, row2String));
 | ||
|     withoutScrollAndFocus(editorView, () => {
 | ||
|       editorView.dispatch(...transactionSpecs);
 | ||
|     });
 | ||
|   }
 | ||
|   async deleteRow(table, rowIndex) {
 | ||
|     if (!table)
 | ||
|       return;
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor || !editorView) {
 | ||
|       console.error("Cannot get editor");
 | ||
|       return;
 | ||
|     }
 | ||
|     if (rowIndex == 0) {
 | ||
|       return;
 | ||
|     }
 | ||
|     const rowLineNumber = TableEditor.getLineNumber(table, rowIndex);
 | ||
|     withoutScrollAndFocus(editorView, () => {
 | ||
|       editorView.dispatch(deleteLine(editor, rowLineNumber));
 | ||
|     });
 | ||
|   }
 | ||
|   async deleteCol(table, colIndex) {
 | ||
|     if (!table)
 | ||
|       return;
 | ||
|     table.formatLine.splice(colIndex, 1);
 | ||
|     for (const row of table.cells)
 | ||
|       row.splice(colIndex, 1);
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor || !editorView) {
 | ||
|       console.error("Cannot get editor");
 | ||
|       return;
 | ||
|     }
 | ||
|     if (table.formatLine.length == 1) {
 | ||
|       editorView.dispatch(deleteLines(editor, table.fromLine, table.toLine));
 | ||
|     } else {
 | ||
|       const transactionSpecs = [];
 | ||
|       transactionSpecs.push(setLineWithoutScroll(editor, table.fromLine + 1, TableEditor.rowCells2rowString(table.formatLine)));
 | ||
|       for (let i = 0; i < table.cells.length; i++) {
 | ||
|         const lineNumber = TableEditor.getLineNumber(table, i);
 | ||
|         transactionSpecs.push(setLineWithoutScroll(editor, lineNumber, TableEditor.rowCells2rowString(table.cells[i])));
 | ||
|       }
 | ||
|       withoutScrollAndFocus(editorView, () => {
 | ||
|         editorView.dispatch(...transactionSpecs);
 | ||
|       });
 | ||
|     }
 | ||
|   }
 | ||
|   async sortByCol(table, colIndex, order) {
 | ||
|     if (!table)
 | ||
|       return;
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor || !editorView) {
 | ||
|       console.error("Cannot get editor");
 | ||
|       return;
 | ||
|     }
 | ||
|     const sortedBody = table.cells.slice(1).sort((row1, row2) => {
 | ||
|       const cell1 = row1[colIndex].toUpperCase();
 | ||
|       const cell2 = row2[colIndex].toUpperCase();
 | ||
|       if (!order || order == "aes")
 | ||
|         return cell1 < cell2 ? -1 : cell1 > cell2 ? 1 : 0;
 | ||
|       else
 | ||
|         return cell1 < cell2 ? 1 : cell1 > cell2 ? -1 : 0;
 | ||
|     });
 | ||
|     const bodyString = sortedBody.map(TableEditor.rowCells2rowString).join("\n");
 | ||
|     editor.replaceRange(bodyString, { line: table.fromLine + 2, ch: 0 }, { line: table.toLine, ch: 0 });
 | ||
|   }
 | ||
|   async createEmptyTable(i, j, fill) {
 | ||
|     if (j < 1 || i < 1) {
 | ||
|       console.error("Cannot create an empty table");
 | ||
|       return;
 | ||
|     }
 | ||
|     const markdownView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor || !editorView) {
 | ||
|       console.error("Cannot get editor");
 | ||
|       return;
 | ||
|     }
 | ||
|     const cursor = editor.getCursor();
 | ||
|     const cursorLine = editor.getLine(cursor.line);
 | ||
|     const bodyString = "|" + "  |".repeat(j);
 | ||
|     const formatString = this.plugin.settings.defaultAlignmentForTableGenerator == "left" ? "|" + ":--|".repeat(j) : this.plugin.settings.defaultAlignmentForTableGenerator == "center" ? "|" + ":-:|".repeat(j) : this.plugin.settings.defaultAlignmentForTableGenerator == "right" ? "|" + "--:|".repeat(j) : null;
 | ||
|     const tableArr = [
 | ||
|       cursorLine,
 | ||
|       "\n",
 | ||
|       bodyString,
 | ||
|       "\n",
 | ||
|       formatString,
 | ||
|       "\n"
 | ||
|     ];
 | ||
|     while (i--)
 | ||
|       tableArr.push(bodyString, "\n");
 | ||
|     editor.setLine(cursor.line, tableArr.join(""));
 | ||
|   }
 | ||
|   static rowCells2rowString(cells) {
 | ||
|     const result = ["|"];
 | ||
|     try {
 | ||
|       for (const cell of cells) {
 | ||
|         result.push(cell.length == 0 ? "  " : cell);
 | ||
|         result.push("|");
 | ||
|       }
 | ||
|     } catch (err) {
 | ||
|       console.error(err);
 | ||
|       console.error(cells);
 | ||
|       throw err;
 | ||
|     }
 | ||
|     return result.join("");
 | ||
|   }
 | ||
| };
 | ||
| 
 | ||
| // src/icon.ts
 | ||
| var insertBelowIcon = `
 | ||
| <svg
 | ||
| 	t="1661842034318"
 | ||
| 	class="icon"
 | ||
| 	viewBox="0 0 1024 1024"
 | ||
| 	version="1.1"
 | ||
| 	xmlns="http://www.w3.org/2000/svg"
 | ||
| 	p-id="5688"
 | ||
| 	width="16"
 | ||
| 	height="16"
 | ||
| >
 | ||
| 	<path
 | ||
| 		d="M904 768H120c-4.4 0-8 3.6-8 8v80c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-80c0-4.4-3.6-8-8-8zM878.7 160H145.3c-18.4 0-33.3 14.3-33.3 32v464c0 17.7 14.9 32 33.3 32h733.3c18.4 0 33.3-14.3 33.3-32V192c0.1-17.7-14.8-32-33.2-32zM360 616H184V456h176v160z m0-224H184V232h176v160z m240 224H424V456h176v160z m0-224H424V232h176v160z m240 224H664V456h176v160z m0-224H664V232h176v160z" 
 | ||
| 		p-id="5689"
 | ||
| 		fill="currentColor"
 | ||
| 	    stroke="currentColor"
 | ||
| 	></path>
 | ||
| </svg>`;
 | ||
| var deleteIcon = `
 | ||
| <svg
 | ||
| 	t="1661781161180"
 | ||
| 	class="icon"
 | ||
| 	viewBox="0 0 1024 1024"
 | ||
| 	version="1.1"
 | ||
| 	xmlns="http://www.w3.org/2000/svg"
 | ||
| 	p-id="3242"
 | ||
| 	width="16"
 | ||
| 	height="16"
 | ||
| >
 | ||
| 	<path
 | ||
| 		d="M512 471.744l207.424-207.36a28.416 28.416 0 1 1 40.256 40.192L552.256 512l207.36 207.424a28.416 28.416 0 1 1-40.192 40.256L512 552.256l-207.424 207.36a28.416 28.416 0 1 1-40.256-40.192L471.744 512l-207.36-207.424a28.416 28.416 0 0 1 40.192-40.256L512 471.744z"
 | ||
| 		p-id="3243"
 | ||
| 		fill="currentColor"
 | ||
| 	    stroke="currentColor"
 | ||
| 	>
 | ||
| 	</path>
 | ||
| </svg>`;
 | ||
| var insertRightIcon = `
 | ||
| <svg
 | ||
| 	t="1661842059940"
 | ||
| 	class="icon"
 | ||
| 	viewBox="0 0 1024 1024"
 | ||
| 	version="1.1"
 | ||
| 	xmlns="http://www.w3.org/2000/svg"
 | ||
| 	p-id="5924"
 | ||
| 	width="16"
 | ||
| 	height="16"
 | ||
| >
 | ||
| 	<path
 | ||
| 		d="M856 112h-80c-4.4 0-8 3.6-8 8v784c0 4.4 3.6 8 8 8h80c4.4 0 8-3.6 8-8V120c0-4.4-3.6-8-8-8zM656 112H192c-17.7 0-32 14.9-32 33.3v733.3c0 18.4 14.3 33.3 32 33.3h464c17.7 0 32-14.9 32-33.3V145.3c0-18.4-14.3-33.3-32-33.3zM392 840H232V664h160v176z m0-240H232V424h160v176z m0-240H232V184h160v176z m224 480H456V664h160v176z m0-240H456V424h160v176z m0-240H456V184h160v176z" 
 | ||
| 		p-id="5925"
 | ||
| 		fill="currentColor"
 | ||
| 	    stroke="currentColor"
 | ||
| 	></path>
 | ||
| </svg>`;
 | ||
| var moveRightIcon = `
 | ||
| <svg
 | ||
| 	t="1662187765148"
 | ||
| 	class="icon"
 | ||
| 	viewBox="0 0 1024 1024"
 | ||
| 	version="1.1"
 | ||
| 	xmlns="http://www.w3.org/2000/svg"
 | ||
| 	p-id="9678"
 | ||
| 	width="16"
 | ||
| 	height="16"
 | ||
| >
 | ||
| 	<path
 | ||
| 		d="M593.450667 512.128L360.064 278.613333l45.290667-45.226666 278.613333 278.762666L405.333333 790.613333l-45.226666-45.269333z" 
 | ||
| 		p-id="9679"
 | ||
| 		fill="currentColor"
 | ||
|     	stroke="currentColor"
 | ||
| 	></path>
 | ||
| </svg>`;
 | ||
| var moveLeftIcon = `
 | ||
| <svg
 | ||
| 	t="1662188090144"
 | ||
| 	class="icon"
 | ||
| 	viewBox="0 0 1024 1024"
 | ||
| 	version="1.1"
 | ||
| 	xmlns="http://www.w3.org/2000/svg"
 | ||
| 	p-id="6067"
 | ||
| 	width="16"
 | ||
| 	height="16"
 | ||
| >
 | ||
| 	<path
 | ||
| 		d="M641.28 278.613333l-45.226667-45.226666-278.634666 278.762666 278.613333 278.485334 45.248-45.269334-233.365333-233.237333z"
 | ||
| 		p-id="6068"
 | ||
| 		fill="currentColor"
 | ||
|     	stroke="currentColor"
 | ||
| 	></path>
 | ||
| </svg>`;
 | ||
| var cloneIcon = `
 | ||
| <svg t="1671932954709" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4984" width="16" height="16"><path d="M160 160v544h128v-64H224V224h416v64h64V160H160z m160 160v544h544V320H320z m64 64h416v416H384V384z" fill="currentColor"
 | ||
|     	stroke="currentColor" p-id="4985"></path></svg>`;
 | ||
| var upwardIcon = `
 | ||
| <svg t="1671934713104" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2640" width="16" height="16"><path d="M830.24 685.76l11.328-11.312a16 16 0 0 0 0-22.64L530.448 340.688a16 16 0 0 0-22.64 0L196.688 651.808a16 16 0 0 0 0 22.64l11.312 11.312a16 16 0 0 0 22.624 0l288.496-288.512L807.632 685.76a16 16 0 0 0 22.624 0z" fill="currentColor"
 | ||
| 	   stroke="currentColor" p-id="2641"></path></svg>`;
 | ||
| var downIcon = `
 | ||
| <svg t="1671934792670" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3163" width="16" height="16"><path d="M830.24 340.688l11.328 11.312a16 16 0 0 1 0 22.624L530.448 685.76a16 16 0 0 1-22.64 0L196.688 374.624a16 16 0 0 1 0-22.624l11.312-11.312a16 16 0 0 1 22.624 0l288.496 288.496 288.512-288.496a16 16 0 0 1 22.624 0z" fill="currentColor"
 | ||
| 	   stroke="currentColor" p-id="3164"></path></svg>`;
 | ||
| var insertColRight = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon">
 | ||
|     <path d="M6,5C5.448,5 5,5.448 5,6L5,18C5,18.552 5.448,19 6,19L12,19C12.552,19 13,18.552 13,18L13,6C13,5.448 12.552,5 12,5L6,5Z"/>
 | ||
|     <path d="M19,19L19,5"/>
 | ||
| </svg>`;
 | ||
| var insertRowBelow = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon">
 | ||
|     <path d="M19,6C19,5.448 18.552,5 18,5L6,5C5.448,5 5,5.448 5,6L5,12C5,12.552 5.448,13 6,13L18,13C18.552,13 19,12.552 19,12L19,6Z"/>
 | ||
|     <path d="M5,19L19,19"/>
 | ||
| </svg>`;
 | ||
| var cloneRow = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon">
 | ||
|     <path d="M19,6L5,6"/>
 | ||
|     <path d="M7,19L5,19"/>
 | ||
|     <path d="M13,19L11,19"/>
 | ||
|     <path d="M19,19L17,19"/>
 | ||
|     <path d="M12,14L15,11"/>
 | ||
|     <path d="M12,14L9,11"/>
 | ||
| </svg>`;
 | ||
| var cloneCol = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon">
 | ||
|     <path d="M6,5L6,19"/>
 | ||
|     <path d="M19,17L19,19"/>
 | ||
|     <path d="M19,11L19,13"/>
 | ||
|     <path d="M19,5L19,7"/>
 | ||
|     <path d="M14,12L11,9"/>
 | ||
|     <path d="M14,12L11,15"/>
 | ||
| </svg>`;
 | ||
| var delRow = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon">
 | ||
|     <path d="M17.75,5L4,5"/>
 | ||
|     <path d="M17.75,19L4,19"/>
 | ||
|     <path d="M12,12L4,12"/>
 | ||
|     <path d="M15,14.5L20,9.5"/>
 | ||
|     <path d="M20,14.5L15,9.5"/>
 | ||
| </svg>`;
 | ||
| var delCol = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon">
 | ||
|     <path d="M5,6.25L5,20"/>
 | ||
|     <path d="M19,6.25L19,20"/>
 | ||
|     <path d="M12,12L12,20"/>
 | ||
|     <path d="M14.5,9L9.5,4"/>
 | ||
|     <path d="M14.5,4L9.5,9"/>
 | ||
| </svg>`;
 | ||
| 
 | ||
| // src/toolBar.ts
 | ||
| var import_obsidian3 = require("obsidian");
 | ||
| var ToolBar = class {
 | ||
|   constructor(plugin) {
 | ||
|     this.plugin = plugin;
 | ||
|     this.rowOpBarEl = createDiv({ cls: "ob-table-enhancer-row-bar" });
 | ||
|     this.colOpBarEl = createDiv({ cls: "ob-table-enhancer-col-bar" });
 | ||
|     this.rowOpBarEl.createDiv({
 | ||
|       cls: "ob-table-enhancer-row-bar-button"
 | ||
|     }, (el) => {
 | ||
|       el.innerHTML = upwardIcon;
 | ||
|       el.onclick = async () => {
 | ||
|         if (this.cell.i == 1) {
 | ||
|           new import_obsidian3.Notice("Current column is already the top row.");
 | ||
|           return;
 | ||
|         }
 | ||
|         const table = await plugin.tableEditor.getTable(this.cell.tableLine);
 | ||
|         if (!table) {
 | ||
|           console.error("Cannot get table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         await this.plugin.tableEditor.swapRows(table, this.cell.i, this.cell.i - 1);
 | ||
|       };
 | ||
|     });
 | ||
|     this.rowOpBarEl.createDiv({
 | ||
|       cls: "ob-table-enhancer-row-bar-button"
 | ||
|     }, (el) => {
 | ||
|       el.innerHTML = downIcon;
 | ||
|       el.onclick = async () => {
 | ||
|         const table = await plugin.tableEditor.getTable(this.cell.tableLine);
 | ||
|         if (!table) {
 | ||
|           console.error("Cannot get table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         const rowNum = table.cells.length;
 | ||
|         if (this.cell.i == rowNum - 1) {
 | ||
|           new import_obsidian3.Notice("Current column is already the bottom row.");
 | ||
|           return;
 | ||
|         }
 | ||
|         await this.plugin.tableEditor.swapRows(table, this.cell.i, this.cell.i + 1);
 | ||
|       };
 | ||
|     });
 | ||
|     this.rowOpBarEl.createDiv({
 | ||
|       cls: "ob-table-enhancer-row-bar-button"
 | ||
|     }, (el) => {
 | ||
|       el.innerHTML = insertBelowIcon;
 | ||
|       el.onclick = async () => {
 | ||
|         const table = await plugin.tableEditor.getTable(this.cell.tableLine);
 | ||
|         if (!table) {
 | ||
|           console.error("Cannot get table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         await this.plugin.tableEditor.insertRowBelow(table, this.cell.i);
 | ||
|       };
 | ||
|     });
 | ||
|     this.colOpBarEl.createDiv({
 | ||
|       cls: "ob-table-enhancer-col-bar-button"
 | ||
|     }, (el) => {
 | ||
|       el.innerHTML = moveLeftIcon;
 | ||
|       el.onclick = async () => {
 | ||
|         if (this.cell.j == 0) {
 | ||
|           new import_obsidian3.Notice("Current column is already the leftmost column.");
 | ||
|           return;
 | ||
|         }
 | ||
|         const table = await plugin.tableEditor.getTable(this.cell.tableLine);
 | ||
|         if (!table) {
 | ||
|           console.error("Cannot get table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         await plugin.tableEditor.swapCols(table, this.cell.j, this.cell.j - 1);
 | ||
|       };
 | ||
|     });
 | ||
|     this.colOpBarEl.createDiv({
 | ||
|       cls: "ob-table-enhancer-col-bar-button"
 | ||
|     }, (el) => {
 | ||
|       el.innerHTML = insertRightIcon;
 | ||
|       el.onclick = async () => {
 | ||
|         const table = await plugin.tableEditor.getTable(this.cell.tableLine);
 | ||
|         if (!table) {
 | ||
|           console.error("Cannot get table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         await this.plugin.tableEditor.insertColRight(table, this.cell.j);
 | ||
|       };
 | ||
|     });
 | ||
|     this.rowOpBarEl.createDiv({
 | ||
|       cls: "ob-table-enhancer-row-bar-button"
 | ||
|     }, (el) => {
 | ||
|       el.innerHTML = deleteIcon;
 | ||
|       el.onclick = async () => {
 | ||
|         if (this.cell.i == 0) {
 | ||
|           new import_obsidian3.Notice("You can't delete the header of a table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         const table = await plugin.tableEditor.getTable(this.cell.tableLine);
 | ||
|         if (!table) {
 | ||
|           console.error("Cannot get table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         await this.plugin.tableEditor.deleteRow(table, this.cell.i);
 | ||
|       };
 | ||
|     });
 | ||
|     this.colOpBarEl.createDiv({
 | ||
|       cls: "ob-table-enhancer-col-bar-button"
 | ||
|     }, (el) => {
 | ||
|       el.innerHTML = deleteIcon;
 | ||
|       el.onclick = async () => {
 | ||
|         const table = await plugin.tableEditor.getTable(this.cell.tableLine);
 | ||
|         if (!table) {
 | ||
|           console.error("Cannot get table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         await this.plugin.tableEditor.deleteCol(table, this.cell.j);
 | ||
|       };
 | ||
|     });
 | ||
|     this.colOpBarEl.createDiv({
 | ||
|       cls: "ob-table-enhancer-col-bar-button"
 | ||
|     }, (el) => {
 | ||
|       el.innerHTML = moveRightIcon;
 | ||
|       el.onclick = async () => {
 | ||
|         const table = await plugin.tableEditor.getTable(this.cell.tableLine);
 | ||
|         if (!table) {
 | ||
|           console.error("Cannot get table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         const colNum = table.formatLine.length;
 | ||
|         if (this.cell.j == colNum - 1) {
 | ||
|           new import_obsidian3.Notice("Current column is already the rightmost column.");
 | ||
|           return;
 | ||
|         }
 | ||
|         await this.plugin.tableEditor.swapCols(table, this.cell.j, this.cell.j + 1);
 | ||
|       };
 | ||
|     });
 | ||
|     this.colOpBarEl.createDiv({
 | ||
|       cls: "ob-table-enhancer-col-bar-button"
 | ||
|     }, (el) => {
 | ||
|       el.innerHTML = cloneIcon;
 | ||
|       el.onclick = async () => {
 | ||
|         const table = await plugin.tableEditor.getTable(this.cell.tableLine);
 | ||
|         if (!table) {
 | ||
|           console.error("Cannot get table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         const col = table.cells.map((row) => row[this.cell.j]);
 | ||
|         await this.plugin.tableEditor.insertColRight(table, this.cell.j, col);
 | ||
|       };
 | ||
|     });
 | ||
|     this.rowOpBarEl.createDiv({
 | ||
|       cls: "ob-table-enhancer-row-bar-button"
 | ||
|     }, (el) => {
 | ||
|       el.innerHTML = cloneIcon;
 | ||
|       el.onclick = async () => {
 | ||
|         const table = await plugin.tableEditor.getTable(this.cell.tableLine);
 | ||
|         if (!table) {
 | ||
|           console.error("Cannot get table.");
 | ||
|           return;
 | ||
|         }
 | ||
|         await this.plugin.tableEditor.insertRowBelow(table, this.cell.i, table.cells[this.cell.i]);
 | ||
|       };
 | ||
|     });
 | ||
|     plugin.registerDomEvent(activeDocument, "scroll", (e) => {
 | ||
|       this.colOpBarEl.style.opacity = "0";
 | ||
|       this.rowOpBarEl.style.opacity = "0";
 | ||
|       this.activeOpBars = [];
 | ||
|     }, true);
 | ||
|     if (activeDocument) {
 | ||
|       activeDocument.body.appendChild(this.rowOpBarEl);
 | ||
|       activeDocument.body.appendChild(this.colOpBarEl);
 | ||
|     }
 | ||
|   }
 | ||
|   tryShowFor(cellEl) {
 | ||
|     if (this.plugin.isInReadingView())
 | ||
|       return;
 | ||
|     if (this.hideTimeout)
 | ||
|       clearTimeout(this.hideTimeout);
 | ||
|     this.cell = getCellInfo(cellEl, this.plugin);
 | ||
|     if (this.cell.j == 0) {
 | ||
|       this.activeOpBars.push(this.rowOpBarEl);
 | ||
|       this.rowOpBarEl.style.opacity = "1";
 | ||
|       this.colOpBarEl.style.zIndex = "99";
 | ||
|       const cellRect = cellEl.getBoundingClientRect();
 | ||
|       const toolBarRect = this.rowOpBarEl.getBoundingClientRect();
 | ||
|       this.rowOpBarEl.style.top = `${cellRect.top}px`;
 | ||
|       this.rowOpBarEl.style.left = `${cellRect.left - toolBarRect.width}px`;
 | ||
|       this.rowOpBarEl.style.height = `${cellRect.height}px`;
 | ||
|     }
 | ||
|     if (this.cell.i == 0) {
 | ||
|       this.activeOpBars.push(this.colOpBarEl);
 | ||
|       this.colOpBarEl.style.opacity = "1";
 | ||
|       this.colOpBarEl.style.zIndex = "99";
 | ||
|       const cellRect = cellEl.getBoundingClientRect();
 | ||
|       const toolBarRect = this.colOpBarEl.getBoundingClientRect();
 | ||
|       this.colOpBarEl.style.top = `${cellRect.top - toolBarRect.height}px`;
 | ||
|       this.colOpBarEl.style.left = `${cellRect.left}px`;
 | ||
|       this.colOpBarEl.style.width = `${cellRect.width}px`;
 | ||
|     }
 | ||
|   }
 | ||
|   tryHide(timeout) {
 | ||
|     this.hideTimeout = setTimeout(() => {
 | ||
|       this.colOpBarEl.style.opacity = "0";
 | ||
|       this.rowOpBarEl.style.opacity = "0";
 | ||
|       this.colOpBarEl.style.zIndex = "-1";
 | ||
|       this.rowOpBarEl.style.zIndex = "-1";
 | ||
|       this.activeOpBars = [];
 | ||
|     }, timeout);
 | ||
|     const stopHideTimeout = (e) => {
 | ||
|       clearTimeout(this.hideTimeout);
 | ||
|       this.activeOpBars.forEach((toolBarEl) => {
 | ||
|         toolBarEl.onmouseout = (e2) => {
 | ||
|           if (e2.relatedTarget instanceof Node && toolBarEl.contains(e2.relatedTarget))
 | ||
|             return;
 | ||
|           this.tryHide(500);
 | ||
|         };
 | ||
|       });
 | ||
|     };
 | ||
|     this.activeOpBars.forEach((toolbar) => {
 | ||
|       toolbar.onmouseenter = stopHideTimeout;
 | ||
|     });
 | ||
|   }
 | ||
|   onUnload() {
 | ||
|     this.colOpBarEl.remove();
 | ||
|     this.rowOpBarEl.remove();
 | ||
|   }
 | ||
| };
 | ||
| 
 | ||
| // src/buttonPanel.ts
 | ||
| var import_obsidian4 = require("obsidian");
 | ||
| var addButtons = (menu, plugin, { tableLine, i, j }) => {
 | ||
|   const oldOnLoad = menu.onload;
 | ||
|   menu.onload = () => {
 | ||
|     oldOnLoad.call(menu);
 | ||
|     const menuDom = menu.dom;
 | ||
|     const containerEl = createDiv({ cls: ["ob-table-enhancer", "button-menu"] });
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Insert row below").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to insert row below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.insertRowBelow(table, i);
 | ||
|     }).then((button) => button.buttonEl.innerHTML = insertRowBelow);
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Insert column right").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to insert column below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.insertColRight(table, j);
 | ||
|     }).then((button) => button.buttonEl.innerHTML = insertColRight);
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Clone row").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to copy row below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.insertRowBelow(table, i, table.cells[i]);
 | ||
|     }).then((button) => button.buttonEl.innerHTML = cloneRow);
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Clone column").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to copy row below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       const col = table.cells.map((row) => row[j]);
 | ||
|       await plugin.tableEditor.insertColRight(table, j, col);
 | ||
|     }).then((button) => button.buttonEl.innerHTML = cloneCol);
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Delete row").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to copy row below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.deleteRow(table, i);
 | ||
|     }).then((button) => button.buttonEl.innerHTML = delRow);
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Wider").setIcon("chevrons-left-right").setClass("clickable-icon").onClick(async (e) => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying sort table ");
 | ||
|         return;
 | ||
|       }
 | ||
|       e.stopPropagation();
 | ||
|       e.preventDefault();
 | ||
|       const oldContent = table.cells[0][j];
 | ||
|       await plugin.tableEditor.updateCell(table, 0, j, oldContent + "\u2007");
 | ||
|     });
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Delete column").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to copy row below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.deleteCol(table, j);
 | ||
|     }).then((button) => button.buttonEl.innerHTML = delCol);
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Move column left").setIcon("chevron-left").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to copy row below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       if (j == 0) {
 | ||
|         new import_obsidian4.Notice("Current column is already the leftmost column.");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.swapCols(table, j, j - 1);
 | ||
|     });
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Move column right").setIcon("chevron-right").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to copy row below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       const colNum = table.formatLine.length;
 | ||
|       if (j == colNum - 1) {
 | ||
|         new import_obsidian4.Notice("Current column is already the rightmost column.");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.swapCols(table, j, j + 1);
 | ||
|     });
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Move row upward").setIcon("chevron-up").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to copy row below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       if (i == 1) {
 | ||
|         new import_obsidian4.Notice("Current column is already the top row.");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.swapRows(table, i, i - 1);
 | ||
|     });
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Move row down").setIcon("chevron-down").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to copy row below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       const rowNum = table.cells.length;
 | ||
|       if (i == rowNum - 1) {
 | ||
|         new import_obsidian4.Notice("Current column is already the bottom row.");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.swapRows(table, i, i + 1);
 | ||
|     });
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Narrower").setIcon("chevrons-right-left").setClass("clickable-icon").onClick(async (e) => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying sort table ");
 | ||
|         return;
 | ||
|       }
 | ||
|       e.stopPropagation();
 | ||
|       e.preventDefault();
 | ||
|       const newContent = table.cells[0][j].replace(/ $/, "");
 | ||
|       await plugin.tableEditor.updateCell(table, 0, j, newContent);
 | ||
|     });
 | ||
|     const setColAlign = (aligned) => async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying to copy row below ");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.setColAligned(table, j, aligned);
 | ||
|     };
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Center align").setIcon("align-center").setClass("clickable-icon").onClick(setColAlign("center"));
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Left align").setIcon("align-left").setClass("clickable-icon").onClick(setColAlign("left"));
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Right align").setIcon("align-right").setClass("clickable-icon").onClick(setColAlign("right"));
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Sort ascending").setIcon("sort-asc").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying sort table ");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.sortByCol(table, j, "aes");
 | ||
|     });
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Sort descending").setIcon("sort-desc").setClass("clickable-icon").onClick(async () => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying sort table ");
 | ||
|         return;
 | ||
|       }
 | ||
|       await plugin.tableEditor.sortByCol(table, j, "desc");
 | ||
|     });
 | ||
|     new import_obsidian4.ButtonComponent(containerEl).setTooltip("Reset Column Width").setIcon("undo-2").setClass("clickable-icon").onClick(async (e) => {
 | ||
|       await plugin.doneEdit();
 | ||
|       const table = plugin.tableEditor.getTable(tableLine);
 | ||
|       if (!table) {
 | ||
|         console.error("cannot locate table when trying sort table ");
 | ||
|         return;
 | ||
|       }
 | ||
|       e.stopPropagation();
 | ||
|       e.preventDefault();
 | ||
|       const newContent = table.cells[0][j].trimRight();
 | ||
|       await plugin.tableEditor.updateCell(table, 0, j, newContent);
 | ||
|     });
 | ||
|     const dividerEl = createDiv({ cls: "menu-separator" });
 | ||
|     menuDom.prepend(dividerEl);
 | ||
|     menuDom.prepend(containerEl);
 | ||
|   };
 | ||
| };
 | ||
| 
 | ||
| // src/tableGenerator.ts
 | ||
| var import_obsidian5 = require("obsidian");
 | ||
| var addTableGenerator = (menu, plugin, editor) => {
 | ||
|   menu.addItem((menuItem) => {
 | ||
|     menuItem.setTitle("Create new table");
 | ||
|     menuItem.setIcon("table");
 | ||
|     menuItem.onClick(async (e) => {
 | ||
|       var _a, _b, _c;
 | ||
|       const cursor = editor.getCursor("from");
 | ||
|       const editor2 = editor;
 | ||
|       let coord;
 | ||
|       if (editor2.coordsAtPos) {
 | ||
|         const offset = editor.posToOffset(cursor);
 | ||
|         coord = (_c = (_b = (_a = editor2.cm).coordsAtPos) == null ? void 0 : _b.call(_a, offset)) != null ? _c : editor2.coordsAtPos(offset);
 | ||
|       } else {
 | ||
|         console.error("Cannot get cursor coordinate");
 | ||
|         return;
 | ||
|       }
 | ||
|       const tableGenerator = new TableGenerator(plugin);
 | ||
|       tableGenerator.showAtPosition({ x: coord.left, y: coord.bottom });
 | ||
|     });
 | ||
|   });
 | ||
| };
 | ||
| var TableGenerator = class extends import_obsidian5.Menu {
 | ||
|   constructor(plugin) {
 | ||
|     super();
 | ||
|     this.plugin = plugin;
 | ||
|     this.addItem((item) => item.setDisabled(true));
 | ||
|   }
 | ||
|   onload() {
 | ||
|     super.onload();
 | ||
|     const menuDom = this.dom;
 | ||
|     const frag = activeDocument.createDocumentFragment();
 | ||
|     const containerEl = frag.createDiv({ cls: "table-generator-container" });
 | ||
|     const counter = frag.createDiv({ cls: ["table-generator-counter", "menu-item"] });
 | ||
|     for (let i = 0; i < 7; i++) {
 | ||
|       for (let j = 0; j < 7; j++) {
 | ||
|         const gridEl = createDiv({ cls: "table-generator-grid" });
 | ||
|         gridEl.setAttr("i", i);
 | ||
|         gridEl.setAttr("j", j);
 | ||
|         gridEl.addEventListener("click", async () => {
 | ||
|           await this.plugin.tableEditor.createEmptyTable(i + 1, j + 1);
 | ||
|         });
 | ||
|         gridEl.addEventListener("mouseenter", async () => {
 | ||
|           containerEl.querySelectorAll(".table-generator-grid").forEach((gridEl2) => {
 | ||
|             const i2 = parseInt(gridEl2.getAttr("i"));
 | ||
|             const j2 = parseInt(gridEl2.getAttr("j"));
 | ||
|             if (i2 > i || j2 > j)
 | ||
|               gridEl2.removeClass("select");
 | ||
|             else
 | ||
|               gridEl2.addClass("select");
 | ||
|           });
 | ||
|           counter.innerText = `${i + 1} rows ${j + 1} columns`;
 | ||
|         });
 | ||
|         containerEl.append(gridEl);
 | ||
|       }
 | ||
|     }
 | ||
|     menuDom.append(frag);
 | ||
|   }
 | ||
| };
 | ||
| 
 | ||
| // src/settings.ts
 | ||
| var import_obsidian6 = require("obsidian");
 | ||
| var DEFAULT_SETTINGS = {
 | ||
|   enableButtonPanel: true,
 | ||
|   enableTableGenerator: true,
 | ||
|   enableFloatingToolbar: false,
 | ||
|   adjustTableCellHeight: true,
 | ||
|   removeEditBlockButton: false,
 | ||
|   defaultAlignmentForTableGenerator: "left",
 | ||
|   defaultAlignmentWhenInsertNewCol: "follow",
 | ||
|   enableColumnWidthAdjust: true
 | ||
| };
 | ||
| var TableEnhancer2SettingTab = class extends import_obsidian6.PluginSettingTab {
 | ||
|   constructor(app2, plugin) {
 | ||
|     super(app2, plugin);
 | ||
|     this.plugin = plugin;
 | ||
|   }
 | ||
|   display() {
 | ||
|     this.containerEl.empty();
 | ||
|     this.containerEl.createEl("h2", { text: "Table Enhancer Settings" });
 | ||
|     new import_obsidian6.Setting(this.containerEl).setName("Enable button panel").addToggle((c) => c.setValue(this.plugin.settings.enableButtonPanel).onChange(async (val) => {
 | ||
|       this.plugin.settings.enableButtonPanel = val;
 | ||
|       await this.plugin.saveSettings();
 | ||
|     }));
 | ||
|     new import_obsidian6.Setting(this.containerEl).setName("Enable table generator").addToggle((c) => c.setValue(this.plugin.settings.enableTableGenerator).onChange(async (val) => {
 | ||
|       this.plugin.settings.enableTableGenerator = val;
 | ||
|       await this.plugin.saveSettings();
 | ||
|     }));
 | ||
|     new import_obsidian6.Setting(this.containerEl).setName("Enable floating panel").addToggle((c) => c.setValue(this.plugin.settings.enableFloatingToolbar).onChange(async (val) => {
 | ||
|       this.plugin.settings.enableFloatingToolbar = val;
 | ||
|       await this.plugin.saveSettings();
 | ||
|     }));
 | ||
|     new import_obsidian6.Setting(this.containerEl).setName("Adjust height of cells").setDesc("The default height of an empty cell is very short. Activate this to increase the cell height and make it easier to click.").addToggle((c) => c.setValue(this.plugin.settings.adjustTableCellHeight).onChange(async (val) => {
 | ||
|       var _a, _b;
 | ||
|       if (val)
 | ||
|         (_a = activeDocument == null ? void 0 : activeDocument.body) == null ? void 0 : _a.addClass("table-height-adjust");
 | ||
|       else
 | ||
|         (_b = activeDocument == null ? void 0 : activeDocument.body) == null ? void 0 : _b.removeClass("table-height-adjust");
 | ||
|       this.plugin.settings.adjustTableCellHeight = val;
 | ||
|       await this.plugin.saveSettings();
 | ||
|     }));
 | ||
|     new import_obsidian6.Setting(this.containerEl).setName("Default alignment for new created table").setDesc("Choose if you want to align the text in a cell to the right, left or in the middle.").addDropdown((d) => d.addOption("left", "left").addOption("center", "center").addOption("right", "right").setValue(this.plugin.settings.defaultAlignmentForTableGenerator).onChange(async (val) => {
 | ||
|       this.plugin.settings.defaultAlignmentForTableGenerator = val;
 | ||
|       await this.plugin.saveSettings();
 | ||
|     }));
 | ||
|     new import_obsidian6.Setting(this.containerEl).setName("Default alignment for new inserted column").setDesc("Choose if you want to align the text in a cell to the right, left, in the middle, or follow other columns.").addDropdown((d) => d.addOption("left", "left").addOption("center", "center").addOption("right", "right").addOption("follow", "follow").setValue(this.plugin.settings.defaultAlignmentWhenInsertNewCol).onChange(async (val) => {
 | ||
|       this.plugin.settings.defaultAlignmentWhenInsertNewCol = val;
 | ||
|       await this.plugin.saveSettings();
 | ||
|     }));
 | ||
|   }
 | ||
| };
 | ||
| 
 | ||
| // src/tableHoverPostProcessor.ts
 | ||
| function getTableHoverPostProcessor(plugin) {
 | ||
|   return (el) => {
 | ||
|     var _a;
 | ||
|     const tables = el.getElementsByTagName("table");
 | ||
|     for (let i = 0; i < tables.length; i++) {
 | ||
|       const table = tables[i];
 | ||
|       const headers = table.rows[0].cells;
 | ||
|       for (let i2 = 0; i2 < headers.length; i2++) {
 | ||
|         const headerCell = headers[i2];
 | ||
|         const oldHtml = headerCell.innerHTML;
 | ||
|         const spaceCnt = (_a = oldHtml.match(/ +$/)) == null ? void 0 : _a[0].length;
 | ||
|         if (spaceCnt) {
 | ||
|           headerCell.innerHTML = oldHtml.slice(0, -spaceCnt);
 | ||
|           headerCell.style.width = String(5 + spaceCnt * 2) + "%";
 | ||
|         }
 | ||
|       }
 | ||
|       for (let i2 = 0; i2 < table.rows.length; i2++) {
 | ||
|         const row = table.rows[i2];
 | ||
|         for (let j = 0; j < row.cells.length; j++) {
 | ||
|           const cell = row.cells[j];
 | ||
|           cell.addEventListener("mouseenter", () => {
 | ||
|             cell.addClass(hoveredCellClassName);
 | ||
|           });
 | ||
|           cell.addEventListener("mouseleave", () => {
 | ||
|             cell.removeClass(hoveredCellClassName);
 | ||
|           });
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   };
 | ||
| }
 | ||
| 
 | ||
| // src/mousedownHandler.ts
 | ||
| var import_obsidian7 = require("obsidian");
 | ||
| function isClickable(node) {
 | ||
|   if (node instanceof HTMLElement) {
 | ||
|     if (node.tagName == "A")
 | ||
|       return true;
 | ||
|   }
 | ||
|   return false;
 | ||
| }
 | ||
| function getEditableNode(node) {
 | ||
|   if (!(node instanceof HTMLElement))
 | ||
|     return null;
 | ||
|   if (node instanceof HTMLTableCellElement)
 | ||
|     return node;
 | ||
|   if (isClickable(node))
 | ||
|     return null;
 | ||
|   let parent = node.parentNode;
 | ||
|   while (parent) {
 | ||
|     if (parent instanceof HTMLTableCellElement)
 | ||
|       break;
 | ||
|     parent = parent.parentNode;
 | ||
|   }
 | ||
|   if (!parent)
 | ||
|     return null;
 | ||
|   return parent;
 | ||
| }
 | ||
| function getClickHandler(plugin) {
 | ||
|   return async (e) => {
 | ||
|     if (plugin.isInReadingView())
 | ||
|       return;
 | ||
|     const markdownView = plugin.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     const cellEl = getEditableNode(e.targetNode);
 | ||
|     if (!cellEl)
 | ||
|       return;
 | ||
|     let tableEl = cellEl.parentNode;
 | ||
|     while (tableEl) {
 | ||
|       if (tableEl instanceof HTMLTableElement)
 | ||
|         break;
 | ||
|       tableEl = tableEl.parentNode;
 | ||
|     }
 | ||
|     if (!tableEl) {
 | ||
|       console.error("Cannot get table element of cell ", cellEl);
 | ||
|       return;
 | ||
|     }
 | ||
|     if (!(editorView == null ? void 0 : editorView.contentDOM.contains(tableEl)))
 | ||
|       return;
 | ||
|     if (tableEl.classList.length > 0)
 | ||
|       return;
 | ||
|     e.stopImmediatePropagation();
 | ||
|     e.preventDefault();
 | ||
|     const { tableLine, i, j } = getCellInfo(cellEl, plugin, tableEl);
 | ||
|     if (cellEl.isContentEditable) {
 | ||
|       return;
 | ||
|     }
 | ||
|     const tablePos = editorView.posAtDOM(tableEl);
 | ||
|     const editingCell = activeDocument.querySelector("." + editingCellClassName);
 | ||
|     if (editingCell instanceof HTMLTableCellElement) {
 | ||
|       await plugin.doneEdit(editingCell);
 | ||
|     }
 | ||
|     setTimeout(() => {
 | ||
|       const newCellEl = getCellEl(tablePos, i, j, plugin);
 | ||
|       if (!(newCellEl instanceof HTMLTableCellElement)) {
 | ||
|         console.error("Cannot relocate table cell");
 | ||
|         return;
 | ||
|       }
 | ||
|       plugin.setCellEditing(newCellEl, tableLine, i, j);
 | ||
|     }, 50);
 | ||
|   };
 | ||
| }
 | ||
| function getMousedownHandler(plugin) {
 | ||
|   return async (e) => {
 | ||
|     const markdownView = plugin.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView);
 | ||
|     const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|     const tableEl = getTableOfCell(e.targetNode);
 | ||
|     if (!tableEl) {
 | ||
|       const editingCell = activeDocument.querySelector("." + editingCellClassName);
 | ||
|       if (editingCell instanceof HTMLTableCellElement) {
 | ||
|         await plugin.doneEdit(editingCell);
 | ||
|         editor == null ? void 0 : editor.focus();
 | ||
|       }
 | ||
|       return;
 | ||
|     }
 | ||
|   };
 | ||
| }
 | ||
| 
 | ||
| // src/keydownHandler.ts
 | ||
| var import_obsidian8 = require("obsidian");
 | ||
| function getKeydownHandler(plugin) {
 | ||
|   return async (e) => {
 | ||
|     const markdownView = plugin.app.workspace.getActiveViewOfType(import_obsidian8.MarkdownView);
 | ||
|     if (!markdownView)
 | ||
|       return;
 | ||
|     const editor = markdownView.editor;
 | ||
|     const editorView = editor == null ? void 0 : editor.cm;
 | ||
|     if (!editor.hasFocus()) {
 | ||
|       if (!e.repeat && e.ctrlKey && e.key == "z") {
 | ||
|         e.stopPropagation();
 | ||
|         e.preventDefault();
 | ||
|         editor.undo();
 | ||
|         editor.blur();
 | ||
|         return;
 | ||
|       } else if (!e.repeat && e.ctrlKey && e.key == "Z") {
 | ||
|         e.stopPropagation();
 | ||
|         e.preventDefault();
 | ||
|         editor.redo();
 | ||
|         editor.blur();
 | ||
|         return;
 | ||
|       }
 | ||
|     }
 | ||
|     const cellEl = activeDocument.querySelector("." + editingCellClassName);
 | ||
|     if (!(cellEl instanceof HTMLTableCellElement))
 | ||
|       return;
 | ||
|     if (!e.repeat && e.key == "Enter" && e.shiftKey) {
 | ||
|       e.stopPropagation();
 | ||
|       e.preventDefault();
 | ||
|       const prevCaretPos = getCaretPosition(cellEl);
 | ||
|       const text1 = cellEl.innerText.slice(0, prevCaretPos);
 | ||
|       const text2 = cellEl.innerText.slice(prevCaretPos + 1);
 | ||
|       cellEl.innerText = [text1, " <br> ", text2].join("");
 | ||
|       setCaretPosition(cellEl, prevCaretPos + 6);
 | ||
|       return;
 | ||
|     }
 | ||
|     if (!e.repeat && (e.key == "Enter" || e.key == "Escape")) {
 | ||
|       e.stopPropagation();
 | ||
|       e.preventDefault();
 | ||
|       await plugin.doneEdit(cellEl);
 | ||
|       return;
 | ||
|     }
 | ||
|     let tableEl = cellEl.parentNode;
 | ||
|     while (tableEl) {
 | ||
|       if (tableEl instanceof HTMLTableElement)
 | ||
|         break;
 | ||
|       tableEl = tableEl.parentNode;
 | ||
|     }
 | ||
|     if (!tableEl) {
 | ||
|       console.error("Cannot find table of cell", cellEl);
 | ||
|       return;
 | ||
|     }
 | ||
|     if (e.key == "ArrowLeft") {
 | ||
|       const caretPos = getCaretPosition(cellEl);
 | ||
|       const { tableLine, i, j } = getCellInfo(cellEl, plugin, tableEl);
 | ||
|       if (cellEl.innerText.length == 0 || caretPos == 0) {
 | ||
|         e.preventDefault();
 | ||
|         const tablePos = editorView.posAtDOM(tableEl);
 | ||
|         await plugin.doneEdit(cellEl);
 | ||
|         setTimeout(() => {
 | ||
|           const newCellEl = getCellEl(tablePos, i, j - 1, plugin);
 | ||
|           if (newCellEl instanceof HTMLTableCellElement) {
 | ||
|             plugin.setCellEditing(newCellEl, tableLine, i, j - 1);
 | ||
|           }
 | ||
|         }, 50);
 | ||
|       }
 | ||
|       e.stopPropagation();
 | ||
|       return;
 | ||
|     }
 | ||
|     if (e.key == "ArrowRight") {
 | ||
|       const caretPos = getCaretPosition(cellEl);
 | ||
|       const { tableLine, i, j } = getCellInfo(cellEl, plugin, tableEl);
 | ||
|       if (caretPos >= cellEl.innerText.length) {
 | ||
|         e.preventDefault();
 | ||
|         const tablePos = editorView.posAtDOM(tableEl);
 | ||
|         await plugin.doneEdit(cellEl);
 | ||
|         setTimeout(() => {
 | ||
|           const newCellEl = getCellEl(tablePos, i, j + 1, plugin);
 | ||
|           if (newCellEl instanceof HTMLTableCellElement) {
 | ||
|             plugin.setCellEditing(newCellEl, tableLine, i, j + 1);
 | ||
|           }
 | ||
|         }, 50);
 | ||
|       }
 | ||
|       e.stopPropagation();
 | ||
|       return;
 | ||
|     }
 | ||
|     if (e.key == "ArrowUp") {
 | ||
|       e.stopPropagation();
 | ||
|       e.preventDefault();
 | ||
|       const { tableLine, i, j } = getCellInfo(cellEl, plugin, tableEl);
 | ||
|       const tablePos = editorView.posAtDOM(tableEl);
 | ||
|       await plugin.doneEdit(cellEl);
 | ||
|       setTimeout(() => {
 | ||
|         const newCellEl = getCellEl(tablePos, i - 1, j, plugin);
 | ||
|         if (newCellEl instanceof HTMLTableCellElement) {
 | ||
|           plugin.setCellEditing(newCellEl, tableLine, i - 1, j);
 | ||
|         }
 | ||
|       }, 50);
 | ||
|       return;
 | ||
|     }
 | ||
|     if (e.key == "ArrowDown") {
 | ||
|       e.stopPropagation();
 | ||
|       e.preventDefault();
 | ||
|       const { tableLine, i, j } = getCellInfo(cellEl, plugin, tableEl);
 | ||
|       const tablePos = editorView.posAtDOM(tableEl);
 | ||
|       await plugin.doneEdit(cellEl);
 | ||
|       setTimeout(() => {
 | ||
|         const newCellEl = getCellEl(tablePos, i + 1, j, plugin);
 | ||
|         if (newCellEl instanceof HTMLTableCellElement) {
 | ||
|           plugin.setCellEditing(newCellEl, tableLine, i + 1, j);
 | ||
|         }
 | ||
|       }, 50);
 | ||
|       return;
 | ||
|     }
 | ||
|     if (!e.repeat && e.ctrlKey && e.key == "a") {
 | ||
|       e.stopPropagation();
 | ||
|       e.preventDefault();
 | ||
|       const selection = activeWindow.getSelection();
 | ||
|       const range = activeDocument.createRange();
 | ||
|       range.selectNodeContents(cellEl);
 | ||
|       selection == null ? void 0 : selection.removeAllRanges();
 | ||
|       selection == null ? void 0 : selection.addRange(range);
 | ||
|       return;
 | ||
|     }
 | ||
|     if (e.shiftKey && e.key == "Tab") {
 | ||
|       e.stopPropagation();
 | ||
|       e.preventDefault();
 | ||
|       const { tableLine, i, j } = getCellInfo(cellEl, plugin, tableEl);
 | ||
|       const rowNum = tableEl.rows.length;
 | ||
|       const colNum = tableEl.rows[0].cells.length;
 | ||
|       const tablePos = editorView.posAtDOM(tableEl);
 | ||
|       let nextI, nextJ;
 | ||
|       if (i == 0 && j == 0) {
 | ||
|         nextI = rowNum - 1;
 | ||
|         nextJ = colNum - 1;
 | ||
|       } else if (j == 0) {
 | ||
|         nextI = i - 1;
 | ||
|         nextJ = colNum - 1;
 | ||
|       } else {
 | ||
|         nextI = i;
 | ||
|         nextJ = j - 1;
 | ||
|       }
 | ||
|       await plugin.doneEdit(cellEl);
 | ||
|       setTimeout(() => {
 | ||
|         const newCellEl = getCellEl(tablePos, nextI, nextJ, plugin);
 | ||
|         if (newCellEl instanceof HTMLTableCellElement) {
 | ||
|           plugin.setCellEditing(newCellEl, tableLine, nextI, nextJ);
 | ||
|         }
 | ||
|       }, 50);
 | ||
|       return;
 | ||
|     }
 | ||
|     if (e.key == "Tab") {
 | ||
|       e.stopPropagation();
 | ||
|       e.preventDefault();
 | ||
|       const { tableLine, i, j } = getCellInfo(cellEl, plugin, tableEl);
 | ||
|       const rowNum = tableEl.rows.length;
 | ||
|       const colNum = tableEl.rows[0].cells.length;
 | ||
|       const tablePos = editorView.posAtDOM(tableEl);
 | ||
|       let nextI, nextJ;
 | ||
|       if (i == rowNum - 1 && j == colNum - 1) {
 | ||
|         nextI = 0;
 | ||
|         nextJ = 0;
 | ||
|       } else if (j == colNum - 1) {
 | ||
|         nextI = i + 1;
 | ||
|         nextJ = 0;
 | ||
|       } else {
 | ||
|         nextI = i;
 | ||
|         nextJ = j + 1;
 | ||
|       }
 | ||
|       await plugin.doneEdit(cellEl);
 | ||
|       setTimeout(() => {
 | ||
|         const newCellEl = getCellEl(tablePos, nextI, nextJ, plugin);
 | ||
|         if (newCellEl instanceof HTMLTableCellElement) {
 | ||
|           plugin.setCellEditing(newCellEl, tableLine, nextI, nextJ);
 | ||
|         }
 | ||
|       }, 50);
 | ||
|       return;
 | ||
|     }
 | ||
|   };
 | ||
| }
 | ||
| 
 | ||
| // node_modules/monkey-around/mjs/index.js
 | ||
| function around(obj, factories) {
 | ||
|   const removers = Object.keys(factories).map((key) => around1(obj, key, factories[key]));
 | ||
|   return removers.length === 1 ? removers[0] : function() {
 | ||
|     removers.forEach((r) => r());
 | ||
|   };
 | ||
| }
 | ||
| function around1(obj, method, createWrapper) {
 | ||
|   const original = obj[method], hadOwn = obj.hasOwnProperty(method);
 | ||
|   let current = createWrapper(original);
 | ||
|   if (original)
 | ||
|     Object.setPrototypeOf(current, original);
 | ||
|   Object.setPrototypeOf(wrapper, current);
 | ||
|   obj[method] = wrapper;
 | ||
|   return remove;
 | ||
|   function wrapper(...args) {
 | ||
|     if (current === original && obj[method] === wrapper)
 | ||
|       remove();
 | ||
|     return current.apply(this, args);
 | ||
|   }
 | ||
|   function remove() {
 | ||
|     if (obj[method] === wrapper) {
 | ||
|       if (hadOwn)
 | ||
|         obj[method] = original;
 | ||
|       else
 | ||
|         delete obj[method];
 | ||
|     }
 | ||
|     if (current === original)
 | ||
|       return;
 | ||
|     current = original;
 | ||
|     Object.setPrototypeOf(wrapper, original || Function);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| // src/commands.ts
 | ||
| var getCommands = (plugin) => {
 | ||
|   return {
 | ||
|     "editor:toggle-bold": () => withEditingCell((cellEl) => {
 | ||
|       const selection = activeWindow.getSelection();
 | ||
|       if (!selection)
 | ||
|         return;
 | ||
|       let selectionStart, selectionEnd;
 | ||
|       if (selection.anchorOffset < selection.focusOffset) {
 | ||
|         selectionStart = selection.anchorOffset;
 | ||
|         selectionEnd = selection.focusOffset;
 | ||
|       } else {
 | ||
|         selectionStart = selection.focusOffset;
 | ||
|         selectionEnd = selection.anchorOffset;
 | ||
|       }
 | ||
|       const prevText = cellEl.innerText.slice(0, selectionStart);
 | ||
|       const selectText = cellEl.innerText.slice(selectionStart, selectionEnd);
 | ||
|       const succText = cellEl.innerText.slice(selectionEnd);
 | ||
|       cellEl.innerText = [prevText, "**", selectText, "**", succText].join("");
 | ||
|       setCaretPosition(cellEl, selectionEnd + 4);
 | ||
|       return true;
 | ||
|     }),
 | ||
|     "editor:toggle-italics": () => withEditingCell((cellEl) => {
 | ||
|       const selection = activeWindow.getSelection();
 | ||
|       if (!selection)
 | ||
|         return;
 | ||
|       let selectionStart, selectionEnd;
 | ||
|       if (selection.anchorOffset < selection.focusOffset) {
 | ||
|         selectionStart = selection.anchorOffset;
 | ||
|         selectionEnd = selection.focusOffset;
 | ||
|       } else {
 | ||
|         selectionStart = selection.focusOffset;
 | ||
|         selectionEnd = selection.anchorOffset;
 | ||
|       }
 | ||
|       const prevText = cellEl.innerText.slice(0, selectionStart);
 | ||
|       const selectText = cellEl.innerText.slice(selectionStart, selectionEnd);
 | ||
|       const succText = cellEl.innerText.slice(selectionEnd);
 | ||
|       cellEl.innerText = [prevText, "*", selectText, "*", succText].join("");
 | ||
|       setCaretPosition(cellEl, selectionEnd + 2);
 | ||
|       return true;
 | ||
|     }),
 | ||
|     "editor:toggle-blockquote": () => withEditingCell((cellEl) => {
 | ||
|       const selection = activeWindow.getSelection();
 | ||
|       if (!selection)
 | ||
|         return;
 | ||
|       let selectionStart, selectionEnd;
 | ||
|       if (selection.anchorOffset < selection.focusOffset) {
 | ||
|         selectionStart = selection.anchorOffset;
 | ||
|         selectionEnd = selection.focusOffset;
 | ||
|       } else {
 | ||
|         selectionStart = selection.focusOffset;
 | ||
|         selectionEnd = selection.anchorOffset;
 | ||
|       }
 | ||
|       const prevText = cellEl.innerText.slice(0, selectionStart);
 | ||
|       const selectText = cellEl.innerText.slice(selectionStart, selectionEnd);
 | ||
|       const succText = cellEl.innerText.slice(selectionEnd);
 | ||
|       cellEl.innerText = ["> ", prevText, selectText, succText].join("");
 | ||
|       setCaretPosition(cellEl, selectionEnd + 2);
 | ||
|       return true;
 | ||
|     }),
 | ||
|     "editor:toggle-bullet-list": () => withEditingCell((cellEl) => {
 | ||
|       return true;
 | ||
|     }),
 | ||
|     "editor:toggle-checklist-status": () => withEditingCell((cellEl) => {
 | ||
|       return true;
 | ||
|     }),
 | ||
|     "editor:toggle-code": () => withEditingCell((cellEl) => {
 | ||
|       const selection = activeWindow.getSelection();
 | ||
|       if (!selection)
 | ||
|         return;
 | ||
|       let selectionStart, selectionEnd;
 | ||
|       if (selection.anchorOffset < selection.focusOffset) {
 | ||
|         selectionStart = selection.anchorOffset;
 | ||
|         selectionEnd = selection.focusOffset;
 | ||
|       } else {
 | ||
|         selectionStart = selection.focusOffset;
 | ||
|         selectionEnd = selection.anchorOffset;
 | ||
|       }
 | ||
|       const prevText = cellEl.innerText.slice(0, selectionStart);
 | ||
|       const selectText = cellEl.innerText.slice(selectionStart, selectionEnd);
 | ||
|       const succText = cellEl.innerText.slice(selectionEnd);
 | ||
|       cellEl.innerText = [prevText, "`", selectText, "`", succText].join("");
 | ||
|       setCaretPosition(cellEl, selectionEnd + 2);
 | ||
|       return true;
 | ||
|     }),
 | ||
|     "editor:toggle-highlight": () => withEditingCell((cellEl) => {
 | ||
|       const selection = activeWindow.getSelection();
 | ||
|       if (!selection)
 | ||
|         return;
 | ||
|       let selectionStart, selectionEnd;
 | ||
|       if (selection.anchorOffset < selection.focusOffset) {
 | ||
|         selectionStart = selection.anchorOffset;
 | ||
|         selectionEnd = selection.focusOffset;
 | ||
|       } else {
 | ||
|         selectionStart = selection.focusOffset;
 | ||
|         selectionEnd = selection.anchorOffset;
 | ||
|       }
 | ||
|       const prevText = cellEl.innerText.slice(0, selectionStart);
 | ||
|       const selectText = cellEl.innerText.slice(selectionStart, selectionEnd);
 | ||
|       const succText = cellEl.innerText.slice(selectionEnd);
 | ||
|       cellEl.innerText = [prevText, "==", selectText, "==", succText].join("");
 | ||
|       setCaretPosition(cellEl, selectionEnd + 4);
 | ||
|       return true;
 | ||
|     }),
 | ||
|     "editor:toggle-numbered-list": () => withEditingCell((cellEl) => {
 | ||
|       return null;
 | ||
|     }),
 | ||
|     "editor:toggle-strikethrough": () => withEditingCell((cellEl) => {
 | ||
|       const selection = activeWindow.getSelection();
 | ||
|       if (!selection)
 | ||
|         return;
 | ||
|       let selectionStart, selectionEnd;
 | ||
|       if (selection.anchorOffset < selection.focusOffset) {
 | ||
|         selectionStart = selection.anchorOffset;
 | ||
|         selectionEnd = selection.focusOffset;
 | ||
|       } else {
 | ||
|         selectionStart = selection.focusOffset;
 | ||
|         selectionEnd = selection.anchorOffset;
 | ||
|       }
 | ||
|       const prevText = cellEl.innerText.slice(0, selectionStart);
 | ||
|       const selectText = cellEl.innerText.slice(selectionStart, selectionEnd);
 | ||
|       const succText = cellEl.innerText.slice(selectionEnd);
 | ||
|       cellEl.innerText = [prevText, "~~", selectText, "~~", succText].join("");
 | ||
|       setCaretPosition(cellEl, selectionEnd + 4);
 | ||
|       return true;
 | ||
|     })
 | ||
|   };
 | ||
| };
 | ||
| 
 | ||
| // main.ts
 | ||
| var TableEnhancer2 = class extends import_obsidian9.Plugin {
 | ||
|   async onload() {
 | ||
|     this.tableEditor = new TableEditor(this);
 | ||
|     await this.loadSettings();
 | ||
|     this.addSettingTab(new TableEnhancer2SettingTab(this.app, this));
 | ||
|     if (this.settings.enableFloatingToolbar)
 | ||
|       this.toolBar = new ToolBar(this);
 | ||
|     const tableHoverPostProcessor = getTableHoverPostProcessor(this);
 | ||
|     this.registerMarkdownPostProcessor(tableHoverPostProcessor);
 | ||
|     this.app.workspace.onLayoutReady(() => {
 | ||
|       const markdownView = app.workspace.getActiveViewOfType(import_obsidian9.MarkdownView);
 | ||
|       const editor = markdownView == null ? void 0 : markdownView.editor;
 | ||
|       const editorView = editor == null ? void 0 : editor.cm;
 | ||
|       if (this.settings.adjustTableCellHeight)
 | ||
|         activeDocument.body.addClass("table-height-adjust");
 | ||
|       const mousedownHandler = getMousedownHandler(this);
 | ||
|       this.registerDomEvent(window, "mousedown", mousedownHandler, true);
 | ||
|       const clickHandler = getClickHandler(this);
 | ||
|       this.registerDomEvent(window, "click", clickHandler, true);
 | ||
|       const keydownHandler = getKeydownHandler(this);
 | ||
|       this.registerDomEvent(window, "keydown", keydownHandler, true);
 | ||
|       this.register(around(app.commands, {
 | ||
|         executeCommand(next) {
 | ||
|           return function(command) {
 | ||
|             const commands = getCommands(this);
 | ||
|             const callback = commands[command.id];
 | ||
|             if (callback == null ? void 0 : callback.call(this)) {
 | ||
|               return;
 | ||
|             }
 | ||
|             return next.call(this, command);
 | ||
|           };
 | ||
|         }
 | ||
|       }));
 | ||
|     });
 | ||
|     this.registerEvent(this.app.workspace.on("editor-menu", (menu, editor) => {
 | ||
|       menu.setUseNativeMenu(false);
 | ||
|       const hoveredCell = activeDocument.querySelector("." + hoveredCellClassName);
 | ||
|       if (!(hoveredCell instanceof HTMLTableCellElement)) {
 | ||
|         if (this.settings.enableTableGenerator)
 | ||
|           addTableGenerator(menu, this, editor);
 | ||
|         return;
 | ||
|       }
 | ||
|       const cellInfo = getCellInfo(hoveredCell, this);
 | ||
|       if (this.settings.enableButtonPanel)
 | ||
|         addButtons(menu, this, cellInfo);
 | ||
|     }));
 | ||
|   }
 | ||
|   setCellEditing(cellEl, tableLine, i, j) {
 | ||
|     const table = this.tableEditor.getTable(tableLine);
 | ||
|     if (!table) {
 | ||
|       console.error("Cannot get table of cell ", cellEl);
 | ||
|       return;
 | ||
|     }
 | ||
|     const text = getCellText(table, i, j);
 | ||
|     if (text == null)
 | ||
|       return;
 | ||
|     cellEl.addClass(editingCellClassName);
 | ||
|     cellEl.focus();
 | ||
|     cellEl.contentEditable = "true";
 | ||
|     if (text == "") {
 | ||
|       cellEl.innerText = " ";
 | ||
|       setCaretPosition(cellEl, 0);
 | ||
|     } else {
 | ||
|       cellEl.innerText = text;
 | ||
|       setCaretPosition(cellEl, text.length);
 | ||
|     }
 | ||
|   }
 | ||
|   async doneEdit(cellEl) {
 | ||
|     if (!cellEl) {
 | ||
|       const el = activeDocument.querySelector("." + editingCellClassName);
 | ||
|       if (el instanceof HTMLTableCellElement)
 | ||
|         cellEl = el;
 | ||
|       else
 | ||
|         return;
 | ||
|     }
 | ||
|     cellEl.setAttr("contenteditable", false);
 | ||
|     cellEl.removeClass(editingCellClassName);
 | ||
|     const { tableLine, i, j } = getCellInfo(cellEl, this);
 | ||
|     const table = this.tableEditor.getTable(tableLine);
 | ||
|     if (!table) {
 | ||
|       console.error("Cannot get table when trying to done edit");
 | ||
|       return;
 | ||
|     }
 | ||
|     await this.tableEditor.updateCell(table, i, j, cellEl.innerText);
 | ||
|   }
 | ||
|   isInReadingView() {
 | ||
|     const markdownView = this.app.workspace.getActiveViewOfType(import_obsidian9.MarkdownView);
 | ||
|     return markdownView instanceof import_obsidian9.MarkdownView && markdownView.getMode() == "preview";
 | ||
|   }
 | ||
|   async loadSettings() {
 | ||
|     this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
 | ||
|   }
 | ||
|   async saveSettings() {
 | ||
|     await this.saveData(this.settings);
 | ||
|   }
 | ||
|   onunload() {
 | ||
|   }
 | ||
| };
 |