From 8daa53dd3eaba12711e08f22dad2ded86e233348 Mon Sep 17 00:00:00 2001 From: daboe01 Date: Tue, 7 Jan 2020 12:34:39 +0100 Subject: [PATCH] Fixed: CPTextView keyboard issue in recent Firefox versions (#2874) Wrong characters were sometimes emitted in keyboard events on Firefox --- AppKit/Platform/DOM/CPPlatformWindow+DOM.j | 10 ++++++++-- AppKit/Platform/DOM/CPPlatformWindow+DOMKeys.j | 8 +++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index ed9bb0718..e6d467bf6 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -738,8 +738,14 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio if (aDOMEvent.which === 0 || aDOMEvent.charCode === 0 || (aDOMEvent.which === undefined && aDOMEvent.charCode === undefined)) characters = KeyCodesToUnicodeMap[_keyCode]; + // The problem with keyCode is that this property refers to keys on the keyboard and not to characters + // This is why String.fromCharCode does not always work in more recent versions of Firefox + // E.g. pressing a '#' on a German keyboard gives you a charCode of 163, which refers to '£' and not '#' + // The property key works fine, though. From there we can get the actual character more robustly. + // Therefore we prefer key over keyCode whenever possible + if (!characters) - characters = String.fromCharCode(_keyCode).toLowerCase(); + characters = (aDOMEvent.key && aDOMEvent.key.length == 1) ? aDOMEvent.key.toLowerCase() : String.fromCharCode(_keyCode).toLowerCase(); overrideCharacters = (modifierFlags & CPShiftKeyMask || _capsLockActive) ? characters.toUpperCase() : characters; @@ -767,7 +773,7 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio //this lets us be consistent in all browsers and send on the keydown //which means we can cancel the event early enough, but only if sendEvent needs to } - else if (CPKeyCodes.firesKeyPressEvent(_keyCode, _lastKey, aDOMEvent.shiftKey, aDOMEvent.ctrlKey, aDOMEvent.altKey)) + else if (CPKeyCodes.firesKeyPressEvent(_keyCode, aDOMEvent.key, _lastKey, aDOMEvent.shiftKey, aDOMEvent.ctrlKey, aDOMEvent.altKey)) { // this branch is taken by events which fire keydown, keypress, and keyup. // this is the only time we'll ALLOW character keys to propagate (needed for text fields) diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOMKeys.j b/AppKit/Platform/DOM/CPPlatformWindow+DOMKeys.j index 08a426f3a..b0e04d400 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOMKeys.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOMKeys.j @@ -157,8 +157,14 @@ CPKeyCodes = { * @param opt_altKey Whether the alt key is held down. * @return Returns YES if it's a key that fires a keypress event. */ -CPKeyCodes.firesKeyPressEvent = function(keyCode, opt_heldKeyCode, opt_shiftKey, opt_ctrlKey, opt_altKey) +CPKeyCodes.firesKeyPressEvent = function(keyCode, key, opt_heldKeyCode, opt_shiftKey, opt_ctrlKey, opt_altKey) { + // The property key from event is one character wide in case of 'regular' keys (as opposed e.g. to arrow keys) + // Regular keys all fire the keypress event + + if (key && key.length == 1) + return true; + if (!CPFeatureIsCompatible(CPJavaScriptRemedialKeySupport)) return true;