UNPKG

@schukai/monster

Version:

Monster is a simple library for creating fast, robust and lightweight websites.

157 lines (132 loc) 5.28 kB
'use strict'; import {extend} from "../../source/data/extend.mjs"; import {getGlobal} from "../../source/types/global.mjs"; import {ResizeObserverMock} from "./resize-observer.mjs"; export const isBrowser = new Function("try {return this===window;}catch(e){ return false;}"); export const isNode = new Function("try {return this===global;}catch(e){return false;}"); let JSDOMExport = null; /** * this helper function creates the dom stack in the node environment * * @return {Promise<unknown>|Promise<void>} */ function initJSDOM(options) { if (typeof window === "object" && window['DOMParser']) return Promise.resolve(); const g = getGlobal(); options = extend({}, { pretendToBeVisual: true, contentType: "text/html", includeNodeLocations: true, storageQuota: 10000000, runScripts: "dangerously", resources: "usable", url: "https://example.test/" }, options || {}) return import("jsdom").then(({JSDOM}) => { JSDOMExport = JSDOM; const {window} = new JSDOM(`<!DOCTYPE html><html lang="en"><head><title>Test</title></head><body><div id="mocks"></div></body></html>`, options); g['window'] = window; return new Promise((resolve, reject) => { let settled = false; const finalize = () => { if (settled) return; settled = true; [ 'Blob', 'CSSStyleSheet', 'customElements', 'CustomEvent', 'document', 'DOMException', 'DOMImplementation', 'Document', 'DocumentFragment', 'DOMParser', 'Element', 'ElementInternals', 'Event', 'EventTarget', 'getComputedStyle', 'HTMLButtonElement', 'HTMLCollection', 'HTMLDivElement', 'HTMLDocument', 'HTMLElement', 'HTMLFormElement', 'HTMLInputElement', 'HTMLScriptElement', 'requestAnimationFrame', 'HTMLSelectElement', 'HTMLTemplateElement', 'HTMLTextAreaElement', 'InputEvent', 'KeyboardEvent', 'MutationObserver', // 'navigator', 'Node', 'NodeFilter', 'NodeList', 'self', 'ShadowRoot', 'XMLSerializer', ].forEach(key => { try { g[key] = window[key] } catch(e) { console.error("Error setting key", key, e); } }); if (!window.ResizeObserver) { window.ResizeObserver = ResizeObserverMock; } if (!g.ResizeObserver) { g.ResizeObserver = window.ResizeObserver; } import("dom-storage").then(({default: Storage}) => { const ensureStorage = (key) => { let existing = null; try { existing = window[key]; } catch (e) {} if (existing) { g[key] = existing; return; } const storage = new Storage(null, {strict: true}); const descriptor = Object.getOwnPropertyDescriptor(window, key); if (!descriptor || descriptor.writable || typeof descriptor.set === "function") { window[key] = storage; } else if (descriptor.configurable === true) { Object.defineProperty(window, key, { value: storage, configurable: true, }); } try { g[key] = window[key] ?? storage; } catch (e) { g[key] = storage; } }; ensureStorage("localStorage"); ensureStorage("sessionStorage"); resolve(g); }).catch(e => { console.error("Error loading dom-storage", e); reject(e); }); }; const onLoad = () => { window.removeEventListener("load", onLoad); finalize(); }; window.addEventListener("load", onLoad); if (window.document.readyState === "complete") { queueMicrotask(finalize); } else { setTimeout(finalize, 50); } }); }); } export {initJSDOM, JSDOMExport}