ios/CollaboraOnlineWebViewKeyboardManager/CollaboraOnlineWebViewKeyboardManager.m
 |   22 +++++-
 ios/Mobile/DocumentViewController.mm                                           
   |   27 +++++++
 loleaflet/html/loleaflet.html.m4                                               
   |   15 ++++
 loleaflet/src/layer/marker/TextInput.js                                        
   |   35 ++++++++--
 4 files changed, 86 insertions(+), 13 deletions(-)

New commits:
commit 91041961f3f2841b50c3f74fa05761ac338181da
Author:     Tor Lillqvist <t...@collabora.com>
AuthorDate: Tue Sep 1 16:58:17 2020 +0300
Commit:     Tor Lillqvist <t...@collabora.com>
CommitDate: Wed Sep 2 19:38:42 2020 +0200

    tdf#133284: Improve hardware and on-screen keyboard in the iOS app
    
    This is a quite complicated change that should both fix tdf#133284
    (cursor keys on a hardware keyboard do not work in a spreadsheet
    document) and also improve the interaction with
    CollaboraOnlineWebViewKeyboardManager that manages the on-screen
    keyboard. We need to jump through complicated hoops in order to get
    the hardware cursor keys handled right after loading a spreadsheet
    document.
    
    In the CollaboraOnlineWebViewKeyboardManager case we try harder to
    keep loleaflet's _textArea buffer in sync with what the UITextView in
    CollaboraOnlineWebViewKeyboardManager uses to provide suggestions
    above the on-screen keyboard.
    
    Also merges in related changes from today to
    CollaboraOnlineWebViewKeyboardManager.
    
    Change-Id: Ic4acb54bd4e815aa8bfb2bf40b08493446ae5ab0
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/101878
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Tor Lillqvist <t...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/101953

diff --git 
a/ios/CollaboraOnlineWebViewKeyboardManager/CollaboraOnlineWebViewKeyboardManager.m
 
b/ios/CollaboraOnlineWebViewKeyboardManager/CollaboraOnlineWebViewKeyboardManager.m
index 561b726d6..fd1bcaff3 100644
--- 
a/ios/CollaboraOnlineWebViewKeyboardManager/CollaboraOnlineWebViewKeyboardManager.m
+++ 
b/ios/CollaboraOnlineWebViewKeyboardManager/CollaboraOnlineWebViewKeyboardManager.m
@@ -79,6 +79,18 @@
 
     NSMutableString *quotedText = [NSMutableString string];
 
+    int location = range.location;
+
+    if (location < self.text.length && location + range.length == 
self.text.length) {
+        // To guard against possible mismatch between our self.text and the 
_textArea.value in
+        // TextInput.js, we indicate deletion or replacement from the end with 
negative location.
+        location = location - self.text.length;
+    }
+    else if (range.location == 0 && range.length == 0 && text.length == 0) {
+        // Backspace without anything known about preceding text
+        location = -1;
+    }
+
     for (unsigned i = 0; i < text.length; i++) {
         const unichar c = [text characterAtIndex:i];
         if (c == '\'' || c == '\\') {
@@ -93,7 +105,7 @@
 
     NSMutableString *message = [NSMutableString string];
 
-    [message appendFormat:@"{id: 'COKbdMgr', command: 'replaceText', location: 
%lu, length: %lu, text: '", range.location, range.length];
+    [message appendFormat:@"{id: 'COKbdMgr', command: 'replaceText', location: 
%d, length: %lu, text: '", location, range.length];
     [message appendString:quotedText];
     [message appendString:@"'}"];
 
@@ -209,15 +221,15 @@
         // will be added.
         control.autocapitalizationType = UITextAutocapitalizationTypeNone;
 
-        control.text = text;
-        control.selectedRange = NSMakeRange(location, 0);
-
         lastCommandIsHide = NO;
 
         [self->webView addSubview:control];
         NSLog(@"COKbdMgr: Added _COWVKMKeyInputControl to webView");
         [control becomeFirstResponder];
     }
+    control.text = text;
+    control.selectedRange = NSMakeRange(location, 0);
+
 }
 
 - (void)hideKeyboard {
@@ -253,6 +265,8 @@
             NSString *text = message.body[@"text"];
             NSNumber *location = message.body[@"location"];
             NSLog(@"COKbdMgr: command=display type=%@ text=%@ location=%@", 
type, text, location);
+            if (text == nil)
+                text = @"";
             [self displayKeyboardOfType:type withText:text at:(location != nil 
? [location unsignedIntegerValue] : UINT_MAX)];
         } else if ([stringCommand isEqualToString:@"hide"]) {
             lastCommandIsHide = YES;
diff --git a/ios/Mobile/DocumentViewController.mm 
b/ios/Mobile/DocumentViewController.mm
index cefd23c9e..eab598c2a 100644
--- a/ios/Mobile/DocumentViewController.mm
+++ b/ios/Mobile/DocumentViewController.mm
@@ -105,8 +105,10 @@ static IMP standardImpOfInputAccessoryView = nil;
     // contents is handled fully in JavaScript, the WebView has no knowledge 
of that.)
     self.webView.scrollView.delegate = self;
 
-    keyboardManager =
-        [[CollaboraOnlineWebViewKeyboardManager alloc] 
initForWebView:self.webView];
+    if (!isExternalKeyboardAttached()) {
+        keyboardManager =
+            [[CollaboraOnlineWebViewKeyboardManager alloc] 
initForWebView:self.webView];
+    }
 
     [self.view addSubview:self.webView];
 
@@ -447,6 +449,27 @@ static IMP standardImpOfInputAccessoryView = nil;
                     std::remove(printFile.c_str());
                 }];
 
+            return;
+        } else if ([message.body isEqualToString:@"FOCUSIFHWKBD"]) {
+            if (isExternalKeyboardAttached()) {
+                NSString *hwKeyboardMagic = @"{"
+                    "    if (window.MagicToGetHWKeyboardWorking) {"
+                    "        window.MagicToGetHWKeyboardWorking();"
+                    "    }"
+                    "}";
+                [self.webView evaluateJavaScript:hwKeyboardMagic
+                               completionHandler:^(id _Nullable obj, NSError * 
_Nullable error)
+                     {
+                         if (error) {
+                             LOG_ERR("Error after " << [hwKeyboardMagic 
UTF8String] << ": " << [[error localizedDescription] UTF8String]);
+                             NSString *jsException = 
error.userInfo[@"WKJavaScriptExceptionMessage"];
+                             if (jsException != nil)
+                                 LOG_ERR("JavaScript exception: " << 
[jsException UTF8String]);
+                         }
+                     }
+                 ];
+            }
+
             return;
         } else if ([message.body hasPrefix:@"HYPERLINK"]) {
             NSArray *messageBodyItems = [message.body 
componentsSeparatedByString:@" "];
diff --git a/loleaflet/html/loleaflet.html.m4 b/loleaflet/html/loleaflet.html.m4
index 9f42ed9f9..2a53e2603 100644
--- a/loleaflet/html/loleaflet.html.m4
+++ b/loleaflet/html/loleaflet.html.m4
@@ -69,7 +69,20 @@ m4_ifelse(ANDROIDAPP,[true],
 )
 
 if (window.ThisIsTheiOSApp) {
-  window.addEventListener("keydown", function(e) { e.preventDefault(); });
+  window.addEventListener('keydown', function(e) {
+    if (e.metaKey) {
+      e.preventDefault();
+    }
+    if (window.MagicKeyDownHandler)
+      window.MagicKeyDownHandler(e);
+  });
+  window.addEventListener('keyup', function(e) {
+    if (e.metaKey) {
+      e.preventDefault();
+    }
+    if (window.MagicKeyUpHandler)
+      window.MagicKeyUpHandler(e);
+  });
 }
 
 var Base64ToArrayBuffer = function(base64Str) {
diff --git a/loleaflet/src/layer/marker/TextInput.js 
b/loleaflet/src/layer/marker/TextInput.js
index 418ffd7d1..42ebdbf34 100644
--- a/loleaflet/src/layer/marker/TextInput.js
+++ b/loleaflet/src/layer/marker/TextInput.js
@@ -102,10 +102,28 @@ L.TextInput = L.Layer.extend({
                        this._onFocusBlur({ type: 'focus' });
                }
 
+               if (window.ThisIsTheiOSApp) {
+                       var that = this;
+                       window.MagicToGetHWKeyboardWorking = function() {
+                               var that2 = that;
+                               window.MagicKeyDownHandler = function(e) {
+                                       that2._onKeyDown(e);
+                               };
+                               window.MagicKeyUpHandler = function(e) {
+                                       that2._onKeyUp(e);
+                               };
+                       };
+                       window.postMobileMessage('FOCUSIFHWKBD');
+               }
+
                L.DomEvent.on(this._map.getContainer(), 'mousedown touchstart', 
this._abortComposition, this);
        },
 
        onRemove: function() {
+               window.MagicToGetHWKeyboardWorking = null;
+               window.MagicKeyDownHandler = null;
+               window.MagicKeyUpHandler = null;
+
                if (this._container) {
                        this.getPane().removeChild(this._container);
                }
@@ -226,10 +244,16 @@ L.TextInput = L.Layer.extend({
                                                throw errorMessage;
                                        }
 
-                                       if (that._textArea.value.length == 2 && 
message.length == 0 && message.text.length == 0) {
-                                               that._removeTextContent(1, 0);
-                                       } else {
-                                               that._textArea.value = 
that._textArea.value.slice(0, message.location + 1) + message.text + 
that._textArea.value.slice(message.location + 1 + message.length);
+                                       if (message.location < 0) {
+                                               if (that._textArea.value.length 
> 2) {
+                                                       that._textArea.value = 
that._textArea.value.slice(0, message.location - 1) + 
that._textArea.value.slice(-1);
+                                                       that._onInput({});
+                                               } else {
+                                                       
that._removeTextContent(-message.location, 0);
+                                               }
+                                       }
+                                       if (message.text.length > 0) {
+                                               that._textArea.value = 
that._textArea.value.slice(0, -1) + message.text + 
that._textArea.value.slice(-1);
                                                that._onInput({});
                                        }
                                } else {
@@ -239,8 +263,7 @@ L.TextInput = L.Layer.extend({
                                }
                        };
 
-                       // We don't know the seed text to feed 
CollaboraOnlineWebViewKeyboardManager
-                       
window.webkit.messageHandlers.CollaboraOnlineWebViewKeyboardManager.postMessage({command:
 'display'});
+                       
window.webkit.messageHandlers.CollaboraOnlineWebViewKeyboardManager.postMessage({command:
 'display', text: this._textArea.value.slice(1, -1)});
                        this._onFocusBlur({type: 'focus'});
 
                        return;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to