diff --git a/themes/bthree/assets/js/get_os.js b/themes/bthree/assets/js/get_os.js index c88f0b9..7598e24 100644 --- a/themes/bthree/assets/js/get_os.js +++ b/themes/bthree/assets/js/get_os.js @@ -1,75 +1,132 @@ /* Code modified from VLC's website. * https://code.videolan.org/VideoLAN.org/websites/-/blob/master/www.videolan.org/include/os-specific.php */ -function getOS() { - var OS = "windows"; //Default +/* + * Function 'getOS' must be asynchronous to support the async browser method 'navigator.userAgentData.getHighEntropyValues' and nested promise chains. + */ +async function getOS() { + // Init variable OS default + let OS = "windows"; - if (navigator.appVersion.indexOf("Win") != -1) { - if (navigator.userAgent.indexOf('Windows NT 5.0') == -1 && - navigator.userAgent.indexOf('Windows NT 5.1') == -1 && - (navigator.userAgent.indexOf('Win64') > -1 || - navigator.platform == 'Win64' || - navigator.userAgent.indexOf('x86_64') > -1 || - navigator.userAgent.indexOf('x86_64') > -1 || - navigator.userAgent.indexOf('amd64') > -1 || - navigator.userAgent.indexOf('AMD64') > -1 || - navigator.userAgent.indexOf('WOW64') > -1 - )) { - OS = "windows-64"; - } else { - if (window.external && window.external.getHostEnvironmentValue && window.external.getHostEnvironmentValue('os-architecture').indexOf("ARM64") !== -1) { - OS = "windows-arm"; + function getOSPlaformVersion() { + //MacOS, MacOS X, macOS + if (navigator.appVersion.indexOf("Mac") != -1) { + if (navigator.platform.indexOf("MacPPC") != -1 || navigator.platform.indexOf("PowerPC") != -1) { + OS = "macos-PPC"; + } else if (navigator.userAgent.indexOf("OS X 10.5") != -1 || + navigator.userAgent.indexOf("OS X 10.6") != -1) { + OS = "macos-32"; } else { + OS = "macos"; try { - var canvas = document.createElement('canvas'); - var gl = canvas.getContext('webgl'); - - var debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); - var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); - if (renderer.indexOf("Qualcomm") !== -1) - OS = "windows-arm"; + var glcontext = document.createElement("canvas").getContext("webgl"); + var debugrenderer = glcontext ? glcontext.getExtension('WEBGL_debug_renderer_info') : null; + var renderername = debugrenderer && glcontext.getParameter(debugrenderer.UNMASKED_RENDERER_WEBGL) || ""; + if (renderername.match(/Apple M/) || renderername.match(/Apple GPU/)) { + OS = "macos-apple-silicon"; + } } catch (e) {} } } + + // Linux + if (navigator.platform.indexOf("Linux") != -1) { + if ((navigator.userAgent.indexOf("Ubuntu") != -1) || + (navigator.userAgent.indexOf("ubuntu") != -1)) OS = "linux-ubuntu"; + else if (navigator.userAgent.indexOf("Debian") != -1) OS = "linux-debian"; + else if (navigator.userAgent.indexOf("Android") != -1) OS = "linux-android"; + else if (navigator.userAgent.indexOf("Mandriva") != -1) OS = "linux-mandriva"; + else if (navigator.userAgent.indexOf("Red Hat") != -1) OS = "linux-redhat"; + else if (navigator.userAgent.indexOf("Fedora") != -1) OS = "linux-fedora"; + else if (navigator.userAgent.indexOf("SUSE") != -1) OS = "linux-suse"; + else if (navigator.userAgent.indexOf("Gentoo") != -1) OS = "linux-gentoo"; + else OS = "linux"; + } + + // iOS + if (navigator.userAgent.indexOf("iPad") != -1 || navigator.userAgent.indexOf("iPhone") != -1 || navigator.userAgent.indexOf("iPod") != -1) { + OS = "ios"; + } + + // FreeBSD + if (navigator.platform.indexOf("freebsd") != -1) OS = "freebsd"; + if (navigator.platform.indexOf("FreeBSD") != -1) OS = "freebsd"; + + return OS; } - //MacOS, MacOS X, macOS - if (navigator.appVersion.indexOf("Mac") != -1) { - if (navigator.platform.indexOf("MacPPC") != -1 || navigator.platform.indexOf("PowerPC") != -1) { - OS = "macos-PPC"; - } else if (navigator.userAgent.indexOf("OS X 10.5") != -1 || - navigator.userAgent.indexOf("OS X 10.6") != -1) { - OS = "macos-32"; + // Create functions init + async function init() { + // Check if the browser method 'navigator.userAgentData' is supported + if (navigator.userAgentData && typeof navigator.userAgentData.getHighEntropyValues == 'function') { + return await initAsync(); } else { - OS = "macos"; - try { - var glcontext = document.createElement("canvas").getContext("webgl"); - var debugrenderer = glcontext ? glcontext.getExtension('WEBGL_debug_renderer_info') : null; - var renderername = debugrenderer && glcontext.getParameter(debugrenderer.UNMASKED_RENDERER_WEBGL) || ""; - if (renderername.match(/Apple M/) || renderername.match(/Apple GPU/)) { - OS = "macos-apple-silicon"; - } - } catch (e) {} + return initSync(); } } - if (navigator.platform.indexOf("Linux") != -1) { - if ((navigator.userAgent.indexOf("Ubuntu") != -1) || - (navigator.userAgent.indexOf("ubuntu") != -1)) OS = "linux-ubuntu"; - else if (navigator.userAgent.indexOf("Debian") != -1) OS = "linux-debian"; - else if (navigator.userAgent.indexOf("Android") != -1) OS = "linux-android"; - else if (navigator.userAgent.indexOf("Mandriva") != -1) OS = "linux-mandriva"; - else if (navigator.userAgent.indexOf("Red Hat") != -1) OS = "linux-redhat"; - else if (navigator.userAgent.indexOf("Fedora") != -1) OS = "linux-fedora"; - else if (navigator.userAgent.indexOf("SUSE") != -1) OS = "linux-suse"; - else if (navigator.userAgent.indexOf("Gentoo") != -1) OS = "linux-gentoo"; - else OS = "linux"; + + // Create function initAsync for browsers that support navigator.userAgentData (e.g. Chromium-based browsers) + async function initAsync() { + try { + /* Code modified from Microsoft's website. + * https://learn.microsoft.com/en-us/microsoft-edge/web-platform/how-to-detect-win11#sample-code-for-detecting-arm-or-x86 + */ + // Wait for and get the high entropy values from async method + let ua = await navigator.userAgentData.getHighEntropyValues(["architecture", "bitness"]); + + // Check if the platform is Windows + if (navigator.userAgentData.platform === "Windows") { + if (ua.architecture === 'arm') { + OS = "windows-arm"; + } else { + if (ua.bitness === '64') { + OS = "windows-64"; + } + } + } else { + // Check other platforms + OS = getOSPlaformVersion(); + } + + return OS; + } catch (e) {} } - if (navigator.userAgent.indexOf("iPad") != -1 || navigator.userAgent.indexOf("iPhone") != -1 || navigator.userAgent.indexOf("iPod") != -1) { - OS = "ios"; - } - if (navigator.platform.indexOf("freebsd") != -1) OS = "freebsd"; - if (navigator.platform.indexOf("FreeBSD") != -1) OS = "freebsd"; + // Create function initSync for browsers that don't support navigator.userAgentData (e.g. Gecko-based browsers) + function initSync() { + if (navigator.appVersion.indexOf("Win") != -1) { + if (navigator.userAgent.indexOf('Windows NT 5.0') == -1 && + navigator.userAgent.indexOf('Windows NT 5.1') == -1 && + (navigator.userAgent.indexOf('Win64') > -1 || + navigator.platform == 'Win64' || + navigator.userAgent.indexOf('x86_64') > -1 || + navigator.userAgent.indexOf('x86_64') > -1 || + navigator.userAgent.indexOf('amd64') > -1 || + navigator.userAgent.indexOf('AMD64') > -1 || + navigator.userAgent.indexOf('WOW64') > -1 + )) { + OS = "windows-64"; + } else { + if (window.external && window.external.getHostEnvironmentValue && window.external.getHostEnvironmentValue('os-architecture').indexOf("ARM64") !== -1) { + OS = "windows-arm"; + } else { + try { + var canvas = document.createElement('canvas'); + var gl = canvas.getContext('webgl'); - return OS; + var debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); + var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); + if (renderer.indexOf("Qualcomm") !== -1) + OS = "windows-arm"; + } catch (e) {} + } + } + } else { + OS = getOSPlaformVersion(); + } + + return OS; + } + + return await init(); } diff --git a/themes/bthree/page-download.php b/themes/bthree/page-download.php index d5d3ead..7f77840 100644 --- a/themes/bthree/page-download.php +++ b/themes/bthree/page-download.php @@ -324,58 +324,68 @@ $analytics_event_name = 'Downloads+Blender'; let downloadButtons = document.getElementsByClassName('dl-os-windows'); /* Get the current operating system. See get_os.js */ - let os = getOS(); + let os; - /* Windows. */ - if (os == 'windows') { - showPlatformWarning('This Windows version might not be supported.'); - } - else if (os == 'windows-arm') { - showPlatformWarning('Blender is not available for Windows ARM architecture yet.'); - } - /* Linux. */ - else if (os.startsWith('linux') || os.startsWith('freebsd')) { + /* Call async IIFE to await async function 'getOS' */ + (async function() { + os = await getOS(); - /* Set the Download button platform to Linux. */ - downloadButtons = document.getElementsByClassName('dl-os-linux'); - - if (os == 'freebsd') { - showPlatformWarning('There are no official builds for FreeBSD yet.'); + /* Windows. */ + if (os == 'windows') { + showPlatformWarning('This Windows version might not be supported.'); } - } - /* macOS. */ - else if (os.startsWith('macos') || os.startsWith('ios')) { - /* Set the Download button platform to macOS. */ - downloadButtons = document.getElementsByClassName('dl-os-macos'); + /* Windows Arm. */ + else if (os == 'windows-arm') { + /* Set the Download button platform to Windows Arm. */ + downloadButtons = document.getElementsByClassName('dl-os-windows-arm'); + } - if (os == 'macos-apple-silicon') { - downloadButtons = document.getElementsByClassName('dl-os-macos-apple-silicon'); + /* Linux. */ + else if (os.startsWith('linux') || os.startsWith('freebsd')) { - /* Safari does not have a reliable way to detect if the system is Intel or Apple Silicon, - * Show Download buttons for both systems for the time being until navigator.gpu is supported. */ - let is_safari = navigator.userAgent.indexOf('Safari') > -1 && navigator.userAgent.indexOf('Chrome') <= -1; + /* Set the Download button platform to Linux. */ + downloadButtons = document.getElementsByClassName('dl-os-linux'); - if (is_safari) { - downloadButtons = document.querySelectorAll('[class^="dl-header-cta dl-os-macos"]'); + if (os == 'freebsd') { + showPlatformWarning('There are no official builds for FreeBSD yet.'); } - } else if (os == 'macos-32' || os == 'macos-PPC') { - showPlatformWarning('This macOS version might not be supported.'); } - else if (os == 'ios') { - showPlatformWarning('Blender is not available for iOS yet.'); + /* macOS. */ + else if (os.startsWith('macos') || os.startsWith('ios')) { + + /* Set the Download button platform to macOS. */ + downloadButtons = document.getElementsByClassName('dl-os-macos'); + + if (os == 'macos-apple-silicon') { + downloadButtons = document.getElementsByClassName('dl-os-macos-apple-silicon'); + + /* Safari does not have a reliable way to detect if the system is Intel or Apple Silicon, + * Show Download buttons for both systems for the time being until navigator.gpu is supported. */ + let is_safari = navigator.userAgent.indexOf('Safari') > -1 && navigator.userAgent.indexOf('Chrome') <= -1; + + if (is_safari) { + downloadButtons = document.querySelectorAll('[class^="dl-header-cta dl-os-macos"]'); + } + } else if (os == 'macos-32' || os == 'macos-PPC') { + showPlatformWarning('This macOS version might not be supported.'); + } + else if (os == 'ios') { + showPlatformWarning('Blender is not available for iOS yet.'); + } } - } - /* Show the Download button for the current OS. */ - for (var i = 0; i < downloadButtons.length; i++) { - downloadButtons[i].style.display = 'block'; - downloadButtons[i].classList.add('active'); - } + /* Show the Download button for the current OS. */ + for (var i = 0; i < downloadButtons.length; i++) { + downloadButtons[i].style.display = 'block'; + downloadButtons[i].classList.add('active'); + } + + /* Style the other platforms button, so we can highlight alternative builds on the same platform. */ + $('#menu-other-platforms').addClass('dl-other-list-os-' + os); + $('.dl-header-other').addClass('current-os-' + os); + })(); - /* Style the other platforms button, so we can highlight alternative builds on the same platform. */ - $('#menu-other-platforms').addClass('dl-other-list-os-' + os); - $('.dl-header-other').addClass('current-os-' + os); /* Click anywhere on the page to hide these popups. */ $(document).click(function () {