Path: blob/master/platform/web/js/engine/features.js
10279 views
const Features = {1/**2* Check whether WebGL is available. Optionally, specify a particular version of WebGL to check for.3*4* @param {number=} [majorVersion=1] The major WebGL version to check for.5* @returns {boolean} If the given major version of WebGL is available.6* @function Engine.isWebGLAvailable7*/8isWebGLAvailable: function (majorVersion = 1) {9try {10return !!document.createElement('canvas').getContext(['webgl', 'webgl2'][majorVersion - 1]);11} catch (e) { /* Not available */ }12return false;13},1415/**16* Check whether the Fetch API available and supports streaming responses.17*18* @returns {boolean} If the Fetch API is available and supports streaming responses.19* @function Engine.isFetchAvailable20*/21isFetchAvailable: function () {22return 'fetch' in window && 'Response' in window && 'body' in window.Response.prototype;23},2425/**26* Check whether the engine is running in a Secure Context.27*28* @returns {boolean} If the engine is running in a Secure Context.29* @function Engine.isSecureContext30*/31isSecureContext: function () {32return window['isSecureContext'] === true;33},3435/**36* Check whether the engine is cross origin isolated.37* This value is dependent on Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers sent by the server.38*39* @returns {boolean} If the engine is running in a Secure Context.40* @function Engine.isSecureContext41*/42isCrossOriginIsolated: function () {43return window['crossOriginIsolated'] === true;44},4546/**47* Check whether SharedBufferArray is available.48*49* Most browsers require the page to be running in a secure context, and the50* the server to provide specific CORS headers for SharedArrayBuffer to be available.51*52* @returns {boolean} If SharedArrayBuffer is available.53* @function Engine.isSharedArrayBufferAvailable54*/55isSharedArrayBufferAvailable: function () {56return 'SharedArrayBuffer' in window;57},5859/**60* Check whether the AudioContext supports AudioWorkletNodes.61*62* @returns {boolean} If AudioWorkletNode is available.63* @function Engine.isAudioWorkletAvailable64*/65isAudioWorkletAvailable: function () {66return 'AudioContext' in window && 'audioWorklet' in AudioContext.prototype;67},6869/**70* Return an array of missing required features (as string).71*72* @returns {Array<string>} A list of human-readable missing features.73* @function Engine.getMissingFeatures74* @param {{threads: (boolean|undefined)}} supportedFeatures75*/76getMissingFeatures: function (supportedFeatures = {}) {77const {78// Quotes are needed for the Closure compiler.79'threads': supportsThreads = true,80} = supportedFeatures;8182const missing = [];83if (!Features.isWebGLAvailable(2)) {84missing.push('WebGL2 - Check web browser configuration and hardware support');85}86if (!Features.isFetchAvailable()) {87missing.push('Fetch - Check web browser version');88}89if (!Features.isSecureContext()) {90missing.push('Secure Context - Check web server configuration (use HTTPS)');91}9293if (supportsThreads) {94if (!Features.isCrossOriginIsolated()) {95missing.push('Cross-Origin Isolation - Check that the web server configuration sends the correct headers.');96}97if (!Features.isSharedArrayBufferAvailable()) {98missing.push('SharedArrayBuffer - Check that the web server configuration sends the correct headers.');99}100}101102// Audio is normally optional since we have a dummy fallback.103return missing;104},105};106107108