mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-310: Merge fix clipboard handling of newlines.
This commit is contained in:
@@ -57,10 +57,9 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
|
|||||||
*
|
*
|
||||||
* @type Element
|
* @type Element
|
||||||
*/
|
*/
|
||||||
var clipboardContent = document.createElement('div');
|
var clipboardContent = document.createElement('textarea');
|
||||||
|
|
||||||
// Ensure clipboard target is selectable but not visible
|
// Ensure clipboard target is selectable but not visible
|
||||||
clipboardContent.setAttribute('contenteditable', 'true');
|
|
||||||
clipboardContent.className = 'clipboard-service-target';
|
clipboardContent.className = 'clipboard-service-target';
|
||||||
|
|
||||||
// Add clipboard target to DOM
|
// Add clipboard target to DOM
|
||||||
@@ -136,14 +135,23 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
|
|||||||
*/
|
*/
|
||||||
var selectAll = function selectAll(element) {
|
var selectAll = function selectAll(element) {
|
||||||
|
|
||||||
// Generate a range which selects all nodes within the given element
|
// Use the select() function defined for input elements, if available
|
||||||
var range = document.createRange();
|
if (element.select)
|
||||||
range.selectNodeContents(element);
|
element.select();
|
||||||
|
|
||||||
// Replace any current selection with the generated range
|
// Fallback to manual manipulation of the selection
|
||||||
var selection = $window.getSelection();
|
else {
|
||||||
selection.removeAllRanges();
|
|
||||||
selection.addRange(range);
|
// Generate a range which selects all nodes within the given element
|
||||||
|
var range = document.createRange();
|
||||||
|
range.selectNodeContents(element);
|
||||||
|
|
||||||
|
// Replace any current selection with the generated range
|
||||||
|
var selection = $window.getSelection();
|
||||||
|
selection.removeAllRanges();
|
||||||
|
selection.addRange(range);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,7 +175,7 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
|
|||||||
|
|
||||||
// Copy the given value into the clipboard DOM element
|
// Copy the given value into the clipboard DOM element
|
||||||
if (typeof data.data === 'string')
|
if (typeof data.data === 'string')
|
||||||
clipboardContent.textContent = data.data;
|
clipboardContent.value = data.data;
|
||||||
else {
|
else {
|
||||||
clipboardContent.innerHTML = '';
|
clipboardContent.innerHTML = '';
|
||||||
var img = document.createElement('img');
|
var img = document.createElement('img');
|
||||||
@@ -176,6 +184,7 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Select all data within the clipboard target
|
// Select all data within the clipboard target
|
||||||
|
clipboardContent.focus();
|
||||||
selectAll(clipboardContent);
|
selectAll(clipboardContent);
|
||||||
|
|
||||||
// Attempt to copy data from clipboard element into local clipboard
|
// Attempt to copy data from clipboard element into local clipboard
|
||||||
@@ -399,53 +408,81 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
|
|||||||
var originalElement = document.activeElement;
|
var originalElement = document.activeElement;
|
||||||
pushSelection();
|
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
|
// Clear and select the clipboard DOM element
|
||||||
clipboardContent.innerHTML = '';
|
clipboardContent.value = '';
|
||||||
clipboardContent.focus();
|
clipboardContent.focus();
|
||||||
selectAll(clipboardContent);
|
selectAll(clipboardContent);
|
||||||
|
|
||||||
// Attempt paste local clipboard into clipboard DOM element
|
// If focus failed to be set, we cannot read the clipboard
|
||||||
if (document.activeElement === clipboardContent && document.execCommand('paste')) {
|
if (document.activeElement !== clipboardContent)
|
||||||
|
|
||||||
// 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.textContent
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, reading from the clipboard has failed
|
|
||||||
else
|
|
||||||
deferred.reject();
|
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);
|
}, CLIPBOARD_READ_DELAY);
|
||||||
|
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
|
@@ -52,10 +52,10 @@
|
|||||||
|
|
||||||
.clipboard-service-target {
|
.clipboard-service-target {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: -1px;
|
left: -1em;
|
||||||
right: -1px;
|
right: -1em;
|
||||||
width: 1px;
|
width: 1em;
|
||||||
height: 1px;
|
height: 1em;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user