diff options
Diffstat (limited to 'app/assets/javascripts/copy_to_clipboard.js')
-rw-r--r-- | app/assets/javascripts/copy_to_clipboard.js | 34 |
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); + }); }); |