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

This commit is contained in:
Michael Jumper
2017-08-29 11:39:49 -07:00
parent cc22f23c02
commit 47acaf5b41

View File

@@ -398,53 +398,81 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
var originalElement = document.activeElement;
pushSelection();
/**
* 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 : 'text/plain',
data : clipboardContent.value
}));
}
// 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();
});
// Ensure clipboard element is blurred (and that the "focus" event
// will fire)
clipboardContent.blur();
clipboardContent.addEventListener('focus', performPaste);
// 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) {
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 : 'text/plain',
data : clipboardContent.value
}));
}
// Otherwise, reading from the clipboard has failed
else
// If focus failed to be set, we cannot read the clipboard
if (document.activeElement !== clipboardContent)
deferred.reject();
// Unfocus the clipboard DOM event to avoid mobile keyboard opening,
// restoring whichever element was originally focused
clipboardContent.blur();
originalElement.focus();
popSelection();
}, CLIPBOARD_READ_DELAY);
return deferred.promise;