| 28 | // on `globalThis.document`. See the bootstrap at the bottom of this module. |
| 29 | |
| 30 | export function installDom(): () => void { |
| 31 | const previous: DomGlobalsSnapshot = { |
| 32 | window: globalThis.window, |
| 33 | document: globalThis.document, |
| 34 | Element: (globalThis as unknown as { Element?: unknown }).Element, |
| 35 | DocumentFragment: (globalThis as unknown as { DocumentFragment?: unknown }).DocumentFragment, |
| 36 | navigator: globalThis.navigator, |
| 37 | HTMLInputElement: (globalThis as unknown as { HTMLInputElement?: unknown }).HTMLInputElement, |
| 38 | localStorage: globalThis.localStorage, |
| 39 | CustomEvent: globalThis.CustomEvent, |
| 40 | NodeFilter: (globalThis as unknown as { NodeFilter?: unknown }).NodeFilter, |
| 41 | HTMLElement: (globalThis as unknown as { HTMLElement?: unknown }).HTMLElement, |
| 42 | Node: (globalThis as unknown as { Node?: unknown }).Node, |
| 43 | Image: (globalThis as unknown as { Image?: unknown }).Image, |
| 44 | requestAnimationFrame: globalThis.requestAnimationFrame, |
| 45 | getComputedStyle: globalThis.getComputedStyle, |
| 46 | cancelAnimationFrame: globalThis.cancelAnimationFrame, |
| 47 | ResizeObserver: (globalThis as unknown as { ResizeObserver?: unknown }).ResizeObserver, |
| 48 | MutationObserver: (globalThis as unknown as { MutationObserver?: unknown }).MutationObserver, |
| 49 | IntersectionObserver: (globalThis as unknown as { IntersectionObserver?: unknown }) |
| 50 | .IntersectionObserver, |
| 51 | }; |
| 52 | |
| 53 | const domWindow = new GlobalWindow({ url: "http://localhost" }) as unknown as Window & |
| 54 | typeof globalThis; |
| 55 | |
| 56 | globalThis.window = domWindow; |
| 57 | globalThis.document = domWindow.document; |
| 58 | globalThis.navigator = domWindow.navigator; |
| 59 | globalThis.getComputedStyle = domWindow.getComputedStyle.bind(domWindow); |
| 60 | globalThis.localStorage = domWindow.localStorage; |
| 61 | globalThis.CustomEvent = domWindow.CustomEvent as typeof globalThis.CustomEvent; |
| 62 | (globalThis as unknown as { Element: unknown }).Element = domWindow.Element; |
| 63 | (globalThis as unknown as { DocumentFragment: unknown }).DocumentFragment = |
| 64 | domWindow.DocumentFragment; |
| 65 | (globalThis as unknown as { HTMLInputElement: unknown }).HTMLInputElement = |
| 66 | domWindow.HTMLInputElement; |
| 67 | (globalThis as unknown as { HTMLElement: unknown }).HTMLElement = domWindow.HTMLElement; |
| 68 | (globalThis as unknown as { MutationObserver: unknown }).MutationObserver = |
| 69 | domWindow.MutationObserver; |
| 70 | (globalThis as unknown as { NodeFilter: unknown }).NodeFilter = domWindow.NodeFilter; |
| 71 | (globalThis as unknown as { Node: unknown }).Node = domWindow.Node; |
| 72 | // Image is used by react-dnd-html5-backend for drag preview |
| 73 | (globalThis as unknown as { Image: unknown }).Image = domWindow.Image ?? class MockImage {}; |
| 74 | // DataTransfer is used by drag-drop tests |
| 75 | if (!(globalThis as unknown as { DataTransfer?: unknown }).DataTransfer) { |
| 76 | (globalThis as unknown as { DataTransfer: unknown }).DataTransfer = |
| 77 | domWindow.DataTransfer ?? class MockDataTransfer {}; |
| 78 | } |
| 79 | |
| 80 | // happy-dom returns null from canvas.getContext("2d") by default. Libraries like |
| 81 | // lottie-web expect a writable 2D context during module initialization. |
| 82 | const canvasPrototype = domWindow.HTMLCanvasElement?.prototype as |
| 83 | | { |
| 84 | getContext?: (contextId: string, options?: unknown) => unknown; |
| 85 | } |
| 86 | | undefined; |
| 87 | |