mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #14630 from overleaf/mj-table-copy-paste
[visual] Fix copying and pasting with multicolumn GitOrigin-RevId: 4710cedb40493ed018daf122e68aecfb91e1efc4
This commit is contained in:
parent
a2e231185c
commit
5d33e5a658
2 changed files with 56 additions and 25 deletions
|
@ -262,24 +262,26 @@ export const Table: FC = () => {
|
|||
const changes: ChangeSpec[] = []
|
||||
const data = event.clipboardData?.getData('text/plain')
|
||||
if (data) {
|
||||
const rows = data.split('\n')
|
||||
const { minX, minY } = selection.normalized()
|
||||
for (let row = 0; row < rows.length; row++) {
|
||||
if (tableData.rows.length <= minY + row) {
|
||||
// TODO: Add rows
|
||||
continue
|
||||
const cells = data.split('\n').map(row => row.split('\t'))
|
||||
const { minY, minX } = selection.normalized()
|
||||
for (let row = 0; row < cells.length; ++row) {
|
||||
const rowIndex = minY + row
|
||||
if (rowIndex >= tableData.rows.length) {
|
||||
// TODO: add more rows
|
||||
break
|
||||
}
|
||||
const cells = rows[row].split('\t')
|
||||
for (let cell = 0; cell < cells.length; cell++) {
|
||||
if (tableData.columns.length <= minX + cell) {
|
||||
// TODO: Add columns
|
||||
continue
|
||||
const cellStart = tableData.getCellIndex(rowIndex, minX)
|
||||
for (let column = 0; column < cells[row].length; ++column) {
|
||||
const cellIndex = cellStart + column
|
||||
if (cellIndex >= tableData.rows[rowIndex].cells.length) {
|
||||
// TODO: add more columns
|
||||
break
|
||||
}
|
||||
const cellData = tableData.getCell(minY + row, minX + cell)
|
||||
const cell = tableData.rows[rowIndex].cells[cellIndex]
|
||||
changes.push({
|
||||
from: cellData.from,
|
||||
to: cellData.to,
|
||||
insert: cells[cell],
|
||||
from: cell.from,
|
||||
to: cell.to,
|
||||
insert: cells[row][column],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -293,16 +295,16 @@ export const Table: FC = () => {
|
|||
return false
|
||||
}
|
||||
event.preventDefault()
|
||||
const { minX, minY, maxX, maxY } = selection.normalized()
|
||||
const content = []
|
||||
for (let row = minY; row <= maxY; row++) {
|
||||
const rowContent = []
|
||||
for (let cell = minX; cell <= maxX; cell++) {
|
||||
rowContent.push(tableData.getCell(row, cell).content)
|
||||
}
|
||||
content.push(rowContent.join('\t'))
|
||||
}
|
||||
navigator.clipboard.writeText(content.join('\n'))
|
||||
const { minY, maxY } = selection.normalized()
|
||||
const cells: string[][] = Array.from(
|
||||
{ length: maxY - minY + 1 },
|
||||
() => []
|
||||
)
|
||||
tableData.iterateSelection(selection, (cell, row) => {
|
||||
cells[row - minY].push(cell.content)
|
||||
})
|
||||
const content = cells.map(row => row.join('\t')).join('\n')
|
||||
navigator.clipboard.writeText(content)
|
||||
}
|
||||
window.addEventListener('paste', onPaste)
|
||||
window.addEventListener('copy', onCopy)
|
||||
|
|
|
@ -5,6 +5,7 @@ import { Toolbar } from './toolbar/toolbar'
|
|||
import { Table } from './table'
|
||||
import {
|
||||
SelectionContextProvider,
|
||||
TableSelection,
|
||||
useSelectionContext,
|
||||
} from './contexts/selection-context'
|
||||
import {
|
||||
|
@ -78,6 +79,34 @@ export class TableData {
|
|||
return this.rows[row].cells.length - 1
|
||||
}
|
||||
|
||||
iterateCells(
|
||||
minRow: number,
|
||||
maxRow: number,
|
||||
minColumn: number,
|
||||
maxColumn: number,
|
||||
callback: (cell: CellData, row: number, column: number) => void
|
||||
) {
|
||||
for (let row = minRow; row <= maxRow; ++row) {
|
||||
let currentCellOffset = this.getCellBoundaries(row, minColumn).from
|
||||
const minX = this.getCellIndex(row, minColumn)
|
||||
const maxX = this.getCellIndex(row, maxColumn)
|
||||
for (let column = minX; column <= maxX; ++column) {
|
||||
const currentCell = this.rows[row].cells[column]
|
||||
const skip = currentCell.multiColumn?.columnSpan ?? 1
|
||||
callback(currentCell, row, currentCellOffset)
|
||||
currentCellOffset += skip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iterateSelection(
|
||||
selection: TableSelection,
|
||||
callback: (cell: CellData, row: number, column: number) => void
|
||||
) {
|
||||
const { minX, maxX, minY, maxY } = selection.normalized()
|
||||
this.iterateCells(minY, maxY, minX, maxX, callback)
|
||||
}
|
||||
|
||||
getCell(row: number, column: number): CellData {
|
||||
return this.rows[row].cells[this.getCellIndex(row, column)]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue