fix: table paste will be nested
This commit is contained in:
parent
9453ea48b7
commit
a53e5db82e
|
@ -119,17 +119,20 @@ class CardToolbar implements CardToolbarInterface {
|
|||
content:
|
||||
item.content ||
|
||||
`<span class="data-icon data-icon-copy"></span>`,
|
||||
title:
|
||||
item.title || language.get('copy', 'title').toString(),
|
||||
onClick: () => {
|
||||
title: item.title || language.get<string>('copy', 'title'),
|
||||
onClick: (e, node) => {
|
||||
if (item.onClick) {
|
||||
item.onClick(e, node);
|
||||
return;
|
||||
}
|
||||
const result = clipboard.copy(this.card.root[0], true);
|
||||
if (result)
|
||||
editor.messageSuccess(
|
||||
language.get('copy', 'success').toString(),
|
||||
language.get<string>('copy', 'success'),
|
||||
);
|
||||
else
|
||||
editor.messageError(
|
||||
language.get('copy', 'error').toString(),
|
||||
language.get<string>('copy', 'error'),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
@ -142,7 +145,11 @@ class CardToolbar implements CardToolbarInterface {
|
|||
title:
|
||||
item.title ||
|
||||
language.get('delete', 'title').toString(),
|
||||
onClick: () => {
|
||||
onClick: (e, node) => {
|
||||
if (item.onClick) {
|
||||
item.onClick(e, node);
|
||||
return;
|
||||
}
|
||||
card.remove(this.card.root);
|
||||
},
|
||||
};
|
||||
|
@ -155,7 +162,11 @@ class CardToolbar implements CardToolbarInterface {
|
|||
title:
|
||||
item.title ||
|
||||
language.get('maximize', 'title').toString(),
|
||||
onClick: () => {
|
||||
onClick: (e, node) => {
|
||||
if (item.onClick) {
|
||||
item.onClick(e, node);
|
||||
return;
|
||||
}
|
||||
this.card.maximize();
|
||||
},
|
||||
};
|
||||
|
|
|
@ -75,6 +75,7 @@ export type CardToolbarItemOptions =
|
|||
disabled?: boolean;
|
||||
content?: string;
|
||||
title?: string;
|
||||
onClick?: (event: MouseEvent, node: NodeInterface) => void;
|
||||
}
|
||||
| {
|
||||
type: 'more';
|
||||
|
|
|
@ -457,9 +457,9 @@ class TableCommand extends EventEmitter2 implements TableCommandInterface {
|
|||
this.editor.card.remove(this.table.id);
|
||||
}
|
||||
|
||||
copy() {
|
||||
copy(all: boolean = false) {
|
||||
const { selection, helper } = this.table;
|
||||
const areaHtml = selection.getSelectionHtml();
|
||||
const areaHtml = selection.getSelectionHtml(all);
|
||||
if (!areaHtml) return;
|
||||
this.editor.clipboard.copy($(areaHtml)[0]);
|
||||
helper.copyHTML(areaHtml);
|
||||
|
|
|
@ -32,7 +32,7 @@ class Helper implements HelperInterface {
|
|||
isEmptyModelCol(
|
||||
model: TableModelCol | TableModelEmptyCol,
|
||||
): model is TableModelEmptyCol {
|
||||
return (model as TableModelEmptyCol).isEmpty;
|
||||
return model && (model as TableModelEmptyCol).isEmpty;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -413,6 +413,12 @@ class TableComponent<V extends TableValue = TableValue>
|
|||
},
|
||||
{
|
||||
type: 'copy',
|
||||
onClick: () => {
|
||||
this.command.copy(true);
|
||||
this.editor.messageSuccess(
|
||||
this.editor.language.get<string>('copy', 'success'),
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'delete',
|
||||
|
|
|
@ -369,6 +369,7 @@ class TableSelection extends EventEmitter2 implements TableSelectionInterface {
|
|||
for (let row = fBeginRow; row > -1 && row <= fEndRow; row++) {
|
||||
for (let col = fBeginCol; col > -1 && col <= fEndCol; col++) {
|
||||
const cell = this.tableModel.table[row][col];
|
||||
if (!cell) continue;
|
||||
if (this.table.helper.isEmptyModelCol(cell)) {
|
||||
if (beginRow > cell.parent.row) beginRow = cell.parent.row;
|
||||
if (beginCol >= cell.parent.col) beginCol = cell.parent.col;
|
||||
|
@ -409,7 +410,7 @@ class TableSelection extends EventEmitter2 implements TableSelectionInterface {
|
|||
for (let r = beginRow; r <= endRow; r++) {
|
||||
for (let c = beginCol; c <= endCol; c++) {
|
||||
const col = this.tableModel.table[r][c];
|
||||
if (!this.table.helper.isEmptyModelCol(col)) {
|
||||
if (col && !this.table.helper.isEmptyModelCol(col)) {
|
||||
if (!isSame && col.element) {
|
||||
$(col.element).attributes(
|
||||
'table-cell-selection',
|
||||
|
@ -424,6 +425,7 @@ class TableSelection extends EventEmitter2 implements TableSelectionInterface {
|
|||
if (isSame && begin.row > -1 && begin.col > -1) {
|
||||
const cell = this.tableModel.table[begin.row][begin.col];
|
||||
if (
|
||||
cell &&
|
||||
!this.table.helper.isEmptyModelCol(cell) &&
|
||||
cell.element &&
|
||||
!this.prevMouseDownTd?.equal(cell.element)
|
||||
|
@ -871,11 +873,18 @@ class TableSelection extends EventEmitter2 implements TableSelectionInterface {
|
|||
} else this.select(begin, { ...end, row: triggerRow });
|
||||
}
|
||||
|
||||
getSelectionHtml() {
|
||||
getSelectionHtml(all: boolean = false) {
|
||||
const { tableModel } = this;
|
||||
const { helper } = this.table;
|
||||
if (!tableModel || !this.tableRoot) return null;
|
||||
const { begin, end } = this.getSelectArea();
|
||||
let begin = { row: 0, col: 0 };
|
||||
let end = { row: tableModel.rows - 1, col: tableModel.cols - 1 };
|
||||
if (!all) {
|
||||
const area = this.getSelectArea();
|
||||
begin = area.begin;
|
||||
end = area.end;
|
||||
}
|
||||
|
||||
const colsEl = this.tableRoot.find('col');
|
||||
let cols = [];
|
||||
let tableWidth = 0;
|
||||
|
|
|
@ -60,7 +60,10 @@ class Table<T extends TableOptions = TableOptions> extends Plugin<T> {
|
|||
if (!isEngine(this.editor)) return true;
|
||||
const { change, card } = this.editor;
|
||||
const range = change.range.get();
|
||||
const component = card.find(range.commonAncestorNode, true);
|
||||
const component = card.find<TableValue, TableComponent>(
|
||||
range.commonAncestorNode,
|
||||
true,
|
||||
);
|
||||
if (
|
||||
component &&
|
||||
component.getSelectionNodes &&
|
||||
|
@ -69,8 +72,10 @@ class Table<T extends TableOptions = TableOptions> extends Plugin<T> {
|
|||
const nodes = component.getSelectionNodes();
|
||||
if (nodes.length > 1) {
|
||||
event.preventDefault();
|
||||
const tableComponent = component as TableInterface;
|
||||
tableComponent.command.copy();
|
||||
component.command.copy();
|
||||
this.editor.messageSuccess(
|
||||
this.editor.language.get<string>('copy', 'success'),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +86,10 @@ class Table<T extends TableOptions = TableOptions> extends Plugin<T> {
|
|||
if (!isEngine(this.editor)) return true;
|
||||
const { change, card } = this.editor;
|
||||
const range = change.range.get();
|
||||
const component = card.find(range.commonAncestorNode, true);
|
||||
const component = card.find<TableValue, TableComponent>(
|
||||
range.commonAncestorNode,
|
||||
true,
|
||||
);
|
||||
if (
|
||||
component &&
|
||||
component.getSelectionNodes &&
|
||||
|
@ -90,8 +98,7 @@ class Table<T extends TableOptions = TableOptions> extends Plugin<T> {
|
|||
const nodes = component.getSelectionNodes();
|
||||
if (nodes.length > 1) {
|
||||
event.preventDefault();
|
||||
const tableComponent = component as TableInterface;
|
||||
tableComponent.command.cut();
|
||||
component.command.cut();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -102,19 +109,19 @@ class Table<T extends TableOptions = TableOptions> extends Plugin<T> {
|
|||
if (!isEngine(this.editor)) return true;
|
||||
const { change, card } = this.editor;
|
||||
const range = change.range.get();
|
||||
const component = card.find(range.commonAncestorNode, true);
|
||||
const component = card.find<TableValue, TableComponent>(
|
||||
range.commonAncestorNode,
|
||||
true,
|
||||
);
|
||||
if (
|
||||
component &&
|
||||
component.getSelectionNodes &&
|
||||
component.name === TableComponent.cardName
|
||||
component.name === TableComponent.cardName &&
|
||||
component.command.hasCopyData()
|
||||
) {
|
||||
const nodes = component.getSelectionNodes();
|
||||
if (nodes.length > 0) {
|
||||
event.preventDefault();
|
||||
const tableComponent = component as TableInterface;
|
||||
tableComponent.command.mockPaste();
|
||||
return false;
|
||||
}
|
||||
event.preventDefault();
|
||||
component.command.mockPaste();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -284,22 +291,53 @@ class Table<T extends TableOptions = TableOptions> extends Plugin<T> {
|
|||
if (width.endsWith('pt')) node.css(type, this.convertToPX(width));
|
||||
};
|
||||
const tables = root.find('table');
|
||||
if (tables.length === 0) return;
|
||||
const helper = new Helper(this.editor);
|
||||
// 判断当前是在可编辑卡片内,在可编辑卡片内不嵌套表格
|
||||
const { change } = this.editor;
|
||||
const range = change.range.get();
|
||||
|
||||
const clearTable = (table: NodeInterface) => {
|
||||
const thead = table.find('thead');
|
||||
const headTds = thead.find('th,td').toArray();
|
||||
headTds.forEach((td) => {
|
||||
table.before(td.children());
|
||||
});
|
||||
const trs = table.find('tr').toArray();
|
||||
trs.forEach((tr) => {
|
||||
const tds = tr.find('td').toArray();
|
||||
tds.forEach((td) => {
|
||||
if (!this.editor.node.isEmpty(td))
|
||||
table.before(td.children());
|
||||
});
|
||||
});
|
||||
const tfoot = table.find('tfoot');
|
||||
const footTds = tfoot.find('th,td').toArray();
|
||||
footTds.forEach((td) => {
|
||||
table.before(td.children());
|
||||
});
|
||||
table.remove();
|
||||
};
|
||||
const isClear = range.startNode.closest(EDITABLE_SELECTOR).length > 0;
|
||||
tables.each((_, index) => {
|
||||
let node = tables.eq(index);
|
||||
if (!node) return;
|
||||
if (isClear || node.parent()?.name === 'td') {
|
||||
clearTable(node);
|
||||
return;
|
||||
}
|
||||
node = helper.normalizeTable(node);
|
||||
clearWH(node);
|
||||
clearWH(node, 'height');
|
||||
const tbody = node.find('tbody');
|
||||
|
||||
// 表头放在tbody最前面
|
||||
const thead = node.find('thead');
|
||||
if (thead && thead.length > 0)
|
||||
node.find('tbody').prepend(thead.children());
|
||||
if (thead && thead.length > 0) tbody.prepend(thead.children());
|
||||
thead.remove();
|
||||
// 表头放在tbody最前面
|
||||
const tfoot = node.find('thead');
|
||||
if (tfoot && tfoot.length > 0)
|
||||
node.find('tbody').append(tfoot.children());
|
||||
const tfoot = node.find('tfoot');
|
||||
if (tfoot && tfoot.length > 0) tbody.append(tfoot.children());
|
||||
tfoot.remove();
|
||||
const ths = node.find('th');
|
||||
ths.each((_, index) => {
|
||||
|
|
|
@ -293,7 +293,7 @@ export interface TableCommandInterface extends EventEmitter2 {
|
|||
|
||||
removeTable(): void;
|
||||
|
||||
copy(): void;
|
||||
copy(all?: boolean): void;
|
||||
|
||||
mockCopy(): void;
|
||||
|
||||
|
@ -373,7 +373,7 @@ export interface TableSelectionInterface extends EventEmitter2 {
|
|||
|
||||
clearSelect(): void;
|
||||
|
||||
getSelectionHtml(): string | null;
|
||||
getSelectionHtml(all?: boolean): string | null;
|
||||
|
||||
hasMergeCell(): boolean;
|
||||
|
||||
|
|
Loading…
Reference in New Issue