mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Copy column type and options when pasting into an empty column
Summary: Adds a `data-grist-col-ref` attribute to the copied HTML, then uses that when pasting to look up the source column and retrieve info about it. Copies the info into the target column if: - The document is the same (the docId hash matches) - The source column still exists and has the same type as when copied - The source type isn't Text, because in that case it's nice if type guessing still happens - The target column is empty, meaning it has type Any (we check earlier that it's not a formula column) The info copied is the type, widgetOptions, and reference column settings (visible and display columns) but not conditional formatting. The changes are mostly in a function `parsePasteForView` which is based on `BaseView._parsePasteForView` but ported to TypeScript in a new file `BaseView2.ts`. Added a useraction `MaybeCopyDisplayFormula` exposing an existing Python function `maybe_copy_display_formula` because the target column needs a slightly different display formula. Test Plan: Added a new nbrowser test file and fixture doc. Reviewers: cyprien Reviewed By: cyprien Subscribers: jarek, dsagal Differential Revision: https://phab.getgrist.com/D3344
This commit is contained in:
@@ -102,9 +102,10 @@ export function makePasteHtml(tableData: TableData, selection: CopySelection, in
|
||||
|
||||
const elem = dom('table',
|
||||
{border: '1', cellspacing: '0', style: 'white-space: pre', 'data-grist-doc-id-hash': getDocIdHash()},
|
||||
dom('colgroup', selection.colIds.map(colId =>
|
||||
dom('colgroup', selection.colIds.map((colId, idx) =>
|
||||
dom('col', {
|
||||
style: _styleAttr(colStyle[colId]),
|
||||
'data-grist-col-ref': String(selection.colRefs[idx]),
|
||||
'data-grist-col-type': tableData.getColType(colId)
|
||||
})
|
||||
)),
|
||||
@@ -134,6 +135,7 @@ export interface RichPasteObject {
|
||||
displayValue: string;
|
||||
docIdHash?: string|null;
|
||||
colType?: string|null; // Column type of the source column.
|
||||
colRef?: number|null;
|
||||
rawValue?: unknown; // Optional rawValue that should be used if colType matches destination.
|
||||
}
|
||||
|
||||
@@ -145,20 +147,17 @@ export interface RichPasteObject {
|
||||
export function parsePasteHtml(data: string): RichPasteObject[][] {
|
||||
const parser = new G.DOMParser() as DOMParser;
|
||||
const doc = parser.parseFromString(data, 'text/html');
|
||||
const table = doc.querySelector('table');
|
||||
const docIdHash = table?.getAttribute('data-grist-doc-id-hash');
|
||||
const table = doc.querySelector('table')!;
|
||||
const docIdHash = table.getAttribute('data-grist-doc-id-hash');
|
||||
|
||||
const colTypes = Array.from(table!.querySelectorAll('col'), col =>
|
||||
col.getAttribute('data-grist-col-type'));
|
||||
|
||||
const result = Array.from(table!.querySelectorAll('tr'), (row, rowIdx) =>
|
||||
const cols = [...table.querySelectorAll('col')];
|
||||
const rows = [...table.querySelectorAll('tr')];
|
||||
const result = rows.map(row =>
|
||||
Array.from(row.querySelectorAll('td, th'), (cell, colIdx) => {
|
||||
const o: RichPasteObject = {displayValue: cell.textContent!, docIdHash};
|
||||
|
||||
// If there's a column type, add it to the object
|
||||
if (colTypes[colIdx]) {
|
||||
o.colType = colTypes[colIdx];
|
||||
}
|
||||
const col = cols[colIdx];
|
||||
const colType = col?.getAttribute('data-grist-col-type');
|
||||
const colRef = col && Number(col.getAttribute('data-grist-col-ref'));
|
||||
const o: RichPasteObject = {displayValue: cell.textContent!, docIdHash, colType, colRef};
|
||||
|
||||
if (cell.hasAttribute('data-grist-raw-value')) {
|
||||
o.rawValue = safeJsonParse(cell.getAttribute('data-grist-raw-value')!,
|
||||
|
||||
Reference in New Issue
Block a user