// @flow strict // This file is intended for use in the GL-JS test suite // It implements a JSDOM window object for use in Node environments // In a browser environment, this file is replaced with ./src/util/browser/window.js // when Rollup builds the main bundle // See package.json#browser import jsdom from 'jsdom'; import gl from 'gl'; import sinon from 'sinon'; import type {Window} from '../types/window'; const {window: _window} = new jsdom.JSDOM('', { virtualConsole: new jsdom.VirtualConsole().sendTo(console) }); restore(); export default _window; function restore(): Window { // Remove previous window from exported object const previousWindow = _window; if (previousWindow.close) previousWindow.close(); for (const key in previousWindow) { if (previousWindow.hasOwnProperty(key)) { delete previousWindow[key]; } } // Create new window and inject into exported object const {window} = new jsdom.JSDOM('', { // Send jsdom console output to the node console object. virtualConsole: new jsdom.VirtualConsole().sendTo(console) }); // Delete local and session storage from JSDOM and stub them out with a warning log // Accessing these properties during extend() produces an error in Node environments // See https://github.com/mapbox/mapbox-gl-js/pull/7455 for discussion delete window.localStorage; delete window.sessionStorage; window.localStorage = window.sessionStorage = () => console.log('Local and session storage not available in Node. Use a stub implementation if needed for testing.'); window.devicePixelRatio = 1; window.requestAnimationFrame = function(callback) { return setImmediate(callback, 0); }; window.cancelAnimationFrame = clearImmediate; // Add webgl context with the supplied GL const originalGetContext = window.HTMLCanvasElement.prototype.getContext; window.HTMLCanvasElement.prototype.getContext = function (type, attributes) { if (type === 'webgl') { if (!this._webGLContext) { this._webGLContext = gl(this.width, this.height, attributes); } return this._webGLContext; } // Fallback to existing HTMLCanvasElement getContext behaviour return originalGetContext.call(this, type, attributes); }; window.useFakeHTMLCanvasGetContext = function() { this.HTMLCanvasElement.prototype.getContext = function() { return '2d'; }; }; window.useFakeXMLHttpRequest = function() { sinon.xhr.supportsCORS = true; this.server = sinon.fakeServer.create(); this.XMLHttpRequest = this.server.xhr; }; window.URL.revokeObjectURL = function () {}; window.fakeWorkerPresence = function() { global.WorkerGlobalScope = function() {}; global.self = new global.WorkerGlobalScope(); }; window.clearFakeWorkerPresence = function() { global.WorkerGlobalScope = undefined; global.self = undefined; }; window.restore = restore; window.performance.getEntriesByName = function() {}; window.performance.mark = function() {}; window.performance.measure = function() {}; window.performance.clearMarks = function() {}; window.performance.clearMeasures = function() {}; window.ImageData = window.ImageData || function() { return false; }; window.ImageBitmap = window.ImageBitmap || function() { return false; }; window.WebGLFramebuffer = window.WebGLFramebuffer || Object; Object.assign(_window, window); // eslint-disable-line no-restricted-properties return window; }