Skip to content

Instantly share code, notes, and snippets.

@alexeyr
Created February 22, 2010 22:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexeyr/311567 to your computer and use it in GitHub Desktop.
Save alexeyr/311567 to your computer and use it in GitHub Desktop.
// $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