mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-526: Maintain full correct chain of promises for clipboard read attempts, including the "finally" used for cleanup. The "finally" handler creates a new promise with a potentially unhandled rejection otherwise.
This commit is contained in:
@@ -415,81 +415,79 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
|
||||
|
||||
var deferred = $q.defer();
|
||||
|
||||
// Mark read attempt as in progress
|
||||
pendingRead = deferred.promise;
|
||||
// Track the originally-focused element prior to changing focus
|
||||
var originalElement = document.activeElement;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
};
|
||||
|
||||
// Mark read attempt as in progress, cleaning up event listener and
|
||||
// selection once the paste attempt has completed
|
||||
pendingRead = 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();
|
||||
|
||||
// No read is pending any longer
|
||||
pendingRead = null;
|
||||
|
||||
});
|
||||
|
||||
// Wait for the next event queue run before attempting to read
|
||||
// clipboard data (in case the copy/cut has not yet completed)
|
||||
$window.setTimeout(function deferredClipboardRead() {
|
||||
|
||||
// Track the originally-focused element prior to changing focus
|
||||
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();
|
||||
|
||||
// No read is pending any longer
|
||||
pendingRead = null;
|
||||
|
||||
});
|
||||
|
||||
// Ensure clipboard element is blurred (and that the "focus" event
|
||||
// will fire)
|
||||
clipboardContent.blur();
|
||||
@@ -506,7 +504,8 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
|
||||
|
||||
}, CLIPBOARD_READ_DELAY);
|
||||
|
||||
return deferred.promise;
|
||||
return pendingRead;
|
||||
|
||||
};
|
||||
|
||||
return service;
|
||||
|
Reference in New Issue
Block a user