Greasemonkey Mouse Gestures

Just a Mouse Gestures script

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name               Greasemonkey Mouse Gestures
// @name:zh-CN         油猴鼠标手势
// @name:zh-TW         油猴滑鼠手勢
// @namespace          hoothin
// @version            0.70
// @description        Just a Mouse Gestures script
// @description:zh-CN  就是个鼠标手势脚本
// @description:zh-TW  就是個滑鼠手勢脚本
// @author             hoothin
// @include            *
// @grant              GM_openInTab
// @grant              GM_setValue
// @grant              GM_getValue
// @grant              GM_registerMenuCommand
// @grant              unsafeWindow
// @grant              GM_info
// @license            MIT License
// @compatible        chrome
// @compatible        firefox
// ==/UserScript==

var lastX,lastY,lastSign,afterGestures,gesturesWords,gesturesContent,gestures,signs;
const defaultFun={
    close:()=>{unsafeWindow.opener=null;unsafeWindow.open('', '_self', '');unsafeWindow.close();},
    openNew:()=>{GM_openInTab('about:newtab', false)},
    scrollToTop:()=>{unsafeWindow.scrollTo(0, 0)},
    scrollToBottom:()=>{unsafeWindow.scrollTo(0, 1073741824)},
    back:()=>{unsafeWindow.history.back()},
    forward:()=>{unsafeWindow.history.forward()},
    reload:()=>{unsafeWindow.location.reload()}
};
function initEventListener(start,move,end,tracer,clientX,clientY,startBool){
    var isMouse=start=="mousedown";
    var moveFun=function(e){
        tracer(clientX(e),clientY(e),isMouse);
        gesturesWords.innerHTML=signs;
        var gesturesWidth=signs.length*51+40;
        gesturesContent.style.width=gesturesWidth+"px";
        gesturesContent.style.marginLeft=-gesturesWidth/2+"px";
    };
    document.addEventListener(start, function(e) {
        if(!startBool || startBool(e)){
            lastX=clientX(e);
            lastY=clientY(e);
            lastSign=signs="";
            document.addEventListener(move, moveFun, false);
        }
    }, false);
    var endFun=function(e) {
        document.removeEventListener(move, moveFun, false);
        setTimeout(function(){if(gesturesContent.parentNode)gesturesContent.parentNode.removeChild(gesturesContent);},500);
        if(signs){
            if(afterGestures)afterGestures();
            for(var g of gestures){
                var gSign=g.gesture;
                if(signs==gSign){
                    if(!isMouse)document.body.appendChild(gesturesContent);
                    var fun=defaultFun[g.fun];
                    if(fun===undefined || !fun){
                        eval(g.fun);
                    }else {
                        fun();
                    }
                    e.stopPropagation();
                    e.preventDefault();
                    e.returnValue=false;
                    e.cancelBubble=true;
                    return false;
                }
            }
            signs="";
        }
    };
    document.addEventListener(end, endFun, false);
    document.addEventListener("mouseup", endFun, false);
}
(function() {
    'use strict';
    var i18n;
    var lang = navigator.appName=="Netscape"?navigator.language:navigator.userLanguage;
    const minLength=256,tg=0.5;
    switch (lang){
        case "zh-CN":
            i18n={
                close:"关闭页面",
                openNew:"新建标签页",
                scrollToTop:"滚动至最上",
                scrollToBottom:"滚动至最下",
                back:"后退",
                forward:"前进",
                reload:"刷新",
                addListener:"点击监听鼠标手势",
                listening:"正在监听鼠标手势",
                bind:"绑定功能",
                custom:"自定义代码",
                ok:"确定",
                del:"删除",
                saved:"已设定的手势",
                alert1:"请先监听手势",
                alert2:"还没有绑定功能",
                alert3:"请输入自定义代码",
                configure:"鼠标手势设置",
                update:"鼠标手势脚本已更新,是否覆盖脚本设置?"
            };
            break;
        default:
            i18n={
                close:"Close tab",
                openNew:"Open new tab",
                scrollToTop:"Scroll to top",
                scrollToBottom:"Scroll to bottom",
                back:"Back",
                forward:"Forward",
                reload:"Reload",
                addListener:"Click to add gesture listener",
                listening:"Listening",
                bind:"Bind function",
                custom:"Custom code",
                ok:"Ok",
                del:"Delete",
                saved:"Saved gestures",
                alert1:"Please add gesture first",
                alert2:"Nothing bind",
                alert3:"Input custom code please",
                configure:"Mouse Gestures - Configure",
                update:"Greasemonkey Mouse Gestures has updated, recover config?"
            };
            break;
    }
    gestures=GM_getValue("gestures");
    if(GM_info.script.version != GM_getValue("gmMouseGestureVersion")){
        if(!gestures || window.confirm(i18n.update))
            gestures=[{gesture:"↓→",fun:"close"},
                  {gesture:"→↑",fun:"openNew"},
                  {gesture:"←↑",fun:"scrollToTop"},
                  {gesture:"←↓",fun:"scrollToBottom"},
                  {gesture:"→↑←",fun:"back"},
                  {gesture:"←↑→",fun:"forward"},
                  {gesture:"↑↓",fun:"reload"},
                  {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);}"},
                  {gesture:"↓↑↓←",fun:'var d=document,b=d.body;with(b.onselectstart=b.oncopy=b.onpaste=b.onkeydown=b.oncontextmenu=b.onmousemove=b.ondragstart=d.oncopy=d.onpaste=null,d.onselectstart=d.oncontextmenu=d.onmousedown=d.onkeydown=function(){return!0},d.wrappedJSObject||d)onmouseup=null,onmousedown=null,oncontextmenu=null;for(var a=d.getElementsByTagName("*"),i=a.length-1;i>=0;i--){var o=a[i];with(o.wrappedJSObject||o)onmouseup=null,onmousedown=null}var h=d.getElementsByTagName("head")[0];if(h){var s=d.createElement("style");s.innerHTML="html,*{user-select:text!important;-moz-user-select:text!important;-webkit-user-select:text!important;-webkit-user-drag:text!important;-khtml-user-select:text!important;-khtml-user-drag:text!important;pointer-events:auto!important;}",h.appendChild(s)}unsafeWindow.Event.prototype.preventDefault=function(){};'},
                  {gesture:"↓↑↓↑",fun:"var d = document, e = d.getElementById('wappalyzer-container') ; if ( e !== null ) { d.body.removeChild(e); } var u = 'https://wappalyzer.com/', 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/bookmarklet.css'); d.head.appendChild(l); p.setAttribute('id', 'wappalyzer-pending'); p.setAttribute('style', 'background-image: url(' + u + 'images/spinner.gif) !important'); c.appendChild(p); s.setAttribute('src', u + 'bookmarklet/wappalyzer.js'); s.onload = function() { s = d.createElement('script'); s.setAttribute('src', u + 'bookmarklet/apps.js'); s.onload = function() { s = d.createElement('script'); s.setAttribute('src', u + 'bookmarklet/driver.js'); c.appendChild(s); }; c.appendChild(s); }; c.appendChild(s); d.body.appendChild(c);"}
                 ];
        GM_setValue("gestures",gestures);
        GM_setValue("gmMouseGestureVersion",GM_info.script.version);
    }
    function tracer(curX,curY,showSign) {
        let distanceX=curX-lastX,distanceY=curY-lastY;
        let distance=distanceX*distanceX+distanceY*distanceY;
        if (distance>minLength) {
            lastX=curX;
            lastY=curY;
            let direction="";
            let slope=Math.abs(distanceY/distanceX);
            if(slope>tg){
                if(distanceY>0) {
                    direction="↓";
                }else{
                    direction="↑";
                }
            }else if(slope<=1/tg) {
                if(distanceX>0) {
                    direction="→";
                }else{
                    direction="←";
                }
            }
            if(lastSign!=direction) {
                signs+=direction;
                lastSign=direction;
                if(showSign)document.body.appendChild(gesturesContent);
            }
        }
    }
    gesturesContent=document.createElement("div");
    gesturesContent.id="gesturesContent";
    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;";
    gesturesContent.innerHTML='<div id="gesturesWords" style="position:absolute;left:20px;top:5px;font:bold 50px \'黑体\';color:#ffffff"></div>';
    gesturesWords=gesturesContent.querySelector("#gesturesWords");
    initEventListener("touchstart","touchmove","touchend",tracer,e=>{return e.changedTouches[0].clientX},e=>{return e.changedTouches[0].clientY});
    initEventListener("mousedown","mousemove","contextmenu",tracer,e=>{return e.clientX},e=>{return e.clientY},e=>{return e.which === 3});
    if(location.href=="https://github.com/hoothin/UserScripts/tree/master/Mouse%20Gestures"){
        var entryContent=document.querySelector("article.entry-content"),mobile=false;
        if(!entryContent){
            mobile=true;
            entryContent=document.querySelector(".files-list");
        }
        var configBody=document.createElement("div");
        configBody.id="configBody";
        configBody.style.cssText="opacity:0.65;filter:alpha(opacity=65);box-shadow:5px 5px 20px 0px #000;height:160px";
        configBody.innerHTML='<div id="configContent" style="position:relative;left:20px;top:5px;"></div>';
        var configContent=configBody.querySelector("#configContent");
        var newOrEdit=document.createElement("div");
        configContent.appendChild(newOrEdit);
        var newOrEditSign=document.createElement("div");
        newOrEditSign.innerHTML="";
        newOrEditSign.style.float="left";
        newOrEdit.appendChild(newOrEditSign);
        var newOrEditBtn=document.createElement("input");
        newOrEditBtn.type="button";
        newOrEditBtn.value=i18n.addListener;
        newOrEdit.appendChild(newOrEditBtn);
        var functionArea=document.createElement("p");
        newOrEdit.appendChild(functionArea);
        var functionSelect=document.createElement("select");
        functionSelect.innerHTML="<option>"+i18n.bind+"</option><option value='custom'>"+i18n.custom+"</option>";
        for(var key in defaultFun){
            var optionStr="<option value='"+key+"'>"+i18n[key]+"</option>";
            functionSelect.innerHTML+=optionStr;
        }
        functionArea.appendChild(functionSelect);
        var newOrEditEval=document.createElement("input");
        newOrEditEval.style.width=(mobile?"230":"750")+"px";
        newOrEditEval.style.display="none";
        functionArea.appendChild(newOrEditEval);
        var newOrEditOkBtn=document.createElement("input");
        newOrEditOkBtn.type="button";
        newOrEditOkBtn.value=i18n.ok;
        newOrEdit.appendChild(newOrEditOkBtn);
        var gesturesHas=document.createElement("p");
        newOrEdit.appendChild(gesturesHas);
        var gesturesSelect=document.createElement("select");
        var refreshGestures=function(){
            gesturesSelect.innerHTML="<option>"+i18n.saved+"</option>";
            gestures.forEach(function(item){
                var optionStr="<option value='"+item.gesture+"'>"+item.gesture+"</option>";
                gesturesSelect.innerHTML+=optionStr;
            });
        };
        refreshGestures();
        gesturesHas.appendChild(gesturesSelect);
        var newOrEditDelBtn=document.createElement("input");
        newOrEditDelBtn.type="button";
        newOrEditDelBtn.value=i18n.del;
        gesturesHas.appendChild(newOrEditDelBtn);
        entryContent.insertBefore(configBody,entryContent.firstChild);
        functionSelect.onchange=function(){
            if(functionSelect.options.selectedIndex===0)return;
            var value=functionSelect.options[functionSelect.options.selectedIndex].value;
            newOrEditEval.style.display=(value=="custom"?"initial":"none");
        };
        gesturesSelect.onchange=function(){
            if(gesturesSelect.options.selectedIndex===0)return;
            var value=gesturesSelect.options[gesturesSelect.options.selectedIndex].value;
            newOrEditSign.innerHTML=value;
            gestures.every(function(item){
                if(item.gesture==value){
                    functionSelect.options[1].selected = true;
                    for (var i=2;i<functionSelect.options.length;i++) {
                        if (functionSelect.options[i].value == item.fun) {
                            functionSelect.options[i].selected = true;
                            break;
                        }
                    }
                    functionSelect.onchange();
                    newOrEditEval.value=item.fun;
                    return false;
                }
                return true;
            });
        };
        newOrEditBtn.onclick=function(e){
            newOrEditBtn.value=i18n.listening;
            newOrEditBtn.setAttribute("disabled","disabled");
            afterGestures=function(){
                newOrEditBtn.removeAttribute("disabled");
                afterGestures=null;
                newOrEditSign.innerHTML=signs;
                newOrEditBtn.value=i18n.addListener;
            };
        };
        newOrEditOkBtn.onclick=function(e){
            if(!newOrEditSign.innerHTML){
                alert(i18n.alert1);
            }else if(functionSelect.options.selectedIndex===0){
                alert(i18n.alert2);
            }else {
                var op=functionSelect.options;
                var selIndex=op.selectedIndex;
                if(selIndex===1 && !newOrEditEval.value){
                    alert(i18n.alert3);
                }else{
                    var code=op[selIndex].value;
                    if(selIndex===1){
                        code=newOrEditEval.value;
                    }
                    for(var index in gestures){
                        if(gestures[index].gesture==newOrEditSign.innerHTML){
                            gestures.splice(index,1);
                            break;
                        }
                    }
                    gestures.push({gesture:newOrEditSign.innerHTML,fun:code});
                    GM_setValue("gestures",gestures);
                    refreshGestures();
                }
            }
        };
        newOrEditDelBtn.onclick=function(e){
            var value=gesturesSelect.options[gesturesSelect.options.selectedIndex].value;
            for(var index in gestures){
                if(gestures[index].gesture==value){
                    gestures.splice(index,1);
                    GM_setValue("gestures",gestures);
                    break;
                }
            }
            refreshGestures();
        };
    }
    function goSetting(){
        GM_openInTab("https://github.com/hoothin/UserScripts/tree/master/Mouse%20Gestures", false);
    }
    GM_registerMenuCommand(i18n.configure, goSetting);
})();