Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Greiling <mike@pixelcog.com>2017-11-29 00:34:51 +0300
committerMike Greiling <mike@pixelcog.com>2017-11-29 00:37:58 +0300
commit2e5ce7e60f16c2e49178442ea065f5154b265d52 (patch)
tree6900beaf2215d1e61f6ca9696edcce34e04e3b34 /app/assets/javascripts/behaviors
parent7b893d1b52fa9df61739ce291c931338f95ef6d5 (diff)
move copy_to_clipboard to behaviors directory as it is needed on all pages
[ci-skip]
Diffstat (limited to 'app/assets/javascripts/behaviors')
-rw-r--r--app/assets/javascripts/behaviors/copy_to_clipboard.js73
-rw-r--r--app/assets/javascripts/behaviors/index.js2
2 files changed, 75 insertions, 0 deletions
diff --git a/app/assets/javascripts/behaviors/copy_to_clipboard.js b/app/assets/javascripts/behaviors/copy_to_clipboard.js
new file mode 100644
index 00000000000..e61745c3be2
--- /dev/null
+++ b/app/assets/javascripts/behaviors/copy_to_clipboard.js
@@ -0,0 +1,73 @@
+import Clipboard from 'clipboard';
+
+function showTooltip(target, title) {
+ const $target = $(target);
+ const originalTitle = $target.data('original-title');
+
+ if (!$target.data('hideTooltip')) {
+ $target
+ .attr('title', title)
+ .tooltip('fixTitle')
+ .tooltip('show')
+ .attr('title', originalTitle)
+ .tooltip('fixTitle');
+ }
+}
+
+function genericSuccess(e) {
+ showTooltip(e.trigger, 'Copied');
+ // Clear the selection and blur the trigger so it loses its border
+ e.clearSelection();
+ $(e.trigger).blur();
+}
+
+// Safari doesn't support `execCommand`, so instead we inform the user to
+// copy manually.
+//
+// See http://clipboardjs.com/#browser-support
+function genericError(e) {
+ let key;
+ if (/Mac/i.test(navigator.userAgent)) {
+ key = '&#8984;'; // Command
+ } else {
+ key = 'Ctrl';
+ }
+ showTooltip(e.trigger, `Press ${key}-C to copy`);
+}
+
+export default function initCopyToClipboard() {
+ const clipboard = new Clipboard('[data-clipboard-target], [data-clipboard-text]');
+ clipboard.on('success', genericSuccess);
+ 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]', (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);
+ });
+}
diff --git a/app/assets/javascripts/behaviors/index.js b/app/assets/javascripts/behaviors/index.js
index 671532394a9..34e905222b4 100644
--- a/app/assets/javascripts/behaviors/index.js
+++ b/app/assets/javascripts/behaviors/index.js
@@ -1,6 +1,7 @@
import './autosize';
import './bind_in_out';
import initCopyAsGFM from './copy_as_gfm';
+import initCopyToClipboard from './copy_to_clipboard';
import './details_behavior';
import installGlEmojiElement from './gl_emoji';
import './quick_submit';
@@ -9,3 +10,4 @@ import './toggler_behavior';
installGlEmojiElement();
initCopyAsGFM();
+initCopyToClipboard();