(
tag: 'th' | 'td',
row: number,
col: number,
text: string
)
| 381 | } |
| 382 | |
| 383 | private buildCell( |
| 384 | tag: 'th' | 'td', |
| 385 | row: number, |
| 386 | col: number, |
| 387 | text: string |
| 388 | ): HTMLTableCellElement { |
| 389 | const cell = document.createElement(tag) |
| 390 | const align = this.model.aligns[col] ?? 'none' |
| 391 | if (align !== 'none') cell.setAttribute('align', align) |
| 392 | |
| 393 | const editable = document.createElement('div') |
| 394 | editable.className = 'cm-table-cell' |
| 395 | editable.dataset.row = String(row) |
| 396 | editable.dataset.col = String(col) |
| 397 | editable.dataset.raw = text |
| 398 | // Vim: cells are non-editable in NORMAL mode, so there's no native text |
| 399 | // caret (a block cursor is drawn in CSS); i/a turns editing on. tabindex |
| 400 | // keeps the cell focusable for navigation while non-editable. Non-Vim: |
| 401 | // always editable (click-to-edit), unchanged. |
| 402 | editable.setAttribute('tabindex', '-1') |
| 403 | editable.setAttribute('contenteditable', vimEnabled() ? 'false' : 'true') |
| 404 | // Idle: show rendered inline markdown (code/bold/links). Editing: show the |
| 405 | // raw source. `data-raw` stays authoritative for commits either way. |
| 406 | editable.innerHTML = renderInlineCell(text) |
| 407 | editable.dataset.rendered = 'true' |
| 408 | |
| 409 | editable.addEventListener('focus', () => { |
| 410 | if (vimEnabled()) { |
| 411 | // Vim: land in NORMAL mode at the pending offset (carried across cells |
| 412 | // by h/l), or 0. The cell becomes a block cursor over its source. |
| 413 | this.cellMode = 'normal' |
| 414 | this.pendingOp = null |
| 415 | this.pendingScope = null |
| 416 | this.visualMode = false |
| 417 | this.visualScope = null |
| 418 | const len = (editable.dataset.raw ?? '').length |
| 419 | this.cursorOffset = |
| 420 | this.pendingOffset === 'end' |
| 421 | ? Math.max(0, len - 1) |
| 422 | : Math.max(0, this.pendingOffset ?? 0) |
| 423 | this.pendingOffset = null |
| 424 | this.enterNormalCell(editable) |
| 425 | return |
| 426 | } |
| 427 | if (editable.dataset.rendered === 'true') { |
| 428 | editable.textContent = editable.dataset.raw ?? '' |
| 429 | editable.dataset.rendered = 'false' |
| 430 | placeCaretEnd(editable) |
| 431 | } |
| 432 | }) |
| 433 | editable.addEventListener('input', () => { |
| 434 | this.dirty = true |
| 435 | editable.dataset.raw = editable.textContent ?? '' |
| 436 | }) |
| 437 | editable.addEventListener('blur', () => { |
| 438 | this.clearCellCursor(editable) |
| 439 | editable.classList.remove('is-vim-normal') |
| 440 | // Leaving the cell: pull the (possibly edited) source back out of the DOM |
no test coverage detected