You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

.keysnail.js 34 KiB

13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907
  1. // ========================== KeySnail Init File =========================== //
  2. // この領域は, GUI により設定ファイルを生成した際にも引き継がれます
  3. // 特殊キー, キーバインド定義, フック, ブラックリスト以外のコードは, この中に書くようにして下さい
  4. // ========================================================================= //
  5. //{{%PRESERVE%
  6. // prompt.rows = 12;
  7. // prompt.useMigemo = false;
  8. // prompt.migemoMinWordLength = 2;
  9. // prompt.displayDelayTime = 300;
  10. // command.kill.killRingMax = 15;
  11. // command.kill.textLengthMax = 8192;
  12. //userscript.addLoadPath(".");
  13. //userscript.require("verticaltab.js");
  14. //////////////////////////////////////
  15. //// sitelocalkeymap
  16. var local = {};
  17. plugins.options["site_local_keymap.local_keymap"] = local;
  18. function fake(k, i) function () { key.feed(k, i); };
  19. function pass(k, i) [k, fake(k, i)];
  20. function ignore(k, i) [k, null];
  21. // ext.add("ext-name", function () {}, "ext description");
  22. // style.register("");
  23. // local["^http://"] = [['a', function(ev, arg){}],];
  24. ///////////////////////////////////////////
  25. //// firefox
  26. // style.register("#bookmarksPanel > hbox,#history-panel > hbox {display: none !important;} //#urlbar-container{max-width: 500px !important;}");
  27. util.setPrefs(
  28. {
  29. "browser.tabs.loadDivertedInBackground": true,
  30. "dom.disable_window_open_feature.location": false,
  31. "dom.max_script_run_time": 30,
  32. "browser.bookmarks.max_backups":0,
  33. "browser.urlbar.autocomplete.enabled":false,
  34. "browser.cache.memory.capacity":16384,
  35. "browser.sessionhistory.max_total_viewers":8,
  36. "browser.download.manager.closeWhenDone":true,
  37. "browser.download.useDownloadDir":false,
  38. "browser.tabs.closeWindowWithLastTab":false,
  39. "network.dns.disableIPv6":true,
  40. "browser.urlbar.trimURLs":false,
  41. }
  42. );
  43. ///////////////////////////////////
  44. //検索エンジン
  45. plugins.options["search-url-list"] = [
  46. ["bing","http://bing.com/search?q=%q"],
  47. ["yatwitter search","http://yats-data.com/yats/search?query=%q"],
  48. ["twitter search","http://search.twitter.com/search?q=%q&lang=all"],
  49. ["tospy", "http://topsy.com/s?allow_lang=ja&q=%q"],
  50. ["2ch","http://2ch-ranking.net/search.php?q=%q&imp=and&order=time"],
  51. ["I\'m feelig lucky!","http://www.google.co.jp/search?q=%q&btnI=kudos"],
  52. ["uncyclopedia","http://ja.uncyclopedia.info/wiki/%q"],
  53. ["wikipedia","http://ja.wikipedia.org/wiki/%q"],
  54. ["nicovideo.jp","http://www.nicovideo.jp/search/%q"],
  55. ["alc","http://eow.alc.co.jp/%q/UTF-8/"],
  56. ["google map","http://maps.google.co.jp/maps?hl=ja&q=%q&um=1&ie=UTF-8&sa=N&tab=wl"],
  57. ["weblio","http://www.weblio.jp/content_find?query=%q"],
  58. ["shoutcast","http://www.shoutcast.com/Internet-Radio/%q"],
  59. ["10sr.posterous.com","http://www.google.com/search?q=%q&ie=UTF-8&oe=UTF-8&hl=ja&domains=10sr.posterous.com&sitesearch=10sr.posterous.com"],
  60. ["delicious 10sr","http://delicious.com/10sr?addtag=%q&setcount=50&opennew=1"],
  61. ["open raw","%r"],
  62. ];
  63. plugins.options["my-keysnail-bookmarks"] = [
  64. "twitter.com",
  65. ];
  66. //sitelocal
  67. //////////////////////////////////////////
  68. // 2ch chaika
  69. local["^http://127.0.0.1:8823/thread/"] = [
  70. ['k', function (ev, arg) {
  71. curl = window.content.location.href;
  72. kurl = curl.replace(/http:.*thread\/(.*\/).*/, "chaika://post/$1");
  73. window.content.location.href = kurl;
  74. }
  75. ],
  76. ];
  77. local["^http://w2.p2.2ch.net/p2/read.php"] = [
  78. ['k', function (ev, arg) {
  79. var url = window.content.location.href;
  80. var pt = /host=(.*?)&bbs=(.*?)&key=(.*?)&ls=/ ;
  81. var result = url.match(pt);
  82. var k = format("chaika://post/http://%s/test/read.cgi/%s/%s/", result[1], result[2], result[3]);
  83. window.content.location.href = k;
  84. }
  85. ],
  86. ];
  87. /////////////////////////////////////////
  88. // feedly用マップ
  89. local["^http://www.feedly.com/"] = [
  90. ['d', null],
  91. ['j', null],
  92. ['k', null],
  93. ['n', null],
  94. ['p', null],
  95. ['o', null],
  96. ['b', null],
  97. ['S', null],
  98. ['s', null],
  99. ['?', null],
  100. ['l', function (ev, arg) {window.content.location.href = "http://www.feedly.com/home#latest";}],
  101. ['r', null],
  102. ['x', function (ev, arg) {ev.target.dispatchEvent(key.stringToKeyEvent("g", true));}],
  103. [['t', 'p'], function (ev, arg) {ev.target.dispatchEvent(key.stringToKeyEvent("t", true));}],
  104. [['t', 'w'], function (ev, arg) {ext.exec("twitter-client-tweet", arg, ev);}],
  105. ];
  106. /////////////////////////////////////////
  107. //nicovideo用
  108. local["http://(www|tw|es|de|)\.nicovideo\.jp\/watch/*"] = [
  109. ["i", function (ev, arg) { ext.exec("nicoinfo", arg); }],
  110. ["p", function (ev, arg) { ext.exec("nicopause", arg); }],
  111. ["o", function (ev, arg) { ext.exec("nicommentvisible", arg); }],
  112. ["m", function (ev, arg) { ext.exec("nicomute", arg); }],
  113. [".", function (ev, arg) { ext.exec("nicovolumeIncrement", arg); }],
  114. [",", function (ev, arg) { ext.exec("nicovolumeDecrement", arg); }],
  115. ['f', function (ev, arg) {
  116. curl = window.content.location.href;
  117. kurl = curl.replace(/nicovideo.jp/, "nicovideofire.jp");
  118. window.content.location.href = kurl;
  119. }
  120. ],
  121. ];
  122. /////////////////////////////////////////
  123. // tumblr/dashboard
  124. local["^http://www.tumblr.com/dashboard"] = [
  125. // ["C-<left>", function (ev, arg) {gBrowser.mTabContainer.advanceSelectedTab(-1, true); }],
  126. // ["C-<right>", function (ev, arg) {gBrowser.mTabContainer.advanceSelectedTab(1, true); }],
  127. ["<left>", function (ev, arg) {window.content.location.href = "http://www.tumblr.com/dashboard"; }],
  128. // ["<right>", null],
  129. ["J", function (ev, arg) {
  130. if (window.loadURI) {
  131. loadURI("javascript:(function(){b=20;s=100;t=document.getElementById('next_page_link').href.split('/')[5];max=t.substr(0,t.length-5);min=max-s;i=Math.floor(Math.random()*(max-min)+min);u=(i<b)?'http://www.tumblr.com/dashboard':'http://www.tumblr.com/dashboard/2/'+i+'00000';window.content.location.href=u;}())");
  132. }
  133. }],
  134. ];
  135. ///////////////////////////////////
  136. //tanythhing用
  137. plugins.options["tanything_opt.keymap"] = {
  138. "\\" : "prompt-cancel",
  139. "j" : "prompt-next-completion",
  140. "k" : "prompt-previous-completion",
  141. "o" : "localOpen",
  142. ":" : "localClose",
  143. "L" : "localMovetoend"
  144. };
  145. //////////////////////////////////////////
  146. // yatc
  147. style.register("#keysnail-twitter-client-container{ display:none !important; }");
  148. plugins.options["twitter_client.popup_new_statuses"] = false;
  149. plugins.options["twitter_client.automatically_begin"] = false;
  150. plugins.options["twitter_client.automatically_begin_list"] = false;
  151. plugins.options["twitter_client.timeline_count_beginning"] = 0;
  152. plugins.options["twitter_client.timeline_count_every_updates"] = 0;
  153. plugins.options["twitter_client.tweet_keymap"] = {
  154. "C-RET" : "prompt-decide",
  155. "RET" : ""
  156. };
  157. plugins.options["twitter_client.jmp_id"] = "10sr";
  158. plugins.options["twitter_client.jmp_key"] = "R_c51f889a77cb4b4e993ed868f65083f5";
  159. plugins.options["twitter_client.use_jmp"] = true;
  160. ////////////////////////////////////////////
  161. // エクステ
  162. /////////////////////////////////////
  163. // google itranslate
  164. (function(){
  165. let targetLang = "ja"; // target lang to translate into
  166. let alternativeLang = "en"; // if given word is in targetLang, use this instead as a target lang
  167. function translate(word, target, next) {
  168. next("", "", " getting...");
  169. const base = "https://www.googleapis.com/language/translate/v2?key=%s&q=%s&target=%s";
  170. const apikey = "AIzaSyBq48p8NhFgaJ1DfUJ5ltbwLxeXpjEL86A";
  171. let ep = util.format(base, apikey, encodeURIComponent(word), target);
  172. util.httpGet(ep, false, function (res) {
  173. if (res.status === 200) {
  174. let json = decodeJSON(res.responseText);
  175. let srclang = json.data.translations[0].detectedSourceLanguage;
  176. if (target == srclang) {
  177. lookupword(word, alternativeLang);
  178. } else {
  179. let result = json.data.translations[0].translatedText;
  180. next(srclang, target, result);
  181. }
  182. } else {
  183. next("", "", "ERROR!");
  184. }
  185. });
  186. };
  187. function echo(srclang, from, tglang, to){
  188. display.echoStatusBar(srclang + " : " + from + " -> " + tglang + " : " + to);
  189. };
  190. function decodeJSON(json) {
  191. return util.safeEval("(" + json + ")");
  192. };
  193. function lookupword(word, target){
  194. translate(word, target, function (src, tg, translated) {
  195. echo(src, word, tg, translated);
  196. });
  197. };
  198. function read (aInitialInput) {
  199. let prevText = "";
  200. prompt.reader({
  201. message : "word or sentence to translate:",
  202. initialinput : aInitialInput,
  203. onChange: function (arg) {
  204. let word = arg.textbox.value;
  205. if (word !== prevText) {
  206. prevText = word;
  207. lookupword(word, targetLang);
  208. }
  209. },
  210. callback: function (s){},
  211. });
  212. };
  213. ext.add("google-itranslate",function(){read(content.document.getSelection() || "");},"google itranslate");
  214. })();
  215. //////////////////////////////////////
  216. //
  217. ext.add("restart-firefox-add-menu", function(){
  218. const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  219. var cmdelm = document.createElementNS(XUL_NS, "command");
  220. cmdelm.setAttribute("id", "my_cmd_restartFirefoxKs")
  221. cmdelm.setAttribute("oncommand", "ext.exec('restart-firefox');");
  222. var commandset = document.getElementById("mainCommandSet");
  223. // menu.insertBefore(elm, menu.getElementById("menu_FileQuitItem"));
  224. commandset.appendChild(cmdelm);
  225. var menuelm = document.createElementNS(XUL_NS, "menuitem");
  226. menuelm.setAttribute("label", "Restart Firefox");
  227. menuelm.setAttribute("id", "my_menu_restartFirefoxKs")
  228. menuelm.setAttribute("command", "my_cmd_restartFirefoxKs");
  229. var menu = document.getElementById("menu_FilePopup");
  230. // menu.insertBefore(elm, menu.getElementById("menu_FileQuitItem"));
  231. menu.appendChild(menuelm);
  232. }, "add restart firefox menu");
  233. //////////////////////////////////////
  234. //
  235. ext.add("fullscreen-page",function (ev) {
  236. getBrowser().selectedTab = getBrowser().addTab("http://home.tiscali.nl/annejan/swf/timeline.swf");
  237. BrowserFullScreen();
  238. }, "fullscreen page");
  239. //////////////////////////////////////
  240. // restart firefox
  241. // http://keysnail.g.hatena.ne.jp/Shinnya/20100723/1279878815
  242. ext.add("restart-firefox",function (ev) {
  243. const nsIAppStartup = Components.interfaces.nsIAppStartup;
  244. // Notify all windows that an application quit has been requested.
  245. var os = Components.classes["@mozilla.org/observer-service;1"]
  246. .getService(Components.interfaces.nsIObserverService);
  247. var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
  248. .createInstance(Components.interfaces.nsISupportsPRBool);
  249. os.notifyObservers(cancelQuit, "quit-application-requested", null);
  250. // Something aborted the quit process.
  251. if (cancelQuit.data)
  252. return;
  253. // Notify all windows that an application quit has been granted.
  254. os.notifyObservers(null, "quit-application-granted", null);
  255. // Enumerate all windows and call shutdown handlers
  256. var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  257. .getService(Components.interfaces.nsIWindowMediator);
  258. var windows = wm.getEnumerator(null);
  259. while (windows.hasMoreElements()) {
  260. var win = windows.getNext();
  261. if (("tryToClose" in win) && !win.tryToClose())
  262. return;
  263. }
  264. Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(nsIAppStartup)
  265. .quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit);
  266. }, "restart firefox");
  267. /////////////////////////////////////////
  268. // copy feed url
  269. ext.add("copy-url", function () {
  270. const doc = content.document;
  271. let feeds = [[e.getAttribute("title"), e.getAttribute("href")]
  272. for ([, e] in Iterator(doc.querySelectorAll(['link[type="application/rss+xml"]',
  273. 'link[type="application/atom+xml"]'])))];
  274. var uh = window.content.location.href.replace(/(.*?\/\/[^/]*)(\/.*)?/,"$1");
  275. for (i = 0; i < feeds.length; i++)
  276. if ( feeds[i][1].substr(0,1) == "/" ) feeds[i][1] = uh + feeds[i][1];
  277. feeds.unshift([window.content.document.title,window.content.location.href]);
  278. prompt.selector(
  279. {
  280. message : "Select Feed",
  281. collection : feeds,
  282. callback : function (i) {
  283. if (i >= 0)
  284. command.setClipboardText(feeds[i][1]);
  285. }
  286. }
  287. );
  288. }, "Copy url or feed url of current page");
  289. ///////////////////////////////////////
  290. // 評価しちゃうっぽい とりあえずこんな感じで
  291. ext.add("keysnail-setting-menu",function(){
  292. var settingmenulist = [["keysnail setting dialogue",function(){return function(){KeySnail.openPreference();};}],
  293. ["firefox addon manager",function(){return function(){BrowserOpenAddonsMgr();};}],
  294. ["reload .keysnail.js",function(){return function() {userscript.reload();};}],
  295. ["check for plugins update",function(){return function(){ext.exec("check-for-plugins-update");};}],
  296. ];
  297. prompt.selector(
  298. {
  299. message : "open setting dialog",
  300. collection : settingmenulist,
  301. callback : function (i) { settingmenulist[i][1]()(); },
  302. });
  303. },"open keysnail setting menu");
  304. //////////////////////////
  305. //プラグイン一括アップデート
  306. ext.add("check-for-plugins-update", function () {
  307. [p for (p in plugins.context)].forEach(function (p) { try { userscript.updatePlugin(p); } catch(e) {} });
  308. }, "Check for all plugin's update");
  309. ////////////////////////
  310. //マルチプルタブハンドラ
  311. ext.add("multiple-tab-handler-close-selected-and-current-tabs", function () {
  312. BrowserCloseTabOrWindow();
  313. // if (MultipleTabService) {
  314. // //BrowserCloseTabOrWindow();
  315. // //MultipleTabService.setSelection(gBrowser.mCurrentTab, true);
  316. MultipleTabService.closeTabs(MultipleTabService.getSelectedTabs());
  317. // } else {
  318. // BrowserCloseTabOrWindow();}
  319. }, '選択タブと現在のタブを閉じる');
  320. ext.add("if-mth-exist", function() {
  321. if (MultipleTabService != undefined) display.echoStatusBar("true");
  322. },'if mth exist');
  323. ////////////////////////
  324. // instapaper
  325. ext.add("instapaper-add-this-page-and-close",function(){
  326. var url = window.content.location.href;
  327. var title = window.content.document.title;
  328. var tab = gBrowser.selectedTab;
  329. var username = "8slashes+instapaper@gmail.com";
  330. var password = "";
  331. var passwordManager = (Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager));
  332. var logins = passwordManager.findLogins({}, "http://www.instapaper.com", "", null);
  333. for (var i = 0; i < logins.length; i++) {
  334. if (logins[i].username == username) {
  335. password = logins[i].password;
  336. break;
  337. }
  338. }
  339. var comment = "";
  340. // prompt.read("Instapaper comment:",function(cm){
  341. // if(cm){comment = cm;}
  342. // });
  343. display.echoStatusBar("Instapaper: adding " + url + "...");
  344. util.httpPost("https://www.instapaper.com/api/add",
  345. {"username" : encodeURIComponent(username),
  346. "password" : password,
  347. "url" : encodeURIComponent(url),
  348. "title" : encodeURIComponent(title),},
  349. function (xhr) {
  350. display.echoStatusBar(xhr.status);
  351. if (xhr.readyState == 4 && xhr.status == 201) {
  352. // var title = decodeURIComponent(xhr.getResponseHeader("X-Instapaper-Title")); //超文字化けする
  353. try {
  354. Components.classes['@mozilla.org/alerts-service;1'].
  355. getService(Components.interfaces.nsIAlertsService).
  356. showAlertNotification(null, "Instapaper", "Page " + title + " added successfully", false, '', null);
  357. } catch(e) {
  358. // prevents runtime error on platforms that don't implement nsIAlertsService
  359. }
  360. display.echoStatusBar("Instapaper: adding " + url + "...done.");
  361. gBrowser.removeTab(tab);
  362. } else{
  363. display.echoStatusBar("Instapaper: Something wrong has happended!");
  364. if (window.loadURI) {
  365. loadURI("javascript:function%20iprl5(){var%20d=document,z=d.createElement('scr'+'ipt'),b=d.body,l=d.location;try{if(!b)throw(0);d.title='(Saving...)%20'+d.title;z.setAttribute('src',l.protocol+'//www.instapaper.com/j/mt8YO6Cuosmf?u='+encodeURIComponent(l.href)+'&t='+(new%20Date().getTime()));b.appendChild(z);}catch(e){alert('Please%20wait%20until%20the%20page%20has%20loaded.');}}iprl5();void(0)");
  366. }
  367. }
  368. });
  369. },'instapaper add page and close tab when done without error.');
  370. ////////////////////////
  371. //検索
  372. ext.add("query-then-engine", function () {
  373. prompt.reader({message : "Search Word?:",
  374. callback : function (q) {
  375. if (q) {
  376. prompt.selector({ message : "search \"" + q + "\" with?",
  377. collection : plugins.options["search-url-list"],
  378. width : [20,80],
  379. callback : function (i) { getBrowser().selectedTab = getBrowser().addTab(plugins.options["search-url-list"][i][1].replace("%r",q).replace("%q",encodeURIComponent(q))); },
  380. });
  381. };
  382. },
  383. initialInput : content.document.getSelection() || "",
  384. });
  385. }, "enter search word and then select engine");
  386. ///////////////////////
  387. //diggler
  388. ext.add("dig-url", function () {
  389. var url = window.content.location.href;
  390. var nsurl = [];
  391. var pname = "";
  392. var ssurl = [];
  393. var durl = [];
  394. nsurl = url.split("#");
  395. var pname = nsurl[1];
  396. ssurl = nsurl[0].split("/");
  397. durl[0] = ssurl[0] + "//" + ssurl[2];
  398. ssurl.splice(0,3);
  399. for (var i = 0; i < ssurl.length; i++){
  400. var durlsaved = durl[0];
  401. durl.unshift(durlsaved + "/" + ssurl[i]);
  402. };
  403. if (pname) {
  404. var durlfull = durl[0] + "#"+ pname;
  405. durl.unshift(durlfull);
  406. };
  407. prompt.selector({ message : "dig " + url,
  408. collection : durl,
  409. callback : function (i) { window.content.location.href = durl[i]; },
  410. });
  411. },"keysnail diggler ");
  412. /////////////////////////////////////
  413. // 閉じたタブリスト
  414. ext.add("list-closed-tabs", function () {
  415. const fav = "chrome://mozapps/skin/places/defaultFavicon.png";
  416. var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
  417. var json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
  418. var closedTabs = [[tab.image || fav, tab.title, tab.url] for each (tab in json.decode(ss.getClosedTabData(window)))];
  419. if (!closedTabs.length)
  420. return void display.echoStatusBar("最近閉じたタブが見つかりませんでした", 2000);
  421. prompt.selector(
  422. {
  423. message : "select tab to undo:",
  424. collection : closedTabs,
  425. flags : [ICON | IGNORE, 0, 0],
  426. callback : function (i) { if (i >= 0) window.undoCloseTab(i); }
  427. });
  428. }, "List closed tabs");
  429. ext.add("echo-closed-tabs", function () {
  430. var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
  431. var json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
  432. // var closedTabs = [[tab.image || fav, tab.title, tab.url] for each (tab in json.decode(ss.getClosedTabData(window)))];
  433. var lasttab = json.decode(ss.getClosedTabData(window))[0];
  434. dump = ""
  435. for (var i in lasttab) { dump += lasttab[i] + "\n"; }
  436. confirm(dump);
  437. }, "List closed tabs");
  438. ///////////////////////////////////////
  439. //
  440. ext.add("focus-on-content", function(){
  441. document.getElementById("searchbar").focus();
  442. document.commandDispatcher.advanceFocus();
  443. document.commandDispatcher.advanceFocus();
  444. }, "forcus on content");
  445. ext.add("_focus-on-content", function(){
  446. gBrowser.focus();
  447. _content.focus();
  448. }, "focus on content");
  449. ext.add("hide-sidebar", function(){
  450. var sidebarBox = document.getElementById("sidebar-box");
  451. if (!sidebarBox.hidden) {
  452. toggleSidebar(sidebarBox.getAttribute("sidebarcommand"));
  453. }
  454. }, "hide-sidebar");
  455. //}}%PRESERVE%
  456. // ========================================================================= //
  457. // ========================= Special key settings ========================== //
  458. key.quitKey = "ESC";
  459. key.helpKey = "C-h";
  460. key.escapeKey = "C-q";
  461. key.macroStartKey = "";
  462. key.macroEndKey = "";
  463. key.universalArgumentKey = "C-u";
  464. key.negativeArgument1Key = "C--";
  465. key.negativeArgument2Key = "C-M--";
  466. key.negativeArgument3Key = "M--";
  467. key.suspendKey = "Not defined";
  468. // ================================= Hooks ================================= //
  469. hook.setHook('KeySnailInitialized', function () {
  470. ext.exec("shiitake-toggle-style");
  471. });
  472. hook.setHook('KeyBoardQuit', function (aEvent) {
  473. command.closeFindBar();
  474. if (util.isCaretEnabled()) {
  475. command.resetMark(aEvent);
  476. } else {
  477. goDoCommand("cmd_selectNone");
  478. }
  479. key.generateKey(aEvent.originalTarget, KeyEvent.DOM_VK_ESCAPE, true);
  480. });
  481. hook.addToHook('KeyBoardQuit', function (aEvent) {
  482. ext.exec("hide-sidebar");
  483. });
  484. hook.setHook('Unload', function () {
  485. util.getBrowserWindows().some(function (win) {
  486. if (win === window) {
  487. return false;
  488. }
  489. const ks = win.KeySnail;
  490. share.pluginUpdater = ks.getPluginUpdater(share.pluginUpdater.pluginsWithUpdate);
  491. ks.setUpPluginUpdaterDelegator();
  492. return true;
  493. });
  494. });
  495. // ============================= Key bindings ============================== //
  496. key.setGlobalKey([['<delete>'], ['\\']], function (ev, arg) {
  497. ev.target.dispatchEvent(key.stringToKeyEvent("ESC", true));
  498. }, 'escape');
  499. key.setGlobalKey('C-<right>', function () {
  500. gBrowser.mTabContainer.advanceSelectedTab(1, true);
  501. }, 'ひとつ右のタブへ');
  502. key.setGlobalKey('C-<left>', function () {
  503. gBrowser.mTabContainer.advanceSelectedTab(-1, true);
  504. }, 'ひとつ左のタブへ');
  505. key.setGlobalKey('C-<up>', function () {
  506. var browser = getBrowser();
  507. if (browser.mCurrentTab.previousSibling) {
  508. browser.moveTabTo(browser.mCurrentTab, browser.mCurrentTab._tPos - 1);
  509. } else {
  510. browser.moveTabTo(browser.mCurrentTab, browser.mTabContainer.childNodes.length - 1);
  511. }
  512. }, '選択中のタブを右へ');
  513. key.setGlobalKey('C-<down>', function () {
  514. var browser = getBrowser();
  515. if (browser.mCurrentTab.nextSibling) {
  516. browser.moveTabTo(browser.mCurrentTab, browser.mCurrentTab._tPos + 1);
  517. } else {
  518. browser.moveTabTo(browser.mCurrentTab, 0);
  519. }
  520. }, '選択中のタブを左へ');
  521. key.setGlobalKey('M-:', function (ev) {
  522. command.interpreter();
  523. }, 'JavaScript のコードを評価');
  524. key.setGlobalKey('C-g', function (ev, arg) {
  525. return;
  526. }, 'ignore');
  527. key.setViewKey('0', function (ev, arg) {
  528. var n = gBrowser.mCurrentTab._tPos;
  529. BrowserCloseTabOrWindow();
  530. gBrowser.selectedTab = gBrowser.mTabs[n];
  531. }, '閉じて次のタブ');
  532. key.setViewKey('x', function (aEvent, aArg) {
  533. ext.select(aArg, aEvent);
  534. }, 'エクステ一覧');
  535. key.setViewKey(['t', 'm'], function (ev, arg) {
  536. if (window.loadURI) {
  537. loadURI("javascript:window.location='http://api.tweetmeme.com/visit?url='+window.location;");
  538. }
  539. }, 'open with tweetmeme');
  540. key.setViewKey(['t', 'w'], function (ev, arg) {
  541. ext.exec("twitter-client-tweet", arg, ev);
  542. }, 'つぶやく', true);
  543. key.setViewKey(['t', 'p'], function (ev, arg) {
  544. ext.exec("twitter-client-tweet-this-page", arg, ev);
  545. }, 'このページのタイトルと URL を使ってつぶやく', true);
  546. key.setViewKey('u', function () {
  547. undoCloseTab();
  548. }, '閉じたタブを元に戻す');
  549. key.setViewKey('g', function () {
  550. goDoCommand("cmd_scrollTop");
  551. }, 'ページ先頭へ移動');
  552. key.setViewKey('G', function () {
  553. goDoCommand("cmd_scrollBottom");
  554. }, 'ページ末尾へ移動');
  555. key.setViewKey('r', function (aEvent) {
  556. BrowserReload();
  557. }, '再読み込み');
  558. key.setViewKey('m', function (ev, arg) {
  559. _fi.toogle();
  560. }, 'fetchimiをトグル');
  561. key.setViewKey('d', function (ev, arg) {
  562. if (window.loadURI) {
  563. loadURI("javascript:(function(){f='http://www.delicious.com/save?url='+encodeURIComponent(window.location.href)+'&title='+encodeURIComponent(document.title)+'&notes='+encodeURIComponent(''+(window.getSelection?window.getSelection():document.getSelection?document.getSelection():document.selection.createRange().text))+'&v=6&';a=function(){if(!window.open(f+'noui=1&jump=doclose','deliciousuiv6','location=1,links=0,scrollbars=0,toolbar=0,width=550,height=585'))location.href=f+'jump=yes'};if(/Firefox/.test(navigator.userAgent)){setTimeout(a,0)}else{a()}})()");
  564. }
  565. }, 'deliciousでブックマーク');
  566. key.setViewKey('p', function (ev, arg) {
  567. if (window.loadURI) {
  568. loadURI("javascript:var%20b=document.body;var%20POSTEROUS___bookmarklet_domain='http://posterous.com';if(b&&!document.xmlVersion){void(z=document.createElement('script'));void(z.type='text/javascript');void(z.src='http://posterous.com/javascripts/bookmarklet2.js');void(b.appendChild(z));}else{}");
  569. }
  570. }, 'posterousに投稿');
  571. key.setViewKey('SPC', function (ev, arg) {
  572. MultipleTabService.toggleSelection(gBrowser.mCurrentTab);
  573. gBrowser.mTabContainer.advanceSelectedTab(1, true);
  574. }, 'タブの選択をトグルして次のタブ');
  575. key.setViewKey('S-SPC', function (ev, arg) {
  576. MultipleTabService.toggleSelection(gBrowser.selectedTab);
  577. gBrowser.mTabContainer.advanceSelectedTab(-1, true);
  578. }, 'タブの選択をトグルして前のタブ');
  579. key.setViewKey('z', function (ev, arg) {
  580. ext.exec("keysnail-setting-menu", arg, ev);
  581. }, 'open keysnail setting menu', true);
  582. key.setViewKey('T', function (ev, arg) {
  583. ext.exec("google-itranslate", arg, ev);
  584. }, 'google itranslate', true);
  585. key.setViewKey('l', function (ev, arg) {
  586. var n = gBrowser.mCurrentTab._tPos;
  587. gBrowser.moveTabTo(gBrowser.mCurrentTab, gBrowser.mTabContainer.childNodes.length - 1);
  588. gBrowser.selectedTab = gBrowser.mTabs[n];
  589. }, 'このタブを後回し');
  590. key.setViewKey('C-SPC', function (ev, arg) {
  591. MultipleTabService.toggleSelection(gBrowser.selectedTab);
  592. }, 'タブの選択をトグル');
  593. key.setViewKey('s', function (ev, arg) {
  594. var n = gBrowser.mCurrentTab._tPos;
  595. gBrowser.moveTabTo(gBrowser.mCurrentTab, 0);
  596. if (n != 0) {
  597. gBrowser.selectedTab = gBrowser.mTabs[n];
  598. }
  599. }, 'このタブを保持する');
  600. key.setViewKey('U', function (ev, arg) {
  601. ext.exec("list-closed-tabs", arg, ev);
  602. }, 'List closed tabs', true);
  603. key.setViewKey('e', function () {
  604. command.focusElement(command.elementsRetrieverTextarea, 0);
  605. }, '最初のインプットエリアへフォーカス', true);
  606. key.setViewKey('S', function (ev, arg) {
  607. if (window.loadURI) {
  608. loadURI("javascript:var%20b=document.body;var%20GR________bookmarklet_domain='https://www.google.com';if(b&&!document.xmlVersion){void(z=document.createElement('script'));void(z.src='https://www.google.com/reader/ui/link-bookmarklet.js');void(b.appendChild(z));}else{}");
  609. }
  610. }, 'google reader share');
  611. key.setViewKey('!', function (ev, arg) {
  612. shell.input();
  613. }, 'Command system');
  614. key.setViewKey('b', function (ev, arg) {
  615. BarTap.putOnTap(gBrowser.mCurrentTab, gBrowser);
  616. }, 'bartab put on tab');
  617. key.setViewKey('R', function () {
  618. BrowserReloadSkipCache();
  619. }, '更新(キャッシュを無視)');
  620. key.setViewKey('<backspace>', function () {
  621. BrowserBack();
  622. }, '戻る');
  623. key.setViewKey('S-<backspace>', function () {
  624. BrowserForward();
  625. }, '進む');
  626. key.setViewKey('q', function (ev, arg) {
  627. ext.exec("query-then-engine", arg, ev);
  628. }, 'enter search word and then select engine', true);
  629. key.setViewKey('D', function (ev, arg) {
  630. ext.exec("dig-url", arg, ev);
  631. }, 'keysnail diggler ', true);
  632. key.setViewKey('/', function () {
  633. command.iSearchForward();
  634. }, 'インクリメンタル検索', true);
  635. key.setViewKey('?', function (ev) {
  636. command.iSearchForwardKs(ev);
  637. }, 'Emacs ライクなインクリメンタル検索', true);
  638. key.setViewKey('a', function (ev, arg) {
  639. allTabs.open();
  640. }, 'alltabs.open');
  641. key.setViewKey('C', function (ev, arg) {
  642. ext.exec("copy-url", arg, ev);
  643. }, '選択タブと現在のタブを閉じる', true);
  644. key.setViewKey('I', function (ev, arg) {
  645. ext.exec("instapaper-add-this-page-and-close", arg, ev);
  646. }, 'instapaper add page', true);
  647. key.setViewKey('<left>', function (ev) {
  648. goDoCommand("cmd_scrollPageUp");
  649. }, '一画面分スクロールアップ');
  650. key.setViewKey('<right>', function (ev) {
  651. goDoCommand("cmd_scrollPageDown");
  652. }, '一画面スクロールダウン');
  653. key.setViewKey('C-w', function (ev) {
  654. command.copyRegion(ev);
  655. }, '選択中のテキストをコピー');
  656. key.setViewKey([['<prior>'], ['<next>']], function (ev, arg) {
  657. return;
  658. }, 'ignore');
  659. key.setEditKey(['C-x', 'h'], function (ev) {
  660. command.selectAll(ev);
  661. }, '全て選択', true);
  662. key.setEditKey([['C-x', 'u'], ['C-_']], function (ev) {
  663. display.echoStatusBar("Undo!", 2000);
  664. goDoCommand("cmd_undo");
  665. }, 'アンドゥ');
  666. key.setEditKey(['C-x', 'r', 'd'], function (ev, arg) {
  667. command.replaceRectangle(ev.originalTarget, "", false, !arg);
  668. }, '矩形削除', true);
  669. key.setEditKey(['C-x', 'r', 't'], function (ev) {
  670. prompt.read("String rectangle: ", function (aStr, aInput) {command.replaceRectangle(aInput, aStr);}, ev.originalTarget);
  671. }, '矩形置換', true);
  672. key.setEditKey(['C-x', 'r', 'o'], function (ev) {
  673. command.openRectangle(ev.originalTarget);
  674. }, '矩形行空け', true);
  675. key.setEditKey(['C-x', 'r', 'k'], function (ev, arg) {
  676. command.kill.buffer = command.killRectangle(ev.originalTarget, !arg);
  677. }, '矩形キル', true);
  678. key.setEditKey(['C-x', 'r', 'y'], function (ev) {
  679. command.yankRectangle(ev.originalTarget, command.kill.buffer);
  680. }, '矩形ヤンク', true);
  681. key.setEditKey([['C-SPC'], ['C-@']], function (ev) {
  682. command.setMark(ev);
  683. }, 'マークをセット', true);
  684. key.setEditKey('C-o', function (ev) {
  685. command.openLine(ev);
  686. }, '行を開く (Open line)');
  687. key.setEditKey('C-\\', function (ev) {
  688. display.echoStatusBar("Redo!", 2000);
  689. goDoCommand("cmd_redo");
  690. }, 'リドゥ');
  691. key.setEditKey('C-a', function (ev) {
  692. command.beginLine(ev);
  693. }, '行頭へ移動');
  694. key.setEditKey('C-e', function (ev) {
  695. command.endLine(ev);
  696. }, '行末へ');
  697. key.setEditKey('M-h', function (ev) {
  698. command.previousChar(ev);
  699. }, '一文字左へ移動');
  700. key.setEditKey('M-f', function (ev) {
  701. command.forwardWord(ev);
  702. }, '一単語右へ移動');
  703. key.setEditKey('M-b', function (ev) {
  704. command.backwardWord(ev);
  705. }, '一単語左へ移動');
  706. key.setEditKey('M-j', function (ev) {
  707. command.nextLine(ev);
  708. }, '一行下へ');
  709. key.setEditKey('M-k', function (ev) {
  710. command.previousLine(ev);
  711. }, '一行上へ');
  712. key.setEditKey('C-v', function (ev) {
  713. command.pageDown(ev);
  714. }, '一画面分下へ');
  715. key.setEditKey('M-v', function (ev) {
  716. command.pageUp(ev);
  717. }, '一画面分上へ');
  718. key.setEditKey('M-<', function (ev) {
  719. command.moveTop(ev);
  720. }, 'テキストエリア先頭へ');
  721. key.setEditKey('M->', function (ev) {
  722. command.moveBottom(ev);
  723. }, 'テキストエリア末尾へ');
  724. key.setEditKey('C-d', function (ev) {
  725. goDoCommand("cmd_deleteCharForward");
  726. }, '次の一文字削除');
  727. key.setEditKey('C-h', function (ev) {
  728. goDoCommand("cmd_deleteCharBackward");
  729. }, '前の一文字を削除');
  730. key.setEditKey('M-d', function (ev) {
  731. command.deleteForwardWord(ev);
  732. }, '次の一単語を削除');
  733. key.setEditKey([['C-<backspace>'], ['M-<delete>']], function (ev) {
  734. command.deleteBackwardWord(ev);
  735. }, '前の一単語を削除');
  736. key.setEditKey('M-u', function (ev, arg) {
  737. command.wordCommand(ev, arg, command.upcaseForwardWord, command.upcaseBackwardWord);
  738. }, '次の一単語を全て大文字に (Upper case)');
  739. key.setEditKey('M-c', function (ev, arg) {
  740. command.wordCommand(ev, arg, command.capitalizeForwardWord, command.capitalizeBackwardWord);
  741. }, '次の一単語をキャピタライズ');
  742. key.setEditKey('C-k', function (ev) {
  743. command.killLine(ev);
  744. }, 'カーソルから先を一行カット (Kill line)');
  745. key.setEditKey('C-y', command.yank, '貼り付け (Yank)');
  746. key.setEditKey('M-y', command.yankPop, '古いクリップボードの中身を順に貼り付け (Yank pop)', true);
  747. key.setEditKey('C-M-y', function (ev) {
  748. if (!command.kill.ring.length) {
  749. return;
  750. }
  751. let (ct = command.getClipboardText()) (!command.kill.ring.length || ct != command.kill.ring[0]) &&
  752. command.pushKillRing(ct);
  753. prompt.selector({message: "Paste:", collection: command.kill.ring, callback: function (i) {if (i >= 0) {key.insertText(command.kill.ring[i]);}}});
  754. }, '以前にコピーしたテキスト一覧から選択して貼り付け', true);
  755. key.setEditKey('C-w', function (ev) {
  756. goDoCommand("cmd_copy");
  757. goDoCommand("cmd_delete");
  758. command.resetMark(ev);
  759. }, '選択中のテキストを切り取り (Kill region)', true);
  760. key.setEditKey('M-n', function (ev) {
  761. command.walkInputElement(command.elementsRetrieverTextarea, true, true);
  762. }, '次のテキストエリアへフォーカス');
  763. key.setEditKey('M-p', function (ev) {
  764. command.walkInputElement(command.elementsRetrieverTextarea, false, true);
  765. }, '前のテキストエリアへフォーカス');
  766. key.setEditKey('M-w', function (ev) {
  767. command.copyRegion(ev);
  768. }, '選択中のテキストをコピー');
  769. key.setEditKey('M-l', function (ev) {
  770. command.nextChar(ev);
  771. }, '一文字右へ移動');