NetxPage:
try { var node = FireGestures.sourceNode; } catch (e) {} while (node && node.nodeName != "BODY") node = node.parentNode; if (!node) node = getBrowser().contentDocument; var e = document.createEvent("KeyboardEvent"); e.initKeyEvent("keydown", true, true, window, false, false, false, false, 39, 0); node.dispatchEvent(e);
PrePage:
try { var node = FireGestures.sourceNode; } catch (e) {} while (node && node.nodeName != "BODY") node = node.parentNode; if (!node) node = getBrowser().contentDocument; var e = document.createEvent("KeyboardEvent"); e.initKeyEvent("keydown", true, true, window, false, false, false, false, 37, 0); node.dispatchEvent(e);
IsDownLoadDirChanged:
var pref="browser.download.useDownloadDir"; var PS = Components.classes['@mozilla.org/preferences-service;1'] .getService(Components.interfaces.nsIPrefBranch); PS.setBoolPref(pref,!PS.getBoolPref(pref)); if (PS.getBoolPref(pref) == true){ alert('Set to true'); }else{ alert('Set to false'); }
PS:配合翻页手势,需要GreaseMonkey的nextpage脚本。
// This is a greasemonkey script, for use with the Firefox extension Greasemonkey. // More info: http://greasemonkey.mozdev.org/ // // ==UserScript== // @name Next Page // @author Sunwan // @version 0.1.7.3 // @namespace http://www.zjcnnj.cn/mozilla/greasemonkey/ // @description 使用左右方向键来翻页 [Ver 0.1.7.3] // @include http://* // @include https://* // ==/UserScript== (function() { var checked = false; var delay = false; var next = {}; var previous = {}; // 下一页链接里的文字 next.texts = [ 'next', 'next page', 'old', 'older', 'earlier', '下页', '下頁', '下一页', '下一頁', '后一页', '后一頁', '翻下页', '翻下頁', '后页', '后頁', '下翻', '下一个', '下一张', '下一幅', '下一节', '下一章', '下一篇', '后一章', '后一篇' ]; // 上一页链接里的文字 previous.texts = [ 'previous', 'prev', 'previous page', 'new', 'newer', 'later', '上页', '上頁', '上一页', '上一頁', '前一页', '前一頁', '翻上页', '翻上頁', '前页', '前頁', '上翻', '上一个', '上一张', '上一幅', '上一节', '上一章', '上一篇', '前一章', '前一篇' ]; // 可能会误判的关键词 next.miswords = { "下一章": 30, "下一篇": 30, "后一章": 30, "后一篇": 30, "下一节": 30, ">>": 2000, "»": 2000 } previous.miswords = { "上一章": 30, "上一篇": 30, "前一章": 30, "前一篇": 30, "上一节": 30, "<<": 2000, "«": 2000 } // 取得自定义关键词 getCustom(next, "next"); getCustom(previous, "previous"); // 注册脚本菜单 registerMenu("next"); registerMenu("previous"); // 最后添加一些论坛使用的翻页符号 next.texts.push(">>"); next.texts.push(">"); next.texts.push("»"); next.texts.push("›"); previous.texts.push("<<"); previous.texts.push("<"); previous.texts.push("«"); previous.texts.push("‹"); // 翻页文字的前面和后面可能包含的字符(正则表达式) var preRegexp = '(^\\s*(?:[<‹«]*|[>›»]*|[\\(\\[『「[【]?)\\s*)'; var nextRegexp = '(\\s*(?:[>›»]*|[\\)\\]』」]】]?)\\s*$)'; // 取得并设置自定义关键词 function getCustom(aObj, key) { var site, re; var cKeyWords = GM_getValue("custom_" + key, ""); var words = cKeyWords.split(/,|,/); for each (var w in words) { site = null; if (/^\s*{\s*(\S*?)\s*}(.*)$/.test(w)) { site = RegExp.$1; w = RegExp.$2; site = site.replace(/[\/\?\.\(\)\+\-\[\]\$]/g, "\\$&").replace(/\*/g, "\.*"); } w = w.replace(/\\/g, "\\").replace(/^\s+|\s+$/g, ""); if (w) { if (site) { re = eval('/' + site + '/i'); if (re.test(location.href)) aObj.texts.push(w); } else aObj.texts.push(w); } } } // 注册菜单 function registerMenu(key) { if (navigator.language == "zh-CN") { var word = key == "next" ? "下一页" : "上一页"; GM_registerMenuCommand("Next Page " + word + "关键词", function(){setCustom(key, word)}); } else { GM_registerMenuCommand("Next Page custom_" + key, function(){setCustom(key, key)}); } } // 设置新的关键词 function setCustom(k, w) { var text = navigator.language == "zh-CN" ? "请输入“"+w+"”的关键词,以“,”号分隔开。" : "Please enter the "+w+" page key-words, split with ','."; var result = prompt(text, GM_getValue("custom_" + k, "")); if (result != null) GM_setValue("custom_" + k, result); } function checkLinks() { var link, text, ldnc, lnc, ldpc, lpc, num, digCurFound, linkNumber, found, tmpNode; var regexp = new RegExp(); // 查找相应的链接 var links = document.getElementsByTagName('A'); for (var i = 0; i < links.length; i++) { link = links[i]; // 跳过不起作用的链接 if (!link.offsetParent || link.offsetWidth == 0 || link.offsetHeight == 0 || !link.hasAttribute("href") && !link.hasAttribute("onclick")) continue; // 跳过日历 if (/(?:^|\s)(?:monthlink|weekday|day|day[\-_]\S+)(?:\s|$)/i.test(link.className)) continue; if (/^nextlink/i.test(link.id) || /^linknext/i.test(link.id) || /(^|\s)nextlink/i.test(link.className) || /(^|\s)linknext/i.test(link.className)) next.link = link; if (/^prev(ious)?link/i.test(link.id) || /^linkprev(ious)?/i.test(link.id) || /(^|\s)prev(ious)?link/i.test(link.className) || /(^|\s)linkprev(ious)?/i.test(link.className)) previous.link = link; text = link.textContent; if (!text) { // 若链接中没有文字,则检查图片的alt属性、链接或图片的title for each (var img in link.childNodes) { if (img.localName == "IMG") { text = img.alt || link.title || img.title; if (text) break; } } if (!text) continue; } text = text.toLowerCase().replace(/^\s+|\s+$/g, ""); if (!text) continue; // 纯数字链接 if (isDigital(text)) { if (digCurFound) continue; linkNumber = parseInt(RegExp.$1); // 检测下一个位置是否是当前页面的页数 if ((tmpNode = getCurrentPageNode(link, linkNumber, 1)) && tmpNode) { digCurFound = true; previous.link = link; previous.found = true; previous.pos = i; // 再检测下下一个位置是否是“下一页”的链接 if (getNextLink(tmpNode, linkNumber+2, true)) break; // 设置往后的30个位置以内为“下一页”的可能链接,以提高检测速度。 ldnc = i + 30; } // 检测上一个位置是否是当前页面的页数 else if (getCurrentPageNode(link, linkNumber, -1)) { digCurFound = true; next.link = link; next.found = true; next.pos = i; ldpc = i + 30; continue; } // 检测自身是否是当前页面的页数 else if (getCurrentPageNode(link, linkNumber, 0)) { digCurFound = true; // 再检测下一个位置是否是“下一页”的链接 if (getNextLink(link, linkNumber+1, true)) { next.pos = i; ldpc = i + 30; continue; } // 设置往后的30个位置以内为“下一页”的可能链接,以提高检测速度。 ldnc = i + 30; } continue; } else { found = false; if (!next.found && !(lnc < i) && !(ldnc < i)) { for (var j = 0; j < next.texts.length; j++) { if (regexp.compile(preRegexp + next.texts[j] + nextRegexp, 'i').test(text)) { // 检测到“下一页”的链接 found = true; next.link = link; num = next.miswords[next.texts[j]]; // 若“下一页”的词语有可能会误判时,最多再检测预定个数的链接。 (num == null) ? next.found = true : lnc = i + num; break; } } } if (!next.digital && lnc < i) next.found = true; if (!found && !previous.found && !(lpc < i) && !(ldpc < i)) { for (var j = 0; j < previous.texts.length; j++) { if (regexp.compile(preRegexp + previous.texts[j] + nextRegexp, 'i').test(text)) { // 检测到“上一页”的链接 previous.link = link; num = previous.miswords[previous.texts[j]]; // 若“上一页”的词语有可能会误判时,最多再检测预定个数的链接。 (num == null) ? previous.found = true : lpc = i + num; break; } } } if (lpc < i) previous.found = true; // 重新设置纯数字链接未被检查 digCurFound = null; } // 找到“上一页”和“下一页”的链接或找到其中一个而另一个超过规定范围没找到,将不再查找。 if (next.found && previous.found || next.found && i > next.pos + 30 || previous.found && i > previous.pos + 30) break; } // 通过以上方法没有找到“下一页”的,把第一次检测出来的数字1的链接作为当前页,2作为“下一页”。 if (!next.found /*&& !next.link*/ && next.digital) next.link = next.digital; if (next.link) next.found = true; if (previous.link) previous.found = true; if (!next.found && !previous.found) checkButtons(); } // 检查翻页按钮 function checkButtons() { var but, text, found; var regexp = new RegExp(); var buts = document.getElementsByTagName('INPUT'); for (var i = 0; i < buts.length; i++) { but = buts[i]; if (but.hasAttribute("disabled") || !(/^button$/i.test(but.type) && but.getAttribute("onclick"))) continue; text = but.value; found = false; if (!next.found) { for (var j = 0; j < next.texts.length; j++) { if (regexp.compile(preRegexp + next.texts[j] + nextRegexp, 'i').test(text)) { // 检测到“下一页”的按钮 next.link = but; next.found = found = true; break; } } } if (!found && !previous.found) { for (var j = 0; j < previous.texts.length; j++) { if (regexp.compile(preRegexp + previous.texts[j] + nextRegexp, 'i').test(text)) { // 检测到“上一页”的按钮 previous.link = but; previous.found = true; break; } } } if (next.found && previous.found) break; } } // 取得相邻的纯数字节点,type: 1 下一个;-1 上一个 function getSiblingNode(node, type) { if (!node) return null; node = getSibling(node, type); while (node && (node.nodeName == "#coment" || (/^\s*[\]]】]?[,\|]?\s*[\[[【]?\s*$/.test(node.textContent)))) node = getSibling(node, type); return node; } function getSibling(aNode, type) { if (!aNode) return null; if (isOnlyNode(aNode)) { try { aNode = (type == 1 ? aNode.parentNode.nextSibling : aNode.parentNode.previousSibling); if (skipNode(aNode)) aNode = (type == 1 ? aNode.nextSibling : aNode.previousSibling); aNode = aNode.childNodes[0]; if (skipNode(aNode)) aNode = aNode.nextSibling; } catch (e) {return null;} } else { aNode = (type == 1 ? aNode.nextSibling : aNode.previousSibling); } return aNode; } function isOnlyNode(n) { return !n.nextSibling && !n.previousSibling || !n.nextSibling && skipNode(n.previousSibling) && !n.previousSibling.previousSibling || !n.previousSibling && skipNode(n.nextSibling) && !n.nextSibling.nextSibling || skipNode(n.previousSibling) && !n.previousSibling.previousSibling && skipNode(n.nextSibling) && !n.nextSibling.nextSibling; } function skipNode(sNode) { return sNode && /*sNode.nodeName == "#text" &&*/ (/^\s*$/.test(sNode.textContent)); } // 检测是否有下一页的纯数字链接,number:页数 function getNextLink(node, number, set) { var tNode = getSiblingNode(node, 1); if (tNode && tNode.nodeName == "A" && isDigital(tNode.textContent)) { if (RegExp.$1 == number) { // 找到纯数字链接 if (set) { next.link = tNode; next.found = true; } return tNode; } } return null; } function isDigital(str, t) { str = str.replace(/^\s+|\s+$/g, ""); if (t == -1) str = str.split(/\s+/).pop(); else if (t == 1) str = str.split(/\s+/)[0]; return (/^(\d+)$/.test(str)) || (/^\[\s?(\d+)\s?\]$/.test(str)) || (/^【\s?(\d+)\s?】$/.test(str)) || (/^[\s?(\d+)\s?]$/.test(str)) || (/^<\s?(\d+)\s?>$/.test(str)); } // 判断是否是当前页面的数字,type:-1,0,1 分别是要判别的上一个、当前、下一个节点 function getCurrentPageNode(node, linkNum, type) { var tNode; if (type == 0) { tNode = getSiblingNode(node, 1) || getSiblingNode(node, -1); if (!tNode) return null; if (!node.hasAttribute("onclick") && node.href != tNode.href && (!node.hasAttribute("href") && isDigital(node.textContent, type) || !(/\/#[^\/]+$/.test(node.href)) && node.href == location.href && isDigital(node.textContent, type))) { if (linkNum > 0 && RegExp.$1 == linkNum) return node; } // 某些论坛处在第一页时,实际链接和当前页链接不符,只有和其余纯数字链接的结构或颜色不同时, // 才使用纯数字的“2”作为“下一页”的链接。 else if (!next.digital && (/^\s*[\[[【]?1[\]]】]?\s*$/.test(node.textContent))) { var two = getNextLink(node, 2); if (two && difDigital(node, two)) next.digital = two; } } else { tNode = getSiblingNode(node, type); if (!tNode) return null; if (tNode.nodeName != "A" && isDigital(tNode.textContent, type) || tNode.nodeName == "A" && !tNode.hasAttribute("onclick") && node.href != tNode.href && (!tNode.hasAttribute("href") && isDigital(tNode.textContent, type) || !(/\/#[^\/]+$/.test(tNode.href)) && tNode.href == location.href && isDigital(tNode.textContent, type))) { var n = linkNum + type; if (n > 0 && RegExp.$1 == n) { if (next.digital) next.digital = null; return tNode; } } } return null; } function difDigital(node1, node2) { if (getStructure(node1) == getStructure(node2) && getStyleColor(node1) == getStyleColor(node2)) return false; return true; } function getStructure(aNode) { return aNode.innerHTML.replace(/\d+/, ""); } function getStyleColor(aNode) { return document.defaultView.getComputedStyle(aNode, null).getPropertyValue("color"); } function openLink(linkNode) { if (!linkNode) return; var hf = linkNode.getAttribute("href"); if (!linkNode.hasAttribute("onclick") && hf && !(/^#/.test(hf)) && linkNode.href != location.href) { cleanVars(); location.assign(linkNode.href); } else { // 有些4D鼠标摆动一下滚轮会触发多下的方向键,故增设一个延迟参数,使它只翻一页。 delay = true; setTimeout(cleanVars, 300); var e = document.createEvent("MouseEvents"); e.initMouseEvent("click", 1, 1, window, 1, 0,0,0,0,0,0,0,0,0, linkNode); linkNode.dispatchEvent(e); } } function cleanVars() { try { checked = false; delay = false; next.link = next.found = next.digital = null; previous.link = previous.found = previous.digital = null; delete next.pos; delete previous.pos; } catch(e) {} } function onKeyDown(event) { // 不是左右方向建被按下或不到延迟时间则退出 if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey || event.keyCode != 37 && event.keyCode != 39 || delay) return // 确保光标不是定位在文字输入框或选择框 var localName = event.target.localName; if (localName == 'TEXTAREA' || localName == 'INPUT' || localName == 'SELECT') return; // 检查过且没有发现上一页或下一页的连接,则退出 if (checked && !next.found && !previous.found) return; if (!checked) { checkLinks(); checked = true; } if (event.keyCode == 37 && previous.found) { // 左方向键,跳到“上一页” openLink(previous.link) } else if (event.keyCode == 39 && next.found) { // 右方向键,跳到“下一页” openLink(next.link) } } window.addEventListener("keydown", function(e){onKeyDown(e)}, true); })();