GUACAMOLE-310: Wait until clipboard target is actually focused before 
attempting paste.

Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/47acaf5b
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/47acaf5b
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/47acaf5b

Branch: refs/heads/master
Commit: 47acaf5b41c911d402a9f242cc58619bc74c4cb9
Parents: cc22f23
Author: Michael Jumper <[email protected]>
Authored: Tue Aug 29 11:39:49 2017 -0700
Committer: Michael Jumper <[email protected]>
Committed: Sun Sep 3 17:08:34 2017 -0700

----------------------------------------------------------------------
 .../app/clipboard/services/clipboardService.js  | 102 ++++++++++++-------
 1 file changed, 65 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/47acaf5b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js
----------------------------------------------------------------------
diff --git 
a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js 
b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js
index ff626ea..311dbc0 100644
--- a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js
+++ b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js
@@ -398,52 +398,80 @@ angular.module('clipboard').factory('clipboardService', 
['$injector',
             var originalElement = document.activeElement;
             pushSelection();
 
-            // Clear and select the clipboard DOM element
-            clipboardContent.value = '';
-            clipboardContent.focus();
-            selectAll(clipboardContent);
-
-            // Attempt paste local clipboard into clipboard DOM element
-            if (document.activeElement === clipboardContent && 
document.execCommand('paste')) {
-
-                // If the pasted data is a single image, resolve with a blob
-                // containing that image
-                var currentImage = service.getImageContent(clipboardContent);
-                if (currentImage) {
-
-                    // Convert the image's data URL into a blob
-                    var blob = service.parseDataURL(currentImage);
-                    if (blob) {
+            /**
+             * Attempts to paste the clipboard contents into the
+             * currently-focused element. The promise related to the current
+             * attempt to read the clipboard will be resolved or rejected
+             * depending on whether the attempt to paste succeeds.
+             */
+            var performPaste = function performPaste() {
+
+                // Attempt paste local clipboard into clipboard DOM element
+                if (document.execCommand('paste')) {
+
+                    // If the pasted data is a single image, resolve with a 
blob
+                    // containing that image
+                    var currentImage = 
service.getImageContent(clipboardContent);
+                    if (currentImage) {
+
+                        // Convert the image's data URL into a blob
+                        var blob = service.parseDataURL(currentImage);
+                        if (blob) {
+                            deferred.resolve(new ClipboardData({
+                                type : blob.type,
+                                data : blob
+                            }));
+                        }
+
+                        // Reject if conversion fails
+                        else
+                            deferred.reject();
+
+                    } // end if clipboard is an image
+
+                    // Otherwise, assume the clipboard contains plain text
+                    else
                         deferred.resolve(new ClipboardData({
-                            type : blob.type,
-                            data : blob
+                            type : 'text/plain',
+                            data : clipboardContent.value
                         }));
-                    }
-
-                    // Reject if conversion fails
-                    else
-                        deferred.reject();
 
-                } // end if clipboard is an image
+                }
 
-                // Otherwise, assume the clipboard contains plain text
+                // Otherwise, reading from the clipboard has failed
                 else
-                    deferred.resolve(new ClipboardData({
-                        type : 'text/plain',
-                        data : clipboardContent.value
-                    }));
+                    deferred.reject();
 
-            }
+            };
 
-            // Otherwise, reading from the clipboard has failed
-            else
-                deferred.reject();
+            // Clean up event listener and selection once the paste attempt has
+            // completed
+            deferred.promise['finally'](function cleanupReadAttempt() {
+
+                // Do not use future changes in focus
+                clipboardContent.removeEventListener('focus', performPaste);
+
+                // Unfocus the clipboard DOM event to avoid mobile keyboard 
opening,
+                // restoring whichever element was originally focused
+                clipboardContent.blur();
+                originalElement.focus();
+                popSelection();
 
-            // Unfocus the clipboard DOM event to avoid mobile keyboard 
opening,
-            // restoring whichever element was originally focused
+            });
+
+            // Ensure clipboard element is blurred (and that the "focus" event
+            // will fire)
             clipboardContent.blur();
-            originalElement.focus();
-            popSelection();
+            clipboardContent.addEventListener('focus', performPaste);
+
+            // Clear and select the clipboard DOM element
+            clipboardContent.value = '';
+            clipboardContent.focus();
+            selectAll(clipboardContent);
+
+            // If focus failed to be set, we cannot read the clipboard
+            if (document.activeElement !== clipboardContent)
+                deferred.reject();
 
         }, CLIPBOARD_READ_DELAY);
 

Reply via email to