GitPaste

copy github && gist code quickly

Verze ze dne 12. 04. 2015. Zobrazit nejnovější verzi.

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