aboutsummaryrefslogtreecommitdiff
path: root/chrome/content
diff options
context:
space:
mode:
authorEinar Egilsson2007-09-27 21:51:41 +0000
committerEinar Egilsson2007-09-27 21:51:41 +0000
commitec5b381d57a1a873d423c9e6f2d6ca78c1aa1963 (patch)
treeecc6593206e6982c252ba48f4bd35aaf34bcfe36 /chrome/content
parent87b8db3e5ebf0911f613f71ce1251276ece47304 (diff)
Redirector 1.0
git-svn-id: http://einaregilsson.googlecode.com/svn/mozilla/redirector/trunk@87 119bf307-c92d-0410-89bd-8f53e6181181
Diffstat (limited to 'chrome/content')
-rw-r--r--chrome/content/overlay.js58
-rw-r--r--chrome/content/redirector.js95
2 files changed, 136 insertions, 17 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 = {
}
}
- },
+ }
};