1 // Import support https://stackoverflow.com/questions/13673346/supporting-both-commonjs-and-amd 2 (function(name, definition) { 3 if (typeof module != "undefined") module.exports = definition(); 4 else if (typeof define == "function" && typeof define.amd == "object") define(definition); 5 else this[name] = definition(); 6 }("clipboard", function() { 7 if (!document.addEventListener) { 8 return null; 9 } 10 11 var clipboard = {}; 12 13 clipboard.copy = (function() { 14 var _intercept = false; 15 var _data; // Map from data type (e.g. "text/html") to value. 16 17 document.addEventListener("copy", function(e){ 18 if (_intercept) { 19 _intercept = false; 20 for (var key in _data) { 21 e.clipboardData.setData(key, _data[key]); 22 } 23 e.preventDefault(); 24 } 25 }); 26 27 return function(data) { 28 return new Promise(function(resolve, reject) { 29 _intercept = true; 30 if (typeof data === "string") { 31 _data = {"text/plain": data}; 32 } else if (data instanceof Node) { 33 _data = {"text/html": new XMLSerializer().serializeToString(data)}; 34 } else { 35 _data = data; 36 } 37 try { 38 if (document.execCommand("copy")) { 39 // document.execCommand is synchronous: http://www.w3.org/TR/2015/WD-clipboard-apis-20150421/#integration-with-rich-text-editing-apis 40 // So we can call resolve() back here. 41 resolve(); 42 } 43 else { 44 _intercept = false; 45 reject(new Error("Unable to copy. Perhaps it's not available in your browser?")); 46 } 47 } 48 catch (e) { 49 _intercept = false; 50 reject(e); 51 } 52 }); 53 }; 54 }()); 55 56 clipboard.paste = (function() { 57 var _intercept = false; 58 var _resolve; 59 var _dataType; 60 61 document.addEventListener("paste", function(e) { 62 if (_intercept) { 63 _intercept = false; 64 e.preventDefault(); 65 _resolve(e.clipboardData.getData(_dataType)); 66 } 67 }); 68 69 return function(dataType) { 70 return new Promise(function(resolve, reject) { 71 _intercept = true; 72 _resolve = resolve; 73 _dataType = dataType || "text/plain"; 74 try { 75 if (!document.execCommand("paste")) { 76 _intercept = false; 77 reject(new Error("Unable to paste. Pasting only works in Internet Explorer at the moment.")); 78 } 79 } catch (e) { 80 _intercept = false; 81 reject(new Error(e)); 82 } 83 }); 84 }; 85 }()); 86 87 // Handle IE behaviour. 88 if (typeof ClipboardEvent === "undefined" && 89 typeof window.clipboardData !== "undefined" && 90 typeof window.clipboardData.setData !== "undefined") { 91 92 /*! promise-polyfill 2.0.1 */ 93 (function(a){function b(a,b){return function(){a.apply(b,arguments)}}function c(a){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof a)throw new TypeError("not a function");this._state=null,this._value=null,this._deferreds=[],i(a,b(e,this),b(f,this))}function d(a){var b=this;return null===this._state?void this._deferreds.push(a):void j(function(){var c=b._state?a.onFulfilled:a.onRejected;if(null===c)return void(b._state?a.resolve:a.reject)(b._value);var d;try{d=c(b._value)}catch(e){return void a.reject(e)}a.resolve(d)})}function e(a){try{if(a===this)throw new TypeError("A promise cannot be resolved with itself.");if(a&&("object"==typeof a||"function"==typeof a)){var c=a.then;if("function"==typeof c)return void i(b(c,a),b(e,this),b(f,this))}this._state=!0,this._value=a,g.call(this)}catch(d){f.call(this,d)}}function f(a){this._state=!1,this._value=a,g.call(this)}function g(){for(var a=0,b=this._deferreds.length;b>a;a++)d.call(this,this._deferreds[a]);this._deferreds=null}function h(a,b,c,d){this.onFulfilled="function"==typeof a?a:null,this.onRejected="function"==typeof b?b:null,this.resolve=c,this.reject=d}function i(a,b,c){var d=!1;try{a(function(a){d||(d=!0,b(a))},function(a){d||(d=!0,c(a))})}catch(e){if(d)return;d=!0,c(e)}}var j=c.immediateFn||"function"==typeof setImmediate&&setImmediate||function(a){setTimeout(a,1)},k=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)};c.prototype["catch"]=function(a){return this.then(null,a)},c.prototype.then=function(a,b){var e=this;return new c(function(c,f){d.call(e,new h(a,b,c,f))})},c.all=function(){var a=Array.prototype.slice.call(1===arguments.length&&k(arguments[0])?arguments[0]:arguments);return new c(function(b,c){function d(f,g){try{if(g&&("object"==typeof g||"function"==typeof g)){var h=g.then;if("function"==typeof h)return void h.call(g,function(a){d(f,a)},c)}a[f]=g,0===--e&&b(a)}catch(i){c(i)}}if(0===a.length)return b([]);for(var e=a.length,f=0;f<a.length;f++)d(f,a[f])})},c.resolve=function(a){return a&&"object"==typeof a&&a.constructor===c?a:new c(function(b){b(a)})},c.reject=function(a){return new c(function(b,c){c(a)})},c.race=function(a){return new c(function(b,c){for(var d=0,e=a.length;e>d;d++)a[d].then(b,c)})},"undefined"!=typeof module&&module.exports?module.exports=c:a.Promise||(a.Promise=c)})(this); 94 95 clipboard.copy = function(data) { 96 return new Promise(function(resolve, reject) { 97 // IE supports string and URL types: https://msdn.microsoft.com/en-us/library/ms536744(v=vs.85).aspx 98 // We only support the string type for now. 99 if (typeof data !== "string" && !("text/plain" in data)) { 100 throw new Error("You must provide a text/plain type.") 101 } 102 103 var strData = (typeof data === "string" ? data : data["text/plain"]); 104 var copySucceeded = window.clipboardData.setData("Text", strData); 105 copySucceeded ? resolve() : reject(new Error("Copying was rejected.")); 106 }); 107 }; 108 109 clipboard.paste = function(data) { 110 return new Promise(function(resolve, reject) { 111 var strData = window.clipboardData.getData("Text"); 112 if (strData) { 113 resolve(strData); 114 } else { 115 // The user rejected the paste request. 116 reject(new Error("Pasting was rejected.")); 117 } 118 }); 119 }; 120 } 121 122 return clipboard; 123 })); 124