import when from '../ThirdParty/when.js'; import defaultValue from './defaultValue.js'; import defined from './defined.js'; import defineProperties from './defineProperties.js'; import DeveloperError from './DeveloperError.js'; import Fullscreen from './Fullscreen.js'; /*global CanvasPixelArray*/ var theNavigator; if (typeof navigator !== 'undefined') { theNavigator = navigator; } else { theNavigator = {}; } function extractVersion(versionString) { var parts = versionString.split('.'); for (var i = 0, len = parts.length; i < len; ++i) { parts[i] = parseInt(parts[i], 10); } return parts; } var isChromeResult; var chromeVersionResult; function isChrome() { if (!defined(isChromeResult)) { isChromeResult = false; // Edge contains Chrome in the user agent too if (!isEdge()) { var fields = (/ Chrome\/([\.0-9]+)/).exec(theNavigator.userAgent); if (fields !== null) { isChromeResult = true; chromeVersionResult = extractVersion(fields[1]); } } } return isChromeResult; } function chromeVersion() { return isChrome() && chromeVersionResult; } var isSafariResult; var safariVersionResult; function isSafari() { if (!defined(isSafariResult)) { isSafariResult = false; // Chrome and Edge contain Safari in the user agent too if (!isChrome() && !isEdge() && (/ Safari\/[\.0-9]+/).test(theNavigator.userAgent)) { var fields = (/ Version\/([\.0-9]+)/).exec(theNavigator.userAgent); if (fields !== null) { isSafariResult = true; safariVersionResult = extractVersion(fields[1]); } } } return isSafariResult; } function safariVersion() { return isSafari() && safariVersionResult; } var isWebkitResult; var webkitVersionResult; function isWebkit() { if (!defined(isWebkitResult)) { isWebkitResult = false; var fields = (/ AppleWebKit\/([\.0-9]+)(\+?)/).exec(theNavigator.userAgent); if (fields !== null) { isWebkitResult = true; webkitVersionResult = extractVersion(fields[1]); webkitVersionResult.isNightly = !!fields[2]; } } return isWebkitResult; } function webkitVersion() { return isWebkit() && webkitVersionResult; } var isInternetExplorerResult; var internetExplorerVersionResult; function isInternetExplorer() { if (!defined(isInternetExplorerResult)) { isInternetExplorerResult = false; var fields; if (theNavigator.appName === 'Microsoft Internet Explorer') { fields = /MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(theNavigator.userAgent); if (fields !== null) { isInternetExplorerResult = true; internetExplorerVersionResult = extractVersion(fields[1]); } } else if (theNavigator.appName === 'Netscape') { fields = /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(theNavigator.userAgent); if (fields !== null) { isInternetExplorerResult = true; internetExplorerVersionResult = extractVersion(fields[1]); } } } return isInternetExplorerResult; } function internetExplorerVersion() { return isInternetExplorer() && internetExplorerVersionResult; } var isEdgeResult; var edgeVersionResult; function isEdge() { if (!defined(isEdgeResult)) { isEdgeResult = false; var fields = (/ Edge\/([\.0-9]+)/).exec(theNavigator.userAgent); if (fields !== null) { isEdgeResult = true; edgeVersionResult = extractVersion(fields[1]); } } return isEdgeResult; } function edgeVersion() { return isEdge() && edgeVersionResult; } var isFirefoxResult; var firefoxVersionResult; function isFirefox() { if (!defined(isFirefoxResult)) { isFirefoxResult = false; var fields = /Firefox\/([\.0-9]+)/.exec(theNavigator.userAgent); if (fields !== null) { isFirefoxResult = true; firefoxVersionResult = extractVersion(fields[1]); } } return isFirefoxResult; } var isWindowsResult; function isWindows() { if (!defined(isWindowsResult)) { isWindowsResult = /Windows/i.test(theNavigator.appVersion); } return isWindowsResult; } function firefoxVersion() { return isFirefox() && firefoxVersionResult; } var hasPointerEvents; function supportsPointerEvents() { if (!defined(hasPointerEvents)) { //While navigator.pointerEnabled is deprecated in the W3C specification //we still need to use it if it exists in order to support browsers //that rely on it, such as the Windows WebBrowser control which defines //PointerEvent but sets navigator.pointerEnabled to false. //Firefox disabled because of https://github.com/AnalyticalGraphicsInc/cesium/issues/6372 hasPointerEvents = !isFirefox() && typeof PointerEvent !== 'undefined' && (!defined(theNavigator.pointerEnabled) || theNavigator.pointerEnabled); } return hasPointerEvents; } var imageRenderingValueResult; var supportsImageRenderingPixelatedResult; function supportsImageRenderingPixelated() { if (!defined(supportsImageRenderingPixelatedResult)) { var canvas = document.createElement('canvas'); canvas.setAttribute('style', 'image-rendering: -moz-crisp-edges;' + 'image-rendering: pixelated;'); //canvas.style.imageRendering will be undefined, null or an empty string on unsupported browsers. var tmp = canvas.style.imageRendering; supportsImageRenderingPixelatedResult = defined(tmp) && tmp !== ''; if (supportsImageRenderingPixelatedResult) { imageRenderingValueResult = tmp; } } return supportsImageRenderingPixelatedResult; } function imageRenderingValue() { return supportsImageRenderingPixelated() ? imageRenderingValueResult : undefined; } function supportsWebP() { //>>includeStart('debug', pragmas.debug); if (!supportsWebP.initialized) { throw new DeveloperError('You must call FeatureDetection.supportsWebP.initialize and wait for the promise to resolve before calling FeatureDetection.supportsWebP'); } //>>includeEnd('debug'); return supportsWebP._result; } supportsWebP._promise = undefined; supportsWebP._result = undefined; supportsWebP.initialize = function() { // From https://developers.google.com/speed/webp/faq#how_can_i_detect_browser_support_for_webp if (defined(supportsWebP._promise)) { return supportsWebP._promise; } var supportsWebPDeferred = when.defer(); supportsWebP._promise = supportsWebPDeferred.promise; if (isEdge()) { // Edge's WebP support with WebGL is incomplete. // See bug report: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/19221241/ supportsWebP._result = false; supportsWebPDeferred.resolve(supportsWebP._result); return supportsWebPDeferred.promise; } var image = new Image(); image.onload = function () { supportsWebP._result = (image.width > 0) && (image.height > 0); supportsWebPDeferred.resolve(supportsWebP._result); }; image.onerror = function () { supportsWebP._result = false; supportsWebPDeferred.resolve(supportsWebP._result); }; image.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA'; return supportsWebPDeferred.promise; }; defineProperties(supportsWebP, { initialized: { get: function() { return defined(supportsWebP._result); } } }); var typedArrayTypes = []; if (typeof ArrayBuffer !== 'undefined') { typedArrayTypes.push(Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array); if (typeof Uint8ClampedArray !== 'undefined') { typedArrayTypes.push(Uint8ClampedArray); } if (typeof CanvasPixelArray !== 'undefined') { typedArrayTypes.push(CanvasPixelArray); } } /** * A set of functions to detect whether the current browser supports * various features. * * @exports FeatureDetection */ var FeatureDetection = { isChrome : isChrome, chromeVersion : chromeVersion, isSafari : isSafari, safariVersion : safariVersion, isWebkit : isWebkit, webkitVersion : webkitVersion, isInternetExplorer : isInternetExplorer, internetExplorerVersion : internetExplorerVersion, isEdge : isEdge, edgeVersion : edgeVersion, isFirefox : isFirefox, firefoxVersion : firefoxVersion, isWindows : isWindows, hardwareConcurrency : defaultValue(theNavigator.hardwareConcurrency, 3), supportsPointerEvents : supportsPointerEvents, supportsImageRenderingPixelated: supportsImageRenderingPixelated, supportsWebP: supportsWebP, imageRenderingValue: imageRenderingValue, typedArrayTypes: typedArrayTypes }; /** * Detects whether the current browser supports the full screen standard. * * @returns {Boolean} true if the browser supports the full screen standard, false if not. * * @see Fullscreen * @see {@link http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html|W3C Fullscreen Living Specification} */ FeatureDetection.supportsFullscreen = function() { return Fullscreen.supportsFullscreen(); }; /** * Detects whether the current browser supports typed arrays. * * @returns {Boolean} true if the browser supports typed arrays, false if not. * * @see {@link http://www.khronos.org/registry/typedarray/specs/latest/|Typed Array Specification} */ FeatureDetection.supportsTypedArrays = function() { return typeof ArrayBuffer !== 'undefined'; }; /** * Detects whether the current browser supports Web Workers. * * @returns {Boolean} true if the browsers supports Web Workers, false if not. * * @see {@link http://www.w3.org/TR/workers/} */ FeatureDetection.supportsWebWorkers = function() { return typeof Worker !== 'undefined'; }; /** * Detects whether the current browser supports Web Assembly. * * @returns {Boolean} true if the browsers supports Web Assembly, false if not. * * @see {@link https://developer.mozilla.org/en-US/docs/WebAssembly} */ FeatureDetection.supportsWebAssembly = function() { return typeof WebAssembly !== 'undefined' && !FeatureDetection.isEdge(); }; export default FeatureDetection;