import { describe, test } from "@odoo/hoot"; import { press } from "@odoo/hoot-dom"; import { tick } from "@odoo/hoot-mock"; import { testEditor } from "../_helpers/editor"; import { insertText, splitBlock } from "../_helpers/user_actions"; import { unformat } from "../_helpers/format"; import { MAIN_PLUGINS } from "@html_editor/plugin_sets"; import { QWebPlugin } from "@html_editor/others/qweb_plugin"; describe("Selection collapsed", () => { describe("Basic", () => { test("should duplicate an empty paragraph", async () => { await testEditor({ contentBefore: "
[]
[]
[
]
[]
[]
[]
[]abc
", stepFunction: splitBlock, contentAfter: "[]abc
", }); await testEditor({ contentBefore: "[] abc
", stepFunction: splitBlock, // JW cAfter: '[]abc
', contentAfter: "[] abc
", }); }); test("should split a paragraph in two", async () => { await testEditor({ contentBefore: "ab[]cd
", stepFunction: splitBlock, contentAfter: "ab
[]cd
", }); await testEditor({ contentBefore: "ab []cd
", stepFunction: splitBlock, // The space is converted to a non-breaking // space so it is visible. contentAfter: "ab
[]cd
", }); await testEditor({ contentBefore: "ab[] cd
", stepFunction: splitBlock, // The space is converted to a non-breaking // space so it is visible. contentAfter: "ab
[] cd
", }); }); test("should insert an empty paragraph after a paragraph", async () => { await testEditor({ contentBefore: "abc[]
", stepFunction: splitBlock, contentAfter: "abc
[]
abc[]
", stepFunction: splitBlock, contentAfter: "abc
[]
[]def
`, }); }); test("should split block without afecting the uploaded document link (2)", async () => { await testEditor({ contentBefore: ``, stepFunction: splitBlock, contentAfter: `[]
ab[]cd", stepFunction: splitBlock, contentAfter: "
ab", }); }); test("should insert a line break within the pre containing inline element", async () => { await testEditor({ contentBefore: "
[]cd
ab[]cd", stepFunction: splitBlock, contentAfter: "
ab", }); }); test("should insert a line break within the pre containing inline elementd", async () => { await testEditor({ contentBefore: "
[]cd
ab[]cd", stepFunction: splitBlock, contentAfter: "
ab", }); }); test("should insert a new paragraph after the pre", async () => { await testEditor({ contentBefore: "
[]cd
abc[]", stepFunction: splitBlock, contentAfter: "
abc
[]
abc[]", stepFunction: splitBlock, contentAfter: "
abc
[]
abc[]", stepFunction: splitBlock, contentAfter: "
abc
[]
[]", stepFunction: splitBlock, contentAfter: "
[]
", stepFunction: splitBlock, contentAfter: "abc
def[]
", }); }); test("should insert a new line after pre", async () => { await testEditor({ contentBefore: "abc
def
[]
", stepFunction: splitBlock, contentAfter: "abc
def
[]
abc
def
[]
abc[]", stepFunction: splitBlock, contentAfter: "
abc
[]
abc[]", stepFunction: splitBlock, contentAfter: "
abc
[]
[]", stepFunction: splitBlock, contentAfter: "
[]
", stepFunction: splitBlock, contentAfter: "abc
def[]
", }); }); test("should insert a new line after blockquote", async () => { await testEditor({ contentBefore: "abc
def
[]
", stepFunction: splitBlock, contentAfter: "abc
def
[]
abc
def
[]
[]
[]
[
]
[]
[]
[]
[]abc
", stepFunction: async (editor) => { splitBlock(editor); splitBlock(editor); }, contentAfter: "[]abc
", }); }); test("should split a paragraph in three", async () => { await testEditor({ contentBefore: "ab[]cd
", stepFunction: async (editor) => { splitBlock(editor); splitBlock(editor); }, contentAfter: "ab
[]cd
", }); }); test("should split a paragraph in four", async () => { await testEditor({ contentBefore: "ab[]cd
", stepFunction: async (editor) => { splitBlock(editor); splitBlock(editor); splitBlock(editor); }, contentAfter: "ab
[]cd
", }); }); test("should insert two empty paragraphs after a paragraph", async () => { await testEditor({ contentBefore: "abc[]
", stepFunction: async (editor) => { splitBlock(editor); splitBlock(editor); }, contentAfter: "abc
[]
abc[]def
", stepFunction: splitBlock, contentAfter: "abc
[]def
", }); await testEditor({ // That selection is equivalent to [] contentBefore: "abc[]def
", stepFunction: splitBlock, contentAfter: "abc
[]def
", }); await testEditor({ contentBefore: "abc []def
", stepFunction: splitBlock, // The space is converted to a non-breaking // space so it is visible (because it's after a //abc
[]def
", }); await testEditor({ contentBefore: "abc[] def
", stepFunction: splitBlock, // The space is converted to a non-breaking // space so it is visible (because it's before a //abc
[] def
', contentAfter: "abc
[] def
", }); }); test("should split a paragraph after a format node", async () => { await testEditor({ contentBefore: "abc[]def
", stepFunction: splitBlock, contentAfter: "abc
[]def
", }); await testEditor({ // That selection is equivalent to [] contentBefore: "abc[]def
", stepFunction: splitBlock, contentAfter: "abc
[]def
", }); await testEditor({ contentBefore: "abc[] def
", stepFunction: splitBlock, // The space is converted to a non-breaking // space so it is visible. contentAfter: "abc
[] def
", }); await testEditor({ contentBefore: "abc []def
", stepFunction: splitBlock, // The space is converted to a non-breaking // space so it is visible (because it's before a //abc
[]def
", }); }); test("should split a paragraph at the beginning of a format node", async () => { await testEditor({ contentBefore: "[]abc
", stepFunction: splitBlock, contentAfter: "[]abc
", }); await testEditor({ // That selection is equivalent to [] contentBefore: "[]abc
", stepFunction: splitBlock, contentAfter: "[]abc
", }); await testEditor({ contentBefore: "[] abc
", stepFunction: splitBlock, // The space should have been parsed away. // JW cAfter: '[]abc
', contentAfter: "[] abc
", }); }); test("should split a paragraph within a format node", async () => { await testEditor({ contentBefore: "ab[]cd
", stepFunction: splitBlock, contentAfter: "ab
[]cd
", }); await testEditor({ contentBefore: "ab []cd
", stepFunction: splitBlock, // The space is converted to a non-breaking // space so it is visible. contentAfter: "ab
[]cd
", }); await testEditor({ contentBefore: "ab[] cd
", stepFunction: splitBlock, // The space is converted to a non-breaking // space so it is visible. contentAfter: "ab
[] cd
", }); }); test("should split a paragraph at the end of a format node", async () => { await testEditor({ contentBefore: "abc[]
", stepFunction: splitBlock, contentAfter: "abc
[]
abc[]
", stepFunction: splitBlock, contentAfter: "abc
[]
abc[]
", stepFunction: splitBlock, // The space should have been parsed away. contentAfter: "abc
[]
\ufeff\ufeff[]ab\ufeff\ufeff
', contentAfter: "ab[]cd
", stepFunction: splitBlockA, contentAfterEdit: 'ab
\ufeff\ufeff[]cd\ufeff\ufeff
', contentAfter: "ab
", }); }); test("should insert a paragraph break in the middle of an anchor", async () => { await testEditor({ contentBefore: "", stepFunction: splitBlockA, contentAfterEdit: '\ufeff\ufeffa\ufeff\ufeff
\ufeff\ufeff[]b\ufeff\ufeff
', contentAfter: "", }); }); test("should insert a paragraph break outside the ending edge of an anchor", async () => { await testEditor({ contentBefore: "", stepFunction: async (editor) => { splitBlock(editor); await press("enter"); editor.shared.selection.focusEditable(); await tick(); }, contentAfterEdit: `\ufeff\ufeffab\ufeff\ufeff
[]
[]
ab[]cd
", stepFunction: splitBlockA, contentAfterEdit: "\ufeff\ufeffab\ufeff\ufeff
[]cd
", contentAfter: "[]cd
", }); }); }); describe("With attributes", () => { test("should insert an empty paragraph before a paragraph with a span with a class", async () => { await testEditor({ contentBefore: 'ab
[]cd
', stepFunction: splitBlock, contentAfter: 'ab
[]cd
', }); }); test("should split a paragraph with a span with a bold in two", async () => { await testEditor({ contentBefore: 'ab[]cd
', stepFunction: splitBlock, contentAfter: 'ab
[]cd
', }); }); test("should split a paragraph at its end, with a paragraph after it, and both have the same class", async () => { await testEditor({ contentBefore: 'a[]
a
[]
[]
[]
[]
[ab]cd
", stepFunction: splitBlock, contentAfter: "[]cd
", }); // Backward selection await testEditor({ contentBefore: "]ab[cd
", stepFunction: splitBlock, contentAfter: "[]cd
", }); }); test("should delete part of a paragraph, then split it", async () => { // Forward selection await testEditor({ contentBefore: "a[bc]d
", stepFunction: splitBlock, contentAfter: "a
[]d
", }); // Backward selection await testEditor({ contentBefore: "a]bc[d
", stepFunction: splitBlock, contentAfter: "a
[]d
", }); }); test("should delete the last half of a paragraph, then split it", async () => { // Forward selection await testEditor({ contentBefore: "ab[cd]
", stepFunction: splitBlock, contentAfter: "ab
[]
ab]cd[
", stepFunction: splitBlock, contentAfter: "ab
[]
[abcd]
", stepFunction: splitBlock, contentAfter: "[]
]abcd[
", stepFunction: splitBlock, contentAfter: "[]
ab
[c]de
ab
f[]de
[abc def |
abcd |
ab] |
[] |
abcd |
ab |
]ab |
abcd |
abc def[ |
ab |
abcd |
[] |
[Test Test Test] |
[] |