import { isBlock } from "@html_editor/utils/blocks"; import { ancestors, closestElement, descendants, firstLeaf, getAdjacentNextSiblings, getAdjacentPreviousSiblings, getAdjacents, lastLeaf, getCommonAncestor, } from "@html_editor/utils/dom_traversal"; import { describe, expect, getFixture, test } from "@odoo/hoot"; import { insertTestHtml } from "../_helpers/editor"; import { unformat } from "../_helpers/format"; describe("closestElement", () => { test("should find the closest element to a text node", () => { const [div] = insertTestHtml("
abc
abc
"); const result = closestElement(p); expect(result).toBe(p); }); test("should not find a node which is not contained inside a .odoo-editor-editable", () => { const [div] = insertTestHtml(`abc
abc
abc
def
abc
"); const editable = p.parentElement; const result = ancestors(p, editable); expect(result).toEqual([editable]); }); }); describe("descendants", () => { test("should find all the descendants of a div in depth-first order", () => { const [div] = insertTestHtml( "abc
def
abc
div.firstChild.firstChild.firstChild.firstChild, // "abc" div.firstChild.firstChild.childNodes[1], //def
def
div.firstChild.firstChild.childNodes[1].firstChild.firstChild, // "def" ]); }); }); describe("lastLeaf", () => { test("should find the last leaf of a child-rich block", () => { const [div] = insertTestHtml( "abcdef
abcdef
abcdef
abcdef
abcdef
abcdef
abcdefghijklmnop
"); const gh = p.firstChild.childNodes[1].childNodes[2]; const u = gh.previousSibling; const cd = u.previousSibling; const result = getAdjacentPreviousSiblings(gh); expect(result).toEqual([u, cd]); }); test("should find no adjacent previous siblings of a deeply nested node", () => { const [p] = insertTestHtml("abcdefghijklmnop
"); const ij = p.firstChild.childNodes[1].childNodes[3].firstChild; const result = getAdjacentPreviousSiblings(ij); expect(result).toEqual([]); }); test("should find only the adjacent previous siblings of a deeply nested node that are elements", () => { const [p] = insertTestHtml("abcdefghijklmnop
"); const gh = p.firstChild.childNodes[1].childNodes[2]; const u = gh.previousSibling; const result = getAdjacentPreviousSiblings( gh, (node) => node.nodeType === Node.ELEMENT_NODE ); expect(result).toEqual([u]); }); test("should find only the adjacent previous siblings of a deeply nested node that are text nodes (none)", () => { const [p] = insertTestHtml("abcdefghijklmnop
"); const gh = p.firstChild.childNodes[1].childNodes[2]; const result = getAdjacentPreviousSiblings(gh, (node) => node.nodeType === Node.TEXT_NODE); expect(result).toEqual([]); }); }); describe("getAdjacentNextSiblings", () => { test("should find the adjacent next siblings of a deeply nested node", () => { const [p] = insertTestHtml("abcdefghijklmnop
"); const gh = p.firstChild.childNodes[1].childNodes[2]; const span = gh.nextSibling; const kl = span.nextSibling; const result = getAdjacentNextSiblings(gh); expect(result).toEqual([span, kl]); }); test("should find no adjacent next siblings of a deeply nested node", () => { const [p] = insertTestHtml("abcdefghijklmnop
"); const ij = p.firstChild.childNodes[1].childNodes[3].firstChild; const result = getAdjacentNextSiblings(ij); expect(result).toEqual([]); }); test("should find only the adjacent next siblings of a deeply nested node that are elements", () => { const [p] = insertTestHtml("abcdefghijklmnop
"); const gh = p.firstChild.childNodes[1].childNodes[2]; const span = gh.nextSibling; const result = getAdjacentNextSiblings(gh, (node) => node.nodeType === Node.ELEMENT_NODE); expect(result).toEqual([span]); }); test("should find only the adjacent next siblings of a deeply nested node that are text nodes (none)", () => { const [p] = insertTestHtml("abcdefghijklmnop
"); const gh = p.firstChild.childNodes[1].childNodes[2]; const result = getAdjacentNextSiblings(gh, (node) => node.nodeType === Node.TEXT_NODE); expect(result).toEqual([]); }); }); describe("getAdjacents", () => { test("should find the adjacent siblings of a deeply nested node", () => { const [p] = insertTestHtml("abcdefghijklmnop
"); const gh = p.firstChild.childNodes[1].childNodes[2]; const u = gh.previousSibling; const cd = u.previousSibling; const span = gh.nextSibling; const kl = span.nextSibling; const result = getAdjacents(gh); expect(result).toEqual([cd, u, gh, span, kl]); }); test("should find no adjacent siblings of a deeply nested node", () => { const [p] = insertTestHtml("abcdefghijklmnop
"); const ij = p.firstChild.childNodes[1].childNodes[3].firstChild; const result = getAdjacents(ij); expect(result).toEqual([ij]); }); test("should find the adjacent siblings of a deeply nested node that are elements", () => { const [p] = insertTestHtml( "abcdefghijklmnop
" ); const gh = p.firstChild.childNodes[1].childNodes[2]; const u = gh.previousSibling; const span = gh.nextSibling; const result = getAdjacents(gh, (node) => node.nodeType === Node.ELEMENT_NODE); expect(result).toEqual([u, gh, span]); }); test("should return an empty array if the given node is not satisfying the given predicate", () => { const [p] = insertTestHtml( "abcdefghijklmnopqr
" ); const a = p.querySelector("a"); const result = getAdjacents(a, (node) => node.nodeType === Node.TEXT_NODE); expect(result).toEqual([]); }); }); describe("getCommonAncestor", () => { let root, p1, p2, span1, span2, ul, li1, li2, li3, li4, ol; const prepareHtml = () => { [root] = insertTestHtml( unformat(`paragraph 1
paragraph 2 span1 span2