vimperator
This commit is contained in:
parent
beaa209d52
commit
bbeac9e40d
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
|||||||
FILES = bashrc vimrc zshrc emacs.el gitconfig screenrc commonshrc \
|
FILES = bashrc vimrc zshrc emacs.el gitconfig screenrc commonshrc \
|
||||||
gnomerc gvimrc muttrc pentadactylrc
|
gnomerc gvimrc muttrc pentadactylrc vimperatorrc
|
||||||
FILES2 = msmtprc
|
FILES2 = msmtprc
|
||||||
|
|
||||||
.PHONY: install clean check
|
.PHONY: install clean check
|
||||||
|
737
vimperator/plugin/_libly.js
Normal file
737
vimperator/plugin/_libly.js
Normal file
@ -0,0 +1,737 @@
|
|||||||
|
/*** BEGIN LICENSE BLOCK {{{
|
||||||
|
Copyright (c) 2008 suVene<suvene@zeromemory.info>
|
||||||
|
Copyright (c) 2008-2011 anekos<anekos@snca.net>
|
||||||
|
|
||||||
|
distributable under the terms of an MIT-style license.
|
||||||
|
http://www.opensource.jp/licenses/mit-license.html
|
||||||
|
}}} END LICENSE BLOCK ***/
|
||||||
|
// PLUGIN_INFO//{{{
|
||||||
|
/*
|
||||||
|
var PLUGIN_INFO = xml`
|
||||||
|
<VimperatorPlugin>
|
||||||
|
<name>libly(filename _libly.js)</name>
|
||||||
|
<description>Vimperator plugins library?</description>
|
||||||
|
<description lang="ja">適当なライブラリっぽいものたち。</description>
|
||||||
|
<author mail="suvene@zeromemory.info" homepage="http://zeromemory.sblo.jp/">suVene</author>
|
||||||
|
<author mail="anekos@snca.net" homepage="http://snca.net/">anekos</author>
|
||||||
|
<license>MIT</license>
|
||||||
|
<version>0.1.38</version>
|
||||||
|
<minVersion>2.3pre</minVersion>
|
||||||
|
<updateURL>https://github.com/vimpr/vimperator-plugins/raw/master/_libly.js</updateURL>
|
||||||
|
<detail><![CDATA[
|
||||||
|
== Objects ==
|
||||||
|
- liberator.plugins.libly.$U
|
||||||
|
- liberator.plugins.libly.Request
|
||||||
|
- liberator.plugins.libly.Response
|
||||||
|
- liberator.plugins.libly.Wedata
|
||||||
|
|
||||||
|
== Logger ==
|
||||||
|
getLogger(prefix):
|
||||||
|
log(msg, level), echo(msg, flg), echoerr(msg)
|
||||||
|
のメソッドを持つ logger インスタンスを取得します。
|
||||||
|
ログの書式は prefix + ': ' + yyyy/MM/dd + msg となります。
|
||||||
|
|
||||||
|
== Object Utility ==
|
||||||
|
extend(dst, src):
|
||||||
|
オブジェクトを拡張します。
|
||||||
|
A(iterable):
|
||||||
|
オブジェクトを配列にします。
|
||||||
|
around(obj, name, func, autoRestore):
|
||||||
|
obj がもつ name 関数を、func に置き換えます。
|
||||||
|
func は
|
||||||
|
function (next, args) {...}
|
||||||
|
という形で呼ばれます。
|
||||||
|
next はオリジナルの関数を呼び出すための関数、
|
||||||
|
args はオリジナルの引数列です。
|
||||||
|
通常、next には引数を渡す必要はありません。
|
||||||
|
(任意の引数を渡したい場合は配列で渡します。)
|
||||||
|
また、autoRestore が真であれば、プラグインの再ロードなどで around が再実行されたときに、関数の置き換え前にオリジナル状態に書き戻します。
|
||||||
|
(多重に置き換えられなくなるので、auto_source.js などを使ったプラグイン開発で便利です)
|
||||||
|
返値は以下のオブジェクトです
|
||||||
|
>||
|
||||||
|
{
|
||||||
|
original: オリジナルの関数
|
||||||
|
current: 現在の関数
|
||||||
|
restore: 元に戻すための関数
|
||||||
|
}
|
||||||
|
||<
|
||||||
|
bind(obj, func):
|
||||||
|
func に obj を bind します。
|
||||||
|
func内からは this で obj が参照できるようになります。
|
||||||
|
eval(text):
|
||||||
|
Sandbox による、window.eval を極力利用するようにします。
|
||||||
|
Snadbox が利用できない場合は、unsafe な window の eval が直接利用されます。
|
||||||
|
evalJson(str, toRemove):
|
||||||
|
str を decode します。
|
||||||
|
toRemove が true の場合、文字列の前後を1文字削除します。
|
||||||
|
"(key:value)" 形式の場合などに true を指定して下さい。
|
||||||
|
dateFormat(dtm, fmt):
|
||||||
|
Date型インスタンスを、指定されたフォーマットで文字列に変換します。
|
||||||
|
fmt を省略した場合、"%y/%M/%d %h:%m:%s" となります。
|
||||||
|
runnable(generator):
|
||||||
|
gererator を実行し、再帰的に resume する為の引数を渡します。
|
||||||
|
|
||||||
|
== Browser ==
|
||||||
|
getSelectedString:
|
||||||
|
window の選択文字列を返却します。
|
||||||
|
getUserAndPassword(hostname, formSubmitURL, username):
|
||||||
|
login-manager から [username, password] を取得します。
|
||||||
|
引数の username が省略された場合、検索された 1件目を返却します。
|
||||||
|
データが存在しない場合は、null を返却します。
|
||||||
|
|
||||||
|
== System ==
|
||||||
|
readDirectory(path, fileter, func):
|
||||||
|
path で指定したディレクトリから、filter で指定された正規表現に match する場合、
|
||||||
|
func をファイル名を引数にコールバックします。
|
||||||
|
filter は Function を指定することも可能です。
|
||||||
|
|
||||||
|
== HTML, XML, DOM, E4X ==
|
||||||
|
pathToURL(a, baseURL, doc):
|
||||||
|
相対パスを絶対パスに変換します。
|
||||||
|
getHTMLFragment(html):
|
||||||
|
<html>※1</html>
|
||||||
|
※1 の文字列を取得します。
|
||||||
|
stripTags(str, tags):
|
||||||
|
str から tags で指定されたタグを取り除いて返却します。
|
||||||
|
tags は文字列、または配列で指定して下さい。
|
||||||
|
createHTMLDocument(str, xmlns):
|
||||||
|
引数 str より、HTMLFragment を作成します。
|
||||||
|
getFirstNodeFromXPath(xpath, context):
|
||||||
|
xpath を評価しオブジェクトをを返却します。
|
||||||
|
getNodesFromXPath(xpath, context, callback, thisObj):
|
||||||
|
xpath を評価し snapshot の配列を返却します。
|
||||||
|
xmlSerialize(xml):
|
||||||
|
xml を文字列化します。
|
||||||
|
xmlToDom(node, doc, nodes):
|
||||||
|
for vimperator1.2.
|
||||||
|
@see vimperator2.0pre util.
|
||||||
|
getElementPosition(elem):
|
||||||
|
elem の offset を返却します。
|
||||||
|
return {top: 0, left: 0}
|
||||||
|
toStyleText(style):
|
||||||
|
スタイルが格納されているオブジェクトを
|
||||||
|
>||
|
||||||
|
position: fixed;
|
||||||
|
left: 10px;
|
||||||
|
||<
|
||||||
|
のような文字列に変換します。
|
||||||
|
|
||||||
|
== Object Request ==
|
||||||
|
Request(url, headers, options):
|
||||||
|
コンストラクタ
|
||||||
|
url:
|
||||||
|
HTTPリクエスト先のURL
|
||||||
|
headers:
|
||||||
|
以下のようにHTTPヘッダの値を指定できる(省略可)
|
||||||
|
>||
|
||||||
|
{
|
||||||
|
'Referer' : 'http://example.com/'
|
||||||
|
}
|
||||||
|
||<
|
||||||
|
以下の値はデフォルトで設定される('Content-type'はPOST時のみ)
|
||||||
|
>||
|
||||||
|
{
|
||||||
|
'Accept': 'text/javascript, application/javascript, text/html, application/xhtml+xml, application/xml, text/xml, * /*;q=0.1',
|
||||||
|
'Content-type': 'application/x-www-form-urlencoded; charset=' + options.encodingの値
|
||||||
|
}
|
||||||
|
||<
|
||||||
|
|
||||||
|
options:
|
||||||
|
オプションとして以下のようなオブジェクトを指定できる(省略可)
|
||||||
|
asynchronous:
|
||||||
|
true: 非同期モード/false: 同期モード(デフォルト:true)
|
||||||
|
encoding:
|
||||||
|
エンコーディング(デフォルト: 'UTF-8')
|
||||||
|
username:
|
||||||
|
BASIC認証時のuser名
|
||||||
|
password:
|
||||||
|
BASIC認証時のパスワード
|
||||||
|
postBody:
|
||||||
|
POSTメソッドにより送信するbody
|
||||||
|
addEventListener(name, func):
|
||||||
|
イベントリスナを登録する。
|
||||||
|
name:
|
||||||
|
'success':
|
||||||
|
成功時
|
||||||
|
'failure':
|
||||||
|
失敗を表すステータスコードが返ってきた時
|
||||||
|
'exception':
|
||||||
|
例外発生時
|
||||||
|
func:
|
||||||
|
イベント発火時の処理
|
||||||
|
引数として以下Responseオブジェクトが渡される
|
||||||
|
get():
|
||||||
|
GETメソッドによりHTTPリクエストを発行する。
|
||||||
|
post():
|
||||||
|
POSTメソッドによりHTTPリクエストを発行する。
|
||||||
|
|
||||||
|
== Object Response ==
|
||||||
|
HTTPレスポンスを表すオブジェクト
|
||||||
|
req:
|
||||||
|
レスポンスと対となるRequestオブジェクト
|
||||||
|
doc:
|
||||||
|
レスポンスから生成されたHTMLDocumentオブジェクト
|
||||||
|
isSuccess():
|
||||||
|
ステータスコードが成功を表していればtrue、失敗であればfalse
|
||||||
|
getStatus():
|
||||||
|
ステータスコードを取得する
|
||||||
|
getStatusText():
|
||||||
|
ステータを表す文字列を取得する
|
||||||
|
getHTMLDocument(xpath, xmlns, ignoreTags, callback, thisObj):
|
||||||
|
レスポンスからHTMLDocumentオブジェクトを生成し、xpath を評価した結果の snapshot の配列を返す
|
||||||
|
|
||||||
|
== Object Wedata ==
|
||||||
|
~/vimperator/info/profile_name/plugins-libly-wedata-?????
|
||||||
|
に store されます。
|
||||||
|
getItems(expire, itemCallback, finalCallback):
|
||||||
|
インスタンス作成時に指定した dbname から、item を読込みます。
|
||||||
|
=== TODO ===
|
||||||
|
clearCache:
|
||||||
|
wedata 読込み成功したら、強制的にキャッシュと置き換えるの作って!
|
||||||
|
|
||||||
|
]]></detail>
|
||||||
|
</VimperatorPlugin>`;
|
||||||
|
*/
|
||||||
|
//}}}
|
||||||
|
//if (!liberator.plugins.libly) {
|
||||||
|
|
||||||
|
liberator.plugins.libly = {};
|
||||||
|
var libly = liberator.plugins.libly;
|
||||||
|
|
||||||
|
// XXX for backward compatibillity
|
||||||
|
function fixEventName(name) {
|
||||||
|
return name.replace(/^on/, '').toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
libly.$U = {//{{{
|
||||||
|
// Logger {{{
|
||||||
|
getLogger: function(prefix) {
|
||||||
|
return new function() {
|
||||||
|
this.log = function(msg, level) {
|
||||||
|
if (typeof msg == 'object') msg = util.objectToString(msg);
|
||||||
|
liberator.log(libly.$U.dateFormat(new Date()) + ': ' + (prefix || '') + ': ' + msg, (level || 0));
|
||||||
|
};
|
||||||
|
this.echo = function(msg, flg) {
|
||||||
|
flg = flg || commandline.FORCE_MULTILINE;
|
||||||
|
// this.log(msg);
|
||||||
|
liberator.echo(msg, flg);
|
||||||
|
};
|
||||||
|
this.echoerr = function(msg) {
|
||||||
|
this.log('error: ' + msg);
|
||||||
|
liberator.echoerr(msg);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// }}}
|
||||||
|
// Object Utility {{{
|
||||||
|
extend: function(dst, src) {
|
||||||
|
for (let prop in src)
|
||||||
|
dst[prop] = src[prop];
|
||||||
|
return dst;
|
||||||
|
},
|
||||||
|
A: function(iterable) {
|
||||||
|
var ret = [];
|
||||||
|
if (!iterable) return ret;
|
||||||
|
if (typeof iterable == 'string') return [iterable];
|
||||||
|
if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
|
||||||
|
iterable.toArray) return iterable.toArray();
|
||||||
|
if (typeof iterable.length != 'undefined') {
|
||||||
|
for (let i = 0, len = iterable.length; i < len; ret.push(iterable[i++]));
|
||||||
|
} else {
|
||||||
|
for each (let item in iterable) ret.push(item);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
around: (function () {
|
||||||
|
function getPluginPath () {
|
||||||
|
let pluginPath;
|
||||||
|
Error('hoge').stack.split(/\n/).some(
|
||||||
|
function (s)
|
||||||
|
let (m = s.match(/-> liberator:\/\/template\/chrome:\/\/liberator\/content\/liberator\.js -> (.+):\d+$/))
|
||||||
|
(m && (pluginPath = m[1].replace(/\?.*$/, '')))
|
||||||
|
);
|
||||||
|
return pluginPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
let restores = {};
|
||||||
|
|
||||||
|
return function (obj, name, func, autoRestore) {
|
||||||
|
let original;
|
||||||
|
let restore = function () obj[name] = original;
|
||||||
|
if (autoRestore) {
|
||||||
|
let pluginPath = getPluginPath();
|
||||||
|
if (pluginPath) {
|
||||||
|
restores[pluginPath] =
|
||||||
|
(restores[pluginPath] || []).filter(
|
||||||
|
function (res) (
|
||||||
|
res.object != obj ||
|
||||||
|
res.name != name ||
|
||||||
|
(res.restore() && false)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
restores[pluginPath].push({
|
||||||
|
object: obj,
|
||||||
|
name: name,
|
||||||
|
restore: restore
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
liberator.echoerr('getPluginPath failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
original = obj[name];
|
||||||
|
let current = obj[name] = function () {
|
||||||
|
let self = this, args = arguments;
|
||||||
|
return func.call(self, function (_args) original.apply(self, _args || args), args);
|
||||||
|
};
|
||||||
|
libly.$U.extend(current, {original: original && original.original || original, restore: restore});
|
||||||
|
return libly.$U.extend({
|
||||||
|
original: original,
|
||||||
|
current: current,
|
||||||
|
restore: restore
|
||||||
|
}, [original, current]);
|
||||||
|
};
|
||||||
|
})(),
|
||||||
|
bind: function(obj, func) {
|
||||||
|
return function() {
|
||||||
|
return func.apply(obj, arguments);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
eval: function(text) {
|
||||||
|
var fnc = window.eval;
|
||||||
|
var sandbox;
|
||||||
|
try {
|
||||||
|
sandbox = new Components.utils.Sandbox("about:blank");
|
||||||
|
if (Components.utils.evalInSandbox('true', sandbox) === true) {
|
||||||
|
fnc = function(text) { return Components.utils.evalInSandbox(text, sandbox); };
|
||||||
|
}
|
||||||
|
} catch (e) { liberator.log('warning: _libly.js is working with unsafe sandbox.'); }
|
||||||
|
|
||||||
|
return fnc(text);
|
||||||
|
},
|
||||||
|
evalJson: function(str, toRemove) {
|
||||||
|
var json;
|
||||||
|
try {
|
||||||
|
json = Components.classes['@mozilla.org/dom/json;1'].getService(Components.interfaces.nsIJSON);
|
||||||
|
if (toRemove) str = str.substring(1, str.length - 1);
|
||||||
|
return json.decode(str);
|
||||||
|
} catch (e) { return null; }
|
||||||
|
},
|
||||||
|
dateFormat: function(dtm, fmt) {
|
||||||
|
var d = {
|
||||||
|
y: dtm.getFullYear(),
|
||||||
|
M: dtm.getMonth() + 1,
|
||||||
|
d: dtm.getDate(),
|
||||||
|
h: dtm.getHours(),
|
||||||
|
m: dtm.getMinutes(),
|
||||||
|
s: dtm.getSeconds(),
|
||||||
|
'%': '%'
|
||||||
|
};
|
||||||
|
for (let [n, v] in Iterator(d)) {
|
||||||
|
if (v < 10)
|
||||||
|
d[n] = '0' + v;
|
||||||
|
}
|
||||||
|
return (fmt || '%y/%M/%d %h:%m:%s').replace(/%([yMdhms%])/g, function (_, n) d[n]);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* example)
|
||||||
|
* $U.runnable(function(resume) {
|
||||||
|
* // execute asynchronous function.
|
||||||
|
* // goto next yield;
|
||||||
|
* var val = yield setTimeout(function() { resume('value!'), 1000) });
|
||||||
|
* alert(val); // value!
|
||||||
|
* yield;
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
runnable: function(generator) {
|
||||||
|
var it = generator(function(value) {
|
||||||
|
try { it.send(value); } catch (e) {}
|
||||||
|
});
|
||||||
|
it.next();
|
||||||
|
},
|
||||||
|
// }}}
|
||||||
|
// Browser {{{
|
||||||
|
getSelectedString: function() {
|
||||||
|
return (new XPCNativeWrapper(window.content.window)).getSelection().toString();
|
||||||
|
},
|
||||||
|
getUserAndPassword: function(hostname, formSubmitURL, username) {
|
||||||
|
var passwordManager, logins;
|
||||||
|
try {
|
||||||
|
passwordManager = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
|
||||||
|
logins = passwordManager.findLogins({}, hostname, formSubmitURL, null);
|
||||||
|
if (logins.length) {
|
||||||
|
if (username) {
|
||||||
|
for (let i = 0, len = logins.lengh; i < len; i++) {
|
||||||
|
if (logins[i].username == username)
|
||||||
|
return [logins[i].username, logins[i].password]
|
||||||
|
}
|
||||||
|
liberator.log(this.dateFormat(new Date()) +': [getUserAndPassword] username notfound');
|
||||||
|
//throw 'username notfound.';
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
return [logins[0].username, logins[0].password];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
liberator.log(this.dateFormat(new Date()) + ': [getUserAndPassword] account notfound');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
liberator.log(this.dateFormat(new Date()) + ': [getUserAndPassword] error: ' + e, 0);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// }}}
|
||||||
|
// System {{{
|
||||||
|
readDirectory: function(path, filter, func) {
|
||||||
|
var d = io.File(path);
|
||||||
|
if (d.exists() && d.isDirectory()) {
|
||||||
|
let enm = d.directoryEntries;
|
||||||
|
let flg = false;
|
||||||
|
while (enm.hasMoreElements()) {
|
||||||
|
let item = enm.getNext();
|
||||||
|
item.QueryInterface(Components.interfaces.nsIFile);
|
||||||
|
flg = false;
|
||||||
|
if (typeof filter == 'string') {
|
||||||
|
if ((new RegExp(filter)).test(item.leafName)) flg = true;
|
||||||
|
} else if (typeof filter == 'function') {
|
||||||
|
flg = filter(item);
|
||||||
|
}
|
||||||
|
if (flg) func(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// }}}
|
||||||
|
// HTML, XML, DOM, E4X {{{
|
||||||
|
pathToURL: function(a, baseURL, doc) {
|
||||||
|
if (!a) return '';
|
||||||
|
var XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||||
|
var XML_NS = "http://www.w3.org/XML/1998/namespace";
|
||||||
|
//var path = (a.href || a.getAttribute('src') || a.action || a.value || a);
|
||||||
|
var path = (a.getAttribute('href') || a.getAttribute('src') || a.action || a.value || a);
|
||||||
|
if (/^https?:\/\//.test(path)) return path;
|
||||||
|
var link = (doc || window.content.documtent).createElementNS(XHTML_NS, 'a');
|
||||||
|
link.setAttributeNS(XML_NS, 'xml:base', baseURL);
|
||||||
|
link.href = path;
|
||||||
|
return link.href;
|
||||||
|
},
|
||||||
|
getHTMLFragment: function(html) {
|
||||||
|
if (!html) return html;
|
||||||
|
return html.replace(/^[\s\S]*?<html(?:[ \t\n\r][^>]*)?>|<\/html[ \t\r\n]*>[\S\s]*$/ig, '');
|
||||||
|
},
|
||||||
|
stripTags: function(str, tags) {
|
||||||
|
var ignoreTags = '(?:' + [].concat(tags).join('|') + ')';
|
||||||
|
return str.replace(new RegExp('<' + ignoreTags + '(?:[ \\t\\n\\r][^>]*|/)?>([\\S\\s]*?)<\/' + ignoreTags + '[ \\t\\r\\n]*>', 'ig'), '');
|
||||||
|
},
|
||||||
|
createHTMLDocument: function(str, xmlns, doc) {
|
||||||
|
let root = document.createElementNS("http://www.w3.org/1999/xhtml", "html");
|
||||||
|
let uhService = Cc["@mozilla.org/feed-unescapehtml;1"].getService(Ci.nsIScriptableUnescapeHTML);
|
||||||
|
let text = str.replace(/^[\s\S]*?<body([ \t\n\r][^>]*)?>[\s]*|<\/body[ \t\r\n]*>[\S\s]*$/ig, '');
|
||||||
|
let fragment = uhService.parseFragment(text, false, null, root);
|
||||||
|
let doctype = document.implementation.createDocumentType('html', '-//W3C//DTD HTML 4.01//EN', 'http://www.w3.org/TR/html4/strict.dtd');
|
||||||
|
let htmlFragment = document.implementation.createDocument(null, 'html', doctype);
|
||||||
|
htmlFragment.documentElement.appendChild(htmlFragment.importNode(fragment,true));
|
||||||
|
return htmlFragment;
|
||||||
|
/* うまく動いていない場合はこちらに戻してください
|
||||||
|
doc = doc || window.content.document;
|
||||||
|
var htmlFragment = doc.implementation.createDocument(null, 'html', null);
|
||||||
|
var range = doc.createRange();
|
||||||
|
range.setStartAfter(doc.body);
|
||||||
|
htmlFragment.documentElement.appendChild(htmlFragment.importNode(range.createContextualFragment(str), true));
|
||||||
|
return htmlFragment;
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
getFirstNodeFromXPath: function(xpath, context) {
|
||||||
|
if (!xpath) return null;
|
||||||
|
context = context || window.content.document;
|
||||||
|
var result = (context.ownerDocument || context).evaluate(xpath, context, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
||||||
|
return result.singleNodeValue || null;
|
||||||
|
},
|
||||||
|
getNodesFromXPath: function(xpath, context, callback, thisObj) {
|
||||||
|
var ret = [];
|
||||||
|
if (!xpath) return ret;
|
||||||
|
context = context || window.content.document;
|
||||||
|
var nodesSnapshot = (context.ownerDocument || context).evaluate(xpath, context, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
||||||
|
for (let i = 0, l = nodesSnapshot.snapshotLength; i < l; i++) {
|
||||||
|
if (typeof callback == 'function') callback.call(thisObj, nodesSnapshot.snapshotItem(i), i);
|
||||||
|
ret.push(nodesSnapshot.snapshotItem(i));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
xmlSerialize: function(xml) {
|
||||||
|
try {
|
||||||
|
return (new XMLSerializer()).serializeToString(xml)
|
||||||
|
.replace(/<!--(?:[^-]|-(?!->))*-->/g, '')
|
||||||
|
.replace(/<\s*\/?\s*\w+/g, function(all) all.toLowerCase());
|
||||||
|
} catch (e) { return '' }
|
||||||
|
},
|
||||||
|
xmlToDom: function xmlToDom(node, doc, nodes)
|
||||||
|
{
|
||||||
|
return util.xmlToDom(node, doc, nodes);
|
||||||
|
},
|
||||||
|
getElementPosition: function(elem) {
|
||||||
|
var offsetTrail = elem;
|
||||||
|
var offsetLeft = 0;
|
||||||
|
var offsetTop = 0;
|
||||||
|
while (offsetTrail) {
|
||||||
|
offsetLeft += offsetTrail.offsetLeft;
|
||||||
|
offsetTop += offsetTrail.offsetTop;
|
||||||
|
offsetTrail = offsetTrail.offsetParent;
|
||||||
|
}
|
||||||
|
offsetTop = offsetTop || null;
|
||||||
|
offsetLeft = offsetLeft || null;
|
||||||
|
return {top: offsetTop, left: offsetLeft};
|
||||||
|
},
|
||||||
|
toStyleText: function(style) {
|
||||||
|
var result = '';
|
||||||
|
for (let name in style) {
|
||||||
|
result += name.replace(/[A-Z]/g, function (c) ('-' + c.toLowerCase())) +
|
||||||
|
': ' +
|
||||||
|
style[name] +
|
||||||
|
';\n';
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
};
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
libly.Request = function() {//{{{
|
||||||
|
this.initialize.apply(this, arguments);
|
||||||
|
};
|
||||||
|
libly.Request.EVENTS = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
|
||||||
|
libly.Request.requestCount = 0;
|
||||||
|
libly.Request.prototype = {
|
||||||
|
initialize: function(url, headers, options) {
|
||||||
|
this.url = url;
|
||||||
|
this.headers = headers || {};
|
||||||
|
this.options = libly.$U.extend({
|
||||||
|
asynchronous: true,
|
||||||
|
encoding: 'UTF-8'
|
||||||
|
}, options || {});
|
||||||
|
this.observers = {};
|
||||||
|
},
|
||||||
|
addEventListener: function(name, func) {
|
||||||
|
name = fixEventName(name);
|
||||||
|
try {
|
||||||
|
if (typeof this.observers[name] == 'undefined') this.observers[name] = [];
|
||||||
|
this.observers[name].push(func);
|
||||||
|
} catch (e) {
|
||||||
|
if (!this.fireEvent('exception', new libly.Response(this), e)) throw e;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fireEvent: function(name, args, asynchronous) {
|
||||||
|
name = fixEventName(name);
|
||||||
|
if (!(this.observers[name] instanceof Array)) return false;
|
||||||
|
this.observers[name].forEach(function(event) {
|
||||||
|
if (asynchronous) {
|
||||||
|
setTimeout(event, 10, args);
|
||||||
|
} else {
|
||||||
|
event(args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
_complete: false,
|
||||||
|
_request: function(method) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
libly.Request.requestCount++;
|
||||||
|
|
||||||
|
this.method = method;
|
||||||
|
this.transport = new XMLHttpRequest();
|
||||||
|
this.transport.open(method, this.url, this.options.asynchronous, this.options.username, this.options.password);
|
||||||
|
|
||||||
|
var stateChangeException;
|
||||||
|
this.transport.onreadystatechange = libly.$U.bind(this, function () {
|
||||||
|
try {
|
||||||
|
this._onStateChange();
|
||||||
|
} catch (e) {
|
||||||
|
stateChangeException = e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.setRequestHeaders();
|
||||||
|
this.transport.overrideMimeType(this.options.mimetype || 'text/html; charset=' + this.options.encoding);
|
||||||
|
|
||||||
|
this.body = this.method == 'POST' ? this.options.postBody : null;
|
||||||
|
|
||||||
|
this.transport.send(this.body);
|
||||||
|
|
||||||
|
if (!this.options.asynchronous && stateChangeException) throw stateChangeException;
|
||||||
|
|
||||||
|
// Force Firefox to handle ready state 4 for synchronous requests
|
||||||
|
if (!this.options.asynchronous && this.transport.overrideMimeType)
|
||||||
|
this._onStateChange();
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
if (!this.fireEvent('exception', new libly.Response(this), e)) throw e;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_onStateChange: function() {
|
||||||
|
var readyState = this.transport.readyState;
|
||||||
|
if (readyState > 1 && !(readyState == 4 && this._complete))
|
||||||
|
this.respondToReadyState(this.transport.readyState);
|
||||||
|
},
|
||||||
|
getStatus: function() {
|
||||||
|
try {
|
||||||
|
return this.transport.status || 0;
|
||||||
|
} catch (e) { return 0; }
|
||||||
|
},
|
||||||
|
isSuccess: function() {
|
||||||
|
var status = this.getStatus();
|
||||||
|
return !status || (status >= 200 && status < 300);
|
||||||
|
},
|
||||||
|
respondToReadyState: function(readyState) {
|
||||||
|
var state = libly.Request.EVENTS[readyState];
|
||||||
|
var res = new libly.Response(this);
|
||||||
|
|
||||||
|
if (state == 'Complete') {
|
||||||
|
libly.Request.requestCount--;
|
||||||
|
try {
|
||||||
|
this._complete = true;
|
||||||
|
this.fireEvent(this.isSuccess() ? 'success' : 'failure', res, this.options.asynchronous);
|
||||||
|
} catch (e) {
|
||||||
|
if (!this.fireEvent('exception', res, e)) throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setRequestHeaders: function() {
|
||||||
|
var headers = {
|
||||||
|
'Accept': 'text/javascript, application/javascript, text/html, application/xhtml+xml, application/xml, text/xml, */*;q=0.1'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.method == 'POST') {
|
||||||
|
headers['Content-type'] = 'application/x-www-form-urlencoded' +
|
||||||
|
(this.options.encoding ? '; charset=' + this.options.encoding : '');
|
||||||
|
|
||||||
|
if (this.transport.overrideMimeType) {
|
||||||
|
let year = parseInt((navigator.userAgent.match(/\bGecko\/(\d{4})/) || [0, 2005])[1], 10);
|
||||||
|
if (0 < year && year < 2005)
|
||||||
|
headers['Connection'] = 'close';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let key in this.headers)
|
||||||
|
if (this.headers.hasOwnProperty(key)) headers[key] = this.headers[key];
|
||||||
|
|
||||||
|
for (let name in headers)
|
||||||
|
this.transport.setRequestHeader(name, headers[name]);
|
||||||
|
},
|
||||||
|
get: function() {
|
||||||
|
this._request('GET');
|
||||||
|
},
|
||||||
|
post: function() {
|
||||||
|
this._request('POST');
|
||||||
|
}
|
||||||
|
};//}}}
|
||||||
|
|
||||||
|
libly.Response = function() {//{{{
|
||||||
|
this.initialize.apply(this, arguments);
|
||||||
|
};
|
||||||
|
libly.Response.prototype = {
|
||||||
|
initialize: function(req) {
|
||||||
|
this.req = req;
|
||||||
|
this.transport = req.transport;
|
||||||
|
this.isSuccess = req.isSuccess;
|
||||||
|
this.readyState = this.transport.readyState;
|
||||||
|
|
||||||
|
if (this.readyState == 4) {
|
||||||
|
this.status = this.getStatus();
|
||||||
|
this.statusText = this.getStatusText();
|
||||||
|
this.responseText = (this.transport.responseText == null) ? '' : this.transport.responseText;
|
||||||
|
this.responseXML = this.transport.responseXML;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.doc = null;
|
||||||
|
this.htmlFragmentstr = '';
|
||||||
|
},
|
||||||
|
status: 0,
|
||||||
|
statusText: '',
|
||||||
|
getStatus: libly.Request.prototype.getStatus,
|
||||||
|
getStatusText: function() {
|
||||||
|
try {
|
||||||
|
return this.transport.statusText || '';
|
||||||
|
} catch (e) { return ''; }
|
||||||
|
},
|
||||||
|
getHTMLDocument: function(xpath, xmlns, ignoreTags, callback, thisObj) {
|
||||||
|
if (!this.doc) {
|
||||||
|
//if (doc.documentElement.nodeName != 'HTML') {
|
||||||
|
// return new DOMParser().parseFromString(str, 'application/xhtml+xml');
|
||||||
|
//}
|
||||||
|
this.htmlFragmentstr = libly.$U.getHTMLFragment(this.responseText);
|
||||||
|
this.htmlStripScriptFragmentstr = libly.$U.stripTags(this.htmlFragmentstr, ignoreTags);
|
||||||
|
this.doc = libly.$U.createHTMLDocument(this.htmlStripScriptFragmentstr, xmlns);
|
||||||
|
}
|
||||||
|
if (!xpath) xpath = '//*';
|
||||||
|
return libly.$U.getNodesFromXPath(xpath, this.doc, callback, thisObj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
libly.Wedata = function(dbname) { // {{{
|
||||||
|
this.initialize.apply(this, arguments);
|
||||||
|
};
|
||||||
|
libly.Wedata.prototype = {
|
||||||
|
initialize: function(dbname) {
|
||||||
|
this.HOST_NAME = 'http://wedata.net/';
|
||||||
|
this.dbname = dbname;
|
||||||
|
this.logger = libly.$U.getLogger('libly.Wedata');
|
||||||
|
},
|
||||||
|
getItems: function(expire, itemCallback, finalCallback) {
|
||||||
|
|
||||||
|
var logger = this.logger;
|
||||||
|
var STORE_KEY = 'plugins-libly-wedata-' + encodeURIComponent(this.dbname) + '-items';
|
||||||
|
var store = storage.newMap(STORE_KEY, {store: true});
|
||||||
|
var cache = store && store.get('data');
|
||||||
|
|
||||||
|
if (store && cache && new Date(store.get('expire')) > new Date()) {
|
||||||
|
logger.log('return cache. ');
|
||||||
|
cache.forEach(function(item) { if (typeof itemCallback == 'function') itemCallback(item); });
|
||||||
|
if (typeof finalCallback == 'function')
|
||||||
|
finalCallback(true, cache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
expire = expire || 0;
|
||||||
|
|
||||||
|
function errDispatcher(msg, cache) {
|
||||||
|
if (cache) {
|
||||||
|
logger.log('return cache. -> ' + msg);
|
||||||
|
cache.forEach(function(item) { if (typeof itemCallback == 'function') itemCallback(item); });
|
||||||
|
if (typeof finalCallback == 'function')
|
||||||
|
finalCallback(true, cache);
|
||||||
|
} else {
|
||||||
|
logger.log(msg + ': cache notfound.');
|
||||||
|
if (typeof finalCallback == 'function')
|
||||||
|
finalCallback(false, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var req = new libly.Request(this.HOST_NAME + 'databases/' + encodeURIComponent(this.dbname) + '/items.json');
|
||||||
|
req.addEventListener('success', libly.$U.bind(this, function(res) {
|
||||||
|
var text = res.responseText;
|
||||||
|
if (!text) {
|
||||||
|
errDispatcher('response is null.', cache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var json = libly.$U.evalJson(text);
|
||||||
|
if (!json) {
|
||||||
|
errDispatcher('failed eval json.', cache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.log('success get wedata.');
|
||||||
|
store.set('expire', new Date(new Date().getTime() + expire).toString());
|
||||||
|
store.set('data', json);
|
||||||
|
store.save();
|
||||||
|
json.forEach(function(item) { if (typeof itemCallback == 'function') itemCallback(item); });
|
||||||
|
if (typeof finalCallback == 'function')
|
||||||
|
finalCallback(true, json);
|
||||||
|
}));
|
||||||
|
req.addEventListener('failure', function() errDispatcher('onFailure', cache));
|
||||||
|
req.addEventListener('exception', function() errDispatcher('onException', cache));
|
||||||
|
req.get();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
//}
|
||||||
|
// vim: set fdm=marker sw=4 ts=4 sts=0 et:
|
||||||
|
|
726
vimperator/plugin/feedSomeKeys_3.js
Normal file
726
vimperator/plugin/feedSomeKeys_3.js
Normal file
@ -0,0 +1,726 @@
|
|||||||
|
/* NEW BSD LICENSE {{{
|
||||||
|
Copyright (c) 2010-2011, anekos.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
3. The names of the authors may not be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
###################################################################################
|
||||||
|
# http://sourceforge.jp/projects/opensource/wiki/licenses%2Fnew_BSD_license #
|
||||||
|
# に参考になる日本語訳がありますが、有効なのは上記英文となります。 #
|
||||||
|
###################################################################################
|
||||||
|
|
||||||
|
}}} */
|
||||||
|
|
||||||
|
// INFO {{{
|
||||||
|
let INFO =
|
||||||
|
xml`<plugin name="feedSomeKeys" version="1.9.3"
|
||||||
|
href="http://github.com/vimpr/vimperator-plugins/blob/master/feedSomeKeys_3.js"
|
||||||
|
summary="Feed some defined key events into the Web content"
|
||||||
|
lang="en-US"
|
||||||
|
xmlns="http://vimperator.org/namespaces/liberator">
|
||||||
|
<author email="anekos@snca.net">anekos</author>
|
||||||
|
<license>New BSD License</license>
|
||||||
|
<project name="Vimperator" minVersion="2.3"/>
|
||||||
|
<p>
|
||||||
|
Feed key events directly into web contents.
|
||||||
|
</p>
|
||||||
|
<item>
|
||||||
|
<tags>:fmap</tags>
|
||||||
|
<spec>:fmap <oa>-e<oa>vents</oa>=<a>eventnamelist</a></oa> <oa>-x<oa>path</oa>=<a>xpath</a></oa> <oa>-f<oa>rame</oa>=<a>framenumber</a></oa> <oa>-urls=<a>urlpattern</a></oa> <oa>-modes=<a>modes</a></oa> <a>lhs</a> <a>rhs</a></spec>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
Define one mapping.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If <a>-urls=<a>urlpattern</a></a> is given,
|
||||||
|
the mappings becomes effective mappings only on the page specifed by <a>urlpattern</a>.
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<tags>:fmaps</tags>
|
||||||
|
<spec>:fmaps <oa>-e<oa>vents</oa>=<a>eventnamelist</a></oa> <oa>-x<oa>path</oa>=<a>xpath</a></oa> <oa>-f<oa>rame</oa>=<a>framenumber</a></oa> <oa>-urls=<a>urlpattern</a></oa> <oa>-p<oa>prefix</oa>=<a>prefix</a></oa> <oa>-modes=<a>modes</a></oa> <a>mappingpair</a> ....</spec>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
Two or more mappings are defined at once.
|
||||||
|
<a>mappingpair</a> is a pair of key names separated by ",".
|
||||||
|
<p>e.g. "<Leader><S-j>,j"</p>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If <a>-urls=<a>urlpattern</a></a> is given,
|
||||||
|
the mappings becomes effective mappings only on the page specifed by <a>urlpattern</a>.
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<tags>:fmapc</tags>
|
||||||
|
<spec>:fmapc<oa>!</oa> <oa>-modes=<a>modes</a></oa> <oa>urlpattern</oa></spec>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
Remove the mappings matched with <oa>urlpattern</oa>.
|
||||||
|
If "!" is given, remove all mappings.
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<tags>:funmap</tags>
|
||||||
|
<spec>:funmap <oa>-urls=<a>urlpattern</a></oa> <oa>-modes=<a>modes</a></oa> <a>lhs</a></spec>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
Remove the mappings.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you wish to remove url-local mappings, give <a>-urls=<a>urlpattern</a></a>.
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
</item>
|
||||||
|
<h3 tag="fmap-url-pattern">urlpattern</h3>
|
||||||
|
<p>
|
||||||
|
The value of <a>urlpattern</a> should be regular expression.
|
||||||
|
</p>
|
||||||
|
<h3 tag="fmap-xpath">xpath</h3>
|
||||||
|
<p>
|
||||||
|
The XPath for a target element.
|
||||||
|
</p>
|
||||||
|
<h3 tag="fmap-frame-number">framenumber</h3>
|
||||||
|
<p>
|
||||||
|
The number of a target frame.
|
||||||
|
Refer the completion for this number.
|
||||||
|
</p>
|
||||||
|
<h3 tag="fmap-event-name-list">eventnamelist</h3>
|
||||||
|
<p>
|
||||||
|
<a>eventnamelist</a> is the list constructed with the below values.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>keypress</li>
|
||||||
|
<li>keydown</li>
|
||||||
|
<li>keyup</li>
|
||||||
|
<li>vkeypress</li>
|
||||||
|
<li>vkeydown</li>
|
||||||
|
<li>vkeyup</li>
|
||||||
|
</ul>
|
||||||
|
<p>"v..." values use virtual key code.</p>
|
||||||
|
<p>The event is generated in the order of writing of each key.</p>
|
||||||
|
<p>The default value of this option is "keypress".</p>
|
||||||
|
<h3 tag="fmap-modes">modes</h3>
|
||||||
|
<p>
|
||||||
|
List of mapping modes. (Default is NORMAL mode)
|
||||||
|
</p>
|
||||||
|
<h3 tag="fmaps-examples">fmaps examples for .vimperatorrc</h3>
|
||||||
|
<p>If you input directly these commands in vimperator commandline, remove the ":lazy".</p>
|
||||||
|
<code><ex>
|
||||||
|
:command! -nargs=+ lazy autocmd VimperatorEnter .* <args>
|
||||||
|
:lazy fmaps -u='mail\.google\.com/mail' c / j k n p o u e x s r a # [ ] ? gi gs gt gd ga gc
|
||||||
|
:lazy fmaps -u='mail\.google\.com/mail/.*/[0-9a-f]+$' c / j,n k,p n,j p,k o u e x s r a # [ ] ? gi gs gt gd ga gc
|
||||||
|
:lazy fmaps -u='www\.google\.co\.jp/reader' -events=vkeypress j k n p m s v A r S N P X O gh ga gs gt gu u / ? J K
|
||||||
|
:lazy fmaps -u='(fastladder|livedoor)\.com/reader' j k s a p o v c i,p <Space> <S-Space> z b < > q w e,g
|
||||||
|
:lazy fmaps -u='https?://www\.rememberthemilk\.com/home/' j k m i c t ? d F,f G,g S,s L,l Y,y H,h M,m <Del> <C-S-Left> <C-S-Right>
|
||||||
|
:lazy fmaps -u='http://code.google.com/p/vimperator-labs/issues/list' o j k
|
||||||
|
:lazy fmaps -u='http://code.google.com/p/vimperator-labs/issues/detail' u
|
||||||
|
</ex></code>
|
||||||
|
</plugin>
|
||||||
|
<plugin name="feedSomeKeys" version="1.9.3"
|
||||||
|
href="http://github.com/vimpr/vimperator-plugins/blob/master/feedSomeKeys_3.js"
|
||||||
|
summary="Web コンテンツに直接キーイベントを送ります。"
|
||||||
|
lang="ja"
|
||||||
|
xmlns="http://vimperator.org/namespaces/liberator">
|
||||||
|
<author email="anekos@snca.net">anekos</author>
|
||||||
|
<license>New BSD License</license>
|
||||||
|
<project name="Vimperator" minVersion="2.3"/>
|
||||||
|
<p>
|
||||||
|
Web コンテンツに直接キーイベントを送ります。
|
||||||
|
</p>
|
||||||
|
<item>
|
||||||
|
<tags>:fmap</tags>
|
||||||
|
<spec>:fmap <oa>-e<oa>vents</oa>=<a>eventnamelist</a></oa> <oa>-x<oa>path</oa>=<a>xpath</a></oa> <oa>-f<oa>rame</oa>=<a>framenumber</a></oa> <oa>-urls=<a>urlpattern</a></oa> <oa>-modes=<a>modes</a></oa> <a>lhs</a> <a>rhs</a></spec>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
マッピングを一つ定義します。
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a>-urls=<a>urlpattern</a></a> が与えられたとき、
|
||||||
|
そのマッピングは <a>urlpattern</a> で指定されたページのみで有効になります。
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<tags>:fmaps</tags>
|
||||||
|
<spec>:fmaps <oa>-e<oa>vents</oa>=<a>eventnamelist</a></oa> <oa>-x<oa>path</oa>=<a>xpath</a></oa> <oa>-f<oa>rame</oa>=<a>framenumber</a></oa> <oa>-urls=<a>urlpattern</a></oa> <oa>-p<oa>prefix</oa>=<a>prefix</a></oa> <oa>-modes=<a>modes</a></oa> <a>mappingpair</a> ....</spec>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
一度に複数のマッピングを定義できます。
|
||||||
|
<a>mappingpair</a> は、"," で区切られたキー名の組です。
|
||||||
|
<p>例: "<Leader><S-j>,j"</p>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a>-urls=<a>urlpattern</a></a> が与えられたとき、
|
||||||
|
そのマッピングは <a>urlpattern</a> で指定されたページのみで有効になります。
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<tags>:fmapc</tags>
|
||||||
|
<spec>:fmapc<oa>!</oa> <oa>-modes=<a>modes</a></oa> <oa>urlpattern</oa></spec>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
<oa>urlpattern</oa> のマッピングを削除します。
|
||||||
|
"!" が与えられたときは、全てのマッピングが削除されます。
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<tags>:funmap</tags>
|
||||||
|
<spec>:funmap <oa>-urls=<a>urlpattern</a></oa> <oa>-modes=<a>modes</a></oa> <a>lhs</a></spec>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
マッピングを削除します。
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a>urlpattern</a> 付きのマッピングを削除するときは、<oa>-urls</oa> を指定する必要があります。
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
</item>
|
||||||
|
<h3 tag="fmap-url-pattern">urlpattern</h3>
|
||||||
|
<p>
|
||||||
|
<a>urlpattern</a> の値は正規表現でなければいけません。
|
||||||
|
</p>
|
||||||
|
<h3 tag="fmap-event-name-list">eventnamelist</h3>
|
||||||
|
<p>
|
||||||
|
<a>eventnamelist</a> は以下の値から構成されたリストです。
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>keypress</li>
|
||||||
|
<li>keydown</li>
|
||||||
|
<li>keyup</li>
|
||||||
|
<li>vkeypress</li>
|
||||||
|
<li>vkeydown</li>
|
||||||
|
<li>vkeyup</li>
|
||||||
|
</ul>
|
||||||
|
<p>"v..." のものは、仮想キーコードでイベントを発行します。</p>
|
||||||
|
<p>キー毎に、書かれた順にイベントが発行されます。</p>
|
||||||
|
<p>このオプションのデフォルト値は "keypress" です。</p>
|
||||||
|
<h3 tag="fmap-xpath">xpath</h3>
|
||||||
|
<p>
|
||||||
|
キーイベントを送るべき要素を指定するための XPath。
|
||||||
|
</p>
|
||||||
|
<h3 tag="fmap-frame-number">framenumber</h3>
|
||||||
|
<p>
|
||||||
|
キーイベントを送るべきフレームの番号。
|
||||||
|
番号は、補完を参考にしてください。
|
||||||
|
</p>
|
||||||
|
<h3 tag="fmap-modes">modes</h3>
|
||||||
|
<p>
|
||||||
|
マップするモードのリスト (デフォルトは、NORMALモード)
|
||||||
|
</p>
|
||||||
|
<h3 tag="fmaps-examples">.vimperatorrc 用の fmaps サンプル</h3>
|
||||||
|
<p>コマンドラインで直接に入力するときは、":lazy" を除いてください。</p>
|
||||||
|
<code><ex>
|
||||||
|
:command! -nargs=+ lazy autocmd VimperatorEnter .* <args>
|
||||||
|
:lazy fmaps -u='mail\.google\.com/mail' c / j k n p o u e x s r a # [ ] ? gi gs gt gd ga gc
|
||||||
|
:lazy fmaps -u='mail\.google\.com/mail/.*/[0-9a-f]+$' c / j,n k,p n,j p,k o u e x s r a # [ ] ? gi gs gt gd ga gc
|
||||||
|
:lazy fmaps -u='www\.google\.co\.jp/reader' -events=vkeypress j k n p m s v A r S N P X O gh ga gs gt gu u / ? J K
|
||||||
|
:lazy fmaps -u='(fastladder|livedoor)\.com/reader' j k s a p o v c i,p <Space> <S-Space> z b < > q w e,g
|
||||||
|
:lazy fmaps -u='https?://www\.rememberthemilk\.com/home/' j k m i c t ? d F,f G,g S,s L,l Y,y H,h M,m <Del> <C-S-Left> <C-S-Right>
|
||||||
|
:lazy fmaps -u='http://code.google.com/p/vimperator-labs/issues/list' o j k
|
||||||
|
:lazy fmaps -u='http://code.google.com/p/vimperator-labs/issues/detail' u
|
||||||
|
</ex></code>
|
||||||
|
</plugin>`;
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
const EVENTS = 'keypress keydown keyup'.split(/\s+/);
|
||||||
|
const EVENTS_WITH_V = EVENTS.concat(['v' + n for each (n in EVENTS)]);
|
||||||
|
const IGNORE_URLS = /<ALL>/;
|
||||||
|
|
||||||
|
const VKeys = {
|
||||||
|
'0': KeyEvent.DOM_VK_0,
|
||||||
|
'1': KeyEvent.DOM_VK_1,
|
||||||
|
'2': KeyEvent.DOM_VK_2,
|
||||||
|
'3': KeyEvent.DOM_VK_3,
|
||||||
|
'4': KeyEvent.DOM_VK_4,
|
||||||
|
'5': KeyEvent.DOM_VK_5,
|
||||||
|
'6': KeyEvent.DOM_VK_6,
|
||||||
|
'7': KeyEvent.DOM_VK_7,
|
||||||
|
'8': KeyEvent.DOM_VK_8,
|
||||||
|
'9': KeyEvent.DOM_VK_9,
|
||||||
|
';': KeyEvent.DOM_VK_SEMICOLON,
|
||||||
|
'=': KeyEvent.DOM_VK_EQUALS,
|
||||||
|
'a': KeyEvent.DOM_VK_A,
|
||||||
|
'b': KeyEvent.DOM_VK_B,
|
||||||
|
'c': KeyEvent.DOM_VK_C,
|
||||||
|
'd': KeyEvent.DOM_VK_D,
|
||||||
|
'e': KeyEvent.DOM_VK_E,
|
||||||
|
'f': KeyEvent.DOM_VK_F,
|
||||||
|
'g': KeyEvent.DOM_VK_G,
|
||||||
|
'h': KeyEvent.DOM_VK_H,
|
||||||
|
'i': KeyEvent.DOM_VK_I,
|
||||||
|
'j': KeyEvent.DOM_VK_J,
|
||||||
|
'k': KeyEvent.DOM_VK_K,
|
||||||
|
'l': KeyEvent.DOM_VK_L,
|
||||||
|
'm': KeyEvent.DOM_VK_M,
|
||||||
|
'n': KeyEvent.DOM_VK_N,
|
||||||
|
'o': KeyEvent.DOM_VK_O,
|
||||||
|
'p': KeyEvent.DOM_VK_P,
|
||||||
|
'q': KeyEvent.DOM_VK_Q,
|
||||||
|
'r': KeyEvent.DOM_VK_R,
|
||||||
|
's': KeyEvent.DOM_VK_S,
|
||||||
|
't': KeyEvent.DOM_VK_T,
|
||||||
|
'u': KeyEvent.DOM_VK_U,
|
||||||
|
'v': KeyEvent.DOM_VK_V,
|
||||||
|
'w': KeyEvent.DOM_VK_W,
|
||||||
|
'x': KeyEvent.DOM_VK_X,
|
||||||
|
'y': KeyEvent.DOM_VK_Y,
|
||||||
|
'z': KeyEvent.DOM_VK_Z,
|
||||||
|
'*': KeyEvent.DOM_VK_MULTIPLY,
|
||||||
|
'+': KeyEvent.DOM_VK_ADD,
|
||||||
|
'-': KeyEvent.DOM_VK_SUBTRACT,
|
||||||
|
',': KeyEvent.DOM_VK_COMMA,
|
||||||
|
'.': KeyEvent.DOM_VK_PERIOD,
|
||||||
|
'/': KeyEvent.DOM_VK_SLASH,
|
||||||
|
'?': KeyEvent.DOM_VK_SLASH,
|
||||||
|
'`': KeyEvent.DOM_VK_BACK_QUOTE,
|
||||||
|
'{': KeyEvent.DOM_VK_OPEN_BRACKET,
|
||||||
|
'\\': KeyEvent.DOM_VK_BACK_SLASH,
|
||||||
|
'}': KeyEvent.DOM_VK_CLOSE_BRACKET,
|
||||||
|
'\'': KeyEvent.DOM_VK_QUOTE
|
||||||
|
};
|
||||||
|
|
||||||
|
const State = {
|
||||||
|
feeding: false
|
||||||
|
};
|
||||||
|
|
||||||
|
function id (v)
|
||||||
|
v;
|
||||||
|
|
||||||
|
function or (list, func)
|
||||||
|
(list.length && let ([head,] = list) (func(head) || or(list.slice(1), func)));
|
||||||
|
|
||||||
|
function getFrames () {
|
||||||
|
function bodyCheck (content)
|
||||||
|
(content.document && content.document.body && content.document.body.localName.toLowerCase() === 'body');
|
||||||
|
|
||||||
|
function get (content)
|
||||||
|
(bodyCheck(content) && result.push(content), Array.slice(content.frames).forEach(get));
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
get(content);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fromXPath (doc, xpath) {
|
||||||
|
let result = util.evaluateXPath(xpath, doc);
|
||||||
|
return result.snapshotLength && result.snapshotItem(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createEvent (eventName, event) {
|
||||||
|
let result = content.document.createEvent('KeyEvents');
|
||||||
|
result.initKeyEvent(
|
||||||
|
eventName,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
content,
|
||||||
|
event.ctrlKey,
|
||||||
|
event.altKey,
|
||||||
|
event.shiftKey,
|
||||||
|
event.metaKey,
|
||||||
|
event.keyCode,
|
||||||
|
event.charCode
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function virtualize (event) {
|
||||||
|
let cc = event.charCode;
|
||||||
|
if (/^[A-Z]$/.test(String.fromCharCode(cc)))
|
||||||
|
event.shiftKey = true;
|
||||||
|
event.keyCode = VKeys[String.fromCharCode(cc).toLowerCase()];
|
||||||
|
event.charCode = 0;
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
function feed (keys, eventNames, target) {
|
||||||
|
function finalize (){
|
||||||
|
modes.passAllKeys = _passAllKeys;
|
||||||
|
State.feeding = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
State.feeding = true;
|
||||||
|
|
||||||
|
let _passAllKeys = modes.passAllKeys;
|
||||||
|
|
||||||
|
try {
|
||||||
|
modes.passAllKeys = true;
|
||||||
|
modes.passNextKey = false;
|
||||||
|
|
||||||
|
for (let [, keyEvent] in Iterator(events.fromString(keys))) {
|
||||||
|
eventNames.forEach(function (eventName) {
|
||||||
|
let ke = util.cloneObject(keyEvent);
|
||||||
|
let [, vkey, name] = eventName.match(/^(v)?(.+)$/);
|
||||||
|
if (vkey)
|
||||||
|
virtualize(ke);
|
||||||
|
let event = createEvent(name, ke);
|
||||||
|
target.dispatchEvent(event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
finalize();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeTryValidator (func)
|
||||||
|
function (value) {
|
||||||
|
try {
|
||||||
|
liberator.log(value);
|
||||||
|
func(value);
|
||||||
|
return true;
|
||||||
|
} catch (e) {}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let regexpValidator = makeTryValidator(RegExp);
|
||||||
|
|
||||||
|
let xpathValidator =
|
||||||
|
makeTryValidator(function (expr) document.evaluate(expr, document, null, null, null))
|
||||||
|
|
||||||
|
function fromModeString (s){
|
||||||
|
for (let [, {name, mask, char}] in Iterator(modes._modeMap))
|
||||||
|
if (s === name || s === char)
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fromModeStrings (ss, def) {
|
||||||
|
if (def && (!ss || ss.length < 1))
|
||||||
|
return [modes.NORMAL];
|
||||||
|
return ss.map(fromModeString).filter(function (it) (typeof it === 'number'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function modeStringsValidator (ss)
|
||||||
|
(!ss || (fromModeStrings(ss).length === ss.length));
|
||||||
|
|
||||||
|
function makeListValidator (list)
|
||||||
|
function (values)
|
||||||
|
(values && !values.some(function (value) !list.some(function (event) event === value)));
|
||||||
|
|
||||||
|
function findMappings ({all, filter, urls, ignoreUrls, not, result, modes: targetModes}) {
|
||||||
|
function match (map) {
|
||||||
|
let r = (
|
||||||
|
map.feedSomeKeys &&
|
||||||
|
(all ||
|
||||||
|
(!filter || filter === map.names[0]) &&
|
||||||
|
(ignoreUrls || urls === IGNORE_URLS || mappings._matchingUrlsTest(map, urls)))
|
||||||
|
);
|
||||||
|
if (result && r) {
|
||||||
|
if (typeof result.matched === 'number')
|
||||||
|
result.matched++;
|
||||||
|
else
|
||||||
|
result.matched = 1;
|
||||||
|
}
|
||||||
|
return !!r ^ !!not;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter)
|
||||||
|
filter = mappings._expandLeader(filter);
|
||||||
|
if (urls)
|
||||||
|
urls = RegExp(urls);
|
||||||
|
|
||||||
|
// FIXME 同じオブジェクトがダブって返るかも(あるいはそれで良い?)
|
||||||
|
let result = [];
|
||||||
|
for (let [, m] in Iterator(targetModes || [modes.NORMAL]))
|
||||||
|
result = result.concat(mappings._user[m].filter(match));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unmap (condition) {
|
||||||
|
condition = Object.create(condition);
|
||||||
|
let ms = condition.modes || [modes.NORMAL];
|
||||||
|
condition.not = true;
|
||||||
|
condition.modes = undefined;
|
||||||
|
for (let [, m] in Iterator(ms)) {
|
||||||
|
condition.modes = [m];
|
||||||
|
mappings._user[m] = findMappings(condition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function list (condition) {
|
||||||
|
let maps = findMappings(condition);
|
||||||
|
let template = modules.template;
|
||||||
|
let length = 0;
|
||||||
|
let list =
|
||||||
|
xml`<table>
|
||||||
|
${
|
||||||
|
template.map(maps, function (map){
|
||||||
|
++length;
|
||||||
|
return template.map(map.names, function (name)
|
||||||
|
xml`<tr>
|
||||||
|
<td style="font-weight: bold">${name}</td>
|
||||||
|
<td style="font-weight: bold">${map.feedSomeKeys.rhs}</td>
|
||||||
|
<td>${map.matchingUrls ? map.matchingUrls : '[Global]'}</td>
|
||||||
|
</tr>`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</table>`;
|
||||||
|
|
||||||
|
if (length == 0) {
|
||||||
|
liberator.echomsg("No mapping found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fmapCompleter (context, args) {
|
||||||
|
context.title = ['name', 'rhs & url'];
|
||||||
|
context.completions = [
|
||||||
|
[
|
||||||
|
xml`<span style="font-weight: bold">${map.names[0]}</span>,
|
||||||
|
<span>
|
||||||
|
<span style="font-weight: bold">${map.feedSomeKeys.rhs}</span>
|
||||||
|
<span>${
|
||||||
|
args['-ignoreurls']
|
||||||
|
? xml`<span> for </span><span>${map.matchingUrls ? map.matchingUrls : 'Global'}</span>`
|
||||||
|
: ''
|
||||||
|
}</span>
|
||||||
|
</span>`
|
||||||
|
]
|
||||||
|
for each (map in findMappings({urls: args['-urls'], ignoreUrls: args['-ignoreurls']}))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function urlCompleter ({currentURL}) {
|
||||||
|
return function (context, args) {
|
||||||
|
let maps = findMappings({all: true});
|
||||||
|
let uniq = {};
|
||||||
|
let result = [
|
||||||
|
(uniq[map.matchingUrls] = 1, [map.matchingUrls.source, map.names])
|
||||||
|
for each (map in maps)
|
||||||
|
if (map.matchingUrls && !uniq[map.matchingUrls])
|
||||||
|
];
|
||||||
|
if (currentURL) {
|
||||||
|
result.unshift(['^' + util.escapeRegex(buffer.URL), 'Current URL']);
|
||||||
|
if (content.document.domain)
|
||||||
|
result.unshift([util.escapeRegex(content.document.domain), 'Current domain']);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function frameCompleter (context, args) {
|
||||||
|
return [
|
||||||
|
[i, frame.document.location]
|
||||||
|
for each ([i, frame] in Iterator(getFrames()))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModeStringsCompleter = [
|
||||||
|
[name, disp + ' mode' + (char ? ' (alias: ' + char + ')' : '')]
|
||||||
|
for ([n, {name, char, disp, extended}] in Iterator(modes._modeMap))
|
||||||
|
if (!extended && /^\D+$/.test(n))
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
'fmap fmaps'.split(/\s+/).forEach(function (cmd) {
|
||||||
|
let multi = cmd === 'fmaps';
|
||||||
|
|
||||||
|
function action (multi) {
|
||||||
|
return function (args) {
|
||||||
|
let prefix = args['-prefix'] || '';
|
||||||
|
let ms = fromModeStrings(args['-modes'], true);
|
||||||
|
|
||||||
|
function add ([lhs, rhs]) {
|
||||||
|
if (!lhs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rhs = rhs || lhs;
|
||||||
|
mappings.addUserMap(
|
||||||
|
ms,
|
||||||
|
[prefix + lhs],
|
||||||
|
args['description'] || 'by feedSomeKeys_3.js',
|
||||||
|
function () {
|
||||||
|
function body (win)
|
||||||
|
(win.document.body || win.document);
|
||||||
|
|
||||||
|
let win = document.commandDispatcher.focusedWindow;
|
||||||
|
let frames = getFrames();
|
||||||
|
|
||||||
|
let elem = liberator.focus || body(win);
|
||||||
|
|
||||||
|
if (typeof args['-frame'] !== 'undefined') {
|
||||||
|
frames = [frames[args['-frame']]];
|
||||||
|
elem = body(frames[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args['-xpath']) {
|
||||||
|
elem = or(frames, function (f) fromXPath(f.document, args['-xpath'])) || elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args['-selector']) {
|
||||||
|
elem = or(frames, function (f) f.document.querySelector(args['-selector'])) || elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
feed(rhs, args['-events'] || ['keypress'], elem);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
matchingUrls: args['-urls'],
|
||||||
|
feedSomeKeys: {
|
||||||
|
rhs: rhs,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multi) {
|
||||||
|
let sep = let (s = args['-separator'] || ',') function (v) v.split(s);
|
||||||
|
args.literalArg.split(/\s+/).map(String.trim).map(sep).forEach(add);
|
||||||
|
} else {
|
||||||
|
let [, lhs, rhs] = args.literalArg.match(/^(\S+)\s+(.*)$/) || args.literalArg;
|
||||||
|
if (!rhs) {
|
||||||
|
list({
|
||||||
|
filter: prefix + args.literalArg.trim(),
|
||||||
|
urls: args['-urls'],
|
||||||
|
ignoreUrls: !args['-urls'],
|
||||||
|
modes: ms
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
add([lhs, rhs]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
commands.addUserCommand(
|
||||||
|
[cmd],
|
||||||
|
'Feed map a key sequence',
|
||||||
|
action(multi),
|
||||||
|
{
|
||||||
|
literal: 0,
|
||||||
|
options: [
|
||||||
|
[['-modes', '-m'], commands.OPTION_LIST, modeStringsValidator, ModeStringsCompleter],
|
||||||
|
[['-urls', '-u'], commands.OPTION_STRING, regexpValidator, urlCompleter({currentURL: true})],
|
||||||
|
[['-desc', '-description', '-d'], commands.OPTION_STRING],
|
||||||
|
[['-frame', '-f'], commands.OPTION_INT, null, frameCompleter],
|
||||||
|
[['-xpath', '-x'], commands.OPTION_STRING, xpathValidator],
|
||||||
|
[['-selector', '-s'], commands.OPTION_STRING],
|
||||||
|
[['-prefix', '-p'], commands.OPTION_STRING],
|
||||||
|
[
|
||||||
|
['-events', '-e'],
|
||||||
|
commands.OPTION_LIST,
|
||||||
|
makeListValidator(EVENTS_WITH_V),
|
||||||
|
EVENTS_WITH_V.map(function (v) [v, v])
|
||||||
|
]
|
||||||
|
].concat(
|
||||||
|
multi ? [[['-separator', '-s'], commands.OPTION_STRING]]
|
||||||
|
: []
|
||||||
|
),
|
||||||
|
completer: multi ? null : fmapCompleter
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
commands.addUserCommand(
|
||||||
|
['fmapc'],
|
||||||
|
'Clear fmappings',
|
||||||
|
function (args) {
|
||||||
|
let ms = fromModeStrings(args['-modes'], true);
|
||||||
|
if (args.bang) {
|
||||||
|
unmap({ignoreUrls: true, modes: ms});
|
||||||
|
liberator.log('All fmappings were removed.');
|
||||||
|
} else {
|
||||||
|
let result = {};
|
||||||
|
unmap({urls: args.literalArg, result: result, modes: ms});
|
||||||
|
liberator.echo(result.matched ? 'Some fmappings were removed.' : 'Not found specifed fmappings.');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
literal: 0,
|
||||||
|
bang: true,
|
||||||
|
completer: function (context) {
|
||||||
|
context.title = ['URL Pattern'];
|
||||||
|
context.completions = urlCompleter({})(context);
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
[['-modes', '-m'], commands.OPTION_LIST],
|
||||||
|
]
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
commands.addUserCommand(
|
||||||
|
['funmap'],
|
||||||
|
'Remove fmappings',
|
||||||
|
function (args) {
|
||||||
|
let urls = args['-urls'];
|
||||||
|
let name = args.literalArg;
|
||||||
|
if (!name)
|
||||||
|
return liberator.echoerr('E471: Argument required');
|
||||||
|
|
||||||
|
let result = {};
|
||||||
|
unmap({
|
||||||
|
filter: name,
|
||||||
|
urls: urls,
|
||||||
|
ignoreUrls: args['-ignoreurls'],
|
||||||
|
result: result,
|
||||||
|
modes: fromModeStrings(args['-modes'], true)
|
||||||
|
});
|
||||||
|
liberator.echo(result.matched ? 'Some fmappings were removed.' : 'Not found specifed fmappings.');
|
||||||
|
},
|
||||||
|
{
|
||||||
|
literal: 0,
|
||||||
|
options: [
|
||||||
|
[['-modes', '-m'], commands.OPTION_LIST],
|
||||||
|
[['-urls', '-u'], commands.OPTION_STRING, regexpValidator, urlCompleter({})],
|
||||||
|
[['-ignoreurls', '-iu'], commands.OPTION_NOARG]
|
||||||
|
],
|
||||||
|
completer: fmapCompleter
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
plugins.libly.$U.around(
|
||||||
|
mappings,
|
||||||
|
'getCandidates',
|
||||||
|
function (next, [mode, prefix, patternOrUrl]) {
|
||||||
|
let map = mappings.get(mode, prefix, patternOrUrl);
|
||||||
|
if (map && map.matchingUrls)
|
||||||
|
return [];
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
__context__.API =
|
||||||
|
'State VKeys feed getFrames fromXPath virtualize unmap findMappings list'.split(/\s+/).reduce(
|
||||||
|
function (result, name)
|
||||||
|
(result[name] = eval(name), result),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
// vim:sw=2 ts=2 et si fdm=marker:
|
35
vimperator/plugin/wallabag.js
Normal file
35
vimperator/plugin/wallabag.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
let PLUGIN_INFO = xml`
|
||||||
|
<VimperatorPlugin>
|
||||||
|
<name>wallabag</name>
|
||||||
|
<description lang="en">Pocket</description>
|
||||||
|
<version>0.1.1</version>
|
||||||
|
<minVersion>3.2</minVersion>
|
||||||
|
<author mail="philipp@schmitt.co" homepage="http://lxl.io">Philipp Schmitt</author>
|
||||||
|
<updateURL>https://raw.github.com/pschmitt/vimperator-wallabag/master/wallabag.js</updateURL>
|
||||||
|
<detail lang="en"><![CDATA[
|
||||||
|
// TODO Documentation
|
||||||
|
]]></detail>
|
||||||
|
</VimperatorPlugin>`;
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
let wallabag_url = (liberator.globalVariables.wallabag_url) ? liberator.globalVariables.wallabag_url : '';
|
||||||
|
|
||||||
|
commands.addUserCommand(['wallabag', 'wg'], 'Wallabag plugin',
|
||||||
|
function(args) {
|
||||||
|
let url = buffer.URL;
|
||||||
|
|
||||||
|
if (typeof args != 'undefined' && args.length > 0) {
|
||||||
|
url = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wallabag_url == '') {
|
||||||
|
liberator.echoerr('Wallabag URL undefined. Please add let g:wallabag_url="http://YOURURL" to your vimperatorrc');
|
||||||
|
} else {
|
||||||
|
liberator.open(wallabag_url + '/?action=add&url=' + btoa(url), liberator.NEW_TAB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
50
vimperatorrc
Normal file
50
vimperatorrc
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
set runtimepath=~/etc/vimperator
|
||||||
|
|
||||||
|
set gui=none,tabs
|
||||||
|
"set tabnumbers
|
||||||
|
|
||||||
|
set defsearch=g
|
||||||
|
|
||||||
|
" follow hints on return
|
||||||
|
set followhints=1
|
||||||
|
|
||||||
|
set incsearch hlsearch
|
||||||
|
set ignorecase smartcase
|
||||||
|
|
||||||
|
set noerrorbells novisualbell
|
||||||
|
js liberator.beep = function() { return false; }
|
||||||
|
|
||||||
|
" google
|
||||||
|
map s og<Space>
|
||||||
|
map S tg<Space>
|
||||||
|
|
||||||
|
" fast scrolling
|
||||||
|
noremap j <Down>
|
||||||
|
noremap k <Up>
|
||||||
|
|
||||||
|
let g:wallabag_url="https://wllbg.gebner.org"
|
||||||
|
|
||||||
|
js <<EOM
|
||||||
|
googleTranslate = function() {
|
||||||
|
let getParameterByName = function(url, name) {
|
||||||
|
let name = name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]');
|
||||||
|
let regexS = '[\\?&]' + name + '=([^&#]*)';
|
||||||
|
let regex = new RegExp(regexS);
|
||||||
|
let results = regex.exec(url);
|
||||||
|
if (results == null)
|
||||||
|
return '';
|
||||||
|
else
|
||||||
|
return decodeURIComponent(results[1].replace(/\+/g, ' '));
|
||||||
|
};
|
||||||
|
if (buffer.URL.startsWith('http://translate.google.com/')) {
|
||||||
|
liberator.open(getParameterByName(buffer.URL, 'u'));
|
||||||
|
} else {
|
||||||
|
liberator.open('http://translate.google.com/translate?hl=en&sl=auto&tl=en&u=' + encodeURIComponent(buffer.URL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOM
|
||||||
|
command! translate js googleTranslate();
|
||||||
|
|
||||||
|
" FIXME: doesn't work?
|
||||||
|
loadplugins
|
||||||
|
fmaps -u='https://reader.gebner.org/' fr u <C-Up> <C-Down> <Up> <Down>
|
1
vimrc
1
vimrc
@ -59,6 +59,7 @@ NeoBundle 'derekwyatt/vim-scala'
|
|||||||
NeoBundle 'othree/html5.vim'
|
NeoBundle 'othree/html5.vim'
|
||||||
|
|
||||||
NeoBundle 'dogrover/vim-pentadactyl'
|
NeoBundle 'dogrover/vim-pentadactyl'
|
||||||
|
NeoBundle 'superbrothers/vim-vimperator'
|
||||||
|
|
||||||
NeoBundle 'idris-hackers/idris-vim'
|
NeoBundle 'idris-hackers/idris-vim'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user