From 9e015e88be66504c1de22f78202178b66b156cbb Mon Sep 17 00:00:00 2001 From: Einar Egilsson Date: Fri, 9 Oct 2009 14:59:56 +0000 Subject: Preferences part of window ready Compiled patterns Preferences object git-svn-id: http://einaregilsson.googlecode.com/svn/mozilla/redirector/trunk@258 119bf307-c92d-0410-89bd-8f53e6181181 --- chrome/content/code/browserOverlay.xul.js | 67 ++++-------- chrome/content/code/prefs.js | 92 ++++++++++++++++ chrome/content/code/redirect.js | 164 +++++++++++++--------------- chrome/content/code/redirectList.xul.js | 59 ++++++---- chrome/content/code/redirector.prototype.js | 52 +++------ chrome/content/ui/redirectList.xul | 25 +++-- 6 files changed, 261 insertions(+), 198 deletions(-) create mode 100644 chrome/content/code/prefs.js (limited to 'chrome') diff --git a/chrome/content/code/browserOverlay.xul.js b/chrome/content/code/browserOverlay.xul.js index 129da48..b5ec077 100644 --- a/chrome/content/code/browserOverlay.xul.js +++ b/chrome/content/code/browserOverlay.xul.js @@ -13,12 +13,9 @@ var RedirectorOverlay = { document.getElementById('contentAreaContextMenu') .addEventListener("popupshowing", function(e) { RedirectorOverlay.showContextMenu(e); }, false); - document.getElementById('redirector-status').hidden = !Redirector.getBoolPref('showStatusBarIcon'); - document.getElementById('redirector-context').hidden = !Redirector.getBoolPref('showContextMenu'); - this.strings = document.getElementById("redirector-strings"); - this.prefObserver.register(); - this.setStatusBarImg(); + this.changedPrefs(Redirector.prefs); + Redirector.prefs.addListener(this); } catch(e) { if (this.strings) { @@ -30,10 +27,25 @@ var RedirectorOverlay = { }, onUnload : function(event) { - RedirectorOverlay.prefObserver.unregister(); + Redirector.prefs.removeListener(this); Redirector.debug("Finished cleanup"); }, + changedPrefs : function(prefs) { + var statusImg = document.getElementById('redirector-statusbar-img'); + + if (prefs.enabled) { + statusImg.src = 'chrome://redirector/content/images/statusactive.PNG' + statusImg.setAttribute('tooltiptext', this.strings.getString('enabledTooltip')); + } else { + statusImg.src = 'chrome://redirector/content/images/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'); @@ -60,7 +72,7 @@ var RedirectorOverlay = { }, toggleEnabled : function(event) { - Redirector.setEnabled(!Redirector.enabled); + Redirector.prefs.enabled = !Redirector.prefs.enabled; }, openSettings : function() { @@ -85,47 +97,8 @@ var RedirectorOverlay = { } else if (event.button == RIGHT) { this.openSettings(); } - }, - - setStatusBarImg : function() { - var statusImg = document.getElementById('redirector-statusbar-img'); - - if (Redirector.enabled) { - statusImg.src = 'chrome://redirector/content/images/statusactive.PNG' - statusImg.setAttribute('tooltiptext', this.strings.getString('enabledTooltip')); - } else { - statusImg.src = 'chrome://redirector/content/images/statusinactive.PNG' - statusImg.setAttribute('tooltiptext', this.strings.getString('disabledTooltip')); - } - }, - - prefObserver : { - - getService : function() { - return Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranchInternal); - }, - - register: function() { - this.getService().addObserver('extensions.redirector', this, false); - }, - - unregister: function() { - this.getService().removeObserver('extensions.redirector', this); - }, - - observe : function(subject, topic, data) { - if (topic != 'nsPref:changed') { - return; - } - if (data == 'extensions.redirector.enabled') { - RedirectorOverlay.setStatusBarImg(); - } else if (data == 'extensions.redirector.showStatusBarIcon') { - document.getElementById('redirector-status').hidden = !Redirector.getBoolPref('showStatusBarIcon'); - } else if (data == 'extensions.redirector.showContextMenu') { - document.getElementById('redirector-context').hidden = !Redirector.getBoolPref('showContextMenu'); - } - } } + }; window.addEventListener("load", function(event) { RedirectorOverlay.onLoad(event); }, false); window.addEventListener("unload", function(event) { RedirectorOverlay.onUnload(event); }, false); diff --git a/chrome/content/code/prefs.js b/chrome/content/code/prefs.js new file mode 100644 index 0000000..c87eb27 --- /dev/null +++ b/chrome/content/code/prefs.js @@ -0,0 +1,92 @@ +// $Id$ + +function Prefs() { + this.init(); +} + +Prefs.prototype = { + + //Preferences: + _version : null, + _enabled : null, + _showStatusBarIcon : null, + _showContextMenu : null, + _debugEnabled : null, + _defaultDir : null, + _redirects : null, + + _prefBranch : null, + + _listeners : null, + + //Preferences props + + get version() { return this._version; }, + set version(value) { this._prefBranch.setCharPref('version', value); }, + + get enabled() { return this._enabled; }, + set enabled(value) { this._prefBranch.setBoolPref('enabled', value); }, + + get showStatusBarIcon() { return this._showStatusBarIcon; }, + set showStatusBarIcon(value) { this._prefBranch.setBoolPref('showStatusBarIcon', value); }, + + get showContextMenu() { return this._showContextMenu; }, + set showContextMenu(value) { this._prefBranch.setBoolPref('showContextMenu', value); }, + + get debugEnabled() { return this._debugEnabled; }, + set debugEnabled(value) { this._prefBranch.setBoolPref('debugEnabled', value); }, + + get defaultDir() { return this._defaultDir; }, + set defaultDir(value) { this._prefBranch.setCharPref('defaultDir', value); }, + + get redirects() { return this._redirects; }, + set redirects(value) { this._prefBranch.setCharPref('redirects', value); }, + + init : function() { + this._prefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("extensions.redirector."); + this.reload(); + this._listeners = []; + this.service.addObserver('extensions.redirector', this, false); + }, + + destroy : function() { + this.service.removeObserver('extensions.redirector', this); + }, + + reload : function() { + this._version = this._prefBranch.getCharPref('version'); + this._enabled = this._prefBranch.getBoolPref('enabled'); + this._showStatusBarIcon = this._prefBranch.getBoolPref('showStatusBarIcon'); + this._showContextMenu = this._prefBranch.getBoolPref('showContextMenu'); + this._debugEnabled = this._prefBranch.getBoolPref('debugEnabled'); + this._defaultDir = this._prefBranch.getCharPref('defaultDir'); + this._redirects = this._prefBranch.getCharPref('redirects'); + }, + + get service() { + return Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranchInternal); + }, + + observe : function(subject, topic, data) { + if (topic != 'nsPref:changed') { + return; + } + this.reload(); + for each (var listener in this._listeners) { + listener && listener.changedPrefs && listener.changedPrefs(this); + } + }, + + addListener : function(listener) { + this._listeners.push(listener); + }, + + removeListener : function(listener) { + for (var i = 0; i < this._listeners.length; i++) { + if (this._listeners[i] == listener) { + this._listeners.splice(i,1); + return; + } + } + }, +} \ No newline at end of file diff --git a/chrome/content/code/redirect.js b/chrome/content/code/redirect.js index 740eda9..dcd3596 100644 --- a/chrome/content/code/redirect.js +++ b/chrome/content/code/redirect.js @@ -9,6 +9,65 @@ Redirect.WILDCARD = 'W'; Redirect.REGEX = 'R'; Redirect.prototype = { + + //These are the only ones that are necessary to have as properties for now + //The others can be changed to properties later as neccessary + _includePattern : null, + _excludePattern : null, + _patternType : null, + _rxInclude : null, + _rxExclude : null, + + get patternType() { return this._patternType; }, + set patternType(value) { + this._patternType = value; + this.compile(); + }, + + 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); + }, + + _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() { + this._rxInclude = this._compile(this._includePattern); + this._rxExclude = this._compile(this._excludePattern); + }, + + _compile : function(pattern) { + if (!pattern) { + return null; + } + return new RegExp(this._preparePattern(pattern),"gi"); + }, + _init : function(exampleUrl, includePattern, excludePattern, redirectUrl, patternType, unescapeMatches, disabled) { this.exampleUrl = exampleUrl || ''; this.includePattern = includePattern || ''; @@ -78,11 +137,11 @@ Redirect.prototype = { }; var redirectTo = null; - redirectTo = this._match(url, this.includePattern, this.redirectUrl); + redirectTo = this._includeMatch(url); if (redirectTo !== null) { if (this.disabled) { result.isDisabledMatch = true; - } else if (this._match(url, this.excludePattern, 'exclude') == 'exclude') { + } else if (this._excludeMatch(url)) { result.isExcludeMatch = true; } else { result.isMatch = true; @@ -92,95 +151,24 @@ Redirect.prototype = { return result; }, - _match : function(url, pattern, redirectUrl) { - if (this.isWildcard()) { - return this._wildcardMatch(url, pattern, redirectUrl); - } else { - return this._regexMatch(url, pattern, redirectUrl); + _includeMatch : function(url) { + if (!this._rxInclude) { + return null; } - }, - - _wildcardMatch : function(url, pattern, redirectUrl) { - - if (!pattern || !url) { - return null; + var matches = this._rxInclude.exec(url); + if (!matches) { + 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 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]); } - - 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; - }, + return resultUrl; + }, + + _excludeMatch : function(url) { + return !!(this._rxExclude && this._rxExclude.exec(url)); + }, clone : function() { return new Redirect(this.exampleUrl, this.includePattern, diff --git a/chrome/content/code/redirectList.xul.js b/chrome/content/code/redirectList.xul.js index 76b450f..046d018 100644 --- a/chrome/content/code/redirectList.xul.js +++ b/chrome/content/code/redirectList.xul.js @@ -11,24 +11,55 @@ var RedirectList = { btnEdit : null, btnUp : null, btnDown : null, - + chkEnableRedirector : null, + chkShowStatusBarIcon : null, + chkShowContextMenu : null, + chkEnableDebugOutput : null, + onLoad : function() { try { + //Get references to controls this.lstRedirects = document.getElementById('lstRedirects'); - this.lstRedirects.selType = 'single'; - this.template = document.getElementsByTagName('richlistitem')[0]; - this.lstRedirects.removeChild(this.template); this.btnDelete = document.getElementById('btnDelete'); this.btnEdit = document.getElementById('btnEdit'); this.btnUp = document.getElementById('btnUp'); this.btnDown = document.getElementById('btnDown'); + this.chkEnableRedirector = document.getElementById('chkEnableRedirector'); + this.chkShowStatusBarIcon = document.getElementById('chkShowStatusBarIcon'); + this.chkShowContextMenu = document.getElementById('chkShowContextMenu'); + this.chkEnableDebugOutput = document.getElementById('chkEnableDebugOutput'); + + //Preferences + this.setPrefs(Redirector.prefs); + Redirector.prefs.addListener(this); + + //Redirect list + this.lstRedirects.selType = 'single'; + this.template = document.getElementsByTagName('richlistitem')[0]; + this.lstRedirects.removeChild(this.template); this.addItemsToListBox(Redirector.list); - this.strings = document.getElementById('redirector-strings'); + + this.strings = document.getElementById('redirector-strings'); } catch(e) { alert(e); } }, + + onUnload : function() { + Redirector.prefs.removeListener(this); + }, + changedPrefs : function(prefs) { + this.setPrefs(prefs); + }, + + setPrefs : function(prefs) { + this.chkEnableRedirector.setAttribute('checked', prefs.enabled); + this.chkShowStatusBarIcon.setAttribute('checked', prefs.showStatusBarIcon); + this.chkShowContextMenu.setAttribute('checked', prefs.showContextMenu); + this.chkEnableDebugOutput.setAttribute('checked', prefs.debugEnabled); + }, + addItemsToListBox : function(items) { var item, row, value, newItem; @@ -94,6 +125,10 @@ var RedirectList = { listItem.getElementsByAttribute('name', 'dscrRedirectTo')[0].setAttribute('value', item.redirectUrl); }, + preferenceChange : function(event) { + Redirector.prefs[event.originalTarget.getAttribute('preference')] = event.originalTarget.hasAttribute('checked'); + }, + addRedirect : function() { var args = { saved : false, redirect : new Redirect() }; window.openDialog("chrome://redirector/content/ui/editRedirect.xul", "redirect", "chrome,dialog,modal,centerscreen", args); @@ -124,12 +159,6 @@ var RedirectList = { } }, - buttonKeyPress : function(event) { - if (event.keyCode == 13 && !event.originalTarget.disabled) { - event.originalTarget.click(); - } - }, - deleteRedirect : function() { var index = this.lstRedirects.selectedIndex; @@ -165,14 +194,6 @@ var RedirectList = { this.btnDown.disabled = (index == -1 || index >= Redirector.list.length-1); }, - redirectListKeyDown : function(event) { - if (event.keyCode == 46) { //Del key - this.deleteRedirect(); - } else if (event.keyCode == 13) { //Enter key - this.editRedirect(); - } - }, - importExport : function(mode, captionKey, func) { //Mostly borrowed from Adblock Plus var picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); diff --git a/chrome/content/code/redirector.prototype.js b/chrome/content/code/redirector.prototype.js index 8218395..e364ecc 100644 --- a/chrome/content/code/redirector.prototype.js +++ b/chrome/content/code/redirector.prototype.js @@ -6,19 +6,20 @@ Cr = Components.results; nsIContentPolicy = Ci.nsIContentPolicy; Redirector.prototype = { - prefBranch : null, - list : null, + + prefs : null, + list : null, strings : null, cout : Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService), + + init : function() { - this.prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).getBranch("extensions.redirector."); + this.prefs = new Prefs(); //Check if we need to update existing redirects - var data = this.prefBranch.getCharPref('redirects'); - var version = this.prefBranch.getCharPref('version'); - this.debugEnabled = this.prefBranch.getBoolPref('debug'); - this.enabled = this.prefBranch.getBoolPref('enabled'); + var data = this.prefs.redirects; + var version = this.prefs.version; this.loadStrings(); //Here update checks are handled if (version == 'undefined') { //Either a fresh install of Redirector, or first time install of v2.0 @@ -33,14 +34,14 @@ Redirector.prototype = { arr.splice(3,1); //Remove the "only if link exists" data newArr.push(arr.join(',,,')); } - this.prefBranch.setCharPref('redirects', newArr.join(':::')); + this.prefs.redirects = newArr.join(':::'); } - this.prefBranch.setCharPref('version', '2.0'); + this.prefs.version = '2.0'; } //Update finished //Now get from the new format - data = this.prefBranch.getCharPref('redirects'); + data = this.prefs.redirects; var arr; this.list = []; if (data != '') { @@ -52,14 +53,6 @@ Redirector.prototype = { } }, - getDefaultDir : function() { - return this.prefBranch.getCharPref('defaultDir'); - }, - - setDefaultDir : function(dir) { - this.prefBranch.setCharPref('defaultDir', dir.spec); - }, - loadStrings : function() { var src = 'chrome://redirector/locale/redirector.properties'; var localeService = Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci.nsILocaleService); @@ -69,7 +62,7 @@ Redirector.prototype = { }, debug : function(msg) { - if (this.debugEnabled) { + if (this.prefs.debugEnabled) { this.cout.logStringMessage('REDIRECTOR: ' + msg); } }, @@ -77,14 +70,15 @@ Redirector.prototype = { // nsIContentPolicy interface implementation shouldLoad: function(contentType, contentLocation, requestOrigin, aContext, mimeTypeGuess, extra) { try { - if (!this.enabled) { + if (!this.prefs.enabled) { return nsIContentPolicy.ACCEPT; } - if (contentLocation.scheme != "http" && contentLocation.scheme != "https") { + + if (contentType != nsIContentPolicy.TYPE_DOCUMENT) { return nsIContentPolicy.ACCEPT; } - - if (contentType != nsIContentPolicy.TYPE_DOCUMENT) { + + if (contentLocation.scheme != "http" && contentLocation.scheme != "https") { return nsIContentPolicy.ACCEPT; } @@ -122,11 +116,6 @@ Redirector.prototype = { return nsIContentPolicy.ACCEPT; }, - setEnabled : function(val) { - this.enabled = val; - this.prefBranch.setBoolPref('enabled', val); - }, - reload : function() { loader.loadSubScript('chrome://redirector/content/code/redirector.prototype.js'); loader.loadSubScript('chrome://redirector/content/code/redirect.js'); @@ -148,17 +137,13 @@ Redirector.prototype = { }, save : function() { - this.prefBranch.setCharPref('redirects', this.redirectsAsString(':::')); + this.prefs.redirects = this.redirectsAsString(':::'); }, redirectsAsString : function(seperator) { return [r.serialize() for each (r in this.list)].join(seperator); }, - getBoolPref : function(name) { - return this.prefBranch.getBoolPref(name); - }, - exportRedirects : function(file) { var fileStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); const PR_WRONLY = 0x02; @@ -166,7 +151,6 @@ Redirector.prototype = { const PR_TRUNCATE = 0x20; fileStream.init(file, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0644, 0); - //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.redirectsAsString('\n')); diff --git a/chrome/content/ui/redirectList.xul b/chrome/content/ui/redirectList.xul index 02b1b72..9154e8a 100644 --- a/chrome/content/ui/redirectList.xul +++ b/chrome/content/ui/redirectList.xul @@ -7,6 +7,7 @@ + + + + - + @@ -56,11 +61,11 @@ -