From a703799580a208beac24c827fcd54b799f46a3d7 Mon Sep 17 00:00:00 2001 From: Einar Egilsson Date: Wed, 7 Oct 2009 11:24:44 +0000 Subject: Finally working normally again after massive refactoring. Disabling single redirects works but needs more GUI work. Added Redirector log file since the Error Console keeps deleting our messages. git-svn-id: http://einaregilsson.googlecode.com/svn/mozilla/redirector/trunk@253 119bf307-c92d-0410-89bd-8f53e6181181 --- chrome/content/code/redirect.js | 211 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 chrome/content/code/redirect.js (limited to 'chrome/content/code/redirect.js') diff --git a/chrome/content/code/redirect.js b/chrome/content/code/redirect.js new file mode 100644 index 0000000..740eda9 --- /dev/null +++ b/chrome/content/code/redirect.js @@ -0,0 +1,211 @@ +//// $Id$ + +function Redirect(exampleUrl, includePattern, excludePattern, patternType, unescapeMatches, disabled) { + this._init(exampleUrl, includePattern, excludePattern, patternType, unescapeMatches, disabled); +} + +//Static +Redirect.WILDCARD = 'W'; +Redirect.REGEX = 'R'; + +Redirect.prototype = { + _init : function(exampleUrl, includePattern, excludePattern, redirectUrl, patternType, unescapeMatches, disabled) { + this.exampleUrl = exampleUrl || ''; + this.includePattern = includePattern || ''; + this.excludePattern = excludePattern || ''; + this.redirectUrl = redirectUrl || ''; + this.patternType = patternType || Redirect.WILDCARD; + this.unescapeMatches = (unescapeMatches === 'true' || unescapeMatches === true); + this.disabled = (disabled === 'true' || disabled === true); + }, + + toString : function() { + return 'REDIRECT: {' + + '\n\tExample url : ' + this.exampleUrl + + '\n\tInclude pattern : ' + this.includePattern + + '\n\tExclude pattern : ' + this.excludePattern + + '\n\tRedirect url : ' + this.redirectUrl + + '\n\tPattern type : ' + this.patternType + + '\n\tUnescape matches : ' + this.unescapeMatches + + '\n\tDisabled : ' + this.disabled + + '\n}\n'; + }, + + isWildcard : function() { + return this.patternType == Redirect.WILDCARD; + }, + + isRegex: function() { + return this.patternType == Redirect.REGEX; + }, + + test : function() { + return this.getMatch(this.exampleUrl); + }, + + serialize : function() { + return [ this.exampleUrl + , this.includePattern + , this.excludePattern + , this.redirectUrl + , this.patternType + , this.unescapeMatches + , this.disabled ].join(',,,'); + }, + + deserialize : function(str) { + if (!str || !str.split) { + //TODO: THROW ERROR + } + var parts = str.split(',,,'); + if (parts.length < 5) { + ///TODO: throw + } + this._init.apply(this, parts); + }, + + getMatch: function(url) { + var result = { + isMatch : false, + isExcludeMatch : false, + isDisabledMatch : false, + redirectTo : '', + toString : function() { return "{ isMatch : " + this.isMatch + + ", isExcludeMatch : " + this.isExcludeMatch + + ", isDisabledMatch : " + this.isDisabledMatch + + ", redirectTo : \"" + this.redirectTo + "\"" + + "}"; } + }; + var redirectTo = null; + + redirectTo = this._match(url, this.includePattern, this.redirectUrl); + if (redirectTo !== null) { + if (this.disabled) { + result.isDisabledMatch = true; + } else if (this._match(url, this.excludePattern, 'exclude') == 'exclude') { + result.isExcludeMatch = true; + } else { + result.isMatch = true; + result.redirectTo = redirectTo; + } + } + return result; + }, + + _match : function(url, pattern, redirectUrl) { + if (this.isWildcard()) { + return this._wildcardMatch(url, pattern, redirectUrl); + } else { + return this._regexMatch(url, pattern, redirectUrl); + } + }, + + _wildcardMatch : function(url, pattern, redirectUrl) { + + if (!pattern || !url) { + return null; + } + if (pattern.indexOf('*') == -1) { + return (pattern == url) ? redirectUrl : null; + } + + var parts = pattern.split('*'); + var first = parts[0], + last = parts[parts.length-1]; + + if (first) { + if (url.substr(0, first.length) != first) { + return null; + } + url = url.substr(first.length); + } + + if (last) { + if (url.substr(url.length-last.length) != last) { + return null; + } + url = url.substr(0, url.length-last.length); + } + + if ((first || last) && parts.length == 2) { + return redirectUrl.replace('$1', url); + } + parts.splice(0,1); + parts.splice(parts.length-1,1); + var pos = 0, lastPos = 0; + var matches = []; + for each(part in parts) { + pos = url.indexOf(part, lastPos); + if (pos == -1) { + return null; + } + var match = url.substr(lastPos, pos-lastPos); + matches.push(match); + lastPos = pos + part.length; + } + matches.push(url.substr(lastPos)); + + return this._replaceCaptures(redirectUrl, matches); + }, + + _regexMatch : function(url, pattern, redirectUrl, unescapeMatches) { + + if (!pattern) { + return null; + } + var strings, rx, match; + try { + rx = new RegExp(pattern, 'gi'); + match = rx.exec(url); + } catch(e) { + //External users can display this to the user if they want + throw { type : 'regexPatternError', + 'pattern' : pattern, + message : "The pattern '" + pattern + "' is not a valid regular expression", + toString : function() { return this.message; } + }; + } + + var rxrepl; + + if (!match) { + return null; + } + match.splice(0,1); //First element in regex match is the whole match + return this._replaceCaptures(redirectUrl, match); + }, + + _replaceCaptures : function(redirectUrl, captures) { + for (var i = 1; i <= captures.length; i++) { + redirectUrl = redirectUrl.replace(new RegExp('\\$' + i, 'gi'), this.unescapeMatches ? unescape(captures[i-1]) : captures[i-1]); + } + return redirectUrl; + }, + + clone : function() { + return new Redirect(this.exampleUrl, this.includePattern, + this.excludePattern, this.redirectUrl, + this.patternType, this.unescapeMatches, + this.disabled); + }, + + copyValues : function(other) { + this.exampleUrl = other.exampleUrl; + this.includePattern = other.includePattern; + this.excludePattern = other.excludePattern; + this.redirectUrl = other.redirectUrl; + this.patternType = other.patternType; + this.unescapeMatches = other.unescapeMatches; + this.disabled = other.disabled; + }, + + equals : function(redirect) { + return this.exampleUrl == redirect.exampleUrl + && this.includePattern == redirect.includePattern + && this.excludePattern == redirect.excludePattern + && this.redirectUrl == redirect.redirectUrl + && this.patternType == redirect.patternType + && this.unescapeMatches == redirect.unescapeMatches + ; + } +}; \ No newline at end of file -- cgit v1.2.3-70-g09d2