[Libreoffice-commits] online.git: ios/CollaboraOnlineWebViewKeyboardManager ios/Mobile loleaflet/html loleaflet/src

Tor Lillqvist (via logerrit) logerrit at kemper.freedesktop.org
Tue Sep 1 15:24:56 UTC 2020


 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 3df718aac72138849ecafadc13f0207c3ec52283
Author:     Tor Lillqvist <tml at collabora.com>
AuthorDate: Tue Sep 1 16:58:17 2020 +0300
Commit:     Tor Lillqvist <tml at collabora.com>
CommitDate: Tue Sep 1 17:24:36 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 <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Tor Lillqvist <tml at collabora.com>

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 2a2d870c3..5be21cd0f 100644
--- a/ios/Mobile/DocumentViewController.mm
+++ b/ios/Mobile/DocumentViewController.mm
@@ -102,8 +102,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];
 
@@ -441,6 +443,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 8ec343996..31820d1bd 100644
--- a/loleaflet/html/loleaflet.html.m4
+++ b/loleaflet/html/loleaflet.html.m4
@@ -70,7 +70,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 bae93c25e..7ce02fa08 100644
--- a/loleaflet/src/layer/marker/TextInput.js
+++ b/loleaflet/src/layer/marker/TextInput.js
@@ -99,10 +99,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);
 		}
@@ -223,10 +241,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 {
@@ -236,8 +260,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;


More information about the Libreoffice-commits mailing list