Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/__tests__/unit/table-redo-undo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,46 @@ afterEach(() => {
});

describe('table undo', () => {
it('undo remove column with merged cell and image should keep embed/content/format', async () => {
const quill = createQuillWithTableModule(`<p><br></p>`);
const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
quill.setContents([
{ insert: '\n' },
{ insert: { 'table-up-col': { tableId: '1', colId: '1', full: true, width: 33.3333 } } },
{ insert: { 'table-up-col': { tableId: '1', colId: '2', full: true, width: 33.3333 } } },
{ insert: { 'table-up-col': { tableId: '1', colId: '3', full: true, width: 33.3333 } } },
{ insert: { image: 'https://live.mdnplay.dev/en-US/docs/Web/HTML/Element/img/favicon144.png' } },
{ attributes: { 'table-up-cell-inner': { tableId: '1', rowId: '1', colId: '1', rowspan: 1, colspan: 1 } }, insert: '\n' },
{ insert: 'text' },
{ attributes: { 'table-up-cell-inner': { tableId: '1', rowId: '1', colId: '2', rowspan: 1, colspan: 1 } }, insert: '\n' },
{ insert: 'r1c3' },
{ attributes: { 'table-up-cell-inner': { tableId: '1', rowId: '1', colId: '3', rowspan: 1, colspan: 1 } }, insert: '\n' },
{ insert: 'merged' },
{ attributes: { 'table-up-cell-inner': { tableId: '1', rowId: '2', colId: '1', rowspan: 1, colspan: 2 } }, insert: '\n' },
{ insert: 'r2c3' },
{ attributes: { 'table-up-cell-inner': { tableId: '1', rowId: '2', colId: '3', rowspan: 1, colspan: 1 } }, insert: '\n' },
{ insert: 'r3c1' },
{ attributes: { 'table-up-cell-inner': { tableId: '1', rowId: '3', colId: '1', rowspan: 1, colspan: 1 } }, insert: '\n' },
{ insert: 'r3c2' },
{ attributes: { 'table-up-cell-inner': { tableId: '1', rowId: '3', colId: '2', rowspan: 1, colspan: 1 } }, insert: '\n' },
{ insert: 'r3c3' },
{ attributes: { 'table-up-cell-inner': { tableId: '1', rowId: '3', colId: '3', rowspan: 1, colspan: 1 } }, insert: '\n' },
{ insert: '\n' },
]);
await vi.runAllTimersAsync();
const initDelta = quill.getContents();

const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
tableModule.removeCol(tds.filter(td => td.colId === '1'));
await vi.runAllTimersAsync();
quill.history.undo();
await vi.runAllTimersAsync();

expectDelta(quill.getContents(), initDelta);
expect(quill.root.querySelector('tbody img')).not.toBeNull();
expect(quill.root.querySelector('colgroup img')).toBeNull();
});

it('merge all cell undo', async () => {
const quill = await createTable(3, 3);
const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
Expand Down
8 changes: 8 additions & 0 deletions src/formats/table-col-format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,14 @@ export class TableColFormat extends BlockEmbed {
console.warn('TableCol not in TableColgroup');
}
}
else if (value !== this.statics.blotName) {
// Redirect non-tableCol embeds/blots (e.g. image from undo) outside table wrapper.
// Otherwise they are inserted into colgroup and then removed by allowedChildren check.
const tableWrapperBlot = findParentBlot(this, blotName.tableWrapper);
const parentBlot = tableWrapperBlot.split(this.offset(tableWrapperBlot)) as TypeParchment.Parent;
const blot = this.scroll.create(value, def);
parentBlot.parent.insertBefore(blot, parentBlot);
}
else {
super.insertAt(index, value, def);
}
Expand Down
Loading