summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/copy_to_clipboard.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/copy_to_clipboard.js')
-rw-r--r--app/assets/javascripts/copy_to_clipboard.js34
1 files changed, 30 insertions, 4 deletions
diff --git a/app/assets/javascripts/copy_to_clipboard.js b/app/assets/javascripts/copy_to_clipboard.js
index 6dbec50b890..ab9a8e43dd1 100644
--- a/app/assets/javascripts/copy_to_clipboard.js
+++ b/app/assets/javascripts/copy_to_clipboard.js
@@ -38,9 +38,35 @@ showTooltip = function(target, title) {
};
$(function() {
- var clipboard;
-
- clipboard = new Clipboard('[data-clipboard-target], [data-clipboard-text]');
+ const clipboard = new Clipboard('[data-clipboard-target], [data-clipboard-text]');
clipboard.on('success', genericSuccess);
- return clipboard.on('error', genericError);
+ clipboard.on('error', genericError);
+
+ // This a workaround around ClipboardJS limitations to allow the context-specific copy/pasting of plain text or GFM.
+ // The Ruby `clipboard_button` helper sneaks a JSON hash with `text` and `gfm` keys into the `data-clipboard-text`
+ // attribute that ClipboardJS reads from.
+ // When ClipboardJS creates a new `textarea` (directly inside `body`, with a `readonly` attribute`), sets its value
+ // to the value of this data attribute, focusses on it, and finally programmatically issues the 'Copy' command,
+ // this code intercepts the copy command/event at the last minute to deconstruct this JSON hash and set the
+ // `text/plain` and `text/x-gfm` copy data types to the intended values.
+ $(document).on('copy', 'body > textarea[readonly]', function(e) {
+ const clipboardData = e.originalEvent.clipboardData;
+ if (!clipboardData) return;
+
+ const text = e.target.value;
+
+ let json;
+ try {
+ json = JSON.parse(text);
+ } catch (ex) {
+ return;
+ }
+
+ if (!json.text || !json.gfm) return;
+
+ e.preventDefault();
+
+ clipboardData.setData('text/plain', json.text);
+ clipboardData.setData('text/x-gfm', json.gfm);
+ });
});