Refactor clipboard copying into a separate file for use outside the SQL Editor.

This commit is contained in:
Atira Odhner 2017-03-15 17:11:11 +00:00 committed by Dave Page
parent 4445f9dd63
commit 172b41cba8
3 changed files with 71 additions and 65 deletions

View File

@ -0,0 +1,61 @@
define(['translate', 'alertify'], function (t, alertify) {
var clipboard = {
copyTextToClipboard: function (text) {
var textArea = document.createElement("textarea");
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a flash,
// so some of these are just precautions. However in IE the element
// is visible whilst the popup box asking the user for permission for
// the web page to copy to the clipboard.
//
// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand('copy');
} catch (err) {
alertify.alert(
t('Error'),
t('Oops, unable to copy to clipboard'));
}
document.body.removeChild(textArea);
}
};
return clipboard;
});

View File

@ -158,6 +158,7 @@
},
paths: {
pgadmin: "{{ url_for('static', filename='js/pgadmin') }}",
selection: "{{ url_for('static', filename='js/selection') }}",
'pgadmin.alertifyjs': "{{ url_for('static', filename='js/alertify.pgadmin.defaults') }}",
"pgadmin.backgrid": "{{ url_for('static', filename='js/backgrid.pgadmin') }}",
'pgadmin.backform': "{{ url_for('static', filename='js/backform.pgadmin') }}",

View File

@ -1,8 +1,10 @@
define(
[
'jquery', 'underscore', 'underscore.string', 'alertify', 'pgadmin',
'backbone', 'backgrid', 'codemirror', 'pgadmin.misc.explain', 'slickgrid',
'bootstrap', 'pgadmin.browser', 'wcdocker',
'backbone', 'backgrid', 'codemirror', 'pgadmin.misc.explain',
'selection/clipboard',
'slickgrid', 'bootstrap', 'pgadmin.browser', 'wcdocker',
'codemirror/mode/sql/sql', 'codemirror/addon/selection/mark-selection',
'codemirror/addon/selection/active-line', 'codemirror/addon/fold/foldcode',
'codemirror/addon/fold/foldgutter', 'codemirror/addon/hint/show-hint',
@ -25,7 +27,7 @@ define(
'slickgrid/slick.grid'
],
function(
$, _, S, alertify, pgAdmin, Backbone, Backgrid, CodeMirror, pgExplain
$, _, S, alertify, pgAdmin, Backbone, Backgrid, CodeMirror, pgExplain, clipboard
) {
/* Return back, this has been called more than once */
if (pgAdmin.SqlEditor)
@ -738,8 +740,7 @@ define(
}
var grid = args.grid, column_info, column_values, value,
cell = args.cell, row = args.row, selected_rows,
self = this.editor.handler;
cell = args.cell, row = args.row;
// Copy operation (Only when if there is no row selected)
// When user press `Ctrl + c` on selected cell
@ -752,12 +753,12 @@ define(
value = column_values[column_info.pos] || '';
// Copy this value to Clipboard
if(value)
this.editor.handler.copyTextToClipboard(value);
clipboard.copyTextToClipboard(value);
// Go to cell again
grid.gotoCell(row, cell, false);
}
}.bind(editor_data));
});
// Listener function which will be called when user updates existing rows
@ -2930,63 +2931,6 @@ define(
});
},
// This function will copy the selected rows(s) in Clipboard.
copyTextToClipboard: function (text) {
var textArea = document.createElement("textarea");
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a flash,
// so some of these are just precautions. However in IE the element
// is visible whilst the popup box asking the user for permission for
// the web page to copy to the clipboard.
//
// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand('copy');
} catch (err) {
alertify.alert('{{ _('Error') }}',
'{{ _('Oops, unable to copy to clipboard') }}');
}
document.body.removeChild(textArea);
},
// This function will copy the selected row.
_copy_row: function() {
var self = this, grid, data, rows, copied_text = '';
@ -3026,7 +2970,7 @@ define(
}
// If there is something to set into clipboard
if(copied_text)
self.copyTextToClipboard(copied_text);
clipboard.copyTextToClipboard(copied_text);
},
// This function will paste the selected row.