diff options
author | Einar Egilsson | 2007-09-27 21:51:41 +0000 |
---|---|---|
committer | Einar Egilsson | 2007-09-27 21:51:41 +0000 |
commit | ec5b381d57a1a873d423c9e6f2d6ca78c1aa1963 (patch) | |
tree | ecc6593206e6982c252ba48f4bd35aaf34bcfe36 /chrome/content | |
parent | 87b8db3e5ebf0911f613f71ce1251276ece47304 (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.js | 58 | ||||
-rw-r--r-- | chrome/content/redirector.js | 95 |
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 = { } } - }, + } }; |