Github Mirror Jumper

在检测到选中文本包含guihub.com地址,会弹出镜像地址按钮,点击打开新窗口

  1. // ==UserScript==
  2. // @name Github Mirror Jumper
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.0.1
  5. // @description 在检测到选中文本包含guihub.com地址,会弹出镜像地址按钮,点击打开新窗口
  6. // @author fightplane
  7. // @match *://*/*
  8. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16. const enums = {
  17. STORE_NAME: 'GithubMirrorJumper',
  18. VERSION: 0.01,
  19. };
  20. const gobleData = {
  21. githubBox: {},
  22. jumpPointer: {},
  23. data: {
  24. mirrorList: [
  25. {
  26. name: 'FastGit',
  27. url: 'https://hub.fgit.cf'
  28. }
  29. ],
  30. currentMirror: 'FastGit',
  31. matchUrl: 'github.com',
  32. version: enums.VERSION,
  33. },
  34. error: "",
  35. };
  36.  
  37. // Your code here...
  38. try{
  39. initail(gobleData, enums);
  40. initailData(gobleData, enums);
  41. setPositionAndText(gobleData, enums);
  42. } catch(e) {
  43. console.log(e);
  44. }
  45. })();
  46.  
  47.  
  48. function initail(gobleData, enums) {
  49. const { mirrorList } = gobleData.data;
  50. const { STORE_NAME } = enums;
  51. const githubBox = document.createElement('div');
  52. gobleData.githubBox = githubBox; // 设置全局变量
  53. githubBox.id = 'github-mirror-jumper';
  54. githubBox.style.minWidth = '120px';
  55. githubBox.style.fontSize = '16px';
  56. githubBox.style.display = 'inline-block';
  57. githubBox.style.position = 'fixed';
  58. githubBox.style.zIndex = '9999';
  59. githubBox.style.top = '50px';
  60. gobleData.githubBox.style.visibility = 'hidden';
  61.  
  62. githubBox.innerHTML = `
  63. <div id="memu-pointer" style="line-height: 1em;vertical-align: bottom;font-size:0.7em; display: inline; background-color: #24292f; color: #fff; padding: 0px 4px; border-top-right-radius: 4px;">Github Mirror Jumper</div>
  64. <div id="jump-pointer">
  65. <p style="margin: 0px; background-color: #30a14e; color: #fff; padding: 2px;border-top-right-radius: 4px; border-bottom-right-radius: 4px;box-shadow: inset 0px -8px 5px rgb(0 0 0/0.5);cursor: pointer;">
  66. To:<span id="url" style="padding: 0 4px 0 0">${mirrorList[0].url}</span></p>
  67. </div>
  68. `;
  69.  
  70. document.body.appendChild(githubBox);
  71. const jumpPointer = githubBox.querySelector('#jump-pointer');
  72. if (jumpPointer){
  73. gobleData.jumpPointer = jumpPointer; // 设置全局参数
  74. jumpPointer.addEventListener('click', (e) => {
  75. window.open(gobleData.jumpPointer.querySelector('#url').innerText);
  76. });
  77. }
  78.  
  79. const memuPointer = githubBox.querySelector('#memu-pointer');
  80. if (memuPointer) {
  81. memuPointer.addEventListener('click', (e) => {
  82. console.log(e);
  83. });
  84. }
  85. }
  86.  
  87. // init data struct
  88. function initailData(gobleData, enums) {
  89. const { data, jumpPointer } = gobleData;
  90. const { STORE_NAME, VERSION } = enums;
  91.  
  92. if (!GM_getValue(STORE_NAME)) {
  93. GM_setValue(STORE_NAME, JSON.stringify(data));
  94. } else {
  95. let storeData = GM_getValue(STORE_NAME);
  96. storeData = JSON.parse(storeData);
  97. const mirror = storeData.mirrorList.find(i => i.name === storeData.currentMirror);
  98. jumpPointer.querySelector('#url').innerText = `${mirror && mirror.url || storeData.mirrorList[0].url}`;
  99.  
  100. if (storeData.version < VERSION){
  101. GM_setValue(STORE_NAME, JSON.stringify(data));
  102. }
  103. }
  104. }
  105.  
  106. // setPosition and text
  107. function setPositionAndText(gobleData, enums){
  108. const { matchUrl } = gobleData.data;
  109. const { githubBox, jumpPointer }= gobleData;
  110. const { STORE_NAME } = enums;
  111.  
  112. document.body.addEventListener('mouseup', (e) => {
  113. setTimeout(() => {
  114. try {
  115. // 设置文本
  116. const selectedText = window.getSelection().toString().trim();
  117. if (!selectedText) {
  118. githubBox.style.visibility = 'hidden';
  119. return;
  120. }
  121. const reg = new RegExp(`${matchUrl}\\S+`, 'ig');
  122. // const reg2 = new RegExp(`\^${matchUrl}\\S+`, 'ig');
  123. const matchStr = (selectedText && selectedText.match(reg)) || null;
  124. if (matchStr){
  125. // 设置位置
  126. githubBox.style.top = (e.clientY - githubBox.clientHeight * 1.2) + 'px';
  127. githubBox.style.left = (e.clientX + 24) + 'px';
  128. githubBox.style.visibility = 'visible';
  129. const urlStr = matchStr[0].substring(matchUrl.length);
  130. let storeData = GM_getValue(STORE_NAME);
  131. if (storeData) {
  132. storeData = JSON.parse(storeData);
  133. const mirror = storeData.mirrorList.find(i => i.name === storeData.currentMirror);
  134. jumpPointer.querySelector('#url').innerText = `${mirror && mirror.url || storeData.mirrorList[0].url}${urlStr}`;
  135. } else {
  136. jumpPointer.querySelector('#url').innerText = `${storeData.mirrorList[0].url}${urlStr}`;
  137. }
  138. } else {
  139. githubBox.style.visibility = 'hidden';
  140. }
  141. gobleData.error = null; // 无错误
  142. } catch (e) {
  143. gobleData.error = e;
  144. // githubBox.style.background = "red";
  145. // githubBox.style.color = "white";
  146. // githubBox.innerText = `Github Mirror Jumper 插件出现异常,您可以关闭此插件,并向作者反馈,感谢使用!`;
  147. // githubBox.style.visibility = 'visible';
  148. }
  149. }, 100);
  150. });
  151. }