| 1 | // Vimperator plugin: 'Walk Input' |
|---|
| 2 | // Last Change: 2009-01-25 |
|---|
| 3 | // License: BSD |
|---|
| 4 | // Version: 1.1 |
|---|
| 5 | // Maintainer: Takayama Fumihiko <tekezo@pqrs.org> |
|---|
| 6 | |
|---|
| 7 | // ------------------------------------------------------------ |
|---|
| 8 | // The focus walks <input> & <textarea> elements. |
|---|
| 9 | // If you type M-i first, the focus moves to "<input name='search' />". |
|---|
| 10 | // Then if you type M-i once more, the focus moves to "<input name='name' />". |
|---|
| 11 | // |
|---|
| 12 | // <html> |
|---|
| 13 | // <input name="search" /> |
|---|
| 14 | // <a href="xxx">xxx</a> |
|---|
| 15 | // <a href="yyy">yyy</a> |
|---|
| 16 | // <a href="zzz">zzz</a> |
|---|
| 17 | // <input name="name" /> |
|---|
| 18 | // <textarea name="comment"></textarea> |
|---|
| 19 | // </html> |
|---|
| 20 | |
|---|
| 21 | // PLUGIN_INFO {{{ |
|---|
| 22 | let INFO = |
|---|
| 23 | <plugin name="Walk-Input" version="1.1" |
|---|
| 24 | href="http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/walk-input.js" |
|---|
| 25 | summary="The focus walks 'input' and 'textarea' element." |
|---|
| 26 | xmlns="http://vimperator.org/namespaces/liberator"> |
|---|
| 27 | <author email="tekezo@pqrs.org">Takayama Fumihiko</author> |
|---|
| 28 | <license>BSD</license> |
|---|
| 29 | <project name="Vimperator" minVersion="2.2"/> |
|---|
| 30 | <p> |
|---|
| 31 | The focus walks <input> & <textarea> element. |
|---|
| 32 | If you type <k name="M-i"/> first, the focus moves to "<input name='search' />". |
|---|
| 33 | Then if you type <k name="M-i"/> once more, the focus moves to "<input name='name' />". |
|---|
| 34 | </p> |
|---|
| 35 | <code><![CDATA[ |
|---|
| 36 | <html> |
|---|
| 37 | <input name="search" /> |
|---|
| 38 | <a href="xxx">xxx</a> |
|---|
| 39 | <a href="yyy">yyy</a> |
|---|
| 40 | <a href="zzz">zzz</a> |
|---|
| 41 | <input name="name" /> |
|---|
| 42 | <textarea name="comment"></textarea> |
|---|
| 43 | </html> |
|---|
| 44 | ]]></code> |
|---|
| 45 | <item> |
|---|
| 46 | <tags><![CDATA[i_<M-i> i_<A-i> <M-i> <A-i>]]></tags> |
|---|
| 47 | <spec><M-i></spec> |
|---|
| 48 | <spec><A-i></spec> |
|---|
| 49 | <description> |
|---|
| 50 | <p>Move focus forward</p> |
|---|
| 51 | </description> |
|---|
| 52 | </item> |
|---|
| 53 | <item> |
|---|
| 54 | <tags><![CDATA[i_<M-S-i> i_<A-S-i> <M-S-i> <A-S-i>]]></tags> |
|---|
| 55 | <spec><M-S-i></spec> |
|---|
| 56 | <spec><A-S-i></spec> |
|---|
| 57 | <description> |
|---|
| 58 | <p>Move focus backward</p> |
|---|
| 59 | </description> |
|---|
| 60 | </item> |
|---|
| 61 | </plugin>; |
|---|
| 62 | // }}} |
|---|
| 63 | |
|---|
| 64 | (function () { |
|---|
| 65 | |
|---|
| 66 | var xpath = '//input[@type="text" or @type="password" or @type="search" or not(@type)] | //textarea'; |
|---|
| 67 | |
|---|
| 68 | var walkinput = function (forward) { |
|---|
| 69 | var focused = document.commandDispatcher.focusedElement; |
|---|
| 70 | var current = null; |
|---|
| 71 | var next = null; |
|---|
| 72 | var prev = null; |
|---|
| 73 | var list = []; |
|---|
| 74 | |
|---|
| 75 | (function (frame) { |
|---|
| 76 | var doc = frame.document; |
|---|
| 77 | if (doc.body.localName.toLowerCase() == 'body') { |
|---|
| 78 | let r = doc.evaluate(xpath, doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); |
|---|
| 79 | for (let i = 0, l = r.snapshotLength; i < l; ++i) { |
|---|
| 80 | let e = r.snapshotItem(i); |
|---|
| 81 | if (/^none$/i.test(getComputedStyle(e, '').display)) |
|---|
| 82 | continue; |
|---|
| 83 | let ef = {element: e, frame: frame}; |
|---|
| 84 | list.push(ef); |
|---|
| 85 | if (e == focused) { |
|---|
| 86 | current = ef; |
|---|
| 87 | } else if (current && !next) { |
|---|
| 88 | next = ef; |
|---|
| 89 | } else if (!current) { |
|---|
| 90 | prev = ef; |
|---|
| 91 | } |
|---|
| 92 | } |
|---|
| 93 | } |
|---|
| 94 | for (let i = 0; i < frame.frames.length; i++) |
|---|
| 95 | arguments.callee(frame.frames[i]); |
|---|
| 96 | })(content); |
|---|
| 97 | |
|---|
| 98 | if (list.length <= 0) |
|---|
| 99 | return; |
|---|
| 100 | |
|---|
| 101 | var elem = forward ? (next || list[0]) |
|---|
| 102 | : (prev || list[list.length - 1]); |
|---|
| 103 | |
|---|
| 104 | if (!current || current.frame != elem.frame) |
|---|
| 105 | elem.frame.focus(); |
|---|
| 106 | elem.element.focus(); |
|---|
| 107 | }; |
|---|
| 108 | |
|---|
| 109 | mappings.addUserMap([modes.NORMAL, modes.INSERT], ['<M-i>', '<A-i>'], |
|---|
| 110 | 'Walk Input Fields (Forward)', function () walkinput(true)); |
|---|
| 111 | mappings.addUserMap([modes.NORMAL, modes.INSERT], ['<M-S-i>', '<A-S-i>'], |
|---|
| 112 | 'Walk Input Fields (Backward)', function () walkinput(false)); |
|---|
| 113 | |
|---|
| 114 | })(); |
|---|