root/lang/javascript/vimperator-plugins/trunk/mouse_gestures.js

Revision 30709, 10.2 kB (checked in by anekos, 18 months ago)

Wiki 記法のまちがいっぽいのを修正

Line 
1var PLUGIN_INFO =
2<VimperatorPlugin>
3  <name>Mouse Gestures</name>
4  <name lang='ja'>マウスジェスチャー</name>
5  <description>mouse gestures</description>
6  <description lang='ja'>マウスジェスチャー</description>
7  <version>0.10.1</version>
8  <author>pekepeke</author>
9  <minVersion>2.0pre</minVersion>
10  <maxVersion>2.0pre</maxVersion>
11  <updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/mouse_gestures.js</updateURL>
12  <detail lang='ja'><![CDATA[
13  == .vimperatorrc example ==
14  >||
15  js <<EOM
16  liberator.globalVariables.mousegesture_showmsg = true;  // default is true
17  liberator.globalVariables.mousegesture_rocker = true;  // default is false
18  liberator.globalVariables.mousegesture_wheel = true;  // default is false
19  liberator.globalVariables.mousegesture_list = [
20    //['UDLR', 'Description', '#id or function or :vimp command or vimp_key', noremap flag]
21    ['L'  , 'Back', '#Browser:Back'],
22    ['R'  , 'Forward', '#Browser:Forward'],
23    ['RLR', 'Close Tab Or Window', '#cmd_close'],
24    ['LD' , 'Stop Loading Page', '#Browser:Stop'],
25    ['LR' , 'Undo Close Tab', '#History:UndoCloseTab'],
26    ['UL' , 'Select Previous Tab', 'gT', true],
27    ['UR' , 'Select Next Tab', 'gt', true],
28    ['LU' , 'Scroll To Top', function() goDoCommand('cmd_scrollTop')],
29    ['LD' , 'Scroll To Bottom', function() goDoCommand('cmd_scrollBottom')],
30    ['UDR', 'Add Bookmark', ':dialog addbookmark'],
31    ['L>R', 'Forward', '#Browser:Forward'],
32    ['L<R', 'Back', '#Browser:Back'],
33    ['W-' , 'Select Previous Tab', function() gBrowser.tabContainer.advanceSelectedTab(-1, true) ],
34    ['W+' , 'Select Next Tab', function() gBrowser.tabContainer.advanceSelectedTab(+1, true) ],
35  ];
36  EOM
37  ||<
38  == liberator.globalVariables ==
39  - mousegesture_showmsg
40    ジェスチャー情報を表示するかどうか(デフォルト=true:表示する)
41  - mousegesture_rocker
42    ロッカージェスチャを有効にするかどうか(デフォルト=false:無効)
43  - mousegesture_wheel
44    ホイールジェスチャを有効にするかどうか(デフォルト=false:無効)
45  - mousegesture_list
46    ジェスチャー設定。2次元配列で指定してください。
47    [ <UDLR>, <Description>, <Command>, <noremap flag> ]
48    - UDLR
49      ジェスチャーを指定します。
50      UDLRの文字列を指定してください。
51      それぞれ、マウスジェスチャーの↑、↓、←, →に対応しています。
52      一応、ロッカージェスチャー・ホイールジェスチャー等にも暫定で対応しています(別途、オプションを有効にする必要がある)。
53      ロッカージェスチャはL>R(左→右クリック), L<R(右→左クリック)で指定可能。
54      ホイールジェスチャは W-(↓回転), W+(上回転)で指定可能
55    - Description
56      コマンドの説明文。
57    - Command
58      ジェスチャーが実施された際に実行するコマンドを指定します。
59      以下の3通りの指定が可能です。
60        - '#id'
61          document.getElementById(id).doCommand() を実行します。
62        - function() { ... }
63          記述された関数を実行します。
64        - ':[command]'
65          Vimperatorのユーザコマンド [command]を実行します。
66        - '[key]'
67          キーを送ります。
68    - noremap flag
69      キーを送る、かつ、そのキーコードを noremap で処理を行いたい場合、true を指定してください。
70  ]]></detail>
71</VimperatorPlugin>
72
73liberator.plugins.MouseGestures = (function() {
74
75  const Ci = Components.interfaces;
76  var global = liberator.globalVariables;
77
78  if (typeof global.mousegesture_list == 'undefined') return;
79  if (liberator.plugins.MouseGestures) liberator.plugins.MouseGestures.registerEvents('remove');
80
81  var Class = function() function() {this.initialize.apply(this, arguments);};
82  var MouseGestures = new Class();
83
84  var doCommandByID = function(id) {
85    if (document.getElementById(id))
86      document.getElementById(id).doCommand();
87  };
88
89  MouseGestures.prototype = {
90    initialize: function() {
91      this.parseSetting();
92
93      var self = this;
94      this.registerEvents('add');
95      window.addEventListener('unload', function() { self.registerEvents('remove'); }, false);
96    },
97    parseSetting: function() {
98      var gestures = {};
99      var self = this;
100      this._showstatus = global.mousegesture_showmsg || true;
101
102      this._enableRocker = global.mousegesture_rocker || false;
103      this._enableWheel = global.mousegesture_wheel || false;
104      if (this._enableRocker) this.captureEvents.push('draggesture');
105      if (this._enableWheel) this.captureEvents.push('DOMMouseScroll');
106      global.mousegesture_list.forEach(function( [gesture, desc, action, noremap] ) {
107        action = action || desc;
108        noremap = noremap || false;
109        if (typeof action == 'string') {
110          let str = action;
111          if (str.charAt(0) == ':') action = function() liberator.execute(str.substr(1));
112          else if (str.charAt(0) == '#') action = function() doCommandByID(str.substr(1));
113          else action = function() modules.events.feedkeys(str, noremap);
114        }
115        gestures[gesture] = [desc, action];
116      });
117      this.GESTURES = gestures;
118    },
119    captureEvents : ['mousedown', 'mousemove', 'mouseup', 'contextmenu'],
120    registerEvents: function(action) {
121      var self = this;
122      this.captureEvents.forEach(
123        function(type) { getBrowser().mPanelContainer[action + 'EventListener'](type, self, type == 'contextmenu' || type == 'draggesture');
124      });
125    },
126    set status(msg) {
127      if (this._showstatus) commandline.echo(msg, null, commandline.FORCE_SINGLELINE);
128    },
129    handleEvent: function(event) {
130      switch(event.type) {
131      case 'mousedown':
132        if (event.button == 2) {
133          this._isMouseDownR = true;
134          this._suppressContext = false;
135          this.startGesture(event);
136          if (this._enableRocker && this._isMouseDownL) {
137            this._isMouseDownR = false;
138            this._suppressContext = true;
139            this._gesture = 'L>R';
140            this.stopGesture(event);
141          }
142        } else if (this._enableRocker && event.button == 0) {
143          this._isMouseDownL = true;
144          if (this._isMouseDownR) {
145            this._isMouseDownL = false;
146            this._suppressContext = true;
147            this._gesture = 'L<R';
148            this.stopGesture(event);
149          }
150        }
151        break;
152      case 'mousemove':
153        if (this._isMouseDownR) this.progressGesture(event);
154        break;
155      case 'mouseup':
156        if (this._isMouseDownR && event.button == 2) {
157          this._isMouseDownR = false;
158          this._suppressContext = !!this._gesture;
159          if (this._enableWheel && this._gesture && this._gesture.charAt(0) == 'W') this._gesture = '';
160          this.stopGesture(event);
161          if (this._shouldFireContext) {      // for Linux & Mac
162            this._shouldFireContext = false;
163            let mEvent = event.originalTarget.ownerDocument.createEvent('MouseEvents');
164            mEvent.initMouseEvent('contextmenu', true, true, aEvent.originalTarget.defaultView, 0, event.screenX, event.screenY, event.clientX, event.clientY, false, false, false, false, 2, null);
165            event.originalTarget.dispatchEvent(mEvent);
166          }
167        } else if (this._isMouseDownL && event.button == 0) this._isMouseDownL = false;
168        break;
169      case 'contextmenu':
170        if (this._suppressContext || this._isMouseDownR) {
171          this._suppressContext = false;
172          this._shouldFireContext = this._isMouseDownR;
173          event.preventDefault();
174          event.stopPropagation();
175        }
176        break;
177      case 'DOMMouseScroll':
178        if (this._enableWheel && this._isMouseDownR) {
179          event.preventDefault();
180          event.stopPropagation();
181          this._suppressContext = true;
182          this._gesture = 'W' + (event.detail > 0 ? '+' : '-');
183          this.stopGesture( event, false );
184        }
185        break;
186      case 'draggesture':
187        this._isMouseDownL = false;
188        break;
189      }
190    },
191    startGesture: function(event) {
192      this._gesture = '';
193      this._x = event.screenX;
194      this._y = event.screenY;
195      this._origDoc = event.originalTarget.ownerDocument;
196      this._links = [];
197    },
198    progressGesture: function(event) {
199      if (!this._origDoc) return;
200      for (let node = event.originalTarget; node; node = node.parentNode) {
201        if (node instanceof Ci.nsIDOMHTMLAnchorElement) {
202          if (this._links.indexOf(node.href) == -1) this._links.push(node.href);
203          break;
204        }
205      }
206      this.timerGesture();
207      var x = event.screenX, y = event.screenY;
208      var distX = Math.abs(x-this._x), distY = Math.abs(y-this._y);
209      var threshold = 15/ (gBrowser.selectedBrowser.markupDocumentViewer.fullZoom || 1.0);
210      if (distX < threshold && distY < threshold) return;
211      var dir = distX > distY ? (x<this._x ? 'L' : 'R') : (y<this._y ? 'U': 'D');
212      if (dir != this._gesture.slice(-1)) {
213        this._gesture += dir;
214        this.status = 'Gesture: ' + this._gesture + (this.GESTURES[this._gesture] ? ' (' + this.GESTURES[this._gesture][0] + ')' : '');
215      }
216      this._x = x; this._y = y;
217    },
218    timerGesture: function(isClear) {
219      if (this._timer)  clearTimeout(this._timer);
220        this._timer = setTimeout( !isClear ? function(self) self.stopGesture({}, true) : function(self) self._timer = self.status = '', 1500, this);
221    },
222    stopGesture: function(event, cancel) {
223      if (this._gesture) {
224        try {
225          if (cancel) throw 'Gesture Canceled';
226
227          let cmd = this.GESTURES[this._gesture] || null;
228/*
229          if ( !cmd && this.GESTURES['*'] ) {
230            for (let key in this.GESTURES['*']) {
231              if (this.GESTURES['*'][key].test(this._gesture)) {
232                cmd = this.GESTURES[key];
233                break;
234              }
235            }
236          }
237*/
238          if (!cmd) throw 'Unknown Gesture: ' + this._gesture;
239
240          cmd[1].call(this);
241          this.status = 'Gesture: ' + cmd[0];
242        } catch (exp) {
243          this.status = exp;
244        }
245        this.timerGesture(true);
246      }
247      this._origDoc = this._links = null;
248    }
249  };
250  return new MouseGestures();
251})();
Note: See TracBrowser for help on using the browser.