1// assets/js/utility-scripts/detect-device-os-universal.js 2 3(function() { 4 async function initGreenDownload() { 5 let platform, os, architecture; 6 7 try { 8 let userData = await navigator.userAgentData.getHighEntropyValues(["architecture"]); 9 platform = userData.platform; 10 architecture = userData.architecture; 11 } catch(e) { 12 platform = window.navigator?.userAgentData?.platform || window.navigator.platform; 13 } 14 15 var userAgent = window.navigator.userAgent, 16 macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K', 'macOS'], 17 windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'], 18 iosPlatforms = ['iPhone', 'iPad', 'iPod']; 19 20 if (macosPlatforms.indexOf(platform) !== -1) { 21 if (architecture == "x86") 22 os = 'Mac_x86'; 23 else if (architecture == "arm") 24 os = 'Mac_ARM'; 25 else 26 os = 'Mac'; 27 } else if (iosPlatforms.indexOf(platform) !== -1) { 28 os = 'iOS'; 29 } else if (windowsPlatforms.indexOf(platform) !== -1) { 30 os = 'Windows'; 31 } else if (/Android/.test(userAgent)) { 32 os = 'Android'; 33 } else if (/Linux/.test(platform)) { 34 os = 'Linux'; 35 } 36 37 // Process all green download components on the page 38 const greenDownloadComponents = document.querySelectorAll('[data-green-download]'); 39 40 greenDownloadComponents.forEach(component => { 41 const dropdownTrigger = component.querySelector('[data-role="dropdown-trigger"]'); 42 const macX86Button = component.querySelector('[data-role="mac_x86"]'); 43 const macArmButton = component.querySelector('[data-role="mac_arm"]'); 44 const iosButton = component.querySelector('[data-role="ios"]'); 45 const windowsButton = component.querySelector('[data-role="windows"]'); 46 const androidDropdown = component.querySelector('[data-role="android"]'); 47 const linuxDropdown = component.querySelector('[data-role="linux"]'); 48 const allDropdown = component.querySelector('[data-role="all"]'); 49 50 // Hide dropdown trigger by default 51 if (dropdownTrigger) dropdownTrigger.style.display = "none"; 52 53 switch (os) { 54 case "Mac_x86": 55 if (macX86Button) macX86Button.style.display = "flex"; 56 break; 57 case "Mac_ARM": 58 if (macArmButton) macArmButton.style.display = "flex"; 59 break; 60 case "Mac": 61 if (macX86Button) macX86Button.style.display = "flex"; 62 break; 63 case "iOS": 64 if (iosButton) iosButton.style.display = "flex"; 65 break; 66 case "Windows": 67 if (windowsButton) windowsButton.style.display = "flex"; 68 break; 69 case "Android": 70 if (androidDropdown) androidDropdown.style.display = "flex"; 71 break; 72 case "Linux": 73 if (linuxDropdown) linuxDropdown.style.display = "flex"; 74 break; 75 default: 76 if (allDropdown) allDropdown.style.display = "flex"; 77 } 78 }); 79 80 // Set up click prevention for all dropdown triggers 81 const allDropdownTriggers = document.querySelectorAll('[data-role="dropdown-trigger"], .dropdown-trigger'); 82 allDropdownTriggers.forEach(trigger => { 83 trigger.addEventListener("click", function(e) { 84 e.preventDefault(); 85 }); 86 }); 87 88 // Set up pixel tracking 89 const downloadButtons = document.querySelectorAll('.greenDownload .dropdown-item, .greenDownload .green-download-button, .greenDownload .green-mac-download'); 90 downloadButtons.forEach(button => button.addEventListener("click", pixelTrigger)); 91 } 92 93 let pixelTriggered = false;
94 function pixelTrigger(e) { 95 if (!pixelTriggered) { 96 pixelTriggered = true; 97 let platform = e.target.closest('[data-green-download]')?.getAttribute('data-green-download') || 'unknown'; 98 99 // X pixel 100 if (typeof twq !== 'undefined') { 101 twq('event', 'tw-ondrb-ondrc', { 102 contents: [{ 103 content_type: 'green download', 104 content_id: null, 105 content_name: 'green download', 106 content_price: null, 107 num_items: 1, 108 content_group_id: null 109 }], 110 platform: platform, 111 }); 112 } 113 114 // Reddit pixel 115 if (typeof rdt !== 'undefined') { 116 rdt('track', 'Custom', { 117 customEventName: 'Green download', 118 }); 119 } 120 } 121 } 122 123 function showAllDownloadOptions(componentSelector) { 124 const component = document.querySelector(componentSelector || '[data-green-download]'); 125 if (!component) return; 126 127 // Hide all platform-specific elements 128 const elementsToHide = ['mac', 'mac_x86', 'mac_arm', 'ios', 'windows', 'android', 'linux']; 129 elementsToHide.forEach(role => { 130 const element = component.querySelector(`[data-role="${role}"]`); 131 if (element) element.style.display = "none"; 132 }); 133 134 // Show all options 135 const allDropdown = component.querySelector('[data-role="all"]'); 136 if (allDropdown) allDropdown.style.display = "flex"; 137 } 138 139 // Make the function globally available 140 window.showAllDownloadOptions = showAllDownloadOptions; 141 142 // Initialize when DOM is ready 143 if (document.readyState === 'loading') { 144 document.addEventListener('DOMContentLoaded', initGreenDownload); 145 } else { 146 initGreenDownload(); 147 } 148})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.