Greasemonkey Mouse Gestures

Just a Mouse Gestures

Mint 2017.02.18.. Lásd a legutóbbi verzió

  1. // ==UserScript==
  2. // @name Greasemonkey Mouse Gestures
  3. // @name:zh-CN 鼠标手势
  4. // @name:zh-TW 滑鼠手勢
  5. // @namespace hoothin
  6. // @version 0.61
  7. // @description Just a Mouse Gestures
  8. // @description:zh-CN 就是个鼠标手势
  9. // @description:zh-TW 就是個滑鼠手勢
  10. // @author hoothin
  11. // @include *
  12. // @grant GM_openInTab
  13. // @grant GM_setValue
  14. // @grant GM_getValue
  15. // @grant GM_registerMenuCommand
  16. // @grant unsafeWindow
  17. // @license MIT License
  18. // @compatible chrome
  19. // @compatible firefox
  20. // ==/UserScript==
  21.  
  22. (function() {
  23. 'use strict';
  24. var lastX, lastY, signs, lastSign, gestures, i18n;
  25. var lang = navigator.appName=="Netscape"?navigator.language:navigator.userLanguage;
  26. const minLength=256,tg=0.5,
  27. defaultFun={
  28. close:"unsafeWindow.opener=null;unsafeWindow.open('', '_self', '');unsafeWindow.close();",
  29. openNew:"GM_openInTab('about:newtab', false)",
  30. scrollToTop:"unsafeWindow.scrollTo(0, 0)",
  31. scrollToBottom:"unsafeWindow.scrollTo(0, 1073741824)",
  32. back:"unsafeWindow.history.back()",
  33. forward:"unsafeWindow.history.forward()",
  34. reload:"unsafeWindow.location.reload()"
  35. };
  36. switch (lang){
  37. case "zh-CN":
  38. i18n={
  39. close:"关闭页面",
  40. openNew:"新建标签页",
  41. scrollToTop:"滚动至最上",
  42. scrollToBottom:"滚动至最下",
  43. back:"后退",
  44. forward:"前进",
  45. reload:"刷新",
  46. addListener:"点击监听鼠标手势",
  47. listening:"正在监听鼠标手势",
  48. bind:"绑定功能",
  49. custom:"自定义代码",
  50. ok:"确定",
  51. del:"删除",
  52. saved:"已设定的手势",
  53. alert1:"请先监听手势",
  54. alert2:"还没有绑定功能",
  55. alert3:"请输入自定义代码",
  56. configure:"鼠标手势设置"
  57. };
  58. break;
  59. default:
  60. i18n={
  61. close:"Close tab",
  62. openNew:"Open new tab",
  63. scrollToTop:"Scroll to top",
  64. scrollToBottom:"Scroll to bottom",
  65. back:"Back",
  66. forward:"Forward",
  67. reload:"Reload",
  68. addListener:"Click to add gesture listener",
  69. listening:"Listening",
  70. bind:"Bind function",
  71. custom:"Custom code",
  72. ok:"Ok",
  73. del:"Delete",
  74. saved:"Saved gestures",
  75. alert1:"Please add gesture first",
  76. alert2:"Nothing bind",
  77. alert3:"Input custom code please",
  78. configure:"Mouse Gestures - Configure"
  79. };
  80. break;
  81. }
  82. gestures=GM_getValue("gestures");
  83. if(!gestures){
  84. gestures=[{gesture:"↓→",fun:"close"},
  85. {gesture:"→↑",fun:"openNew"},
  86. {gesture:"↑",fun:"scrollToTop"},
  87. {gesture:"↓",fun:"scrollToBottom"},
  88. {gesture:"←",fun:"back"},
  89. {gesture:"→",fun:"forward"},
  90. {gesture:"↑↓",fun:"reload"},
  91. {gesture:"↓↑↓",fun:"var t=((unsafeWindow.getSelection&&unsafeWindow.getSelection())||(document.getSelection&&document.getSelection())||(document.selection&&document.selection.createRange&&document.selection.createRange().text));var e=(document.charset||document.characterSet);if(t!=''){GM_openInTab('http://translate.google.cn/?text='+t+'&hl=zh-CN&langpair=auto|zh-CN&tbb=1&ie='+e,false);}else{GM_openInTab('http://translate.google.cn/translate?u='+encodeURIComponent(location.href)+'&hl=zh-CN&langpair=auto|zh-CN&tbb=1&ie='+e,false);}"},
  92. {gesture:"↓↑↓←",fun:'function R(a){var ona = "on"+a; if(unsafeWindow.addEventListener) unsafeWindow.addEventListener(a, function (e) { for(var n=e.originalTarget; n; n=n.parentNode) n[ona]=null; }, true); unsafeWindow[ona]=null; document[ona]=null; if(document.body) document.body[ona]=null; } R("contextmenu"); R("click"); R("mousedown"); R("mouseup"); R("selectstart");'},
  93. {gesture:"↓↑↓↑",fun:"var d = document, e = d.getElementById('wappalyzer-container') ; if ( e !== null ) { d.body.removeChild(e); } var u = 'https://wappalyzer.com/bookmarklet/', t = new Date().getTime(), c = d.createElement('div'), p = d.createElement('div'), l = d.createElement('link'), s = d.createElement('script') ; c.setAttribute('id', 'wappalyzer-container'); l.setAttribute('rel', 'stylesheet'); l.setAttribute('href', u + 'css/wappalyzer.css'); d.head.appendChild(l); p.setAttribute('id', 'wappalyzer-pending'); p.setAttribute('style', 'background-image: url(' + u + 'images/pending.gif) !important'); c.appendChild(p); s.setAttribute('src', u + 'js/wappalyzer.js?' + t); s.onload = function() { s = d.createElement('script'); s.setAttribute('src', u + 'js/apps.js?' + t); s.onload = function() { s = d.createElement('script'); s.setAttribute('src', u + 'js/driver.js?' + t); c.appendChild(s); }; c.appendChild(s); }; c.appendChild(s); d.body.appendChild(c);"},
  94. {gesture:"↓↑↓→",fun:"GM_openInTab('http://just998.com/xiu/photo'+unsafeWindow.location.search,false)"}
  95. ];
  96. GM_setValue("gestures",gestures);
  97. }
  98. function tracer(curX,curY,showSign) {
  99. let distanceX=curX-lastX,distanceY=curY-lastY;
  100. let distance=distanceX*distanceX+distanceY*distanceY;
  101. if (distance>minLength) {
  102. lastX=curX;
  103. lastY=curY;
  104. let direction="";
  105. let slope=Math.abs(distanceY/distanceX);
  106. if(slope>tg){
  107. if(distanceY>0) {
  108. direction="↓";
  109. }else{
  110. direction="↑";
  111. }
  112. }else if(slope<=1/tg) {
  113. if(distanceX>0) {
  114. direction="→";
  115. }else{
  116. direction="←";
  117. }
  118. }
  119. if(lastSign!=direction) {
  120. signs+=direction;
  121. lastSign=direction;
  122. if(showSign)document.body.appendChild(gesturesContent);
  123. }
  124. }
  125. }
  126. function initEventListener(start,move,end,clientX,clientY,startBool){
  127. var isMouse=start=="mousedown";
  128. var moveFun=function(e){
  129. tracer(eval(clientX),eval(clientY),isMouse);
  130. gesturesWords.innerHTML=signs;
  131. var gesturesWidth=signs.length*51+40;
  132. gesturesContent.style.width=gesturesWidth+"px";
  133. gesturesContent.style.marginLeft=-gesturesWidth/2+"px";
  134. };
  135. document.addEventListener(start, function(e) {
  136. if(!startBool || eval(startBool)){
  137. lastX=eval(clientX);
  138. lastY=eval(clientY);
  139. lastSign=signs="";
  140. document.addEventListener(move, moveFun, false);
  141. }
  142. }, false);
  143. document.addEventListener(end, function(e) {
  144. document.removeEventListener(move, moveFun, false);
  145. setTimeout(function(){if(gesturesContent.parentNode)gesturesContent.parentNode.removeChild(gesturesContent);},500);
  146. if(afterGestures)afterGestures();
  147. for(var g of gestures){
  148. var gSign=g.gesture;
  149. if(signs==gSign){
  150. if(!isMouse)document.body.appendChild(gesturesContent);
  151. var fun=defaultFun[g.fun];
  152. if(!fun){
  153. eval(g.fun);
  154. }
  155. eval(fun);
  156. e.stopPropagation();
  157. e.preventDefault();
  158. break;
  159. }
  160. }
  161. }, false);
  162. }
  163. initEventListener("touchstart","touchmove","touchend","e.changedTouches[0].clientX","e.changedTouches[0].clientY");
  164. initEventListener("mousedown","mousemove","contextmenu","e.clientX","e.clientY","e.which === 3");
  165. var afterGestures;
  166. var gesturesContent=document.createElement("div");
  167. gesturesContent.id="gesturesContent";
  168. gesturesContent.style.cssText="width:300px;height:70px;position:fixed;left:50%;top:50%;margin-top:-25px;margin-left:-150px;z-index:999999999;background-color:#000;border:1px solid;border-radius:10px;opacity:0.65;filter:alpha(opacity=65);box-shadow:5px 5px 20px 0px #000;";
  169. gesturesContent.innerHTML='<div id="gesturesWords" style="position:absolute;left:20px;top:5px;font:bold 50px \'黑体\';color:#ffffff"></div>';
  170. var gesturesWords=gesturesContent.querySelector("#gesturesWords");
  171. if(location.href=="https://github.com/hoothin/UserScripts/tree/master/Mouse%20Gestures"){
  172. var entryContent=document.querySelector("article.entry-content"),mobile=false;
  173. if(!entryContent){
  174. mobile=true;
  175. entryContent=document.querySelector(".files-list");
  176. }
  177. var configBody=document.createElement("div");
  178. configBody.id="configBody";
  179. configBody.style.cssText="opacity:0.65;filter:alpha(opacity=65);box-shadow:5px 5px 20px 0px #000;height:160px";
  180. configBody.innerHTML='<div id="configContent" style="position:relative;left:20px;top:5px;"></div>';
  181. var configContent=configBody.querySelector("#configContent");
  182. var newOrEdit=document.createElement("div");
  183. configContent.appendChild(newOrEdit);
  184. var newOrEditSign=document.createElement("div");
  185. newOrEditSign.innerHTML="";
  186. newOrEditSign.style.float="left";
  187. newOrEdit.appendChild(newOrEditSign);
  188. var newOrEditBtn=document.createElement("input");
  189. newOrEditBtn.type="button";
  190. newOrEditBtn.value=i18n.addListener;
  191. newOrEdit.appendChild(newOrEditBtn);
  192. var functionArea=document.createElement("p");
  193. newOrEdit.appendChild(functionArea);
  194. var functionSelect=document.createElement("select");
  195. functionSelect.innerHTML="<option>"+i18n.bind+"</option><option value='custom'>"+i18n.custom+"</option>";
  196. for(var key in defaultFun){
  197. var optionStr="<option value='"+key+"'>"+i18n[key]+"</option>";
  198. functionSelect.innerHTML+=optionStr;
  199. }
  200. functionArea.appendChild(functionSelect);
  201. var newOrEditEval=document.createElement("input");
  202. newOrEditEval.style.width=(mobile?"230":"750")+"px";
  203. newOrEditEval.style.display="none";
  204. functionArea.appendChild(newOrEditEval);
  205. var newOrEditOkBtn=document.createElement("input");
  206. newOrEditOkBtn.type="button";
  207. newOrEditOkBtn.value=i18n.ok;
  208. newOrEdit.appendChild(newOrEditOkBtn);
  209. var gesturesHas=document.createElement("p");
  210. newOrEdit.appendChild(gesturesHas);
  211. var gesturesSelect=document.createElement("select");
  212. var refreshGestures=function(){
  213. gesturesSelect.innerHTML="<option>"+i18n.saved+"</option>";
  214. gestures.forEach(function(item){
  215. var optionStr="<option value='"+item.gesture+"'>"+item.gesture+"</option>";
  216. gesturesSelect.innerHTML+=optionStr;
  217. });
  218. };
  219. refreshGestures();
  220. gesturesHas.appendChild(gesturesSelect);
  221. var newOrEditDelBtn=document.createElement("input");
  222. newOrEditDelBtn.type="button";
  223. newOrEditDelBtn.value=i18n.del;
  224. gesturesHas.appendChild(newOrEditDelBtn);
  225. entryContent.insertBefore(configBody,entryContent.firstChild);
  226. functionSelect.onchange=function(){
  227. if(functionSelect.options.selectedIndex===0)return;
  228. var value=functionSelect.options[functionSelect.options.selectedIndex].value;
  229. newOrEditEval.style.display=(value=="custom"?"initial":"none");
  230. };
  231. gesturesSelect.onchange=function(){
  232. if(gesturesSelect.options.selectedIndex===0)return;
  233. var value=gesturesSelect.options[gesturesSelect.options.selectedIndex].value;
  234. newOrEditSign.innerHTML=value;
  235. gestures.every(function(item){
  236. if(item.gesture==value){
  237. functionSelect.options[1].selected = true;
  238. for (var i=2;i<functionSelect.options.length;i++) {
  239. if (functionSelect.options[i].value == item.fun) {
  240. functionSelect.options[i].selected = true;
  241. break;
  242. }
  243. }
  244. functionSelect.onchange();
  245. newOrEditEval.value=item.fun;
  246. return false;
  247. }
  248. return true;
  249. });
  250. };
  251. newOrEditBtn.onclick=function(e){
  252. newOrEditBtn.value=i18n.listening;
  253. newOrEditBtn.setAttribute("disabled","disabled");
  254. afterGestures=function(){
  255. newOrEditBtn.removeAttribute("disabled");
  256. afterGestures=null;
  257. newOrEditSign.innerHTML=signs;
  258. newOrEditBtn.value=i18n.addListener;
  259. };
  260. };
  261. newOrEditOkBtn.onclick=function(e){
  262. if(!newOrEditSign.innerHTML){
  263. alert(i18n.alert1);
  264. }else if(functionSelect.options.selectedIndex===0){
  265. alert(i18n.alert2);
  266. }else {
  267. var op=functionSelect.options;
  268. var selIndex=op.selectedIndex;
  269. if(selIndex===1 && !newOrEditEval.value){
  270. alert(i18n.alert3);
  271. }else{
  272. var code=op[selIndex].value;
  273. if(selIndex===1){
  274. code=newOrEditEval.value;
  275. }
  276. for(var index in gestures){
  277. if(gestures[index].gesture==newOrEditSign.innerHTML){
  278. gestures.splice(index,1);
  279. break;
  280. }
  281. }
  282. gestures.push({gesture:newOrEditSign.innerHTML,fun:code});
  283. GM_setValue("gestures",gestures);
  284. refreshGestures();
  285. }
  286. }
  287. };
  288. newOrEditDelBtn.onclick=function(e){
  289. var value=gesturesSelect.options[gesturesSelect.options.selectedIndex].value;
  290. for(var index in gestures){
  291. if(gestures[index].gesture==value){
  292. gestures.splice(index,1);
  293. break;
  294. }
  295. }
  296. refreshGestures();
  297. };
  298. }
  299. function goSetting(){
  300. location.href="https://github.com/hoothin/UserScripts/tree/master/Mouse%20Gestures";
  301. }
  302. GM_registerMenuCommand(i18n.configure, goSetting);
  303. })();