import { expect, test } from "@odoo/hoot"; import { manuallyDispatchProgrammaticEvent } from "@odoo/hoot-dom"; import { patchWithCleanup } from "@web/../tests/web_test_helpers"; import { setupEditor, testEditor } from "../_helpers/editor"; import { cleanLinkArtifacts } from "../_helpers/format"; import { getContent, setSelection } from "../_helpers/selection"; import { insertText, undo } from "../_helpers/user_actions"; async function insertSpace(editor) { await manuallyDispatchProgrammaticEvent(editor.editable, "keydown", { key: " " }); // InputEvent is required to simulate the insert text. await manuallyDispatchProgrammaticEvent(editor.editable, "beforeinput", { inputType: "insertText", data: " ", }); const range = editor.document.getSelection().getRangeAt(0); if (!range.collapsed) { throw new Error("need to implement something... maybe"); } let offset = range.startOffset; const node = range.startContainer; // mimic the behavior of the browser when inserting a   const twoSpace = " \u00A0"; node.textContent = ( node.textContent.slice(0, offset) + " " + node.textContent.slice(offset) ).replaceAll(" ", twoSpace); if ( node.nextSibling && node.nextSibling.textContent.startsWith(" ") && node.textContent.endsWith(" ") ) { node.nextSibling.textContent = "\u00A0" + node.nextSibling.textContent.slice(1); } offset++; setSelection({ anchorNode: node, anchorOffset: offset, }); await manuallyDispatchProgrammaticEvent(editor.editable, "input", { inputType: "insertText", data: " ", }); // KeyUpEvent is not required but is triggered like the browser would. await manuallyDispatchProgrammaticEvent(editor.editable, "keyup", { key: " " }); } /** * Automatic link creation when pressing Space, Enter or Shift+Enter after an url */ test("should transform url after space", async () => { await testEditor({ contentBefore: "
a http://test.com b http://test.com[] c http://test.com d
", stepFunction: async (editor) => { await insertSpace(editor); }, contentAfter: 'a http://test.com b http://test.com [] c http://test.com d
', }); await testEditor({ contentBefore: "http://test.com[]
", stepFunction: async (editor) => { // Setup: simulate multiple text nodes in a p:"http://test" ".com"
editor.editable.firstChild.firstChild.splitText(11); /** @todo fix warnings */ patchWithCleanup(console, { warn: () => {} }); // Action: insert space await insertSpace(editor); }, contentAfter: '', }); }); test("should transform url followed by punctuation characters after space", async () => { await testEditor({ contentBefore: "http://test.com.[]
", stepFunction: async (editor) => { await insertSpace(editor); }, contentAfter: 'http://test.com. []
', }); await testEditor({ contentBefore: "test.com...[]
", stepFunction: (editor) => insertSpace(editor), contentAfter: 'test.com... []
', }); await testEditor({ contentBefore: "test.com,[]
", stepFunction: (editor) => insertSpace(editor), contentAfter: 'test.com, []
', }); await testEditor({ contentBefore: "test.com,hello[]
", stepFunction: (editor) => insertSpace(editor), contentAfter: 'test.com,hello []
', }); await testEditor({ contentBefore: "http://test.com[]
", stepFunction: async (editor) => { // Setup: simulate multiple text nodes in a p:"http://test" ".com"
editor.editable.firstChild.firstChild.splitText(11); /** @todo fix warnings */ patchWithCleanup(console, { warn: () => {} }); // Action: insert space await insertSpace(editor); }, contentAfter: '', }); }); test("should transform url after enter", async () => { await testEditor({ contentBefore: "a http://test.com b http://test.com[] c http://test.com d
", stepFunction: async (editor) => { // Simulate "Enter" await manuallyDispatchProgrammaticEvent(editor.editable, "beforeinput", { inputType: "insertParagraph", }); }, contentAfter: 'a http://test.com b http://test.com
[] c http://test.com d
', }); }); test("should transform url after shift+enter", async () => { await testEditor({ contentBefore: "a http://test.com b http://test.com[] c http://test.com d
", stepFunction: async (editor) => { // Simulate "Shift + Enter" await manuallyDispatchProgrammaticEvent(editor.editable, "beforeinput", { inputType: "insertLineBreak", }); }, contentAfter: 'a http://test.com b http://test.com
[] c http://test.com d
user@domain.com[]
", stepFunction: (editor) => insertSpace(editor), contentAfter: "user@domain.com []
", }); }); test("should not transform url after two space", async () => { await testEditor({ contentBefore: "a http://test.com b http://test.com [] c http://test.com d
", stepFunction: (editor) => insertSpace(editor), contentAfter: "a http://test.com b http://test.com [] c http://test.com d
", }); }); test("transform text url into link and undo it", async () => { const { el, editor } = await setupEditor(`[]
`); await insertText(editor, "www.abc.jpg "); expect(cleanLinkArtifacts(getContent(el))).toBe( 'www.abc.jpg []
' ); undo(editor); expect(cleanLinkArtifacts(getContent(el))).toBe( '' ); undo(editor); expect(cleanLinkArtifacts(getContent(el))).toBe("www.abc.jpg[]
"); });