aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEinar Egilsson2011-08-26 14:37:27 +0200
committerEinar Egilsson2011-08-26 14:37:27 +0200
commit3ac1838cba725705a96a9d7b65721b15f4ec67b1 (patch)
tree6eea260d1e5882ba1031c5bb78bd2b9ac0884fb9
parent5aefd85d7975c8934b32a30a1dec68aa421cdee3 (diff)
Moved everything to a js module, removed custom xpcom interfaces
-rw-r--r--build.py2
-rw-r--r--chrome.manifest17
-rw-r--r--chrome/code/browserOverlay.xul.js104
-rw-r--r--chrome/code/component.js21
-rw-r--r--chrome/code/editRedirect.xul.js103
-rw-r--r--chrome/code/redirect.js218
-rw-r--r--chrome/code/redirector.js (renamed from chrome/content/code/redirector.prototype.js)713
-rw-r--r--chrome/code/redirectorprefs.js93
-rw-r--r--chrome/code/settings.xul.js276
-rw-r--r--chrome/code/unittest/run.html99
-rw-r--r--chrome/code/unittest/testcases.js129
-rw-r--r--chrome/ui/browserOverlay.xul34
-rw-r--r--chrome/ui/editRedirect.xul58
-rw-r--r--chrome/ui/help.html182
-rw-r--r--chrome/ui/settings.xul118
-rw-r--r--chrome/ui/skin/movedown.pngbin0 -> 294 bytes
-rw-r--r--chrome/ui/skin/movedowndisabled.pngbin0 -> 361 bytes
-rw-r--r--chrome/ui/skin/moveup.pngbin0 -> 360 bytes
-rw-r--r--chrome/ui/skin/moveupdisabled.pngbin0 -> 282 bytes
-rw-r--r--chrome/ui/skin/redirector.css15
-rw-r--r--chrome/ui/skin/redirector.pngbin0 -> 1462 bytes
-rw-r--r--chrome/ui/skin/statusactive.pngbin0 -> 360 bytes
-rw-r--r--chrome/ui/skin/statusinactive.pngbin0 -> 396 bytes
-rw-r--r--components/interfaces/nsIFile.idl343
-rw-r--r--components/interfaces/nsISimpleEnumerator.idl81
-rw-r--r--components/interfaces/nsISupports.idl77
-rw-r--r--components/interfaces/nsrootidl.idl128
-rw-r--r--components/interfaces/rdIMatchResult.idl13
-rw-r--r--components/interfaces/rdIRedirect.idl29
-rw-r--r--components/interfaces/rdIRedirector.idl23
-rw-r--r--components/interfaces/xpidl.exebin487424 -> 0 bytes
-rw-r--r--install.rdf4
-rw-r--r--locale/en-US/browserOverlay.xul.dtd9
-rw-r--r--locale/en-US/editRedirect.xul.dtd14
-rw-r--r--locale/en-US/redirector.properties33
-rw-r--r--locale/en-US/settings.xul.dtd65
-rw-r--r--locale/zh-CN/browserOverlay.xul.dtd9
-rw-r--r--locale/zh-CN/editRedirect.xul.dtd14
-rw-r--r--locale/zh-CN/redirector.properties33
-rw-r--r--locale/zh-CN/settings.xul.dtd65
40 files changed, 2071 insertions, 1051 deletions
diff --git a/build.py b/build.py
index 886151c..2454945 100644
--- a/build.py
+++ b/build.py
@@ -6,7 +6,7 @@ for f in os.listdir('.'):
os.system(r'xpidl -m typelib -e ..\%s %s' % (f[:-3] + 'xpt',f))
os.chdir(r'..\..')
-xpi = zipfile.ZipFile('redirector-2.5.2.xpi','w')
+xpi = zipfile.ZipFile('redirector-2.6.xpi','w')
for (root, folders, files) in os.walk('.'):
if not '.svn' in root:
for f in files:
diff --git a/chrome.manifest b/chrome.manifest
index bc60f58..3ca72f2 100644
--- a/chrome.manifest
+++ b/chrome.manifest
@@ -1,17 +1,12 @@
-# $Id$
-content redirector file:chrome/content/
-locale redirector en-US file:chrome/locale/en-US/
-locale redirector zh-CN file:chrome/locale/zh-CN/
-skin redirector classic/1.0 file:chrome/skin/
-overlay chrome://browser/content/browser.xul chrome://redirector/content/ui/browserOverlay.xul
+content redirector file:chrome/
+locale redirector en-US file:locale/en-US/
+locale redirector zh-CN file:locale/zh-CN/
+skin redirector classic/1.0 file:chrome/ui/skin/
-#FF4 registration
-interfaces components/rdIMatchResult.xpt
-interfaces components/rdIRedirect.xpt
-interfaces components/rdIRedirector.xpt
+overlay chrome://browser/content/browser.xul chrome://redirector/content/ui/browserOverlay.xul
-component {b7a7a54f-0581-47ff-b086-d6920cb7a3f7} components/redirector.component.js
+component {b7a7a54f-0581-47ff-b086-d6920cb7a3f7} chrome/code/component.js
contract @einaregilsson.com/redirector;1 {b7a7a54f-0581-47ff-b086-d6920cb7a3f7}
category profile-after-change Redirector @einaregilsson.com/redirector;1
category content-policy Redirector @einaregilsson.com/redirector;1
diff --git a/chrome/code/browserOverlay.xul.js b/chrome/code/browserOverlay.xul.js
new file mode 100644
index 0000000..0d2f46e
--- /dev/null
+++ b/chrome/code/browserOverlay.xul.js
@@ -0,0 +1,104 @@
+
+Components.utils.import("chrome://redirector/content/code/redirector.js");
+
+var RedirectorOverlay = {
+
+ strings : null,
+ prefs : null,
+
+ onLoad : function(event) {
+ try {
+
+ // initialization code
+ document.getElementById('contentAreaContextMenu')
+ .addEventListener("popupshowing", function(e) { RedirectorOverlay.showContextMenu(e); }, false);
+
+ this.strings = document.getElementById("redirector-strings");
+ this.prefs = new RedirectorPrefs();
+ this.changedPrefs(this.prefs);
+ this.prefs.addListener(this);
+ } catch(e) {
+ if (this.strings) {
+ alert(this.strings.getString("initError") + "\n\n" + e);
+ } else {
+ alert(e);
+ }
+ }
+ },
+
+ onUnload : function(event) {
+ this.prefs.dispose();
+ Redirector.debug("Finished cleanup");
+ },
+
+ changedPrefs : function(prefs) {
+ var statusImg = document.getElementById('redirector-statusbar-img');
+
+ if (prefs.enabled) {
+ statusImg.src = 'chrome://redirector/skin/statusactive.png'
+ statusImg.setAttribute('tooltiptext', this.strings.getString('enabledTooltip'));
+ } else {
+ statusImg.src = 'chrome://redirector/skin/statusinactive.png'
+ statusImg.setAttribute('tooltiptext', this.strings.getString('disabledTooltip'));
+ }
+
+ document.getElementById('redirector-status').hidden = !prefs.showStatusBarIcon;
+ document.getElementById('redirector-context').hidden = !prefs.showContextMenu;
+ },
+
+ showContextMenu : function(event) {
+ if (gContextMenu.onLink) {
+ document.getElementById("redirector-context").label = this.strings.getString('addLinkUrl');
+ } else {
+ document.getElementById("redirector-context").label = this.strings.getString('addCurrentUrl');
+ }
+ },
+
+ onContextMenuCommand: function(event) {
+ var redirect = new Redirect(window.content.location.href, window.content.location.href);
+ if (gContextMenu.onLink) {
+ redirect.redirectUrl = gContextMenu.link.toString();
+ }
+
+ 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();
+ },
+
+ toggleEnabled : function(event) {
+ this.prefs.enabled = !this.prefs.enabled;
+ },
+
+ openSettings : function() {
+ var windowName = "redirectorSettings";
+ var windowsMediator = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
+ var win = windowsMediator.getMostRecentWindow(windowName);
+ if (win) {
+ win.focus();
+ } else {
+ window.openDialog("chrome://redirector/content/ui/settings.xul",
+ windowName,
+ "chrome,dialog,resizable=yes,centerscreen", this);
+ }
+
+ },
+
+ statusBarClick : function(event) {
+ var LEFT = 0, RIGHT = 2;
+
+ if (event.button == LEFT) {
+ RedirectorOverlay.toggleEnabled();
+ } else if (event.button == RIGHT) {
+ this.openSettings();
+ }
+ }
+
+};
+window.addEventListener("load", function(event) { RedirectorOverlay.onLoad(event); }, false);
+window.addEventListener("unload", function(event) { RedirectorOverlay.onUnload(event); }, false);
diff --git a/chrome/code/component.js b/chrome/code/component.js
new file mode 100644
index 0000000..453d134
--- /dev/null
+++ b/chrome/code/component.js
@@ -0,0 +1,21 @@
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Ci = Components.interfaces;
+Cr = Components.results;
+
+Components.utils.import("chrome://redirector/content/code/redirector.js");
+
+function RedirectorComponent() { }
+
+RedirectorComponent.prototype = {
+ classDescription: "My Hello World Javascript XPCOM Component",
+ classID: Components.ID("{b7a7a54f-0581-47ff-b086-d6920cb7a3f7}"),
+ contractID: "@einaregilsson.com/redirector;1",
+ QueryInterface: function(iid) {
+ if (iid.equals(Ci.nsISupports) || iid.equals(Ci.nsIContentPolicy) || iid.equals(Ci.nsIChannelEventSink)) {
+ return Redirector;
+ }
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+};
+
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([RedirectorComponent]);
diff --git a/chrome/code/editRedirect.xul.js b/chrome/code/editRedirect.xul.js
new file mode 100644
index 0000000..0c8f34b
--- /dev/null
+++ b/chrome/code/editRedirect.xul.js
@@ -0,0 +1,103 @@
+//// $Id$
+
+var EditRedirect = {
+ txtExampleUrl : null,
+ txtIncludePattern : null,
+ txtRedirectUrl : null,
+ txtExcludePattern : null,
+ chkUnescapeMatches : null,
+ rdoRegex : null,
+ rdoWildcard : null,
+
+ onLoad : function() {
+ 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());
+
+ this.txtIncludePattern.focus();
+ this.strings = document.getElementById("redirector-strings");
+ },
+
+ onAccept : function() {
+ var args = window.arguments[0];
+ var msg, title;
+ args.saved = true;
+ this.saveValues(args.redirect);
+
+ var oldDisabled = args.redirect.disabled;
+ args.redirect.disabled = false;
+ if (!/^\s*$/.test(args.redirect.exampleUrl)) {
+ var result = args.redirect.getMatch(args.redirect.exampleUrl);
+ if (!result.isMatch) {
+ title = this.strings.getString('warningExampleUrlDoesntMatchPatternTitle');
+ msg = this.strings.getString('warningExampleUrlDoesntMatchPattern');
+ var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
+ var rv = ps.confirmEx(window, title, msg, ps.STD_YES_NO_BUTTONS, ps.BUTTON_TITLE_YES, ps.BUTTON_TITLE_NO, null, null, {});
+ return rv == 0;
+ } else {
+ var resultUrl = result.redirectTo;
+ if (!resultUrl.match(/https?:/)) {
+ var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
+ var uri = ioService.newURI(args.redirect.exampleUrl, null, null);
+ resultUrl = uri.resolve(resultUrl);
+ }
+
+ var secondResult = args.redirect.getMatch(resultUrl);
+ if (secondResult.isMatch) {
+ title = this.strings.getString('errorExampleUrlMatchesRecursiveTitle');
+ msg = this.strings.getFormattedString('errorExampleUrlMatchesRecursive', [args.redirect.exampleUrl, resultUrl]);
+ this.msgBox(title, msg);
+ return false;
+ }
+ }
+ }
+ return true;
+ },
+
+ msgBox : function(title, text) {
+ Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService)
+ .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;
+ var val = this.chkUnescapeMatches.getAttribute('checked');
+ redirect.unescapeMatches = val === 'true' || val === true;
+ //Disabled cannot be set here
+ },
+
+ testPattern : function() {
+ 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/code/redirect.js b/chrome/code/redirect.js
new file mode 100644
index 0000000..f9b7f00
--- /dev/null
+++ b/chrome/code/redirect.js
@@ -0,0 +1,218 @@
+
+var EXPORTED_SYMBOLS = ['Redirect'];
+
+
+function Redirect(exampleUrl, includePattern, redirectUrl, patternType, excludePattern, unescapeMatches, disabled) {
+ this._init(exampleUrl, includePattern, redirectUrl, patternType, excludePattern, unescapeMatches, disabled);
+}
+
+//Static
+Redirect.WILDCARD = 'W';
+Redirect.REGEX = 'R';
+
+Redirect.prototype = {
+
+ //attributes
+ exampleUrl : null,
+
+ get includePattern() { return this._includePattern; },
+ set includePattern(value) {
+ this._includePattern = value;
+ this._rxInclude = this._compile(value);
+ },
+
+ get excludePattern() { return this._excludePattern; },
+ set excludePattern(value) {
+ this._excludePattern = value;
+ this._rxExclude = this._compile(value);
+ },
+
+ redirectUrl : null,
+
+ get patternType() { return this._patternType; },
+ set patternType(value) {
+ this._patternType = value;
+ this.compile();
+ },
+
+ unescapeMatches : false,
+
+ disabled : false,
+
+ //Functions
+ clone : function() {
+ return new Redirect(this.exampleUrl, this.includePattern,
+ this.redirectUrl, this.patternType,
+ this.excludePattern, this.unescapeMatches,
+ this.disabled);
+ },
+
+ compile : function() {
+ this._rxInclude = this._compile(this._includePattern);
+ this._rxExclude = this._compile(this._excludePattern);
+ },
+
+ 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;
+ },
+
+ deserialize : function(str) {
+ if (!str || !str.split) {
+ throw Error("Invalid serialized redirect: " + str);
+ }
+ var parts = str.split(',,,');
+ if (parts.length < 5) {
+ throw Error("Invalid serialized redirect, too few fields: " + str);
+ }
+ this._init.apply(this, parts);
+ },
+
+ 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
+ ;
+ },
+
+ 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._includeMatch(url);
+ if (redirectTo !== null) {
+ if (this.disabled) {
+ result.isDisabledMatch = true;
+ } else if (this._excludeMatch(url)) {
+ result.isExcludeMatch = true;
+ } else {
+ result.isMatch = true;
+ result.redirectTo = redirectTo;
+ }
+ }
+ return result;
+ },
+
+ isRegex: function() {
+ return this.patternType == Redirect.REGEX;
+ },
+
+ isWildcard : function() {
+ return this.patternType == Redirect.WILDCARD;
+ },
+
+ serialize : function() {
+ return [ this.exampleUrl
+ , this.includePattern
+ , this.redirectUrl
+ , this.patternType
+ , this.excludePattern
+ , this.unescapeMatches
+ , this.disabled ].join(',,,');
+ },
+
+ test : function() {
+ return this.getMatch(this.exampleUrl);
+ },
+
+
+ //Private functions below
+
+ _includePattern : null,
+ _excludePattern : null,
+ _patternType : null,
+ _rxInclude : null,
+ _rxExclude : null,
+
+ _preparePattern : function(pattern) {
+ if (this.patternType == Redirect.REGEX) {
+ return pattern;
+ } else { //Convert wildcard to regex pattern
+ var converted = '^';
+ for (var i = 0; i < pattern.length; i++) {
+ var ch = pattern.charAt(i);
+ if ('()[]{}?.^$\\+'.indexOf(ch) != -1) {
+ converted += '\\' + ch;
+ } else if (ch == '*') {
+ converted += '(.*?)';
+ } else {
+ converted += ch;
+ }
+ }
+ converted += '$';
+ return converted;
+ }
+ },
+
+ _compile : function(pattern) {
+ if (!pattern) {
+ return null;
+ }
+ return new RegExp(this._preparePattern(pattern),"gi");
+ },
+
+ _init : function(exampleUrl, includePattern, redirectUrl, patternType, excludePattern, 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';
+ },
+
+ _includeMatch : function(url) {
+ if (!this._rxInclude) {
+ return null;
+ }
+ var matches = this._rxInclude.exec(url);
+ if (!matches) {
+ return null;
+ }
+ var resultUrl = this.redirectUrl;
+ for (var i = 1; i < matches.length; i++) {
+ resultUrl = resultUrl.replace(new RegExp('\\$' + i, 'gi'), this.unescapeMatches ? unescape(matches[i]) : matches[i]);
+ }
+ this._rxInclude.lastIndex = 0;
+ return resultUrl;
+ },
+
+ _excludeMatch : function(url) {
+ if (!this._rxExclude) {
+ return false;
+ }
+ var shouldExclude = !!this._rxExclude.exec(url);
+ this._rxExclude.lastIndex = 0;
+ return shouldExclude;
+ }
+}; \ No newline at end of file
diff --git a/chrome/content/code/redirector.prototype.js b/chrome/code/redirector.js
index be920d8..8744483 100644
--- a/chrome/content/code/redirector.prototype.js
+++ b/chrome/code/redirector.js
@@ -1,343 +1,370 @@
-//// $Id$
-
-Redirector.prototype = {
-
- //rdIRedirector implementation
- get enabled() {
- return this._prefs && this._prefs.enabled;
- },
-
- set enabled(value) {
- if (this._prefs) {
- this._prefs.enabled = value;
- }
- },
-
- get redirectCount() {
- return this._list.length;
- },
-
- addRedirect : function(redirect) {
- //This runaround is necessary because the redirect
- //that was created somewhere up in the GUI doesn't
- //have the Redirect function in scope.
- var rx = new Redirect();
- rx.copyValues(redirect);
- this._list.push(rx);
- this.save();
- },
-
- debug : function(msg) {
- if (this._prefs.debugEnabled) {
- this._cout.logStringMessage('REDIRECTOR: ' + msg);
- }
- },
-
- deleteRedirectAt : function(index) {
- this._list.splice(index, 1);
- this.save();
- },
-
- exportRedirects : function(file) {
- var fileStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
- const PR_WRONLY = 0x02;
- const PR_CREATE_FILE = 0x08;
- const PR_TRUNCATE = 0x20;
-
- fileStream.init(file, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0644, 0);
- 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._redirectsAsString('\n'));
- stream.close();
- },
-
- getRedirectAt : function(index) {
- return this._list[index];
- },
-
- //Get the redirect url for the given url. This will not check if we are enabled, and
- //not do any verification on the url, just assume that it is a good string url that is for http/s
- getRedirectUrl : function(url) {
- this.debug("Checking " + url);
-
- for each (var redirect in this._list) {
- 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);
-
- //check for loops...
- result = redirect.getMatch(redirectUrl);
- if (result.isMatch) {
- var title = this._getString('invalidRedirectTitle');
- var msg = this._getFormattedString('invalidRedirectText', [redirect.includePattern, url, redirectUrl]);
- this.debug(msg);
- redirect.disabled = true;
- this.save();
- this._msgBox(title, msg);
- } else {
- this.debug('Redirecting ' + url + ' to ' + redirectUrl);
- return redirectUrl;
- }
- }
- }
- return null;
- },
-
- importRedirects : function(file) {
- var fileStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
- fileStream.init(file, 0x01, 0444, 0); //TODO: Find the actual constants for these magic numbers
-
- var stream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
- stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
- stream = stream.QueryInterface(Ci.nsIUnicharLineInputStream);
-
- var importCount = 0, existsCount = 0;
- var lines = [];
- var line = {value: null};
- stream.readLine(line);
- while (line.value) {
- var redirect = new Redirect();
- redirect.deserialize(line.value.replace('\n', ''));
- if (this._containsRedirect(redirect)) {
- existsCount++;
- } else {
- this._list.push(redirect);
- importCount++;
- }
- stream.readLine(line);
- }
- stream.close();
- this.save();
- return importCount | (existsCount << 16);
- },
-
- reload : function() {
- loader.loadSubScript('chrome://redirector/content/code/redirector.prototype.js');
- loader.loadSubScript('chrome://redirector/content/code/redirect.js');
- var oldEnabled = this.enabled;
- for (var key in Redirector.prototype) {
- if (key != 'redirectCount' && key != 'enabled') {
- this[key] = Redirector.prototype[key];
- }
- }
- this._init();
- this.enabled = oldEnabled;
- },
-
- save : function() {
- this._prefs.redirects = this._redirectsAsString(':::');
- },
-
- switchItems : function(index1, index2) {
- var item = this._list[index1];
- this._list[index1] = this._list[index2];
- this._list[index2] = item;
- this.save();
- },
-
- //End rdIRedirector
-
- // nsIContentPolicy implementation
- shouldLoad: function(contentType, contentLocation, requestOrigin, aContext, mimeTypeGuess, extra) {
- rdump('nsIContentPolicy::ShouldLoad ' + contentLocation.spec);
- try {
- //This is also done in getRedirectUrl, but we want to exit as quickly as possible for performance
- if (!this._prefs.enabled) {
- return Ci.nsIContentPolicy.ACCEPT;
- }
-
- if (contentType != Ci.nsIContentPolicy.TYPE_DOCUMENT) {
- return Ci.nsIContentPolicy.ACCEPT;
- }
-
- if (contentLocation.scheme != "http" && contentLocation.scheme != "https") {
- return Ci.nsIContentPolicy.ACCEPT;
- }
-
- if (!aContext || !aContext.loadURI) {
- return Ci.nsIContentPolicy.ACCEPT;
- }
-
- var redirectUrl = this.getRedirectUrl(contentLocation.spec);
-
- if (!redirectUrl) {
- return Ci.nsIContentPolicy.ACCEPT;
- }
-
- aContext.loadURI(redirectUrl, requestOrigin, null);
- return Ci.nsIContentPolicy.REJECT_REQUEST;
- } catch(e) {
- this.debug(e);
- }
-
- },
-
- shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra) {
- return Ci.nsIContentPolicy.ACCEPT;
- },
- //end nsIContentPolicy
-
- //nsIChannelEventSink implementation
-
- //For FF4.0. Got this from a thread about adblock plus, https://adblockplus.org/forum/viewtopic.php?t=5895
- asyncOnChannelRedirect: function(oldChannel, newChannel, flags, redirectCallback) {
- this.onChannelRedirect(oldChannel, newChannel, flags);
- redirectCallback.onRedirectVerifyCallback(0);
- },
-
- onChannelRedirect: function(oldChannel, newChannel, flags)
- {
- try {
- let newLocation = newChannel.URI.spec;
- rdump('nsIChannelEventSink::onChannelRedirect ' + newLocation);
-
- if (!(newChannel.loadFlags & Ci.nsIChannel.LOAD_DOCUMENT_URI)) {
- //We only redirect documents...
- return;
- }
-
- if (!this._prefs.enabled) {
- return;
- }
-
- if (!newLocation) {
- return;
- }
- let callbacks = [];
- if (newChannel.notificationCallbacks) {
- callbacks.push(newChannel.notificationCallbacks);
- }
- if (newChannel.loadGroup && newChannel.loadGroup.notificationCallbacks) {
- callbacks.push(newChannel.loadGroup.notificationCallbacks);
- }
- var win;
- var webNav;
- for each (let callback in callbacks)
- {
- try {
- win = callback.getInterface(Ci.nsILoadContext).associatedWindow;
- webNav = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation);
- break;
- } catch(e) {}
- }
- if (!webNav) {
- return;
- }
- var redirectUrl = this.getRedirectUrl(newLocation);
-
- if (redirectUrl) {
- webNav.loadURI(redirectUrl,null,null,null,null);
- throw Cr.NS_BASE_STREAM_WOULD_BLOCK; //Throw this because the real error we should throw shows up in console...
- }
-
- } catch (e if (e != Cr.NS_BASE_STREAM_WOULD_BLOCK)) {
- // We shouldn't throw exceptions here - this will prevent the redirect.
- dump("Redirector: Unexpected error in onChannelRedirect: " + e + "\n");
- }
- },
- //end nsIChannelEventSink
-
- //Private members and methods
-
- _prefs : null,
- _list : null,
- _strings : null,
- _cout : Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService),
-
- _init : function() {
- if (this._prefs) {
- this._prefs.dispose();
- }
- this._cout.logStringMessage('REDIRECTOR CREATED');
- this._prefs = new RedirectorPrefs();
- //Check if we need to update existing redirects
- var data = this._prefs.redirects;
- var version = this._prefs.version;
- this._loadStrings();
- var currentVersion = '2.5';
- //Here update checks are handled
- if (version == 'undefined') { //Either a fresh install of Redirector, or first time install of v2.0
- if (data) { //There is some data in redirects, we are upgrading from a previous version, need to upgrade data
- var tempList = JSON.parse(data);
- var arr;
- var newArr = []
- for each (arr in tempList) {
- if (arr.length == 5) {
- arr.push(''); //For those that don't have an exclude pattern. Backwards compatibility is a bitch!
- }
- arr.splice(3,1); //Remove the "only if link exists" data
- newArr.push(arr.join(',,,'));
- }
- this._prefs.redirects = newArr.join(':::');
- }
- this._prefs.version = currentVersion;
- } else if (version == '2.0' || version == '2.0.1' || version == '2.0.2') {
- this._prefs.version = currentVersion;
- }
- //Update finished <