// Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import { surroundNoSplitting as surround } from "./no-splitting"; const parser = new DOMParser(); function p(html: string): HTMLBodyElement { const parsed = parser.parseFromString(html, "text/html"); return parsed.body as HTMLBodyElement; } describe("surround text", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("111222"); }); test("all text", () => { const range = new Range(); range.selectNode(body.firstChild!); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(0); expect(body).toHaveProperty("innerHTML", "111222"); expect(surroundedRange.toString()).toEqual("111222"); }); test("first half", () => { const range = new Range(); range.setStart(body.firstChild!, 0); range.setEnd(body.firstChild!, 3); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(0); expect(body).toHaveProperty("innerHTML", "111222"); expect(surroundedRange.toString()).toEqual("111"); }); test("second half", () => { const range = new Range(); range.setStart(body.firstChild!, 3); range.setEnd(body.firstChild!, 6); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(0); expect(body).toHaveProperty("innerHTML", "111222"); expect(surroundedRange.toString()).toEqual("222"); }); }); describe("surround text next to nested", () => { describe("before", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("beforeafter"); }); test("enlarges bottom tag of nested", () => { const range = new Range(); range.selectNode(body.firstChild!); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("u"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(1); expect(body).toHaveProperty("innerHTML", "beforeafter"); expect(surroundedRange.toString()).toEqual("before"); }); test("moves nested down", () => { const range = new Range(); range.selectNode(body.firstChild!); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(1); expect(body).toHaveProperty("innerHTML", "beforeafter"); expect(surroundedRange.toString()).toEqual("before"); }); }); describe("after", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("beforeafter"); }); test("enlarges bottom tag of nested", () => { const range = new Range(); range.selectNode(body.childNodes[1]); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("u"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(1); expect(body).toHaveProperty("innerHTML", "beforeafter"); expect(surroundedRange.toString()).toEqual("after"); }); test("moves nested down", () => { const range = new Range(); range.selectNode(body.childNodes[1]); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(1); expect(body).toHaveProperty("innerHTML", "beforeafter"); expect(surroundedRange.toString()).toEqual("after"); }); }); }); describe("surround across block element", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("Before
"); }); test("does not insert empty elements", () => { const range = new Range(); range.setStartBefore(body.firstChild!); range.setEndAfter(body.lastChild!); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(3); expect(removedNodes).toHaveLength(0); expect(body).toHaveProperty( "innerHTML", "Before
", ); expect(surroundedRange.toString()).toEqual("BeforeFirstSecond"); }); }); describe("next to nested", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("111222333444555"); }); test("surround after", () => { const range = new Range(); range.selectNode(body.lastChild!); const { addedNodes, removedNodes } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(3); expect(body).toHaveProperty("innerHTML", "111222333444555"); // expect(surroundedRange.toString()).toEqual("555"); }); }); describe("next to element with nested non-matching", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("111222333444555"); }); test("surround after", () => { const range = new Range(); range.selectNode(body.lastChild!); const { addedNodes, removedNodes } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(1); expect(body).toHaveProperty( "innerHTML", "111222333444555", ); // expect(surroundedRange.toString()).toEqual("555"); }); }); describe("next to element with text element text", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("111222333444555"); }); test("surround after", () => { const range = new Range(); range.selectNode(body.lastChild!); const { addedNodes, removedNodes } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(2); expect(body).toHaveProperty("innerHTML", "111222333444555"); // expect(surroundedRange.toString()).toEqual("555"); }); }); describe("surround elements that already have nested block", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("12
"); }); test("normalizes nodes", () => { const range = new Range(); range.selectNode(body.children[0]); const { addedNodes, removedNodes } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(2); expect(body).toHaveProperty("innerHTML", "12
"); // expect(surroundedRange.toString()).toEqual("12"); }); }); describe("surround complicated nested structure", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("12345"); }); test("normalize nodes", () => { const range = new Range(); range.setStartBefore(body.firstElementChild!.firstChild!); range.setEndAfter(body.lastElementChild!.firstChild!); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(1); expect(body).toHaveProperty( "innerHTML", "12345", ); expect(surroundedRange.toString()).toEqual("12345"); }); }); describe("skips over empty elements", () => { describe("joins two newly created", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("before
after"); }); test("normalize nodes", () => { const range = new Range(); range.setStartBefore(body.firstChild!); range.setEndAfter(body.childNodes[2]!); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(0); expect(body).toHaveProperty("innerHTML", "before
after
"); expect(surroundedRange.toString()).toEqual("beforeafter"); }); }); describe("joins with already existing", () => { let body: HTMLBodyElement; beforeEach(() => { body = p("before
after"); }); test("normalize nodes", () => { const range = new Range(); range.selectNode(body.firstChild!); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(1); expect(body).toHaveProperty("innerHTML", "before
after
"); expect(surroundedRange.toString()).toEqual("before"); }); test("normalize node contents", () => { const range = new Range(); range.selectNodeContents(body.firstChild!); const { addedNodes, removedNodes, surroundedRange } = surround( range, document.createElement("b"), body, ); expect(addedNodes).toHaveLength(1); expect(removedNodes).toHaveLength(1); expect(body).toHaveProperty("innerHTML", "before
after
"); expect(surroundedRange.toString()).toEqual("before"); }); }); });