GitPaste

copy github && gist code quickly

As of 2015-04-12. See the latest version.

  1. // ==UserScript==
  2. // @name GitPaste
  3. // @author Hakurouken
  4. // @description copy github && gist code quickly
  5. // @namespace GitPaste/Hakurouken
  6. // @icon https://github.com/favicon.ico
  7. // @encoding utf-8
  8. // @date 12/04/2015
  9. // @include /^https?:\/\/github.com\/[\w-]+\/[\w_-]+\/blob\/.*/
  10. // @include /^https?:\/\/gist.github.com\/[\w-]+\/.*/
  11. // @grant GM_getResourceText
  12. // @grant GM_addStyle
  13. // @grant GM_setClipboard
  14. // @grant GM_xmlhttpRequest
  15. // @require http://code.jquery.com/jquery-2.1.3.min.js
  16. // @run-at document-end
  17. // @version 1.0
  18. // ==/UserScript==
  19.  
  20. this.$ = this.jQuery = jQuery.noConflict(true);
  21.  
  22. // jquery.eatost
  23. GM_addStyle(".toast-container{position:fixed;list-style:none;top:0;left:50%;z-index:999999;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:14px}.toast{line-height:20px;padding:5px 10px 5px 10px;border:1px solid transparent;border-radius:5px;-webkit-box-shadow:3px 3px 3px rgba(0,0,0,0.4);-moz-box-shadow:3px 3px 3px rgba(0,0,0,0.4);-o-box-shadow:3px 3px 3px rgba(0,0,0,0.4);box-shadow:3px 3px 3px rgba(0,0,0,0.4)}.toast .message{font-weight:bold;font-size:14px;line-height:20px}.toast button.close{position:relative;top:-1px;line-height:20px;float:right;padding:0;margin:0 -5px 0 5px;background:0;border:0;font-size:14px;color:rgba(0,0,0,.25);cursor:pointer;-webkit-transition:text-shadow .2s;-moz-transition:text-shadow .2s;-o-transition:text-shadow .2s;transition:text-shadow .2s}.toast button.close:hover{-webkit-text-shadow:0 0 2px rgba(0,0,0,.25);-moz-text-shadow:0 0 2px rgba(0,0,0,.25);-o-text-shadow:0 0 2px rgba(0,0,0,.25);text-shadow:0 0 2px rgba(0,0,0,.25)}.toast.default{color:#333;background-color:#fff;border-color:#ccc}.toast.success{background-color:#e0ebdb;border-color:#c9d7be;color:#4c914e}.toast.info{background-color:#d4e2ea;border-color:#bce8f1;color:#307fa3}.toast.warn{background-color:#eeefe2;border-color:#eadccd;color:#de9246}.toast.danger{background-color:#f2dede;border-color:#d0b9bc;color:#be4843}");
  24. (function ($) {
  25. var toast = {},
  26. tmpl = '<div class="toast"><button class="close">&times;</button><span class="message">{{text}}</span></div>';
  27.  
  28. // format the configuration
  29. function formatConf(config) {
  30. var _config = {
  31. duration: 3000,
  32. text: '',
  33. container: document.body,
  34. color: '#333',
  35. background: '#F5F5F5',
  36. border: 'none',
  37. style: '',
  38. autoclose: true,
  39. closeBtn: false,
  40. width: 'auto',
  41. animate: 'fade',
  42. align: 'top',
  43. speed: 'fast',
  44. opacity: 0.9,
  45. position: '20%'
  46. };
  47. var config;
  48.  
  49. if ($.isPlainObject(config)) {
  50. config = $.extend(_config, config);
  51. } else if ($.type(config) === 'string') {
  52. config = $.extend(_config, {
  53. text: config
  54. });
  55. } else {
  56. config = _config;
  57. }
  58.  
  59. config.animate = config.animate.toLowerCase();
  60. config.width = typeof config.width === 'number' ? config.width + 'px' : config.width;
  61. config.align = config.align.toLowerCase() === 'top' ? 'top' : 'bottom';
  62.  
  63. var totalHeight = config.container === document.body ? $(window).height : $(config.container).height();
  64. if ($.type(config.position) === 'string') {
  65. if (config.position.indexOf('%') === -1) {
  66. config.position = (parseInt(config.position) / totalHeight * 100) >> 0
  67. }
  68. config.position = isNaN(config.position) ? '20%' : config.position.toString();
  69. } else if ($.isNumber(config.position)) {
  70. config.position = (config.position / totalHeight * 100) >> 0
  71. }
  72. return config;
  73. }
  74.  
  75. function toastAnimation($wrapper, config) {
  76. var closeAnimation = function () {};
  77. switch (config.animate) {
  78. case 'slide':
  79. var start = {
  80. opacity: 0,
  81. top: config.align === 'top' ? 0 : "100%"
  82. };
  83. var end = {
  84. opacity: config.opacity,
  85. top: config.align === 'top' ? config.position : (100 - parseInt(config.position) + "%")
  86. };
  87.  
  88. $wrapper.css(start).show().css({
  89. 'margin-left': -$wrapper.width() / 2 + 'px'
  90. }).animate(end, config.speed);
  91.  
  92. closeAnimation = function () {
  93. $wrapper.animate(start, config.speed, function () {
  94. $wrapper.remove();
  95. });
  96. };
  97. break;
  98.  
  99. case 'fade':
  100. default:
  101. $wrapper.css({
  102. opacity: 0,
  103. top: config.align === 'top' ? config.position : (100 - parseInt(config.position) + "%")
  104. })
  105. .show()
  106. .css({
  107. 'margin-left': -$wrapper.width() / 2 + 'px'
  108. })
  109. .animate({
  110. opacity: config.opacity
  111. });
  112. closeAnimation = function () {
  113. $wrapper.fadeOut(config.speed,function(){
  114. $wrapper.remove();
  115. });
  116. };
  117. break;
  118. }
  119.  
  120. // deal with close && autoclose
  121. $wrapper.find('.close').click(function () {
  122. closeAnimation();
  123. });
  124. config.autoclose && setTimeout(function () {
  125. closeAnimation();
  126. }, config.duration);
  127. }
  128.  
  129. toast.show = function (config) {
  130. config = formatConf(config);
  131.  
  132. var html = tmpl.replace('{{text}}', config.text.toString()),
  133. $toast = $(html).appendTo($(config.container)).hide(),
  134. $wrapper = $toast.wrap('<div class="toast-container"></div>').parent().hide();
  135.  
  136. if (!config.style) {
  137. $toast.css({
  138. color: config.color,
  139. background: config.background,
  140. border: config.border,
  141. width: config.width
  142. });
  143. } else {
  144. $toast.addClass(config.style);
  145. }
  146.  
  147. !config.closeBtn && $toast.find('.close').hide();
  148. $toast.show();
  149. $wrapper.css(config.align, config.position);
  150. toastAnimation($wrapper, config);
  151. return $wrapper;
  152. }
  153.  
  154. $.each(['default', 'success', 'info', 'warn', 'danger'], function (i, prop) {
  155. toast[prop] = function (config) {
  156. var opt;
  157. if ($.isPlainObject(config)) {
  158. opt = config;
  159. opt.style = prop;
  160. } else if ($.type(config) === 'string') {
  161. opt = {
  162. style: prop,
  163. text: config
  164. }
  165. }
  166.  
  167. return toast.show(opt);
  168. }
  169. });
  170.  
  171. $.extend({
  172. toast: toast
  173. });
  174. })(jQuery);
  175.  
  176. (function($) {
  177. var addBtn = (function($){
  178. function addGithubBtn() {
  179. var $btns = $('.file-actions .btn-group'),
  180. link = $btns.find('#raw-url').attr('href');
  181.  
  182. $btns.prepend('<a id="git-paste-addons" class="btn btn-sm" data-link="' + link + '" href="javascript:void(0);">Copy</a>');
  183.  
  184. return $btns.find('#git-paste-addons');
  185. }
  186.  
  187. function addGistBtn(){
  188. var $btns = $('.files .actions .button-group');
  189.  
  190. $btns.each(function(i,elem){
  191. var $self = $(elem),
  192. link = $self.find('.raw-url').attr('href');
  193. $self.prepend('<a class="minibutton git-paste-addons" data-link="' + link + '" href="javascript:void(0);">Copy</a>');
  194. });
  195.  
  196. return $btns.find('.git-paste-addons');
  197. }
  198.  
  199. return function(){
  200. if( location.host.indexOf('gist.github.com') > -1 ){
  201. return addGistBtn();
  202. } else {
  203. return addGithubBtn();
  204. }
  205. }
  206. })($);
  207.  
  208. var copy = (function($){
  209. var _source = [];
  210.  
  211. function copyRemote(link,callback){
  212. GM_xmlhttpRequest({
  213. method: 'GET',
  214. url: link,
  215. onload: function(response) {
  216. $.toast.success("Copy Successfully.");
  217. GM_setClipboard(response.responseText);
  218. callback(response.responseText);
  219. _source.push({
  220. link: link,
  221. content: response.responseText
  222. });
  223. },
  224. onerror: function(response) {
  225. $.toast.error("Error occured, copy failed!");
  226. }
  227. });
  228. }
  229.  
  230. return function(link,callback){
  231. callback = callback || function(){};
  232. var content = null;
  233. $.each(_source,function(i,src){
  234. if( link === src.link ){
  235. content = src.content;
  236. }
  237. });
  238.  
  239. if( content ){
  240. $.toast.success("Copy Successfully.");
  241. GM_setClipboard(content);
  242. callback(content);
  243. } else {
  244. copyRemote(link,callback);
  245. }
  246. }
  247. })($);
  248.  
  249. var $copy = addBtn();
  250. $copy.click(function(e) {
  251. e.preventDefault();
  252. var $self = $(this),
  253. link = $self.data('link');
  254.  
  255. copy(link);
  256. });
  257.  
  258. })(jQuery);