From 75a575d050abcca8c8dec98df39ee0b3bb322dea Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 3 Sep 2017 16:07:21 -0700 Subject: [PATCH 1/3] GUACAMOLE-128: Do not allow overlapping clipboard read attempts. --- .../clipboard/services/clipboardService.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js index 07091f316..939161eeb 100644 --- a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js +++ b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js @@ -44,6 +44,14 @@ angular.module('clipboard').factory('clipboardService', ['$injector', */ var CLIPBOARD_READ_DELAY = 100; + /** + * The promise associated with the current pending clipboard read attempt. + * If no clipboard read is active, this will be null. + * + * @type Promise. + */ + var pendingRead = null; + /** * Reference to the window.document object. * @@ -398,8 +406,16 @@ angular.module('clipboard').factory('clipboardService', ['$injector', */ service.getLocalClipboard = function getLocalClipboard() { + // If the clipboard is already being read, do not overlap the read + // attempts; instead share the result across all requests + if (pendingRead) + return pendingRead; + var deferred = $q.defer(); + // Mark read attempt as in progress + pendingRead = deferred.promise; + // 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() { @@ -467,6 +483,9 @@ angular.module('clipboard').factory('clipboardService', ['$injector', originalElement.focus(); popSelection(); + // No read is pending any longer + pendingRead = null; + }); // Ensure clipboard element is blurred (and that the "focus" event From 6ce1eb1d3a2d63597cc61b00a850619bb3546552 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 3 Sep 2017 16:30:52 -0700 Subject: [PATCH 2/3] GUACAMOLE-128: Stop propagation of "cut" events from within clipboard service event target. --- .../src/main/webapp/app/clipboard/services/clipboardService.js | 1 + 1 file changed, 1 insertion(+) diff --git a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js index 939161eeb..06abb048a 100644 --- a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js +++ b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js @@ -86,6 +86,7 @@ angular.module('clipboard').factory('clipboardService', ['$injector', }; // Prevent events generated due to execCommand() from disturbing external things + clipboardContent.addEventListener('cut', stopEventPropagation); clipboardContent.addEventListener('copy', stopEventPropagation); clipboardContent.addEventListener('paste', stopEventPropagation); From 1c50311178d3af5f5af07561ccc2f3f599bf62fe Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 3 Sep 2017 16:32:39 -0700 Subject: [PATCH 3/3] GUACAMOLE-128: Check clipboard for received events only during bubble phase (allow clipboard service to manage propagation from its event target). --- .../src/main/webapp/app/index/controllers/indexController.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guacamole/src/main/webapp/app/index/controllers/indexController.js b/guacamole/src/main/webapp/app/index/controllers/indexController.js index 0f4d78dc5..3a9230bf7 100644 --- a/guacamole/src/main/webapp/app/index/controllers/indexController.js +++ b/guacamole/src/main/webapp/app/index/controllers/indexController.js @@ -137,8 +137,8 @@ angular.module('index').controller('indexController', ['$scope', '$injector', // Attempt to read the clipboard if it may have changed $window.addEventListener('load', checkClipboard, true); - $window.addEventListener('copy', checkClipboard, true); - $window.addEventListener('cut', checkClipboard, true); + $window.addEventListener('copy', checkClipboard); + $window.addEventListener('cut', checkClipboard); $window.addEventListener('focus', function focusGained(e) { // Only recheck clipboard if it's the window itself that gained focus