From dd5521a07ccb110e234bb7b533f60f2e9945019e Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sat, 27 Jun 2015 13:03:41 +0200 Subject: [PATCH] various native deadkey fixes --- AppKit/CPTextView/CPTextView.j | 109 +++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 46 deletions(-) diff --git a/AppKit/CPTextView/CPTextView.j b/AppKit/CPTextView/CPTextView.j index 9ec4f24c7..122a2bd4d 100644 --- a/AppKit/CPTextView/CPTextView.j +++ b/AppKit/CPTextView/CPTextView.j @@ -667,8 +667,8 @@ var kDelegateRespondsTo_textShouldBeginEditing [_delegate textViewDidChangeSelection:[[CPNotification alloc] initWithName:CPTextViewDidChangeSelectionNotification object:self userInfo:nil]]; } - if (_selectionRange.length > 0) - [_CPNativeInputManager focusForClipboard]; // workaround Safari native pasting limitation + if (!selecting && _selectionRange.length > 0) + [_CPNativeInputManager focusForClipboard]; } // interface to the _CPNativeInputManager @@ -748,8 +748,10 @@ var kDelegateRespondsTo_textShouldBeginEditing { [[_window platformWindow] _propagateCurrentDOMEvent:YES]; // necessary for the _CPNativeInputManager to work - if (![_CPNativeInputManager isNativeInputFieldActive] && [event charactersIgnoringModifiers].charCodeAt(0) != 229) // filter out 229 because this would be inserted in chrome on each deadkey - [self interpretKeyEvents:[event]]; + if ([_CPNativeInputManager isNativeInputFieldActive]) + return; + + if ([event charactersIgnoringModifiers].charCodeAt(0) != 229) // filter out 229 because this would be inserted in chrome on each deadkey [_caret setPermanentlyVisible:YES]; } @@ -2116,6 +2118,9 @@ var _CPCopyPlaceholder = '-'; } + (void)cancelCurrentNativeInputSession { + if (_CPNativeInputField.innerHTML.length > 2) + _CPNativeInputField.innerHTML = ''; + [self _endInputSessionWithString:_CPNativeInputField.innerHTML]; } + (void)cancelCurrentInputSessionIfNeeded @@ -2143,21 +2148,24 @@ var _CPCopyPlaceholder = '-'; _CPNativeInputField = document.createElement("div"); _CPNativeInputField.contentEditable = YES; - _CPNativeInputField.onkeyup = function(e) + _CPNativeInputField.addEventListener("keyup", function(e) { + _CPNativeInputFieldKeyUpCalled = YES; // filter out the shift-up, cursor keys and friends used to access the deadkeys // fixme: e.which is depreciated(?) -> find a better way to identify the modifier-keyups - if (e.which != 8 && e.which != 13 && e.which < 27 || e.which == 91 || e.which == 93) // include apple command keys - return; + if (e.which < 27 || e.which == 91 || e.which == 93) // include apple command keys + { + if (_CPNativeInputField.innerHTML.length == 0 || _CPNativeInputField.innerHTML.length > 2) // backspace + [self cancelCurrentInputSessionIfNeeded]; + + return false; // prevent the default behaviour + } - if (e.which == 8) // safari backspace fix - _CPNativeInputFieldKeyPressedCalled = YES; - _CPNativeInputFieldKeyUpCalled = YES; var currentFirstResponder = [[CPApp mainWindow] firstResponder]; if (![currentFirstResponder respondsToSelector:@selector(_activateNativeInputElement:)]) - return; + return false; // prevent the default behaviour var charCode = _CPNativeInputField.innerHTML.charCodeAt(0); @@ -2168,22 +2176,22 @@ var _CPCopyPlaceholder = '-'; return; } - if (!_CPNativeInputFieldActive && _CPNativeInputFieldKeyPressedCalled == NO && _CPNativeInputField.innerHTML.length && _CPNativeInputField.innerHTML != _CPCopyPlaceholder) // chrome-trigger: keypressed is omitted for deadkeys + if (!_CPNativeInputFieldActive && _CPNativeInputFieldKeyPressedCalled == NO && _CPNativeInputField.innerHTML.length && _CPNativeInputField.innerHTML != _CPCopyPlaceholder && _CPNativeInputField.innerHTML.length < 3) // chrome-trigger: keypressed is omitted for deadkeys { _CPNativeInputFieldActive = YES; [currentFirstResponder _activateNativeInputElement:_CPNativeInputField]; } else { - if (_CPNativeInputField.innerHTML.length > 1) - _CPNativeInputField.innerHTML = ''; - if (_CPNativeInputFieldActive) [self _endInputSessionWithString:_CPNativeInputField.innerHTML]; _CPNativeInputField.innerHTML = ''; } - } - _CPNativeInputField.onkeydown = function(e) + + return false; // prevent the default behaviour + }, true); + + _CPNativeInputField.addEventListener("keydown", function(e) { if(e.metaKey) // do not interfere with native copy-paste { @@ -2207,7 +2215,7 @@ var _CPCopyPlaceholder = '-'; // FF-trigger: here the best way to detect a dead key is the missing keyup event if (CPBrowserIsEngine(CPGeckoBrowserEngine)) setTimeout(function(){ - if (!_CPNativeInputFieldActive && _CPNativeInputFieldKeyUpCalled == NO && _CPNativeInputField.innerHTML.length && _CPNativeInputField.innerHTML != _CPCopyPlaceholder && !e.repeat) + if (!_CPNativeInputFieldActive && _CPNativeInputFieldKeyUpCalled == NO && _CPNativeInputField.innerHTML.length && _CPNativeInputField.innerHTML != _CPCopyPlaceholder && _CPNativeInputField.innerHTML.length < 3 && !e.repeat) { _CPNativeInputFieldActive = YES; [currentFirstResponder _activateNativeInputElement:_CPNativeInputField]; @@ -2215,20 +2223,25 @@ var _CPCopyPlaceholder = '-'; else if (!_CPNativeInputFieldActive) [self hideInputElement]; }, 200); - } - _CPNativeInputField.onkeypress=function(e) + return false; + }, true); // capture mode + + _CPNativeInputField.addEventListener("keypress", function(e) { _CPNativeInputFieldKeyUpCalled = YES; _CPNativeInputFieldKeyPressedCalled = YES; - } + return false; + }, true); // capture mode if (CPBrowserIsEngine(CPGeckoBrowserEngine)) _CPNativeInputField.addEventListener("input", function() { if(_CPNativeInputFieldActive) setTimeout(function(){ - [self cancelCurrentInputSessionIfNeeded]; + if (_CPNativeInputField.innerHTML.length > 1) + [self cancelCurrentInputSessionIfNeeded]; }, 500); - }, false); + return false; + }, true) _CPNativeInputField.style.width="64px"; _CPNativeInputField.style.zIndex = 10000; @@ -2249,7 +2262,7 @@ var _CPCopyPlaceholder = '-'; if (_CPNativeInputFieldLastCopyWasNative) { var data = e.clipboardData.getData('text/plain'); - [pasteboard setString:data forType:CPStringPboardType]; + [pasteboard setString:data forType:CPStringPboardType]; } var currentFirstResponder = [[CPApp mainWindow] firstResponder]; @@ -2258,9 +2271,6 @@ var _CPCopyPlaceholder = '-'; [currentFirstResponder paste:self]; }, 20); - e.preventDefault(); - e.stopPropagation(); - return false; } _CPNativeInputField.oncopy = function(e) @@ -2278,9 +2288,6 @@ var _CPCopyPlaceholder = '-'; e.clipboardData.setData('text/plain', stringForPasting); // e.clipboardData.setData('application/rtf', stringForPasting); // does not seem to work - e.preventDefault(); - e.stopPropagation(); - return false; } _CPNativeInputField.oncut = function(e) @@ -2302,36 +2309,38 @@ var _CPCopyPlaceholder = '-'; e.clipboardData.setData('text/plain', stringForPasting); // e.clipboardData.setData('application/rtf', stringForPasting); // does not seem to work - e.preventDefault(); - e.stopPropagation(); - return false; } } + (void)focus { + var currentFirstResponder = [[CPApp mainWindow] firstResponder]; if (![currentFirstResponder respondsToSelector:@selector(_activateNativeInputElement:)]) return; [self hideInputElement]; + + + // only append the _CPNativeInputField if it is not already there + var children = currentFirstResponder._DOMElement.childNodes, + l = children.length; + + for (var i = 0; i < l; i++) + { + if (children[i] === _CPNativeInputField) // we are (almost) done + { + if (document.activeElement !== _CPNativeInputField) // focus the _CPNativeInputField if necessary + _CPNativeInputField.focus(); + + return; + } + } + currentFirstResponder._DOMElement.appendChild(_CPNativeInputField); _CPNativeInputField.focus(); -} - -+ (void)focusForClipboard -{ - var currentFirstResponder = [[CPApp mainWindow] firstResponder]; - - [self hideInputElement]; - currentFirstResponder._DOMElement.appendChild(_CPNativeInputField); - - if (_CPNativeInputField.innerHTML.length == 0) - _CPNativeInputField.innerHTML = _CPCopyPlaceholder; // make sure we have a selection to allow the native pasteboard work in safari - - _CPNativeInputField.focus(); // select all in the contenteditable div (http://stackoverflow.com/questions/12243898/how-to-select-all-text-in-contenteditable-div) if (document.body.createTextRange) @@ -2349,6 +2358,14 @@ var _CPCopyPlaceholder = '-'; } } ++ (void)focusForClipboard +{ + if (_CPNativeInputField.innerHTML.length == 0) + _CPNativeInputField.innerHTML = _CPCopyPlaceholder; // make sure we have a selection to allow the native pasteboard work in safari + + [self focus]; +} + + (void)hideInputElement { _CPNativeInputField.style.top="-10000px";