Skip to content

Commit

Permalink
Switch to URI domain logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ocornu committed Sep 27, 2009
1 parent e98b92e commit f00e07f
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 35 deletions.
1 change: 1 addition & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ _______________________________________________________________________________
convert2RegExp.js URI mask parser
file.jsm File management
prefs.jsm Preferences management
uriset.jsm URI sets management
script/ Userscript internals
api.jsm Sandbox API
console.jsm Dummy Firebug console
Expand Down
4 changes: 2 additions & 2 deletions src/content/pages-overlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ function PagesControl(ctlPages) {
this.script = null;
this.populate = function(script) {
this.clear();
includesBox.populate(script, "includes", script.meta.includes);
excludesBox.populate(script, "excludes", script.meta.excludes);
includesBox.populate(script, "includes", script.meta.domain.includes);
excludesBox.populate(script, "excludes", script.meta.domain.excludes);
this.script = script;
GM_getConfig().addObserver(this, this.script);
};
Expand Down
253 changes: 253 additions & 0 deletions src/modules/lib/uriset.jsm
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
/**
* @fileoverview URI sets and overlays.
*/
// JSM exported symbols
var EXPORTED_SYMBOLS = ["UriSet"];


const Cc = Components.classes;
const Ci = Components.interfaces;


// import dependencies
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("resource://webmonkey/lib/convert2RegExp.js");


/**
* Construct a new <code>UriSet</code> object.
* @constructor
*
* @class Implementation of an abstract URI set.
* <p>A URI set is a (potentially infinite) set of URIs.<br>
* It is specified using a list of include/exclude masks. A target URI that
* matches an exclude mask is not part of the set; else if it matches an include
* mask it is part of the set.</p>
* <p>Masks are URI strings, optionally featuring the wildcard char '*' which
* stands for "any number of chars".<br>
* Example: <code>http://www.google.com/*</code></p>
* <p>For convenience, it is also possible to define a URI set using rules: a
* rule is a mask, optionally preceded by '-' (exclude) or '+' (include, default).<br>
* Example: <code>-http://www.google.com/login</code></p>
* <p>Note: include/exclude masks are unique in their category.</p>
*/
function UriSet() {
this._init();
}

UriSet.prototype = {
/**
* Initializer.
*/
_init: function() {
/**
* Included URI masks.
* @type string[]
*/
this.includes = [];
/**
* Excluded URI masks.
* @type string[]
*/
this.excludes = [];
},

/**
* Add an include mask.
* @param aMask The include mask to add.
* @return {boolean} <code>true</code> if it was added,
* <code>false</code> otherwise.
*/
addInclude: function(/**string*/ aMask) {
return add(this.includes, aMask);
},
/**
* Remove an include mask.
* @param aMask The include mask to remove.
* @return {boolean} <code>true</code> if it was removed,
* <code>false</code> otherwise.
*/
removeInclude: function(/**string*/ aMask) {
return remove(this.includes, aMask);
},
/**
* Remove an include mask.
* @param aIndex The include mask index to remove.
* @return {boolean} <code>true</code> if it was removed,
* <code>false</code> otherwise.
*/
removeIncludeAt: function(/**int*/ aIndex) {
return removeAt(this.includes, aIndex);
},

/**
* Add an exclude mask.
* @param aMask The exclude mask to add.
* @return {boolean} <code>true</code> if it was added,
* <code>false</code> otherwise.
*/
addExclude: function(/**string*/ aMask) {
return add(this.excludes, aMask);
},
/**
* Remove an exclude mask.
* @param aMask The exclude mask to remove.
* @return {boolean} <code>true</code> if it was removed,
* <code>false</code> otherwise.
*/
removeExclude: function(/**string*/ aMask) {
return remove(this.excludes, aMask);
},
/**
* Remove an exclude mask.
* @param aIndex The exclude mask index to remove.
* @return {boolean} <code>true</code> if it was removed,
* <code>false</code> otherwise.
*/
removeExcludeAt: function(/**int*/ aIndex) {
return removeAt(this.excludes, aIndex);
},

/**
* Add a rule.
* @param aRule The rule to add.
* @return {boolean} <code>true</code> if it was added,
* <code>false</code> otherwise.
*/
addRule: function(/**string*/ aRule) {
var mask = getMask(aRule);
if (mask=="") return false;
var target = isInclude(aRule) ? this.includes : this.excludes;
return add(target, mask);
},
/**
* Remove a rule.
* @param aRule The rule to remove.
* @return {boolean} <code>true</code> if it was removed,
* <code>false</code> otherwise.
*/
removeRule: function(/**string*/ aRule) {
var mask = getMask(aRule);
if (mask=="") return false;
var target = isInclude(aRule) ? this.includes : this.excludes;
return remove(target, mask);
},
/**
* Replace a rule with another.
* @param oldRule The rule to be replaced.
* @param newRule The rule to put in its place.
* @return {boolean} <code>true</code> if it was replaced,
* <code>false</code> otherwise.
*/
replaceRule: function(/**string*/ oldRule, /**string*/ newRule) {
var oldMask = getMask(oldRule);
if (oldMask=="") return false;
var oldTarget = isInclude(oldRule) ? this.includes : this.excludes;
var index = oldTarget.indexOf(oldMask);
if (index<0) return false;

var newMask = getMask(newRule);
if (newMask=="") return false;
var newTarget = isInclude(newRule) ? this.includes : this.excludes;
if (newTarget.indexOf(newMask)>=0) return false;

if (oldTarget==newTarget)
oldTarget[index] = newMask;
else {
oldTarget.splice(oldIndex, 1);
newTarget.push(newMask);
}
return true;
},

/**
* Whether this set contains the specified URI.
* @param aUri The URI to test.
* @return {boolean} <code>true</code> if it does, <code>false</code> if not.
*/
contains: function(/**nsIURI|string*/ aUri) {
if (aUri instanceof Ci.nsIURI)
aUri = aUri.spec;
// Do we forbid this URI?
if (this.excludes.some(match))
return false;
// If not, do we allow this URI?
if (this.includes.some(match))
return true;
return false;

// URI mask tester
function match(mask) {
return convert2RegExp(mask).test(aUri);
}
}
};


/**
* Add a mask to a target list, if it does not exist yet.
* @param target The target masks list.
* @param mask The mask to add.
* @return {boolean} <code>true</code> if it was added,
* <code>false</code> otherwise.
* @private
*/
function add(/**string[]*/ target, /**string*/ mask) {
if (target.indexOf(mask)>=0) return false;
target.push(mask);
return true;
}

/**
* Remove a mask from a target list, if it does exist.
* @param target The target masks list.
* @param mask The mask to remove.
* @return {boolean} <code>true</code> if it was removed,
* <code>false</code> otherwise.
* @private
*/
function remove(/**string[]*/ target, /**string*/ mask) {
var index = target.indexOf(mask);
if (index<0) return false;
target.splice(index, 1);
return true;
}

/**
* Remove a mask at the specified index in the target list.
* @param target The target masks list.
* @param index The mask index to remove.
* @return {boolean} <code>true</code> if it was removed,
* <code>false</code> otherwise.
* @private
*/
function removeAt(/**string[]*/ target, /**int*/ index) {
if (!(index>=0 && index<target.length)) return false;
target.splice(index, 1);
return true;
}

/**
* Whether the specified rule is an include rule.
* @param rule The rule to test.
* @return {boolean} <code>true</code> if it's an include,
* <code>false</code> otherwise.
* @private
*/
function isInclude(/**string*/ rule) {
return /^\s*[^-]/.test(rule);
}

/**
* Extract the string mask contained in this rule.
* @param rule The rule to extract a mask from.
* @return {string} The included mask if there is any,
* <code>""</code> otherwise.
* @private
*/
function getMask(/**string*/ rule) {
if (typeof rule != "string") return "";
return rule.replace(/^\s*(\+|-)?\s*(.*)\s*$/, "$2");
}

11 changes: 1 addition & 10 deletions src/modules/script.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,13 @@
var EXPORTED_SYMBOLS = ["Script"];


const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;

// import dependencies
Cu.import("resource://webmonkey/script/metadata.jsm");
Cu.import("resource://webmonkey/script/api.jsm");
Cu.import("resource://webmonkey/lib/file.jsm");
Cu.import("resource://webmonkey/lib/prefs.jsm");
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("resource://webmonkey/lib/convert2RegExp.js");


/**
Expand Down Expand Up @@ -77,11 +72,7 @@ Script.prototype = {
* <code>false</code> otherwise.
*/
isRunnable: function(/**string*/ url) {
return this.meta.includes.some(match) && !this.meta.excludes.some(match);

function match(rule) {
return convert2RegExp(rule).test(url);
}
return this.meta.domain.contains(url);
},

/**
Expand Down

0 comments on commit f00e07f

Please sign in to comment.