PageRenderTime 61ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/firefox/keysnail/.keysnail.js

https://bitbucket.org/bamanzi/misc-utils
JavaScript | 1614 lines | 1250 code | 282 blank | 82 comment | 160 complexity | 734677ca914272e7ede1082a264df6b2 MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. // ========================== KeySnail Init File =========================== //
  2. // You can preserve your code in this area when generating the init file using GUI.
  3. // Put all your code except special key, set*key, hook, blacklist.
  4. // ========================================================================= //
  5. //{{%PRESERVE%
  6. //* PRESERVE
  7. //** Use Fox Splitter addon to mimic C-x 1/2/3 stuff
  8. ext.add("other-window", function() {
  9. function focusSubBrowserById(aId) {
  10. SplitBrowser.getSubBrowserById(aId).browser.contentWindow.focus();
  11. }
  12. var browsers = SplitBrowser.browsers;
  13. if (SplitBrowser.activeBrowser === gBrowser) {
  14. focusSubBrowserById(browsers[arg == null ? 0 : browsers.length - 1].id);
  15. return;
  16. }
  17. var id = SplitBrowser.activeSubBrowser.id;
  18. for (var i = 0; i < browsers.length; i++) {
  19. if (browsers[i].id == id) {
  20. break;
  21. }
  22. }
  23. var nextIndex = arg == null ? i + 1 : i - 1;
  24. if (nextIndex >= browsers.length || nextIndex < 0) {
  25. gBrowser.contentWindow.focus();
  26. } else {
  27. focusSubBrowserById(browsers[nextIndex].id);
  28. }
  29. }, 'Select another window (Fox Splitter addon)');
  30. ext.add("delete-frame", function() {
  31. if (typeof SplitBrowser == "undefined") {
  32. BrowserTryToCloseWindow();
  33. } else {
  34. SplitBrowser.activeBrowserCloseWindow();
  35. }
  36. }, 'Close current active "window" (Fox Splitter addon)');
  37. ext.add("delete-window", function() {
  38. if (typeof SplitBrowser == "undefined") {
  39. BrowserCloseTabOrWindow();
  40. } else {
  41. var b = SplitBrowser.activeBrowser;
  42. if (b.mTabs.length > 1) {
  43. b.removeTab(b.mCurrentTab);
  44. } else if (b === gBrowser) {
  45. gBrowser.removeTab(gBrowser.mCurrentTab);
  46. }
  47. }
  48. }, 'Close tab (or \'window\', if Fox Splitter addon installed)');
  49. ext.add("delete-other-windows", function() {
  50. if (typeof SplitBrowser == "undefined") {
  51. splitpannel.toggle(null, false, "any");
  52. } else {
  53. var url = SplitBrowser.activeBrowser != gBrowser ? SplitBrowser.activeSubBrowser.src : null;
  54. var browsers = SplitBrowser.browsers;
  55. for (var i = 0; i < browsers.length; ++i) {
  56. browsers[i].close();
  57. }
  58. if (url) {
  59. window.loadURI(url);
  60. }
  61. }
  62. }, 'delete-other-windows (Fox Splitter or Split Pannel required');
  63. ext.add("split-window-vertically" , function() {
  64. if ( (typeof(SplitBrowser)) != "undefined" ) {
  65. SplitBrowser.addSubBrowser(window.content.location.href, SplitBrowser.activeSubBrowser, SplitBrowser.POSITION_BOTTOM);
  66. } else {
  67. splitpannel.toggle(window._content.document.location, true, "bottom");
  68. }
  69. }, 'split-window-vertically (Fox Splitter addon)');
  70. ext.add("split-window-horizontally", function() {
  71. if ( (typeof(SplitBrowser)) != "undefined" ) {
  72. SplitBrowser.addSubBrowser(window.content.location.href, SplitBrowser.activeSubBrowser, SplitBrowser.POSITION_RIGHT);
  73. } else {
  74. splitpannel.toggle(window._content.document.location, true, "right");
  75. }
  76. }, 'split-window-horizontally (Fox Splitter or Split Pannel required');
  77. //** split panel
  78. ext.add("view-in-split-panel", function () {
  79. splitpannel.toggle(window._content.document.location, true, 'right');
  80. }, 'Open Split Panel and load current URL in it .');
  81. ext.add("bookmarks-sidebar-in-split-panel", function() {
  82. splitpannel.toggle("chrome://browser/content/bookmarks/bookmarksPanel.xul", true, 'right');
  83. }, 'Open Bookmarks Sidebar in Split Panel');
  84. ext.add("cnblogs-ing-in-split-panel", function () {
  85. splitpannel.toggle('http://space.cnblogs.com/mi/', true, 'right');
  86. }, 'Open Split Panel and load http://space.cnblogs.com/mi/ in it .');
  87. ext.add("google-reader-i-in-split-panel", function() {
  88. splitpannel.toggle('https://www.google.com/reader/i/#stream/user%2F02753487812100788291%2Fstate%2Fcom.google%2Fread', true, 'right');
  89. }, 'Open Split Panel and load Google Reader in it .');
  90. ext.add("google-translate-in-split-panel", function () {
  91. splitpannel.toggle("http://translate.google.com/m?hl=zh-CN&sl=auto&tl=en&ie=UTF-8", true, 'right');
  92. }, 'Open Split Panel and load Google Translate (any->en) in it .');
  93. ext.add("google-translate-cn-in-split-panel", function () {
  94. splitpannel.toggle("http://translate.google.com/m?hl=zh-CN&sl=auto&tl=zh-CN&ie=UTF-8", true, 'right');
  95. }, 'Open Split Panel and load Google Translate (any->zh-CN) in it .');
  96. ext.add("read-it-later-list-in-split-panel", function() {
  97. splitpannel.toggle("http://readitlaterlist.com/unread", true, 'right');
  98. }, 'Show Read It Later list Split Panel');
  99. ext.add("read-it-later-sidebar-in-split-panel", function() {
  100. splitpannel.toggle('chrome://isreaditlater/content/list.xul', true, 'right');
  101. }, 'Show ReadItLater sidebar in Split Panel. (readitlater extension)');
  102. ext.add("save-to-read-sidebar-in-split-panel", function() {
  103. splitpannel.toggle("chrome://save2read/content/ff-sidebar.xul", true, 'right');
  104. }, 'Toggle Save-To-Read sidebar. (save2read extension)');
  105. //FIXME: not work?
  106. ext.add("pano-sidebar-in-split-panel", function() {
  107. splitpannel.toggle('chrome://pano/content/sidebar.xul', true, 'right');
  108. }, 'Open Pano sidebar in Split Panel (extension Pano).');
  109. //FIXME: manual refreshing needed when active tab changed in main panel
  110. ext.add("headings-map-in-split-panel", function() {
  111. splitpannel.toggle('chrome://headings/content/headings.xul', 'true', 'right');
  112. }, 'Show Headings Map sidebar in Split Panel.');
  113. //** sidebar
  114. ext.add("scrapbook-sidebar-in-split-panel", function () {
  115. splitpannel.toggle('chrome://scrapbook/content/scrapbook.xul', true, 'right');
  116. }, 'Toggle Scrapbook sidebar (extension Scrapbook or Scrapbook Plus)');
  117. ext.add("view-in-sidebar", function() {
  118. toggleSidebar('', false);
  119. var sidebarcmd = document.getElementById('viewURISidebar');
  120. //print(sidebarcmd.getAttribute("sidebarurl"))
  121. //print(sidebarcmd.getAttribute("checked"))
  122. sidebarcmd.removeAttribute("checked");
  123. sidebarcmd.setAttribute("sidebarurl", content.location.href);
  124. sidebarcmd.setAttribute("sidebartitle", content.document.title);
  125. toggleSidebar('viewURISidebar', true);
  126. }, "Load current URL in sidebar");
  127. //toggle sidebar
  128. ext.add("toggle-sidebar", function () {
  129. toggleSidebar("");
  130. }, 'toggle sidebar');
  131. ext.add("read-it-later-sidebar", function () {
  132. toggleSidebar("RIL_sidebarlist");
  133. }, 'Toggle ReadItLater sidebar. (readitlater extension)');
  134. ext.add("save-to-read-sidebar", function () {
  135. toggleSidebar("viewSidebar_save2read");
  136. }, 'Toggle Save-To-Read sidebar. (save2read extension)');
  137. ext.add("pano-sidebar", function() {
  138. toggleSidebar('viewPanoramaSidebar');
  139. }, 'Toggle Pano side bar (extension Pano).');
  140. ext.add("scrapbook-sidebar", function () {
  141. toggleSidebar("viewScrapBookSidebar");
  142. }, 'Toggle Scrapbook sidebar (extension Scrapbook or Scrapbook Plus)');
  143. //** sidebar
  144. //FIXME: not work on Firefox > 24?
  145. toggleToolbar = function(aEvent, toolbar_id, force) {
  146. if(toolbar_id != aEvent.originalTarget.parentNode.id) {
  147. var toolbar = document.getElementById(toolbar_id);
  148. try {
  149. // Firefox 4, mainly the bookmark toolbar button
  150. var hidingAttribute = toolbar.getAttribute("type") == "menubar" ?
  151. "autohide" : "collapsed";
  152. var isHidden = toolbar.getAttribute(hidingAttribute) == "true";
  153. setToolbarVisibility(toolbar, !isHidden);
  154. if(force)
  155. toolbar.collapsed = !toolbar.collapsed;
  156. } catch(e) {
  157. toolbar.collapsed = !toolbar.collapsed;
  158. document.persist(toolbar_id, "collapsed");
  159. }
  160. }
  161. };
  162. ext.add("toggle-nav-bar", function(ev, argv) {
  163. toggleToolbar(ev, "nav-bar");
  164. }, "Toggle navigation bar");
  165. ext.add("toggle-bookmark-bar", function(ev, argv) {
  166. toggleToolbar(ev, "PersonalToolbar");
  167. }, "Toggle bookmark bar");
  168. ext.add("toggle-menu-bar", function(ev, arg) {
  169. toggleToolbar(ev, "toolbar-menubar");
  170. }, "Toggle menu bar");
  171. ext.add("toggle-addon-bar", function(ev, argv) {
  172. toggleToolbar(ev, "addon-bar");
  173. }, "Toggle addon bar");
  174. ext.add("toggle-tgm-bar", function(ev, arg) {
  175. toggleToolbar(ev, "TabGroupsManagerToolbar");
  176. }, "Toggle TabGroups Manager toolbar.");
  177. //** Scrapbook (Plus)
  178. //make some ScrapBook (Plus)'s command could be manipulated with keyboard
  179. ext.add("scrapbook-highlight", function(ev, arg) {
  180. //if ARG given, switch to correspding highligher and use it
  181. sbPageEditor.highlight(arg);
  182. }, "Highlight selection with scrapbook's highlighter");
  183. ext.add("scrapbook-undo", function() {
  184. sbPageEditor.undo();
  185. }, "Scrapbook Editor's undo.");
  186. ext.add("scrapbook-save", function() {
  187. sbPageEditor.saveOrCapture();
  188. }, "Capture current page to Scrapbook, or save modification.");
  189. //** some online services
  190. //is.gd service
  191. ext.add("is.gd", function () {
  192. let endpoint = "http://is.gd/api.php?longurl=" + encodeURIComponent(window._content.document.location);
  193. let result = util.httpGet(endpoint, true);
  194. if (result.status == 200) {
  195. command.setClipboardText(result.responseText);
  196. display.echoStatusBar("Short URL copied into clipboard: " + result.responseText, 3000);
  197. }
  198. else
  199. display.echoStatusBar("is.gd service failed: " + result.statusText, 3000);
  200. }, "Shorten current page's URL with http://is.gd service");
  201. // goo.gl
  202. ext.add("goo.gl", function () {
  203. let endpoint = "https://www.googleapis.com/urlshortener/v1/url";
  204. let params = { "longUrl": window._content.document.location.href };
  205. let result = util.httpPostJSON(endpoint, params, function (xhr) {
  206. if (xhr.status == 200) {
  207. var ret = JSON.parse(xhr.responseText);
  208. command.setClipboardText(ret.id);
  209. display.echoStatusBar("Short URL copied into clipboard: " + ret.id, 3000);
  210. } else {
  211. display.echoStatusBar("goo.gl service failed: " + xhr.statusText, 3000);
  212. }
  213. });
  214. }, "Shorten URL with http://goo.gl service");
  215. // goo.gl only accepts content-type as 'application/json',
  216. // but keysnail's httpGet/httpPost doesn't support it
  217. util.httpPostJSON= function (url, params, callback) {
  218. let xhr = new XMLHttpRequest();
  219. switch (typeof params)
  220. {
  221. case "string":
  222. // nothing
  223. break;
  224. case "object":
  225. params = JSON.stringify(params);
  226. break;
  227. default:
  228. params = "";
  229. break;
  230. }
  231. let async = typeof callback === "function";
  232. if (async)
  233. {
  234. xhr.onreadystatechange = function () {
  235. if (xhr.readyState === 4)
  236. callback(xhr);
  237. };
  238. }
  239. xhr.open("POST", url, async);
  240. xhr.setRequestHeader("Content-type", "application/json");
  241. xhr.setRequestHeader("Content-length", params.length);
  242. xhr.setRequestHeader("Connection", "close");
  243. xhr.send(params);
  244. return xhr;
  245. };
  246. ext.add("bookmark-on-delicious", function(ev, arg) {
  247. var f='http://www.delicious.com/save?url='+encodeURIComponent(content.location.href)+
  248. '&title='+encodeURIComponent(content.title)+
  249. '&notes='+encodeURIComponent(''+(content.getSelection?
  250. content.getSelection():
  251. content.getSelection?
  252. content.getSelection():
  253. content.selection.createRange().text))+
  254. '&v=6&';
  255. var a=function(){
  256. if(!window.open(f+'noui=1&jump=doclose','deliciousuiv6',
  257. 'location=yes,links=no,scrollbars=no,toolbar=no,width=550,height=550'))
  258. location.href=f+'jump=yes';
  259. };
  260. if(/Firefox/.test(navigator.userAgent)) {
  261. setTimeout(a,0);
  262. } else {
  263. a();
  264. }
  265. }, "bookmark current page on delicious.");
  266. ext.add("gwt", function() {
  267. var newurl = "http://gxc.google.com/gwt/x?u=" + window.content.location.href;
  268. content.location.href = newurl;
  269. }, "Use GWT to view current url.");
  270. //** selection
  271. ext.add("go-to-selected-url", function() {
  272. if(!getBrowserSelection()) return;
  273. gBrowser.loadOneTab(getBrowserSelection(), null, null, null, true);
  274. }, "Open selected text as an URL and go to it.");
  275. ext.add("highlight-all", function() {
  276. var word = getBrowserSelection();
  277. if (word) {
  278. gFindBar._findField.value = word;
  279. gFindBar._highlightDoc(true, word);
  280. }
  281. }, "highlight all occurrence of current selected word.");
  282. ext.add("next-occur", function() {
  283. var word = getBrowserSelection();
  284. if (word) {
  285. gFindBar._findField.value = word;
  286. gFindBar._highlightDoc(true, word);
  287. }
  288. gFindBar.onFindAgainCommand(false);
  289. }, "highlight next occurrence of current selected word");
  290. ext.add("previous-occur", function() {
  291. var word = getBrowserSelection();
  292. if (word) {
  293. gFindBar._findField.value = word;
  294. gFindBar._highlightDoc(true, word);
  295. }
  296. gFindBar.onFindAgainCommand(true);
  297. }, "highlight previouse occurence of current selected word");
  298. //*** translation
  299. //{{{ inline translate:
  300. // based on code stolen from Mar Mod extension
  301. function google_translate (whatToTranslate, lang, callback) {
  302. if (whatToTranslate.length<=0 || whatToTranslate.length>=1000) {
  303. alert('Text is too long');
  304. return;
  305. }
  306. var httpRequest = null;
  307. //e.g http://translate.google.com/m?hl=zh-CN&sl=auto&tl=en&ie=UTF-8&prev=_m&q=dictionary
  308. // var fullUrl = "http://translate.google.com/m?hl=" + lang + "&sl=auto&tl=" + lang + "&ie=UTF-8" +
  309. // "&q=" + whatToTranslate;
  310. var fullUrl = "http://translate.google.hu/translate_t?text=" + whatToTranslate +
  311. "&hl=" + lang + "&langpair=auto|" + lang + "&tbb=1" ;
  312. function removeHTMLTags(mitkell) { //clean up a string from html tags
  313. var strInputCode = mitkell;
  314. var strTagStrippedText = strInputCode.replace(/<\/?[^>]+(>|$)/g, "");
  315. return strTagStrippedText;
  316. }
  317. function infoReceived() { // if there is response from Google then write out translation
  318. var output = httpRequest.responseText;
  319. // alert(output)
  320. if (output.length) {
  321. // Build the output string from Google Page
  322. output = output.replace(/&quot;/gi,'"');
  323. output = output.replace(/&lt;/gi,'<');
  324. output = output.replace(/&gt;/gi,'>');
  325. output = output.replace(/&amp;/gi,'&');
  326. output = output.replace(/&#39;/gi,"'");
  327. var fieldArray = output.split('</head>');
  328. var tempResz = [];
  329. if (fieldArray[1].search('class="short_text"')!=-1) {
  330. tempResz = fieldArray[1].split('<span id=result_box class="short_text">');
  331. }
  332. else if (fieldArray[1].search('class="medium_text"')!=-1) {
  333. tempResz = fieldArray[1].split('<span id=result_box class="medium_text">');
  334. }
  335. else {
  336. tempResz = fieldArray[1].split('<span id=result_box class="long_text">');
  337. }
  338. //alert(tempResz[1]);
  339. var kimenet = tempResz[1].split('</span></div>');
  340. if (callback) {
  341. callback(kimenet[0]);
  342. } else {
  343. display.echoStatusBar(whatToTranslate + ': ' + kimenet[0], 5000);
  344. }
  345. }
  346. }
  347. httpRequest = new XMLHttpRequest();
  348. httpRequest.open("GET", fullUrl, true);
  349. httpRequest.onload = infoReceived;
  350. httpRequest.send(null);
  351. }
  352. function inline_translate_selection(lang) {
  353. var callback = function (result) {
  354. var range = content.getSelection().getRangeAt(0);
  355. range.deleteContents();
  356. range.insertNode(document.createTextNode(removeHTMLTags(result[0])));
  357. };
  358. google_translate(content.getSelection(), lang, callback);
  359. }
  360. ext.add("google-translate-selection-inline", function() {
  361. inline_translate_selection("en");
  362. }, "Translate the selection and replace it with result.");
  363. ext.add("google-translate-selection-inline-to-cn", function() {
  364. inline_translate_selection("zh-CN");
  365. }, "Translate the selection and replace it with result.");
  366. ext.add("google-translate-selection", function() {
  367. var selection = content.getSelection();
  368. var callback = function(result) {
  369. //alert(result);
  370. // <span title="Emacs粉丝应该很喜欢这个插件" onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">Emacs fans should like this plug-in</span>
  371. var ret = result.split(">");
  372. result = ret[1].split("<");
  373. display.echoStatusBar(selection + ": " + result[0], 5000);
  374. };
  375. google_translate(selection, "en", callback);
  376. }, "Translate the selection to English and show result in status bar.");
  377. ext.add("google-translate-selection-to-cn", function() {
  378. var selection = content.getSelection();
  379. var callback = function(result) {
  380. //alert(result);
  381. // <span title="Emacs粉丝应该很喜欢这个插件" onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">Emacs fans should like this plug-in</span>
  382. var ret = result.split(">");
  383. result = ret[1].split("<");
  384. display.echoStatusBar(selection + ": " + result[0], 5000);
  385. };
  386. google_translate(selection, "zh-CN", callback);
  387. }, "Translate the selection to Chinese and show result in status bar.");
  388. ext.add("fast-translation", function() {
  389. fasttransk.openresult(0);
  390. }, 'Translate selection and show result in Fast Translation dialog.');
  391. ext.add("wiktionary-lookup-selection", function() {
  392. if (!getBrowserSelection()) {
  393. display.echoStatusBar("Wiktionary: You must selection something.", 2000);
  394. return;
  395. }
  396. gd12.select.lookupSelected();
  397. }, 'Show translation for selection (extension: Wiktionary & Google Translate).');
  398. ext.add("dict", function () {
  399. dictDefineSelection();
  400. }, 'Looks up the definition of selected words using Dict protocol (requires Dict extension).');
  401. //*** web search
  402. ext.add("search-selection", function() {
  403. if(!getBrowserSelection()) return;
  404. BrowserSearch.loadSearch(getBrowserSelection(), true);
  405. }, "Use the default search engine to search the phrase currently selected");
  406. ext.add("google-search-selection", function() {
  407. if(!getBrowserSelection()) return;
  408. //https://www.google.com.hk/s?wd=ctags%20site%3Akomodoide.com
  409. var url = "http://www.jwss.cc/?q=" + getBrowserSelection()
  410. gBrowser.loadOneTab(url, null, null, null, false);
  411. }, "Use Google search engine to search the phrase currently selected");
  412. ext.add("ddg-search-selection", function() {
  413. if(!getBrowserSelection()) return;
  414. //https://duckduckgo.com/?q=ctags%20site:komodoide.com
  415. var url = "https://duckduckgo.com/?q=" + getBrowserSelection()
  416. gBrowser.loadOneTab(url, null, null, null, false);
  417. }, "Use DuckDuckGo search engine to search the phrase currently selected");
  418. ext.add("baidu-search-selection", function() {
  419. if(!getBrowserSelection()) return;
  420. //https://www.baidu.com/s?wd=ctags%20site%3Akomodoide.com
  421. var url = "https://www.baidu.com/s?wd=" + getBrowserSelection()
  422. gBrowser.loadOneTab(url, null, null, null, false);
  423. }, "Use Baidu search engine to search the phrase currently selected");
  424. ext.add("yahoo-search-selection", function() {
  425. if(!getBrowserSelection()) return;
  426. //https://search.yahoo.com/search?p=ctags%20site:komodoide.com
  427. var url = "https://search.yahoo.com/search?p=" + getBrowserSelection()
  428. gBrowser.loadOneTab(url, null, null, null, false);
  429. }, "Use Yahoo search engine to search the phrase currently selected");
  430. ext.add("google-site-search-selection", function() {
  431. if(!getBrowserSelection()) return;
  432. //https://www.google.com.hk/s?q=ctags%20site%3Akomodoide.com
  433. var url = "http://www.jwss.cc/?q=" + getBrowserSelection() +" site%3A" + content.location.hostname;
  434. gBrowser.loadOneTab(url, null, null, null, false);
  435. }, "Use Google search engine to search the phrase currently selected on current site");
  436. ext.add("ddg-site-search-selection", function() {
  437. if(!getBrowserSelection()) return;
  438. //https://duckduckgo.com/?q=ctags%20site%3Akomodoide.com
  439. var url = "https://duckduckgo.com/?q=" + getBrowserSelection() +" site%3A" + content.location.hostname;
  440. gBrowser.loadOneTab(url, null, null, null, false);
  441. }, "Use DuckDuckGo search engine to search the phrase currently selected on current site");
  442. ext.add("baidu-site-search-selection", function() {
  443. if(!getBrowserSelection()) return;
  444. //https://www.baidu.com/s?wd=ctags%20site%3Akomodoide.com
  445. var url = "https://www.baidu.com/s?wd=" + getBrowserSelection() +" site%3A" + content.location.hostname;
  446. gBrowser.loadOneTab(url, null, null, null, false);
  447. }, "Use Baidu search engine to search the phrase currently selected on current site");
  448. ext.add("yahoo-site-search-selection", function() {
  449. if(!getBrowserSelection()) return;
  450. //https://search.yahoo.com/search?p=ctags%20site:komodoide.com
  451. var url = "https://search.yahoo.com/search?p=" + getBrowserSelection() +" site%3A" + content.location.hostname;
  452. gBrowser.loadOneTab(url, null, null, null, false);
  453. }, "Use Yahoo search engine to search the phrase currently selected on current site");
  454. //** navigration
  455. //jump to previous page or next page
  456. ext.add("previous-page", function () {
  457. var document = window._content.document;
  458. var links = document.links;
  459. for(i = 0; i < links.length; i++) {
  460. if ( (links[i].text == '上一页') || (links[i].text == '<上一页')
  461. || (links[i].text == '上一篇') || (links[i].text == '< 前一页')
  462. || (links[i].text == 'Previous') || (links[i].text == 'Prev')
  463. || (links[i].text == '<') || (links[i].text == '<<'))
  464. document.location = links[i].href;
  465. }
  466. }, "Previous page");
  467. ext.add("next-page", function () {
  468. var document = window._content.document;
  469. var links = document.links;
  470. for(i = 0; i < links.length; i++) {
  471. if ( (links[i].text == '下一页') || (links[i].text == '下一页>')
  472. || (links[i].text == '下一篇') || (links[i].text == '后一页 >')
  473. || (links[i].text == 'Next') || (links[i].text == 'next')
  474. || (links[i].text == '>') || (links[i].text == '>>'))
  475. document.location = links[i].href;
  476. }
  477. }, "Next page");
  478. // paste and go
  479. ext.add("paste-and-go", function() {
  480. if (typeof(pastego) != "undefined") {
  481. //pastego addon
  482. pastego.onToolbarButtonCommand();
  483. return;
  484. }
  485. var url = command.getClipboardText();
  486. if (url.indexOf("://") != -1)
  487. {
  488. window._content.location = url;
  489. }
  490. else
  491. {
  492. //url = util.format("http://www.google.com/search?q=%s&ie=utf-8&oe=utf-8", encodeURIComponent(url));
  493. BrowserSearch.loadSearch(url, false);
  494. }
  495. }, "Paste the URL or keyword from clipboard and Go");
  496. ext.add("paste-to-tab-and-go", function() {
  497. var url = command.getClipboardText();
  498. if (url.indexOf("://") != -1)
  499. gBrowser.loadOneTab(url, null, null, null, false);
  500. else
  501. {
  502. //url = util.format("http://www.google.com/search?q=%s&ie=utf-8&oe=utf-8", encodeURIComponent(url));
  503. BrowserSearch.loadSearch(url, true);
  504. }
  505. }, "Paste the URL or keyword from clipboard to a new tab and Go");
  506. ext.add("increase-digit-in-url", function() {
  507. var pattern = /(.*?)([0]*)([0-9]+)([^0-9]*)$/;
  508. var url = content.location.href;
  509. var digit = url.match(pattern);
  510. if (digit[1] && digit[3]) {
  511. let len = digit[3].length;
  512. let next = +digit[3] + (arg ? arg : 1);
  513. content.location.href = digit[1] + (digit[2] || "").slice(next.toString().length - len) + next + (digit[4] || "");
  514. }
  515. }, 'Increment last digit in the URL');
  516. ext.add("decrease-digit-in-url", function() {
  517. var pattern = /(.*?)([0]*)([0-9]+)([^0-9]*)$/;
  518. var url = content.location.href;
  519. var digit = url.match(pattern);
  520. if (digit[1] && digit[3]) {
  521. let len = digit[3].length;
  522. let next = +digit[3] - (arg ? arg : 1);
  523. content.location.href = digit[1] + (digit[2] || "").slice(next.toString().length - len) + next + (digit[4] || "");
  524. }
  525. }, 'Decrement last digit in the URL');
  526. //** misc
  527. ext.add("count-region", function(ev, arg) {
  528. var aInput = ev.originalTarget;
  529. var value = aInput.value;
  530. var selcount = aInput.selectionEnd - aInput.selectionStart;
  531. display.echoStatusBar("Total:" + value.length + " Selected:" + selcount, 3000);
  532. }, "Count chars.");
  533. ext.add("open-extension-dialog", function(ev, arg) {
  534. var wm = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator);
  535. OpenAddonsMgr = function(type, typeUrl) {
  536. var extensionManager = wm.getMostRecentWindow("Extension:Manager");
  537. if (extensionManager) {
  538. extensionManager.focus();
  539. extensionManager.showView(type);
  540. } else {
  541. var addonManager = wm.getMostRecentWindow("Addons:Manager");
  542. if (addonManager) {
  543. addonManager.focus();
  544. addonManager.gViewController.loadView(typeUrl);
  545. } else {
  546. //var contents = toolbar_buttons.getUrlContents("chrome://mozapps/content/extensions/extensions.xul");
  547. window.openDialog(
  548. "chrome://mozapps/content/extensions/extensions.xul",
  549. "",
  550. "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable,width=1024,height=768,centerscreen",
  551. //contents.match("Addons:Manager") ? {"view" :typeUrl} : type);
  552. {"view" :typeUrl});
  553. }
  554. }
  555. };
  556. OpenAddonsMgr('extensions', 'addons://list/extension');
  557. }, "Open the Addons Manager.");
  558. ext.add("evernote-clearly", function() {
  559. readable_by_evernote__menu__call();
  560. }, "Read current page in Evernote Clearly (call again to quit).");
  561. ext.add("tabundle-group", function(ev, arg) {
  562. Tabundle.createGroupListHtml = function() {
  563. //....https://gist.github.com/1851778
  564. };
  565. Tabundle.createIndexHtml();
  566. //var path = Tabundle.createListHtml()
  567. var path = Tabundle.createGroupListHtml();
  568. if (path) {
  569. gBrowser.selectedTab = gBrowser.addTab('file://' + path);
  570. }
  571. }, "Use tabundle extension to capture info of all tabs of current group.");
  572. ext.add("tab-send-to-tmt", function(ev, arg) {
  573. var panoGroup = TabView._window.GroupItems.getActiveGroupItem();
  574. var groupName = panoGroup.getTitle();
  575. var tmtGroupId = -1;
  576. var rows = Visibo.common.gTMTRowPanel.childNodes;
  577. for (var i=0; i<rows.length; i++) {
  578. var row = rows[i];
  579. //alert("title: " + row.getAttribute("title") + "\n" +
  580. // "bmId: " + row.getAttribute("bmId"));
  581. if (row.getAttribute("title")==groupName) {
  582. tmtGroupId = row.getAttribute("bmId");
  583. }
  584. }
  585. if (tmtGroupId < 0) {
  586. //create a new group
  587. tmtGroupId = Visibo.TMT.API.addRow(groupName);
  588. }
  589. var tab = gBrowser.selectedTab;
  590. var tabdata = Visibo.TMT.Tab.extractTabData(tab);
  591. if (tabdata) {
  592. Visibo.TMT.API.addTabToRow(tabdata, tmtGroupId);
  593. //gBrowser.removeTab(tab);
  594. }
  595. }, "Send current tab to TooManyTabs (the row of TabCandy group name) and then close it.");
  596. ext.add("tabgroup-send-to-tmt", function(ev, arg) {
  597. var panoGroup = TabView._window.GroupItems.getActiveGroupItem();
  598. var groupName = panoGroup.getTitle();
  599. var tmtGroupId = -1;
  600. var rows = Visibo.common.gTMTRowPanel.childNodes;
  601. for (var i=0; i<rows.length; i++) {
  602. var row = rows[i];
  603. //alert("title: " + row.getAttribute("title") + "\n" +
  604. // "bmId: " + row.getAttribute("bmId"));
  605. if (row.getAttribute("title")==groupName) {
  606. tmtGroupId = row.getAttribute("bmId");
  607. }
  608. }
  609. if (tmtGroupId < 0) {
  610. //create a new group
  611. tmtGroupId = Visibo.TMT.API.addRow(groupName);
  612. }
  613. //print("tmtGroupId=" + tmtGroupId);
  614. var groupTabs = panoGroup._children;
  615. for (var i=0; i<groupTabs.length; i++) {
  616. var tab = groupTabs[i].tab;
  617. var tabdata = Visibo.TMT.Tab.extractTabData(tab);
  618. if (tabdata) {
  619. Visibo.TMT.API.addTabToRow(tabdata, tmtGroupId);
  620. }
  621. }
  622. //FIXME: how to close a tab without activating neighbour?
  623. // or: how to close a whole group (just like pano extension)?
  624. for (var i=groupTabs.length-1; i>=0; i--) {
  625. gBrowser.removeTab(groupTabs[i]);
  626. }
  627. }, "Send all tabs of current group (FF4+ TabCandy group) to TooManyTabs and then close them.");
  628. ext.add("reload-pac", function(ev, arg) {
  629. Components.classes["@mozilla.org/network/protocol-proxy-service;1"].getService().reloadPAC();
  630. }, "Reload proxy PAC script.");
  631. //** some utiltity functions
  632. function inputChars(ev, chars) {
  633. var aInput = ev.originalTarget;
  634. var value = aInput.value;
  635. var originalSelStart = aInput.selectionStart;
  636. aInput.value = value.slice(0, aInput.selectionStart) + chars + value.slice(aInput.selectionEnd, value.length);
  637. aInput.selectionStart = originalSelStart + 1;
  638. aInput.selectionEnd = aInput.selectionStart;
  639. }
  640. //}}%PRESERVE%
  641. // ========================================================================= //
  642. // ========================= Special key settings ========================== //
  643. key.quitKey = "C-g";
  644. key.helpKey = "<f1>";
  645. key.escapeKey = "C-q";
  646. key.macroStartKey = "C-x (";
  647. key.macroEndKey = "C-x )";
  648. key.universalArgumentKey = "C-u";
  649. key.negativeArgument1Key = "C--";
  650. key.negativeArgument2Key = "C-M--";
  651. key.negativeArgument3Key = "M--";
  652. key.suspendKey = "<f2>";
  653. // ================================= Hooks ================================= //
  654. hook.setHook('KeySnailInitialized', function () {
  655. hook.removeHook("KeySnailInitialized", arguments.callee);
  656. var displayHelpKey = [];
  657. for (let[k, act] in Iterator(actionKeys.selector)) {
  658. if (act === "prompt-display-keymap-help") {
  659. displayHelpKey.push(k);
  660. }
  661. }
  662. $("keysnail-prompt-selector-help-title").setAttribute("value", util.getLocaleString("promptSelectorKeymapHelpTitle", [displayHelpKey.join(", ")]));
  663. });
  664. hook.setHook('KeyBoardQuit', function (aEvent) {
  665. if (key.currentKeySequence.length) {
  666. return;
  667. }
  668. command.closeFindBar();
  669. var marked = command.marked(aEvent);
  670. if (util.isCaretEnabled()) {
  671. if (marked) {
  672. command.resetMark(aEvent);
  673. } else {
  674. if ("blur" in aEvent.target) {
  675. aEvent.target.blur();
  676. }
  677. gBrowser.focus();
  678. _content.focus();
  679. }
  680. } else {
  681. goDoCommand("cmd_selectNone");
  682. }
  683. if (KeySnail.windowType === "navigator:browser" && !marked) {
  684. key.generateKey(aEvent.originalTarget, KeyEvent.DOM_VK_ESCAPE, true);
  685. }
  686. });
  687. hook.setHook('Unload', function () {
  688. util.getBrowserWindows().some(function (win) {
  689. if (win === window) {
  690. return false;
  691. }
  692. const ks = win.KeySnail;
  693. share.pluginUpdater = ks.getPluginUpdater(share.pluginUpdater.pluginsWithUpdate);
  694. ks.setUpPluginUpdaterDelegator();
  695. return true;
  696. });
  697. });
  698. hook.addToHook('Unload', function () {
  699. util.getBrowserWindows().some(function (win) {
  700. if (win === window) {
  701. return false;
  702. }
  703. const ks = win.KeySnail;
  704. share.pluginUpdater = ks.getPluginUpdater(share.pluginUpdater.pluginsWithUpdate);
  705. ks.setUpPluginUpdaterDelegator();
  706. return true;
  707. });
  708. });
  709. hook.addToHook('Unload', function () {
  710. util.getBrowserWindows().some(function (win) {
  711. if (win === window) {
  712. return false;
  713. }
  714. const ks = win.KeySnail;
  715. share.pluginUpdater = ks.getPluginUpdater(share.pluginUpdater.pluginsWithUpdate);
  716. ks.setUpPluginUpdaterDelegator();
  717. return true;
  718. });
  719. });
  720. hook.addToHook('Unload', function () {
  721. util.getBrowserWindows().some(function (win) {
  722. if (win === window) {
  723. return false;
  724. }
  725. const ks = win.KeySnail;
  726. share.pluginUpdater = ks.getPluginUpdater(share.pluginUpdater.pluginsWithUpdate);
  727. ks.setUpPluginUpdaterDelegator();
  728. return true;
  729. });
  730. });
  731. // ============================= Key bindings ============================== //
  732. //* global mode
  733. key.setGlobalKey('C-M-r', function (ev) {
  734. userscript.reload();
  735. }, 'Reload the initialization file', true);
  736. key.setGlobalKey(['C-c', 'C-r'], function (ev) {
  737. userscript.reload();
  738. }, 'Reload the initialization file', true);
  739. key.setGlobalKey('M-x', function (ev, arg) {
  740. ext.select(arg, ev);
  741. }, 'List exts and execute selected one', true);
  742. key.setGlobalKey('M-:', function (ev) {
  743. command.interpreter();
  744. }, 'Command interpreter', true);
  745. key.setGlobalKey(['<f1>', 'b'], function (ev) {
  746. key.listKeyBindings();
  747. }, 'List all keybindings');
  748. key.setGlobalKey(['<f1>', 'F'], function (ev) {
  749. openHelpLink("firefox-help");
  750. }, 'Display Firefox help');
  751. key.setGlobalKey('C-m', function (ev) {
  752. key.generateKey(ev.originalTarget, KeyEvent.DOM_VK_RETURN, true);
  753. }, 'Generate the return key code');
  754. key.setGlobalKey(['C-x', 'l'], function (ev) {
  755. command.focusToById("urlbar");
  756. }, 'Focus to the location bar', true);
  757. key.setGlobalKey(['C-x', 'g'], function (ev) {
  758. command.focusToById("searchbar");
  759. }, 'Focus to the search bar', true);
  760. key.setGlobalKey(['C-x', 't'], function (ev) {
  761. command.focusElement(command.elementsRetrieverTextarea, 0);
  762. }, 'Focus to the first textarea', true);
  763. key.setGlobalKey(['C-x', 's'], function (ev) {
  764. command.focusElement(command.elementsRetrieverButton, 0);
  765. }, 'Focus to the first button', true);
  766. key.setGlobalKey(['C-x', '1'], function (ev, arg) {
  767. ext.exec("delete-other-windows", arg, ev);
  768. }, 'close-other-window (Fox Splitter addon)');
  769. key.setGlobalKey(['C-x', '2'], function (ev, arg) {
  770. ext.exec("split-window-vertically", arg, ev);
  771. }, 'split-window-vertically (Fox Splitter addon)');
  772. key.setGlobalKey(['C-x', '3'], function (ev, arg) {
  773. ext.exec("split-window-horizontally", arg, ev);
  774. }, 'split-window-horizontally (Fox Splitter addon)');
  775. key.setGlobalKey([['C-x', 'k'], ['C-c', 'x']], function (ev) {
  776. ext.exec("delete-window", arg, ev);
  777. }, 'Close tab (or \'window\', if Fox Splitter addon installed)');
  778. key.setGlobalKey(['C-x', 'o'], function (ev, arg) {
  779. ext.exec("other-window", arg, ev);
  780. }, 'other-window (Fox Splitter addon)', true);
  781. key.setGlobalKey([['C-x', 'K'], ['C-x', '5', '0']], function (ev) {
  782. closeWindow(true);
  783. }, 'Close the window');
  784. key.setGlobalKey([['C-x', 'n'], ['C-x', '5', '2']], function (ev) {
  785. OpenBrowserWindow();
  786. }, 'Open new window');
  787. key.setGlobalKey(['C-x', 'C-c'], function (ev) {
  788. goQuitApplication();
  789. }, 'Exit Firefox', true);
  790. key.setGlobalKey(['C-x', 'C-o'], function (ev, arg) {
  791. command.focusOtherFrame(arg);
  792. }, 'Select next frame');
  793. key.setGlobalKey(['C-x', 'C-1'], function (ev) {
  794. window.loadURI(ev.target.ownerDocument.location.href);
  795. }, 'Show current frame only', true);
  796. key.setGlobalKey(['C-x', 'C-f'], function (ev) {
  797. BrowserOpenFileWindow();
  798. }, 'Open the local file', true);
  799. key.setGlobalKey(['C-x', 'C-s'], function (ev) {
  800. saveDocument(window.content.document);
  801. }, 'Save current page to the file', true);
  802. key.setGlobalKey('M-w', function (ev) {
  803. command.copyRegion(ev);
  804. }, 'Copy selected text', true);
  805. key.setGlobalKey('C-s', function (ev) {
  806. command.iSearchForwardKs(ev);
  807. }, 'Emacs like incremental search forward', true);
  808. key.setGlobalKey('C-r', function (ev) {
  809. command.iSearchBackwardKs(ev);
  810. }, 'Emacs like incremental search backward', true);
  811. key.setGlobalKey(['C-c', 'u'], function (ev) {
  812. undoCloseTab();
  813. }, 'Undo closed tab');
  814. key.setGlobalKey(['C-c', 'C-c', 'C-v'], function (ev) {
  815. toJavaScriptConsole();
  816. }, 'Display JavaScript console', true);
  817. key.setGlobalKey(['C-c', 'C-c', 'C-c'], function (ev) {
  818. command.clearConsole();
  819. }, 'Clear Javascript console', true);
  820. key.setGlobalKey([['C-c', 'e'], ['C-c', 'C-i']], function (ev, arg) {
  821. ext.exec("edit_text", arg, ev);
  822. }, 'edit by external editor', true);
  823. key.setGlobalKey(['C-c', 'f'], function (ev, arg) {
  824. ext.exec("hok-start-foreground-mode", arg, ev);
  825. }, 'Start Hit a Hint foreground mode', true);
  826. key.setGlobalKey(['C-c', 'F'], function (ev, arg) {
  827. ext.exec("hok-start-background-mode", arg, ev);
  828. }, 'Start Hit a Hint background mode', true);
  829. key.setGlobalKey(['C-c', ';'], function (ev, arg) {
  830. ext.exec("hok-start-extended-mode", arg, ev);
  831. }, 'Start Hit a Hint extended mode', true);
  832. key.setGlobalKey(['C-c', 'C-e'], function (ev, arg) {
  833. ext.exec("hok-start-continuous-mode", arg, ev);
  834. }, 'Start Hit a Hint continuous mode', true);
  835. key.setGlobalKey(['C-c', 'g', 'u'], function (ev) {
  836. var uri = getBrowser().currentURI;
  837. if (uri.path == "/") {
  838. return;
  839. }
  840. var pathList = uri.path.split("/");
  841. if (!pathList.pop()) {
  842. pathList.pop();
  843. }
  844. loadURI(uri.prePath + pathList.join("/") + "/");
  845. }, 'Go upper directory');
  846. key.setGlobalKey(['C-c', 'g', 'U'], function (ev) {
  847. var uri = window._content.location.href;
  848. if (uri == null) {
  849. return;
  850. }
  851. var root = uri.match(/^[a-z]+:\/\/[^/]+\//);
  852. if (root) {
  853. loadURI(root, null, null);
  854. }
  855. }, 'Go to the root directory', true);
  856. key.setGlobalKey(['C-c', 't', 't'], function (ev, arg) {
  857. ext.exec("twitter-client-tweet", arg);
  858. }, 'Tweet', true);
  859. key.setGlobalKey(['C-c', 't', 'T'], function (ev, arg) {
  860. ext.exec("twitter-client-tweet-this-page", arg);
  861. }, 'Tweet with the title and URL of this page', true);
  862. key.setGlobalKey(['C-c', 't', 'r'], function (ev, arg) {
  863. ext.exec("twitter-client-display-timeline", arg);
  864. }, 'Display your timeline', true);
  865. key.setGlobalKey(['C-c', 'p'], function (ev, arg) {
  866. ext.exec("paste-and-go", arg, ev);
  867. }, 'Paste an URL or a search term and Go');
  868. key.setGlobalKey(['C-c', 'P'], function (ev, arg) {
  869. ext.exec("paste-to-tab-and-go", arg, ev);
  870. }, 'Paste to new tab and Go');
  871. key.setGlobalKey('C-M-l', function (ev) {
  872. getBrowser().mTabContainer.advanceSelectedTab(1, true);
  873. }, 'Select next tab');
  874. key.setGlobalKey('C-M-h', function (ev) {
  875. getBrowser().mTabContainer.advanceSelectedTab(-1, true);
  876. }, 'Select previous tab');
  877. key.setGlobalKey(['C-o', 'o'], function (ev, arg) {
  878. shell.input("Open ", arg);
  879. }, 'Open an URL', true);
  880. key.setGlobalKey(['C-o', 't'], function (ev, arg) {
  881. shell.input("tabopen ", arg);
  882. }, 'Open an URL in new tab', true);
  883. key.setGlobalKey(['C-o', 'f'], function (ev, arg) {
  884. BrowserOpenFileWindow();
  885. }, 'Open an existing file', true);
  886. key.setGlobalKey(['C-o', 'b'], function (ev, arg) {
  887. ext.exec("bmany-list-all-bookmarks", arg, ev);
  888. }, 'bmany - List all bookmarks', true);
  889. key.setGlobalKey(['C-o', 'k'], function (ev, arg) {
  890. ext.exec("bmany-list-all-bookmarks-with-keyword", arg, ev);
  891. }, 'bmany - List bookmarks with keyword', true);
  892. //* view mode
  893. key.setViewKey([['C-n'], ['C-c', 'j']], function (ev) {
  894. key.generateKey(ev.originalTarget, KeyEvent.DOM_VK_DOWN, true);
  895. }, 'Scroll line down');
  896. key.setViewKey([['C-c', 'k'], ['C-p']], function (ev) {
  897. key.generateKey(ev.originalTarget, KeyEvent.DOM_VK_UP, true);
  898. }, 'Scroll line up');
  899. key.setViewKey([['C-c', 'g', 'g'], ['M-<']], function (ev) {
  900. goDoCommand("cmd_scrollTop");
  901. }, 'Scroll to the top of the page', true);
  902. key.setViewKey(['C-c', 'g', 't'], function (ev) {
  903. getBrowser().mTabContainer.advanceSelectedTab(1, true);
  904. }, 'Select next tab');
  905. key.setViewKey(['C-c', 'g', 'T'], function (ev) {
  906. getBrowser().mTabContainer.advanceSelectedTab(-1, true);
  907. }, 'Select previous tab');
  908. key.setViewKey(['C-c', 'g', 'i'], function (ev) {
  909. command.focusElement(command.elementsRetrieverTextarea, 0);
  910. }, 'Focus to the first textarea', true);
  911. key.setViewKey([['C-c', 'G'], ['M->']], function (ev) {
  912. goDoCommand("cmd_scrollBottom");
  913. }, 'Scroll to the bottom of the page', true);
  914. key.setViewKey(['C-c', 'r'], function (ev) {
  915. BrowserReload();
  916. }, 'Reload the page', true);
  917. key.setViewKey(['C-c', 'h'], function (ev) {
  918. BrowserBack();
  919. }, 'Back');
  920. key.setViewKey(['C-c', 'l'], function (ev) {
  921. BrowserForward();
  922. }, 'Forward');
  923. key.setViewKey(['C-x', 'k'], function (ev) {
  924. BrowserCloseTabOrWindow();
  925. }, 'Close tab / window');
  926. key.setViewKey('C-f', function (ev) {
  927. key.generateKey(ev.originalTarget, KeyEvent.DOM_VK_RIGHT, true);
  928. }, 'Scroll right');
  929. key.setViewKey(['C-c', 'z', 'i'], function (ev) {
  930. FullZoom.enlarge();
  931. }, 'Enlarge text size');
  932. key.setViewKey(['C-c', 'z', 'o'], function (ev) {
  933. FullZoom.reduce();
  934. }, 'Reduce text size');
  935. key.setViewKey('M-v', function (ev) {
  936. goDoCommand("cmd_scrollPageUp");
  937. }, 'Scroll page up');
  938. key.setViewKey('C-v', function (ev) {
  939. goDoCommand("cmd_scrollPageDown");
  940. }, 'Scroll page down');
  941. key.setViewKey(['C-x', 'h'], function (ev) {
  942. goDoCommand("cmd_selectAll");
  943. }, 'Select all', true);
  944. key.setViewKey('M-p', function (ev) {
  945. command.walkInputElement(command.elementsRetrieverButton, true, true);
  946. }, 'Focus to the next button');
  947. key.setViewKey('M-n', function (ev) {
  948. command.walkInputElement(command.elementsRetrieverButton, false, true);
  949. }, 'Focus to the previous button');
  950. key.setViewKey('M-<down>', function (ev, arg) {
  951. var backForwardMenu = document.getElementById("backForwardMenu");
  952. backForwardMenu.openPopupAtScreen(document.width / 2, document.height / 2, true);
  953. }, 'Show page history menu');
  954. key.setViewKey('<backspace>', function (ev) {
  955. BrowserBack();
  956. }, 'Back to last page in history.');
  957. //** f3: related to selection
  958. key.setViewKey(['<f3>', 'j'], function (ev, arg) {
  959. ext.exec("highlight-all", arg, ev);
  960. }, 'highlight all occurences of current selected word');
  961. key.setViewKey(['<f3>', '*'], function (ev, arg) {
  962. ext.exec("next-occur", arg, ev);
  963. }, 'highlight next occurence of current selected word');
  964. key.setViewKey(['<f3>', '#'], function (ev, arg) {
  965. ext.exec("previous-occur", arg, ev);
  966. }, 'highlight previous occurence of current selected word');
  967. key.setViewKey(['<f3>', 'q'], function (ev, arg) {
  968. ext.exec("search-selection", arg, ev);
  969. }, 'Search the selection with current default engine');
  970. key.setViewKey(['<f3>', 'd'], function(ev, arg) {
  971. ext.exec('dict', arg, ev);
  972. }, "Query selection with Dict protocol (requires Dict extension)");
  973. key.setViewKey(['<f3>', 'w'], function(ev, arg) {
  974. ext.exec('wiktionary-lookup-selection', arg, ev);
  975. }, "Translation selection with Wiktionary & Google Translate.");
  976. key.setViewKey(['<f3>', 'g'], function(ev, arg) {
  977. ext.exec('go-to-selected-url', arg, ev);
  978. }, "Go to selected URL.");
  979. key.setViewKey(['<f3>', 'C-T'], function(ev, arg) {
  980. var sel = getBrowserSelection();
  981. if (sel) {
  982. splitpannel.toggle("http://translate.google.com/m?hl=zh-CN&sl=auto&tl=en&ie=UTF-8&q=" + encodeURIComponent(sel), true, 'right');
  983. }
  984. }, 'Translate selection to English and show result in Split Panel.');
  985. key.setViewKey(['<f3>', 'C-t'], function(ev, arg) {
  986. var sel = getBrowserSelection();
  987. if (sel) {
  988. splitpannel.toggle("http://translate.google.com/m?hl=zh-CN&sl=auto&tl=zh-CN&ie=UTF-8&q=" + encodeURIComponent(sel), true, 'right');
  989. }
  990. }, 'Translate selection to Chinese and show result in Split Panel.');
  991. //** misc user commands
  992. key.setViewKey(['C-c', 'i'], function (ev, arg) {
  993. //stolen from keysnail's vi-style configuration
  994. children = document.getElementById("nav-bar").children;
  995. for (i = 0; i < children.length; i++) {
  996. children[i].style.backgroundColor = "pink";
  997. }
  998. util.setBoolPref("accessibility.browsewithcaret", !util.getBoolPref("accessibility.browsewithcaret"));
  999. }, 'Enter caret mode');
  1000. key.setViewKey(['C-c', ':'], function (ev, arg) {
  1001. shell.input(null, arg);
  1002. }, 'List and execute commands', true);
  1003. key.setViewKey(['C-c', 'C-a'], function (ev, arg) {
  1004. ext.exec('increase-digit-in-url', arg, ev);
  1005. }, 'Increase last digit in the URL (go to next page)');
  1006. key.setViewKey(['C-c', 'C-d'], function (ev, arg) {
  1007. ext.exec('decrease-digit-in-url', arg, ev);
  1008. }, 'Decrease last digit in the URL (go to prev page)');
  1009. key.setViewKey(['[', '['], function (ev, arg) {
  1010. ext.exec("previous-page", arg, ev);
  1011. }, 'Previous page');
  1012. key.setViewKey([']', ']'], function (ev, arg) {
  1013. ext.exec("next-page", arg, ev);
  1014. }, 'Next page');
  1015. //* caret mode
  1016. key.setCaretKey([['C-c', 'i'], ['ESC']], function (ev, arg) {
  1017. children = document.getElementById("nav-bar").children;
  1018. for (i = 0; i < children.length; i++) {
  1019. children[i].style.backgroundColor = "transparent";
  1020. }
  1021. util.setBoolPref("accessibility.browsewithcaret", false);
  1022. }, 'Exit caret mode');
  1023. key.setCaretKey(['C-c', ';'], function (ev) {
  1024. ext.exec("hok-start-extended-mode", ev);
  1025. }, 'Start Hit a Hint extended mode');
  1026. key.setCaretKey([['C-a'], ['^']], function (ev) {
  1027. ev.target.ksMarked ? goDoCommand("cmd_selectBeginLine") : goDoCommand("cmd_beginLine");
  1028. }, 'Move caret to the beginning of the line');
  1029. key.setCaretKey('C-e', function (ev) {
  1030. ext.exec("hok-start-continuous-mode", ev);
  1031. }, 'Start Hit a Hint continuous mode');
  1032. key.setCaretKey([['$'], ['M->'], ['G']], function (ev) {
  1033. ev.target.ksMarked ? goDoCommand("cmd_selectEndLine") : goDoCommand("cmd_endLine");
  1034. }, 'Move caret to the end of the line');
  1035. key.setCaretKey([['C-n'], ['j']], function (ev) {
  1036. ev.target.ksMarked ? goDoCommand("cmd_selectLineNext") : goDoCommand("cmd_scrollLineDown");
  1037. }, 'Move caret to the next line');
  1038. key.setCaretKey([['C-p'], ['k']], function (ev) {
  1039. ev.target.ksMarked ? goDoCommand("cmd_selectLinePrevious") : goDoCommand("cmd_scrollLineUp");
  1040. }, 'Move caret to the previous line');
  1041. key.setCaretKey([['C-f'], ['l']], function (ev) {
  1042. ev.target.ksMarked ? goDoCommand("cmd_selectCharNext") : goDoCommand("cmd_scrollRight");
  1043. }, 'Move caret to the right');
  1044. key.setCaretKey([['C-b'], ['h'], ['C-h']], function (ev) {
  1045. ev.target.ksMarked ? goDoCommand("cmd_selectCharPrevious") : goDoCommand("cmd_scrollLeft");
  1046. }, 'Move caret to the left');
  1047. key.setCaretKey([['M-f'], ['w']], function (ev) {
  1048. ev.target.ksMarked ? goDoCommand("cmd_selectWordNext") : goDoCommand("cmd_wordNext");
  1049. }, 'Move caret to the right by word');
  1050. key.setCaretKey([['M-b'], ['W']], function (ev) {
  1051. ev.target.ksMarked ? goDoCommand("cmd_selectWordPrevious") : goDoCommand("cmd_wordPrevious");
  1052. }, 'Move caret to the left by word');
  1053. key.setCaretKey([['C-v'], ['SPC']], function (ev) {
  1054. ev.target.ksMarked ? goDoCommand("cmd_selectPageNext") : goDoCommand("cmd_movePageDown");
  1055. }, 'Move caret down by page');
  1056. key.setCaretKey([['M-v'], ['b']], function (ev) {
  1057. ev.target.ksMarked ? goDoCommand("cmd_selectPagePrevious") : goDoCommand("cmd_movePageUp");
  1058. }, 'Move caret up by page');
  1059. key.setCaretKey([['M-<'], ['g']], function (ev) {
  1060. ev.target.ksMarked ? goDoCommand("cmd_selectTop") : goDoCommand("cmd_scrollTop");
  1061. }, 'Move caret to the top of the page');
  1062. key.setCaretKey('J', function (ev) {
  1063. util.getSelectionController().scrollLine(true);
  1064. }, 'Scroll line down');
  1065. key.setCaretKey('K', function (ev) {
  1066. util.getSelectionController().scrollLine(false);
  1067. }, 'Scroll line up');
  1068. key.setCaretKey(',', function (ev) {
  1069. util.getSelectionController().scrollHorizontal(true);
  1070. goDoCommand("cmd_scrollLeft");
  1071. }, 'Scroll left');
  1072. key.setCaretKey('.', function (ev) {
  1073. goDoCommand("cmd_scrollRight");
  1074. util.getSelectionController().scrollHorizontal(false);
  1075. }, 'Scroll right');
  1076. key.setCaretKey('z', function (ev) {
  1077. command.recenter(ev);
  1078. }, 'Scroll to the cursor position');
  1079. key.setCaretKey([['C-SPC'], ['C-@']], function (ev) {
  1080. command.setMark(ev);
  1081. }, 'Set the mark', true);
  1082. key.setCaretKey(':', function (ev, arg) {
  1083. shell.input(null, arg);
  1084. }, 'List and execute commands', true);
  1085. key.setCaretKey('R', function (ev) {
  1086. BrowserReload();
  1087. }, 'Reload the page', true);
  1088. key.setCaretKey('B', function (ev) {
  1089. BrowserBack();
  1090. }, 'Back');
  1091. key.setCaretKey('F', function (ev) {
  1092. ext.exec("hok-start-background-mode", ev);
  1093. }, 'Start Hit a Hint background mode');
  1094. key.setCaretKey(['C-x', 'h'], function (ev) {
  1095. goDoCommand("cmd_selectAll");
  1096. }, 'Select all', true);
  1097. key.setCaretKey('f', function (ev) {
  1098. ext.exec("hok-start-foreground-mode", ev);
  1099. }, 'Start Hit a Hint foreground mode');
  1100. key.setCaretKey('M-p', function (ev) {
  1101. command.walkInputElement(command.elementsRetrieverButton, true, true);
  1102. }, 'Focus to the next button');
  1103. key.setCaretKey('M-n', function (ev) {
  1104. command.walkInputElement(command.elementsRetrieverButton, false, true);
  1105. }, 'Focus to the previous button');
  1106. //* edit mode
  1107. key.setEditKey(['C-x', 'h'], function (ev) {
  1108. command.selectAll(ev);
  1109. }, 'Select whole text', true);
  1110. key.setEditKey([['C-x', 'u'], ['C-_']], function (ev) {
  1111. display.echoStatusBar("Undo!", 2000);
  1112. goDoCommand("cmd_undo");
  1113. }, 'Undo');
  1114. key.setEditKey([['C-x', 'U'], ['M-_']], function (ev) {
  1115. display.echoStatusBar("Redo!", 2000);
  1116. goDoCommand("cmd_redo");
  1117. }, 'Redo');
  1118. key.setEditKey(['C-x', 'r', 'd'], function (ev, arg) {
  1119. command.replaceRectangle(ev.originalTarget, "", false, !arg);
  1120. }, 'Delete text in the region-rectangle', true);
  1121. key.setEditKey(['C-x', 'r', 't'], function (ev) {
  1122. prompt.read("String rectangle: ", function (aStr, aInput) {command.replaceRectangle(aInput, aStr);}, ev

Large files files are truncated, but you can click here to view the full file