| 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 = domain.split("").reverse().join(""); |
| + addSuffix(rules.domain, reverse, CUSTOM_RULE_PRIORITY); |
| +} |
| +exports.onWhitelistEntryAdded = onWhitelistEntryAdded; |
| + |
| +function onWhitelistEntryRemoved(domain) |
| +{ |
| + let reverse = domain.split("").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++) |