From 812d294e42956902dc85cd534e0ab3afbf52e8c2 Mon Sep 17 00:00:00 2001 From: Jason Stirnaman Date: Tue, 13 May 2025 15:59:27 -0500 Subject: [PATCH] ### Refactor keybindings to a component and replace deprecated detection method - Extracted platform detection to its own reusable utility module - Eliminates deprecated Navigator.platform API usage; uses the User-Agent Client Hints API as the primary method when available - Handles iOS and Android devices correctly --- assets/js/keybindings.js | 64 +++++++++++++++----------- assets/js/utils/user-agent-platform.js | 29 ++++++++++++ 2 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 assets/js/utils/user-agent-platform.js diff --git a/assets/js/keybindings.js b/assets/js/keybindings.js index 6048e899c..ce0449e96 100644 --- a/assets/js/keybindings.js +++ b/assets/js/keybindings.js @@ -1,42 +1,52 @@ -// Dynamically update keybindings or hotkeys -function getPlatform() { - if (/Mac/.test(navigator.platform)) { - return "osx" - } else if (/Win/.test(navigator.platform)) { - return "win" - } else if (/Linux/.test(navigator.platform)) { - return "linux" - } else { - return "other" - } -} +import { getPlatform } from './utils/user-agent-platform.js'; +/** + * Adds OS-specific class to component + * @param {string} osClass - OS-specific class to add + * @param {Object} options - Component options + * @param {jQuery} options.$component - jQuery element reference + */ function addOSClass(osClass, { $component }) { - $component.addClass(osClass) + $component.addClass(osClass); } -function updateKeyBindings({ $component }) { - var osx = $component.data("osx") - var linux = $component.data("linux") - var win = $component.data("win") +/** + * Updates keybinding display based on detected platform + * @param {Object} options - Component options + * @param {jQuery} options.$component - jQuery element reference + * @param {string} options.platform - Detected platform + */ +function updateKeyBindings({ $component, platform }) { + const osx = $component.data('osx'); + const linux = $component.data('linux'); + const win = $component.data('win'); + + let keybind; - if (platform === "other") { - if (win != linux) { - var keybind = '' + osx + ' for macOS, ' + linux + ' for Linux, and ' + win + ' for Windows'; - } else { - var keybind = '' + linux + ' for Linux and Windows and ' + osx + ' for macOS'; - } + if (platform === 'other') { + if (win !== linux) { + keybind = `${osx} for macOS, ${linux} for Linux, and ${win} for Windows`; } else { - var keybind = '' + $component.data(platform) + '' + keybind = `${linux} for Linux and Windows and ${osx} for macOS`; } + } else { + keybind = `${$component.data(platform)}`; + } - $component.html(keybind) + $component.html(keybind); } +/** + * Initialize and render platform-specific keybindings + * @param {Object} options - Component options + * @param {HTMLElement} options.component - DOM element + * @returns {void} + */ export default function KeyBinding({ component }) { // Initialize keybindings const platform = getPlatform(); const $component = $(component); + addOSClass(platform, { $component }); - updateKeyBindings({ $component }); -} + updateKeyBindings({ $component, platform }); +} \ No newline at end of file diff --git a/assets/js/utils/user-agent-platform.js b/assets/js/utils/user-agent-platform.js new file mode 100644 index 000000000..ffb1407e0 --- /dev/null +++ b/assets/js/utils/user-agent-platform.js @@ -0,0 +1,29 @@ +/** + * Platform detection utility functions + * Provides methods for detecting user's operating system + */ + +/** + * Detects user's operating system using modern techniques + * Falls back to userAgent parsing when newer APIs aren't available + * @returns {string} Operating system identifier ("osx", "win", "linux", or "other") + */ +export function getPlatform() { + // Try to use modern User-Agent Client Hints API first (Chrome 89+, Edge 89+) + if (navigator.userAgentData && navigator.userAgentData.platform) { + const platform = navigator.userAgentData.platform.toLowerCase(); + + if (platform.includes('mac')) return 'osx'; + if (platform.includes('win')) return 'win'; + if (platform.includes('linux')) return 'linux'; + } + + // Fall back to userAgent string parsing + const userAgent = navigator.userAgent.toLowerCase(); + + if (userAgent.includes('mac') || userAgent.includes('iphone') || userAgent.includes('ipad')) return 'osx'; + if (userAgent.includes('win')) return 'win'; + if (userAgent.includes('linux') || userAgent.includes('android')) return 'linux'; + + return 'other'; +} \ No newline at end of file