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 45 KiB

13 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
13 vuotta sitten
11 vuotta sitten
13 vuotta sitten
11 vuotta sitten
11 vuotta sitten
13 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
11 vuotta sitten
13 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
11 vuotta sitten
13 vuotta sitten
9 vuotta sitten
9 vuotta sitten
9 vuotta sitten
13 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
11 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
13 vuotta sitten
12 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
13 vuotta sitten
12 vuotta sitten
12 vuotta sitten
13 vuotta sitten
12 vuotta sitten
8 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
8 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
11 vuotta sitten
11 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
13 vuotta sitten
13 vuotta sitten
13 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
12 vuotta sitten
11 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422
  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. // Original is at https://gist.github.com/Griever/62715
  13. ext.add("open-bookmarks-in-new-tab", function(){
  14. // this makes all clicks open in new tab.
  15. // return;
  16. // test if firefox 12
  17. if (12 > parseFloat(Cc['@mozilla.org/xre/app-info;1'].
  18. getService(Ci.nsIXULAppInfo).version)) {
  19. return;
  20. }
  21. // I cannot fully understand what happen but keysnail emit error
  22. // *after* initialization of firefox finished successfully and I assured
  23. // that new tabs open as I expect when clicking bookmarks, for example,
  24. // when I try to tweet using the twitter keysnail plugin, with error
  25. // message saying "whereToOpenLink is undefined.".
  26. // if no modifier key pressed open in new tab.
  27. try {
  28. var whereToOpenLink_org = new String(window.whereToOpenLink.toString());
  29. window.whereToOpenLink = eval(
  30. "(" +
  31. whereToOpenLink_org.replace(
  32. '{',
  33. '{ if(!e || ' +
  34. '(!e.ctrlKey && !e.shiftKey && !e.metaKey && ' +
  35. '!(e.altKKey && !ignoreAlt))) ' +
  36. 'return "tab";'
  37. ) +
  38. ")"
  39. );
  40. } catch (e if e instanceof TypeError) {
  41. return;
  42. }
  43. // This is useless because this makes reload open new tab.
  44. // window.whereToOpenLink = function(e, ib, ia){ return "tab"; };
  45. }, "open in new tab");
  46. // ext.exec("open-bookmarks-in-new-tab");
  47. //////////////////////////////////////
  48. //// sitelocalkeymap
  49. var local = {};
  50. plugins.options["site_local_keymap.local_keymap"] = local;
  51. function fake(k, i) function(){ key.feed(k, i); };
  52. function pass(k, i) [k, fake(k, i)];
  53. function ignore(k, i) [k, null];
  54. // ext.add("ext-name", function () {}, "ext description");
  55. // style.register("");
  56. // local["^http://"] = [['a', function(ev, arg){}],];
  57. ///////////////////////////////////////////
  58. //// firefox
  59. // style.register("#bookmarksPanel > hbox,#history-panel > hbox {" +
  60. // "display: none !important;}" +
  61. // " //#urlbar-container{max-width: 500px !important;}");
  62. // style.register( //not work
  63. // <><![CDATA[
  64. // input,textarea {
  65. // font-family: monospace !important;
  66. // }
  67. // ]]></>.toString()
  68. // );
  69. style.register(
  70. '@-moz-document ' +
  71. 'url-prefix(\"http://www.tumblr.com/\"), ' +
  72. 'url-prefix(\"https://www.tumblr.com/\") ' +
  73. '{ #pagination {' +
  74. 'position: fixed;' +
  75. 'bottom: 50px;' +
  76. 'right: 100px;' +
  77. 'padding-right: 0px !important' +
  78. '} }' , style.XHTML);
  79. ///////////////////////////////////
  80. //search engine
  81. plugins.options["search-url-list"] = [
  82. ["DuckDuckGo", "https://duckduckgo.com/?q=%q"],
  83. ["Bing", "http://bing.com/search?q=%q"],
  84. ["Google", "http://google.com/search?q=%q"],
  85. ["Yahoo Realtime",
  86. "http://realtime.search.yahoo.co.jp/search?rkf=1&ei=UTF-8&p=%q"],
  87. ["Twitter Search", "http://twitter.com/search?q=%q&lang=all"],
  88. ["Tospy", "http://topsy.com/s?allow_lang=ja&q=%q"],
  89. ["2ch syoboi.jp", "http://ff2ch.syoboi.jp/?q=%q"],
  90. ["2ch-ranking","http://2ch-ranking.net/search.php?q=%q&imp=and&order=time"],
  91. //["2ch ttsearch", "http://ttsearch.net/s2.cgi?k=%q&o=r"],
  92. ["I\'m feelig lucky!", "http://www.google.co.jp/search?q=%q&btnI=kudos"],
  93. ["Uncyclopedia", "http://ja.uncyclopedia.info/wiki/%q"],
  94. ["Wikipedia", "http://ja.wikipedia.org/wiki/%q"],
  95. ["nicovideo.jp", "http://www.nicovideo.jp/search/%q"],
  96. ["alc", "http://eow.alc.co.jp/%q/UTF-8/"],
  97. ["google map",
  98. "http://maps.google.co.jp/maps?hl=ja&q=%q&um=1&ie=UTF-8&sa=N&tab=wl"],
  99. ["Weblio", "http://www.weblio.jp/content_find?query=%q"],
  100. ["ShoutCast", "http://www.shoutcast.com/Internet-Radio/%q"],
  101. ["Delicious 10sr", "http://delicious.com/10sr/%q"],
  102. ["Open raw", "%r"]
  103. ];
  104. plugins.options["my-keysnail-bookmarks"] = [
  105. "twitter.com"
  106. ];
  107. // sitelocal keymap
  108. //////////////////////////////////////////
  109. // 2ch chaika
  110. // change chaika port every time firefox starts
  111. util.setIntPref("extensions.chaika.server_port.firefox",
  112. 8800 + Math.floor(Math.random() * 30));
  113. local["^http://127.0.0.1:88"] = [
  114. ['k', function(ev, arg){
  115. curl = window.content.location.href;
  116. kurl = curl.replace(/http:.*thread\/(.*\/).*/, "chaika://post/$1");
  117. window.content.location.href = kurl;
  118. }
  119. ]
  120. ];
  121. local["^http://w2.p2.2ch.net/p2/read.php"] = [
  122. ['k', function(ev, arg){
  123. var url = window.content.location.href;
  124. var pt = /host=(.*?)&bbs=(.*?)&key=(.*?)&ls=/ ;
  125. var result = url.match(pt);
  126. var k = format("chaika://post/http://%s/test/read.cgi/%s/%s/",
  127. result[1], result[2], result[3]);
  128. window.content.location.href = k;
  129. }
  130. ]
  131. ];
  132. /////////////////////////////////////////
  133. // feedly
  134. local["^https?://(www\.|cloud\.|)feedly\.com/"] = [
  135. ['d', null],
  136. ['j', null],
  137. ['k', null],
  138. ['n', null],
  139. ['p', null],
  140. ['o', null],
  141. ['b', null],
  142. ['S', null],
  143. ['s', null],
  144. ['?', null],
  145. ['r', null],
  146. ['g', null],
  147. // ['x', function(ev, arg){
  148. // ev.target.dispatchEvent(key.stringToKeyEvent("g", true));
  149. // }],
  150. // ['l', function(ev, arg){
  151. // var host = window.content.location.host;
  152. // if (host === "cloud.feedly.com" || host === "feedly.com") {
  153. // window.content.location.href = "http://" + host + "/#latest";
  154. // } else if (host === "www.feedly.com") {
  155. // window.content.location.href = "http://" + host + "/home#latest";
  156. // }
  157. // }],
  158. ['a', null],
  159. [['t', 'p'], function(ev, arg){
  160. ev.target.dispatchEvent(key.stringToKeyEvent("t", true));
  161. }],
  162. [['t', 'w'], function(ev, arg){
  163. ext.exec("twitter-client-tweet", arg, ev);
  164. }]
  165. ];
  166. /////////////////////////////////////////
  167. //nicovideo
  168. // http://dic.nicovideo.jp/id/4858151
  169. local["^http://(www|tw|es|de|)\.nicovideo\.jp\/(watch|playlist)"] = [
  170. // ["i", function(ev, arg){ ext.exec("nicoinfo", arg); }],
  171. ["SPC", function(ev, arg){ ext.exec("nicopause", arg); }],
  172. ["f", function(ev, arg){ ext.exec("nicosize", arg); }],
  173. ["F", function(ev, arg){ ext.exec("nicosize", arg); }],
  174. // ["o", function(ev, arg){ ext.exec("nicommentvisible", arg); }],
  175. // ["m", function(ev, arg){ ext.exec("nicomute", arg); }],
  176. // [".", function(ev, arg){ ext.exec("nicovolumeIncrement", arg); }],
  177. // [",", function(ev, arg){ ext.exec("nicovolumeDecrement", arg); }],
  178. // ['f', function(ev, arg){
  179. // curl = window.content.location.href;
  180. // kurl = curl.replace(/nicovideo.jp/, "nicovideofire.jp");
  181. // window.content.location.href = kurl;
  182. // }]
  183. ];
  184. /////////////////////////////////////////
  185. // tumblr/dashboard
  186. local["^http://www.tumblr.com/dashboard"] = [
  187. // ["C-<left>", function(ev, arg){
  188. // gBrowser.mTabContainer.advanceSelectedTab(-1, true);
  189. // }],
  190. // ["C-<right>", function(ev, arg){
  191. // gBrowser.mTabContainer.advanceSelectedTab(1, true);
  192. // }],
  193. ["<left>", function(ev, arg){
  194. window.content.location.href = "http://www.tumblr.com/dashboard";
  195. }],
  196. ["<right>", null],
  197. ["J", function(ev, arg){
  198. if (window.loadURI) {
  199. 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;}())");
  200. }
  201. }]
  202. ];
  203. ///////////////////////////////////////////
  204. // plugin option
  205. plugins.options["builtin_commands_ext.ext_list"] = [
  206. "focus-to-prompt",
  207. "open-url-from-clipboard",
  208. "restart-firefox"
  209. ];
  210. plugins.options["instapaper.close_after_post"] = true;
  211. plugins.options["instapaper.initial_comment_function"] = function(){
  212. var now = new Date();
  213. return "[" + now.toString() + "]";
  214. };
  215. //////////////////////////////////////////
  216. // yatc
  217. style.register("#keysnail-twitter-client-container{ display:none !important; }");
  218. plugins.options["twitter_client.popup_new_statuses"] = false;
  219. plugins.options["twitter_client.automatically_begin"] = false;
  220. plugins.options["twitter_client.automatically_begin_list"] = false;
  221. plugins.options["twitter_client.timeline_count_beginning"] = 0;
  222. plugins.options["twitter_client.timeline_count_every_updates"] = 0;
  223. plugins.options["twitter_client.tweet_keymap"] = {
  224. "C-RET" : "prompt-decide",
  225. "RET" : ""
  226. };
  227. plugins.options["twitter_client.jmp_id"] = "10sr";
  228. plugins.options["twitter_client.jmp_key"] =
  229. "R_c51f889a77cb4b4e993ed868f65083f5";
  230. plugins.options["twitter_client.use_jmp"] = true;
  231. ////////////////////////////////////////////
  232. // my exts and functions
  233. var autoSaveTabList = (function(){
  234. const PREF_PREFIX = "extensions.keysnail.plugins.autosavetablist.";
  235. const PREF_DSTDIR = "dstdir";
  236. const PREF_ENABLED = "enabled";
  237. // use plugin option to set
  238. // in sec
  239. var default_timer_interval = 60 * 5;
  240. // "/" for unix system
  241. const DIR_DELIM = userscript.directoryDelimitter;
  242. var __timer = null;
  243. var __last_tab_list = null;
  244. function selectDirectory(title){
  245. // open dialog and return nsILocalFile object
  246. // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile
  247. // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker
  248. // this function blocks.
  249. var nsIFilePicker = Components.interfaces.nsIFilePicker;
  250. var fp = Components.classes["@mozilla.org/filepicker;1"].
  251. createInstance(nsIFilePicker);
  252. fp.init(window, title, nsIFilePicker.modeGetFolder);
  253. // block
  254. var res = fp.show();
  255. if (res !== nsIFilePicker.returnOK) {
  256. return null;
  257. }
  258. return fp.file;
  259. }
  260. function selectFile(title){
  261. // open dialog and return nsILocalFile object
  262. // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile
  263. // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker
  264. // this function blocks.
  265. var nsIFilePicker = Components.interfaces.nsIFilePicker;
  266. var fp = Components.classes["@mozilla.org/filepicker;1"].
  267. createInstance(nsIFilePicker);
  268. fp.init(window, title, nsIFilePicker.modeOpen);
  269. // block
  270. var res = fp.show();
  271. if (res !== nsIFilePicker.returnOK) {
  272. return null;
  273. }
  274. return fp.file;
  275. }
  276. function setup(){
  277. // set destination directory
  278. var dstdir = selectDirectory("Select Directory to Save Tab List");
  279. if (! dstdir) { return; }
  280. if (! dstdir.isWritable()) {
  281. display.notify("Directory is not writable");
  282. return;
  283. }
  284. util.setUnicharPref(PREF_PREFIX + PREF_DSTDIR, dstdir.path);
  285. }
  286. function genFileName(){
  287. function formatCurrent(){
  288. var d = new Date();
  289. function pad(n){
  290. return n < 10 ? '0' + n.toString() : n.toString()
  291. }
  292. return [
  293. d.getFullYear().toString(),
  294. pad(d.getMonth() + 1),
  295. pad(d.getDate()),
  296. "-",
  297. pad(d.getHours()),
  298. pad(d.getMinutes()),
  299. pad(d.getSeconds())
  300. ].join("");
  301. }
  302. return "tablist." + formatCurrent() + ".lst";
  303. }
  304. function getTabList(){
  305. // returns list of urls of current tabs.
  306. return [(function(){
  307. var browser = tab.linkedBrowser;
  308. var win = browser.contentWindow;
  309. // var title = tab.label;
  310. var url = win.location.href;
  311. return url;
  312. })() for each (tab in Array.slice(gBrowser.mTabContainer.childNodes))];
  313. // Array.slice is required?
  314. }
  315. function saveCurrentList(){
  316. var dstdir = util.getUnicharPref(PREF_PREFIX + PREF_DSTDIR);
  317. if (! dstdir) {
  318. display.showPopup("AutoSaveTabList",
  319. "Dest dir is not set yet. Run astl-setup first");
  320. return;
  321. }
  322. var filename = genFileName();
  323. var tab_list = getTabList().join("\n") + "\n"
  324. if (tab_list !== __last_tab_list) {
  325. util.writeTextFile(
  326. tab_list,
  327. dstdir + userscript.directoryDelimiter + filename
  328. );
  329. display.showPopup("AutoSaveTabList",
  330. "Tab List saved: " + filename);
  331. __last_tab_list = tab_list;
  332. }
  333. }
  334. function openFromFile(){
  335. var file = selectFile();
  336. if (file) {
  337. openFromLFSplittedString(util.readTextFile(file.path));
  338. }
  339. }
  340. function openFromClipboard(){
  341. openFromLFSplittedString(command.getClipboardText());
  342. }
  343. function openFromLFSplittedString(str){
  344. var urls = str.split("\n");
  345. for (var i = 0; i < urls.length; i++) {
  346. if (urls[i].match(/^http/)) {
  347. window.openUILinkIn(urls[i], "tab");
  348. }
  349. }
  350. }
  351. function enableTimer(ev, sec){
  352. disableTimer();
  353. sec = sec || default_timer_interval;
  354. __timer = window.setInterval(saveCurrentList, sec * 1000);
  355. display.showPopup("AutoSaveTabList",
  356. "Auto save enabled for every " + sec.toString() + " sec");
  357. }
  358. function disableTimer(){
  359. if (__timer) {
  360. window.clearInterval(__timer);
  361. __timer = null;
  362. display.showPopup("AutoSaveTabList",
  363. "Auto save disabled");
  364. } else {
  365. display.showPopup("AutoSaveTabList",
  366. "Auto save timer is not set yet !");
  367. }
  368. }
  369. function isEnabled(){
  370. return util.getBoolPref(PREF_PREFIX + PREF_ENABLED, false);
  371. }
  372. function enable(){
  373. util.setBoolPref(PREF_PREFIX + PREF_ENABLED, true);
  374. enableTimer();
  375. }
  376. function disable(){
  377. util.setBoolPref(PREF_PREFIX + PREF_ENABLED, false);
  378. disableTimer();
  379. }
  380. function init(){
  381. // Intended to be called on startup
  382. if (isEnabled()) {
  383. enableTimer();
  384. } else {
  385. disableTimer();
  386. }
  387. }
  388. return {
  389. selectDirectory: selectDirectory,
  390. setup: setup,
  391. getTabList: getTabList,
  392. saveCurrentList: saveCurrentList,
  393. openFromClipboard: openFromClipboard,
  394. openFromFile: openFromFile,
  395. enableTimer: enableTimer,
  396. disableTimer: disableTimer,
  397. isEnabled: isEnabled,
  398. enable: enable,
  399. disable: disable,
  400. init: init
  401. };
  402. })();
  403. ext.add("astl-setup", autoSaveTabList.setup, "Auto save tab list - Setup");
  404. ext.add("astl-open-from-clipboard", autoSaveTabList.openFromClipboard, "Auto save tab list - Open tabs from clipboard");
  405. ext.add("astl-open-from-file", autoSaveTabList.openFromFile, "Auto save tab list - Open tabs from local file");
  406. ext.add("astl-save-current", autoSaveTabList.saveCurrentList,
  407. "Auto save tab list - Save current list");
  408. //ext.add("astl-enable-timer", autoSaveTabList.enableTimer, "Auto save tab list - Enable periodic timer");
  409. //ext.add("astl-disable-timer", autoSaveTabList.disableTimer, "Auto save tab list - Disable periodic timer");
  410. ext.add("astl-enable", autoSaveTabList.enable, "Auto save tab list - Enable");
  411. ext.add("astl-disable", autoSaveTabList.disable, "Auto save tab list - Disable");
  412. ext.add("astl-init", autoSaveTabList.init, "Auto save tab list - Initalize");
  413. if (autoSaveTabList.isEnabled()) {
  414. //ext.exec("astl-init");
  415. // I cannot understand AT ALL but calling init() breaks something only my one
  416. // environment: Firefox on Windows7
  417. autoSaveTabList.init();
  418. }
  419. var echoTabInfo = (function(){
  420. var currenttab;
  421. function _display(msg){
  422. display.prettyPrint(msg, {
  423. timeout: 1500,
  424. style: {
  425. "font-size": "18px",
  426. "font-family": "monospace"
  427. }
  428. });
  429. }
  430. function __display(msg){
  431. display.echoStatusBar(msg);
  432. }
  433. function echo(){
  434. var newtab = getBrowser().mCurrentTab;
  435. if (currenttab === newtab) {
  436. return;
  437. }
  438. currenttab = newtab;
  439. var len = getBrowser().tabs.length;
  440. var idx = currenttab._tPos;
  441. var title = window.content.document.title;
  442. var url = window.content.location.href;
  443. var doc = content ? content.document : document;
  444. var dBody = doc.body;
  445. if (dBody && !util.isFrameSetWindow(content)) {
  446. // if page has been prepared
  447. _display(
  448. "[" +
  449. (idx + 1).toString() + "/" +
  450. len.toString() + "] " +
  451. title + " <" +
  452. decodeURIComponent(url) + ">"
  453. );
  454. }
  455. }
  456. return {
  457. echo: echo
  458. };
  459. })();
  460. ext.add("open-remote-init-file", function(ev, arg){
  461. const URL = "https://raw.github.com/10sr/dotfiles/master/_keysnail.js";
  462. window.openUILinkIn(URL, "tab");
  463. }, "Open remote initialization file");
  464. var updateInitFile = (function(){
  465. const URL = "https://raw.github.com/10sr/dotfiles/master/_keysnail.js";
  466. // content/modules/userscript.js
  467. // copy file from aFile
  468. function placeFile(aFile, force) {
  469. var dstdir = util.getUnicharPref("extensions.keysnail.userscript.location");
  470. if (dstdir === "") {
  471. throw util.getLocaleString("failedToInstallFile", [aFile.leafName]) + " :: " + x;
  472. }
  473. try
  474. {
  475. // calc dir from path
  476. let destinationDir = util.openFile(dstdir);
  477. let destinationFile = util.openFile(dstdir);
  478. destinationFile.append(aFile.leafName);
  479. if (destinationFile.exists())
  480. {
  481. if (util.hashFile(aFile) === util.hashFile(destinationFile))
  482. {
  483. // no need to install this file
  484. return destinationFile;
  485. }
  486. let confirmed = force ||
  487. util.confirm(
  488. util.getLocaleString("overWriteConfirmationTitle"),
  489. util.getLocaleString("overWriteConfirmation",
  490. [destinationFile.path])
  491. );
  492. if (!confirmed) {
  493. throw util.getLocaleString("canceledByUser");
  494. }
  495. }
  496. aFile.moveTo(destinationDir, "");
  497. return destinationFile;
  498. }
  499. catch (x)
  500. {
  501. throw util.getLocaleString("failedToInstallFile",
  502. [aFile.leafName]) +
  503. " :: " + x;
  504. }
  505. }
  506. function updateFile() {
  507. util.httpGet(URL, false, function (req) {
  508. if (req.status !== 200) {
  509. util.message(req.responseText);
  510. }
  511. try {
  512. let name = util.getLeafNameFromURL(URL);
  513. let file = userscript.writeTextTmp(name, req.responseText);
  514. let installed = placeFile(file);
  515. util.message(installed.path + " installed");
  516. display.showPopup("update-init-file",
  517. installed.path + " installed")
  518. } catch (x) {
  519. util.message(
  520. "An error occured while installing required scripts :: " +
  521. x.message
  522. );
  523. display.showPopup(
  524. "update-init-file",
  525. "An error occured while installing required scripts :: " +
  526. x.message
  527. );
  528. }
  529. });
  530. }
  531. return {
  532. updateFile: updateFile
  533. };
  534. })();
  535. ext.add("update-init-file", updateInitFile.updateFile, "update init file");
  536. var importExportBookmarks = (function(){
  537. function getOrganizer(){
  538. // [How to call for Firefox bookmark dialog? - Stack Overflow]
  539. // (http://stackoverflow.com/questions/9158187/how-to-call-for-firefox-bookmark-dialog)
  540. Components.utils.import("resource://gre/modules/Services.jsm");
  541. var organizer = Services.wm.getMostRecentWindow("Places:Organizer");
  542. if (!organizer) {
  543. // No currently open places window,
  544. // so open one with the specified mode.
  545. openDialog("chrome://browser/content/places/places.xul",
  546. "",
  547. "chrome,toolbar=yes,dialog=no,resizable",
  548. "AllBookmarks");
  549. return null;
  550. } else {
  551. return organizer;
  552. }
  553. }
  554. ext.add("export-bookmarks", function(ev, arg){
  555. var organizer = getOrganizer();
  556. if (organizer) {
  557. organizer.PlacesOrganizer.exportBookmarks();
  558. }
  559. }, "export bookmarks");
  560. ext.add("import-bookmarks", function(ev, arg){
  561. var organizer = getOrganizer();
  562. if (organizer) {
  563. organizer.PlacesOrganizer.importBookmarks();
  564. }
  565. }, "import bookmarks");
  566. return {
  567. getOrganizer: getOrganizer
  568. };
  569. })();
  570. ext.add("my-index-html", function(ev, arg){
  571. homepath = util.getEnv("HOME");
  572. file = ".index.html";
  573. if (homepath) {
  574. path = "file://" + homepath + "/" + file;
  575. window.openUILinkIn(path, "tab");
  576. }
  577. }, "open my index.html");
  578. ext.add("strong-fullscreen", function(){
  579. var elemids = [
  580. "navigator-toolbox"
  581. ];
  582. BrowserFullScreen();
  583. var isfullscreen = window.fullScreen;
  584. for(var i = 0; i < elemids.length; i++){
  585. var elem = document.getElementById(elemids[i]);
  586. if(elem){
  587. if(isfullscreen){
  588. elem.style.display = "none";
  589. }else{
  590. elem.style.display = null;
  591. }
  592. }
  593. }
  594. var tabs = document.getElementById("verticaltabs-box");
  595. if(tabs){
  596. var pref_key = "extensions.verticaltabs.width";
  597. var pref_key_bak = pref_key + "_bak";
  598. if(isfullscreen){
  599. var width_orig = util.getIntPref(pref_key);
  600. util.setIntPref(pref_key_bak, width_orig);
  601. util.setIntPref(pref_key, 0);
  602. tabs.setAttribute("width", "0");
  603. }else if(parseInt(tabs.getAttribute("width") || "") === 0){
  604. var width_bak = util.getIntPref(pref_key_bak);
  605. util.setIntPref(pref_key, width_bak);
  606. tabs.setAttribute("width", width_bak.toString());
  607. }
  608. }
  609. }, "go fullscreen with hiding toolbar and tabbar");
  610. ext.add("bookmark-delicious", function(){
  611. f= 'http://www.delicious.com/save?url=' +
  612. encodeURIComponent(window.content.location.href) +
  613. '&title=' + encodeURIComponent(document.title) +
  614. '&notes=' + encodeURIComponent(
  615. '' + (window.getSelection ?
  616. window.getSelection() : (
  617. document.getSelection ?
  618. document.getSelection() :
  619. document.selection.createRange().text))) + '&v=6&';
  620. a = function(){
  621. if(! window.open(
  622. f + 'noui=1&jump=doclose',
  623. 'deliciousuiv6',
  624. 'location=1,links=0,scrollbars=0,toolbar=0,width=710,height=660')){
  625. location.href = f + 'jump=yes';
  626. }
  627. };
  628. if(/Firefox/.test(navigator.userAgent)){
  629. setTimeout(a,0);
  630. }else{
  631. a();
  632. }
  633. }, "bookmark delicious");
  634. ext.add('view-page-source', function(){
  635. window.content.location.href = "view-source:" +
  636. window.content.location.href;
  637. }, 'view page source');
  638. ext.add('my-setpref', function(){
  639. util.setPrefs(
  640. {
  641. "browser.bookmarks.max_backups":0,
  642. "browser.cache.memory.capacity":16384,
  643. "browser.download.manager.closeWhenDone":true,
  644. "browser.download.useDownloadDir":false,
  645. "browser.fullscreen.autohide":false,
  646. "browser.search.openintab":true,
  647. "browser.sessionhistory.max_total_viewers":8,
  648. "browser.sessionstore.restore_on_demand":true,
  649. "browser.tabs.closeWindowWithLastTab":false,
  650. "browser.tabs.loadDivertedInBackground": true,
  651. "browser.urlbar.autocomplete.enabled":false,
  652. "browser.urlbar.trimURLs":false,
  653. "browser.fixup.alternate.enabled": false,
  654. "dom.disable_window_open_feature.location": false,
  655. "dom.max_script_run_time": 30,
  656. "extensions.chaika.bbsmenu.open_new_tab":true,
  657. "extensions.chaika.bbsmenu.open_single_click":false,
  658. "extensions.chaika.board.open_new_tab":true,
  659. "extensions.chaika.board.open_single_click":false,
  660. "extensions.foxage2ch.openThreadInTab":true,
  661. "extensions.saveimageinfolder.general-duplicatefilenamevalue":1,
  662. "extensions.saveimageinfolder.general-fileprefixvalue":
  663. "%yyyy%%MM%%dd%-%hh%%mm%%ss%_",
  664. "extensions.saveimageinfolder.usecache":true,
  665. "extensions.tabutils.openTabNext":1,
  666. "extensions.tabutils.openUrlInTab":false,
  667. "extensions.tabutils.styles.current":
  668. "{\"bold\":true,\"italic\":false,\"underline\":true,\"strikethrough\":false,\"color\":true,\"colorCode\":\"#000000\",\"bgColor\":false,\"bgColorCode\":\"#000000\",\"outline\":false,\"outlineColorCode\":\"#000000\"}",
  669. "extensions.tabutils.styles.unread":
  670. "{\"bold\":false,\"italic\":false,\"underline\":false,\"strikethrough\":false,\"color\":true,\"colorCode\":\"#CC0000\",\"bgColor\":false,\"bgColorCode\":\"undefined\",\"outline\":false,\"outlineColorCode\":\"undefined\"}",
  671. "extensions.tabutils.TFS_Enable":false,
  672. // Always select right tab on close
  673. "extensions.tabutils.selectOnClose":10,
  674. "extensions.yass.edgetype":0,
  675. "extensions.yass.selectedpreset":"red",
  676. "font.default.x-western":"sans-serif",
  677. "gecko.handlerService.schemes.mailto.1.name":"Gmail",
  678. "general.warnOnAboutConfig":false,
  679. "keyword.URL":"http://www.bing.com/search?q=",
  680. "browser.search.defaultenginename":"Bing",
  681. "browser.search.defaulturl":"http://www.bing.com/search?q=",
  682. "network.dns.disableIPv6":true,
  683. "refcontrol.actions":
  684. "@DEFAULT=@FORGE www.heartrails.com=@NORMAL www.pixiv.net=@NORMAL",
  685. "scrapbook.tabs.open":true
  686. }
  687. );
  688. if(/^Linux/.test(navigator.platform)){
  689. util.setPrefs(
  690. {
  691. "browser.cache.disk.parent_directory":"/tmp",
  692. "browser.cache.disk.capacity":524288
  693. }
  694. );
  695. }
  696. display.showPopup("Keysnail", "My prefs done.");
  697. }, 'my setpref');
  698. ext.add('auto-install-plugins', function(ev, arg){
  699. var urls = [
  700. 'https://raw.github.com/mooz/keysnail/master/plugins/yet-another-twitter-client-keysnail.ks.js',
  701. 'https://raw.github.com/mooz/keysnail/master/plugins/site-local-keymap.ks.js',
  702. 'https://raw.github.com/mooz/keysnail/master/plugins/hok.ks.js',
  703. 'https://github.com/mooz/keysnail/raw/master/plugins/builtin-commands-ext.ks.js',
  704. 'https://raw.github.com/azu/KeySnail-Plugins/master/JSReference/js-referrence.ks.js',
  705. 'https://raw.github.com/gongo/keysnail_plugin/master/linksnail.ks.js',
  706. 'https://raw.githubusercontent.com/azu/keysnail-plugin/master/nicontroller.ks.js',
  707. 'https://raw.github.com/10sr/keysnail-plugin/master/shiitake.ks.js',
  708. 'https://raw.github.com/10sr/keysnail-plugin/master/dig-url.ks.js',
  709. 'https://raw.github.com/10sr/keysnail-plugin/master/instapaper.ks.js',
  710. 'https://raw.github.com/10sr/keysnail-plugin/master/pixiv_autojump.ks.js',
  711. 'https://raw.github.com/10sr/keysnail-plugin/master/list-current-urls.ks.js',
  712. 'https://gist.githubusercontent.com/10sr/1976942/raw/firefox-addon-manager.ks.js',
  713. 'https://gist.githubusercontent.com/958/1450594/raw/mstranslator.ks.js'
  714. ];
  715. function inst(a){
  716. if(a.length == 0){
  717. display.showPopup("auto-install-plugins",
  718. "All installation finished.");
  719. }else{
  720. var url = a.shift();
  721. var path = userscript.pluginDir +
  722. userscript.directoryDelimiter + url.match(/[^/]+$/)[0];
  723. if(plugins.context[path] === undefined){
  724. userscript.installPluginFromURL(url, function(){inst(a);});
  725. }else{
  726. inst(a);
  727. }
  728. }
  729. }
  730. inst(urls);
  731. }, 'Install plugins automatically if not installed yet.');
  732. ext.add('put-aside-this-page', function (ev, arg) {
  733. var n = getBrowser().mCurrentTab._tPos;
  734. getBrowser().moveTabTo(getBrowser().mCurrentTab, 0);
  735. if (n != 0) {
  736. getBrowser().selectedTab = getBrowser().mTabs[n];
  737. }
  738. }, 'put aside this page');
  739. ext.add('send-escape', function (ev, arg) {
  740. ev.target.dispatchEvent(key.stringToKeyEvent("ESC", true));
  741. }, 'escape');
  742. ext.add("open-hatebu-comment", function (ev, arg) {
  743. var url = window.content.location.href.replace(/^[^/]*\/\//, "");
  744. window.content.location.href = "http://b.hatena.ne.jp/entry/" + url;
  745. }, 'hatebu');
  746. // ext.add("focus-on-content", function(){
  747. // let(elem = document.commandDispatcher.focusedElement) elem && elem.blur();
  748. // gBrowser.focus();
  749. // content.focus();
  750. // }, "forcus on content");
  751. ext.add("hide-sidebar", function(){
  752. var sidebarBox = document.getElementById("sidebar-box");
  753. if (!sidebarBox.hidden) {
  754. toggleSidebar(sidebarBox.getAttribute("sidebarcommand"));
  755. }
  756. }, "hide-sidebar");
  757. ext.add("close-and-next-tab", function (ev, arg) {
  758. var n = getBrowser().mCurrentTab._tPos;
  759. getBrowser().removeCurrentTab();
  760. getBrowser().selectedTab = getBrowser().mTabs[n];
  761. }, "close and focus to next tab");
  762. //////////////////////////////////////
  763. //
  764. ext.add("restart-firefox-add-menu", function(){
  765. const XUL_NS =
  766. "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  767. var cmdelm = document.createElementNS(XUL_NS, "command");
  768. cmdelm.setAttribute("id", "my_cmd_restartFirefoxKs");
  769. cmdelm.setAttribute("oncommand", "ext.exec('restart-firefox');");
  770. var commandset = document.getElementById("mainCommandSet");
  771. // menu.insertBefore(elm, menu.getElementById("menu_FileQuitItem"));
  772. commandset.appendChild(cmdelm);
  773. var menuelm = document.createElementNS(XUL_NS, "menuitem");
  774. menuelm.setAttribute("label", "Restart Firefox");
  775. menuelm.setAttribute("id", "my_menu_restartFirefoxKs");
  776. menuelm.setAttribute("command", "my_cmd_restartFirefoxKs");
  777. var menu = document.getElementById("menu_FilePopup");
  778. // menu.insertBefore(elm, menu.getElementById("menu_FileQuitItem"));
  779. menu.appendChild(menuelm);
  780. }, "add restart firefox menu");
  781. /////////////////////////////////////////
  782. // feed url
  783. ext.add("feed-add-to-feedly", function(){
  784. var url = window.content.location.href;
  785. window.content.location.href =
  786. "http://cloud.feedly.com/#subscription%2Ffeed%2F" +
  787. encodeURIComponent(url);
  788. }, "Add current feed to feedly");
  789. var feedUtils = (function(){
  790. var feedhandler = "http://cloud.feedly.com/#subscription%2Ffeed%2F%s";
  791. function getFeeds(){
  792. const doc = content.document;
  793. var feeds = [[e.getAttribute("title"), e.getAttribute("href")]
  794. for ([, e] in Iterator(doc.querySelectorAll([
  795. 'link[type="application/rss+xml"]',
  796. 'link[type="application/atom+xml"]'
  797. ])))];
  798. var uh = window.content.location.href.replace(/(.*?\/\/[^/]*)(\/.*)?/,
  799. "$1");
  800. for (i = 0; i < feeds.length; i++)
  801. if ( feeds[i][1].substr(0,1) == "/" ) feeds[i][1] = uh + feeds[i][1];
  802. // feeds.unshift([window.content.document.title,
  803. // window.content.location.href]);
  804. return feeds;
  805. };
  806. ext.add("copy-feed-url", function () {
  807. var feeds = getFeeds();
  808. if (! feeds.length) {
  809. display.echoStatusBar("No feed found.");
  810. return;
  811. }
  812. prompt.selector({
  813. message : "Select Feed",
  814. collection : feeds,
  815. callback : function (i) {
  816. if (i >= 0) {
  817. command.setClipboardText(feeds[i][1]);
  818. }
  819. }
  820. });
  821. }, "Copy url or feed url of current page");
  822. ext.add("open-feed", function () {
  823. var feeds = getFeeds();
  824. if (! feeds.length) {
  825. display.echoStatusBar("No feed found.");
  826. return;
  827. }
  828. prompt.selector({
  829. message : "Select Feed",
  830. collection : feeds,
  831. callback : function (i) {
  832. if (i < 0) {
  833. return;
  834. }
  835. var feedurl = feeds[i][1];
  836. if (feedhandler) {
  837. window.openUILinkIn(
  838. feedhandler.replace("%s", feedurl),
  839. "tab"
  840. );
  841. } else {
  842. window.openUILinkIn(feedurl, "tab");
  843. }
  844. }
  845. });
  846. }, "Copy url or feed url of current page");
  847. return {
  848. getFeeds: getFeeds
  849. };
  850. })();
  851. ///////////////////////////////////////
  852. // keysnail z menu
  853. ext.add("keysnail-setting-dialog", function(){
  854. KeySnail.openPreference();
  855. }, "keysnail setting dialog");
  856. ext.add("keysnail-plugin-manager", function(){
  857. userscript.openPluginManager();
  858. }, "keysnail plugin manager");
  859. ext.add("firefox-open-addon-manager", function(){
  860. BrowserOpenAddonsMgr();
  861. }, "firefox addon manager");
  862. ext.add("keysnail-reload-init-file", function(){
  863. userscript.reload();
  864. }, "keysnail reload init file");
  865. ext.add("keysnail-z-menu",function(){
  866. var list = [["keysnail-setting-dialog"],
  867. ["keysnail-plugin-manager"],
  868. ["firefox-open-addon-manager"],
  869. ["keysnail-reload-init-file"],
  870. // ["check-for-plugins-update"],
  871. ["restart-firefox"]
  872. ];
  873. prompt.selector(
  874. {
  875. message : "open setting dialog",
  876. collection : list,
  877. callback : function (i) {
  878. ext.exec(list[i][0]);
  879. }
  880. });
  881. },"open keysnail z menu");
  882. ///////////////////////////////////
  883. // search web
  884. ext.add("query-then-engine", function () {
  885. prompt.reader({
  886. message : "Search Word?:",
  887. group : "query_word",
  888. // completer : completer.matcher.header(share.friendsCache || []),
  889. initialInput : content.document.getSelection() || "",
  890. callback : function (q) {
  891. if (q) {
  892. prompt.selector({
  893. message : "search \"" + q + "\" with?",
  894. collection : plugins.options["search-url-list"],
  895. width : [20,80],
  896. callback : function (i) {
  897. getBrowser().selectedTab =
  898. getBrowser().addTab(
  899. plugins.options["search-url-list"][i][1].
  900. replace("%r",q).replace(
  901. "%q",encodeURIComponent(q)
  902. )
  903. )
  904. ;
  905. }
  906. });
  907. };
  908. }
  909. });
  910. }, "enter search word and then select engine");
  911. /////////////////////////////////////
  912. // closed tab list
  913. ext.add("list-closed-tabs", function () {
  914. const fav = "chrome://mozapps/skin/places/defaultFavicon.png";
  915. var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(
  916. Ci.nsISessionStore
  917. );
  918. var json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
  919. var closedTabs = [[tab.image || fav, tab.title, tab.url]
  920. for each (tab in json.decode(ss.getClosedTabData(window)))
  921. ];
  922. if (!closedTabs.length)
  923. return void display.echoStatusBar("No recently closed tab.", 2000);
  924. prompt.selector(
  925. {
  926. message : "select tab to undo:",
  927. collection : closedTabs,
  928. flags : [ICON | IGNORE, 0, 0],
  929. callback : function (i) { if (i >= 0) window.undoCloseTab(i); }
  930. });
  931. }, "List closed tabs");
  932. ///////////////////////////////
  933. // http://malblue.tumblr.com/post/349001250/tips-japanese-keysnail-github
  934. ext.add("list-tab-history", function () {
  935. const fav = "chrome://mozapps/skin/places/defaultFavicon.png";
  936. var tabHistory = [];
  937. var sessionHistory = getBrowser().webNavigation.sessionHistory;
  938. if (sessionHistory.count < 1)
  939. return void display.echoStatusBar("Tab history not exist", 2000);
  940. var curIdx = sessionHistory.index;
  941. for (var i = 0; i < sessionHistory.count; i++) {
  942. var entry = sessionHistory.getEntryAtIndex(i, false);
  943. if (!entry)
  944. continue;
  945. try {
  946. var iconURL = Cc["@mozilla.org/browser/favicon-service;1"]
  947. .getService(Ci.nsIFaviconService)
  948. .getFaviconForPage(entry.URI).spec;
  949. } catch (ex) {}
  950. tabHistory.push([iconURL || fav, entry.title, entry.URI.spec, i]);
  951. }
  952. for (var thIdx = 0; thIdx < tabHistory.length; thIdx++) {
  953. if (tabHistory[thIdx][3] == curIdx) break;
  954. }
  955. prompt.selector(
  956. {
  957. message : "select history in tab",
  958. collection : tabHistory,
  959. flags : [ICON | IGNORE, 0, 0, IGNORE | HIDDEN],
  960. header : ["Title", "URL"],
  961. initialIndex : thIdx,
  962. callback : function(i) {
  963. if (i >= 0)
  964. getBrowser().webNavigation.gotoIndex(tabHistory[i][3]);
  965. }
  966. });
  967. }, 'List tab history');
  968. //}}%PRESERVE%
  969. // ========================================================================= //
  970. // ========================= Special key settings ========================== //
  971. key.quitKey = "ESC";
  972. key.helpKey = "<f1>";
  973. key.escapeKey = "C-q";
  974. key.macroStartKey = "";
  975. key.macroEndKey = "";
  976. key.universalArgumentKey = "C-u";
  977. key.negativeArgument1Key = "C--";
  978. key.negativeArgument2Key = "C-M--";
  979. key.negativeArgument3Key = "M--";
  980. key.suspendKey = "Not defined";
  981. // ================================= Hooks ================================= //
  982. hook.setHook('KeyBoardQuit', function (aEvent) {
  983. // ext.exec("hide-sidebar");
  984. var elem = document.commandDispatcher.focusedElement;
  985. elem && elem.blur();
  986. getBrowser().focus();
  987. content.focus();
  988. command.closeFindBar();
  989. if (util.isCaretEnabled()) {
  990. command.resetMark(aEvent);
  991. } else {
  992. goDoCommand("cmd_selectNone");
  993. }
  994. key.generateKey(aEvent.originalTarget, KeyEvent.DOM_VK_ESCAPE, true);
  995. });
  996. hook.setHook('Unload', function () {
  997. util.getBrowserWindows().some(function (win) {
  998. if (win === window) {
  999. return false;
  1000. }
  1001. const ks = win.KeySnail;
  1002. share.pluginUpdater = ks.getPluginUpdater(
  1003. share.pluginUpdater.pluginsWithUpdate);
  1004. ks.setUpPluginUpdaterDelegator();
  1005. return true;
  1006. });
  1007. });
  1008. hook.setHook('LocationChange', function (aNsURI) {
  1009. echoTabInfo.echo();
  1010. });
  1011. // ============================= Key bindings ============================== //
  1012. key.setGlobalKey('C-<up>', function () {
  1013. var browser = getBrowser();
  1014. if (browser.mCurrentTab.previousSibling) {
  1015. browser.moveTabTo(browser.mCurrentTab, browser.mCurrentTab._tPos - 1);
  1016. } else {
  1017. browser.moveTabTo(browser.mCurrentTab,
  1018. browser.mTabContainer.childNodes.length - 1);
  1019. }
  1020. }, '選択中のタブを右へ');
  1021. key.setGlobalKey('C-<down>', function () {
  1022. var browser = getBrowser();
  1023. if (browser.mCurrentTab.nextSibling) {
  1024. browser.moveTabTo(browser.mCurrentTab, browser.mCurrentTab._tPos + 1);
  1025. } else {
  1026. browser.moveTabTo(browser.mCurrentTab, 0);
  1027. }
  1028. }, '選択中のタブを左へ');
  1029. key.setGlobalKey('<delete>', function (ev, arg) {
  1030. var elem = document.commandDispatcher.focusedElement;
  1031. elem && elem.blur();
  1032. getBrowser().focus();
  1033. content.focus();
  1034. }, 'コンテンツへフォーカス', true);
  1035. key.setGlobalKey('<f11>', function (ev, arg) {
  1036. ext.exec("strong-fullscreen", arg, ev);
  1037. }, 'go fullscreen with hiding toolbar and tabbar', true);
  1038. key.setGlobalKey('<end>', function (ev) {
  1039. getBrowser().mTabContainer.advanceSelectedTab(1, true);
  1040. }, 'ひとつ右のタブへ');
  1041. key.setGlobalKey('<home>', function (ev) {
  1042. getBrowser().mTabContainer.advanceSelectedTab(-1, true);
  1043. }, 'ひとつ左のタブへ');
  1044. key.setGlobalKey('<next>', function (ev) {
  1045. let browser = getBrowser();
  1046. if (browser.mCurrentTab.nextSibling) {
  1047. browser.moveTabTo(browser.mCurrentTab, browser.mCurrentTab._tPos + 1);
  1048. } else {
  1049. browser.moveTabTo(browser.mCurrentTab, 0);
  1050. }
  1051. }, '選択中のタブを右へ');
  1052. key.setGlobalKey('<prior>', function (ev) {
  1053. let browser = getBrowser();
  1054. if (browser.mCurrentTab.previousSibling) {
  1055. browser.moveTabTo(browser.mCurrentTab, browser.mCurrentTab._tPos - 1);
  1056. } else {
  1057. browser.moveTabTo(browser.mCurrentTab, browser.mTabContainer.childNodes.length - 1);
  1058. }
  1059. }, '選択中のタブを左へ');
  1060. key.setViewKey('0', function (ev) {
  1061. BrowserCloseTabOrWindow();
  1062. }, 'タブ / ウィンドウを閉じる');
  1063. key.setViewKey('l', function (ev) {
  1064. getBrowser().mTabContainer.advanceSelectedTab(1, true);
  1065. }, 'ひとつ右のタブへ');
  1066. key.setViewKey('h', function (ev) {
  1067. getBrowser().mTabContainer.advanceSelectedTab(-1, true);
  1068. }, 'ひとつ左のタブへ');
  1069. key.setViewKey('o', function (ev, arg) {
  1070. ext.exec("hok-start-foreground-mode", arg, ev);
  1071. }, 'Start Hit a Hint foreground mode', true);
  1072. key.setViewKey('c', function (ev) {
  1073. command.interpreter();
  1074. }, 'JavaScript のコードを評価');
  1075. key.setViewKey('D', function (ev, arg) {
  1076. ext.exec("dig-url", arg, ev);
  1077. }, 'dig url with selector', true);
  1078. key.setViewKey('x', function (aEvent, aArg) {
  1079. ext.select(aArg, aEvent);
  1080. }, 'エクステ一覧');
  1081. key.setViewKey(['t', 'w'], function (ev, arg) {
  1082. ext.exec("twitter-client-tweet", arg, ev);
  1083. }, 'つぶやく', true);
  1084. key.setViewKey(['t', 'p'], function (ev, arg) {
  1085. ext.exec("twitter-client-tweet-this-page", arg, ev);
  1086. }, 'このページのタイトルと URL を使ってつぶやく', true);
  1087. key.setViewKey([['u'], ['S-SPC']], function (ev) {
  1088. goDoCommand("cmd_scrollPageUp");
  1089. }, '一画面分スクロールアップ');
  1090. key.setViewKey('g', function () {
  1091. goDoCommand("cmd_scrollTop");
  1092. }, 'ページ先頭へ移動');
  1093. key.setViewKey('G', function () {
  1094. goDoCommand("cmd_scrollBottom");
  1095. }, 'ページ末尾へ移動');
  1096. key.setViewKey('r', function (aEvent) {
  1097. BrowserReload();
  1098. }, '再読み込み');
  1099. key.setViewKey('z', function (ev, arg) {
  1100. ext.exec("keysnail-z-menu", arg, ev);
  1101. }, 'open keysnail setting menu', true);
  1102. key.setViewKey('e', function () {
  1103. command.focusElement(command.elementsRetrieverTextarea, 0);
  1104. }, '最初のインプットエリアへフォーカス', true);
  1105. key.setViewKey('S', function (ev, arg) {
  1106. if (window.loadURI) {
  1107. 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{}");
  1108. }
  1109. }, 'google reader share');
  1110. key.setViewKey('!', function (ev, arg) {
  1111. shell.input();
  1112. }, 'Command system');
  1113. key.setViewKey('R', function () {
  1114. BrowserReloadSkipCache();
  1115. }, '更新(キャッシュを無視)');
  1116. key.setViewKey('<backspace>', function () {
  1117. BrowserBack();
  1118. }, '戻る');
  1119. key.setViewKey('S-<backspace>', function () {
  1120. BrowserForward();
  1121. }, '進む');
  1122. key.setViewKey('q', function (ev, arg) {
  1123. ext.exec("query-then-engine", arg, ev);
  1124. }, 'enter search word and then select engine', true);
  1125. key.setViewKey('/', function () {
  1126. command.iSearchForward();
  1127. }, 'インクリメンタル検索', true);
  1128. key.setViewKey('?', function (ev) {
  1129. command.iSearchForwardKs(ev);
  1130. }, 'Emacs ライクなインクリメンタル検索', true);
  1131. key.setViewKey('a', function (ev, arg) {
  1132. allTabs.open();
  1133. }, 'alltabs.open');
  1134. key.setViewKey([['d'], ['SPC']], function (ev) {
  1135. goDoCommand("cmd_scrollPageDown");
  1136. }, '一画面スクロールダウン');
  1137. key.setViewKey(':', function (ev, arg) {
  1138. return !document.getElementById("keysnail-prompt").hidden &&
  1139. document.getElementById("keysnail-prompt-textbox").focus();
  1140. }, 'KeySnail のプロンプトへフォーカス', true);
  1141. key.setViewKey('B', function (ev) {
  1142. var browser = getBrowser();
  1143. if (browser.mCurrentTab.previousSibling) {
  1144. browser.moveTabTo(browser.mCurrentTab, browser.mCurrentTab._tPos - 1);
  1145. } else {
  1146. browser.moveTabTo(browser.mCurrentTab,
  1147. browser.mTabContainer.childNodes.length - 1);
  1148. }
  1149. }, '選択中のタブを左へ');
  1150. key.setViewKey('C', function (ev, arg) {
  1151. ext.exec("linksnail", arg, ev);
  1152. }, 'LinkSnail', true);
  1153. key.setViewKey('C-<backspace>', function (ev, arg) {
  1154. ext.exec("list-tab-history", arg, ev);
  1155. }, 'List tab history', true);
  1156. key.setViewKey('I', function (ev, arg) {
  1157. ext.exec("instapaper-post-page-with-comment", arg, ev);
  1158. }, 'post page and comment', true);
  1159. key.setViewKey('T', function (ev, arg) {
  1160. ext.exec("mstranslator-open-prompt", arg, ev);
  1161. }, 'MSTranslator - Open prompt', true);
  1162. key.setViewKey('f', function (ev, arg) {
  1163. ext.exec('strong-fullscreen', arg, ev);
  1164. }, 'go fullscreen with hiding toolbar and tabbar', true);
  1165. key.setViewKey('F', function (ev) {
  1166. var browser = getBrowser();
  1167. if (browser.mCurrentTab.nextSibling) {
  1168. browser.moveTabTo(browser.mCurrentTab, browser.mCurrentTab._tPos + 1);
  1169. } else {
  1170. browser.moveTabTo(browser.mCurrentTab, 0);
  1171. }
  1172. }, '選択中のタブを右へ');
  1173. key.setViewKey('U', function (ev, arg) {
  1174. ext.exec("list-closed-tabs", arg, ev);
  1175. }, 'List closed tabs', true);
  1176. key.setViewKey('j', function (ev) {
  1177. key.generateKey(ev.originalTarget, KeyEvent.DOM_VK_DOWN, true);
  1178. }, '一行スクロールダウン');
  1179. key.setViewKey('k', function (ev) {
  1180. key.generateKey(ev.originalTarget, KeyEvent.DOM_VK_UP, true);
  1181. }, '一行スクロールアップ');
  1182. key.setViewKey('p', function (ev, arg) {
  1183. ext.exec('pocket-add-current', arg, ev);
  1184. }, 'Add current page', true);
  1185. key.setViewKey('P', function (ev, arg) {
  1186. ext.exec('pocket-open-latest', arg, ev);
  1187. }, 'Open last saved page', true);
  1188. key.setEditKey('C-<tab>', function (ev) {
  1189. command.walkInputElement(command.elementsRetrieverTextarea, true, true);
  1190. }, '次のテキストエリアへフォーカス');
  1191. key.setEditKey('C-a', function (ev) {
  1192. command.beginLine(ev);
  1193. }, '行頭へ移動');
  1194. key.setEditKey('C-e', function (ev) {
  1195. command.endLine(ev);
  1196. }, '行末へ');
  1197. key.setEditKey('C-d', function (ev) {
  1198. goDoCommand("cmd_deleteCharForward");
  1199. }, '次の一文字削除');
  1200. key.setEditKey('C-b', function (ev) {
  1201. command.previousChar(ev);
  1202. }, '一文字左へ移動');
  1203. key.setEditKey('C-f', function (ev) {
  1204. command.nextChar(ev);
  1205. }, '一文字右へ移動');
  1206. key.setEditKey('C-h', function (ev) {
  1207. goDoCommand("cmd_deleteCharBackward");
  1208. }, '前の一文字を削除');
  1209. key.setEditKey('C-k', function (ev) {
  1210. command.killLine(ev);
  1211. }, 'カーソルから先を一行カット (Kill line)');
  1212. key.setEditKey('C-l', function (ev) {
  1213. command.recenter(ev);
  1214. }, 'カーソル位置が画面の中央へ来るようスクロール', true);
  1215. key.setEditKey('C-n', function (ev) {
  1216. command.nextLine(ev);
  1217. }, '一行下へ');
  1218. key.setEditKey('C-p', function (ev) {
  1219. command.previousLine(ev);
  1220. }, '一行上へ');
  1221. key.setEditKey('C-o', function (ev) {
  1222. command.openLine(ev);
  1223. }, '行を開く (Open line)');
  1224. key.setGlobalKey('C-<right>', function (ev) {
  1225. getBrowser().mTabContainer.advanceSelectedTab(1, true);
  1226. }, 'ひとつ右のタブへ');
  1227. key.setGlobalKey('C-<left>', function (ev) {
  1228. getBrowser().mTabContainer.advanceSelectedTab(-1, true);
  1229. }, 'ひとつ左のタブへ');