diff options
author | Einar Egilsson | 2009-10-07 11:24:44 +0000 |
---|---|---|
committer | Einar Egilsson | 2009-10-07 11:24:44 +0000 |
commit | a703799580a208beac24c827fcd54b799f46a3d7 (patch) | |
tree | 5dc5b71933534189abee7bd4c40f26fbaa0c125d /chrome | |
parent | 96966ca83f96ed1babcd2bd23aa68feb63fbb7a7 (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.js | 22 | ||||
-rw-r--r-- | chrome/content/code/editRedirect.xul.js | 115 | ||||
-rw-r--r-- | chrome/content/code/redirect.js | 211 | ||||
-rw-r--r-- | chrome/content/code/redirectList.xul.js | 122 | ||||
-rw-r--r-- | chrome/content/code/redirector.prototype.js | 223 | ||||
-rw-r--r-- | chrome/content/log.html | 29 | ||||
-rw-r--r-- | chrome/content/ui/browserOverlay.xul | 1 | ||||
-rw-r--r-- | chrome/content/ui/editRedirect.xul | 5 | ||||
-rw-r--r-- | chrome/content/ui/redirectList.xul | 5 | ||||
-rw-r--r-- | chrome/content/unittest/run.html | 18 | ||||
-rw-r--r-- | chrome/content/unittest/testcases.js | 46 | ||||
-rw-r--r-- | chrome/locale/en-US/editRedirect.xul.dtd | 2 | ||||
-rw-r--r-- | chrome/locale/en-US/redirectList.xul.dtd | 1 | ||||
-rw-r--r-- | chrome/locale/en-US/redirector.properties | 6 |
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 |