Open keithamus opened 7 years ago
I would love to see this addressed in the platform.
Currently, many libraries like CodeMirror must rely on platform detection. https://github.com/codemirror/codemirror5/blob/5.65.9/src/edit/key_events.js#L120
In my own experience, I have noticed smaller libraries appear often unaware of this interop issue and either listen to one modifier or the other. When the issue is brought to their attention by users of apple or non-apple devices, authors quickly patch the issue by listening to both meta and control keys simultaneously. This unfortunately locks users into there only ever being two possible answers on two possible platforms (apple and non-apple).
MDN docs mention navigation.platform
as the “least-bad” option “when you need to show users advice about whether the modifier key for keyboard shortcuts is the ⌘ command key (found on Apple systems) rather than the ⌃ control key (on non-Apple systems).”
The accepted StackOverflow answer on this subject begins “Unfortunately at this time there is no JavaScript API for detecting if the host OS uses the Ctrl key or the Cmd key for keyboard shortcuts.”
I would suggest adding a new boolean key to KeyboardEvent
; modifierKey
. It would, effectively, map to the following speculative polyfill:
const isApplePlatform = navigator.platform === 'MacIntel' || navigator.platform === 'iPhone'
const modifierKey = isApplePlatform ? 'metaKey' : 'ctrlKey'
const modifierKeyDescriptor = Object.getOwnPropertyDescriptor(KeyboardEvent.prototype, modifierKey)
Object.defineProperty(KeyboardEvent.prototype, 'modifierKey', modifierKeyDescriptor)
@jonathantneal Sounds like it's a different issue. And there was Accel
pseudo-key name to check it in the old versions of UI Events, but it was deleted (https://github.com/w3c/uievents/issues/28#issuecomment-192809289). Although Gecko still supports it.
@masayuki-nakano, thank you for the reply.
Sounds like it's a different issue.
Should I open a new issue? Is this issue for detecting the OS-specific modifier (or primary accelerator key?).
When I first looked at this issue, I thought it might be different when read “the solution should be able to determine if one or more modifier keys are truthy” as that seems ‘greedy’, but then it is followed by, “while ensuring rest of the available modifier keys are falsey” which makes me think it is the same as my need.
Which would be best for the working group? This issue? A new issue? ... no issue? 😅
it was deleted
Thank you for that link. I see that they mention that we should open new bugs to track any further issues we encounter. Would my issue and the prior art that I’ve shared qualify?
Although Gecko still supports it.
Upon a brief cross browser testing with the following code, it seems that Firefox and all Chromium browsers support event.getModifierState('Accel')
. It turned out that the only browser which did not support this was Safari.
<pre id="log"></pre>
<script>
window.addEventListener('keydown', event => {
event.preventDefault()
log.textContent = JSON.stringify({
key: event.key,
Accel: event.getModifierState('Accel'),
Meta: event.getModifierState('Meta'),
Control: event.getModifierState('Control'),
Option: event.getModifierState('Option'),
Alt: event.getModifierState('Alt'),
}, null, ' ')
})
</script>
@jonathantneal In my understanding, this issue requests an API to check multiple modifier stats with a call for making modifier check code simpler.
I think that you should file a new issue in "uievents". Handling only one thing in an issue makes everybody manage issues easier. And I've not known that Accel
was supported by Chrome. It sounds like that it's reasonable to resurrect the pseudo modifier.
For a real-world example of why the current boolean flag-based API leads to bugs, see: https://medium.engineering/the-curious-case-of-disappearing-polish-s-fa398313d4df
I think the solution is as easy as adding an API to spit out all the modifiers in one string like Java's getKeyModifiersText()
which gives eg Ctrl+Shift
; any modifiers not included in the string are false. This isn't difficult to do in userland but the API currently affords incorrect usage, and it'd be better to encourage correct usage instead.
I agree that @jonathantneal is talking about something totally different, which is about somehow helping with Ctrl- and Meta- modifiers having different meanings on Mac than they do on Win/Linux; I'm not sure that's something the browser should help with at all. Java, for example, doesn't seem to help with that all, presenting basically the same API as the browser: https://docs.oracle.com/javase/6/docs/api/java/awt/event/InputEvent.html#method_summary
(From whatwg/html#2856)
Use Case
Often times, when adding keyboard event listeners, one would like to determine if a modifier key is pressed (one of
ctrlKey
,metaKey
,altKey
,shiftKey
) to create keyboard shortcuts in a webapp type scenario. The inherent problem with checking for truthiness of these values is that this becomes "greedy" - one also needs to check the falseness of other keys. As such it becomes quite a lot of code to determine if only a single modifier is pressed:Reasoning
This is problematic because it is an easy thing to miss while developing, and it is a fair amount of boilerplate code to check a handful of properties to ensure they are false.
Requirements
So to solve this, I believe the solution should keep to these requirements: