-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a special Mod
modifier that translates to either Meta
on Mac or Control
on other platforms
#66
Changes from all commits
15a2349
272e313
89b6475
0daa605
bf39656
846a166
796e5b9
6e85b53
10b7698
eb49074
d4be521
5f69e39
8705871
4ab901f
867d12e
b14ab35
9bb0699
96eb941
f9dc082
2a61fcb
9171795
730ed3e
70ca175
6693f1f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* Normalizes a hotkey string before comparing it to the serialized event | ||
* string produced by `eventToHotkeyString`. | ||
* - Replaces the `Mod` modifier with `Meta` on mac, `Control` on other | ||
* platforms. | ||
* - Ensures modifiers are sorted in a consistent order | ||
* @param hotkey a hotkey string | ||
* @param platform NOTE: this param is only intended to be used to mock `navigator.platform` in tests | ||
* @returns {string} normalized representation of the given hotkey string | ||
*/ | ||
export function normalizeHotkey(hotkey: string, platform?: string | undefined): string { | ||
let result: string | ||
result = localizeMod(hotkey, platform) | ||
result = sortModifiers(result) | ||
return result | ||
} | ||
|
||
const matchApplePlatform = /Mac|iPod|iPhone|iPad/i | ||
|
||
function localizeMod(hotkey: string, platform: string = navigator.platform): string { | ||
const localModifier = matchApplePlatform.test(platform) ? 'Meta' : 'Control' | ||
return hotkey.replace('Mod', localModifier) | ||
} | ||
|
||
function sortModifiers(hotkey: string): string { | ||
const key = hotkey.split('+').pop() | ||
const modifiers = [] | ||
for (const modifier of ['Control', 'Alt', 'Meta', 'Shift']) { | ||
if (hotkey.includes(modifier)) { | ||
modifiers.push(modifier) | ||
} | ||
} | ||
modifiers.push(key) | ||
return modifiers.join('+') | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import {normalizeHotkey} from '../dist/index.js' | ||
|
||
describe('normalizeHotkey', () => { | ||
it('should exist', () => { | ||
assert.isDefined(normalizeHotkey) | ||
}) | ||
|
||
const tests = [ | ||
// Base case control tests | ||
['a', 'a'], | ||
['Control+a', 'Control+a'], | ||
['Meta+a', 'Meta+a'], | ||
['Control+Meta+a', 'Control+Meta+a'], | ||
// Mod should be localized based on platform | ||
['Mod+a', 'Control+a', 'win / linux'], | ||
['Mod+a', 'Meta+a', 'mac'], | ||
['Mod+a', 'Meta+a', 'iPod'], | ||
['Mod+a', 'Meta+a', 'iPhone'], | ||
['Mod+a', 'Meta+a', 'iPad'], | ||
['Mod+A', 'Control+A', 'win / linux'], | ||
['Mod+A', 'Meta+A', 'mac'], // TODO: on a mac upper-case keys are lowercased when Meta is pressed | ||
['Mod+9', 'Control+9', 'win / linux'], | ||
['Mod+9', 'Meta+9', 'mac'], | ||
['Mod+)', 'Control+)', 'win / linux'], | ||
['Mod+)', 'Meta+)', 'mac'], // TODO: on a mac upper-case keys are lowercased when Meta is pressed | ||
['Mod+Alt+a', 'Control+Alt+a', 'win / linux'], | ||
['Mod+Alt+a', 'Alt+Meta+a', 'mac'], | ||
// Modifier sorting | ||
['Shift+Alt+Meta+Control+m', 'Control+Alt+Meta+Shift+m'], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know this test is only meant to demonstrate sorting works but wondering if we should exclude this given it's invalid. Or maybe we can add a note that this is invalid along with note to not use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is valid to have shortcuts that pair ✅ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right, it's technically valid on mac! |
||
['Shift+Alt+Mod+m', 'Control+Alt+Shift+m', 'win'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we include linux in these tests to demonstrate that it is considered, as noted in the README? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can make this change for sure! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
] | ||
|
||
for (const [input, expected, platform = 'any platform'] of tests) { | ||
it(`given "${input}", returns "${expected}" on ${platform}`, function (done) { | ||
assert.equal(normalizeHotkey(input, platform), expected) | ||
done() | ||
}) | ||
} | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super nitpick,
control
on Android as well? I'm not really familiar with that ecosystemThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think technically Android is Linux, so that might cover it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, right -- that's fair! I've read enough "Android isn't REAL Linux" stuff on the internet I completely forgot about this 😆