import { findInSelection } from "@html_editor/utils/selection";
import { describe, expect, test } from "@odoo/hoot";
import { press } from "@odoo/hoot-dom";
import { setupEditor, testEditor } from "../_helpers/editor";
import { unformat } from "../_helpers/format";
import { undo } from "../_helpers/user_actions";
import { getContent } from "../_helpers/selection";
function addRow(position) {
return (editor) => {
const selection = editor.shared.selection.getEditableSelection();
editor.shared.table.addRow(position, findInSelection(selection, "tr"));
};
}
function addColumn(position) {
return (editor) => {
const selection = editor.shared.selection.getEditableSelection();
editor.shared.table.addColumn(position, findInSelection(selection, "td"));
};
}
function removeRow(row) {
return (editor) => {
if (!row) {
const selection = editor.shared.selection.getEditableSelection();
row = findInSelection(selection, "tr");
}
editor.shared.table.removeRow(row);
};
}
function removeColumn(cell) {
return (editor) => {
if (!cell) {
const selection = editor.shared.selection.getEditableSelection();
cell = findInSelection(selection, "td");
}
editor.shared.table.removeColumn(cell);
};
}
describe("row", () => {
describe("above", () => {
test("should add a row above the top row", async () => {
await testEditor({
contentBefore:
'
' +
'ab | ' +
'cd | ' +
'ef[] | ' +
"
",
stepFunction: addRow("before"),
contentAfter:
'' +
'
| ' +
'
| ' +
'
| ' +
"
" +
'' +
"ab | " +
"cd | " +
"ef[] | " +
"
",
});
});
test("should add a row above the middle row", async () => {
await testEditor({
contentBefore:
'' +
'ab | ' +
'cd | ' +
'ef | ' +
"
" +
'' +
"ab | " +
"cd | " +
"ef[] | " +
"
",
stepFunction: addRow("before"),
contentAfter:
'' +
'ab | ' +
'cd | ' +
'ef | ' +
"
" +
'' +
"
| " +
"
| " +
"
| " +
"
" +
'' +
"ab | " +
"cd | " +
"ef[] | " +
"
",
});
});
});
describe("below", () => {
test("should add a row below the bottom row", async () => {
await testEditor({
contentBefore:
'' +
'ab | ' +
'cd | ' +
'ef[] | ' +
"
",
stepFunction: addRow("after"),
contentAfter:
'' +
'ab | ' +
'cd | ' +
'ef[] | ' +
"
" +
'' +
"
| " +
"
| " +
"
| " +
"
",
});
});
test("should add a row below the middle row", async () => {
await testEditor({
contentBefore:
'' +
'ab | ' +
'cd | ' +
'ef[] | ' +
"
" +
'' +
"ab | " +
"cd | " +
"ef | " +
"
",
stepFunction: addRow("after"),
contentAfter:
'' +
'ab | ' +
'cd | ' +
'ef[] | ' +
"
" +
'' +
"
| " +
"
| " +
"
| " +
"
" +
'' +
"ab | " +
"cd | " +
"ef | " +
"
",
});
});
});
describe("removal", () => {
test("should remove a row based on selection", async () => {
await testEditor({
contentBefore: unformat(`
`),
stepFunction: removeRow(),
// @todo @phoenix: consider changing the behavior and placing the cursor
// inside the td (normalize deep)
contentAfter: unformat(`
`),
});
});
test("should remove the row passed as argument", async () => {
await testEditor({
contentBefore: unformat(`
`),
stepFunction: (editor) => {
// Select the second row
const row = editor.editable.querySelectorAll("tr")[1];
removeRow(row)(editor);
},
contentAfter: unformat(`
`),
});
});
test("should remove the table upon sole row removal", async () => {
await testEditor({
contentBefore: unformat(`
`),
stepFunction: removeRow(),
contentAfter: "[]
",
});
});
});
});
describe("column", () => {
describe("left", () => {
test("should add a column left of the leftmost column", async () => {
await testEditor({
contentBefore:
'' +
'ab[] | ' +
'cd | ' +
'ef | ' +
"
" +
'' +
"ab | " +
"cd | " +
"ef | " +
"
",
stepFunction: addColumn("before"),
contentAfter:
'' +
'
| ' +
'ab[] | ' +
'cd | ' +
'ef | ' +
"
" +
'' +
"
| " +
"ab | " +
"cd | " +
"ef | " +
"
",
});
});
test("should add a column left of the middle column", async () => {
await testEditor({
contentBefore:
'' +
'ab | ' +
'cd | ' +
'ef | ' +
"
" +
'' +
"ab | " +
"cd[] | " +
"ef | " +
"
" +
'' +
"ab | " +
"cd | " +
"ef | " +
"
",
stepFunction: addColumn("before"),
contentAfter:
'' +
'ab | ' +
'
| ' +
'cd | ' +
'ef | ' +
"
" +
'' +
"ab | " +
"
| " +
"cd[] | " +
"ef | " +
"
" +
'' +
"ab | " +
"
| " +
"cd | " +
"ef | " +
"
",
});
});
});
describe("right", () => {
test("should add a column right of the rightmost column", async () => {
await testEditor({
contentBefore:
'' +
'ab | ' +
'cd | ' +
'ef[] | ' +
"
" +
'' +
"ab | " +
"cd | " +
"ef | " +
"
",
stepFunction: addColumn("after"),
contentAfter:
'' +
'ab | ' +
'cd | ' +
'ef[] | ' +
// size was slightly adjusted to
// preserve table width in view on
// fractional division results
'
| ' +
"
" +
'' +
"ab | " +
"cd | " +
"ef | " +
"
| " +
"
",
});
});
test("should add a column right of the middle column", async () => {
await testEditor({
contentBefore:
'' +
'ab | ' +
'cd | ' +
'ef | ' +
"
" +
'' +
"ab | " +
"cd[] | " +
"ef | " +
"
" +
'' +
"ab | " +
"cd | " +
"ef | " +
"
",
stepFunction: addColumn("after"),
contentAfter:
'' +
'ab | ' +
'cd | ' +
'
| ' +
'ef | ' +
"
" +
'' +
"ab | " +
"cd[] | " +
"
| " +
"ef | " +
"
" +
'' +
"ab | " +
"cd | " +
"
| " +
"ef | " +
"
",
});
});
});
describe("removal", () => {
test("should remove a column based on selection", async () => {
await testEditor({
contentBefore: unformat(`
`),
stepFunction: removeColumn(),
contentAfter: unformat(`
`),
});
});
test("should remove the column passed as argument", async () => {
await testEditor({
contentBefore: unformat(`
`),
stepFunction: (editor) => {
// Select the second cell
const cell = editor.editable.querySelectorAll("td")[1];
removeColumn(cell)(editor);
},
contentAfter: unformat(`
`),
});
});
test("should remove the table upon sole column removal", async () => {
await testEditor({
contentBefore: unformat(`
`),
stepFunction: removeColumn(),
contentAfter: "[]
",
});
});
});
});
describe("tab", () => {
test("should add a new row on press tab at the end of a table", async () => {
const contentBefore = unformat(`
`);
const { el, editor } = await setupEditor(contentBefore);
await press("Tab");
const expectedContent = unformat(`
`);
expect(getContent(el)).toBe(expectedContent);
// Check that it was registed as a history step.
undo(editor);
expect(getContent(el)).toBe(contentBefore);
});
test("should not select whole text of the next cell", async () => {
await testEditor({
contentBefore:
'',
stepFunction: () => press("Tab"),
contentAfter:
'',
});
});
});