From ad3f805d2ff3a36ab0caa4aa0a2285badea2cc39 Mon Sep 17 00:00:00 2001
From: Kane York <rikingcoding@gmail.com>
Date: Tue, 21 Jul 2015 09:58:05 -0700
Subject: [PATCH] FIX: Do automatic copy on share in click handler

---
 .../discourse/lib/copy-text.js.es6            | 34 +++++++++++++++++++
 .../javascripts/discourse/templates/share.hbs |  1 +
 .../javascripts/discourse/views/share.js.es6  | 33 ++++++------------
 3 files changed, 46 insertions(+), 22 deletions(-)
 create mode 100644 app/assets/javascripts/discourse/lib/copy-text.js.es6

diff --git a/app/assets/javascripts/discourse/lib/copy-text.js.es6 b/app/assets/javascripts/discourse/lib/copy-text.js.es6
new file mode 100644
index 00000000000..87303623397
--- /dev/null
+++ b/app/assets/javascripts/discourse/lib/copy-text.js.es6
@@ -0,0 +1,34 @@
+/**
+ * Copy text to the clipboard. Must be called from within a user gesture (Chrome).
+ */
+export default function(text, element) {
+  let supported = false;
+  try {
+    // Chrome: This only returns true within a user gesture.
+    // Chrome: queryCommandEnabled() only returns true if a selection is
+    //   present, so we use queryCommandSupported() instead for the fail-fast.
+    if (document.queryCommandSupported('copy')) {
+      supported = true;
+    }
+  } catch (e) {
+    // Ignore
+  }
+  if (!supported) {
+    return;
+  }
+
+  let newRange = document.createRange();
+  newRange.selectNode(element);
+  const selection = window.getSelection();
+  selection.removeAllRanges();
+  selection.addRange(newRange);
+
+  try {
+    if (document.execCommand("copy")) {
+      return true;
+    }
+  } catch (e) {
+    // Ignore
+  }
+  return false;
+}
diff --git a/app/assets/javascripts/discourse/templates/share.hbs b/app/assets/javascripts/discourse/templates/share.hbs
index cdc48cfb581..5bd54e1d599 100644
--- a/app/assets/javascripts/discourse/templates/share.hbs
+++ b/app/assets/javascripts/discourse/templates/share.hbs
@@ -19,3 +19,4 @@
     <a href {{action "close"}} aria-label='{{i18n 'share.close'}}' title='{{i18n 'share.close'}}'>{{fa-icon "times-circle"}}</a>
   </div>
 {{/if}}
+<span class="hidden" id="copy-target"></span>
diff --git a/app/assets/javascripts/discourse/views/share.js.es6 b/app/assets/javascripts/discourse/views/share.js.es6
index ab052c2c5c2..91c9c89ae00 100644
--- a/app/assets/javascripts/discourse/views/share.js.es6
+++ b/app/assets/javascripts/discourse/views/share.js.es6
@@ -1,3 +1,5 @@
+import copyText from 'discourse/lib/copy-text';
+
 export default Discourse.View.extend({
   templateName: 'share',
   elementId: 'share-link',
@@ -18,34 +20,13 @@ export default Discourse.View.extend({
     return null;
   }.property('controller.link'),
 
-  copyLink($element) {
-    const element = $element[0];
-    try {
-      if (document.queryCommandSupported('copy')) {
-        let newRange = document.createRange();
-        newRange.selectNode(element);
-        const selection = window.getSelection();
-        selection.removeAllRanges();
-        selection.addRange(newRange);
-
-        if (document.execCommand("copy")) {
-          this.set('controller.copied', true);
-        }
-      }
-    } catch (e) {
-      // Ignore
-    }
-  },
-
   linkChanged: function() {
     const self = this;
-    this.set('controller.copied', false);
     if (this.present('controller.link')) {
       Em.run.next(function() {
         if (!self.capabilities.touch) {
           var $linkInput = $('#share-link input');
           $linkInput.val(self.get('controller.link'));
-          self.copyLink($linkInput);
 
           // Wait for the fade-in transition to finish before selecting the link:
           window.setTimeout(function() {
@@ -55,7 +36,6 @@ export default Discourse.View.extend({
           var $linkForTouch = $('#share-link .share-for-touch a');
           $linkForTouch.attr('href',self.get('controller.link'));
           $linkForTouch.html(self.get('controller.link'));
-          self.copyLink($linkForTouch);
         }
       });
     }
@@ -83,6 +63,7 @@ export default Discourse.View.extend({
       var $currentTarget = $(e.currentTarget),
           $currentTargetOffset = $currentTarget.offset(),
           $shareLink = $('#share-link'),
+          copyElement = document.getElementById('copy-target'),
           url = $currentTarget.data('share-url'),
           postNumber = $currentTarget.data('post-number'),
           date = $currentTarget.children().data('time');
@@ -113,10 +94,18 @@ export default Discourse.View.extend({
         $shareLink.css({left: "" + x + "px"});
       }
 
+      self.set('controller.copied', false);
+
+      const copySuccess = copyText(url, copyElement);
+
       self.set('controller.link', url);
       self.set('controller.postNumber', postNumber);
       self.set('controller.date', date);
 
+      Ember.run.later(null, function() {
+        self.set('controller.copied', copySuccess);
+      }, 50);
+
       return false;
     });