aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chrome/content/overlay.js58
-rw-r--r--chrome/content/redirector.js95
-rw-r--r--install.rdf2
3 files changed, 137 insertions, 18 deletions
diff --git a/chrome/content/overlay.js b/chrome/content/overlay.js
index a230d23..ca198e6 100644
--- a/chrome/content/overlay.js
+++ b/chrome/content/overlay.js
@@ -20,6 +20,7 @@ var RedirectorOverlay = {
Redirector.init();
var appcontent = window.document.getElementById('appcontent');
+ this.overrideOnStateChange();
if (appcontent && !appcontent.processed) {
appcontent.processed = true;
@@ -31,7 +32,7 @@ var RedirectorOverlay = {
}, false);
}
this.strings = document.getElementById("redirector-strings");
-
+ Redirector.strings = this.strings;
this.prefObserver.register();
this.setStatusBarImg();
@@ -48,6 +49,53 @@ var RedirectorOverlay = {
}
},
+ overrideOnStateChange : function() {
+ var origOnStateChange = nsBrowserStatusHandler.prototype.onStateChange;
+
+ nsBrowserStatusHandler.prototype.onStateChange = function(aWebProgress, aRequest, aStateFlags, aStatus) {
+
+ if(aStateFlags & Ci.nsIWebProgressListener.STATE_START
+ && aStateFlags| Ci.nsIWebProgressListener.STATE_IS_NETWORK
+ && aStateFlags| Ci.nsIWebProgressListener.STATE_IS_REQUEST
+ && aRequest && aWebProgress.DOMWindow == content) {
+
+ //If it's not a GET request we'll always do a slow redirect so the web will continue
+ //to work in the way you'd expect
+ try {
+ var oHttp = aRequest.QueryInterface(Ci.nsIHttpChannel);
+ var method = oHttp.requestMethod;
+
+ if (method != "GET") {
+ origOnStateChange.apply(this, arguments);
+ return;
+ }
+
+ } catch(ex) {
+ origOnStateChange.apply(this, arguments);
+ return;
+ }
+
+ var uri = aRequest.QueryInterface(Ci.nsIChannel).URI.spec;
+
+ RedirLib.debug('Checking url %1 for instant redirect'._(uri));
+ var redirectUrl = Redirector.getRedirectUrlForInstantRedirect(uri);
+ if (redirectUrl.url && oHttp.notificationCallbacks) {
+ const NS_BINDING_ABORTED = 0x804b0002;
+ aRequest.cancel(NS_BINDING_ABORTED);
+ var newStateFlags = Ci.nsIWebProgressListener.STATE_STOP | Ci.nsIWebProgressListener.STATE_IS_NETWORK;
+ origOnStateChange.call(this, aWebProgress, aRequest, newStateFlags, "");
+ var interfaceRequestor = oHttp.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
+ var targetDoc = interfaceRequestor.getInterface(Ci.nsIDOMWindow).document;
+ var gotoUrl = Redirector.makeAbsoluteUrl(uri, redirectUrl.url);
+ Redirector.goto(gotoUrl, redirectUrl.pattern, uri, targetDoc);
+ } else {
+ origOnStateChange.apply(this, arguments);
+ }
+
+ }
+ };
+ },
+
onDOMContentLoaded : function(event) {
var redirect, link, links, url;
@@ -58,7 +106,7 @@ var RedirectorOverlay = {
url = window.content.location.href;
RedirLib.debug('Processing url %1'._(url));
- Redirector.processUrl(url);
+ Redirector.processUrl(url, window.content);
},
@@ -109,9 +157,11 @@ var RedirectorOverlay = {
if (RedirLib.getBoolPref('enabled')) {
statusImg.src = 'chrome://redirector/content/statusactive.png'
statusImg.setAttribute('tooltiptext', this.strings.getString('enabledTooltip'));
+ Redirector.enabled = true;
} else {
statusImg.src = 'chrome://redirector/content/statusinactive.png'
statusImg.setAttribute('tooltiptext', this.strings.getString('disabledTooltip'));
+ Redirector.enabled = false;
}
},
@@ -140,6 +190,4 @@ var RedirectorOverlay = {
};
window.addEventListener("load", function(event) { RedirectorOverlay.onLoad(event); }, false);
-window.addEventListener("unload", function(event) { RedirectorOverlay.onUnload(event); }, false);
-
-
+window.addEventListener("unload", function(event) { RedirectorOverlay.onUnload(event); }, false); \ No newline at end of file
diff --git a/chrome/content/redirector.js b/chrome/content/redirector.js
index 18ac1f9..cab38c3 100644
--- a/chrome/content/redirector.js
+++ b/chrome/content/redirector.js
@@ -50,6 +50,43 @@ var Redirector = {
this.save();
},
+ getRedirectUrlForInstantRedirect : function(url) {
+ var redirect, link, links, redirectUrl;
+
+ if (!this.enabled) {
+ return null;
+ }
+
+ for each (redirect in this.list) {
+
+ redirectUrl = this.getRedirectUrl(url, redirect);
+ //Can't do fast redirect if it requires that link exists
+ //we need the original page to verify that it exists.
+ //Slow redirect will be done automatically.
+ if (redirectUrl) {
+
+ if (!redirect.onlyIfLinkExists && !redirect.redirectUrl.startsWith('xpath:')) {
+ RedirLib.debug('%1 matches %2, and it\'s not only if link exists and not an xpath expression. Can do instant redirect.'._(redirect.pattern, url));
+ return { 'url' : redirectUrl, 'pattern' : redirect.pattern};
+ } else if (redirect.redirectUrl.startsWith('xpath:')) {
+ RedirLib.debug('%1 matches %2, but the redirect is a xpath expression and so has to be a slow redirect'._(redirect.pattern, url));
+ } else {
+ RedirLib.debug('%1 matches %2, but it\'s "only if link exists" and so has to be a slow redirect'._(redirect.pattern, url));
+ }
+ }
+ }
+ return { 'url' : null, 'pattern' : null};
+ },
+
+ getRedirectUrl: function(url, redirect) {
+ if (redirect.patternType == kRedirectorWildcard) {
+ return this.wildcardMatch(redirect.pattern, url, redirect.redirectUrl);
+ } else if (redirect.patternType == kRedirectorRegex) {
+ return this.regexMatch(redirect.pattern, url, redirect.redirectUrl);
+ }
+ return null;
+ },
+
processUrl : function(url) {
var redirect, link, links, redirectUrl;
@@ -59,12 +96,7 @@ var Redirector = {
for each (redirect in this.list) {
-
- if (redirect.patternType == kRedirectorWildcard) {
- redirectUrl = this.wildcardMatch(redirect.pattern, url, redirect.redirectUrl);
- } else if (redirect.patternType == kRedirectorRegex) {
- redirectUrl = this.regexMatch(redirect.pattern, url, redirect.redirectUrl);
- }
+ redirectUrl = this.getRedirectUrl(url, redirect);
if (redirectUrl) {
RedirLib.debug('%1 matches %2'._(redirect.pattern, url));
@@ -75,7 +107,7 @@ var Redirector = {
if (link.href && link.href.toString() == redirectUrl) {
RedirLib.debug('Found a link for %1'._(redirectUrl));
- this._goto(redirectUrl, redirect.pattern);
+ this.goto(redirectUrl, redirect.pattern, url, window.content.document);
return;
}
}
@@ -83,18 +115,53 @@ var Redirector = {
RedirLib.debug('Did not find a link for %1'._(redirectUrl));
} else {
- this._goto(redirectUrl, redirect.pattern);
+ this.goto(redirectUrl, redirect.pattern, url, window.content.document);
}
}
}
},
+
+ makeAbsoluteUrl : function(currentUrl, relativeUrl) {
+
+ if (relativeUrl.startsWith('http://') || relativeUrl.startsWith('https://')) {
+ return relativeUrl;
+ }
+
+ var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+ RedirLib.debug(currentUrl);
+ var uri = ioService.newURI(currentUrl, null, null);
+
+ return uri.resolve(relativeUrl);
+ },
- _goto : function(redirectUrl, pattern) {
+ goto : function(redirectUrl, pattern, url, doc) {
- if (redirectUrl == window.content.location.href) {
+
+ if (redirectUrl.startsWith('xpath:')) {
+
+ var xpath = redirectUrl.substr('xpath:'.length);
+ RedirLib.debug('Evaluating xpath: ' + xpath);
+ xpathResult = doc.evaluate(redirectUrl.substr('xpath:'.length), doc, null, XPathResult.STRING_TYPE,null);
+ if (!xpathResult) {
+ //fail silently
+ RedirLib.debug('%1 returned nothing on url %2'._(xpath, url));
+ return;
+ } else {
+ RedirLib.debug('%1 evaluated to %2'._(redirectUrl, xpathResult.stringValue));
+ redirectUrl = xpathResult.stringValue;
+ if (redirectUrl == '') {
+ RedirLib.debug('XPath failed, no redirection will be made');
+ return;
+ }
+ }
+ }
+
+ redirectUrl = this.makeAbsoluteUrl(url, redirectUrl);
+
+ if (redirectUrl == url) {
RedirLib.msgBox(this.strings.getString('extensionName'), this.strings.getFormattedString('recursiveError', [pattern, redirectUrl]));
} else {
- window.content.location.href = redirectUrl;
+ doc.location.href = redirectUrl;
}
},
@@ -180,6 +247,10 @@ var Redirector = {
if (topic != 'nsPref:changed') {
return;
}
+
+ if (!window.Redirector) {
+ return;
+ }
if (data == 'extensions.redirector.redirects') {
Redirector.load();
@@ -188,5 +259,5 @@ var Redirector = {
}
}
- },
+ }
};
diff --git a/install.rdf b/install.rdf
index 9eb365f..fa1fe63 100644
--- a/install.rdf
+++ b/install.rdf
@@ -5,7 +5,7 @@
<Description about="urn:mozilla:install-manifest">
<em:id>redirector@einaregilsson.com</em:id>
<em:name>Redirector</em:name>
- <em:version>0.9.2</em:version>
+ <em:version>1.0</em:version>
<em:creator>Einar Egilsson</em:creator>
<em:description>Automatically redirects to user-defined urls on certain pages</em:description>
<em:homepageURL>http://tech.einaregilsson.com/projects/redirector/</em:homepageURL>