Index: lib/rules.js |
=================================================================== |
--- a/lib/rules.js |
+++ b/lib/rules.js |
@@ -9,6 +9,8 @@ |
let RULES_VERSION = 2; |
+let CUSTOM_RULE_PRIORITY = 0x7FFFFFFF; |
+ |
let rules = {expressions: []}; |
loadRules(); |
@@ -46,6 +48,10 @@ |
{ |
rules = data; |
callback(true); |
+ |
+ // Add user-defined rules after calling the callback - if the callback |
+ // saves the rules then the custom rules won't be included. |
+ addCustomRules(); |
} |
else |
callback(false); |
@@ -81,6 +87,101 @@ |
return getRuleFile(); |
} |
+function addCustomRules() |
+{ |
+ for (let domain in Prefs.whitelist) |
+ onWhitelistEntryAdded(domain); |
+} |
+ |
+function onWhitelistEntryAdded(domain) |
+{ |
+ let reverse = Array.prototype.slice.call(domain).reverse().join(""); |
+ addSuffix(rules.domain, reverse, CUSTOM_RULE_PRIORITY); |
+} |
+exports.onWhitelistEntryAdded = onWhitelistEntryAdded; |
+ |
+function onWhitelistEntryRemoved(domain) |
+{ |
+ let reverse = Array.prototype.slice.call(domain).reverse().join(""); |
+ removeSuffix(rules.domain, reverse, CUSTOM_RULE_PRIORITY); |
+} |
+exports.onWhitelistEntryRemoved = onWhitelistEntryRemoved; |
+ |
+function addSuffix(tree, suffix, priority) |
+{ |
+ if (suffix.length == 0) |
+ { |
+ // We are at the last character, just put our priority here |
+ tree[""] = " " + priority; |
+ return; |
+ } |
+ |
+ let c = suffix[0]; |
+ if (c in tree) |
+ { |
+ let existing = tree[c]; |
+ if (typeof existing == "string") |
+ { |
+ // Single choice for this suffix, maybe the same entry? |
+ if (existing.substr(0, suffix.length - 1) == suffix.substr(1) && existing[suffix.length - 1] == " ") |
+ { |
+ // Same entry, simply replace it by new priority |
+ tree[c] = suffix.substr(1) + " " + priority; |
+ } |
+ else |
+ { |
+ // Different entry, need to add a new branching point and go deeper |
+ if (existing[0] == " ") |
+ tree[c] = {"": existing}; |
+ else |
+ { |
+ tree[c] = {}; |
+ tree[c][existing[0]] = existing.substr(1); |
+ } |
+ addSuffix(tree[c], suffix.substr(1), priority); |
+ } |
+ } |
+ else |
+ { |
+ // Multiple choices for this suffix - go deeper |
+ addSuffix(existing, suffix.substr(1), priority); |
+ } |
+ } |
+ else |
+ { |
+ // No existing entry yet, just add ours |
+ tree[c] = suffix.substr(1) + " " + priority; |
+ } |
+} |
+ |
+function removeSuffix(tree, suffix, priority) |
+{ |
+ if (suffix.length == 0) |
+ { |
+ // We are at the last character, check whether there is an entry with |
+ // matching priority |
+ if ("" in tree && tree[""] == " " + priority) |
+ delete tree[""]; |
+ return; |
+ } |
+ |
+ let c = suffix[0]; |
+ if (!(c in tree)) |
+ return; |
+ |
+ if (typeof tree[c] == "string") |
+ { |
+ // Single entry - check whether it is the right one |
+ if (tree[c] == suffix.substr(1) + " " + priority) |
+ delete tree[c]; |
+ } |
+ else |
+ { |
+ // Multiple entries, need to go deeper |
+ removeSuffix(tree[c], suffix.substr(1), priority); |
+ } |
+} |
+ |
function onTimer() |
{ |
// Next check in 1 hour |
@@ -97,12 +198,6 @@ |
{ |
rules.timestamp = Date.now(); |
- var dynRules = require("updateRules").updateRules(); |
- for(var i in dynRules) |
- { |
- rules[i] = dynRules[i]; |
- } |
- |
try |
{ |
// Save the rules to file. |
@@ -150,13 +245,6 @@ |
else |
domain = domain.replace(searchString, replacement); |
} |
- |
- // Apply user's whitelist |
- let whitelist = Prefs.whitelist; |
- if (whitelist.hasOwnProperty(domain) || /^www\./.test(domain) && whitelist.hasOwnProperty(domain.substr(4))) |
- { |
- return domain; |
- } |
// Now apply our rules on the domain name |
for (let i = 0, l = rules.expressions.length; i < l; i++) |