aboutsummaryrefslogtreecommitdiff
path: root/chrome
diff options
context:
space:
mode:
authorEinar Egilsson2009-10-07 11:24:44 +0000
committerEinar Egilsson2009-10-07 11:24:44 +0000
commita703799580a208beac24c827fcd54b799f46a3d7 (patch)
tree5dc5b71933534189abee7bd4c40f26fbaa0c125d /chrome
parent96966ca83f96ed1babcd2bd23aa68feb63fbb7a7 (diff)
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
Diffstat (limited to 'chrome')
-rw-r--r--chrome/content/code/browserOverlay.xul.js22
-rw-r--r--chrome/content/code/editRedirect.xul.js115
-rw-r--r--chrome/content/code/redirect.js211
-rw-r--r--chrome/content/code/redirectList.xul.js122
-rw-r--r--chrome/content/code/redirector.prototype.js223
-rw-r--r--chrome/content/log.html29
-rw-r--r--chrome/content/ui/browserOverlay.xul1
-rw-r--r--chrome/content/ui/editRedirect.xul5
-rw-r--r--chrome/content/ui/redirectList.xul5
-rw-r--r--chrome/content/unittest/run.html18
-rw-r--r--chrome/content/unittest/testcases.js46
-rw-r--r--chrome/locale/en-US/editRedirect.xul.dtd2
-rw-r--r--chrome/locale/en-US/redirectList.xul.dtd1
-rw-r--r--chrome/locale/en-US/redirector.properties6
14 files changed, 493 insertions, 313 deletions
diff --git a/chrome/content/code/browserOverlay.xul.js b/chrome/content/code/browserOverlay.xul.js
index 636c02b..968e9c4 100644
--- a/chrome/content/code/browserOverlay.xul.js
+++ b/chrome/content/code/browserOverlay.xul.js
@@ -4,7 +4,6 @@ var Redirector = Components.classes["@einaregilsson.com/redirector;1"].getServic
var RedirectorOverlay = {
- id : "redirector@einaregilsson.com",
name : "Redirector",
initialized : false,
strings : null,
@@ -29,10 +28,10 @@ var RedirectorOverlay = {
Redirector.debug("Finished initialization");
this.initialized = true;
-
+
} catch(e) {
if (this.strings) {
- alert(this.strings.getFormattedString("initError", [this.name]) + "\n\n" + e);
+ alert(this.strings.getString("initError") + "\n\n" + e);
} else {
alert(e);
}
@@ -53,21 +52,18 @@ var RedirectorOverlay = {
},
onContextMenuCommand: function(event) {
-
- var item = { exampleUrl : window.content.location.href, pattern: window.content.location.href};
+ var redirect = new Redirect(window.content.location.href, window.content.location.href);
if (gContextMenu.onLink) {
- item.redirectUrl = gContextMenu.link.toString();
+ redirect.redirectUrl = gContextMenu.link.toString();
}
- window.openDialog("chrome://redirector/content/ui/editRedirect.xul",
- "redirect",
- "chrome,dialog,modal,centerscreen", item);
-
- if (item.saved) {
- Redirector.addRedirect(item);
+ var args = { saved : false, 'redirect' : redirect };
+ window.openDialog("chrome://redirector/content/ui/editRedirect.xul", "redirect", "chrome,dialog,modal,centerscreen", args);
+ if (args.saved) {
+ Redirector.addRedirect(args.redirect);
}
},
-
+
onMenuItemCommand: function(event) {
this.openSettings();
},
diff --git a/chrome/content/code/editRedirect.xul.js b/chrome/content/code/editRedirect.xul.js
index 6e981d2..e497245 100644
--- a/chrome/content/code/editRedirect.xul.js
+++ b/chrome/content/code/editRedirect.xul.js
@@ -1,48 +1,43 @@
//// $Id$
-const kRedirectorWildcard = 'W';
-const kRedirectorRegex= 'R';
var Redirector = Components.classes["@einaregilsson.com/redirector;1"].getService(Components.interfaces.nsISupports).wrappedJSObject;
-function $(id) {
- return document.getElementById(id);
-}
-
var EditRedirect = {
-
+ txtExampleUrl : null,
+ txtIncludePattern : null,
+ txtRedirectUrl : null,
+ txtExcludePattern : null,
+ chkUnescapeMatches : null,
+ rdoRegex : null,
+ rdoWildcard : null,
+
onLoad : function() {
- var item = window.arguments[0];
- item.saved = false;
- $('txtExampleUrl').value = item.exampleUrl;
- $('txtPattern').value = item.pattern;
- $('txtRedirectUrl').value = item.redirectUrl || '';
- $('txtExcludePattern').value = item.excludePattern || '';
- $('chkUnescapeMatches').setAttribute('checked', !!item.unescapeMatches);
+ var args = window.arguments[0];
+ var redirect = args.redirect;
+ this.txtExampleUrl = document.getElementById('txtExampleUrl');
+ this.txtIncludePattern = document.getElementById('txtIncludePattern');
+ this.txtRedirectUrl= document.getElementById('txtRedirectUrl');
+ this.txtExcludePattern= document.getElementById('txtExcludePattern');
+ this.chkUnescapeMatches= document.getElementById('chkUnescapeMatches');
+ this.rdoWildcard= document.getElementById('rdoWildcard');
+ this.rdoRegex = document.getElementById('rdoRegex');
+
+ this.txtExampleUrl.value = redirect.exampleUrl;
+ this.txtIncludePattern.value = redirect.includePattern;
+ this.txtExcludePattern.value = redirect.excludePattern;
+ this.txtRedirectUrl.value = redirect.redirectUrl;
+ this.chkUnescapeMatches.setAttribute('checked', redirect.unescapeMatches);
+ this.rdoRegex.setAttribute('selected', redirect.isRegex());
+ this.rdoWildcard.setAttribute('selected', redirect.isWildcard());
- $('txtPattern').focus();
+ this.txtIncludePattern.focus();
this.strings = document.getElementById("redirector-strings");
-
- if (item.patternType == kRedirectorRegex) {
- $('rdoRegex').setAttribute('selected', true);
- $('rdoWildcard').setAttribute('selected', false);
- }
},
onAccept : function() {
- var item = window.arguments[0];
-
- item.pattern = $('txtPattern').value;
- if ($('rdoRegex').selected) {
- item.patternType = kRedirectorRegex;
- } else {
- item.patternType = kRedirectorWildcard;
- }
- item.exampleUrl = $('txtExampleUrl').value;
- item.redirectUrl = $('txtRedirectUrl').value;
- item.excludePattern = $('txtExcludePattern').value;
- item.unescapeMatches = $('chkUnescapeMatches').hasAttribute('checked') && $('chkUnescapeMatches').getAttribute('checked');
- item.saved = true;
-
+ var args = window.arguments[0];
+ args.saved = true;
+ this.saveValues(args.redirect);
return true;
},
@@ -52,35 +47,29 @@ var EditRedirect = {
.alert(window, title, text);
},
+ saveValues : function(redirect) {
+ redirect.exampleUrl = this.txtExampleUrl.value;
+ redirect.includePattern = this.txtIncludePattern.value;
+ redirect.excludePattern = this.txtExcludePattern.value;
+ redirect.redirectUrl = this.txtRedirectUrl.value;
+ redirect.patternType = this.rdoRegex.getAttribute('selected') == 'true' ? Redirect.REGEX : Redirect.WILDCARD;
+ redirect.unescapeMatches = this.chkUnescapeMatches.getAttribute('checked');
+ //Disabled cannot be set here
+ },
+
testPattern : function() {
- var redirectUrl, pattern, excludePattern, example, extName, isExcluded, unescapeMatches;
- redirectUrl = $('txtRedirectUrl').value;
- pattern = $('txtPattern').value;
- excludePattern = $('txtExcludePattern').value;
- example = $('txtExampleUrl').value;
- unescapeMatches = $('chkUnescapeMatches').checked;
-
- extName = this.strings.getString('extensionName');
-
- if ($('rdoRegex').selected) {
- redirectUrl = Redirector.regexMatch(pattern, example, redirectUrl, unescapeMatches);
- if (excludePattern) {
- isExcluded = Redirector.regexMatch(excludePattern, example, 'exclude');
- }
- } else {
- redirectUrl = Redirector.wildcardMatch(pattern, example, redirectUrl, unescapeMatches);
- if (excludePattern) {
- isExcluded = Redirector.wildcardMatch(excludePattern, example, 'exclude');
- }
- }
-
- var isRedirectMatch = redirectUrl || (redirectUrl === '' && $('txtRedirectUrl').value === '');
- if (isRedirectMatch && !isExcluded) {
- this.msgBox(extName, this.strings.getFormattedString('testPatternSuccess', [pattern, example, redirectUrl]));
- } else if (isExcluded) {
- this.msgBox(extName, this.strings.getFormattedString('testPatternExclude', [example, excludePattern]));
- } else {
- this.msgBox(extName, this.strings.getFormattedString('testPatternFailure', [pattern, example]));
- }
+ try {
+ var redirect = new Redirect();
+ this.saveValues(redirect);
+ var extName = this.strings.getString('extensionName');
+ var result = redirect.test();
+ if (result.isMatch) {
+ this.msgBox(extName, this.strings.getFormattedString('testPatternSuccess', [redirect.includePattern, redirect.exampleUrl, result.redirectTo]));
+ } else if (result.isExcludeMatch) {
+ this.msgBox(extName, this.strings.getFormattedString('testPatternExclude', [redirect.exampleUrl, redirect.excludePattern]));
+ } else {
+ this.msgBox(extName, this.strings.getFormattedString('testPatternFailure', [redirect.includePattern, redirect.exampleUrl]));
+ }
+ } catch(e) {alert(e);}
}
}; \ No newline at end of file
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
diff --git a/chrome/content/code/redirectList.xul.js b/chrome/content/code/redirectList.xul.js
index 65957b4..c7ebcd7 100644
--- a/chrome/content/code/redirectList.xul.js
+++ b/chrome/content/code/redirectList.xul.js
@@ -1,55 +1,50 @@
-//// $Id$
+//// document.getElementByIdId: redirectList.xul.js 249 2009-09-15 21:41:06Z einar@einaregilsson.com document.getElementById
var Redirector = Components.classes["@einaregilsson.com/redirector;1"].getService(Components.interfaces.nsISupports).wrappedJSObject;
const Cc = Components.classes;
const Ci = Components.interfaces;
-function $(id) {
- return document.getElementById(id);
-}
-
var RedirectList = {
- id : "redirector@einaregilsson.com",
- name : "Redirector",
lstRedirects: null,
btnDelete : null,
btnEdit : null,
+ btnDisable : null,
addItemsToListBox : function(items) {
- var list = $('lstRedirects');
- var item, row, value, newItem;
+ var item, row, value, newItem;
for each (item in items) {
newItem = this.template.cloneNode(true);
- newItem.getElementsByAttribute('name', 'dscrIncludePattern')[0].setAttribute('value', item.pattern);
+ newItem.getElementsByAttribute('name', 'dscrIncludePattern')[0].setAttribute('value', item.includePattern);
newItem.getElementsByAttribute('name', 'dscrExcludePattern')[0].setAttribute('value', item.excludePattern);
newItem.getElementsByAttribute('name', 'dscrRedirectTo')[0].setAttribute('value', item.redirectUrl);
newItem.item = item;
- list.appendChild(newItem);
- newItem.setAttribute("selected", false);
+ this.lstRedirects.appendChild(newItem);
+ newItem.setAttribute('selected', false);
}
-
},
onLoad : function() {
try {
- this.lstRedirects = $('lstRedirects');
+ this.lstRedirects = document.getElementById('lstRedirects');
this.lstRedirects.selType = 'single';
this.template = document.getElementsByTagName('richlistitem')[0];
this.lstRedirects.removeChild(this.template);
- this.btnDelete = $('btnDelete');
- this.btnEdit = $('btnEdit');
+ this.btnDelete = document.getElementById('btnDelete');
+ this.btnEdit = document.getElementById('btnEdit');
+ this.btnDisable = document.getElementById('btnDisable');
this.addItemsToListBox(Redirector.list);
+ this.strings = document.getElementById('redirector-strings');
} catch(e) {
alert(e);
}
},
openHelp : function() {
- var windowName = "redirectorHelp";
+ var windowName = 'redirectorHelp';
var windowsMediator = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var win;
var iter = windowsMediator.getEnumerator(null);
@@ -93,42 +88,44 @@ var RedirectList = {
},
setListItemValues : function(listItem, item){
- listItem.getElementsByAttribute('name', 'dscrIncludePattern')[0].setAttribute('value', item.pattern);
+ listItem.getElementsByAttribute('name', 'dscrIncludePattern')[0].setAttribute('value', item.includePattern);
listItem.getElementsByAttribute('name', 'dscrExcludePattern')[0].setAttribute('value', item.excludePattern);
listItem.getElementsByAttribute('name', 'dscrRedirectTo')[0].setAttribute('value', item.redirectUrl);
},
addRedirect : function() {
-
- var item = { pattern : '', exampleUrl : '', redirectUrl : '', patternType : 'W', unescapeMatches : false};
-
- window.openDialog("chrome://redirector/content/ui/editRedirect.xul",
- "redirect",
- "chrome,dialog,modal,centerscreen", item);
-
- if (item.saved) {
- this.addItemsToListBox([item]);
- Redirector.addRedirect(item);
+ var args = { saved : false, redirect : new Redirect() };
+ window.openDialog("chrome://redirector/content/ui/editRedirect.xul", "redirect", "chrome,dialog,modal,centerscreen", args);
+ if (args.saved) {
+ this.addItemsToListBox([args.redirect]);
+ Redirector.addRedirect(args.redirect);
}
-
},
+ toggleDisabled : function() {
+ var listItem = this.lstRedirects.selectedItem;
+ if (!listItem) {
+ return;
+ }
+ var redirect = listItem.item;
+ redirect.disabled = !redirect.disabled;
+ Redirector.save();
+ this.btnDisable.setAttribute('label', this.strings.getString(redirect.disabled ? 'enable' : 'disable'));
+ },
+
editRedirect : function() {
var listItem = this.lstRedirects.selectedItem;
-
if (!listItem) {
return;
}
+ var redirect = listItem.item;
+ var args = { saved: false, "redirect":redirect.clone()};
+ window.openDialog("chrome://redirector/content/ui/editRedirect.xul", "redirect", "chrome,dialog,modal,centerscreen", args);
- var item = listItem.item;
-
- window.openDialog("chrome://redirector/content/ui/editRedirect.xul",
- "redirect",
- "chrome,dialog,modal,centerscreen", item);
-
- if (item.saved) {
- this.setListItemValues(listItem, item);
+ if (args.saved) {
+ redirect.copyValues(args.redirect);
+ this.setListItemValues(listItem, redirect);
Redirector.save();
}
},
@@ -149,45 +146,50 @@ var RedirectList = {
},
selectionChange : function() {
- var index = $('lstRedirects').selectedIndex;
+ var index = this.lstRedirects.selectedIndex;
- $('btnEdit').disabled = (index == -1);
- $('btnDelete').disabled = (index == -1);
+ this.btnEdit.disabled = (index == -1);
+ this.btnDelete.disabled = (index == -1);
+ this.btnDisable.disabled = (index == -1);
+ var redirect = this.lstRedirects.selectedItem.item;
+ try {
+ if (index != -1) {
+ this.btnDisable.setAttribute('label', this.strings.getString(redirect.disabled ? 'enable' : 'disable'));
+ this.lstRedirects.selectedItem.setAttribute('disabled', true);
+ }
+ }catch(e){alert(e);}
},
importExport : function(mode, captionKey, func) {
- //Mostly borrowed from Adblock Plus
+ //Mostly borrowed from Adblock Plus
var picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
picker.init(window, Redirector.getString(captionKey), mode);
picker.defaultExtension = ".rdx";
var dir = Redirector.getDefaultDir();
if (dir) {
- picker.displayDirectory = dir;
+ picker.displayDirectory = dir;
}
picker.appendFilter(Redirector.getString('redirectorFiles'), '*.rdx');
-
- if (picker.show() != picker.returnCancel)
- {
- try
- {
- func(picker.file);
- }
- catch (e)
- {
- alert(e);
- }
+
+ if (picker.show() == picker.returnCancel) {
+ return;
+ }
+ try {
+ func(picker.file);
+ } catch (e) {
+ alert(e);
}
},
export : function() {
- this.importExport(Ci.nsIFilePicker.modeSave, 'exportCaption', function(file) {
- Redirector.exportRedirects(file);
- });
+ this.importExport(Ci.nsIFilePicker.modeSave, 'exportCaption', function(file) {
+ Redirector.exportRedirects(file);
+ });
},
import : function() {
- this.importExport(Ci.nsIFilePicker.modeOpen, 'importCaption', function(file) {
- Redirector.importRedirects(file);
- });
+ this.importExport(Ci.nsIFilePicker.modeOpen, 'importCaption', function(file) {
+ Redirector.importRedirects(file);
+ });
}
};
diff --git a/chrome/content/code/redirector.prototype.js b/chrome/content/code/redirector.prototype.js
index 24a41ba..3f6c0fb 100644
--- a/chrome/content/code/redirector.prototype.js
+++ b/chrome/content/code/redirector.prototype.js
@@ -3,11 +3,8 @@
Cc = Components.classes;
Ci = Components.interfaces;
Cr = Components.results;
-kRedirectorWildcard = 'W';
-kRedirectorRegex= 'R';
nsIContentPolicy = Ci.nsIContentPolicy;
-
Redirector.prototype = {
prefBranch : null,
list : null,
@@ -16,7 +13,6 @@ Redirector.prototype = {
init : function() {
this.prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).getBranch("extensions.redirector.");
-
//Check if we need to update existing redirects
var data = this.prefBranch.getCharPref('redirects');
@@ -49,18 +45,11 @@ Redirector.prototype = {
this.list = [];
if (data != '') {
for each (redirectString in data.split(':::')) {
- arr = redirectString.split(',,,');
- this.list.push({
- exampleUrl : arr[0],
- pattern : arr[1],
- redirectUrl : arr[2],
- patternType : arr[3],
- excludePattern : arr[4],
- unescapeMatches : arr[5] == 'true' //This might be undefined for those upgrading from 1.7.1 but that's ok
- });
+ var redirect = new Redirect();
+ redirect.deserialize(redirectString);
+ this.list.push(redirect);
}
}
-
},
getDefaultDir : function() {
@@ -87,32 +76,41 @@ Redirector.prototype = {
// nsIContentPolicy interface implementation
shouldLoad: function(contentType, contentLocation, requestOrigin, aContext, mimeTypeGuess, extra) {
- if (!this.enabled) {
- return nsIContentPolicy.ACCEPT;
- }
- if (contentLocation.scheme != "http" && contentLocation.scheme != "https") {
- return nsIContentPolicy.ACCEPT;
- }
-
- if (contentType != nsIContentPolicy.TYPE_DOCUMENT) {
- return nsIContentPolicy.ACCEPT;
- }
-
- if (!aContext || !aContext.loadURI) {
- return nsIContentPolicy.ACCEPT;
- }
- this.debug("CHECK: " + contentLocation.spec);
-
- var url = contentLocation.spec;
-
- for each (var redirect in this.list) {
- var redirectUrl = this.getRedirectUrl(url, redirect);
- if (redirectUrl) {
- redirectUrl = this.makeAbsoluteUrl(url, redirectUrl);
- this.debug('Redirecting ' + url + ' to ' + redirectUrl);
- aContext.loadURI(redirectUrl, requestOrigin, null);
- return nsIContentPolicy.REJECT_REQUEST;
- }
+ try {
+ if (!this.enabled) {
+ return nsIContentPolicy.ACCEPT;
+ }
+ if (contentLocation.scheme != "http" && contentLocation.scheme != "https") {
+ return nsIContentPolicy.ACCEPT;
+ }
+
+ if (contentType != nsIContentPolicy.TYPE_DOCUMENT) {
+ return nsIContentPolicy.ACCEPT;
+ }
+
+ if (!aContext || !aContext.loadURI) {
+ return nsIContentPolicy.ACCEPT;
+ }
+ this.debug("Checking " + contentLocation.spec);
+
+ var url = contentLocation.spec;
+
+ for each (var redirect in this.list) {
+ //this.debug(redirect);
+ var result = redirect.getMatch(url);
+ if (result.isExcludeMatch) {
+ this.debug(url + ' matched exclude pattern ' + redirect.excludePattern + ' so the redirect ' + redirect.includePattern + ' will not be used');
+ } else if (result.isDisabledMatch) {
+ this.debug(url + ' matched pattern ' + redirect.includePattern + ' but the redirect is disabled');
+ } else if (result.isMatch) {
+ redirectUrl = this.makeAbsoluteUrl(url, result.redirectTo);
+ this.debug('Redirecting ' + url + ' to ' + redirectUrl);
+ aContext.loadURI(redirectUrl, requestOrigin, null);
+ return nsIContentPolicy.REJECT_REQUEST;
+ }
+ }
+ } catch(e) {
+ this.debug(e);
}
return nsIContentPolicy.ACCEPT;
},
@@ -128,9 +126,8 @@ Redirector.prototype = {
},
reload : function() {
- Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript('chrome://redirector/content/code/redirector.prototype.js');
+ loader.loadSubScript('chrome://redirector/content/code/redirector.prototype.js');
+ loader.loadSubScript('chrome://redirector/content/code/redirect.js');
for (var key in Redirector.prototype) {
this[key] = Redirector.prototype[key];
@@ -149,52 +146,17 @@ Redirector.prototype = {
},
save : function() {
- this.prefBranch.setCharPref('redirects', this.redirectsAsStrings().join(':::'));
+ this.prefBranch.setCharPref('redirects', this.redirectsAsString(':::'));
},
- redirectsAsStrings : function() {
- var r
- , tempList = [];
-
- for each (r in this.list) {
- this.debug(r.unescapeMatches);
- tempList.push([r.exampleUrl, r.pattern, r.redirectUrl, r.patternType, r.excludePattern, r.unescapeMatches].join(',,,'));
- }
- return tempList;
+ redirectsAsString : function(seperator) {
+ return [r.serialize() for each (r in this.list)].join(seperator);
},
getBoolPref : function(name) {
return this.prefBranch.getBoolPref(name);
},
- regexMatch : function(pattern, text, redirectUrl, unescapeMatches) {
-
- if (!pattern) {
- return null;
- }
- var strings, rx, match;
- try {
- rx = new RegExp(pattern, 'gi');
- match = rx.exec(text);
- } catch(e) {
- this.msgBox(this.strings.GetStringFromName('extensionName'), this.strings.formatStringFromName('regexPatternError', [pattern, e.toString()],2));
- return null;
- }
-
- var rxrepl;
-
- if (match) {
- for (var i = 1; i < match.length; i++) {
- rxrepl = new RegExp('\\$' + i, 'gi');
- redirectUrl = redirectUrl.replace(rxrepl, unescapeMatches ? unescape(match[i]) : match[i]);
- }
- return redirectUrl;
- }
-
- return null;
-
- },
-
exportRedirects : function(file) {
var fileStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
const PR_WRONLY = 0x02;
@@ -205,7 +167,7 @@ Redirector.prototype = {
//file.parent.QueryInterface(Ci.nsILocalFile)
var stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
- stream.writeString(this.redirectsAsStrings().join('\n'));
+ stream.writeString(this.redirectsAsString('\n'));
stream.close();
},
@@ -221,24 +183,28 @@ Redirector.prototype = {
var lines = [];
var line = {value: null};
while (stream.readLine(line)) {
- var parts = line.replace('\n', '').split(',,,');
- if (parts.length < 6) {
- var redirect = {
- exampleUrl : parts[0],
- pattern : parts[1],
- redirectUrl : parts[2],
- patternType : parts[3],
- excludePattern : parts[4],
- unescapeMatches : parts[5] == 'true' ? true : false
- };
-
-
+ var redirect = new Redirect();
+ redirect.deserialize(line.replace('\n', ''));
+ if (this.containsRedirect(redirect)) {
+ existsCount++;
+ } else {
+ this.list.push(redirect);
+ importCount++;
}
}
stream.close();
this.save();
},
+ containsRedirect : function(redirect) {
+ for each (var existing in this.list) {
+ if (existing.equals(redirect)) {
+ return true;
+ }
+ }
+ return false;
+ },
+
getString : function(name) {
return this.strings.GetStringFromName(name);
},
@@ -249,24 +215,6 @@ Redirector.prototype = {
.alert(null, title, text);
},
- getRedirectUrl: function(url, redirect) {
-
- if (redirect.patternType == kRedirectorWildcard) {
- if (this.wildcardMatch(redirect.excludePattern, url, 'whatever')) {
- this.debug(url + ' matches exclude pattern ' + redirect.excludePattern);
- return null;
- }
- return this.wildcardMatch(redirect.pattern, url, redirect.redirectUrl, redirect.unescapeMatches);
- } else if (redirect.patternType == kRedirectorRegex) {
- if (this.regexMatch(redirect.excludePattern, url, 'whatever')) {
- this.debug(url + ' matches exclude pattern ' + redirect.excludePattern);
- return null;
- }
- return this.regexMatch(redirect.pattern, url, redirect.redirectUrl, redirect.unescapeMatches);
- }
- return null;
- },
-
makeAbsoluteUrl : function(currentUrl, relativeUrl) {
if (relativeUrl.match(/https?:/)) {
@@ -278,56 +226,5 @@ Redirector.prototype = {
var uri = ioService.newURI(currentUrl, null, null);
return uri.resolve(relativeUrl);
- },
-
- wildcardMatch : function(pattern, text, redirectUrl, unescapeMatches) {
-
- if (!pattern || !text) {
- return null;
- }
- if (pattern.indexOf('*') == -1) {
- return (pattern == text) ? redirectUrl : null;
- }
-
- var parts = pattern.split('*');
- var first = parts[0],
- last = parts[parts.length-1];
-
- if (first) {
- if (text.substr(0, first.length) != first) {
- return null;
- }
- text = text.substr(first.length);
- }
-
- if (last) {
- if (text.substr(text.length-last.length) != last) {
- return null;
- }
- text = text.substr(0, text.length-last.length);
- }
-
- if ((first || last) && parts.length == 2) {
- return redirectUrl.replace('$1', text);
- }
- parts.splice(0,1);
- parts.splice(parts.length-1,1);
- var pos = 0, lastPos = 0;
- var matches = [];
- for each(part in parts) {
- pos = text.indexOf(part, lastPos);
- if (pos == -1) {
- return null;
- }
- var match = text.substr(lastPos, pos-lastPos);
- matches.push(match);
- lastPos = pos + part.length;
- }
- matches.push(text.substr(lastPos));
- for (var i = 1; i <= matches.length; i++) {
- redirectUrl = redirectUrl.replace(new RegExp('\\$' + i, 'gi'), unescapeMatches ? unescape(matches[i-1]) : matches[i-1]);
- }
-
- return redirectUrl;
}
};
diff --git a/chrome/content/log.html b/chrome/content/log.html
new file mode 100644
index 0000000..64ff726
--- /dev/null
+++ b/chrome/content/log.html
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <title>Redirector Log Message Listener
+ <style type="text/css">
+ body { font-family:Arial, sans-serif; }
+ </style>
+ </head>
+ <body onunload="unload();" onload="load();">
+ <script>
+ var listener = {
+ observe : function(msg) {
+ var prefix = 'REDIRECTOR:';
+ if (msg.message.substr(0, prefix.length) == prefix)
+ {
+ document.body.innerHTML += msg.message.substr(prefix.length) + '<br>';
+ }
+ }
+ };
+ var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
+
+ function load() {
+ consoleService.registerListener(listener);
+ }
+ function unload() {
+ consoleService.unregisterListener(listener);
+ }
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/chrome/content/ui/browserOverlay.xul b/chrome/content/ui/browserOverlay.xul
index 9a02332..f12d0ff 100644
--- a/chrome/content/ui/browserOverlay.xul
+++ b/chrome/content/ui/browserOverlay.xul
@@ -3,6 +3,7 @@
<!DOCTYPE overlay SYSTEM "chrome://redirector/locale/browserOverlay.xul.dtd">
<overlay id="redirector-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script src="../code/redirect.js"/>
<script src="../code/browserOverlay.xul.js"/>
<stringbundleset id="stringbundleset">
diff --git a/chrome/content/ui/editRedirect.xul b/chrome/content/ui/editRedirect.xul
index afca5b6..103d1b5 100644
--- a/chrome/content/ui/editRedirect.xul
+++ b/chrome/content/ui/editRedirect.xul
@@ -11,6 +11,7 @@
xmlns:nc="http://home.netscape.com/NC-rdf#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script type="application/x-javascript" src="../code/redirect.js"/>
<script type="application/x-javascript" src="../code/editRedirect.xul.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="redirector-strings" src="chrome://redirector/locale/redirector.properties"/>
@@ -23,8 +24,8 @@
<textbox id="txtExampleUrl" style="width:400px;"/>
</row>
<row align="center">
- <text value="&txtPattern.label;" style="margin-top:6px;"/>
- <textbox id="txtPattern" taborder="1"/>
+ <text value="&txtIncludePattern.label;" style="margin-top:6px;"/>
+ <textbox id="txtIncludePattern" taborder="1"/>
<button id="btnTestPattern" label="&btnTestPattern.label;" onclick="EditRedirect.testPattern();" taborder="2"/>
</row>
<row align="center">
diff --git a/chrome/content/ui/redirectList.xul b/chrome/content/ui/redirectList.xul
index 29d5ceb..643a699 100644
--- a/chrome/content/ui/redirectList.xul
+++ b/chrome/content/ui/redirectList.xul
@@ -12,7 +12,11 @@
xmlns:nc="http://home.netscape.com/NC-rdf#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script type="application/x-javascript" src="../code/redirect.js"/>
<script type="application/x-javascript" src="../code/redirectList.xul.js"/>
+ <stringbundleset id="stringbundleset">
+ <stringbundle id="redirector-strings" src="chrome://redirector/locale/redirector.properties"/>
+ </stringbundleset>
<vbox>
<richlistbox seltype="single" id="lstRedirects" style="margin-bottom:5px; border:solid 1px grey;" height="330px" ondblclick="RedirectList.editRedirect();" onselect="RedirectList.selectionChange();">
@@ -41,6 +45,7 @@
<button id="btnAdd" onclick="RedirectList.addRedirect();" label="&btnAdd.label;" disabled="false" />
<button id="btnEdit" onclick="RedirectList.editRedirect();" label="&btnEdit.label;" disabled="true" />
<button id="btnDelete" onclick="RedirectList.deleteRedirect();" label="&btnDelete.label;" disabled="true" />
+ <button id="btnDisable" onclick="RedirectList.toggleDisabled();" label="&btnDisable.label;" disabled="true" />
<button id="btnImport" onclick="RedirectList.import();" label="&btnImport.label;"/>
<button id="btnExport" onclick="RedirectList.export();" label="&btnExport.label;"/>
<button id="btnHelp" onclick="RedirectList.openHelp();" label="&btnHelp.label;"/>
diff --git a/chrome/content/unittest/run.html b/chrome/content/unittest/run.html
index 2c4f968..5658137 100644
--- a/chrome/content/unittest/run.html
+++ b/chrome/content/unittest/run.html
@@ -6,7 +6,7 @@
body { font-family: Verdana, Arial; color:black; background-color:white; font-size:0.8em; width:800px; margin:auto; text-align:center;}
a { color:blue; }
h1 { text-align:center; margin:10px 0px; }
- table { margin:auto; border:solid 1px black; width:700px; border-collapse:collapse;}
+ table { margin:10px auto; border:solid 1px black; width:700px; border-collapse:collapse;}
td { border:solid 1px black; padding:3px; }
td.result { width:20px; height:20px; padding:0;}
td.result div { width:70%; height:70%; margin:auto; }
@@ -50,7 +50,7 @@
for (var i = 0; i < tables.length; i++) {
tables[i].parentNode.removeChild(tables[i]);
}
-
+ subscriptLoader.loadSubScript('chrome://redirector/content/code/redirect.js');
subscriptLoader.loadSubScript('chrome://redirector/content/unittest/testcases.js');
redirector.reload();
@@ -64,14 +64,20 @@
var testcase = tests[testcaseName];
for (var i = 0; i < testcase.tests.length; i++) {
try {
+ var dot = document.getElementById(testcaseName + '_' + i);
var result = testcase.run(testcase.tests[i]);
- if (result) {
- document.getElementById(testcaseName + '_' + i).style.backgroundColor = '#17f816';
+ if (result && result.passed) {
+ dot.style.backgroundColor = '#17f816';
} else {
- document.getElementById(testcaseName + '_' + i).style.backgroundColor = '#ff0000';
+ dot.style.backgroundColor = '#ff0000';
+ if (result && result.message) {
+ dot.parentNode.nextSibling.innerHTML += '<br/><span style="color:red;">' + result.message + '</span>';
+ }
}
} catch(e) {
- document.getElementById(testcaseName + '_' + i).style.backgroundColor = '#ff0000';
+ dot.style.backgroundColor = '#ff0000';
+ dot.parentNode.nextSibling.innerHTML += '<br/><span style="color:red;">' + e + '</span>';
+ ;
}
}
}
diff --git a/chrome/content/unittest/testcases.js b/chrome/content/unittest/testcases.js
index ea6e26b..ac9539f 100644
--- a/chrome/content/unittest/testcases.js
+++ b/chrome/content/unittest/testcases.js
@@ -1,7 +1,7 @@
//// $Id$
var tests = {
"Wildcard matches" : {
- run : function(data) {
+ run : function(data,log) {
var pattern = data[0],
url = data[1],
expected = data[2];
@@ -13,8 +13,9 @@ var tests = {
}
redirectUrl = redirectUrl.substr(0, redirectUrl.length-1);
}
- var result = redirector.wildcardMatch(pattern, url, redirectUrl, false);
- return result == expected;
+ var redirect = new Redirect(null, pattern, null, redirectUrl, Redirect.WILDCARD, null);
+ var result = redirect.getMatch(url);
+ return { passed: result.isMatch && (result.redirectTo == expected), message : "Expected '" + expected + "', actual was '" + result.redirectTo + "'"};
},
describe : function(data) { return data[0] + ' == ' + data[1] + ', matches=' + data[2]; },
@@ -35,5 +36,44 @@ var tests = {
['*://*oo*bar*', 'http://foo.is/bar/baz', 'http,f,.is/,/baz'],
['*://**oo*bar*', 'http://foo.is/bar/baz', 'http,,f,.is/,/baz'],
]
+ },
+
+ "Regex matches" : {
+ run : function(data,log) {
+ var pattern = data[0],
+ url = data[1],
+ expected = data[2];
+ var parts = expected.split(',');
+ var redirectUrl = '';
+ if (!(parts.length == 1 && parts[0] == '')) {
+ for (var i in parts) {
+ redirectUrl += '$' + (parseFloat(i)+1) + ',';
+ }
+ redirectUrl = redirectUrl.substr(0, redirectUrl.length-1);
+ }
+ var redirect = new Redirect(null, pattern, null, redirectUrl, Redirect.REGEX, null);
+ var result = redirect.getMatch(url);
+ return { passed: result.isMatch && result.redirectTo == expected, message : "Expected '" + expected + "', actual was '" + result.redirectTo + "'"};
+ },
+
+ describe : function(data) { return data[0] + ' == ' + data[1] + ', matches=' + data[2]; },
+ tests : [
+ ['http://foo(.*)', 'http://foobar.is', 'bar.is'],
+ ['http://foo(.*)', 'http://foo', ''],
+ ['(.*)://foo.is', 'http://foo.is', 'http'],
+ ['(.*)http://foo\\.is', 'http://foo.is', ''],
+ ['http(.*)foo(.*)', 'http://foobar.is', '://,bar.is'],
+ ['http(.*)foo(.*)', 'http://foo', '://,'],
+ ['(.*)://f(.*)\\.is', 'http://foo.is', 'http,oo'],
+ ['(.*)http://f(.*)\\.is', 'http://foo.is', ',oo'],
+ ['(.*)foo(.*)', 'http://foo', 'http://,'],
+ ['(.*)foo(.*)', 'foobar.is', ',bar.is'],
+ ['(.*)foo(.*)', 'http://foobar.is', 'http://,bar.is'],
+ ['http://foo\.is', 'http://foo.is', ''],
+ ['(.*)', 'http://foo.is', 'http://foo.is'],
+ ['(.*)://(.*)oo(.*)bar(.*)', 'http://foo.is/bar/baz', 'http,f,.is/,/baz'],
+ ['(.*)://(.*?)(.*)oo(.*)bar(.*)', 'http://foo.is/bar/baz', 'http,,f,.is/,/baz'],
+ ]
}
+
};
diff --git a/chrome/locale/en-US/editRedirect.xul.dtd b/chrome/locale/en-US/editRedirect.xul.dtd
index 40098b8..4b48d9c 100644
--- a/chrome/locale/en-US/editRedirect.xul.dtd
+++ b/chrome/locale/en-US/editRedirect.xul.dtd
@@ -1,7 +1,7 @@
<!-- $Id$ -->
<!ENTITY redirectWindow.title "Redirect">
<!ENTITY txtExampleUrl.label "Example url">
-<!ENTITY txtPattern.label "Include Pattern">
+<!ENTITY txtIncludePattern.label "Include Pattern">
<!ENTITY txtExcludePattern.label "Exclude Pattern">
<!ENTITY txtRedirectUrl.label "Redirect to">
<!ENTITY btnTestPattern.label "Test pattern">
diff --git a/chrome/locale/en-US/redirectList.xul.dtd b/chrome/locale/en-US/redirectList.xul.dtd
index e09b038..5379647 100644
--- a/chrome/locale/en-US/redirectList.xul.dtd
+++ b/chrome/locale/en-US/redirectList.xul.dtd
@@ -6,6 +6,7 @@
<!ENTITY btnAdd.label "Add...">
<!ENTITY btnEdit.label "Edit...">
<!ENTITY btnDelete.label "Delete">
+<!ENTITY btnDisable.label "Disable">
<!ENTITY btnClose.label "Close">
<!ENTITY btnHelp.label "Help">
<!ENTITY btnImport.label "Import...">
diff --git a/chrome/locale/en-US/redirector.properties b/chrome/locale/en-US/redirector.properties
index 0e10390..6b4ecf7 100644
--- a/chrome/locale/en-US/redirector.properties
+++ b/chrome/locale/en-US/redirector.properties
@@ -1,5 +1,5 @@
# $Id$
-initError=Failed to initialize %S.
+initError=Failed to initialize Redirector.
extensions.redirector@einaregilsson.com.description=Automatically redirects to user-defined urls on certain pages
extensionName=Redirector
addCurrentUrl=Add current url to Redirector
@@ -14,4 +14,6 @@ regexPatternError=The pattern '%S' is not a legal regular expression pattern. De
xpathDeprecated=XPath patterns are no longer supported as of version 1.5.1, please remove those redirects.
redirectorFiles=Redirector files (*.rdx)
exportCaption=Export redirects...
-importCaption=Import redirects... \ No newline at end of file
+importCaption=Import redirects...
+disable=Disable
+enable=Enable \ No newline at end of file