diff options
Diffstat (limited to 'chrome/content/code/redirect.js')
-rw-r--r-- | chrome/content/code/redirect.js | 211 |
1 files changed, 211 insertions, 0 deletions
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 |