UI: Implement JavaScript getOS function Windows platform architecture detection #104136

Merged
Márton Lente merged 15 commits from get-os-win-arm into main 2024-11-08 12:03:41 +01:00
2 changed files with 164 additions and 97 deletions

View File

@ -1,75 +1,132 @@
/* Code modified from VLC's website. /* Code modified from VLC's website.
* https://code.videolan.org/VideoLAN.org/websites/-/blob/master/www.videolan.org/include/os-specific.php * 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) { function getOSPlaformVersion() {
if (navigator.userAgent.indexOf('Windows NT 5.0') == -1 && //MacOS, MacOS X, macOS
navigator.userAgent.indexOf('Windows NT 5.1') == -1 && if (navigator.appVersion.indexOf("Mac") != -1) {
(navigator.userAgent.indexOf('Win64') > -1 || if (navigator.platform.indexOf("MacPPC") != -1 || navigator.platform.indexOf("PowerPC") != -1) {
navigator.platform == 'Win64' || OS = "macos-PPC";
navigator.userAgent.indexOf('x86_64') > -1 || } else if (navigator.userAgent.indexOf("OS X 10.5") != -1 ||
navigator.userAgent.indexOf('x86_64') > -1 || navigator.userAgent.indexOf("OS X 10.6") != -1) {
navigator.userAgent.indexOf('amd64') > -1 || OS = "macos-32";
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 { } else {
OS = "macos";
try { try {
var canvas = document.createElement('canvas'); var glcontext = document.createElement("canvas").getContext("webgl");
var gl = canvas.getContext('webgl'); var debugrenderer = glcontext ? glcontext.getExtension('WEBGL_debug_renderer_info') : null;
var renderername = debugrenderer && glcontext.getParameter(debugrenderer.UNMASKED_RENDERER_WEBGL) || "";
var debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); if (renderername.match(/Apple M/) || renderername.match(/Apple GPU/)) {
var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); OS = "macos-apple-silicon";
if (renderer.indexOf("Qualcomm") !== -1) }
OS = "windows-arm";
} catch (e) {} } 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 // Create functions init
if (navigator.appVersion.indexOf("Mac") != -1) { async function init() {
if (navigator.platform.indexOf("MacPPC") != -1 || navigator.platform.indexOf("PowerPC") != -1) { // Check if the browser method 'navigator.userAgentData' is supported
OS = "macos-PPC"; if (navigator.userAgentData && typeof navigator.userAgentData.getHighEntropyValues == 'function') {
} else if (navigator.userAgent.indexOf("OS X 10.5") != -1 || return await initAsync();
navigator.userAgent.indexOf("OS X 10.6") != -1) {
OS = "macos-32";
} else { } else {
OS = "macos"; return initSync();
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) {}
} }
} }
if (navigator.platform.indexOf("Linux") != -1) {
if ((navigator.userAgent.indexOf("Ubuntu") != -1) || // Create function initAsync for browsers that support navigator.userAgentData (e.g. Chromium-based browsers)
(navigator.userAgent.indexOf("ubuntu") != -1)) OS = "linux-ubuntu"; async function initAsync() {
else if (navigator.userAgent.indexOf("Debian") != -1) OS = "linux-debian"; try {
else if (navigator.userAgent.indexOf("Android") != -1) OS = "linux-android"; /* Code modified from Microsoft's website.
else if (navigator.userAgent.indexOf("Mandriva") != -1) OS = "linux-mandriva"; * https://learn.microsoft.com/en-us/microsoft-edge/web-platform/how-to-detect-win11#sample-code-for-detecting-arm-or-x86
else if (navigator.userAgent.indexOf("Red Hat") != -1) OS = "linux-redhat"; */
else if (navigator.userAgent.indexOf("Fedora") != -1) OS = "linux-fedora"; // Wait for and get the high entropy values from async method
else if (navigator.userAgent.indexOf("SUSE") != -1) OS = "linux-suse"; let ua = await navigator.userAgentData.getHighEntropyValues(["architecture", "bitness"]);
else if (navigator.userAgent.indexOf("Gentoo") != -1) OS = "linux-gentoo";
else OS = "linux"; // 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) { // Create function initSync for browsers that don't support navigator.userAgentData (e.g. Gecko-based browsers)
OS = "ios"; function initSync() {
} if (navigator.appVersion.indexOf("Win") != -1) {
if (navigator.platform.indexOf("freebsd") != -1) OS = "freebsd"; if (navigator.userAgent.indexOf('Windows NT 5.0') == -1 &&
if (navigator.platform.indexOf("FreeBSD") != -1) OS = "freebsd"; 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();
} }

View File

@ -324,58 +324,68 @@ $analytics_event_name = 'Downloads+Blender';
let downloadButtons = document.getElementsByClassName('dl-os-windows'); let downloadButtons = document.getElementsByClassName('dl-os-windows');
/* Get the current operating system. See get_os.js */ /* Get the current operating system. See get_os.js */
let os = getOS(); let os;
/* Windows. */ /* Call async IIFE to await async function 'getOS' */
if (os == 'windows') { (async function() {
showPlatformWarning('This Windows version might not be supported.'); os = await getOS();
}
else if (os == 'windows-arm') {
showPlatformWarning('Blender is not available for Windows ARM architecture yet.');
}
/* Linux. */
else if (os.startsWith('linux') || os.startsWith('freebsd')) {
/* Set the Download button platform to Linux. */ /* Windows. */
downloadButtons = document.getElementsByClassName('dl-os-linux'); if (os == 'windows') {
showPlatformWarning('This Windows version might not be supported.');
if (os == 'freebsd') {
showPlatformWarning('There are no official builds for FreeBSD yet.');
} }
}
/* macOS. */
else if (os.startsWith('macos') || os.startsWith('ios')) {
/* Set the Download button platform to macOS. */ /* Windows Arm. */
downloadButtons = document.getElementsByClassName('dl-os-macos'); 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') { /* Linux. */
downloadButtons = document.getElementsByClassName('dl-os-macos-apple-silicon'); 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, /* Set the Download button platform to Linux. */
* Show Download buttons for both systems for the time being until navigator.gpu is supported. */ downloadButtons = document.getElementsByClassName('dl-os-linux');
let is_safari = navigator.userAgent.indexOf('Safari') > -1 && navigator.userAgent.indexOf('Chrome') <= -1;
if (is_safari) { if (os == 'freebsd') {
downloadButtons = document.querySelectorAll('[class^="dl-header-cta dl-os-macos"]'); 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') { /* macOS. */
showPlatformWarning('Blender is not available for iOS yet.'); 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. */ /* Show the Download button for the current OS. */
for (var i = 0; i < downloadButtons.length; i++) { for (var i = 0; i < downloadButtons.length; i++) {
downloadButtons[i].style.display = 'block'; downloadButtons[i].style.display = 'block';
downloadButtons[i].classList.add('active'); 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. */ /* Click anywhere on the page to hide these popups. */
$(document).click(function () { $(document).click(function () {