|
@@ -0,0 +1,194 @@
|
|
|
+import { describe, expect, it } from "vitest";
|
|
|
+import { addGlobalStyle, addParent, getSiblingsFrame, getUnsafeWindow, interceptEvent, isDomLoaded, observeElementProp, preloadImages, probeElementStyle, setInnerHtmlUnsafe } from "./dom.js";
|
|
|
+
|
|
|
+//#region getUnsafeWindow
|
|
|
+describe("dom/getUnsafeWindow", () => {
|
|
|
+ it("Returns the correct window objects", () => {
|
|
|
+ expect(getUnsafeWindow()).toBe(window);
|
|
|
+ var unsafeWindow = window;
|
|
|
+ expect(getUnsafeWindow()).toBe(unsafeWindow);
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+//#region addParent
|
|
|
+describe("dom/addParent", () => {
|
|
|
+ it("Adds a parent to an element", () => {
|
|
|
+ const container = document.createElement("div");
|
|
|
+ container.id = "container";
|
|
|
+
|
|
|
+ const child = document.createElement("div");
|
|
|
+ child.id = "child";
|
|
|
+
|
|
|
+ document.body.appendChild(child);
|
|
|
+
|
|
|
+ addParent(child, container);
|
|
|
+
|
|
|
+ expect(child.parentNode).toBe(container);
|
|
|
+
|
|
|
+ container.remove();
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+//#region addGlobalStyle
|
|
|
+describe("dom/addGlobalStyle", () => {
|
|
|
+ it("Adds a global style to the document", () => {
|
|
|
+ const el = addGlobalStyle(`body { background-color: red; }`);
|
|
|
+ el.id = "test-style";
|
|
|
+
|
|
|
+ expect(document.querySelector("head #test-style")).toBe(el);
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+//#region preloadImages
|
|
|
+//TODO:FIXME: no workis
|
|
|
+describe.skip("dom/preloadImages", () => {
|
|
|
+ it("Preloads images", async () => {
|
|
|
+ const res = await preloadImages(["https://picsum.photos/50/50"]);
|
|
|
+
|
|
|
+ expect(Array.isArray(res)).toBe(true);
|
|
|
+ expect(res.every(r => r.status === "fulfilled")).toBe(true);
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+//#region openInNewTab
|
|
|
+describe.skip("dom/openInNewTab", () => {
|
|
|
+ // obviously cant test this
|
|
|
+});
|
|
|
+
|
|
|
+//#region interceptEvent
|
|
|
+describe("dom/interceptEvent", () => {
|
|
|
+ it("Intercepts an event", () => {
|
|
|
+ const el = document.createElement("div");
|
|
|
+ el.id = "test-intercept";
|
|
|
+ document.body.appendChild(el);
|
|
|
+
|
|
|
+ let clickedTimes = 0;
|
|
|
+
|
|
|
+ el.addEventListener("click", () => ++clickedTimes);
|
|
|
+ interceptEvent(el, "click", () => true);
|
|
|
+ el.addEventListener("click", () => ++clickedTimes);
|
|
|
+
|
|
|
+ el.click();
|
|
|
+
|
|
|
+ expect(clickedTimes).toBe(1);
|
|
|
+
|
|
|
+ document.body.removeChild(el);
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+//#region interceptWindowEvent
|
|
|
+describe("dom/interceptWindowEvent", () => {
|
|
|
+ it("Intercepts a window event", () => {
|
|
|
+ let clickedTimes = 0;
|
|
|
+
|
|
|
+ const inc = () => clickedTimes++;
|
|
|
+
|
|
|
+ window.addEventListener("foo", inc);
|
|
|
+ interceptEvent(window, "foo", () => true);
|
|
|
+ window.addEventListener("foo", inc);
|
|
|
+
|
|
|
+ window.dispatchEvent(new Event("foo"));
|
|
|
+
|
|
|
+ expect(clickedTimes).toBe(1);
|
|
|
+
|
|
|
+ window.removeEventListener("foo", inc);
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+//#region observeElementProp
|
|
|
+//TODO:FIXME: no workio
|
|
|
+describe.skip("dom/observeElementProp", () => {
|
|
|
+ it("Observes an element property", () => {
|
|
|
+ const el = document.createElement("input");
|
|
|
+ el.type = "text";
|
|
|
+ document.body.appendChild(el);
|
|
|
+
|
|
|
+ let newVal = "";
|
|
|
+ observeElementProp(el, "value", (_oldVal, newVal) => {
|
|
|
+ newVal = newVal;
|
|
|
+ });
|
|
|
+
|
|
|
+ el.value = "foo";
|
|
|
+
|
|
|
+ expect(newVal).toBe("foo");
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+//#region getSiblingsFrame
|
|
|
+describe("dom/getSiblingsFrame", () => {
|
|
|
+ it("Returns the correct frame", () => {
|
|
|
+ const container = document.createElement("div");
|
|
|
+ for(let i = 0; i < 10; i++) {
|
|
|
+ const el = document.createElement("div");
|
|
|
+ el.id = `e${i}`;
|
|
|
+ container.appendChild(el);
|
|
|
+ }
|
|
|
+
|
|
|
+ const cntrEl = container.querySelector<HTMLElement>("#e5")!;
|
|
|
+
|
|
|
+ expect(getSiblingsFrame(cntrEl, 2).map(e => e.id)).toEqual(["e5", "e6"]);
|
|
|
+ expect(getSiblingsFrame(cntrEl, 2, "top", false).map(e => e.id)).toEqual(["e6", "e7"]);
|
|
|
+ expect(getSiblingsFrame(cntrEl, 2, "bottom", false).map(e => e.id)).toEqual(["e3", "e4"]);
|
|
|
+ expect(getSiblingsFrame(cntrEl, 2, "center-top", false).map(e => e.id)).toEqual(["e4", "e6"]);
|
|
|
+ expect(getSiblingsFrame(cntrEl, 3, "center-top", true).map(e => e.id)).toEqual(["e4", "e5", "e6"]);
|
|
|
+ expect(getSiblingsFrame(cntrEl, 4, "center-top", true).map(e => e.id)).toEqual(["e4", "e5", "e6", "e7"]);
|
|
|
+ expect(getSiblingsFrame(cntrEl, 4, "center-bottom", true).map(e => e.id)).toEqual(["e3", "e4", "e5", "e6"]);
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+//#region setInnerHtmlUnsafe
|
|
|
+describe("dom/setInnerHtmlUnsafe", () => {
|
|
|
+ it("Sets inner HTML", () => {
|
|
|
+ const el = document.createElement("div");
|
|
|
+ setInnerHtmlUnsafe(el, "<div>foo</div>");
|
|
|
+
|
|
|
+ expect(el.querySelector("div")?.textContent).toBe("foo");
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+//#region probeElementStyle
|
|
|
+//TODO:FIXME: no workiong
|
|
|
+describe.skip("dom/probeElementStyle", () => {
|
|
|
+ it("Resolves a CSS variable", async () => {
|
|
|
+ addGlobalStyle(`:root { --foo: #f00; --bar: var(--foo, #00f); }`);
|
|
|
+
|
|
|
+ const tryResolveCol = (i = 0) => new Promise<string>((res, rej) => {
|
|
|
+ if(i > 100)
|
|
|
+ return rej(new Error("Could not resolve color after 100 tries"));
|
|
|
+
|
|
|
+ const probedCol = probeElementStyle(
|
|
|
+ (style) => style.backgroundColor,
|
|
|
+ () => {
|
|
|
+ const elem = document.createElement("span");
|
|
|
+ elem.style.backgroundColor = "var(--foo, #000)";
|
|
|
+ return elem;
|
|
|
+ },
|
|
|
+ true,
|
|
|
+ );
|
|
|
+
|
|
|
+ if(probedCol.length === 0 || probedCol.match(/^rgba?\((?:(?:255,\s?255,\s?255)|(?:0,\s?0,\s?0))/) || probedCol.match(/^#(?:fff(?:fff)?|000(?:000)?)/))
|
|
|
+ return setTimeout(async () => res(await tryResolveCol(++i)), 100);
|
|
|
+
|
|
|
+ return res(probedCol);
|
|
|
+ });
|
|
|
+
|
|
|
+ const val = await tryResolveCol();
|
|
|
+
|
|
|
+ expect(val).toBe("rgb(255, 0, 0)");
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+const initialState = document.readyState;
|
|
|
+
|
|
|
+//#region isDomLoaded
|
|
|
+describe.skip("dom/isDomLoaded", () => {
|
|
|
+ it("Returns the correct state", () => {
|
|
|
+ // doesn't work cause the lib isn't loaded before DOMContentLoaded
|
|
|
+ expect(isDomLoaded()).toBe(initialState === "complete");
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+//#region onDomLoad
|
|
|
+describe.skip("dom/onDomLoad", () => {
|
|
|
+ // see above
|
|
|
+});
|