mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +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