kidzgy
火狐狸
火狐狸
  • UID35190
  • 注册日期2011-02-03
  • 最后登录2024-03-28
  • 发帖数248
  • 经验196枚
  • 威望0点
  • 贡献值122点
  • 好评度17点
阅读:1307回复:2

求修复FF60 MouseGestures.uc的摇杆手势功能

楼主#
更多 发布于:2018-11-23 02:40
FF60,该脚本取自RunningCheese Firefox V10,UC的好处就是可以在FF内页也能照常使用,但目前唯独缺少摇杆手势功能,比方说:(1)按住左键再点击右键;(2)按住右键再点击左键。
我之前的FF53版本中,是使用FireGestures来实现的。目前发现这个脚本缺少了摇杆手势的相关代码,苦于对JS代码一无所知,不知怎么修改修复,特此来请教各路神仙。
目前提供一个feiruo完善的一个手势脚本的线索,https://github.com/feiruo/userChromeJS/blob/master/MouseGestures/MouseGestures.uc.js,但直接使用这个版本在60是无法生效,在53能生效,而且手势滑动也不如RunningCheese Firefox V10来得流畅。我希望以RunningCheese Firefox V10的作为一个修改蓝本,因为这个在60已能流畅使用,唯独缺少这两个手势而已。谢谢!
下方的L<R,L>R便是摇杆手势;W- W+是鼠标滑轮。

// ==UserScript==
// @name                 Mousegestures.uc.js
// @namespace            Mousegestures@gmail.com
// @description          自定义鼠标手势,自用 DIY版
// @author               紫云飞&黒仪大螃蟹
// @homepageURL          http://www.cnblogs.com/ziyunfei/archive/2011/12/15/2289504.html
// @include              chrome://browser/content/browser.xul
// @charset              UTF-8
// ==/UserScript==
(() =&gt; {
    'use strict';
    let ucjsMouseGestures = {
        lastX: 0,
        lastY: 0,
        directionChain: '',
        isMouseDownL: false,
        isMouseDownR: false,
        hideFireContext: false,
        shouldFireContext: false,
        GESTURES: {
            'L&lt;R': {name: '关闭当前标签', cmd: function(event) {gBrowser.removeCurrentTab();}},
            'L&gt;R': {name: '恢复关闭的标签', cmd:  function() { try {    document.getElementById('History:UndoCloseTab').doCommand();} catch (ex) {if ('undoRemoveTab' in gBrowser) gBrowser.undoRemoveTab();    else throw "Session Restore feature is disabled."}  } },
     
            'W-': {name: '滚动到顶部', cmd: () =&gt; goDoCommand('cmd_scrollTop')},
            'W+': {name: '滚动到底部', cmd: () =&gt; goDoCommand('cmd_scrollBottom')},
     
            'L': {name: '后退', cmd: () =&gt; getWebNavigation().canGoBack && getWebNavigation().goBack()},
            'R': {name: '前进', cmd: () =&gt; getWebNavigation().canGoForward && getWebNavigation().goForward()},
     
     
            'U': {name: '向上滚动', cmd: () =&gt; goDoCommand('cmd_scrollPageUp')},
            'D': {name: '向下滚动', cmd: () =&gt; goDoCommand('cmd_scrollPageDown')},
     
     
            'UD': {name: '刷新', cmd: function() {document.getElementById("Browser:Reload").doCommand();}},
            'DU': {name: '网址向上一层', cmd:  function() { loadURI(content.location.host + content.location.pathname.replace(/\/[^\/]+\/?$/, ""));}},
            'UDUD': {name: '跳过缓存刷新当前页面', cmd: function() {document.getElementById("Browser:ReloadSkipCache").doCommand();}},
     
     
            'LR': {name: '关闭当前标签', cmd: function(event) {gBrowser.removeCurrentTab();}},
            'RL': {name: '恢复关闭的标签', cmd:  function() { try {    document.getElementById('History:UndoCloseTab').doCommand();} catch (ex) {if ('undoRemoveTab' in gBrowser) gBrowser.undoRemoveTab();    else throw "Session Restore feature is disabled."}  } },
         
            'UL': {name: '关闭左边的标签页', cmd: function(event) { for (let i = gBrowser.mCurrentTab._tPos - 1; i &gt;= 0; i--) if (!gBrowser.tabs&lt;span style="font-style: italic;"&gt;.pinned){ gBrowser.removeTab(gBrowser.tabs&lt;span style="font-style: italic;"&gt;, {animate: true});}}},
            'UR': {name: '关闭右边的标签页', cmd: function(event) { gBrowser.removeTabsToTheEndFrom(gBrowser.mCurrentTab);  }},
     
          'DR': {name: '关闭所有标签页', cmd: function(event) {gBrowser.removeAllTabsBut(gBrowser.mCurrentTab); gBrowser.removeCurrentTab(); }},
     
            'RLD': {name: '将当前窗口置顶',  cmd: function(event) {TabStickOnTop();}},
     
},
        init: function() {
            let self = this;
            ['mousedown', 'mousemove', 'mouseup', 'contextmenu', 'DOMMouseScroll'].forEach(type =&gt; {
                gBrowser.mPanelContainer.addEventListener(type, self, true);
            });
            gBrowser.mPanelContainer.addEventListener('unload', () =&gt; {
                ['mousedown', 'mousemove', 'mouseup', 'contextmenu', 'DOMMouseScroll'].forEach(type =&gt; {
                    gBrowser.mPanelContainer.removeEventListener(type, self, true);
                });
            }, false);
        },
        handleEvent: function(event) {
            switch (event.type) {
            case 'mousedown':
                if (event.button == 2) {
                    this.isMouseDownR = true;
                    this.hideFireContext = false;
                    [this.lastX, this.lastY, this.directionChain] = [event.screenX, event.screenY, ''];
                }
                if (event.button == 0) {
                    this.isMouseDownR = false;
                    this.stopGesture();
                }
                break;
            case 'mousemove':
                if (this.isMouseDownR) {
                    let[subX, subY] = [event.screenX - this.lastX, event.screenY - this.lastY];
                    let[distX, distY] = [(subX &gt; 0 ? subX : (-subX)), (subY &gt; 0 ? subY : (-subY))];
                    let direction;
                    if (distX &lt; 10 && distY &lt; 10) return;
                    if (distX &gt; distY) direction = subX &lt; 0 ? 'L' : 'R';
                    else direction = subY &lt; 0 ? 'U' : 'D';
                    if (!this.xdTrailArea) {
                        this.xdTrailArea = document.createElement('hbox');
                        let canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
                        canvas.setAttribute('width', window.screen.width);
                        canvas.setAttribute('height', window.screen.height);
                        this.xdTrailAreaContext = canvas.getContext('2d');
                        this.xdTrailArea.style.cssText = '-moz-user-focus: none !important;-moz-user-select: none !important;display: -moz-box !important;box-sizing: border-box !important;pointer-events: none !important;margin: 0 !important;padding: 0 !important;width: 100% !important;height: 100% !important;border: none !important;box-shadow: none !important;overflow: hidden !important;background: none !important;opacity: 0.9 !important;position: fixed !important;z-index: 2147483647 !important;';
                        this.xdTrailArea.appendChild(canvas);
                        gBrowser.selectedBrowser.parentNode.insertBefore(this.xdTrailArea, gBrowser.selectedBrowser.nextSibling);
                    }
                    if (this.xdTrailAreaContext) {
                        this.hideFireContext = true;
                        this.xdTrailAreaContext.strokeStyle = '#0065FF';
                        this.xdTrailAreaContext.lineJoin = 'round';
                        this.xdTrailAreaContext.lineCap = 'round';
                        this.xdTrailAreaContext.lineWidth = 2;
                        this.xdTrailAreaContext.beginPath();
                        this.xdTrailAreaContext.moveTo(this.lastX - gBrowser.selectedBrowser.boxObject.screenX, this.lastY - gBrowser.selectedBrowser.boxObject.screenY);
                        this.xdTrailAreaContext.lineTo(event.screenX - gBrowser.selectedBrowser.boxObject.screenX, event.screenY - gBrowser.selectedBrowser.boxObject.screenY);
                        this.xdTrailAreaContext.closePath();
                        this.xdTrailAreaContext.stroke();
                        this.lastX = event.screenX;
                        this.lastY = event.screenY;
                    }
                    if (direction != this.directionChain.charAt(this.directionChain.length - 1)) {
                        this.directionChain += direction;
                        XULBrowserWindow.statusTextField.label = this.GESTURES[this.directionChain] ? '手势: ' + this.directionChain + ' ' + this.GESTURES[this.directionChain].name : '未知手势:' + this.directionChain;
                    }
                }
                break;
            case 'mouseup':
                if (this.isMouseDownR && event.button == 2) {
                    if (this.directionChain) this.shouldFireContext = false;
                    this.isMouseDownR = false;
                    this.directionChain && this.stopGesture();
                }
                break;
            case 'contextmenu':
                if (this.isMouseDownR || this.hideFireContext) {
                    this.shouldFireContext = true;
                    this.hideFireContext = false;
                    event.preventDefault();
                    event.stopPropagation();
                }
                break;
            case 'DOMMouseScroll':
                if (this.isMouseDownR) {
                    this.shouldFireContext = false;
                    this.hideFireContext = true;
                    this.directionChain = 'W' + (event.detail &gt; 0 ? '+' : '-');
                    this.stopGesture();
                }
                break;
            }
        },
        stopGesture: function() {
            if (this.GESTURES[this.directionChain]) this.GESTURES[this.directionChain].cmd();
            if (this.xdTrailArea) {
                this.xdTrailArea.parentNode.removeChild(this.xdTrailArea);
                this.xdTrailArea = null;
                this.xdTrailAreaContext = null;
            }
            this.directionChain = '';
            setTimeout(() =&gt; XULBrowserWindow.statusTextField.label = '', 2000);
            this.hideFireContext = true;
        }
    };
    ucjsMouseGestures.init();
})();
     
     
     
     
//加入命令
//将当前窗口置顶
 function TabStickOnTop() {
(function(){if(document.getElementById('main-window').hasAttribute('ontop'))onTop=false;else onTop=true;try{Components.utils.import("resource://gre/modules/ctypes.jsm");var lib=ctypes.open("user32.dll");var funcActiveWindow=0;try{funcActiveWindow=lib.declare("GetActiveWindow",ctypes.winapi_abi,ctypes.int32_t)}catch(ex){funcActiveWindow=lib.declare("GetActiveWindow",ctypes.stdcall_abi,ctypes.int32_t)}if(funcActiveWindow!=0){var activeWindow=funcActiveWindow();var funcSetWindowPos=0;try{funcSetWindowPos=lib.declare("SetWindowPos",ctypes.winapi_abi,ctypes.bool,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.uint32_t)}catch(ex){funcSetWindowPos=lib.declare("SetWindowPos",ctypes.stdcall_abi,ctypes.bool,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.uint32_t)}var hwndAfter=-2;if(onTop){hwndAfter=-1;document.getElementById('main-window').setAttribute('ontop','true')}else document.getElementById('main-window').removeAttribute('ontop');funcSetWindowPos(activeWindow,hwndAfter,0,0,0,0,19)}lib.close()}catch(ex){alwaysontop_log(ex)}})()
};&lt;/span&gt;&lt;/span&gt;
fanmli
小狐狸
小狐狸
  • UID51688
  • 注册日期2015-11-08
  • 最后登录2021-09-29
  • 发帖数54
  • 经验71枚
  • 威望0点
  • 贡献值70点
  • 好评度9点
  • 社区居民
  • 忠实会员
1楼#
发布于:2018-11-23 14:32
kidzgy
火狐狸
火狐狸
  • UID35190
  • 注册日期2011-02-03
  • 最后登录2024-03-28
  • 发帖数248
  • 经验196枚
  • 威望0点
  • 贡献值122点
  • 好评度17点
2楼#
发布于:2018-11-24 20:05
谢谢楼上的,原来alice0775有鼠标手势脚本,那个太全面了,代码太多,很多其实都用不上。现在依样画葫芦改了一下,摇杆手势功能可以正常是用了 ,但是点击右键并不能弹出菜单,不知到底哪里出错。
// ==UserScript==
// @name                 Mousegestures.uc.js
// @namespace            Mousegestures@gmail.com
// @description          自定义鼠标手势,自用 DIY版
// @author               紫云飞&黒仪大螃蟹
// @homepageURL          http://www.cnblogs.com/ziyunfei/archive/2011/12/15/2289504.html
// @include              chrome://browser/content/browser.xul
// @charset              UTF-8
// ==/UserScript==
(() =&gt; {
    'use strict';
    let ucjsMouseGestures = {
        lastX: 0,
        lastY: 0,
        directionChain: '',
        isMouseDownL: false,
        isMouseDownR: false,
        suppressContext: false,
        shouldFireContext: false,
        GESTURES: {
      'W-': {name: '滚动到顶部', cmd: () =&gt; goDoCommand('cmd_scrollTop')},
      'W+': {name: '滚到到底部', cmd: () =&gt; goDoCommand('cmd_scrollBottom')},
            'L': {name: '后退', cmd: () =&gt; getWebNavigation().canGoBack && getWebNavigation().goBack()},
            'R': {name: '前进', cmd: () =&gt; getWebNavigation().canGoForward && getWebNavigation().goForward()},
    
    
            '': {name: '向上滚动', cmd: () =&gt; goDoCommand('cmd_scrollPageUp')},
            '': {name: '向下滚动', cmd: () =&gt; goDoCommand('cmd_scrollPageDown')},
    
    
            'UD': {name: '刷新当前页面', cmd: function() {document.getElementById("Browser:Reload").doCommand();}},
            'UDU': {name: '跳过缓存刷新当前页面', cmd: function() {document.getElementById("Browser:ReloadSkipCache").doCommand();}},
            'UR': {name: '重置缩放', cmd: function() {FullZoom.reset();}},
    
    
            'L&gt;R': {name: '关闭当前标签', cmd: function(event) {gBrowser.removeCurrentTab();}},
            'L&lt;R': {name: '恢复关闭的标签', cmd:  function() { try {    document.getElementById('History:UndoCloseTab').doCommand();} catch (ex) {if ('undoRemoveTab' in gBrowser) gBrowser.undoRemoveTab();    else throw "Session Restore feature is disabled."}  } },
    
          'RL': {name: '关闭左边的标签页', cmd: function(event) {   for (let i = gBrowser.mCurrentTab._tPos - 1; i &gt;= 0; i--) if (!gBrowser.tabs&lt;span style="font-style: italic;"&gt;.pinned){ gBrowser.removeTab(gBrowser.tabs&lt;span style="font-style: italic;"&gt;, {animate: true});}}},
          'LR': {name: '关闭右边的标签页', cmd: function(event) {   gBrowser.removeTabsToTheEndFrom(gBrowser.mCurrentTab);  }},
          '': {name: '关闭其他所有标签页', cmd: function(event) {gBrowser.removeAllTabsBut(gBrowser.mCurrentTab);    }},
          'DR': {name: '关闭所有标签页', cmd: function(event) {gBrowser.removeAllTabsBut(gBrowser.mCurrentTab);gBrowser.removeCurrentTab();    }},
    
            'RLD': {name: '将当前窗口置顶',  cmd: function(event) {TabStickOnTop();}},
    
},
        init: function() {
            let self = this;
            ['mousedown', 'mousemove', 'mouseup', 'contextmenu', 'DOMMouseScroll'].forEach(type =&gt; {
                gBrowser.mPanelContainer.addEventListener(type, self, true);
            });
            gBrowser.mPanelContainer.addEventListener('unload', () =&gt; {
                ['mousedown', 'mousemove', 'mouseup', 'contextmenu', 'DOMMouseScroll'].forEach(type =&gt; {
                    gBrowser.mPanelContainer.removeEventListener(type, self, true);
                });
            }, false);
        },
        handleEvent: function(event) {
            switch (event.type) {
            case 'mousedown':
                if (event.button == 2) {
                    this.isMouseDownR = true;
                    this.suppressContext = false;
                    [this.lastX, this.lastY, this.directionChain] = [event.screenX, event.screenY, ''];
          if (this.isMouseDownL) {
            this.isMouseDownR = false;
            this.suppressContext = true;
            this.directionChain = "L&gt;R";
            this.stopGesture();
                                                                    }
            }else if (event.button == 0) {
          this.isMouseDownL = true;
          if (this.isMouseDownR) {
            this.isMouseDownL = false;
            this.suppressContext = true;
            this.directionChain = "L&lt;R";
            this.stopGesture();
          }
        }
        break;
    
    
    
            case 'mousemove':
                if (this.isMouseDownR) {
                    let[subX, subY] = [event.screenX - this.lastX, event.screenY - this.lastY];
                    let[distX, distY] = [(subX &gt; 0 ? subX : (-subX)), (subY &gt; 0 ? subY : (-subY))];
                    let direction;
                    if (distX &lt; 10 && distY &lt; 10) return;
                    if (distX &gt; distY) direction = subX &lt; 0 ? 'L' : 'R';
                    else direction = subY &lt; 0 ? 'U' : 'D';
                    if (!this.xdTrailArea) {
                        this.xdTrailArea = document.createElement('hbox');
                        let canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
                        canvas.setAttribute('width', window.screen.width);
                        canvas.setAttribute('height', window.screen.height);
                        this.xdTrailAreaContext = canvas.getContext('2d');
                        this.xdTrailArea.style.cssText = '-moz-user-focus: none !important;-moz-user-select: none !important;display: -moz-box !important;box-sizing: border-box !important;pointer-events: none !important;margin: 0 !important;padding: 0 !important;width: 100% !important;height: 100% !important;border: none !important;box-shadow: none !important;overflow: hidden !important;background: none !important;opacity: 0.9 !important;position: fixed !important;z-index: 2147483647 !important;';
                        this.xdTrailArea.appendChild(canvas);
                        gBrowser.selectedBrowser.parentNode.insertBefore(this.xdTrailArea, gBrowser.selectedBrowser.nextSibling);
                    }
                    if (this.xdTrailAreaContext) {
                        this.suppressContext = true;
                        this.xdTrailAreaContext.strokeStyle = '#0065FF';
                        this.xdTrailAreaContext.lineJoin = 'round';
                        this.xdTrailAreaContext.lineCap = 'round';
                        this.xdTrailAreaContext.lineWidth = 2;
                        this.xdTrailAreaContext.beginPath();
                        this.xdTrailAreaContext.moveTo(this.lastX - gBrowser.selectedBrowser.boxObject.screenX, this.lastY - gBrowser.selectedBrowser.boxObject.screenY);
                        this.xdTrailAreaContext.lineTo(event.screenX - gBrowser.selectedBrowser.boxObject.screenX, event.screenY - gBrowser.selectedBrowser.boxObject.screenY);
                        this.xdTrailAreaContext.closePath();
                        this.xdTrailAreaContext.stroke();
                        this.lastX = event.screenX;
                        this.lastY = event.screenY;
                    }
                    if (direction != this.directionChain.charAt(this.directionChain.length - 1)) {
                        this.directionChain += direction;
                        XULBrowserWindow.statusTextField.label = this.GESTURES[this.directionChain] ? '手势: ' + this.directionChain + ' ' + this.GESTURES[this.directionChain].name : '未知手势:' + this.directionChain;
                    }
                }
                break;
            case 'mouseup':
                if (this.isMouseDownR && event.button == 2) {
          this.isMouseDownR = false;
          if (this.directionChain) 
          this.suppressContext = true;
          this.stopGesture();
    
          if(this.shouldFireContext){
            this.shouldFireContext = false;
            }
          } else if (event.button == 0 && this.isMouseDownL) {
          this.isMouseDownL = false;
        }
                break;
            case 'contextmenu':
                if (this.isMouseDownR || this.suppressContext) {
                    this.suppressContext = false;
                    event.preventDefault();
                    event.stopPropagation();
          if (this.isMouseDownR) {
            this.shouldFireContext = true;
          }
                }
                break;
            case 'DOMMouseScroll':
                if (this.isMouseDownR) {
                    this.shouldFireContext = false;
                    this.suppressContext = true;
                    this.directionChain = 'W' + (event.detail &gt; 0 ? '+' : '-');
                    this.stopGesture();
                }
                break;
            }
        },
    
    
    
        stopGesture: function() {
            if (this.GESTURES[this.directionChain]) this.GESTURES[this.directionChain].cmd();
            if (this.xdTrailArea) {
                this.xdTrailArea.parentNode.removeChild(this.xdTrailArea);
                this.xdTrailArea = null;
                this.xdTrailAreaContext = null;
            }
            this.directionChain = '';
            setTimeout(() =&gt; XULBrowserWindow.statusTextField.label = '', 2000);
            this.suppressContext = true;
        }
    };
    ucjsMouseGestures.init();
})();
    
    
    
    
//加入命令
//将当前窗口置顶
 function TabStickOnTop() {
(function(){if(document.getElementById('main-window').hasAttribute('ontop'))onTop=false;else onTop=true;try{Components.utils.import("resource://gre/modules/ctypes.jsm");var lib=ctypes.open("user32.dll");var funcActiveWindow=0;try{funcActiveWindow=lib.declare("GetActiveWindow",ctypes.winapi_abi,ctypes.int32_t)}catch(ex){funcActiveWindow=lib.declare("GetActiveWindow",ctypes.stdcall_abi,ctypes.int32_t)}if(funcActiveWindow!=0){var activeWindow=funcActiveWindow();var funcSetWindowPos=0;try{funcSetWindowPos=lib.declare("SetWindowPos",ctypes.winapi_abi,ctypes.bool,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.uint32_t)}catch(ex){funcSetWindowPos=lib.declare("SetWindowPos",ctypes.stdcall_abi,ctypes.bool,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.int32_t,ctypes.uint32_t)}var hwndAfter=-2;if(onTop){hwndAfter=-1;document.getElementById('main-window').setAttribute('ontop','true')}else document.getElementById('main-window').removeAttribute('ontop');funcSetWindowPos(activeWindow,hwndAfter,0,0,0,0,19)}lib.close()}catch(ex){alwaysontop_log(ex)}})()
};&lt;/span&gt;&lt;/span&gt;
游客

返回顶部