From a703799580a208beac24c827fcd54b799f46a3d7 Mon Sep 17 00:00:00 2001 From: Einar Egilsson Date: Wed, 7 Oct 2009 11:24:44 +0000 Subject: Finally working normally again after massive refactoring. Disabling single redirects works but needs more GUI work. Added Redirector log file since the Error Console keeps deleting our messages. git-svn-id: http://einaregilsson.googlecode.com/svn/mozilla/redirector/trunk@253 119bf307-c92d-0410-89bd-8f53e6181181 --- chrome/content/code/browserOverlay.xul.js | 22 ++- chrome/content/code/editRedirect.xul.js | 115 +++++++------- chrome/content/code/redirect.js | 211 ++++++++++++++++++++++++++ chrome/content/code/redirectList.xul.js | 122 +++++++-------- chrome/content/code/redirector.prototype.js | 223 ++++++++-------------------- chrome/content/log.html | 29 ++++ chrome/content/ui/browserOverlay.xul | 1 + chrome/content/ui/editRedirect.xul | 5 +- chrome/content/ui/redirectList.xul | 5 + chrome/content/unittest/run.html | 18 ++- chrome/content/unittest/testcases.js | 46 +++++- 11 files changed, 487 insertions(+), 310 deletions(-) create mode 100644 chrome/content/code/redirect.js create mode 100644 chrome/content/log.html (limited to 'chrome/content') 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 @@ + +
+