Created
February 22, 2010 22:02
-
-
Save alexeyr/311567 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// $Id: nextpleaseOverlay.js,v 1.4 2010/02/07 Alexey Romanov $ | |
Components.utils.import("resource://nextplease/nextpleaseGlobals.js"); | |
nextplease.DEBUG = false; | |
nextplease.DEBUG_WITH_ALERTS = false; | |
nextplease.useSubmit = false; | |
nextplease.useNumberShortcuts = true; | |
nextplease.useContextMenu = true; | |
nextplease.useSmartNext = false; | |
nextplease.MAX_LINK_NUM = 700; | |
nextplease.MAX_GALLERY_GAP = 20; | |
nextplease.MAX_IMAGE_CACHE = 500; | |
nextplease.DefaultNextPhrases = ["Next", "next", "Next >", "next >", ">", "MORE RESULTS", "Newer ÿÏÍ", "Older topics ÿÏÍ", "next page", "Go to the next photo in the stream"]; | |
nextplease.DefaultPrevPhrases = ["Previous", "previous", "Prev", "prev", "< Previous", "< previous", | |
"PREVIOUS RESULTS", "< Prev", "< prev", "<", "<< Prev", "ÿÏÍ Older", "ÿÏÍ Newer topics", "previous page", "Go to the previous photo in the stream"]; | |
nextplease.DefaultFirstPhrases = ["First", "first", "< First", "< first", "first page", "ÿÏÍ first"]; | |
nextplease.DefaultLastPhrases = ["Last", "last", "Last >", "last >", "last page", "last ÿÏÍ"]; | |
nextplease.DefaultNextImages = ["http://g-images.amazon.com/images/G/01/search-browse/button-more-results.gif"]; | |
nextplease.DefaultPrevImages = ["http://g-images.amazon.com/images/G/01/search-browse/button-previous.gif"]; | |
nextplease.DefaultFirstImages = []; | |
nextplease.DefaultLastImages = []; | |
nextplease.imageLocationMap = {}; | |
nextplease.imageLocationArray = []; | |
// changed ÒŽchevronsÒË to \\xab and \\xbb - v1.31 | |
nextplease.DefaultNextRegEx = "^next(\\s+\\d+)?(\\s+\\w+)?\\s*((>?>?)|\\xbb)\\s*\$"; | |
nextplease.DefaultPrevRegEx = "^((<?<?)|\\xab)\\s*((prev(ious)?(\\s+\\d+)?(\\s+\\w+)?)|back)\\s*\$"; | |
nextplease.DefaultFirstRegEx = "^((<?<?)|\\xab)\\s*(first(\\s+\\d+)?(\\s+\\w+)?)\\s*$"; | |
nextplease.DefaultLastRegEx = "^last(\\s+\\d+)?(\\s+\\w+)?\\s*((>?>?)|\\xbb)\\s*$"; | |
// var nextplease.DefaultNextRegEx = "^next(\\s+\\d+)?(\\s+\\w+)?\\s*((>?>?)|ÿÏÍ|\\xbb)\\s*\$"; | |
// var nextplease.DefaultPrevRegEx = "^((<?<?)|ÿÏÍ|\\xab)\\s*((prev(ious)?(\\s+\\d+)?(\\s+\\w+)?)|back)\\s*\$"; | |
// var nextplease.DefaultFirstRegEx = "^((<?<?)|ÿÏÍ|\\xab)\\s*(first(\\s+\\d+)?(\\s+\\w+)?)\\s*$"; | |
// var nextplease.DefaultLastRegEx = "^last(\\s+\\d+)?(\\s+\\w+)?\\s*((>?>?)|ÿÏÍ|\\xbb)\\s*$"; | |
// var OldDefaultGalleryRegEx = ".*?(\\d+)[^/]*?\\.(?:jpg|gif|bmp|png)$"; | |
nextplease.DefaultGalleryRegEx = "(.*(?:[^\\d]|^))(\\d+)([^/]*?\\.(?:jpg|gif|bmp|png))$"; | |
nextplease.NEXT_SEARCH_TYPE = 1; | |
nextplease.PREV_SEARCH_TYPE = 2; | |
nextplease.FIRST_SEARCH_TYPE = 3; | |
nextplease.LAST_SEARCH_TYPE = 4; | |
// This code was stolen from brody on the mozillazine.org forums. | |
nextplease.loadListener = { | |
dumpToConsole: false, | |
enableAlerts: false, | |
fireBeforeImagesLoaded: true, | |
topLevelDocumentsOnly: true, | |
onLoad: function (event) { | |
this.consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService); | |
this.promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService); | |
if (this.fireBeforeImagesLoaded) this.loadType = "DOMContentLoaded"; | |
else this.loadType = "load"; | |
gBrowser.addEventListener(this.loadType, function (event) { | |
nextplease.loadListener.onContentLoaded(event); | |
}, | |
true); | |
}, | |
onContentLoaded: function (event) { | |
var doc = event.originalTarget; | |
// Only for top level documents and not subframes? | |
if (this.topLevelDocumentsOnly) { | |
// When this becomes true it means that | |
// all of the top level document's | |
// subframes have also finished loading | |
if (!this.isTopLevelDocument(doc)) return; | |
} | |
// Log/alert | |
var eol = this.getEol(); | |
var message = this.loadType + eol + doc.title + eol + doc.documentURI; | |
if (this.dumpToConsole) { | |
this.consoleService.logStringMessage("nextplease.loadListener" + eol + message); | |
} | |
if (this.enableAlerts) { | |
this.promptService.alert(window, "nextplease.loadListener", message); | |
} | |
nextplease.cacheImageLocations(); | |
// Get the browser for the document (if required) | |
var browser = this.getBrowserForDocument(doc); | |
if (!browser) return; | |
// If you have enabled topLevelDocuments only and | |
// want to get all documents contained in the browser | |
// for processing, do it like so | |
// var documents = this.getDocuments(browser.contentWindow, []); | |
}, | |
isTopLevelDocument: function (aDocument) { | |
var browsers = gBrowser.browsers; | |
for (var i = 0; i < browsers.length; i++) { | |
if (aDocument == browsers[i].contentDocument) return true; | |
} | |
return false; | |
}, | |
getDocuments: function (aFrame, aArray) { | |
const frames = aFrame.frames; | |
aArray.push(aFrame.document); | |
for (var i = 0; i < frames.length; i++) this.getDocuments(frames[i], aArray); | |
return aArray; | |
}, | |
getBrowserForDocument: function (aDocument) { | |
// This function can return the browser for not only top level documents | |
// but also documents contained in subframes | |
// If the document is top level then return its browser here | |
var browsers = gBrowser.browsers; | |
for (var i = 0; i < browsers.length; i++) { | |
if (aDocument == browsers[i].contentDocument) return browsers[i]; | |
} | |
// Else it must be in a subframe, so check all frames in each browser | |
// to find the parent browser | |
var documents; | |
for (var j = 0; j < browsers.length; j++) { | |
documents = this.getDocuments(browsers[j].contentWindow, []); | |
for (var k = 0; k < documents.length; k++) { | |
if (aDocument == documents[k]) return browsers[j]; | |
} | |
} | |
// Else the browser could not be determined | |
return null; | |
}, | |
getPlatform: function () { | |
var platform = navigator.platform.toLowerCase(); | |
if (platform.indexOf('win') != -1) return 'win'; // win | |
else if (platform.indexOf('mac') != -1) return 'mac'; // mac | |
else return 'other'; // other (nix) | |
}, | |
getEol: function () { | |
switch (this.getPlatform()) { | |
case 'win': | |
return '\r\n'; | |
case 'mac': | |
return '\r'; | |
case 'other': | |
return '\n'; | |
default: | |
return '<eol>'; | |
} | |
} | |
}; | |
// Strip leading and trailing whitespace from | |
// the passed in string and return it. | |
nextplease.Trim = function (str) { | |
return str.replace(/^\s*|\s*$/g, ""); | |
} | |
nextplease.SetUnicharPref = function (aPrefName, aPrefValue) { | |
if (nextplease.prefs) { | |
try { | |
var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString); | |
str.data = aPrefValue; | |
nextplease.prefs.setComplexValue(aPrefName, Components.interfaces.nsISupportsString, str); | |
} | |
catch(e) {} | |
} | |
} | |
nextplease.GetUnicharPref = function (aPrefName) { | |
if (nextplease.prefs) { | |
try { | |
return nextplease.prefs.getComplexValue(aPrefName, Components.interfaces.nsISupportsString).data; | |
} | |
catch(e) {} | |
} | |
return ""; | |
} | |
// Read the phrases that specify a next link | |
// by reading the preferences or defaults, | |
// and put the phrases in a lookup table. | |
nextplease.initializeNextPrevMap = function (prefbranch, DefaultArray) { | |
var map = {}; | |
var tempprefname = prefbranch + '.expr0'; | |
if (nextplease.prefs.prefHasUserValue(tempprefname)) { | |
var k = 0; | |
while (nextplease.prefs.prefHasUserValue(tempprefname)) { | |
// var phrase = nextplease.prefs.getCharPref(tempprefname); | |
var prefValue = nextplease.GetUnicharPref(tempprefname); | |
var values = prefValue.split("|"); | |
for (var j = 0; j < values.length; j++) { | |
var phrase = values[j].replace(/&pipe;/g, "|"); | |
if (phrase != '') { | |
map[phrase] = true; | |
} | |
} | |
k++; | |
tempprefname = prefbranch + '.expr' + k; | |
} | |
} else { | |
for (var i = 0; i < DefaultArray.length; i++) { | |
map[DefaultArray[i]] = true; | |
} | |
} | |
return map; | |
} | |
// Initialize the lookup table for keycode to keyname | |
nextplease.initializeKeyCodeToStringMap = function () { | |
var map = {}; | |
map[KeyEvent.DOM_VK_LEFT] = "VK_LEFT"; | |
map[KeyEvent.DOM_VK_RIGHT] = "VK_RIGHT"; | |
map[KeyEvent.DOM_VK_UP] = "VK_UP"; | |
map[KeyEvent.DOM_VK_DOWN] = "VK_DOWN"; | |
map[KeyEvent.DOM_VK_PAGE_UP] = "VK_PAGE_UP"; | |
map[KeyEvent.DOM_VK_PAGE_DOWN] = "VK_PAGE_DOWN"; | |
map[KeyEvent.DOM_VK_HOME] = "VK_HOME"; | |
map[KeyEvent.DOM_VK_END] = "VK_END"; | |
map[KeyEvent.DOM_VK_F1] = "VK_F1"; | |
map[KeyEvent.DOM_VK_F2] = "VK_F2"; | |
map[KeyEvent.DOM_VK_F3] = "VK_F3"; | |
map[KeyEvent.DOM_VK_F4] = "VK_F4"; | |
map[KeyEvent.DOM_VK_F5] = "VK_F5"; | |
map[KeyEvent.DOM_VK_F6] = "VK_F6"; | |
map[KeyEvent.DOM_VK_F7] = "VK_F7"; | |
map[KeyEvent.DOM_VK_F8] = "VK_F8"; | |
map[KeyEvent.DOM_VK_F9] = "VK_F9"; | |
map[KeyEvent.DOM_VK_F10] = "VK_F10"; | |
map[KeyEvent.DOM_VK_F11] = "VK_F11"; | |
map[KeyEvent.DOM_VK_F12] = "VK_F12"; | |
return map; | |
} | |
nextplease.init = function () { | |
nextplease.consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService); | |
nextplease.promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService); | |
nextplease.prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(""); | |
nextplease.KeyCodeToNameMap = nextplease.initializeKeyCodeToStringMap(); | |
nextplease.readPreferences(); | |
} | |
nextplease.logDebugMessage = function (message) { | |
if (nextplease.DEBUG) nextplease.consoleService.logStringMessage(message); | |
if (nextplease.DEBUG_WITH_ALERTS) nextplease.promptService.alert(window, "nextplease", message); | |
} | |
nextplease.cacheImageLocations = function () { | |
if (nextplease.DEBUG) { | |
nextplease.loadListener.consoleService.logStringMessage("nextplease.loadListener "); | |
} | |
var start = new Date(); | |
var imgElems = window.content.document.getElementsByTagName("img"); | |
var end = new Date(); | |
if (nextplease.DEBUG) { | |
nextplease.loadListener.consoleService.logStringMessage("nextplease.loadListener " + (end.getTime() - start.getTime())); | |
} | |
var i, j; | |
var deletedVal; | |
start = new Date(); | |
if (imgElems) { | |
for (i = 0; i < imgElems.length; i++) { | |
if (!nextplease.imageLocationMap[imgElems[i].src]) { | |
if (nextplease.imageLocationArray.length >= nextplease.MAX_IMAGE_CACHE) { | |
if (nextplease.DEBUG) { | |
nextplease.loadListener.consoleService.logStringMessage("clearing images cache"); | |
} | |
for (j = 0; j < Math.floor(nextplease.MAX_IMAGE_CACHE / 2); j++) { | |
deletedVal = nextplease.imageLocationArray[j]; | |
delete nextplease.imageLocationMap[deletedVal]; | |
} | |
nextplease.imageLocationArray = nextplease.imageLocationArray.slice(Math.floor(nextplease.MAX_IMAGE_CACHE / 2), nextplease.imageLocationArray.length); | |
} | |
nextplease.imageLocationMap[imgElems[i].src] = true; | |
nextplease.imageLocationArray.push(imgElems[i].src); | |
} | |
} | |
} | |
end = new Date(); | |
if (nextplease.DEBUG) { | |
nextplease.loadListener.consoleService.logStringMessage("nextplease.loadListener took " + (end.getTime() - start.getTime()) + " ms... num imgs = " + imgElems.length); | |
} | |
start = new Date(); | |
var links = window.content.document.getElementsByTagName("a"); | |
if (links) { | |
for (i = 0; i < links.length; i++) { | |
var linkUrl = links[i].href; | |
if (!nextplease.imageLocationMap[linkUrl]) { | |
if (linkUrl.length > 3) { | |
var suffixIndex = linkUrl.length - 3; | |
var suffix = linkUrl.substr(suffixIndex).toLowerCase(); | |
// This is technically not correct, but performance sucks | |
// if we do a proper regex check. | |
if ((suffix == 'jpg') || (suffix == 'gif') || (suffix == 'png') || (suffix == 'bmp')) { | |
if (nextplease.imageLocationArray.length >= nextplease.MAX_IMAGE_CACHE) { | |
if (nextplease.DEBUG) { | |
nextplease.loadListener.consoleService.logStringMessage("clearing images cache"); | |
} | |
for (j = 0; j < Math.floor(nextplease.MAX_IMAGE_CACHE / 2); j++) { | |
deletedVal = nextplease.imageLocationArray[j]; | |
delete nextplease.imageLocationMap[deletedVal]; | |
} | |
nextplease.imageLocationArray = nextplease.imageLocationArray.slice(Math.floor(nextplease.MAX_IMAGE_CACHE / 2), nextplease.imageLocationArray.length); | |
} | |
nextplease.imageLocationMap[linkUrl] = true; | |
nextplease.imageLocationArray.push(linkUrl); | |
} | |
} | |
} | |
} | |
} | |
end = new Date(); | |
if (nextplease.DEBUG) { | |
nextplease.loadListener.consoleService.logStringMessage("nextplease.loadListener took " + (end.getTime() - start.getTime()) + " ms... num links = " + links.length); | |
} | |
// alert(nextplease.imageLocationArray); | |
} | |
nextplease.initModifierString = function (prefname) { | |
var modString; | |
if (nextplease.prefs.prefHasUserValue(prefname)) modString = nextplease.prefs.getCharPref(prefname); | |
else { | |
// Special case check for setting prev modifier for upgraders | |
// for version 0.5.x and earlier | |
if ((prefname == 'nextplease.prevkeymodifier') && (nextplease.prefs.prefHasUserValue('nextplease.keymodifier'))) { | |
modString = nextplease.prefs.getCharPref('nextplease.keymodifier'); | |
} else { | |
modString = 'ctrl+shift'; | |
} | |
} | |
modString = modString.toLowerCase().replace(/\+/g, " "); | |
modString = modString.toLowerCase().replace(/ctrl/g, "accel"); | |
return modString; | |
} | |
nextplease.initKey = function (prefname, keyId, defaultKeyCode, modString) { | |
var keyCode; | |
var keyString; | |
if (nextplease.prefs.prefHasUserValue(prefname)) keyCode = nextplease.prefs.getIntPref(prefname); | |
else keyCode = defaultKeyCode; | |
var keyElem = document.getElementById(keyId); | |
keyElem.setAttribute("modifiers", modString); | |
if (nextplease.KeyCodeToNameMap[keyCode]) { | |
keyString = nextplease.KeyCodeToNameMap[keyCode]; | |
keyElem.removeAttribute("key"); | |
keyElem.setAttribute("keycode", keyString); | |
} else { | |
keyString = String.fromCharCode(keyCode).toUpperCase(); | |
keyElem.setAttribute("key", keyString); | |
keyElem.removeAttribute("keycode"); | |
} | |
return keyString; | |
} | |
// Read the preferences and setup the | |
// useCtrl/useShift/useAlt vars and next/prev | |
// phrase and image lookup tables | |
nextplease.readPreferences = function () { | |
nextplease.nextModifierString = nextplease.initModifierString('nextplease.keymodifier'); | |
nextplease.prevModifierString = nextplease.initModifierString('nextplease.prevkeymodifier'); | |
nextplease.firstModifierString = nextplease.initModifierString('nextplease.firstkeymodifier'); | |
nextplease.lastModifierString = nextplease.initModifierString('nextplease.lastkeymodifier'); | |
nextplease.nextKeyString = nextplease.initKey('nextplease.nextkey', 'nextpleasekey', KeyEvent.DOM_VK_RIGHT, nextplease.nextModifierString); | |
nextplease.prevKeyString = nextplease.initKey('nextplease.prevkey', 'nextpleaseprevkey', KeyEvent.DOM_VK_LEFT, nextplease.prevModifierString); | |
nextplease.firstKeyString = nextplease.initKey('nextplease.firstkey', 'nextpleasefirstkey', KeyEvent.DOM_VK_UP, nextplease.firstModifierString); | |
nextplease.lastKeyString = nextplease.initKey('nextplease.lastkey', 'nextpleaselastkey', KeyEvent.DOM_VK_DOWN, nextplease.lastModifierString); | |
if (nextplease.prefs.prefHasUserValue('nextplease.allowsubmit')) nextplease.useSubmit = nextplease.prefs.getBoolPref('nextplease.allowsubmit'); | |
if (nextplease.prefs.prefHasUserValue('nextplease.allownumbershortcuts')) nextplease.useNumberShortcuts = nextplease.prefs.getBoolPref('nextplease.allownumbershortcuts'); | |
if (nextplease.prefs.prefHasUserValue('nextplease.allowcontextmenu')) nextplease.useContextMenu = nextplease.prefs.getBoolPref('nextplease.allowcontextmenu'); | |
if (nextplease.prefs.prefHasUserValue('nextplease.allowsmartnext')) nextplease.useSmartNext = nextplease.prefs.getBoolPref('nextplease.allowsmartnext'); | |
var numberkey; | |
for (var i = 1; i < 10; i++) { | |
numberkey = document.getElementById("nextplease" + i + "key"); | |
numberkey.setAttribute("disabled", !nextplease.useNumberShortcuts); | |
} | |
var nextRegExString = nextplease.DefaultNextRegEx; | |
if (nextplease.prefs.prefHasUserValue('nextplease.nextregex')) nextRegExString = nextplease.GetUnicharPref('nextplease.nextregex'); | |
if (nextplease.Trim(nextRegExString) == '') nextRegExString = nextplease.DefaultNextRegEx; | |
nextplease.isNextRegExp = new RegExp(nextRegExString, "i"); | |
var prevRegExString = nextplease.DefaultPrevRegEx; | |
if (nextplease.prefs.prefHasUserValue('nextplease.prevregex')) prevRegExString = nextplease.GetUnicharPref('nextplease.prevregex'); | |
if (nextplease.Trim(prevRegExString) == '') prevRegExString = nextplease.DefaultPrevRegEx; | |
nextplease.isPrevRegExp = new RegExp(prevRegExString, "i"); | |
var firstRegExString = nextplease.DefaultFirstRegEx; | |
if (nextplease.prefs.prefHasUserValue('nextplease.firstregex')) firstRegExString = nextplease.GetUnicharPref('nextplease.firstregex'); | |
if (nextplease.Trim(firstRegExString) == '') firstRegExString = nextplease.DefaultFirstRegEx; | |
nextplease.isFirstRegExp = new RegExp(firstRegExString, "i"); | |
var lastRegExString = nextplease.DefaultLastRegEx; | |
if (nextplease.prefs.prefHasUserValue('nextplease.lastregex')) lastRegExString = nextplease.GetUnicharPref('nextplease.lastregex'); | |
if (nextplease.Trim(lastRegExString) == '') lastRegExString = nextplease.DefaultLastRegEx; | |
nextplease.isLastRegExp = new RegExp(lastRegExString, "i"); | |
var galleryRegExString = nextplease.DefaultGalleryRegEx; | |
if (nextplease.prefs.prefHasUserValue('nextplease.galleryregex')) { | |
galleryRegExString = nextplease.GetUnicharPref('nextplease.galleryregex'); | |
if (nextplease.Trim(galleryRegExString) == '') galleryRegExString = nextplease.DefaultGalleryRegEx; | |
nextplease.galleryUrlRegex = new RegExp(galleryRegExString, "i"); | |
var matches = nextplease.galleryUrlRegex.exec('http://nextplease.mozdev.org/test/test101.jpg'); | |
if (matches && (matches.length != 4)) { | |
galleryRegExString = nextplease.DefaultGalleryRegEx; | |
} | |
} | |
nextplease.galleryUrlRegex = new RegExp(galleryRegExString, "i"); | |
nextplease.DisableConflictingKeys(); | |
nextplease.NextPhrasesMap = nextplease.initializeNextPrevMap('nextplease.nextphrase', nextplease.DefaultNextPhrases); | |
nextplease.PrevPhrasesMap = nextplease.initializeNextPrevMap('nextplease.prevphrase', nextplease.DefaultPrevPhrases); | |
nextplease.FirstPhrasesMap = nextplease.initializeNextPrevMap('nextplease.firstphrase', nextplease.DefaultFirstPhrases); | |
nextplease.LastPhrasesMap = nextplease.initializeNextPrevMap('nextplease.lastphrase', nextplease.DefaultLastPhrases); | |
nextplease.NextImagesMap = nextplease.initializeNextPrevMap('nextplease.nextimage', nextplease.DefaultNextImages); | |
nextplease.PrevImagesMap = nextplease.initializeNextPrevMap('nextplease.previmage', nextplease.DefaultPrevImages); | |
nextplease.FirstImagesMap = nextplease.initializeNextPrevMap('nextplease.firstimage', nextplease.DefaultFirstImages); | |
nextplease.LastImagesMap = nextplease.initializeNextPrevMap('nextplease.lastimage', nextplease.DefaultLastImages); | |
} | |
nextplease.DisableKey = function (modifier, key, keycode) { | |
var conflictingKeys; | |
if (key != '') conflictingKeys = document.getElementsByAttribute("key", key); | |
else if (keycode != '') conflictingKeys = document.getElementsByAttribute("keycode", keycode); | |
for (var i = 0; i < conflictingKeys.length; i++) { | |
if (! (/nextplease/.test(conflictingKeys[i].getAttribute("id"))) && conflictingKeys[i].hasAttribute("modifiers")) { | |
var conflictingModifier = conflictingKeys[i].getAttribute("modifiers"); | |
if ((/alt/.test(modifier) == /alt/.test(conflictingModifier)) && (/shift/.test(modifier) == /shift/.test(conflictingModifier)) && (/accel/.test(modifier) == /accel/.test(conflictingModifier))) { | |
conflictingKeys[i].parentNode.removeChild(conflictingKeys[i]); | |
} | |
} | |
} | |
} | |
nextplease.DisableConflictingKeys = function () { | |
// disables any conflicting key-bindings | |
var conflictingKeys; | |
// Check for ALT+1/2/3... key bindings | |
for (var i = 1; i < 10; i++) { | |
nextplease.DisableKey("alt", "" + i, ""); | |
} | |
// If it starts with VK_, then use the keycode instead of key | |
if (nextplease.nextKeyString.indexOf("VK_") >= 0) nextplease.DisableKey(nextplease.nextModifierString, "", nextplease.nextKeyString); | |
else nextplease.DisableKey(nextplease.nextModifierString, nextplease.nextKeyString.toLowerCase(), ""); | |
if (nextplease.prevKeyString.indexOf("VK_") >= 0) nextplease.DisableKey(nextplease.prevModifierString, "", nextplease.prevKeyString); | |
else nextplease.DisableKey(nextplease.prevModifierString, nextplease.prevKeyString.toLowerCase(), ""); | |
if (nextplease.firstKeyString.indexOf("VK_") >= 0) nextplease.DisableKey(nextplease.firstModifierString, "", nextplease.firstKeyString); | |
else nextplease.DisableKey(nextplease.firstModifierString, nextplease.firstKeyString.toLowerCase(), ""); | |
if (nextplease.lastKeyString.indexOf("VK_") >= 0) nextplease.DisableKey(nextplease.lastModifierString, "", nextplease.lastKeyString); | |
else nextplease.DisableKey(nextplease.lastModifierString, nextplease.lastKeyString.toLowerCase(), ""); | |
} | |
// Looks through all the links on the page | |
// and tries to look for one whose text matches | |
// one of the phrases or images. If so, it goes to/ | |
// the corresponding link. | |
// pages with frames. | |
nextplease.getLink = function (curWindow, phraseMap, imageMap, phraseRegEx, searchType) { | |
var text; | |
var isInt = /^\s*\[?\s*(\d+)\s*\]?\s*$/; | |
var useFrames = true; | |
var tmpPageNumLink = null; | |
var firstPageNumLink = null; | |
var firstPageNum; | |
var lastPageNumLink = null; | |
var nextPageNumLink = null; | |
var prevPageNumLink = null; | |
var currentPageNum = 100000; // Init to arbitrarily large num | |
var tmpPageNum = 100000; // Init to arbitrarily large num | |
var isFirstNumber = true; | |
var greatestNum = 1; | |
var i; | |
var link; | |
nextplease.readPreferences(); | |
var range = document.createRange(); | |
if (nextplease.useSmartNext) { | |
if ((searchType == nextplease.NEXT_SEARCH_TYPE) && (getBrowser().canGoForward)) { | |
return curWindow.history.forward(); | |
} else if ((searchType == nextplease.PREV_SEARCH_TYPE) && (getBrowser().canGoBack)) { | |
return curWindow.history.back(); | |
} | |
} | |
// Look for <LINK> tags | |
var linktags = curWindow.document.getElementsByTagName("link"); | |
for (i = 0; i < linktags.length; i++) { | |
link = linktags[i]; | |
// Look for rel attributes for next/prev/first/last | |
if (link.rel) { | |
// Hack to workaround PHPBB's incorrect use of LINK tags. | |
if (curWindow.location.href.match("viewtopic.php")) { | |
// do nothing | |
} else if ((searchType == nextplease.NEXT_SEARCH_TYPE) && (link.rel.toLowerCase() == "next")) { | |
return nextplease.openLink(curWindow, link); | |
} else if ((searchType == nextplease.PREV_SEARCH_TYPE) && ((link.rel.toLowerCase() == "prev") || (link.rel.toLowerCase() == "previous"))) { | |
return nextplease.openLink(curWindow, link); | |
} else if ((searchType == nextplease.FIRST_SEARCH_TYPE) && ((link.rel.toLowerCase() == "start") || (link.rel.toLowerCase() == "first"))) { | |
return nextplease.openLink(curWindow, link); | |
} else if ((searchType == nextplease.LAST_SEARCH_TYPE) && ((link.rel.toLowerCase() == "end") || (link.rel.toLowerCase() == "last"))) { | |
return nextplease.openLink(curWindow, link); | |
} | |
} | |
} | |
// Look for <A HREF="..."> tags | |
var alinks = curWindow.document.links; | |
// Search through each link | |
for (i = 0; i < alinks.length; i++) { | |
link = alinks[i]; | |
// Look for rel attributes for next/prev/first/last | |
if (link.rel) { | |
if ((searchType == nextplease.NEXT_SEARCH_TYPE) && (link.rel.toLowerCase() == "next")) { | |
return nextplease.openLink(curWindow, link); | |
} else if ((searchType == nextplease.PREV_SEARCH_TYPE) && ((link.rel.toLowerCase() == "prev") || (link.rel.toLowerCase() == "previous"))) { | |
return nextplease.openLink(curWindow, link); | |
} else if ((searchType == nextplease.FIRST_SEARCH_TYPE) && ((link.rel.toLowerCase() == "start") || (link.rel.toLowerCase() == "first"))) { | |
return nextplease.openLink(curWindow, link); | |
} else if ((searchType == nextplease.LAST_SEARCH_TYPE) && ((link.rel.toLowerCase() == "end") || (link.rel.toLowerCase() == "last"))) { | |
return nextplease.openLink(curWindow, link); | |
} | |
} | |
range.selectNode(link); | |
text = nextplease.Trim(range.toString()); | |
// If the text is in the lookup table, | |
// go to the URL | |
if (phraseMap[text] == true) { | |
// alert('found phrase match'); | |
if (link.href.indexOf("/dictionary") < 0) { | |
return nextplease.openLink(curWindow, link); | |
} | |
} else { | |
// If we don't have an exact match, | |
// try a regular expression test. | |
// alert(text); | |
if (phraseRegEx.test(text)) { | |
if (link.href.indexOf("/dictionary") < 0) { | |
return nextplease.openLink(curWindow, link); | |
} | |
} else if (link.title) { | |
if (phraseRegEx.test(link.title)) { | |
return nextplease.openLink(curWindow, link); | |
} | |
} | |
// See if there's an image tag | |
var imgElems = link.getElementsByTagName("img"); | |
if (imgElems.length > 0) { | |
// If the image matches, go to the URL. | |
//alert(imgElems[0].src); | |
var imgtext = imgElems[0].alt; | |
if (!imgtext) imgtext = imgElems[0].title; | |
if ((imageMap[imgElems[0].src]) || (phraseMap[imgtext] == true) || (phraseRegEx.test(imgtext))) { | |
// alert('found image match'); | |
return nextplease.openLink(curWindow, link); | |
} | |
} | |
} | |
var intMatches = isInt.exec(text); | |
if (intMatches) { | |
var linkPageNum = parseInt(intMatches[1]); | |
// If the number is greater than a nextplease.MAX_LINK_NUM | |
// it probably doesn't have anything to do with | |
// a next/prev link. | |
// alert(linkPageNum); | |
if (linkPageNum < nextplease.MAX_LINK_NUM) { | |
// Try to figure out what the current page and | |
// next/prev links are for pages that just have | |
// numbered links like 1 2 x 4 5. | |
// if (linkPageNum == 1) { | |
// We're seeing a number link that is smaller | |
// than a previous one so assume that we're | |
// starting a new set of number links, and | |
// count from the beginning. | |
if (linkPageNum <= tmpPageNum) { | |
// alert(linkPageNum); | |
// alert(currentPageNum); | |
firstPageNumLink = link; | |
firstPageNum = linkPageNum; | |
greatestNum = linkPageNum; | |
prevPageNumLink = null; | |
nextPageNumLink = null; | |
lastPageNumLink = null; | |
currentPageNum = linkPageNum; | |
firstPageNumLink = link; | |
greatestNum = linkPageNum; | |
lastPageNumLink = null; | |
//} else if (currentPageNum == linkPageNum) { | |
// currentPageNum++; | |
// prevPageNumLink = link; | |
} else if (tmpPageNum + 1 == linkPageNum) { | |
lastPageNumLink = link; | |
} else if (tmpPageNum + 2 == linkPageNum) { | |
prevPageNumLink = tmpPageNumLink; | |
nextPageNumLink = link; | |
lastPageNumLink = link; | |
} | |
tmpPageNum = linkPageNum; | |
tmpPageNumLink = link; | |
} | |
} | |
} | |
// next and prev are null so that means | |
// we have a solid block of number 3,4,5,6,... | |
if ((nextPageNumLink == null) && (prevPageNumLink == null)) { | |
// If we start with 1, we're probably on last page. | |
// Set prev to be lastPage | |
if (firstPageNum == 1) { | |
prevPageNumLink = lastPageNumLink; | |
lastPageNumLink = null; | |
} | |
// If we start with 2, we're probably on first page. | |
// Set next to be first page | |
if (firstPageNum == 2) { | |
nextPageNumLink = firstPageNumLink; | |
firstPageNumLink = null; | |
} | |
if (firstPageNum > 2) { | |
nextPageNumLink = firstPageNumLink; | |
prevPageNumLink = lastPageNumLink; | |
} | |
} | |
if (firstPageNumLink && lastPageNumLink && (firstPageNumLink.text == lastPageNumLink.text)) firstPageNumLink = null; | |
// alert(firstPageNumLink); | |
// alert(prevPageNumLink); | |
// alert(nextPageNumLink); | |
// alert(lastPageNumLink); | |
// Try to find a match using our number algorithm | |
if ((searchType == nextplease.NEXT_SEARCH_TYPE) && nextPageNumLink) return nextplease.openLink(curWindow, nextPageNumLink); | |
else if ((searchType == nextplease.PREV_SEARCH_TYPE) && prevPageNumLink) return nextplease.openLink(curWindow, prevPageNumLink); | |
else if ((searchType == nextplease.FIRST_SEARCH_TYPE) && firstPageNumLink) return nextplease.openLink(curWindow, firstPageNumLink); | |
else if ((searchType == nextplease.LAST_SEARCH_TYPE) && lastPageNumLink) return nextplease.openLink(curWindow, lastPageNumLink); | |
// Otherwise try looking for next/prev submit buttons | |
// if the user allows it. | |
if (nextplease.useSubmit && nextplease.getForm(phraseMap, phraseRegEx)) return true; | |
// See if we can increment the URL to get to next/prev/first | |
var galleryLink = nextplease.getGalleryNumberLink(curWindow, searchType); | |
// alert(galleryLink); | |
// alert(nextplease.imageLocationArray.length); | |
if (galleryLink) curWindow.open(galleryLink, "_self", ""); | |
// None of it worked, so make a recursive call to | |
// nextplease.getLink on the frame windows. | |
var frames = curWindow.frames; | |
for (var j = 0; j < frames.length; j++) { | |
if (nextplease.getLink(frames[j], phraseMap, imageMap, phraseRegEx, searchType)) return true; | |
} | |
return false; | |
} | |
nextplease.getGalleryNumberLink = function (curWindow, searchType) { | |
var i; | |
// alert(nextplease.imageLocationArray); | |
var matches = nextplease.galleryUrlRegex.exec(unescape(curWindow.location.href)); | |
var prefixUrl; | |
var suffixUrl; | |
var curNumber; | |
var urlNumber; | |
var padStr; | |
var linkUrl; | |
if (matches && (matches.length == 4)) { | |
prefixUrl = matches[1]; | |
suffixUrl = matches[3]; | |
if (searchType == nextplease.NEXT_SEARCH_TYPE) { | |
curNumber = parseInt(matches[2], 10); | |
for (i = 1; i < nextplease.MAX_GALLERY_GAP; i++) { | |
urlNumber = curNumber + i; | |
padStr = nextplease.padNumber(matches[2], urlNumber); | |
linkUrl = prefixUrl + padStr + suffixUrl; | |
if (nextplease.imageLocationMap[linkUrl]) { | |
return linkUrl; | |
} | |
} | |
urlNumber = curNumber + 1; | |
padStr = nextplease.padNumber(matches[2], urlNumber); | |
linkUrl = prefixUrl + padStr + suffixUrl; | |
return linkUrl; | |
} else if (searchType == nextplease.PREV_SEARCH_TYPE) { | |
curNumber = parseInt(matches[2], 10); | |
for (i = 1; (i < nextplease.MAX_GALLERY_GAP) && (i <= curNumber); i++) { | |
urlNumber = curNumber - i; | |
padStr = nextplease.padNumber(matches[2], urlNumber); | |
linkUrl = prefixUrl + padStr + suffixUrl; | |
if (nextplease.imageLocationMap[linkUrl]) { | |
return linkUrl; | |
} | |
} | |
urlNumber = curNumber - 1; | |
if (urlNumber >= 0) { | |
padStr = nextplease.padNumber(matches[2], urlNumber); | |
linkUrl = prefixUrl + padStr + suffixUrl; | |
return linkUrl; | |
} | |
} else if (searchType == nextplease.FIRST_SEARCH_TYPE) { | |
urlNumber = 1; | |
padStr = nextplease.padNumber(matches[2], urlNumber); | |
linkUrl = prefixUrl + padStr + suffixUrl; | |
return linkUrl; | |
} | |
} | |
return; | |
} | |
nextplease.padNumber = function (origNumString, newNum) { | |
var padStr = "" + newNum; | |
var padLen = origNumString.length - padStr.length; | |
for (var i = 0; i < padLen; i++) { | |
padStr = "0" + padStr; | |
} | |
return padStr; | |
} | |
nextplease.openLink = function (curWindow, linkNode) { | |
// If it's got an onclick attr, then try to | |
// simulate a mouse click to activate link. | |
if (linkNode && linkNode.hasAttribute("onclick")) { | |
// alert(linkNode.getAttribute("onclick")); | |
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); | |
} else { | |
curWindow.open(linkNode.href, "_self", ""); | |
} | |
return true; | |
} | |
// Look through all the HTML inputs for submit buttons | |
// that have a value that matches our phrases. If it | |
// finds a match, it submits the corresponding form | |
// (which will hopefully take us to the next/prev page). | |
nextplease.getForm = function (phraseMap, phraseRegEx) { | |
var text; | |
// Probably would be a little faster to | |
// only check forms, but I'm getting problems | |
// with them. I'm not sure if it's only on | |
// malformed HTML pages, or if it's a Firefox bug. | |
var inputs = window.content.document.getElementsByTagName("input"); | |
for (var i = 0; i < inputs.length; i++) { | |
if (inputs[i].type == 'submit') { | |
text = nextplease.Trim(inputs[i].value); | |
if (phraseMap[text] == true) { | |
inputs[i].form.submit(); | |
return true; | |
} else { | |
// If we don't have an exact match, | |
// try a quick regular expression test. | |
if (phraseRegEx.test(text)) { | |
inputs[i].form.submit(); | |
return true; | |
} | |
} | |
} | |
} | |
return false; | |
} | |
// Looks through all the links and finds the link | |
// that matches the linkNum (an integer between | |
// 1 and 9). If it finds a match, it will go to | |
// that link. | |
nextplease.getNumberedLink = function (curWindow, linkNum) { | |
var text; | |
var isInt = /^\s*\[?\s*(\d+)\s*\]?\s*$/; | |
var useFrames = true; | |
nextplease.readPreferences(); | |
var alinks = curWindow.document.links; | |
// Search through each link | |
for (var i = alinks.length - 1; i >= 0; i--) { | |
var link = alinks[i]; | |
text = nextplease.Trim(link.text); | |
var intMatches = isInt.exec(text); | |
if (intMatches) { | |
var linkPageNum = parseInt(intMatches[1]); | |
if (linkPageNum == linkNum) { | |
return nextplease.openLink(curWindow, link); | |
//curWindow.open(link.href, "_self", ""); | |
//return true; | |
} | |
} | |
} | |
var frames = curWindow.frames; | |
for (var j = 0; j < frames.length; j++) { | |
if (nextplease.getNumberedLink(frames[j], linkNum)) return true; | |
} | |
return false; | |
} | |
nextplease.getNextLink = function () { | |
nextplease.getLink(window.content, nextplease.NextPhrasesMap, nextplease.NextImagesMap, nextplease.isNextRegExp, nextplease.NEXT_SEARCH_TYPE); | |
} | |
nextplease.getPrevLink = function () { | |
nextplease.getLink(window.content, nextplease.PrevPhrasesMap, nextplease.PrevImagesMap, nextplease.isPrevRegExp, nextplease.PREV_SEARCH_TYPE); | |
} | |
nextplease.getFirstLink = function () { | |
nextplease.getLink(window.content, nextplease.FirstPhrasesMap, nextplease.FirstImagesMap, nextplease.isFirstRegExp, nextplease.FIRST_SEARCH_TYPE); | |
} | |
nextplease.getLastLink = function () { | |
nextplease.getLink(window.content, nextplease.LastPhrasesMap, nextplease.LastImagesMap, nextplease.isLastRegExp, nextplease.LAST_SEARCH_TYPE); | |
} | |
nextplease.showHideMenuItems = function () { | |
if (gContextMenu) { | |
gContextMenu.showItem("nextplease.topMenu", nextplease.useContextMenu); | |
gContextMenu.showItem("nextPleasePopupMenu", nextplease.useContextMenu); | |
gContextMenu.showItem("prevPleasePopupMenu", nextplease.useContextMenu); | |
gContextMenu.showItem("firstPleasePopupMenu", nextplease.useContextMenu); | |
gContextMenu.showItem("lastPleasePopupMenu", nextplease.useContextMenu); | |
gContextMenu.showItem("nextPleaseAddPrevImage", nextplease.useContextMenu && gContextMenu.onImage); | |
gContextMenu.showItem("nextPleaseAddNextImage", nextplease.useContextMenu && gContextMenu.onImage); | |
gContextMenu.showItem("nextPleaseAddFirstImage", nextplease.useContextMenu && gContextMenu.onImage); | |
gContextMenu.showItem("nextPleaseAddLastImage", nextplease.useContextMenu && gContextMenu.onImage); | |
var showPhraseMenu = !gContextMenu.onImage && gContextMenu.onLink; | |
gContextMenu.showItem("nextPleaseAddNextPhrase", nextplease.useContextMenu && showPhraseMenu); | |
gContextMenu.showItem("nextPleaseAddPrevPhrase", nextplease.useContextMenu && showPhraseMenu); | |
gContextMenu.showItem("nextPleaseAddFirstPhrase", nextplease.useContextMenu && showPhraseMenu); | |
gContextMenu.showItem("nextPleaseAddLastPhrase", nextplease.useContextMenu && showPhraseMenu); | |
gContextMenu.showItem("nextPleaseHideToolbar", true); | |
} | |
} | |
nextplease.addPhrase = function (map, prefname, defaultValues) { | |
if (gContextMenu.onLink) { | |
var range = document.createRange(); | |
range.selectNode(document.popupNode); | |
var text = nextplease.Trim(range.toString()); | |
if (text != '') { | |
if ((map != nextplease.NextPhrasesMap) && (nextplease.NextPhrasesMap[text])) { | |
alert('This phrase is already being used for Next.\n' + 'If you want, use the NextPlease! options page to remove it.'); | |
} else if ((map != nextplease.PrevPhrasesMap) && (nextplease.PrevPhrasesMap[text])) { | |
alert('This phrase is already being used for Prev.\n' + 'If you want, use the NextPlease! options page to remove it.'); | |
} else if ((map != nextplease.FirstPhrasesMap) && (nextplease.FirstPhrasesMap[text])) { | |
alert('This phrase is already being used for First.\n' + 'If you want, use the NextPlease! options page to remove it.'); | |
} else if ((map != nextplease.LastPhrasesMap) && (nextplease.LastPhrasesMap[text])) { | |
alert('This phrase is already being used for Last.\n' + 'If you want, use the NextPlease! options page to remove it.'); | |
} else if (!map[text]) { | |
map[text] = true; | |
nextplease.addToPrefs(prefname, text, defaultValues); | |
} | |
} | |
} | |
} | |
nextplease.addImage = function (map, prefname, defaultValues) { | |
if (document.popupNode) { | |
var imageurl = document.popupNode.src; | |
if ((map != nextplease.NextImagesMap) && (nextplease.NextImagesMap[imageurl])) { | |
alert('This image is already being used for Next.\n' + 'If you want, use the NextPlease! options page to remove it.'); | |
} else if ((map != nextplease.PrevImagesMap) && (nextplease.PrevImagesMap[imageurl])) { | |
alert('This image is already being used for Prev.\n' + 'If you want, use the NextPlease! options page to remove it.'); | |
} else if ((map != nextplease.FirstImagesMap) && (nextplease.FirstImagesMap[imageurl])) { | |
alert('This image is already being used for First.\n' + 'If you want, use the NextPlease! options page to remove it.'); | |
} else if ((map != nextplease.LastImagesMap) && (nextplease.LastImagesMap[imageurl])) { | |
alert('This image is already being used for Last.\n' + 'If you want, use the NextPlease! options page to remove it.'); | |
} else if (!map[imageurl]) { | |
map[imageurl] = true; | |
nextplease.addToPrefs(prefname, imageurl, defaultValues); | |
} | |
} | |
} | |
nextplease.addToPrefs = function (prefbranch, text, defaultValues) { | |
var tempprefname = prefbranch + '.expr0'; | |
var prefvalue; | |
if (nextplease.prefs.prefHasUserValue(tempprefname)) { | |
prefvalue = nextplease.GetUnicharPref(tempprefname); | |
} else { | |
prefvalue = ""; | |
for (var i = 0; i < defaultValues.length; i++) { | |
prefvalue = prefvalue + "|" + defaultValues[i].replace(/\|/g, "&pipe;"); | |
} | |
} | |
text = prefvalue + "|" + text.replace(/\|/g, "&pipe;"); | |
nextplease.SetUnicharPref(tempprefname, text); | |
} | |
nextplease.ToggleToolbar = function () { | |
var toolbar = document.getElementById("nextplease-toolbar"); | |
if (toolbar) { | |
goToggleToolbar('nextplease-toolbar'); | |
} | |
setTimeout("document.getElementById('urlbar').focus()", 0); | |
} | |
window.addEventListener("load", nextplease.init, false); | |
window.addEventListener("popupshowing", nextplease.showHideMenuItems, false); | |
window.addEventListener("load",function(event){ nextplease.loadListener.onLoad(event); },false); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment