import { describe, expect, test } from "@odoo/hoot"; import { patchWithCleanup } from "@web/../tests/web_test_helpers"; import { setupEditor, testEditor } from "../_helpers/editor"; import { getContent } from "../_helpers/selection"; import { em, s, span, u } from "../_helpers/tags"; import { insertText, italic, tripleClick, underline } from "../_helpers/user_actions"; import { unformat } from "../_helpers/format"; test("should make a few characters underline", async () => { await testEditor({ contentBefore: `

ab[cde]fg

`, stepFunction: underline, contentAfter: `

ab${u(`[cde]`)}fg

`, }); }); test("should make a few characters not underline", async () => { await testEditor({ contentBefore: `

${u(`ab[cde]fg`)}

`, stepFunction: underline, contentAfter: `

${u(`ab`)}[cde]${u(`fg`)}

`, }); }); test("should make two paragraphs underline", async () => { await testEditor({ contentBefore: "

[abc

def]

", stepFunction: underline, contentAfter: `

${u(`[abc`)}

${u(`def]`)}

`, }); }); test("should make two paragraphs not underline", async () => { await testEditor({ contentBefore: `

${u(`[abc`)}

${u(`def]`)}

`, stepFunction: underline, contentAfter: "

[abc

def]

", }); }); test("should make qweb tag underline", async () => { await testEditor({ contentBefore: `

[Test]

`, stepFunction: underline, contentAfter: `
[

Test

]
`, }); }); test("should make a whole heading underline after a triple click", async () => { await testEditor({ contentBefore: `

[ab

]cd

`, stepFunction: underline, contentAfter: `

${u(`[ab]`)}

cd

`, }); }); test("should make a whole heading not underline after a triple click", async () => { const { el, editor } = await setupEditor(`

${u(`ab`)}

cd

`); await tripleClick(el.querySelector("h1")); underline(editor); expect(getContent(el)).toBe(`

[ab]

cd

`); }); test("should make a selection starting with underline text fully underline", async () => { await testEditor({ contentBefore: `

${u(`[ab`)}

c]d

`, stepFunction: underline, contentAfter: `

${u(`[ab`)}

${u(`c]`)}d

`, }); }); test("should make a selection with underline text in the middle fully underline", async () => { await testEditor({ contentBefore: `

[a${u(`b`)}

${u(`c`)}d]e

`, stepFunction: underline, contentAfter: `

${u(`[ab`)}

${u(`cd]`)}e

`, }); }); test("should make a selection ending with underline text fully underline", async () => { await testEditor({ // @phoenix content adapted to make it valid html contentBefore: `

[ab

${u(`c]d`)}

`, stepFunction: underline, contentAfter: `

${u(`[ab`)}

${u(`c]d`)}

`, }); }); test("should get ready to type in underline", async () => { await testEditor({ contentBefore: `

ab[]cd

`, stepFunction: underline, contentAfterEdit: `

ab${u(`[]\u200B`, "first")}cd

`, contentAfter: `

ab[]cd

`, }); }); test("should get ready to type in not underline", async () => { await testEditor({ contentBefore: `

${u(`ab[]cd`)}

`, stepFunction: underline, contentAfterEdit: `

${u(`ab`)}${span(`[]\u200B`, "first")}${u(`cd`)}

`, contentAfter: `

${u(`ab[]cd`)}

`, }); }); test("should not format non-editable text (underline)", async () => { await testEditor({ contentBefore: '

[a

b

c]

', stepFunction: underline, contentAfter: `

${u("[a")}

b

${u("c]")}

`, }); }); test("should make a few characters underline inside table (underline)", async () => { await testEditor({ contentBefore: unformat(`

[abc



def



]



` ), stepFunction: underline, contentAfterEdit: unformat(`

${u(`[abc`)}



${u(`def`)}



${u(`]
`)}



` ), }); }); describe("with strikeThrough", () => { test("should get ready to write in strikeThrough without underline (underline was first)", async () => { await testEditor({ contentBefore: `

ab${u(s(`cd[]ef`))}

`, stepFunction: underline, contentAfterEdit: `

ab${u(s(`cd`))}${s(`[]\u200b`, "last")}${u(s(`ef`))}

`, contentAfter: `

ab${u(s(`cd[]ef`))}

`, }); }); test("should restore underline after removing it (collapsed, strikeThrough)", async () => { await testEditor({ contentBefore: `

ab${u(s(`cd`))}${s(`\u200b[]`, "first")}${u(s(`ef`))}

`, stepFunction: underline, contentAfterEdit: `

ab${u(s(`cd`))}${s(u(`[]\u200b`, "first"), "first")}${u( s(`ef`) )}

`, contentAfter: `

ab${u(s(`cd[]ef`))}

`, }); }); test("should remove underline after restoring it after removing it (collapsed, strikeThrough)", async () => { await testEditor({ contentBefore: `

ab${u(s(`cd`))}${s(u(`[]\u200b`, "first"))}${u(s(`ef`))}

`, stepFunction: underline, contentAfterEdit: `

ab${u(s(`cd`))}${s(`[]\u200b`, "last")}${u(s(`ef`))}

`, contentAfter: `

ab${u(s(`cd[]ef`))}

`, }); }); test("should remove underline after restoring it and writing after removing it (collapsed, strikeThrough)", async () => { await testEditor({ contentBefore: `

ab${u(s(`cd`))}${s(u(`ghi[]`))}${u(s(`ef`))}

`, stepFunction: underline, contentAfterEdit: `

ab${u(s(`cd`))}${s(`${u(`ghi`)}`)}${s(`[]\u200b`, "first")}${u( s(`ef`) )}

`, // The reason the cursor is after the tag is because when the editor get's cleaned, the zws tag gets deleted. contentAfter: `

ab${u(s(`cd`))}${s(u(`ghi`))}[]${u(s(`ef`))}

`, }); }); test("should remove underline, write, restore underline, write, remove underline again, write (collapsed, strikeThrough)", async () => { await testEditor({ contentBefore: `

abcd[]ef

`, stepFunction: async (editor) => { /** @todo fix warnings */ patchWithCleanup(console, { warn: () => {} }); underline(editor); await insertText(editor, "A"); underline(editor); await insertText(editor, "B"); underline(editor); await insertText(editor, "C"); }, contentAfterEdit: `

abcdABC[]ef

`, }); }); test("should remove only underline decoration on a span", async () => { await testEditor({ contentBefore: `

[a]

`, stepFunction: underline, contentAfter: `

[a]

`, }); }); }); describe("with italic", () => { test("should get ready to write in italic and underline", async () => { await testEditor({ contentBefore: `

ab[]cd

`, stepFunction: async (editor) => { italic(editor); underline(editor); }, contentAfterEdit: `

ab${em(u(`[]\u200B`, "first"), "first")}cd

`, contentAfter: `

ab[]cd

`, }); }); test("should get ready to write in italic, after changing one's mind about underline (two consecutive at the end)", async () => { await testEditor({ contentBefore: `

ab[]cd

`, stepFunction: async (editor) => { italic(editor); underline(editor); underline(editor); }, contentAfterEdit: `

ab${em(`[]\u200B`, "first")}cd

`, contentAfter: `

ab[]cd

`, }); }); test("should get ready to write in italic, after changing one's mind about underline (separated by italic)", async () => { await testEditor({ contentBefore: `

ab[]cd

`, stepFunction: async (editor) => { underline(editor); italic(editor); underline(editor); }, contentAfterEdit: `

ab${em(`[]\u200B`, "first")}cd

`, contentAfter: `

ab[]cd

`, }); }); test("should get ready to write in italic, after changing one's mind about underline (two consecutive at the beginning)", async () => { await testEditor({ contentBefore: `

ab[]cd

`, stepFunction: async (editor) => { underline(editor); underline(editor); italic(editor); }, contentAfterEdit: `

ab${em(`[]\u200B`, "first")}cd

`, contentAfter: `

ab[]cd

`, }); }); test("should get ready to write in italic without underline (underline was first)", async () => { await testEditor({ contentBefore: `

ab${u(em(`cd[]ef`))}

`, stepFunction: underline, contentAfterEdit: `

ab${u(em(`cd`))}${em(`[]\u200b`, "last")}${u(em(`ef`))}

`, contentAfter: `

ab${u(em(`cd[]ef`))}

`, }); }); test("should restore underline after removing it (collapsed, italic)", async () => { await testEditor({ contentBefore: `

ab${u(em(`cd`))}${em(`[]\u200b`)}${u(em(`ef`))}

`, stepFunction: underline, contentAfterEdit: `

ab${u(em(`cd`))}${em(u(`[]\u200b`, "last"))}${u(em(`ef`))}

`, contentAfter: `

ab${u(em(`cd`))}${em(`[]`)}${u(em(`ef`))}

`, }); }); test("should remove underline after restoring it after removing it (collapsed, italic)", async () => { await testEditor({ contentBefore: `

ab${u(em(`cd`))}${em(u(`[]\u200b`))}${u(em(`ef`))}

`, stepFunction: underline, contentAfterEdit: `

ab${u(em(`cd`))}${em(`[]\u200b`, "last")}${u(em(`ef`))}

`, contentAfter: `

ab${u(em(`cd[]ef`))}

`, }); }); test("should remove underline after restoring it and writing after removing it (collapsed, italic)", async () => { await testEditor({ contentBefore: `

ab${u(em(`cd`))}${em(u(`ghi[]`))}${u(em(`ef`))}

`, stepFunction: underline, contentAfterEdit: `

ab${u(em(`cd`))}${em( u(`ghi`) )}[]\u200b${u(em(`ef`))}

`, // The reason the cursor is after the tag is because when the editor get's cleaned, the zws tag gets deleted. contentAfter: `

ab${u(em(`cd`))}${em(u(`ghi`))}[]${u(em(`ef`))}

`, }); }); test("should remove underline, write, restore underline, write, remove underline again, write (collapsed, italic)", async () => { await testEditor({ contentBefore: `

ab${u(em(`cd[]ef`))}

`, stepFunction: async (editor) => { /** @todo fix warnings */ patchWithCleanup(console, { warn: () => {} }); underline(editor); await insertText(editor, "A"); underline(editor); await insertText(editor, "B"); underline(editor); await insertText(editor, "C"); }, contentAfter: `

ab${u(em(`cd`))}${em(`A${u(`B`)}C[]`)}${u(em(`ef`))}

`, }); }); });